summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-05 17:57:08 +1100
committerquou <quou@disroot.org>2025-01-05 17:57:08 +1100
commitd2c4c385df2594a5d4369f2af2f6a7b5d66bdd8c (patch)
treeed0ee1316cfdf783c05dbd245990807332ed0a46
parent12173bbc77b233997afcc96dede9b292babc7911 (diff)
basic pbr
-rw-r--r--c2.cpp10
-rw-r--r--intermediate/bricks.mat2
-rw-r--r--intermediate/plastic.mat2
-rw-r--r--intermediate/surface.glsl66
-rw-r--r--model.cpp7
5 files changed, 65 insertions, 22 deletions
diff --git a/c2.cpp b/c2.cpp
index 32a0d41..b19c238 100644
--- a/c2.cpp
+++ b/c2.cpp
@@ -429,19 +429,19 @@ extern "C" int entrypoint() {
monkey->transform = m4f::translate(
m4f::identity(),
v3f(0.0f, 0.0f, 0.0f)
- )/* * m4f::rotate(
+ ) * m4f::rotate(
m4f::identity(),
rot,
raxis
- )*/;
+ );
monkey2->transform = m4f::translate(
m4f::identity(),
v3f(2.0f, 0.0f, 2.0f)
- )/* * m4f::rotate(
+ ) * m4f::rotate(
m4f::identity(),
rot * 2.0f,
v3f(1.0f, 0.0f, 0.0f)
- )*/;
+ );
camera.asp = (float)bb.w / (float)bb.h;
camera.update(*app);
scene.update(camera, dev);
@@ -469,7 +469,7 @@ extern "C" int entrypoint() {
ctx.debug_pop();
r += 10;
- rot += 5.0f * app->dt;
+ rot += 1.0f * app->dt;
frame++;
dev->present();
app->end();
diff --git a/intermediate/bricks.mat b/intermediate/bricks.mat
index 28bea24..1ed5535 100644
--- a/intermediate/bricks.mat
+++ b/intermediate/bricks.mat
@@ -1,6 +1,6 @@
[params]
metalness: 1.0
-roughness: 1.0
+roughness: 0.3
ao: 1.0
albedo: ffffff
diff --git a/intermediate/plastic.mat b/intermediate/plastic.mat
index ff71d8b..3d59385 100644
--- a/intermediate/plastic.mat
+++ b/intermediate/plastic.mat
@@ -1,6 +1,6 @@
[params]
metalness: 0.0
-roughness: 0.0
+roughness: 0.1
ao: 1.0
albedo: ff0000
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
diff --git a/model.cpp b/model.cpp
index 4c5edcc..778d945 100644
--- a/model.cpp
+++ b/model.cpp
@@ -20,7 +20,9 @@ struct Mat_Cbuffer {
float metalness;
float roughness;
float ao;
- char pad[40];
+ char pad2[8];
+ float camera_pos[3];
+ char pad[20];
};
void Material::use(
@@ -316,6 +318,9 @@ void Model_Instance::update_cbuffers(
mat.metalness = sm.metalness;
mat.roughness = sm.roughness;
mat.ao = sm.ao;
+ mat.camera_pos[0] = cam.position.x;
+ mat.camera_pos[1] = cam.position.y;
+ mat.camera_pos[2] = cam.position.z;
}
dev->unmap_buffer(mvp);
dev->unmap_buffer(mat);