Unity Shader:(七)漫反射光照模型
漫反射公式=光源颜色*材质漫反射颜色*光源强度
1. 逐顶点漫反射光照
1 Shader "Test/DiffuseShader" 2 { 3 Properties{ _Color("Diffuse",Color)=(1.0,1.0,1.0,1.0)} 4 SubShader 5 { 6 Pass 7 { 8 Tags{"LightMode"="ForwardBase"} 9 10 CGPROGRAM 11 #pragma vertex vert 12 #pragma fragment frag 13 14 #include "Lighting.cginc" 15 fixed4 _Diffuse;//材质的漫反射颜色 16 17 struct a2v 18 { 19 float4 vertex:POSITION; 20 float3 normal:NORMAL; //法线,注意a2v的法线位于模型空间 21 }; 22 struct v2f 23 { 24 float4 pos:SV_POSITION; 25 fixed3 color : COLOR; 26 }; 27 28 v2f vert(a2v v) 29 { 30 v2f o; 31 o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间 32 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光 33 //计算漫反射 34 fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列 35 fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向 36 //漫反射公式=光源颜色*材质漫反射颜色*光源强度 37 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));//saturate可以把参数截取到[0,1]范围内 38 o.color = ambient + diffuse;//环境光+漫反射光 39 return o; 40 } 41 fixed4 frag(v2f i) : SV_Target 42 { 43 return fixed4(i.color,1.0); 44 } 45 ENDCG 46 } 47 } 48 FallBack "Diffuse" 49 }
2. 逐像素漫反射光照:更平滑的光照效果
Shader "Test/DiffuseShader2" { Properties{ _Color("Diffuse",Color) = (1.0,1.0,1.0,1.0) } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "Lighting.cginc" fixed4 _Diffuse;//材质的漫反射颜色 struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; //法线,注意a2v的法线位于模型空间 }; struct v2f { float4 pos:SV_POSITION; fixed3 worldNormal : TEXCOORD0; }; //顶点着色器不计算漫反射,只是把转换后的法线传给片元着色器 v2f vert(a2v v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间 o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列 return o; } //片元着色器里计算漫反射 fixed4 frag(v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光 //计算漫反射 fixed3 worldNormal = normalize(i.worldNormal); fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向 //漫反射公式=光源颜色*材质漫反射颜色*光源强度 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));//saturate可以把参数截取到[0,1]范围内 fixed3 color = ambient + diffuse;//环境光+漫反射光 return fixed4(color,1.0); } ENDCG } } FallBack "Diffuse" }
3. 半兰伯特光照模型:背光区域也会有明暗变化(与逐像素漫反射模型差别用加粗字标注,在光源强度的计算上有差别)
1 Shader "Test/DiffuseShader3" 2 { 3 Properties{ _Color("Diffuse",Color) = (1.0,1.0,1.0,1.0) } 4 SubShader 5 { 6 Pass 7 { 8 Tags{"LightMode" = "ForwardBase"} 9 10 CGPROGRAM 11 #pragma vertex vert 12 #pragma fragment frag 13 14 #include "Lighting.cginc" 15 fixed4 _Diffuse;//材质的漫反射颜色 16 17 struct a2v 18 { 19 float4 vertex:POSITION; 20 float3 normal:NORMAL; //法线,注意a2v的法线位于模型空间 21 }; 22 struct v2f 23 { 24 float4 pos:SV_POSITION; 25 fixed3 worldNormal : TEXCOORD0; 26 }; 27 //顶点着色器不计算漫反射,只是把转换后的法线传给片元着色器 28 v2f vert(a2v v) 29 { 30 v2f o; 31 o.pos = UnityObjectToClipPos(v.vertex);//顶点位置从模型空间转换到裁剪空间 32 o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);//把法线转换到世界空间,(float3x3)表示取矩阵的3行3列 33 return o; 34 } 35 //片元着色器里计算漫反射 36 fixed4 frag(v2f i) : SV_Target 37 { 38 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; //环境光 39 //计算漫反射 40 fixed3 worldNormal = normalize(i.worldNormal); 41 fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);//得到光源方向 42 //漫反射公式=光源颜色*材质漫反射颜色*光源强度 43 fixed halfLambert = dot(worldNormal, worldLight) * 0.5 + 0.5; 44 fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;//saturate可以把参数截取到[0,1]范围内 45 fixed3 color = ambient + diffuse;//环境光+漫反射光 46 return fixed4(color,1.0); 47 } 48 ENDCG 49 } 50 } 51 FallBack "Diffuse" 52 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了