标签:
6.4顶点照明和Unity存放光源的第三种方式打开Lab_ 3文件夹下的场景,其编辑器中Game视日的截图所示。上面蓝色区域的右下角是6个表明了灰度颜色和数字之间关系的图例,而最左边是场景中4个点光源在WorldSpace中的xyz坐标,在上面的是4个点光源的3个灰度材质球的表示,在下面的是4个点光源的一般数字(x, y, x)表示。从上往下依次是黄色点光源Yellow (0.7, 0.5, 0.2)、绿色点光源Green (0.7 ,0.5 , 0.5、红色点光源Red ( 0.5 ,0.2, 0.2)以及蓝色点光源B1ue(0.2, 0.5,0.7)。之所以这样从黄色到蓝色排列,是因为我们可以根据Unity计算光照强度时所使用的Lunimance函数,来预测这4个颜色的点光源在unity_LightPosition[4]数组中的先后顺序。在这组灰度和数字对光源的世界坐标的表示的右边,是相对应的对光源在Camera空间的灰度和数字表示。因为场景中相机的坐标为(-0.3,-0.3,-0.3 ) ,而且相机没有旋转,因此我们可以很简单地算出这4个点光源在Camera空间的xyz坐标,黄色点光源Yellow(1.0,0.8, 0.5)、绿色点光源Green(1.0,0.8 ,0.8 )、红色点光源Red (0.8,0.5,0.5)以及蓝色点光源(0.5,0.8,1.0) 4个点光源的WorldSpace和CameraSpace坐标都在(0,1)区间,可以被屏幕上的灰度正确表示,而且如果unity_LightPosition[4]中4个点光源的坐标是CameraSpace中的表示,那么灰度表示应该整体加亮0.3。将unity_LightPosition[4]数组中的每个向量的每个分量输出列Labes 3/ Shader文件夹下,如前两节一样都很简单,只是将对应的xyzw分量输出成灰度而己。除此之外,还输出了unity_LightAtten[4]数组到倒数第二排球体上,unity LightColor[4]到倒数第一排球体上。
float3 ShadeVertexLights(float4 vertex,float3 normal) { float3 viewpos = mul(UNITY_MATRIX_MV,vertex).xyz; float3 viewN = mul((float3x3)UNITY_MATRIX_IT_MV,normal); float3 lightColor = UNITY_LIGHTMODEL_AMBIENT.xyz; for(int i=0;i<4;i++){ float3 toLight = unity_LightPosition[i].xyz - viewpos.xyz*unity_LightPosition[i].w; float lengthSq = dot(toLight,toLight); float atten = 1.0 / (1.0+lengthSq * unity_LightAtten[i].z); float diff = max(0,dot(viewN,normalize(toLight))); LightColor += unity_LightColor[i].rgb * (diff * atten); } return lightColor; }首先我们可以发现顶点被这个矩阵UNITY_MATRIX_MV变换了,这说明float4 unity_LightPosition[4]中存储的确实是视空间中的光源估息,也就是当前Camera空间的光源的方向矢量或者位置。注意这个函数计算衰减的方式,如果你想让自己手动写的Shade对光照计算的结果和Unity一致,那么对衰减采用同样的计算方式很重要。
hader "Tut/Lighting/VertexLit/Indicator/unity_LightPosition_0" { Properties { _Color ("Base Color", Color) =(1,1,1,1) } SubShader { pass{ Tags{ "LightMode"="Vertex"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" uniform float4 _Color; struct vertOut{ float4 pos:SV_POSITION; float4 color:COLOR; }; vertOut vert(appdata_base v) { //unity_LightPosition in viewSpace,ie,the camera space float3 viewpos = mul (UNITY_MATRIX_MV, v.vertex).xyz; float3 viewN = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal); float3 lightColor = UNITY_LIGHTMODEL_AMBIENT.xyz; float3 toLight = unity_LightPosition[0].xyz - viewpos.xyz * unity_LightPosition[0].w; float lengthSq = dot(toLight, toLight); float atten = 4.0 / (1.0 + lengthSq * unity_LightAtten[0].z); float diff = max (0, dot (viewN, normalize(toLight))); lightColor += unity_LightColor[0].rgb * (diff * atten); vertOut o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.color=float4(lightColor,1)*_Color; return o; } float4 frag(vertOut i):COLOR { return i.color; } ENDCG }//end pass } }
untiy 3d ShaderLab_第6章_VertexLit渲染路径_4_顶点照明和Unity存放光源的第三种方式
标签:
原文地址:http://blog.csdn.net/heyuchang666/article/details/51313216