LIGHTMAP_OFF
#ifndef LIGHTMAP_OFF // 计算LightMap,这部分不懂 #ifndef DIRLIGHTMAP_OFF // directional lightmaps fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy); fixed4 lmIndTex = tex2D(unity_LightmapInd, IN.lmap.xy); half3 lm = LightingLambert_DirLightmap(o, lmtex, lmIndTex, 0).rgb; #else // !DIRLIGHTMAP_OFF // single lightmap fixed4 lmtex = tex2D(unity_Lightmap, IN.lmap.xy); fixed3 lm = DecodeLightmap (lmtex); #endif // !DIRLIGHTMAP_OFF
// combine lightmaps with realtime shadows #ifdef SHADOWS_SCREEN #if (defined(SHADER_API_GLES) || defined(SHADER_API_GLES3)) && defined(SHADER_API_MOBILE) c.rgb += o.Albedo * min(lm, atten*2); #else c.rgb += o.Albedo * max(min(lm,(atten*2)*lmtex.rgb), lm*atten); #endif #else // SHADOWS_SCREEN c.rgb += o.Albedo * lm; #endif // SHADOWS_SCREEN
// 给Alpha通道赋值 c.a = o.Alpha; #endif // LIGHTMAP_OFF
// 调用自定义的final函数, // 对像素值进行最后的更改 final (surfIN, o, c); return c; }
ENDCG
}
// —- end of surface shader generated code
#LINE 57
} FallBack “Diffuse” }
其中比较重要的部分我都写了注释。
一些问题
回到我们一开始的那个问题:为什么我的场景里没有灯光,但物体不是全黑的呢?这一切都是Fragment Shader中一些颜色叠加计算的结果。
我们仔细观察Fragment Shader中计算颜色的部分。前面说过,它使用LightingXXX对颜色值进行初始化,但后面还进行了一系列颜色叠加计算。其中,在没有使用LightMap的情况下,Unity还计算了vertex lights对颜色的影响,也就是下面这句话: #ifdef LIGHTMAP_OFF // 如果没有开启LightMap, // 向像素叠加vertex light的光照颜色 c.rgb += o.Albedo * IN.vlight; #endif // LIGHTMAP_OFF 而IN.vlight是在Vertex Shader中计算的: //如果没有开启LightMap, //vertex lights就是球面调和函数的结果 //球面调和函数ShadeSH9在UnityCG.cginc里定义 float3 shlight = ShadeSH9 (float4(worldN,1.0)); o.vlight = shlight; 我们可以去查看ShadeSH9函数的实现: // normal should be normalized, w=1.0 half3 ShadeSH9 (half4 normal) { half3 x1, x2, x3;
// Linear + constant polynomial terms x1.r = dot(unity_SHAr,normal); x1.g = dot(unity_SHAg,normal); x1.b = dot(unity_SHAb,normal);
// 4 of the quadratic polynomials half4 vB = normal.xyzz * normal.yzzx; x2.r = dot(unity_SHBr,vB); x2.g = dot(unity_SHBg,vB); x2.b = dot(unity_SHBb,vB);
// Final quadratic polynomial float vC = normal.x*normal.x – normal.y*normal.y; x3 = unity_SHC.rgb * vC; return x1 + x2 + x3; } 它是一个球面调和函数,但unity_SHAr这些变量具体是什么我还不清楚。。。如果有人知道麻烦告诉我一下,不胜感激~但是,这些变量是和Unity使用了一个全局环境光(你可以在Edit->RenderSettings->Ambient Light中调整)有关。如果把这个环境光也调成黑色,那么场景就真的全黑了。
呼呼呼,关于这些光源计算的部分就是一开始所说的那些让写shader变得很复杂的原因之一!如果你真的去看那些在UnityCG.cginc、AutoLight.cginc等文件里的关于指令的定义,可以发现Unity是根据定义的光照类型来处理不同的光照的。这部分还没有搞明白,后面会继续探究一下的!
转载: 游戏开发网
|