123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // NOTE: Based on URP Lighting.hlsl which replaced some half3 with floats to avoid lighting artifacts on mobile
- #ifndef LIGHTWEIGHT_FUZZLIGHTING_INCLUDED
- #define LIGHTWEIGHT_FUZZHLIGHTING_INCLUDED
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
- #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
- #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
- real Fuzz(real NdotV, real fuzzPower, real fuzzBias)
- {
- return exp2( (1.0h - NdotV) * fuzzPower - fuzzPower) + fuzzBias;
- }
- real WrappedDiffuse(real NdotL, real3 normalWS, real3 lightDirectionWS, real wrap)
- {
- return saturate( (dot(normalWS, lightDirectionWS) + wrap) * rcp( (1.0h + wrap) * (1.0h + wrap) ) );
- }
- // ---------
- struct AdditionalData {
- half fuzzWrap;
- half fuzz;
- };
- half3 DirectBDRF_LuxFuzz(BRDFData brdfData, half3 normalWS, half3 lightDirectionWS, half3 viewDirectionWS, half NdotL)
- {
- // Regular Code
- #ifndef _SPECULARHIGHLIGHTS_OFF
- float3 halfDir = SafeNormalize(lightDirectionWS + viewDirectionWS);
- float NoH = saturate(dot(normalWS, halfDir));
- half LoH = saturate(dot(lightDirectionWS, halfDir));
- // Standard specular lighting
- float d = NoH * NoH * brdfData.roughness2MinusOne + 1.00001f;
- half LoH2 = LoH * LoH;
- half specularTerm = brdfData.roughness2 / ((d * d) * max(0.1h, LoH2) * brdfData.normalizationTerm);
- #if defined (SHADER_API_MOBILE) || defined (SHADER_API_SWITCH)
- specularTerm = specularTerm - HALF_MIN;
- specularTerm = clamp(specularTerm, 0.0, 100.0); // Prevent FP16 overflow on mobiles
- #endif
- return specularTerm * brdfData.specular + brdfData.diffuse;
- #else
- return brdfData.diffuse;
- #endif
- }
- half3 LightingPhysicallyBased_LuxFuzz(BRDFData brdfData,
- #if defined(_SIMPLEFUZZ)
- AdditionalData addData,
- #endif
- half3 lightColor, half3 lightDirectionWS, half lightAttenuation, half3 normalWS, half3 viewDirectionWS, half NdotL)
- {
- half3 radiance = lightColor * (lightAttenuation * NdotL);
- #if defined(_SIMPLEFUZZ)
- half wrappedNdotL = WrappedDiffuse(NdotL, normalWS, lightDirectionWS, addData.fuzzWrap);
- #endif
- return DirectBDRF_LuxFuzz(brdfData, normalWS, lightDirectionWS, viewDirectionWS, NdotL) * radiance
- #if defined(_SIMPLEFUZZ)
- + (addData.fuzz * brdfData.diffuse) * lightColor * (lightAttenuation * wrappedNdotL )
- #endif
- ;
- }
- half3 LightingPhysicallyBased_LuxFuzz(BRDFData brdfData,
- #if defined(_SIMPLEFUZZ)
- AdditionalData addData,
- #endif
- Light light, half3 normalWS, half3 viewDirectionWS, half NdotL)
- {
- return LightingPhysicallyBased_LuxFuzz(brdfData,
- #if defined(_SIMPLEFUZZ)
- addData,
- #endif
- light.color, light.direction, light.distanceAttenuation * light.shadowAttenuation, normalWS, viewDirectionWS, NdotL);
- }
- half4 LuxURPSimpleFuzzFragmentPBR(InputData inputData, half3 albedo, half metallic, half3 specular,
- half smoothness, half occlusion, half3 emission, half alpha, half4 translucency, half fuzzMask, half fuzzPower, half fuzzBias, half fuzzWrap, half fuzzStrength, half fuzzAmbient)
- {
-
- BRDFData brdfData;
- InitializeBRDFData(albedo, metallic, specular, smoothness, alpha, brdfData);
- // ShadowMask: To ensure backward compatibility we have to avoid using shadowMask input, as it is not present in older shaders
- #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
- half4 shadowMask = inputData.shadowMask;
- #elif !defined (LIGHTMAP_ON)
- half4 shadowMask = unity_ProbesOcclusion;
- #else
- half4 shadowMask = half4(1, 1, 1, 1);
- #endif
- //Light mainLight = GetMainLight(inputData.shadowCoord);
- Light mainLight = GetMainLight(inputData.shadowCoord, inputData.positionWS, shadowMask);
- half3 mainLightColor = mainLight.color;
- // SSAO
- #if defined(_SCREEN_SPACE_OCCLUSION)
- AmbientOcclusionFactor aoFactor = GetScreenSpaceAmbientOcclusion(inputData.normalizedScreenSpaceUV);
- mainLight.color *= aoFactor.directAmbientOcclusion;
- occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
- #endif
- MixRealtimeAndBakedGI(mainLight, inputData.normalWS, inputData.bakedGI, half4(0, 0, 0, 0));
- half NdotL = saturate(dot(inputData.normalWS, mainLight.direction ));
- #if defined(_SIMPLEFUZZ)
- AdditionalData addData;
- addData.fuzzWrap = fuzzWrap;
- // We tweak the diffuse to get some ambient fuzz lighting as well.
- half NdotV = saturate(dot(inputData.normalWS, inputData.viewDirectionWS ));
- addData.fuzz = Fuzz(NdotV, fuzzPower, fuzzBias);
- addData.fuzz *= fuzzMask * fuzzStrength;
- half3 diffuse = brdfData.diffuse;
- brdfData.diffuse *= 1.0h + addData.fuzz * fuzzAmbient;
- #endif
- half3 color = GlobalIllumination(brdfData, inputData.bakedGI, occlusion, inputData.normalWS, inputData.viewDirectionWS);
- #if defined(_SIMPLEFUZZ)
- // Reset diffuse as we want to use WrappedNdotL lighting.
- brdfData.diffuse = diffuse;
- #endif
-
- color += LightingPhysicallyBased_LuxFuzz(brdfData,
- #if defined(_SIMPLEFUZZ)
- addData,
- #endif
- mainLight, inputData.normalWS, inputData.viewDirectionWS, NdotL);
- // translucency
- #if defined(_SCATTERING)
- half transPower = translucency.y;
- half3 transLightDir = mainLight.direction + inputData.normalWS * translucency.w;
- half transDot = dot( transLightDir, -inputData.viewDirectionWS );
- transDot = exp2(saturate(transDot) * transPower - transPower);
- color += brdfData.diffuse * transDot * (1.0h - NdotL) * mainLightColor * lerp(1.0h, mainLight.shadowAttenuation, translucency.z) * translucency.x * 4;
- #endif
- #ifdef _ADDITIONAL_LIGHTS
- uint pixelLightCount = GetAdditionalLightsCount();
- for (uint i = 0u; i < pixelLightCount; ++i)
- {
- // Light light = GetAdditionalPerObjectLight(index, positionWS); // here; shadowAttenuation = 1.0;
- // URP 10: We have to use the new GetAdditionalLight function
- Light light = GetAdditionalLight(i, inputData.positionWS, shadowMask);
- half3 lightColor = light.color;
- #if defined(_SCREEN_SPACE_OCCLUSION)
- light.color *= aoFactor.directAmbientOcclusion;
- #endif
- NdotL = saturate(dot(inputData.normalWS, light.direction ));
- color += LightingPhysicallyBased_LuxFuzz(brdfData,
- #if defined(_SIMPLEFUZZ)
- addData,
- #endif
- light, inputData.normalWS, inputData.viewDirectionWS, NdotL);
- // translucency
- #if defined(_SCATTERING)
- transPower = translucency.y;
- transLightDir = light.direction + inputData.normalWS * translucency.w;
- transDot = dot( transLightDir, -inputData.viewDirectionWS );
- transDot = exp2(saturate(transDot) * transPower - transPower);
- color += brdfData.diffuse * transDot * (1.0h - NdotL) * lightColor * lerp(1.0h, light.shadowAttenuation, translucency.z) * light.distanceAttenuation * translucency.x * 4;
- #endif
- }
- #endif
- #ifdef _ADDITIONAL_LIGHTS_VERTEX
- color += inputData.vertexLighting * brdfData.diffuse;
- #endif
- //color += emission;
- return half4(color, alpha);
- }
- #endif
|