#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