forked from BilalY/Rasagar
117 lines
4.9 KiB
HLSL
117 lines
4.9 KiB
HLSL
#ifndef WATER_LIGHTING_INCLUDED
|
|
#define WATER_LIGHTING_INCLUDED
|
|
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
|
|
|
#define SHADOW_ITERATIONS 4
|
|
|
|
half CalculateFresnelTerm(half3 normalWS, half3 viewDirectionWS)
|
|
{
|
|
return saturate(pow(1.0 - dot(normalWS, viewDirectionWS), 5));//fresnel TODO - find a better place
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Lighting Calculations //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//diffuse
|
|
half4 VertexLightingAndFog(half3 normalWS, half3 posWS, half3 clipPos)
|
|
{
|
|
half3 vertexLight = VertexLighting(posWS, normalWS);
|
|
half fogFactor = ComputeFogFactor(clipPos.z);
|
|
return half4(fogFactor, vertexLight);
|
|
}
|
|
|
|
//specular
|
|
half3 Highlights(half3 positionWS, half roughness, half3 normalWS, half3 viewDirectionWS)
|
|
{
|
|
Light mainLight = GetMainLight();
|
|
|
|
half roughness2 = roughness * roughness;
|
|
half3 halfDir = SafeNormalize(mainLight.direction + viewDirectionWS);
|
|
half NoH = saturate(dot(normalize(normalWS), halfDir));
|
|
half LoH = saturate(dot(mainLight.direction, halfDir));
|
|
// GGX Distribution multiplied by combined approximation of Visibility and Fresnel
|
|
// See "Optimizing PBR for Mobile" from Siggraph 2015 moving mobile graphics course
|
|
// https://community.arm.com/events/1155
|
|
half d = NoH * NoH * (roughness2 - 1.h) + 1.0001h;
|
|
half LoH2 = LoH * LoH;
|
|
half specularTerm = roughness2 / ((d * d) * max(0.1h, LoH2) * (roughness + 0.5h) * 4);
|
|
// on mobiles (where half actually means something) denominator have risk of overflow
|
|
// clamp below was added specifically to "fix" that, but dx compiler (we convert bytecode to metal/gles)
|
|
// sees that specularTerm have only non-negative terms, so it skips max(0,..) in clamp (leaving only min(100,...))
|
|
#if defined (SHADER_API_MOBILE)
|
|
specularTerm = specularTerm - HALF_MIN;
|
|
specularTerm = clamp(specularTerm, 0.0, 5.0); // Prevent FP16 overflow on mobiles
|
|
#endif
|
|
return specularTerm * mainLight.color * mainLight.distanceAttenuation;
|
|
}
|
|
|
|
//Soft Shadows
|
|
half SoftShadows(float3 screenUV, float3 positionWS, half3 viewDir, half depth)
|
|
{
|
|
#if _MAIN_LIGHT_SHADOWS
|
|
half2 jitterUV = screenUV.xy * _ScreenParams.xy * _DitherPattern_TexelSize.xy;
|
|
half shadowAttenuation = 0;
|
|
|
|
float loopDiv = 1.0 / SHADOW_ITERATIONS;
|
|
half depthFrac = depth * loopDiv;
|
|
half3 lightOffset = -viewDir * depthFrac;
|
|
for (uint i = 0u; i < SHADOW_ITERATIONS; ++i)
|
|
{
|
|
#ifndef _STATIC_WATER
|
|
jitterUV += frac(half2(_Time.x, -_Time.z));
|
|
#endif
|
|
float3 jitterTexture = SAMPLE_TEXTURE2D(_DitherPattern, sampler_DitherPattern, jitterUV + i * _ScreenParams.xy).xyz * 2 - 1;
|
|
half3 j = jitterTexture.xzy * depthFrac * i * 0.1;
|
|
float3 lightJitter = (positionWS + j) + (lightOffset * (i + jitterTexture.y));
|
|
shadowAttenuation += SAMPLE_TEXTURE2D_SHADOW(_MainLightShadowmapTexture, sampler_MainLightShadowmapTexture, TransformWorldToShadowCoord(lightJitter));
|
|
}
|
|
//custom-begin:
|
|
float4 shadowCoord = TransformWorldToShadowCoord(positionWS);
|
|
bool beyondFar = BEYOND_SHADOW_FAR(shadowCoord);
|
|
half shadowFade = GetShadowFade(positionWS);
|
|
#if defined(_MAIN_LIGHT_SHADOWS_CASCADE)
|
|
shadowFade = shadowCoord.w == 4 ? 1.0h : shadowFade;
|
|
#endif
|
|
return beyondFar ? 1.0 : lerp(shadowAttenuation * loopDiv, 1, shadowFade);
|
|
//custom-end:
|
|
#else
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Reflection Modes //
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
half3 SampleReflections(half3 normalWS, half3 viewDirectionWS, half2 screenUV, half roughness)
|
|
{
|
|
half3 reflection = 0;
|
|
half2 refOffset = 0;
|
|
|
|
#if _REFLECTION_CUBEMAP
|
|
half3 reflectVector = reflect(-viewDirectionWS, normalWS);
|
|
reflection = SAMPLE_TEXTURECUBE(_CubemapTexture, sampler_CubemapTexture, reflectVector).rgb;
|
|
#elif _REFLECTION_PROBES
|
|
half3 reflectVector = reflect(-viewDirectionWS, normalWS);
|
|
reflection = GlossyEnvironmentReflection(reflectVector, 0, 1);
|
|
#elif _REFLECTION_PLANARREFLECTION
|
|
|
|
// get the perspective projection
|
|
float2 p11_22 = float2(unity_CameraInvProjection._11, unity_CameraInvProjection._22) * 10;
|
|
// conver the uvs into view space by "undoing" projection
|
|
float3 viewDir = -(float3((screenUV * 2 - 1) / p11_22, -1));
|
|
|
|
half3 viewNormal = mul(normalWS, (float3x3)GetWorldToViewMatrix()).xyz;
|
|
half3 reflectVector = reflect(-viewDir, viewNormal);
|
|
|
|
half2 reflectionUV = screenUV + normalWS.zx * half2(0.02, 0.15);
|
|
reflection += SAMPLE_TEXTURE2D_LOD(_PlanarReflectionTexture, sampler_ScreenTextures_linear_clamp, reflectionUV, 6 * roughness).rgb;//planar reflection
|
|
#endif
|
|
//do backup
|
|
//return reflectVector.yyy;
|
|
return reflection;
|
|
}
|
|
|
|
#endif // WATER_LIGHTING_INCLUDED |