78 lines
2.6 KiB
Plaintext
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;
|
|
}
|