Files
Seele/res/shaders/WaterPass.slang
T
2024-08-28 17:54:14 +02:00

121 lines
5.6 KiB
Plaintext

import Common;
import WaterCommon;
float SchlickFresnel(float3 normal, float3 viewDir) {
// 0.02f comes from the reflectivity bias of water kinda idk it's from a paper somewhere i'm not gonna link it tho lmaooo
return 0.02f + (1 - 0.02f) * (pow(1 - clamp(dot(normal, viewDir), 0, 1), 5.0f));
}
float SmithMaskingBeckmann(float3 H, float3 S, float roughness) {
float hdots = max(0.001f, clamp(dot(H, S), 0, 1));
float a = hdots / (roughness * sqrt(1 - hdots * hdots));
float a2 = a * a;
return a < 1.6f ? (1.0f - 1.259f * a + 0.396f * a2) / (3.535f * a + 2.181 * a2) : 0.0f;
}
float Beckmann(float ndoth, float roughness) {
float exp_arg = (ndoth * ndoth - 1) / (roughness * roughness * ndoth * ndoth);
return exp(exp_arg) / (PI * roughness * roughness * ndoth * ndoth * ndoth * ndoth);
}
[shader("pixel")]
float4 fragmentMain(WaterVertex vert) : SV_TARGET {
float3 lightDir = -normalize(pWaterMaterial.sunDirection);
float3 viewDir = normalize(pViewParams.cameraPos_WS.xyz - vert.position_WS);
float3 halfwayDir = normalize(lightDir + viewDir);
float depth = vert.depth;
float LdotH = clamp(dot(lightDir, halfwayDir), 0, 1);
float VdotH = clamp(dot(viewDir, halfwayDir), 0, 1);
float4 displacementFoam1 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile1, 0));
displacementFoam1.a += pWaterMaterial.foamSubtract0;
float4 displacementFoam2 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile2, 0));
displacementFoam2.a += pWaterMaterial.foamSubtract1;
float4 displacementFoam3 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile3, 0));
displacementFoam3.a += pWaterMaterial.foamSubtract2;
float4 displacementFoam4 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile4, 0));
displacementFoam4.a += pWaterMaterial.foamSubtract3;
float4 displacementFoam = displacementFoam1 + displacementFoam2 + displacementFoam3 + displacementFoam4;
float2 slopes1 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile1, 0));
float2 slopes2 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile2, 1));
float2 slopes3 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile3, 2));
float2 slopes4 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile4, 3));
float2 slopes = slopes1 + slopes2 + slopes3 + slopes4;
slopes *= pWaterMaterial.normalStrength;
float foam = lerp(0.0f, saturate(displacementFoam.a), pow(depth, pWaterMaterial.foamDepthAttenuation));
float3 macroNormal = float3(0, 1, 0);
float3 mesoNormal = normalize(float3(-slopes.x, 1.0f, -slopes.y));
mesoNormal = normalize(lerp(macroNormal, mesoNormal, pow(saturate(depth), pWaterMaterial.normalDepthAttenuation)));
mesoNormal = normalize(mesoNormal);
float NdotL = clamp(dot(mesoNormal, lightDir), 0, 1);
float a = pWaterMaterial.roughness + foam * pWaterMaterial.foamRoughnessModifier;
float ndoth = max(0.0001f, dot(mesoNormal, halfwayDir));
float viewMask = SmithMaskingBeckmann(halfwayDir, viewDir, a);
float lightMask = SmithMaskingBeckmann(halfwayDir, lightDir, a);
float G = rcp(1 + viewMask + lightMask);
float eta = 1.33f;
float R = ((eta - 1) * (eta - 1)) / ((eta + 1) * (eta + 1));
float thetaV = acos(viewDir.y);
float numerator = pow(1 - dot(mesoNormal, viewDir), 5 * exp(-2.69 * a));
float F = R + (1 - R) * numerator / (1.0f + 22.7f * pow(a, 1.5f));
F = saturate(F);
float3 specular = pWaterMaterial.sunIrradiance * F * G * Beckmann(ndoth, a);
specular /= 4.0f * max(0.001f, clamp(dot(macroNormal, lightDir), 0, 1));
specular *= clamp(dot(mesoNormal, lightDir), 0, 1);
float3 envReflection = pWaterMaterial.environmentMap.Sample(pWaterMaterial.sampler, reflect(-viewDir, mesoNormal)).rgb;
envReflection *= pWaterMaterial.environmentLightStrength;
float H = max(0.0f, displacementFoam.y) * pWaterMaterial.heightModifier;
float3 scatterColor = pWaterMaterial.scatterColor;
float3 bubbleColor = pWaterMaterial.bubbleColor;
float bubbleDensity = pWaterMaterial.bubbleDensity;
float k1 = pWaterMaterial.wavePeakScatterStrength * H * pow(clamp(dot(lightDir, -viewDir), 0, 1), 4.0f) * pow(0.5f - 0.5f * dot(lightDir, mesoNormal), 3.0f);
float k2 = pWaterMaterial.scatterStrength * pow(clamp(dot(viewDir, mesoNormal), 0, 1), 2.0f);
float k3 = pWaterMaterial.scatterShadowStrength * NdotL;
float k4 = bubbleDensity;
float3 scatter = (k1 + k2) * scatterColor * pWaterMaterial.sunIrradiance * rcp(1 + lightMask);
scatter += k3 * scatterColor * pWaterMaterial.sunIrradiance + k4 * bubbleColor * pWaterMaterial.sunIrradiance;
float3 output = (1 - F) * scatter + specular + F * envReflection;
output = max(0.0f, output);
output = lerp(output, pWaterMaterial.foamColor, saturate(foam));
return float4(output, 1);
//if(vert.lod == 1)
//{
// return float4(1, 0, 0, 1.0f);
//}
//if(vert.lod == 2)
//{
// return float4(0, 1, 0, 1.0f);
//}
//if(vert.lod == 3)
//{
// return float4(0, 0, 1, 1.0f);
//}
//if(vert.lod == 4)
//{
// return float4(1, 1, 1, 1.0f);
//}
//return float4(0, 0, 0, 1);
}