欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity Shader------Specular(高光反射)计算

程序员文章站 2024-03-23 08:27:16
...

高光反射公式:

Specular= 直射光颜色 * pow(max(dot(当前点的反射光方向,当前点到摄像机的方向),0),高光反射参数)

 

Unity Shader------Specular(高光反射)计算Unity Shader------Specular(高光反射)计算

逐顶点高光反射:

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Shader03"{
	Properties{
		_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
		_SpecularColor("_SpecularColor",Color)=(1,1,1,1) //高光的颜色
		_Gloss("Gloss",Range(8,200)) = 10 //控制高光光圈大小
	}
	SubShader{
		Pass{
		    //定义LightMode以得到unity的内置光照变量
		    Tags{"LightMode" = "ForwardBase"}

		    CGPROGRAM
		    //unity内置文件引入,要使用unity的内置变量
		    #include "Lighting.cginc"
		    #pragma vertex vert
		    #pragma fragment frag

		    fixed4 _Color;
		    half _Gloss;
		    fixed4 _SpecularColor;

		    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 = UnityObjectToClipPos(v.vertex);
		    	//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
		    	fixed3 normalDir = normalize(mul(v.normal, (float3x3) unity_WorldToObject));
		    	//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
		    	fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
		    	//取得漫反射颜色
		    	fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
		    	//反射光方向
		    	fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
		    	//当前点到摄像机的方向
		    	fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(v.vertex, unity_WorldToObject).xyz);
		    	//高光反射
		    	fixed3 specular = _LightColor0.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss) *_SpecularColor;
		    	//环境光
		    	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
		    	//颜色叠加
		    	f.color = diffuse + specular + ambient;
		    	return f;
		    }
		    fixed4 frag(v2f f) : SV_Target{
			    return fixed4(f.color,1);
		    }
		    ENDCG
	    }
	}
	FallBack "Diffuse"
}

逐像素高光反射:

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Shader03"{
	Properties{
		_Color("_Color",Color) = (1,1,1,1) //物体本身的颜色
		_SpecularColor("_SpecularColor",Color)=(1,1,1,1) //高光的颜色
		_Gloss("Gloss",Range(8,200)) = 10 //控制高光光圈大小
	}
	SubShader{
		Pass{
		    //定义LightMode以得到unity的内置光照变量
		    Tags{"LightMode" = "ForwardBase"}

		    CGPROGRAM
		    //unity内置文件引入,要使用unity的内置变量
		    #include "Lighting.cginc"
		    #pragma vertex vert
		    #pragma fragment frag

		    fixed4 _Color;
		    half _Gloss;
		    fixed4 _SpecularColor;

		    struct a2v {
		    	float4 vertex : POSITION;
		    	float3 normal : NORMAL;
		    };
		    struct v2f {
		    	float4 position : SV_POSITION;
		    	float3 worldNormal : TEXCOOED0;
				float3 worldVertex : TEXCOOED1;
		    };
		    v2f vert(a2v v) {
		    	v2f f;
		    	//UNITY_MATRIX_MVP 坐标从模型空间转剪裁空间
		    	f.position = UnityObjectToClipPos(v.vertex);
				f.worldNormal = mul(v.normal, (float3x3) unity_WorldToObject);
				f.worldVertex = mul(v.vertex, unity_WorldToObject).xyz;
		    
		    	return f;
		    }
		    fixed4 frag(v2f f) : SV_Target{

				//法线的单位向量:_World2Object 把一个方向从世界空间转模型空间
		    	fixed3 normalDir = normalize(f.worldNormal);
		    	//光的单位向量:对于每个顶点来说,平行光位置就是光的方向 _WorldSpaceLightPos0 取得平行光的位置
		    	fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
		    	//取得漫反射颜色
		    	fixed3 diffuse = _LightColor0.rgb * max(dot(normalDir, lightDir), 0) * _Color.rgb;
		    	//反射光方向
		    	fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
		    	//当前点到摄像机的方向
		    	fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - f.worldVertex);
		    	//高光反射
		    	fixed3 specular = _LightColor0.rgb * pow(max(dot(reflectDir, viewDir), 0), _Gloss) *_SpecularColor;
		    	//环境光
		    	fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;
		    	//颜色叠加
		    	fixed3 tempColor = diffuse + specular + ambient;
			    return fixed4(tempColor,1);
		    }
		    ENDCG
	    }
	}
	FallBack "Diffuse"
}

对比:

Unity Shader------Specular(高光反射)计算

相关标签: UnityShader