Unity URP Shader之标准的BlinnPhong光照模型

BlinnPhong光照,这是shader中最基础,最经典的光照模型,具体计算方法如下:

1. 漫反射

half3 diffuseCol = NdotL * lightCol * baseCol * shadowAttenuation * distanceAttenuation;

2. 镜面反射

half halfDir = normalize(viewDir + lightDir);

half NdotH = saturate(dot(worldNormal, halfDir));

half3 specularCol = pow(NdotH, gloss) * lightCol * baseCol * shadowAttenuation * distanceAttenuation;

shader如下:

  1 Shader "MyURP/Kerry/URPBlinnPhong"
  2 {
  3     Properties
  4     {
  5         _BaseMap("Base Map", 2D) = "white" {}
  6         _NormalMap("Normal Map", 2D) = "bump" {}
  7         _SpecGloss("Specular Gloss", Range(1, 20)) = 8
  8     }
  9 
 10     SubShader
 11     {
 12         Tags
 13         {
 14             "RenderType" = "Opaque"
 15             "RenderPipeline" = "UniversalPipeline"
 16         }
 17 
 18         Pass
 19         {
 20             Tags
 21             {
 22                 "LightMode" = "UniversalForward"
 23             }
 24 
 25             HLSLPROGRAM
 26 
 27             // Universal Pipeline keywords
 28             #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
 29             #pragma multi_compile _ _ADDITIONAL_LIGHTS
 30             #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
 31 
 32             #pragma vertex vert
 33             #pragma fragment frag
 34             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
 35             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
 36 
 37             TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
 38             TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap);
 39             float _SpecGloss;
 40 
 41             struct appdata
 42             {
 43                 float4 vertex : POSITION;
 44                 float2 uv : TEXCOORD0;
 45                 float4 normal : NORMAL;
 46                 float4 tangent : TANGENT;
 47             };
 48 
 49             struct v2f
 50             {
 51                 float4 pos : SV_POSITION;
 52                 float2 uv : TEXCOORD0;
 53                 float3 worldNormal : TEXCOORD1;
 54                 float3 worldTangent : TEXCOORD2;
 55                 float3 worldBinormal : TEXCOORD3;
 56                 float3 worldPos : TEXCOORD4;
 57                 float4 shadowCoord : TEXCOORD5;
 58             };
 59 
 60             v2f vert(appdata v)
 61             {
 62                 v2f o;
 63                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
 64                 o.uv = v.uv;
 65                 o.worldNormal = normalize(mul(v.normal, unity_WorldToObject).xyz);
 66                 o.worldTangent = normalize(mul(unity_ObjectToWorld, v.tangent).xyz);
 67                 o.worldBinormal = normalize(cross(o.worldNormal, o.worldTangent) * v.tangent.w);
 68                 o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
 69                 o.shadowCoord = TransformWorldToShadowCoord(o.worldPos);
 70                 return o;
 71             }
 72 
 73             half4 frag(v2f i) : SV_TARGET
 74             {
 75                 // get info
 76                 float3 worldNormal = normalize(i.worldNormal);
 77                 float3 worldTangent = normalize(i.worldTangent);
 78                 float3 worldBinormal = normalize(i.worldBinormal);
 79                 float3 worldPos = i.worldPos;
 80 
 81                 // sample texture
 82                 half4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, i.uv);
 83                 half4 normalMap = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, i.uv);
 84                 half3 normalData = UnpackNormal(normalMap);
 85 
 86                 // 法线
 87                 float3x3 matrixTNB = float3x3(worldTangent, worldBinormal, worldNormal);
 88                 float3 normal = mul(normalData, matrixTNB);
 89 
 90                 // 主光源光照计算
 91                 float4 shadowCoord = i.shadowCoord;
 92                 float3 worldView = GetWorldSpaceNormalizeViewDir(worldPos);
 93                 half3 finalLightCol = half3(0, 0, 0);
 94                 {
 95                     Light mainLight = GetMainLight(shadowCoord);
 96                     // diffuse
 97                     float NdotL = dot(normal, mainLight.direction);
 98                     NdotL = saturate(NdotL * 0.5 + 0.5);
 99                     half3 diffuse = baseMap.rgb * mainLight.color * NdotL
100                                     * mainLight.shadowAttenuation * mainLight.distanceAttenuation;
101 
102                     // specular
103                     float3 halfVL = normalize(mainLight.direction + worldView);
104                     float NdotH = saturate(dot(normal, halfVL));
105                     half3 specular = baseMap.rgb * mainLight.color * pow(NdotH, _SpecGloss)
106                                     * mainLight.shadowAttenuation * mainLight.distanceAttenuation;
107 
108                     finalLightCol = diffuse + specular;
109                 }
110 
111                 // 其它光源光照计算
112                 #if defined(_ADDITIONAL_LIGHTS)
113                 uint addLightCount = GetAdditionalLightsCount();
114                 for(uint lightIndex = 0;lightIndex < addLightCount;++lightIndex)
115                 {
116                     Light addLight = GetAdditionalLight(lightIndex, worldPos, shadowCoord);
117 
118                     // diffuse
119                     float NdotL = dot(normal, addLight.direction);
120                     NdotL = saturate(NdotL * 0.5 + 0.5);
121                     half3 diffuse = baseMap.rgb * addLight.color * NdotL
122                                      * addLight.shadowAttenuation * addLight.distanceAttenuation;
123 
124                     // specular
125                     float3 halfVL = normalize(addLight.direction + worldView);
126                     float NdotH = saturate(dot(normal, halfVL));
127                     half3 specular = baseMap.rgb * addLight.color * pow(NdotH, _SpecGloss)
128                                     * addLight.shadowAttenuation * addLight.distanceAttenuation;
129 
130                     finalLightCol += (diffuse + specular);
131                 }
132                 #endif
133 
134                 half4 col = half4(finalLightCol, 1);
135                 return col;
136             }
137 
138             ENDHLSL
139         }
140 
141         Pass
142         {
143             Name "ShadowCaster"
144             Tags{"LightMode" = "ShadowCaster"}
145 
146             ZWrite On
147             ZTest LEqual
148             ColorMask 0
149             Cull[_Cull]
150 
151             HLSLPROGRAM
152             #pragma exclude_renderers gles gles3 glcore
153             #pragma target 4.5
154 
155             // -------------------------------------
156             // Material Keywords
157             #pragma shader_feature_local_fragment _ALPHATEST_ON
158             #pragma shader_feature_local_fragment _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
159 
160             //--------------------------------------
161             // GPU Instancing
162             #pragma multi_compile_instancing
163             #pragma multi_compile _ DOTS_INSTANCING_ON
164 
165             // -------------------------------------
166             // Universal Pipeline keywords
167 
168             // This is used during shadow map generation to differentiate between directional and punctual light shadows, as they use different formulas to apply Normal Bias
169             #pragma multi_compile_vertex _ _CASTING_PUNCTUAL_LIGHT_SHADOW
170 
171             #pragma vertex ShadowPassVertex
172             #pragma fragment ShadowPassFragment
173 
174             #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl"
175             #include "Packages/com.unity.render-pipelines.universal/Shaders/ShadowCasterPass.hlsl"
176             ENDHLSL
177         }
178     }
179 
180     FallBack "Hidden/Universal Render Pipeline/FallbackError"
181 }

效果如下:

转载请注明出处:https://www.cnblogs.com/jietian331/p/17019270.html

posted @ 2023-01-01 23:31  孤独の巡礼  阅读(366)  评论(0编辑  收藏  举报