123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- #if !defined(SHADERGRAPH_PREVIEW) || ( defined(LIGHTWEIGHT_LIGHTING_INCLUDED) || defined(UNIVERSAL_LIGHTING_INCLUDED) )
- // As we do not have access to the vertex lights we will make the shader always sample add lights per pixel
- #if defined(_ADDITIONAL_LIGHTS_VERTEX)
- #undef _ADDITIONAL_LIGHTS_VERTEX
- #define _ADDITIONAL_LIGHTS
- #endif
- #if(RECEIVE_SHADOWS_OFF)
- #define _RECEIVE_SHADOWS_OFF
- #endif
- #if defined(LIGHTWEIGHT_LIGHTING_INCLUDED) || defined(UNIVERSAL_LIGHTING_INCLUDED)
- half3 LightingSpecular_Toon (Light light, half lightingRemap, half3 normalWS, half3 viewDirectionWS, half3 specular, half specularSmoothness, half smoothness, half specularStep, half specularUpper, bool energyConservation){
- float3 halfVec = SafeNormalize( float3(light.direction) + float3(viewDirectionWS));
- half NdotH = saturate(dot(normalWS, halfVec));
- half modifier = pow(NdotH /* lightingRemap*/, specularSmoothness);
- // Normalization? Na, we just multiply by smoothness in the return statement.
- // #define ONEOVERTWOPI 0.159155h
- // half normalization = (specularSmoothness + 1) * ONEOVERTWOPI;
- // Sharpen
- half modifierSharpened = smoothstep(specularStep, specularUpper, modifier);
- half toonNormalization = (energyConservation) ? smoothness : 1;
- return light.color * specular * modifierSharpened * toonNormalization; // * smoothness;
- }
- half3 LightingSpecularAniso_Toon (Light light, half NdotL, half3 normalWS, half3 viewDirectionWS, half3 tangentWS, half3 bitangentWS, half anisotropy, half3 specular, half specularSmoothness, half smoothness, half specularStep, half specularUpper, bool energyConservation){
- // This does not let us fade from isotropic to anisotropic...
- // half3 H = SafeNormalize(light.direction + viewDirectionWS);
- // half3 T = cross(normalWS, tangent);
- // T = lerp(tangent, bitangent, (anisotropy + 1) * 0.5);
- // float TdotH = dot(T, H);
- // float sinTHSq = saturate(1.0 - TdotH * TdotH);
- // float exponent = RoughnessToBlinnPhongSpecularExponent_Lux(1 - smoothness);
- // float modifier = dirAttn * pow(sinTHSq, 0.5 * exponent);
- // float norm = smoothness; //(exponent + 2) * rcp(2 * PI);
- // // Sharpen
- // half modifierSharpened = smoothstep(specularStep, specularUpper, modifier);
- // half toonNormalization = (energyConservation == 1.0h) ? norm : 1;
- // return light.color * specular * modifierSharpened * toonNormalization;
- // ///////////////////////////////
- //
- // GGX "like" distribution in order to be able to fade from isotropic to anisotropic
- // We skip visbility here as it is toon lighting.
- // NOTE: Further normalization does not help here to fixe the final shape...
- float3 H = SafeNormalize(float3(light.direction) + float3(viewDirectionWS));
- // TdotH and BdotH should be unclamped here
- float TdotH = dot(tangentWS, H);
- float BdotH = dot(bitangentWS, H);
- float NdotH = dot(normalWS, H);
- float roughness = 1.0f - smoothness;
-
- // roughness^2 would be correct here - but in order to get it a bit closer to our blinn phong isotropic specular we go with ^4 instead
- roughness *= roughness * roughness * roughness;
- float at = roughness * (1.0f + anisotropy);
- float ab = roughness * (1.0f - anisotropy);
-
- float a2 = at * ab;
- float3 v = float3(ab * TdotH, at * BdotH, a2 * NdotH);
-
- float v2 = dot(v, v);
- float w2 = a2 / v2;
- half res = half(a2 * w2 * w2 * (1.0f / PI));
- // Sharpen
- half modifierSharpened = smoothstep(specularStep, specularUpper, res);
- half toonNormalization = (energyConservation == 1.0h) ? smoothness : 1.0h;
- return light.color * specular * modifierSharpened * toonNormalization;
- }
- #endif
- half aaStep(half compValue, half gradient, half softness){
- half change = fwidth(gradient) * softness;
- // Base the range of the inverse lerp on the change over two pixels
- half lowerEdge = compValue - change;
- half upperEdge = compValue + change;
- // Do the inverse interpolation
- half stepped = (gradient - lowerEdge) / (upperEdge - lowerEdge);
- stepped = saturate(stepped);
- return stepped;
- }
- #endif
- void Lighting_half(
- // Base inputs
- float3 positionWS,
- half3 viewDirectionWS,
- // Normal inputs
- half3 normalWS,
- half3 tangentWS,
- half3 bitangentWS,
- half3 normalTS,
- // Surface description
- half3 albedo,
- half3 shadedAlbedo,
- half anisotropy,
- bool energyConservation,
- half3 specular,
- half smoothness,
- half occlusion,
- // Smoothsteps
- half steps,
- half diffuseStep,
- half diffuseFalloff,
- half specularStep,
- half specularFalloff,
- half shadowFalloff,
- half shadowBiasDirectional,
- half shadowBiasAdditional,
- // Colorize shaded parts
- half colorizeMainLight,
- half colorizeAddLights,
- half lightColorContribution,
- half addLightFalloff,
- // Rim Lighting
- half rimPower,
- half rimFalloff,
- half4 rimColor,
- half rimAttenuation,
- // Lightmapping
- float2 lightMapUV,
- // Ramp
- Texture2D GradientMap,
- float GradientWidth,
- SamplerState sampler_Linear,
- SamplerState sampler_Point,
- bool receiveSSAO,
- // Final lit color
- out half3 Lighting,
- out half3 MetaAlbedo,
- out half3 MetaSpecular
- )
- {
- #if defined(SHADERGRAPH_PREVIEW) || ( !defined(LIGHTWEIGHT_LIGHTING_INCLUDED) && !defined(UNIVERSAL_LIGHTING_INCLUDED) )
- Lighting = albedo;
- MetaAlbedo = half3(0,0,0);
- MetaSpecular = half3(0,0,0);
- #else
- // Real Lighting ----------
- half3 tnormal = normalWS;
- // Normal mapping
- #if defined(NORMAL_ON)
- tnormal = TransformTangentToWorld(normalTS, half3x3(tangentWS.xyz, bitangentWS.xyz, normalWS.xyz));
- #endif
- // Not normalized normals cause uggly specular highlights on mobile. So we always normalize.
- #if defined(SPECULAR_ON)
- normalWS = normalize(tnormal);
- #else
- normalWS = NormalizeNormalPerPixel(tnormal);
- #endif
- normalWS = NormalizeNormalPerPixel(tnormal);
- viewDirectionWS = SafeNormalize(viewDirectionWS);
- // Remap values - old version
- //half diffuseUpper = saturate(diffuseStep + diffuseFalloff);
- float4 clipPos = TransformWorldToHClip(positionWS);
- // Get Shadow Sampling Coords / Unfortunately per pixel...
- #if SHADOWS_SCREEN
- float4 shadowCoord = ComputeScreenPos(clipPos);
- #else
- float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
- #endif
- // Shadow mask
- #if defined(SHADOWS_SHADOWMASK) && defined(LIGHTMAP_ON)
- half4 shadowMask = SAMPLE_SHADOWMASK(lightMapUV);
- #elif !defined (LIGHTMAP_ON)
- half4 shadowMask = unity_ProbesOcclusion;
- #else
- half4 shadowMask = half4(1, 1, 1, 1);
- #endif
- //Light mainLight = GetMainLight(shadowCoord);
- Light mainLight = GetMainLight(shadowCoord, positionWS, shadowMask);
- // SSAO
- #if defined(_SCREEN_SPACE_OCCLUSION)
- AmbientOcclusionFactor aoFactor;
- aoFactor.indirectAmbientOcclusion = 1;
- aoFactor.directAmbientOcclusion = 1;
- if(receiveSSAO) {
- float4 ndc = clipPos * 0.5f;
- float2 normalized = float2(ndc.x, ndc.y * _ProjectionParams.x) + ndc.w;
- normalized /= clipPos.w;
- normalized *= _ScreenParams.xy;
- // We could also use IN.Screenpos(default) --> ( IN.Screenpos.xy * _ScreenParams.xy)
- // HDRP 10.1
- normalized = GetNormalizedScreenSpaceUV(normalized);
- aoFactor = GetScreenSpaceAmbientOcclusion(normalized);
- mainLight.color *= aoFactor.directAmbientOcclusion;
- occlusion = min(occlusion, aoFactor.indirectAmbientOcclusion);
- //occlusion = smoothstep(diffuseStep, diffuseUpper, occlusion);
- }
- #endif
- // GI Lighting
- half3 bakedGI = 0;
- #ifdef LIGHTMAP_ON
- lightMapUV = lightMapUV * unity_LightmapST.xy + unity_LightmapST.zw;
- bakedGI = SAMPLE_GI(lightMapUV, half3(0,0,0), normalWS);
- #else
- UNITY_BRANCH if(occlusion > 0) {
- bakedGI = SampleSH(normalWS) * occlusion;
- }
- #endif
- //mainLight.shadowAttenuation = smoothstep(0.0h, shadowFalloff, mainLight.shadowAttenuation);
- mainLight.shadowAttenuation = smoothstep( (1 - shadowFalloff) * shadowFalloff, shadowFalloff, mainLight.shadowAttenuation);
- MixRealtimeAndBakedGI(mainLight, normalWS, bakedGI, half4(0, 0, 0, 0));
- // Set up Lighting
- half lightIntensity = 0;
- half3 specularLighting = 0;
- half3 rimLighting = 0;
- half3 lightColor = 0;
- half luminance;
- // Adjust tangent and reconstruct bitangent in case anisotropic specular is active as otherwise normal mapping has no effect
- #if defined(ANISO_ON) && defined(SPECULAR_ON)
- #if defined(NORMAL_ON)
- tangentWS = Orthonormalize(tangentWS, normalWS);
- #endif
- bitangentWS = cross(normalWS, tangentWS);
- #endif
-
- // Main Light
- // Old version
- //half NdotL = saturate(dot(normalWS, mainLight.direction));
- //NdotL = smoothstep(diffuseStep, diffuseUpper, NdotL);
- // New version which lets you use wrapped around diffuse lighting and shift away shadowed areas if gradient are disabled
- //
- // Remap old diffuseStep and diffuseFalloff in order to match new function
- diffuseStep = diffuseStep + 1.0h;
- diffuseFalloff = diffuseFalloff * 4.0h + 1.0h;
- half NdotL = dot(normalWS, mainLight.direction);
- NdotL = saturate((NdotL + 1.0h) - diffuseStep);
-
- #if !defined(GRADIENT_ON)
- // We have to use steps - 1 here!
- half oneOverSteps = 1.0h / steps;
- half quantizedNdotL = floor(NdotL * steps);
- // IMPORTANT: no saturate on the 2nd param: NdotL - 0.01. 0.01 is eyballed.
- NdotL = (quantizedNdotL + aaStep(saturate(quantizedNdotL * oneOverSteps), NdotL - 0.01h, diffuseFalloff )) * oneOverSteps;
- #else
- #if defined(SMOOTHGRADIENT_ON)
- NdotL = SAMPLE_TEXTURE2D(GradientMap, sampler_Linear, float2 (NdotL, 0.5f)).r;
- #else
- float oneOverTexelWidth = rcp(GradientWidth);
- half NdotL0 = SAMPLE_TEXTURE2D(GradientMap, sampler_Point, float2 (NdotL, 0.5f)).r ;
- half NdotL1 = SAMPLE_TEXTURE2D(GradientMap, sampler_Point, float2 (NdotL + fwidth(NdotL) * oneOverTexelWidth, 0.5f)).r;
- NdotL = (NdotL0 + NdotL1) * 0.5h;
- #endif
- #endif
- half atten = NdotL * mainLight.distanceAttenuation * saturate(shadowBiasDirectional + mainLight.shadowAttenuation);
- mainLight.color = lerp(Luminance(mainLight.color).xxx, mainLight.color, lightColorContribution.xxx);
- // if (colorizeMainLight) {
- // lightColor = mainLight.color * mainLight.distanceAttenuation;
- // }
- // else {
- // lightColor = mainLight.color * atten;
- // }
- lightColor = mainLight.color * lerp(atten, mainLight.distanceAttenuation, colorizeMainLight);
- luminance = Luminance(mainLight.color);
- lightIntensity += luminance * atten;
- // Specular
- half specularSmoothness;
- half3 spec;
- half specularUpper;
-
- #if defined(SPECULAR_ON)
- specularSmoothness = exp2(10 * smoothness + 1);
- specularUpper = saturate(specularStep + specularFalloff * (1.0h + smoothness));
- #if defined(ANISO_ON)
- spec = LightingSpecularAniso_Toon (mainLight, NdotL, normalWS, viewDirectionWS, tangentWS, bitangentWS, anisotropy, specular, specularSmoothness, smoothness, specularStep, specularUpper, energyConservation);
- #else
- spec = LightingSpecular_Toon(mainLight, NdotL, normalWS, viewDirectionWS, specular, specularSmoothness, smoothness, specularStep, specularUpper, energyConservation);
- #endif
- specularLighting = spec * atten;
- #endif
-
- // Rim Lighting
- #if defined(RIM_ON)
- half rim = saturate(1.0h - saturate( dot(normalWS, viewDirectionWS)) );
- //rimLighting = smoothstep(rimPower, rimPower + rimFalloff, rim) * rimColor.rgb;
- // Stabilize rim
- float delta = fwidth(rim);
- rimLighting = smoothstep(rimPower - delta, rimPower + rimFalloff + delta, rim) * rimColor.rgb;
- #endif
-
- // Handle additional lights
- #ifdef _ADDITIONAL_LIGHTS
- uint pixelLightCount = GetAdditionalLightsCount();
- for (uint i = 0u; i < pixelLightCount; ++i) {
- Light light = GetAdditionalLight(i, positionWS);
- #if defined(_SCREEN_SPACE_OCCLUSION)
- if(receiveSSAO) {
- light.color *= aoFactor.directAmbientOcclusion;
- }
- #endif
- light.shadowAttenuation = smoothstep(0.0h, shadowFalloff, light.shadowAttenuation);
- NdotL = dot(normalWS, light.direction);
- NdotL = saturate((NdotL + 1.0h) - diffuseStep);
- #if !defined(GRADIENT_ON)
- half quantizedNdotL = floor(NdotL * steps);
- // IMPORTANT: no saturate on the 2nd param: NdotL - 0.01. 0.01 is eyballed.
- NdotL = (quantizedNdotL + aaStep(saturate(quantizedNdotL * oneOverSteps), NdotL - 0.01h, diffuseFalloff )) * oneOverSteps;
- #else
- #if defined(SMOOTHGRADIENT_ON)
- NdotL = SAMPLE_TEXTURE2D(GradientMap, sampler_Linear, float2 (NdotL, 0.5f)).r;
- #else
- NdotL0 = SAMPLE_TEXTURE2D(GradientMap, sampler_Point, float2 (NdotL, 0.5f)).r;
- NdotL1 = SAMPLE_TEXTURE2D(GradientMap, sampler_Point, float2 (NdotL + fwidth(NdotL) * oneOverTexelWidth, 0.5f)).r;
- NdotL = (NdotL0 + NdotL1) * 0.5h;
- #endif
- #endif
- half distanceAttenuation = (addLightFalloff < 1.0h) ? saturate(light.distanceAttenuation / addLightFalloff) : light.distanceAttenuation;
- atten = NdotL * distanceAttenuation * saturate(shadowBiasAdditional + light.shadowAttenuation);
- light.color = lerp(Luminance(light.color).xxx, light.color, lightColorContribution.xxx);
- // if(colorizeAddLights) {
- // lightColor += light.color * light.distanceAttenuation;
- // }
- // else {
- // lightColor += light.color * atten;
- // }
- lightColor += light.color * lerp(atten, distanceAttenuation, colorizeAddLights);
- luminance = Luminance(light.color);
- lightIntensity += luminance * atten;
- //if (enableSpecular) {
- #if defined(SPECULAR_ON)
- #if defined(ANISO_ON)
- spec = LightingSpecularAniso_Toon (light, NdotL, normalWS, viewDirectionWS, tangentWS, bitangentWS, anisotropy, specular, specularSmoothness, smoothness, specularStep, specularUpper, energyConservation);
- #else
- spec = LightingSpecular_Toon(light, NdotL, normalWS, viewDirectionWS, specular, specularSmoothness, smoothness, specularStep, specularUpper, energyConservation);
- #endif
- specularLighting += spec * atten;
- #endif
- //}
- }
- #endif
- // Combine Lighting
- half3 litAlbedo = lerp(shadedAlbedo, albedo, saturate(lightIntensity.xxx));
- Lighting =
- // ambient diffuse lighting
- bakedGI * albedo
- // direct diffuse lighting
- + ( litAlbedo
- // spec and rim lighting
- #if defined(SPECULAR_ON)
- + specularLighting * lightIntensity
- #endif
- #if defined(RIM_ON)
- + rimLighting * lerp(1.0h, lightIntensity, rimAttenuation)
- #endif
- ) * lightColor
- ;
- // Set Albedo for meta pass
- #if defined(LIGHTWEIGHT_META_PASS_INCLUDED) || defined(UNIVERSAL_META_PASS_INCLUDED)
- Lighting = half3(0,0,0);
- MetaAlbedo = albedo;
- MetaSpecular = half3(0.02,0.02,0.02);
- #else
- MetaAlbedo = half3(0,0,0);
- MetaSpecular = half3(0,0,0);
- #endif
- // End Real Lighting ----------
- #endif
- }
- // Unity 2019.1. needs a float version
- void Lighting_float(
- // Base inputs
- float3 positionWS,
- half3 viewDirectionWS,
- // Normal inputs
- half3 normalWS,
- half3 tangentWS,
- half3 bitangentWS,
- half3 normalTS,
- // Surface description
- half3 albedo,
- half3 shadedAlbedo,
- half anisotropy,
- bool energyConservation,
- half3 specular,
- half smoothness,
- half occlusion,
- // Smoothsteps
- half steps,
- half diffuseStep,
- half diffuseFalloff,
- half specularStep,
- half specularFalloff,
- half shadowFalloff,
- half shadowBiasDirectional,
- half shadowBiasAdditional,
- // Colorize shaded parts
- half colorizeMainLight,
- half colorizeAddLights,
- half lightColorContribution,
- half addLightFalloff,
- // Rim Lighting
- half rimPower,
- half rimFalloff,
- half4 rimColor,
- half rimAttenuation,
- // Lightmapping
- float2 lightMapUV,
- // Ramp
- Texture2D GradientMap,
- float GradientWidth,
- SamplerState sampler_Linear,
- SamplerState sampler_Point,
- bool receiveSSAO,
- // Final lit color
- out half3 Lighting,
- out half3 MetaAlbedo,
- out half3 MetaSpecular
- )
- {
- Lighting_half(
- positionWS, viewDirectionWS, normalWS, tangentWS, bitangentWS, normalTS,
- albedo, shadedAlbedo, anisotropy, energyConservation, specular, smoothness, occlusion,
- steps, diffuseStep, diffuseFalloff, specularStep, specularFalloff, shadowFalloff, shadowBiasDirectional, shadowBiasAdditional,
- colorizeMainLight, colorizeAddLights, lightColorContribution, addLightFalloff,
- rimPower, rimFalloff, rimColor, rimAttenuation,
- lightMapUV,
- GradientMap, GradientWidth, sampler_Linear, sampler_Point,
- receiveSSAO,
- Lighting, MetaAlbedo, MetaSpecular
- );
- }
|