Files
bluflame/hgplus/obliterator/C/lighting.hlsl
2026-04-18 22:31:51 +02:00

80 lines
2.2 KiB
HLSL

#ifndef LIGHTING
#define LIGHTING
#include "utils.hlsl"
float ggx(float dotNH, float roughness) {
float r2 = roughness*roughness;
float r4 = r2*r2;
float dotNH2 = dotNH * dotNH;
float d = abs(dotNH2 * r4 - dotNH2 + 1);
return r4 / (PI*d*d + 0.00000001);
}
float geometricShadowing(float dotNV, float dotNL, float roughness) {
float r = roughness + 1;
float k = r*r / 8;
float ik = 1 - k;
return 1 / (4 * (dotNV * ik + k) * (dotNL * ik + k));
}
float fresnel(float dotNV, float f0) {
float p = (-5.55473 * dotNV - 6.98316) * dotNV;
return f0 + (1 - f0) * exp2(p);
}
float transmittance(float3 i, float3 n, float eta1, float eta2) {
float eta = eta1 / eta2;
float cosI = -dot(n, i);
float sinT2 = eta * eta * (1.0 - cosI * cosI);
if (sinT2 > 1.0) return 1.0;
float cosT = sqrt(1.0 - sinT2);
float rOrth = (eta1 * cosI - eta2 * cosT) / (eta1 * cosI + eta2 * cosT);
float rPar = (eta2 * cosI - eta1 * cosT) / (eta2 * cosI + eta1 * cosT);
return 1.0 - (rOrth * rOrth + rPar * rPar) / 2.0;
}
float brdfSpecular(float dotNV,float dotNL,float dotNH,float dotVH,float roughness, float f0) {
return ggx(dotNH, roughness) *
fresnel(dotNV, f0) *
geometricShadowing(dotNV, dotNL, roughness);
}
float brdfLambert() {
return 1/PI;
}
// n, v, l: assumed to be normalized
float3 brdf(float3 n, float3 v, float3 l,
float3 albedo, float3 specular,
float roughness, float f0) {
roughness = clamp(roughness, 0.05, 1.0);
//roughness = 0.4;
float3 h = normalize(v + l);
float dotNV = max(0, dot(n, v));
float dotNL = max(0, dot(n, l));
float dotNH = max(0, dot(n, h));
float dotVH = max(0, dot(v, h));
float3 color =
albedo * brdfLambert() +
specular* brdfSpecular(dotNV, dotNL, dotNH, dotVH, roughness, f0);
color *= dotNL;
return color;
}
float3 brdfSphereLight(float3 p, float3 n, float3 v,
float3 reflected, float3 lightPosition, float lightRadius,
float3 albedo, float3 specular, float roughness, float f0) {
float3 toLightCenter = lightPosition - p;
float3 centerToRay = toLightCenter - dot(toLightCenter, reflected) * reflected;
float3 closestPoint = toLightCenter - centerToRay * saturate(lightRadius / length(centerToRay));
float3 l = normalize(closestPoint);
return brdf(n, v, l, albedo, specular, roughness, f0);
}
#endif