#ifndef UTS_SURFACE_FEATURE_EVALUATION #define UTS_SURFACE_FEATURE_EVALUATION void UtsEvaluateLighting_Stocking(FragInputs input, PositionInputs posInput, PreLightData preLightData, float3 N, float3 V, inout AggregateLighting aggregateLighting) { float fresnel = pow(preLightData.NdotV, _StockingFresnelWidth); #if _STOCKING_SPARKING_MAP float viewAngleFactor = saturate(1.0 - preLightData.NdotV); float2 shiftedNDC = posInput.positionNDC.xy + viewAngleFactor * 0.05; float spacing = (1.0 - posInput.linearDepth) * _StockingSparkleSpacing; // NOTE: Should we use sparkle texture instead of Voronoi? float screenSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleAmount), 1, 1.0 - Voronoi(shiftedNDC * _ScreenParams.xy / spacing, 5, 5.0)); float objectSparkle = smoothstep(1.0 - (0.5 * _StockingSparkleSize), 1, 1.0 - Voronoi(input.texCoord0, 5, 100.0)); float sparkle = objectSparkle * screenSparkle * _StockingSparkleIntensity * 5; aggregateLighting.direct.specular += sparkle * aggregateLighting.direct.specular; #endif aggregateLighting.direct.diffuse *= fresnel; } DirectLighting UtsEvaluateLighting_RimLight(PositionInputs posInput, UtsBSDFData bsdfData, PreLightData preLightData #if _LIGHT_BASE_RIM_LIGHT_ON , float3 L, float3 lightColor #endif ) { DirectLighting lighting; ZERO_INITIALIZE(DirectLighting, lighting); float3 rimLightColor = _RimLightColor.rgb * _RimLightIntensity; rimLightColor = lerp(rimLightColor, rimLightColor * bsdfData.diffuseColor.rgb, _AlbedoAffectRimLight * _RimLightColor.a); #if _SCREEN_SPACE_RIM_LIGHT_ON float3 normalVS = normalize(mul((float3x3)UNITY_MATRIX_V, bsdfData.geomNormalWS)); float2 depthUV = posInput.positionNDC.xy + normalVS.xy * (_RimLightLevel * 0.05 / posInput.linearDepth); float offsetedDepth = SampleCameraDepth(depthUV); float depthDiff = saturate(posInput.deviceDepth - offsetedDepth); float rimLightMask = step(0.0025 / posInput.linearDepth, depthDiff); #else float clampNdotV = ClampNdotV(preLightData.NdotV); float rimLightMask = pow(1.0 - clampNdotV, exp2(lerp(3.0, 0.0, _RimLightLevel))); rimLightMask = lerp(rimLightMask, step(_RimLightClippingLevel, rimLightMask), _RimLightClipping); #endif #if _LIGHT_BASE_RIM_LIGHT_ON float halfLambert = 0.5 * dot(bsdfData.normalWS, L) + 0.5; float lightBaseMask = saturate(smoothstep(_LightDirectionRimLightLevel, 1.0, halfLambert)); rimLightMask *= lightBaseMask; rimLightColor *= lightColor; #endif lighting.diffuse = rimLightMask * rimLightColor; return lighting; } DirectLighting UtsEvaluateLighting_AngelRing(FragInputs input, float3 N, float3 V) { DirectLighting lighting; ZERO_INITIALIZE(DirectLighting, lighting); // Should we scroll the angel ring texture on x? float3 cameraRight = UNITY_MATRIX_V[0].xyz; float3 cameraFront = UNITY_MATRIX_V[2].xyz; float3 upVector = float3(0, 1, 0); float3 rightAxis = cross(cameraFront, upVector); float cameraRightMagnitude = sqrt(cameraRight.x * cameraRight.x + cameraRight.y * cameraRight.y + cameraRight.z * cameraRight.z); float rightAxisMagnitude = sqrt(rightAxis.x * rightAxis.x + rightAxis.y * rightAxis.y + rightAxis.z * rightAxis.z); float cameraRollCos = dot(rightAxis, cameraRight) / (rightAxisMagnitude * cameraRightMagnitude); float3 cameraRoll = acos(clamp(cameraRollCos, -1.0, 1.0)); float cameraDir = cameraRight.y < 0 ? -1.0 : 1.0; float2 arOffsetU = lerp(mul(UNITY_MATRIX_V, float4(N, 0)).xyz, float3(0, 0, 1), _AngelRingOffsetU).xy; arOffsetU = arOffsetU * 0.5 + 0.5; float2 arvnRotate = RotateUV(arOffsetU, -(cameraDir * cameraRoll).x, 0.5, 1.0); float2 arOffsetUV = float2(arvnRotate.x, lerp(input.texCoord0.y, arvnRotate.y, _AngelRingOffsetV)); float4 angelRingColor = SAMPLE_TEXTURE2D(_AngelRingColorMap, sampler_AngelRingColorMap, TRANSFORM_TEX(arOffsetUV, _AngelRingColorMap)) * _AngelRingColor * _AngelRingIntensity; float weight = saturate(dot(V, N)); lighting.specular = angelRingColor * angelRingColor.a * weight; return lighting; } #endif