标签:pow 文件 strong ora 出版社 color 决定 运行 视频
笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:《手把手教你架构3D游戏引擎》电子工业出版社和《Unity3D实战核心技术详解》电子工业出版社等。
CSDN课程视频网址:http://edu.csdn.net/lecturer/144
Phong 着色法是结合了多边形物体表面反射光的亮度,并以特定位置的表面法线作为像素参考值,以插值方式来估计其周围位置像素的色值。与Gouraud着色法比较,Phong着色法的效果比前者更逼真。实现方式跟上面的一样,新建一个文本文件,将后缀名改成.fx。Shader完整代码如下所示:
float4x4 matWorldViewPrj; float4x4 matWorld; float3 lightPos = float3(0, 60, -60); float lightAttenuation = 0.01; float3 eyePos = float3(0, 200, 400); float4 mtlDiffuseColor = float4(1, 0, 0, 1); struct VS_INPUT { float3 pos : POSITION; float3 normal : NORMAL; }; struct VS_OUTPUT { float4 pos : POSITION; float3 worldPos : TEXCOORD0; float3 normal : TEXCOORD1; }; VS_OUTPUT my_vs(VS_INPUT vert) { VS_OUTPUT vsout; vsout.pos = mul(float4(vert.pos, 1), matWorldViewPrj); vsout.worldPos = mul(float4(vert.pos, 1), matWorld); vsout.normal = normalize(mul(vert.normal, matWorld)); return vsout; } float4 my_ps(float3 worldPos : TEXCOORD0, float3 normal : TEXCOORD1) : COLOR { float4 color; //ambient color = mtlDiffuseColor * 0.2f; normal = normalize(normal); float3 L = lightPos - worldPos; float d = length(L); L /= d; float atten = 1 / (lightAttenuation * d); float diff = saturate(dot(normal, L)); color +=mtlDiffuseColor * diff * atten; float3 V = normalize(worldPos - eyePos); float3 R = reflect(L, normal); float specular = pow(saturate(dot(R, V)), 8) * atten * diff; color += float4(specular, specular, specular, 0); return color; } technique my_tech { pass p0 { VertexShader = compile vs_1_1 my_vs(); PixelShader = compile ps_2_0 my_ps(); } }
float3 R = reflect(L, normal);
float specular = pow(saturate(dot(R, V)), 8) * atten * diff;
color += float4(specular, specular, specular, 0);
Phong着色模型是将物体表面的光反射看成是环境光的反射之和与光源直接有关的漫反射及镜面反射的组合。这句话理解起来比较拗口,从数学上讲就是将反射的总能量看做是光环境的强度,点光源的强度乘以三个不同的系数后相加的和。这三个系数分别表示:物体表面反射环境光、产生漫反射和产生镜面反射的能力。在代码的实现过程中都离不开数学公司的运算,在这里再啰嗦一下,数学知识对于程序开发来说非常重要,它决定了你将能达到的高度。
标签:pow 文件 strong ora 出版社 color 决定 运行 视频
原文地址:http://blog.csdn.net/jxw167/article/details/54866209