Files

78 lines
2.6 KiB
Plaintext

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;
}