Advertisement
noradninja

VertexLightmapCommon.cginc

Feb 27th, 2025
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.62 KB | None | 0 0
  1. #include "UnityCG.cginc"
  2. #include "HLSLSupport.cginc"
  3. #include "UnityShaderVariables.cginc"
  4. #include "UnityShaderUtilities.cginc"
  5. #include "AutoLight.cginc"
  6. #include "Lighting.cginc"
  7. #include "UnityShadowLibrary.cginc"
  8.  
  9. #include "UnityStandardConfig.cginc"
  10. #include "UnityPBSLighting.cginc"
  11. #include "UnityStandardUtils.cginc"
  12. #include "UnityGBuffer.cginc"
  13. #include "UnityStandardBRDF.cginc"
  14.  
  15. #define USING_FOG (defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2))
  16. // ES2.0 can not do loops with non-constant-expression iteration counts :(
  17. #if defined(SHADER_API_GLES)
  18.     #define LIGHT_LOOP_LIMIT 8.0h
  19. #else
  20.     #define LIGHT_LOOP_LIMIT unity_VertexLightParams.x
  21. #endif
  22.  
  23. // uniforms
  24. int4 unity_VertexLightParams; // x: light count, y: zero, z: one (needed for d3d9)
  25. sampler2D _MainTex;
  26. sampler2D _MOAR;
  27. half4 _MainTex_ST;
  28. half _Cutoff;
  29. half4 _wind_dir;
  30. half _wind_size;
  31. half _leaves_wiggle_disp;
  32. half _leaves_wiggle_speed;
  33. half _influence;
  34. half _LeavesOn;
  35. half _AlphaOn;
  36. uniform half _Metallic;
  37. uniform half _Roughness;
  38.  
  39. half3 computeOneLight(int idx, half3 eyePosition, half3 eyeNormal)
  40. {
  41.     half3 dirToLight = unity_LightPosition[idx].xyz;
  42.     half att = 1.5h; //we tweak attenuation on the light to more closely match the attenuation from pixel lights
  43.     #if defined(POINT) || defined(SPOT)
  44.         dirToLight -= eyePosition * unity_LightPosition[idx].w;
  45.         // distance attenuation
  46.         half distSqr = dot(dirToLight, dirToLight);
  47.         att /= (1.0h + unity_LightAtten[idx].z * distSqr);
  48.         if (unity_LightPosition[idx].w != 0.0h &&
  49.             distSqr > unity_LightAtten[idx].w)
  50.             att = 0.0h; // light is out of range
  51.         dirToLight *= rsqrt(distSqr);
  52.        
  53.         #if defined(SPOT)
  54.             // spot angle attenuation
  55.             half rho = max(dot(dirToLight, unity_SpotDirection[idx].xyz), 0.0h);
  56.             half spotAtt = (rho - unity_LightAtten[idx].x) * unity_LightAtten[idx].y;
  57.             att *= saturate(spotAtt);
  58.         #endif
  59.     #endif
  60.  
  61.     // Diffuse contribution: scale by (1 - metal)
  62.     const half NdotL = max(dot(eyeNormal, dirToLight), 0.0h);
  63.     const half3 diffuse = (1.0h - _Metallic) * att * NdotL * unity_LightColor[idx].rgb;
  64.  
  65.     // --- GGX Specular Contribution ---
  66.     half3 V = normalize(-eyePosition);       // view vector in eye-space
  67.     half3 H = normalize(V + dirToLight);       // half vector between view and light
  68.  
  69.     half NdotV = max(dot(eyeNormal, V), 0.0h);
  70.     half NdotH = max(dot(eyeNormal, H), 0.0h);
  71.     half VdotH = max(dot(V, H), 0.0h);
  72.  
  73.     half r = _Roughness;
  74.     half a2 = r * r; // squared roughness
  75.  
  76.     // GGX Normal Distribution Function (D)
  77.     half denom = (NdotH * NdotH * (a2 - 1.0h) + 1.0h);
  78.     denom = 3.14159h * denom * denom;
  79.     half D = a2 / max(denom, 0.001h);
  80.  
  81.     // Geometry term (G) using Schlick-GGX approximation
  82.     half k = (r + 1.0h) * (r + 1.0h) / 8.0h;
  83.     half G_L = NdotL / (NdotL * (1.0h - k) + k);
  84.     half G_V = NdotV / (NdotV * (1.0h - k) + k);
  85.     half G = G_L * G_V;
  86.  
  87.     // Fresnel term (F) using Schlick's approximation
  88.     half F0 = lerp(0.04h, 0.9h, _Metallic);
  89.     half F = F0 + (1.0h - F0) * pow(1.0h - VdotH, 5.0h);
  90.  
  91.     // Combine specular term (division by 4*NdotL*NdotV)
  92.     half specNumerator = D * F * G;
  93.     half specDenom = max(4.0h * NdotL * NdotV, 0.001h);
  94.     half specularTerm = specNumerator / specDenom;
  95.     half3 specular = att * specularTerm * unity_LightColor[idx].rgb;
  96.  
  97.     return min(diffuse + specular, 1.0);
  98. }
  99.  
  100. // Vertex input structure
  101. struct appdata {
  102.     half3 pos : POSITION;
  103.     half3 normal : NORMAL;
  104.     half4 color : COLOR0;
  105.     half3 uv0 : TEXCOORD0;
  106.     half3 uv1 : TEXCOORD1;
  107. };
  108.  
  109. // Vertex-to-fragment interpolators
  110. struct v2f {
  111.     half4 pos : SV_POSITION;
  112.     half2 uv0 : TEXCOORD0;
  113.     half2 uv1 : TEXCOORD1;
  114.     half4 screenPosition : TEXCOORD2;
  115.     half4 color : COLOR;
  116.     half3 worldRefl : TEXCOORD3;
  117.    
  118.     #if USING_FOG
  119.         UNITY_FOG_COORDS(4)
  120.     #endif
  121.     SHADOW_COORDS(5)
  122. };
  123.  
  124. // Main vertex shader: computes vertex lighting and shadow data
  125. v2f vert(appdata v) {
  126.     v2f o;
  127.     UNITY_INITIALIZE_OUTPUT(v2f, o);
  128.  
  129.     half3 worldPos = mul(unity_ObjectToWorld, half4(v.pos, 1.0h)).xyz;
  130.     const half3 eyePos = mul(UNITY_MATRIX_MV, half4(v.pos, 1.0h)).xyz;
  131.     const half3 eyeNormal = normalize(mul((half3x3)UNITY_MATRIX_IT_MV, v.normal).xyz);
  132.     const half dotProduct = 1 - saturate(dot(v.normal, eyeNormal));
  133.     half4 lightColor = half4(0,0,0,1);
  134.    
  135. #if defined(AMBIENT_ON) || !defined(CUSTOM_LIGHTMAPPED)
  136.         lightColor.rgb = glstate_lightmodel_ambient.rgb;
  137.     #endif
  138.     for (int il = 0; il < LIGHT_LOOP_LIMIT; ++il)
  139.         lightColor.rgb += computeOneLight(il, eyePos, eyeNormal);
  140.     lightColor.rgb += smoothstep(0.0h, 1.0h, dotProduct) * 0.15h;
  141.     o.color = saturate(lightColor);
  142.        
  143.     o.uv0 = v.uv0.xy * _MainTex_ST.xy + _MainTex_ST.zw;
  144.     #if defined(CUSTOM_LIGHTMAPPED)
  145.         o.uv1 = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
  146.     #endif
  147.     o.pos = UnityObjectToClipPos(v.pos);
  148.     o.screenPosition = ComputeScreenPos(o.pos);
  149.  
  150.     float3 worldViewDir = normalize(UnityWorldSpaceViewDir(worldPos));
  151.     float3 worldNormal = UnityObjectToWorldNormal(v.normal);
  152.     o.worldRefl = reflect(-worldViewDir, worldNormal);
  153.    
  154.     UNITY_TRANSFER_FOG(o, o.pos);
  155.     TRANSFER_SHADOW(o);
  156.     return o;
  157. }
  158.  
  159. // Main fragment shader
  160. fixed4 frag(v2f v) : SV_Target {
  161.     const half4 posLighting = v.color;
  162.     UNITY_EXTRACT_FOG(v);
  163.     #if defined(CUSTOM_LIGHTMAPPED)
  164.         const half4 lightmap = UNITY_SAMPLE_TEX2D(unity_Lightmap, v.uv1.xy);
  165.         #if CUSTOM_LIGHTMAPPED == 1
  166.             const half4 lighting = half4(lightmap.rgb * 0.25h, 1) + posLighting;
  167.         #endif
  168.     #else
  169.         const half4 lighting = posLighting;
  170.     #endif
  171.     // Compute shadow attenuation (this value is used in the shadow receiver pass)
  172.     fixed shadow = SHADOW_ATTENUATION(v);
  173.     const half4 diffuse = tex2D(_MainTex, v.uv0.xy);
  174.     const half4 moar = tex2D(_MOAR, v.uv0.xy);
  175.     half4 skyData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, v.worldRefl, (1 - moar.a) * 8);
  176.     half3 skyColor = DecodeHDR(skyData, unity_SpecCube0_HDR);
  177.     half3 diff = lerp(diffuse.rgb, skyColor, moar.r) * shadow;
  178.     half4 col = half4((diff.rgb * lighting.rgb) + (skyColor * 0.25h) * moar.g, 1);
  179.  
  180.     if (!_AlphaOn) {
  181.         fixed4 texcol = tex2D(_MainTex, v.uv0.xy);
  182.         clip(texcol.a - _Cutoff);
  183.     } else {
  184.         fixed4 texcol = tex2D(_MOAR, v.uv0.xy);
  185.         clip(texcol.b - _Cutoff);
  186.     }
  187.     #if USING_FOG
  188.         UNITY_APPLY_FOG(v.fogCoord, col);
  189.     #endif
  190.     return col;
  191. }
  192.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement