80 lines
2.2 KiB
HLSL
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 |