Unity shader学习之高光反射光照模型
高光反射光照模型的公式如下:
Cspecular = Clight * mspecular * max(0, dot(v, r))gloss
要计算高光反射需要知道4个参数:入射光线颜色Cspecular,材质高光反射系数gloss,视角方向v和反射方向r。
其中r可由cg函数reflect(i, n)求得。
转载请注明出处:http://www.cnblogs.com/jietian331/p/7088297.html
逐顶点高光反射shader如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Shader "Custom/Specular Vertex-Level" 2 { 3 Properties 4 { 5 _Diffuse ("Diffuse Color", Color) = (1,1,1,1) 6 _Specular ("Specular Color", Color) = (1,1,1,1) 7 _Gloss ("Gloss", Range(8, 256)) = 8 8 } 9 SubShader 10 { 11 Tags { "RenderType"="Opaque" } 12 LOD 100 13 14 Pass 15 { 16 Tags { "LightMode"="ForwardBase" } 17 18 CGPROGRAM 19 #pragma vertex vert 20 #pragma fragment frag 21 22 #include "UnityCG.cginc" 23 #include "Lighting.cginc" 24 25 struct appdata 26 { 27 float4 vertex : POSITION; 28 float3 normal : NORMAL; 29 }; 30 31 struct v2f 32 { 33 float4 vertex : SV_POSITION; 34 fixed4 color : COLOR; 35 }; 36 37 fixed4 _Diffuse; 38 fixed4 _Specular; 39 float _Gloss; 40 41 v2f vert (appdata v) 42 { 43 v2f o; 44 o.vertex = UnityObjectToClipPos(v.vertex); 45 46 // specular 47 float3 lightDir = ObjSpaceLightDir(v.vertex); 48 lightDir = normalize(lightDir); 49 float3 nor = normalize(v.normal); 50 float3 refLightDir = reflect(-lightDir, nor); 51 refLightDir = normalize(refLightDir); 52 float3 viewDir = ObjSpaceViewDir(v.vertex); 53 viewDir = normalize(viewDir); 54 float d = max(0, dot(refLightDir, viewDir)); 55 float3 specColor = _LightColor0.rgb * _Specular.rgb * pow(d, _Gloss); 56 57 // diffuse 58 float3 diffuseColor = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(lightDir, nor)); 59 60 float3 c = specColor + diffuseColor + UNITY_LIGHTMODEL_AMBIENT.rgb; 61 62 o.color = float4(c, 1); 63 64 return o; 65 } 66 67 fixed4 frag (v2f i) : SV_Target 68 { 69 return i.color; 70 } 71 ENDCG 72 } 73 } 74 }
逐像素高光反射shader如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 Shader "Custom/Specular Fragment-Level" 2 { 3 Properties 4 { 5 _Diffuse ("Diffuse Color", Color) = (1,1,1,1) 6 _Specular ("Specular Color", Color) = (1,1,1,1) 7 _Gloss ("Gloss", Range(8, 256)) = 8 8 } 9 SubShader 10 { 11 Tags { "RenderType"="Opaque" } 12 LOD 100 13 14 Pass 15 { 16 Tags { "LightMode"="ForwardBase" } 17 18 CGPROGRAM 19 #pragma vertex vert 20 #pragma fragment frag 21 22 #include "UnityCG.cginc" 23 #include "Lighting.cginc" 24 25 struct appdata 26 { 27 float4 vertex : POSITION; 28 float3 normal : NORMAL; 29 }; 30 31 struct v2f 32 { 33 float4 vertex : SV_POSITION; 34 float3 worldPos : TEXCOORD0; 35 float3 worldNormal : TEXCOORD1; 36 }; 37 38 fixed4 _Diffuse; 39 fixed4 _Specular; 40 float _Gloss; 41 42 v2f vert (appdata v) 43 { 44 v2f o; 45 o.vertex = UnityObjectToClipPos(v.vertex); 46 o.worldNormal = UnityObjectToWorldNormal(v.normal); 47 o.worldPos = mul(unity_ObjectToWorld, v.vertex); 48 return o; 49 } 50 51 fixed4 frag (v2f i) : SV_Target 52 { 53 // specular 54 float3 worldNormal = normalize(i.worldNormal); 55 float3 lightDir = UnityWorldSpaceLightDir(i.worldPos); 56 lightDir = normalize(lightDir); 57 float3 refLightDir = reflect(-lightDir, worldNormal); 58 refLightDir = normalize(refLightDir); 59 float3 viewDir = UnityWorldSpaceViewDir(i.worldPos); 60 viewDir = normalize(viewDir); 61 float d = max(0, dot(refLightDir, viewDir)); 62 float3 spec = _LightColor0.rgb * _Specular.rgb * pow(d, _Gloss); 63 64 // diffuse 65 float3 diff = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(lightDir, worldNormal)); 66 67 float3 c = spec + diff + UNITY_LIGHTMODEL_AMBIENT.rgb; 68 return fixed4(c, 1); 69 } 70 ENDCG 71 } 72 } 73 }
效果分别如下: