opengles法线贴图

xiaoxiao2021-02-27  85

法线贴图:如果一个物体的表面粗糙不平,物体顶点的法线也就朝着各个不同的方向,所以物体看起来凹凸不平,要展现这样的物体

可以使用相当多的包含不同法线的顶点数据,这样做效率很低,一种高效的做法是:把法线坐标值内置于纹理图片中

法线贴图也是一张普通的纹理图片,和一般纹理图片的区别在于,法线贴图中的每个像素保存的是法线数据,一般通过高度图来生成

法线贴图,高度图是8位灰度图,颜色越深高度越低,颜色越浅高度越高。

参考:http://blog.csdn.net/zhangci226/article/details/5588226

效果图:

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);"//法线和切线求叉积 //构造TBN矩阵 http://blog.csdn.net/jxw167/article/details/58671953 //http://blog.csdn.net/jxw167/article/details/58592875 "highp mat3 tangentSpaceXform=mat3(inTangent,bitangent,inNormal);" "LightVec=lightDirection*tangentSpaceXform;" "TexCoord=inTexCoord;" "}" }; const char* ps = { "precision lowp float;" "uniform sampler2D sBaseTex;" "uniform sampler2D sNormalMap;" "varying lowp vec3 LightVec;" "varying mediump vec2 TexCoord;" "void main()" "{" //将像素值映射到[-1,1] TexCoord保存的是法线向量(x,y,z) "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);" "}" };渲染函数:

virtual void onRender(Program_BumpMap& shader,CELL3RDCamera& camera) { static float angle = 0; matrix4 matRot(1); matRot.rotateY(angle); matrix4 matTrans; matTrans.translate(0,5,0); matrix4 matScale(1); matScale.scale(0.3f,0.3f,0.3f); matrix4 matModel = matTrans * matRot * matScale; angle += 1.0f; float4 vMsLightPos = float4(50, 20, 40, 1);//光源位置 vMsLightPos = vMsLightPos * matModel; matrix4 MVP = camera._matProj * camera._matView * matModel ; _device.setUniformMatrix4fv(shader.MVPMatrix,1,false,MVP.data()); _device.setUniform3fv(shader.LightPosModel,1,&vMsLightPos.x); VertexBumpMap* vert = &_arVertexs.front(); _device.attributePointer(shader.inVertex, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), vert); _device.attributePointer(shader.inNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0]._normal); _device.attributePointer(shader.inTexCoord, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0]._uv); _device.attributePointer(shader.inTangent, 3, GL_FLOAT, GL_FALSE, sizeof(VertexBumpMap), &vert[0]._tangent); _device.drawElements(GL_TRIANGLES,_arFaces.size() * 3,GL_UNSIGNED_SHORT,&_arFaces.front()); }

转载请注明原文地址: https://www.6miu.com/read-6053.html

最新回复(0)