这个教程的结构以下:函数
这节讲的是由关于点光源的spa
看上面的图,假设Q点为光源原点,假设在Q点(Xq,Yq,Zq)光照强度为PointLightColor=(r,g,b); Q点到P点(Xp,Yp,Zp)的距离为 d, 灯光衰减因子atten1,atten2,atten3(衰减因子由你本身决定的,三个不可同时为0).net
那么点光源或者说灯泡照射在P点的强度为: LightIntensity=PointLightColor/(atten1+atten2*d+atten3*d*d);code
光入射P点的向量为(Q,P)或者说为(Xp-Xq,Yp-Yq,Zp-Zq);orm
下面的有些我已经在 blog
贴出shader代码,那些累赘重复的代码我没封装成函数,请见谅:教程
Texture2D ShaderTexture:register(t0); //纹理资源 SamplerState SampleType:register(s0); //采样方式 #define LIGHT_NUM 4 cbuffer CBMatrix:register(b0) { matrix World; matrix View; matrix Proj; matrix WorldInvTranspose; }; cbuffer CBDiffuseColor:register(b1) { float4 diffuseColor[LIGHT_NUM]; }; cbuffer CBLightPos : register(b2) { float4 LightPos[LIGHT_NUM]; }; struct VertexIn { float3 Pos:POSITION; float2 Tex:TEXCOORD0; //多重纹理能够用其它数字 float3 Normal:NORMAL; }; struct VertexOut { float4 Pos:SV_POSITION; float3 Pos_W:POSITION; //点在世界空间的位置 float2 Tex:TEXCOORD0; float3 W_Normal:NORMAL; //世界空间的法线 }; VertexOut VS(VertexIn ina) { VertexOut outa; //将模型坐标变到齐次裁剪空间 outa.Pos = mul(float4(ina.Pos,1.0f), World); outa.Pos = mul(outa.Pos, View); outa.Pos = mul(outa.Pos, Proj); //将法向量变到世界空间 outa.W_Normal = mul(ina.Normal, (float3x3)WorldInvTranspose); //此事世界逆转置矩阵的第四行原本就没啥用 outa.W_Normal = normalize(outa.W_Normal); //纹理坐标 outa.Tex= ina.Tex; //求点在世界空间的位置 float4 PosW= mul(float4(ina.Pos, 1.0f), World); outa.Pos_W = PosW.xyz; return outa; } //这里光照发生在世界空间,固然其它空间也行. float4 PS(VertexOut outa) : SV_Target { float4 TexColor; //采集的纹理颜色 float4 color = {0.0f,0.0f,0.0f,0.0f}; //最终输出的颜色 float DiffuseFactor1; float DiffuseFactor2; float DiffuseFactor3; float DiffuseFactor4; float4 DiffuseColorIntensity1; float4 DiffuseColorIntensity2; float4 DiffuseColorIntensity3; float4 DiffuseColorIntensity4; float4 DiffuseColor1; float4 DiffuseColor2; float4 DiffuseColor3; float4 DiffuseColor4; float atten1, atten2, atten3; //衰减系数 //初始化衰减系数 atten1 = 1.0f; atten2 = 0.5f; atten3 = 0.0f; /*灯光一*/ //计算像素到灯光1的向量,照射到像素的光强度, float3 LookDirection1 = LightPos[0].xyz - outa.Pos_W.xyz; //计算光源到像素点的距离 float distance1 = length(LookDirection1); //计算光源照射到像素点的光照强度 DiffuseColorIntensity1 = diffuseColor[0] / (atten1 + atten2*distance1 + atten3*distance1*distance1); //衰减系数注意加括号计算为分母 //将像素点到光源向量进规格化 LookDirection1 = normalize(LookDirection1); //求出漫反射光因子 DiffuseFactor1 = saturate(dot(outa.W_Normal, LookDirection1)); //求出最终照射在像素点的漫反射光照强度 DiffuseColor1 = DiffuseFactor1*DiffuseColorIntensity1; /*灯光二*/ //计算像素到灯光2的向量,照射到像素的光强度, float3 LookDirection2 = LightPos[1].xyz - outa.Pos_W.xyz; float distance2 = length(LookDirection2); DiffuseColorIntensity2 = diffuseColor[1] / (atten1 + atten2*distance2 + atten3*distance2*distance2); LookDirection2 = normalize(LookDirection2); DiffuseFactor2 = saturate(dot(outa.W_Normal, LookDirection2)); DiffuseColor2 = DiffuseFactor2*DiffuseColorIntensity2; /*灯光三*/ //计算像素到灯光3的向量,照射到像素的光强度, float3 LookDirection3 = LightPos[2].xyz - outa.Pos_W.xyz; float distance3 = length(LookDirection3); DiffuseColorIntensity3= diffuseColor[2] / (atten1 + atten2*distance3 + atten3*distance3*distance3); LookDirection3 = normalize(LookDirection3); DiffuseFactor3= saturate(dot(outa.W_Normal, LookDirection3)); DiffuseColor3= DiffuseFactor3*DiffuseColorIntensity3; /*灯光四*/ //计算像素到灯光4的向量,照射到像素的光强度, float3 LookDirection4= LightPos[3].xyz - outa.Pos_W.xyz; float distance4 = length(LookDirection4); DiffuseColorIntensity4 = diffuseColor[3] / (atten1 + atten2*distance4 + atten3*distance4*distance4); LookDirection4= normalize(LookDirection4); DiffuseFactor4 = saturate(dot(outa.W_Normal, LookDirection4)); DiffuseColor4 = DiffuseFactor4*DiffuseColorIntensity4; //获取采样颜色 TexColor = ShaderTexture.Sample(SampleType, outa.Tex); //第五,用灯光颜色调节纹理颜色 color = saturate(DiffuseColor1+ DiffuseColor2+ DiffuseColor3+ DiffuseColor4)*TexColor; return color; }
程序运行效果图:资源