From d2c4c385df2594a5d4369f2af2f6a7b5d66bdd8c Mon Sep 17 00:00:00 2001 From: quou Date: Sun, 5 Jan 2025 17:57:08 +1100 Subject: basic pbr --- intermediate/surface.glsl | 66 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'intermediate/surface.glsl') diff --git a/intermediate/surface.glsl b/intermediate/surface.glsl index 0f55016..2d5d470 100644 --- a/intermediate/surface.glsl +++ b/intermediate/surface.glsl @@ -27,9 +27,6 @@ type: vec2 name: position type: vec4 [interpolator] -name: normal -type: vec3 -[interpolator] name: tbn type: mat3 @@ -56,6 +53,9 @@ type: float [variable] name: ao type: float +[variable] +name: camera_pos +type: vec3 [cbuffer] name: c_mvp @@ -101,7 +101,6 @@ void main() { vec3 t = normalize((c_mvp.model * vec4(tangent, 0.0)).xyz); vec3 n = normalize((c_mvp.model * vec4(normal, 0.0)).xyz); vec3 b = cross(t, n); - interpolator.normal = n; interpolator.tbn = mat3(t, b, n); interpolator.uv = uv; interpolator.position = pos; @@ -113,23 +112,62 @@ void main() { #ifdef FRAGMENT_SHADER +#define pi 3.14159265358979323846 + +vec3 diffuse_brdf(vec2 uv) { + vec3 a = material.albedo * texture(albedo, uv).rgb; + return a / pi; +} + +float specular_G1(float a, vec3 v, vec3 n) { + float ndv = max(dot(n, v), 0.0); + float a1 = a + 1.0; + float k = (a1 * a1) / 8.0; + return ndv / (ndv * (1.0 - k) + k); +} + +float specular_brdf(vec2 uv, vec3 l, vec3 v, vec3 n) { + float ndl = max(dot(n, l), 0.0); + float ndv = max(dot(n, v), 0.0); + vec3 ref = reflect(-l, n); + float a = texture(rough, uv).r * material.roughness; + float a2 = a * a; + float ndr = max(dot(n, ref), 0.0); + float b = ((ndr * ndr) * (a2 - 1) + 1); + float D = + a2 / (pi * b * b); + float G = specular_G1(a, l, n) * specular_G1(a, v, n); + float F0 = G; + float F = F0 + (1.0 - F0) * + pow(2, ((-5.55473 * ndr - 6.98316), ndr)); + return (D * F * G) / (4.0 * ndl * ndv); +} + void main() { vec2 uv = interpolator.uv; + vec3 p = interpolator.position.xyz; vec3 nrmsample = texture(normal, uv).rgb; - vec2 nrmxy = nrmsample.xy * 2.0 - 1.0; vec3 nrm = normalize(vec3(nrmxy, 1.0)); if (nrmsample.b == 1.0) /* default texture */ - nrm = vec3(0, 0, 1); - nrm = normalize(interpolator.tbn * nrm); - - float light = max(dot(nrm, vec3(0, 0, 1)), 0.0); - - vec3 ambient = 0.05.xxx * texture(ao, uv).r; - vec3 col = ambient + light * material.albedo; - col *= texture(albedo, uv).rgb; - colour = vec4(col, 1.0); + nrm = normalize(interpolator.tbn[2]); + else + nrm = normalize(interpolator.tbn * nrm); + + vec3 light_dir = vec3(0, 0, 1); + vec3 col = texture(albedo, uv).rgb * material.albedo; + float cos_theta_i = max(dot(nrm, light_dir), 0.0); + vec3 view_dir = normalize(material.camera_pos - p); + + vec3 diffuse = + diffuse_brdf(uv) * + cos_theta_i; + float spec = + specular_brdf(uv, light_dir, view_dir, nrm) * + cos_theta_i; + + colour = vec4(diffuse + vec3(spec), 1.0); } #endif -- cgit v1.2.3-54-g00ecf