Files
3d-fhsk/Assets/Artwork/MeiGongZiYuan/ShuiXiaoGuo/Water/Shaders/BGWaterLighting.hlsl
2026-03-05 10:28:05 +08:00

163 lines
5.9 KiB
HLSL

#ifndef BADDOG_WATER_LIGHTING
#define BADDOG_WATER_LIGHTING
float3 WaveNormal(BGWaterVertexOutput vertexOutput)
{
half3 waterNormal1 = tex2D(_MainWave, vertexOutput.mainWaveUV.xy).xyz;
half3 waterNormal2 = tex2D(_MainWave, vertexOutput.secondWaveUV.xy).xyz;
half3 waterNormal3 = tex2D(_SecondWave, vertexOutput.secondWaveUV.zw).xyz;
half3 waterNormal = ((waterNormal1 + waterNormal2) * 0.6667 - 0.6667) * half3(_SecondWaveBumpScale, _SecondWaveBumpScale, 1);
waterNormal3 = waterNormal3 * 2 - 1;
waterNormal += (waterNormal3 * half3(_MainWaveBumpScale, _MainWaveBumpScale, 1));
return normalize(TransformTangentToWorld(waterNormal, float3x3(vertexOutput.worldTangentDir.xyz, vertexOutput.worldBitangentDir.xyz, vertexOutput.worldNormalDir.xyz)));
}
BGLightingData PrepareLighting(BGWaterVertexOutput vertexOutput)
{
BGLightingData lightingData = (BGLightingData)0;
lightingData.worldPos = float3(vertexOutput.worldNormalDir.w, vertexOutput.worldTangentDir.w, vertexOutput.worldBitangentDir.w);
lightingData.worldNormal = WaveNormal(vertexOutput);
lightingData.worldLightDir = normalize(_MainLightPosition.xyz);
#if defined(_BGWATER_ORTHO_ON)
lightingData.worldViewDir = normalize(UNITY_MATRIX_V[2].xyz);
#else
lightingData.worldViewDir = normalize(_WorldSpaceCameraPos.xyz - lightingData.worldPos);
#endif
half3 H = normalize(lightingData.worldLightDir + lightingData.worldViewDir);
lightingData.NoL = saturate(dot(lightingData.worldLightDir, lightingData.worldNormal));
lightingData.NoV = saturate(dot(lightingData.worldNormal, lightingData.worldViewDir));
lightingData.NoH = saturate(dot(lightingData.worldNormal, H));
lightingData.LoH = saturate(dot(lightingData.worldLightDir, H));
lightingData.R = normalize(reflect(-lightingData.worldViewDir, lightingData.worldNormal));
lightingData.diffuseColor = _WaterBaseColor;
lightingData.specularColor = half3(0.04, 0.04, 0.04);
lightingData.lightColor = _MainLightColor.rgb;
lightingData.screenUV = vertexOutput.screenPos.xy / vertexOutput.screenPos.w;
#if defined(UNITY_SINGLE_PASS_STEREO)
lightingData.screenUV.xy = UnityStereoTransformScreenSpaceTex(lightingData.screenUV.xy);
#endif
return lightingData;
}
half3 IndirectDiffuse(BGLightingData lightingData)
{
return SampleSH(lightingData.worldNormal);
}
half3 Diffuse(BGLightingData lightingData)
{
return lightingData.lightColor * lightingData.NoL;
}
half3 Specular(BGLightingData lightingData)
{
float D = (-0.004) / (lightingData.NoH * lightingData.NoH - 1.005);
D *= D;
half x = 1 - lightingData.LoH;
half x2 = x * x;
half x5 = x2 * x2 * x;
float F = lightingData.specularColor + (1 - lightingData.specularColor) * x5;
return lightingData.lightColor * D * F * PI * _SpecularIntensity;
}
half3 IndirectSpecular(BGLightingData lightingData)
{
half3 probe = GlossyEnvironmentReflection(lightingData.R, 0, 1);
half fresnelTerm = 1.0 - saturate(dot(lightingData.worldNormal, lightingData.worldViewDir));
fresnelTerm *= fresnelTerm;
fresnelTerm *= fresnelTerm;
return probe.rgb * lerp(lightingData.specularColor, 1, fresnelTerm);
}
half4 GetSSRLighting(BGWaterVertexOutput vertexOutput, BGLightingData lightingData)
{
#if defined(_BGWATER_ORTHO_ON)
float3 uvz = GetSSRUVZOrtho(vertexOutput, lightingData);
#else
float3 uvz = GetSSRUVZ(vertexOutput, lightingData);
#endif
half3 ssrColor = lerp(half3(0, 0, 0), SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, uvz.xy) * _SSRIntensity, uvz.z > 0);
return half4(ssrColor, uvz.z);
}
half3 GetReflectionWithSSR(BGWaterVertexOutput vertexOutput, BGLightingData lightingData)
{
half3 indirectDiffuse = IndirectDiffuse(lightingData);
half3 diffuse = Diffuse(lightingData);
half3 specular = Specular(lightingData);
half3 indirectSpecular = IndirectSpecular(lightingData);
#if defined(_BGWATER_SSR_ON)
half4 ssrLighting = GetSSRLighting(vertexOutput, lightingData);
indirectSpecular = lerp(lerp(indirectSpecular, ssrLighting.rgb, ssrLighting.a), ssrLighting, ssrLighting.a > 0.99);
#endif
indirectSpecular *= _EnviromentIntensity;
return (indirectDiffuse + diffuse) * lightingData.diffuseColor + specular + indirectSpecular;
}
half4 GetRefraction(BGWaterVertexOutput vertexOutput, BGLightingData lightingData)
{
float2 screenUV = lightingData.screenUV;
float2 grabUV = screenUV;
half3 worldViewDir = normalize(lightingData.worldViewDir);
half worldViewDirY = abs(worldViewDir.y);
#if defined(_BGWATER_ORTHO_ON)
float depth = GetOrthoEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV));
#else
float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV), _ZBufferParams);
#endif
depth = depth - vertexOutput.screenPos.z;
half2 deltaUV = lightingData.worldNormal.xz * _WaterDistortScale * saturate(depth) * worldViewDirY / vertexOutput.screenPos.z;
#if defined(_BGWATER_ORTHO_ON)
float newDepth = GetOrthoEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV + deltaUV));
#else
float newDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV + deltaUV), _ZBufferParams);
#endif
newDepth = newDepth - vertexOutput.screenPos.z;
half signDepth = saturate(newDepth * 10);
grabUV = grabUV + deltaUV * signDepth;
depth = lerp(depth, newDepth, signDepth);
half viewMultiplier = (worldViewDirY + _WaterMuddyScale) * _WaterDepthOffset * _WaterDepthOffset;
depth *= viewMultiplier;
half alpha = saturate(1 - depth);
alpha = saturate(1.02 - pow(alpha, (dot(lightingData.worldNormal.xyz, worldViewDir) * 5 + 6)));
half4 refraction = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, grabUV);
refraction.rgb = lerp(refraction.rgb, refraction.rgb * _WaterMuddyColor * _WaterMuddyScale, alpha);
refraction.a = alpha;
return refraction;
}
#endif