Blinn-Phong 着色器实现 概述 Blinn-Phong 着色模型是经典 Phong 模型的改进版本,通过引入半角向量(Halfway Vector)优化了高光计算。我们的实现包含完整的顶点和片段着色器处理流程。
核心实现 1. 顶点着色器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Varyings BlinnPhongShader::vertex (const VertexInput& input) { Varyings output; vec4f worldPos4 = uniform_ModelMatrix * vec4f (input.position, 1.0f ); output.worldPosition = Vector3 <float >(worldPos4. x, worldPos4. y, worldPos4. z); vec4f worldNormal4 = uniform_NormalMatrix * vec4f (input.normal, 0.0f ); output.worldNormal = worldNormal4. xyz ().normalized (); output.uv = input.uv; output.clipPosition = uniform_MVP * vec4f (input.position, 1.0f ); return output; }
2. 片段着色器 片段着色器实现了完整的 Blinn-Phong 光照模型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 bool BlinnPhongShader::fragment (const Varyings& input, Vector3<float >& outColor) { Vector3<float > N = input.worldNormal.normalized (); Vector3<float > V = (uniform_CameraPosition - input.worldPosition).normalized (); Vector3<float > matDiffuse = uniform_Material.diffuseColor; if (uniform_Material.hasDiffuseTexture ()) { matDiffuse = matDiffuse * uniform_Material.diffuseTexture.sample (input.uv.x, input.uv.y); } Vector3<float > totalColor = uniform_AmbientLight * uniform_Material.ambientColor; for (const auto & light : uniform_Lights) { Vector3<float > L = light.getDirectionTo (input.worldPosition); float diffFactor = std::max (0.0f , N.dot (L)); Vector3<float > diffuse = matDiffuse * light.color * diffFactor; Vector3<float > H = (L + V).normalized (); float specFactor = fastPow (std::max (0.0f , N.dot (H)), matShininess); Vector3<float > specular = matSpecular * light.color * specFactor; totalColor += diffuse + specular; } outColor = totalColor.clamp (0.0f , 1.0f ); return true ; }
关键技术点 1. 快速幂计算 1 2 3 4 5 6 7 8 9 10 11 template <typename T>T fastPow (T base, int n) { T res = static_cast <T>(1 ); while (n) { if (n & 1 ) res = res * base; base = base * base; n >>= 1 ; } return res; }
2. 光照类型支持
方向光(Directional Light)
点光源(Point Light)
环境光(Ambient Light)
3. 材质系统
漫反射颜色/贴图
高光颜色
光泽度(Shininess)
环境光反射率
使用方法
创建 BlinnPhongShader 实例
设置必要的 uniform 变量:
绑定到渲染器使用
性能优化
使用快速幂算法优化高光计算
提前终止无效的光照计算
向量运算的规范化处理
后续改进计划
添加法线贴图支持
实现 PBR 材质系统
支持多光源阴影计算