irrlicht代码法线贴图相关问题

irrlicht的代码关于法线贴图的范例即 PerPixelLighting。


程序准备资源部分,


先是一个砖墙普遍纹理,设到 text0


然后是一个法线纹理贴图,设到text1(中间经过处理,将对比度,转换成相应的法线数据)


然后是在COpenGLDriver::drawVertexPrimitiveList函数中,会走到case EVT_TANGENTS:这个分支.


接下来的代码 要结合渲染脚本(一段嵌入的伪汇编,irrlicht 1.7 估计还没有引入glsl)


case EVT_TANGENTS:
if (vertices)
{
glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Normal);
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].TCoords);
glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Pos);
}
else
{
glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(12));
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24));
glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28));
glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0));
}


if (MultiTextureExtension)
{
extGlClientActiveTexture(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (vertices)
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Tangent);
else
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(36));


extGlClientActiveTexture(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (vertices)
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast<const S3DVertexTangents*>(vertices))[0].Binormal);
else
glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48));
}
break;

因为程序并没有设置 text2,所以这段代码令人费解

同样,在text1处,传入的纹理映射数组,也令人不解


所以,它们不是纹理映射,是顶点法线的切空间中的两个轴(相关切空间可以参考 相关文章)

因为多边形的位置在空间中不断变化,根据法线纹理来计算光照,需要将光线变换到切空间中去。

这样才能直接计算出光照值。


text1 text2关于传入的是tangent 和bitangent,

以便在顶点渲染与像素渲染脚本中使用,将光线变换到顶点的切空间,并最终计算出每个顶点的像素值。

相应的渲染脚本存在 COpenGLParallaxMapRenderer.cpp中的数组变量中:

OPENGL_PARALLAX_MAP_VSH OPENGL_PARALLAX_MAP_PSH


注意脚本中的这一段代码:

"#input\n"\
"# 0-3: transposed world matrix;\n"\
"#;12: Light01 position \n"\
"#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\
"#;14: Light02 position \n"\
"#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\
"#;16: Eye position \n"\
"\n"\
"ATTRIB InPos = vertex.position;\n"\
"ATTRIB InColor = vertex.color;\n"\
"ATTRIB InNormal = vertex.normal;\n"\
"ATTRIB InTexCoord = vertex.texcoord[0];\n"\
"ATTRIB InTangent = vertex.texcoord[1];\n"\
"ATTRIB InBinormal = vertex.texcoord[2];\n"\


所以 text1 text2传进去的纹理映射参数,在计算时是作为顶点切空间tangent和binormal(也就是bitangent)。

text2没指定纹理,也没关系,因为实际计算的时候并没有涉及到text2纹理相关的内存。


弄清参数传递机制后,接下来,生成tangent binormal以及相应的光线变换到切空间算法参考

Mathematics for 3D Game Programming and Computer Graphics 这本说的6.8章节(最新版本的好像在7.8章节)



这段代码有点怪异,究其原因也是因为tangent 和 binormal没有现成的机制传给渲染脚本导致的。





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值