3D游戏编程大师技巧(上下册) 9.2分
读书笔记 使用Gouraud光照计算的3D水分子演示程序
麻子

流程总结: -- mGouraudWater.loadFormCOB("model/water_gouraud_01.cob", vscale, Point4D::ZERO, Vector4D::ZERO, VERTEX_FLAGS_SWAP_YZ | VERTEX_FLAGS_TRANSFORM_LOCAL | VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD); 加载模型 同时按vscale对模型缩放 然后。。 调用computePolyNormals() 计算并保存每个面的法向量的长度 调用computeVertexNormals() 计算并保存每个顶点的法向量(归一化为单位向量) 备注:因为缩放会影响法向量的长度(对应两条边构成的平行四边形面积),所以先做缩放,再计算法向量至关重要。 -- mGouraudWater.transformByMat(mat, TRANSFORMMODE_LOCAL_TO_TRANS, true, false); 按旋转矩阵旋转水分子(各顶点),同时顶点法线也跟着旋转了。由于面法线只记录了长度,而旋转是不会影响法线长度的,所以不变。(面法线朝向在光照阶段会重新计算) 备注:transformByMat所用矩阵只可以用来做旋转,因为仅旋转不会影响法线向量的方向和长度,但是如果矩阵包含中有平移,则结果完全不对了。 -- mGouraudWater.transformModelToWorld(TRANSFORMMODE_TRANS_ONLY, false); 这里只是将每个顶点加上了world_pos (平移) -- mRenderList.insert(mGouraudWater, false); 插入到渲染列表 mRenderList.removeBackfaces(mCamera); 背面剔除 -- mRenderList.lightInWorld(mCamera, mLightList); 光照计算,这里用到了之前计算并记录的面法线长度(面法线朝向重新计算了)和顶点法线(单位法线),以提高速度。 备注:应该在处于世界坐标时调用此函数,因为如果坐标已经变为相机坐标的话,则意味着顶点又经过了一次平移和旋转,那么顶点法线向量又要重新计算了。同时如果物体的坐标为相机坐标的话,还得把光源的坐标也都变换为相机坐标。 -- mRenderList.transformWorldToCamera(mCamera); 转为相机坐标 mRenderList.sortZ(SORT_POLY_METHOD_AVGZ); 此时按Z排序 mRenderList.transformCameraToPerspective(mCamera); 转为投影平面坐标(2D) mRenderList.transformPerspectiveToScreen(mCamera); 转为屏幕坐标 (2D) ... -- 备注:以上是我改写过的C++风格的代码,但步骤和原理与原书C风格代码一致。

1
《3D游戏编程大师技巧(上下册)》的全部笔记 16篇
豆瓣
免费下载 iOS / Android 版客户端