Unity Shader------漫反射(Diffuse)计算

光照模型:
一个公式,用来计算在某个点的光照效果
标准光照模型下进入摄像机的光:
自发光
高光反射
漫反射(Diffuse): 直射光颜色 * max(0,cos(光和法线的夹角))
逐顶点实现漫反射:

Shader "Custom/Shader01"{
	SubShader{
		Pass{
		    //定义LightMode以得到unity的内置光照变量
		    Tags{"LightMode"="ForwardBase"}
		    CGPROGRAM
		    //unity内置文件引入,要使用unity的内置变量
            #include "Lighting.cginc"
            #pragma vertex vert
            #pragma fragment frag
			struct a2v{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
            };
	        struct v2f{
				float4 position : SV_POSITION;
				fixed3 color : COLOR;
			};
			v2f vert(a2v v){
				v2f f;
				//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
				f.position = mul(UNITY_MATRIX_MVP,v.vertex);
				//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
				fixed3 normalDir = normalize(mul(v.normal, (float3x3) _World2Object));
				//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
				fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0);//取得漫反射颜色
				f.color = diffuse;

				return f;
		    }
		    fixed4 frag(v2f f) : SV_Target{
		    	return fixed4(f.color,1);
		    }
		    ENDCG
	    }
	}
	FallBack "Diffuse"
}

漫反射效果:
在这里插入图片描述
添加环境光和自身的颜色

Shader "Custom/Shader01"{
	Properties{
		_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
	}
	SubShader{
		Pass{
		    //定义LightMode以得到unity的内置光照变量
		    Tags{"LightMode"="ForwardBase"}
		    CGPROGRAM
		    //unity内置文件引入,要使用unity的内置变量
            #include "Lighting.cginc"
            #pragma vertex vert
            #pragma fragment frag

			fixed4 _Color;

			struct a2v{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
            };
	        struct v2f{
				float4 position : SV_POSITION;
				fixed3 color : COLOR;
			};
			v2f vert(a2v v){
				v2f f;
				//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
				f.position = mul(UNITY_MATRIX_MVP,v.vertex);
				//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
				fixed3 normalDir = normalize(mul(v.normal, (float3x3) _World2Object));
				//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
				fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
				//取得漫反射颜色
				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
				//UNITY_LIGHTMODEL_AMBIENT 获取环境光
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
				f.color = diffuse + ambient;
				return f;
		    }
		    fixed4 frag(v2f f) : SV_Target{
		    	return fixed4(f.color,1);
		    }
		    ENDCG
	    }
	}
	FallBack "Diffuse"
}

在这里插入图片描述
逐像素实现漫反射:

Shader "Custom/Shader02"{
	Properties{
		_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
	}
	SubShader{
		Pass{
		    //定义LightMode以得到unity的内置光照变量
		    Tags{"LightMode"="ForwardBase"}
		    CGPROGRAM
		    //unity内置文件引入,要使用unity的内置变量
            #include "Lighting.cginc"
            #pragma vertex vert
            #pragma fragment frag

			fixed4 _Color;

			struct a2v{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
            };
	        struct v2f{
				float4 position : SV_POSITION;
				fixed3 worldNormalDir : COLOR0;
			};
			v2f vert(a2v v){
				v2f f;
				f.position = mul(UNITY_MATRIX_MVP, v.vertex);
				f.worldNormalDir = normalize(mul(v.normal, (float3x3) unity_WorldToObject));
				
				return f;
		    }
		    fixed4 frag(v2f f) : SV_Target{
				fixed3 normalDir = f.worldNormalDir;
				fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
				fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
				fixed3 tempColor = diffuse + ambient;
		    	return fixed4(tempColor,1);
		    }
		    ENDCG
	    }
	}
	FallBack "Diffuse"
}

与之前的逐顶点进行对比,颜色过渡平滑,效果更好
在这里插入图片描述

半兰伯特光照模型:
之前的漫反射也叫兰伯特光照模型,通过公式我们可以看到cos的值是-1到1的,当小于1时为0,这时物体的背面是几乎是黑色的,会影响游戏的体验
我们将cos值*0.5+0.5,这时值的范围变为0到1

fixed3 diffuse = _LightColor0.rgb * (dot(normalDir, lightDir)*0.5 + 0.5) * _Color.rgb;

在这里插入图片描述
在这里插入图片描述

发布了107 篇原创文章 · 获赞 31 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/love_phoebe/article/details/103759499