{
1:法线介绍
2:实例
3:推荐博客
}
{1:法线介绍
光的强度=光照+法线+法线贴图
模型凹凸纹理效果=基础贴图 X 光的强度
模型有两种贴图
基础贴图 例如一个盒子,盒子是木头纹理,或铁皮纹理
法线贴图 把基础贴图中凹凸的地方生成一个张原纹理大小的贴图
法线
幅法线
切线
}
{2:实例
{
1:Shader
2:调用
}
{1:Shader
const char* vs = {
"attribute vec3 inVertex;"
"attribute vec3 inNormal;"//法线
"attribute vec2 inTexCoord;"
"attribute vec3 inTangent;"//切线
"uniform mat4 MVPMatrix;"
"uniform vec3 LightPosModel;" //光照
"varying vec3 LightVec;"//光的夹角
"varying vec2 TexCoord;"
"void main(){"
"gl_Position = MVPMatrix * vec4(inVertex,1);"
//计算光的方向,在模型空间中
//在模型空间得到的光的方向 --〉 要从模型空间转换到切线空间
"highp vec3 lightDirection = normalize(LightPosModel - vec3(inVertex));"
//! 将灯的方向从模型空间,转化到tangent空间
"highp vec3 bitangent = cross(inNormal, inTangent);"// vec3 cross(vec3 x, vec3 y) 向量x,y之间的叉积
"highp mat3 tangentSpaceXform = mat3(inTangent, bitangent, inNormal);"//算出-〉切线坐标系
"LightVec = lightDirection * tangentSpaceXform;"
"TexCoord = inTexCoord;"
"}"
};
const char * fs = {
"precision lowp float; "
"uniform sampler2D sBaseTex;"
"uniform sampler2D sNormalMap;"//法线图
"varying lowp vec3 LightVec;"//光的向量
"varying mediump vec2 TexCoord;"
"void main(){"
// 将像素值映射到 [-1, 1] 法线的范围是[-1,1],rgb范围[0.1],([0,1]*2-1=[0-1,2-1]=[-1,1])
"vec3 normal = texture2D(sNormalMap, TexCoord).rgb * 2.0 - 1.0;"
"float lightIntensity = dot(LightVec, normal);"//光的强度(算出物体上的一点光的强度)
"vec3 texColor = texture2D(sBaseTex, TexCoord).rgb; "
"gl_FragColor = vec4(texColor * lightIntensity, 1.0);"
"}"
};
pValue=creteShaderProgram(vs,fs);
inVertex =glGetAttribLocation(pValue.pID, "inVertex");
inNormal =glGetAttribLocation(pValue.pID, "inNormal");
inTexCoord =glGetAttribLocation(pValue.pID, "inTexCoord");
inTangent =glGetAttribLocation(pValue.pID,"inTangent");
MVPMatrix =glGetUniformLocation(pValue.pID,"MVPMatrix");
LightPosModel =glGetUniformLocation(pValue.pID,"LightPosModel");
sBaseTex =glGetUniformLocation(pValue.pID,"sBaseTex");
sNormalMap =glGetUniformLocation(pValue.pID,"sNormalMap");
}
{2:调用
bmShader.shaderBegin();
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,textureBaseId);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,textureNormalId);
glUniform1i(bmShader.sBaseTex,0);
glUniform1i(bmShader.sNormalMap,1);
//printf("%d - %d = %d\n",GL_TEXTURE1,GL_TEXTURE0,GL_TEXTURE1-GL_TEXTURE0);
static float angle = 0; // angle += 1.0f;
CELL::matrix4 matRot(1);
matRot.rotateY(angle);
CELL::matrix4 matTrans;
matTrans.translate(0,5,0);
CELL::matrix4 matScale(1);
matScale.scale(0.3f,0.3f,0.3f);
CELL::matrix4 matModel = matTrans * matRot * matScale;
//光源位置
CELL::float4 vMsLightPos = CELL::float4(50, 20, 40, 1);
vMsLightPos = vMsLightPos * matModel;
//CELL::matrix4 MVP = camera._matProj * camera._matView * matModel ;
MVP = matProj * matView *matModel;
glUniformMatrix4fv(bmShader.MVPMatrix,1,false,MVP.data());
glUniform3fv(bmShader.LightPosModel,1,&vMsLightPos.x);
VertexBumpMap* vert = &model.arVertexs.front();
glVertexAttribPointer(bmShader.inVertex, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), vert);
glVertexAttribPointer(bmShader.inNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0].normal);
glVertexAttribPointer(bmShader.inTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0].uv);
glVertexAttribPointer(bmShader.inTangent, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0].tangent);
glDrawElements(GL_TRIANGLES,model.arFaces.size() * 3,GL_UNSIGNED_SHORT,&model.arFaces.front());
}
bmShader.shaderEnd();
}
}
效果图
生成法线贴图工具(photoshop支持Win32/64)
支持版本 Adobe Photoshop 5.0, 5.1, 6.0, 7.0, CS, CS2, CS3, CS4, CS5 and CS6
下载地址
https://developer.nvidia.com/gameworksdownload#?dn=texture-tools-for-adobe-photoshop-8-55
源码地址 http://pan.baidu.com/s/1geVargZ 法线贴图.zip
{3:推荐博客
http://blog.csdn.net/zp373860147/article/details/6758828
http://www.cnblogs.com/flytrace/p/3387748.html
}