import "structs"; static const float INV_PI = 0.31830987; static const float HALF_INV_PI = 0.15915494; static const float3 F90 = float3(1.0); float4 texture2DAA(Texture2D texture, SamplerState sampler, float2 texCoord) { uint width, height; texture.GetDimensions(width, height); let size = float2(width, height); var texCoordPX = texCoord * size; let seam = floor(texCoordPX + 0.5); texCoordPX = (texCoordPX - seam) / fwidth(texCoordPX) + seam; texCoordPX = clamp(texCoordPX, seam - 0.5, seam + 0.5); texCoord = texCoordPX / size; return texture.Sample(sampler, texCoord); } float3 fresnelSchlick(float dotVH, float3 f0) { return lerp(f0, F90, pow(1.0 - dotVH, 5.0)); } float visibilityGGX(float dotNL, float dotNV, float alpha) { let alphaSquared = alpha * alpha; let vGGX = dotNL * sqrt(dotNV * dotNV * (1.0 - alphaSquared) + alphaSquared); let lGGX = dotNV * sqrt(dotNL * dotNL * (1.0 - alphaSquared) + alphaSquared); let GGX = vGGX + lGGX; return select(GGX > 0.0, 0.5 / GGX, 0.0); } float distributionGGX(float dotNH, float alpha) { let alphaSquared = alpha * alpha; let tmp = dotNH * dotNH * (alphaSquared - 1.0) + 1.0; return alphaSquared * INV_PI / (tmp * tmp); } float3 lightOutgoingRadiance( float3 viewDirectionVS, float3 normalVS, float dotNV, Surface surf, IncomingLight light, ) { let halfVectorVS = normalize(light.directionVS + viewDirectionVS); let dotVH = saturate(dot(viewDirectionVS, halfVectorVS)); let dotNH = saturate(dot(normalVS, halfVectorVS)); let dotNL = saturate(dot(normalVS, light.directionVS)); let fresnel = fresnelSchlick(dotVH, surf.f0); let visibility = visibilityGGX(dotNL, dotNV, surf.alpha); let distribution = distributionGGX(dotNH, surf.alpha); let scatteredFactor = (1.0 - fresnel) * (1.0 - surf.metallic) * surf.baseColor * INV_PI; let reflectedFactor = fresnel * visibility * distribution; return (scatteredFactor + reflectedFactor) * light.radiance * dotNL; } float3 toneMapAcesNarkowicz(float3 color) { static const float A = 2.51; static const float B = 0.03; static const float C = 2.43; static const float D = 0.59; static const float E = 0.14; return saturate((color * (A * color + B)) / (color * (C * color + D) + E)); } float3 linearToSrgbColor(float3 color) { return pow(color, 1.0 / 2.2); } float boxSDF(float2 p, float2 center, float2 halfExtents, float borderRadius) { let q = abs(p - center) - halfExtents + borderRadius; return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - borderRadius; }