163 lines
5.9 KiB
HLSL
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
|
|
|