summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-06-16 01:21:12 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-06-16 01:21:12 +1000
commit60d1e086242940993432a40a934241dc40b7382c (patch)
tree1f7a16dd4ad527d3c9f201f616d3f1490445009b
parentd52654dfdbe16345023fed4c61261dc4c66b96fe (diff)
uniform blocks working. fix spec highlight bug tomorrow
-rw-r--r--assets/shaders/pbr_params.frag71
-rw-r--r--assets/shaders/pbr_params.vert4
-rw-r--r--examples/pbr_params/ex_pbr_params.c34
-rw-r--r--src/maths/primitives.c11
-rw-r--r--src/renderer/backends/opengl/backend_opengl.c27
-rw-r--r--src/renderer/builtin_materials.h11
6 files changed, 89 insertions, 69 deletions
diff --git a/assets/shaders/pbr_params.frag b/assets/shaders/pbr_params.frag
index 88cbd0d..0833c2f 100644
--- a/assets/shaders/pbr_params.frag
+++ b/assets/shaders/pbr_params.frag
@@ -7,8 +7,8 @@ in vec3 fragNormal;
in vec2 fragTexCoords;
struct PointLight {
- vec3 position;
- vec3 color;
+ vec4 position;
+ vec4 color;
};
// --- Uniforms
@@ -22,8 +22,8 @@ uniform PBR_Params {
// Lights data
#define NUM_POINT_LIGHTS 4
uniform Scene_Lights {
- vec3 viewPos;
- // PointLight pointLights[NUM_POINT_LIGHTS];
+ PointLight pointLights[NUM_POINT_LIGHTS];
+ vec4 viewPos;
} scene;
const float PI = 3.14;
@@ -35,46 +35,51 @@ float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
void main() {
- vec3 norm = normalize(fragNormal);
- vec3 viewDir = normalize(scene.viewPos - fragWorldPos);
+ vec3 norm = normalize(fragNormal); // N
+ vec3 viewDir = normalize(vec3(scene.viewPos) - fragWorldPos); // V
vec3 F0 = vec3(0.04);
F0 = mix(F0, pbr.albedo, pbr.metallic);
vec3 Lo = vec3(0.0); // denoted L in the radiance equation
- // for (int i = 0; i < 4; i++) {
- // vec3 lightVec = normalize(scene.pointLights[i].position - fragWorldPos);
- // vec3 halfway = normalize(viewDir + lightVec);
- // float distance = length(scene.pointLights[i].position - fragWorldPos);
- // float attenuation = 1.0 / (distance * distance);
- // vec3 radiance = scene.pointLights[i].color * attenuation;
-
- // // cook-torrance brdf
- // float NDF = DistributionGGX(norm, halfway, pbr.roughness);
- // float G = GeometrySmith(norm, viewDir, lightVec, pbr.roughness);
- // vec3 F = fresnelSchlick(max(dot(halfway, viewDir), 0.0), F0);
-
- // vec3 kS = F;
- // vec3 kD = vec3(1.0) - kS;
- // kD *= 1.0 - pbr.metallic;
-
- // vec3 numerator = NDF * G * F;
- // float denominator = 4.0 * max(dot(norm, viewDir), 0.0) * max(dot(norm, lightVec), 0.0) + 0.0001;
- // vec3 specular = numerator / denominator;
-
- // // add to outgoing radiance Lo
- // float NdotL = max(dot(norm, lightVec), 0.0);
- // Lo += (kD * pbr.albedo / PI + specular) * radiance * NdotL;
- // }
+ for (int i = 0; i < 4; i++) {
+ vec3 lightVec = normalize(vec3(scene.pointLights[i].position) - fragWorldPos); // L
+ vec3 halfway = normalize(viewDir + lightVec); // H
+ float distance = length(vec3(scene.pointLights[i].position) - fragWorldPos);
+ float attenuation = 1.0 / (distance * distance);
+ vec3 radiance = vec3(scene.pointLights[i].color) * attenuation;
+
+ // cook-torrance brdf
+ float NDF = DistributionGGX(norm, halfway, pbr.roughness);
+ float G = GeometrySmith(norm, viewDir, lightVec, pbr.roughness);
+ vec3 F = fresnelSchlick(max(dot(halfway, viewDir), 0.0), F0);
+
+ vec3 numerator = NDF * G * F;
+ float denominator = 4.0 * max(dot(norm, viewDir), 0.0) * max(dot(norm, lightVec), 0.0) + 0.0001;
+ vec3 specular = numerator / denominator;
+
+ vec3 kS = F;
+
+ vec3 kD = vec3(1.0) - kS;
+ kD *= 1.0 - pbr.metallic;
+
+ // add to outgoing radiance Lo
+ float NdotL = max(dot(norm, lightVec), 0.0);
+ Lo += (kD * pbr.albedo / PI + specular) * radiance * NdotL;
+ // Lo += radiance;
+ }
vec3 ambient = vec3(0.03) * pbr.albedo * pbr.ao;
- vec3 color = ambient + Lo;
+ vec3 color = ambient + Lo; //ambient + Lo;
color = color / (color + vec3(1.0));
color = pow(color, vec3(1.0/2.2));
- FragColor = vec4(scene.viewPos, 1.0);
- // FragColor = vec4(1.0);
+ FragColor = vec4(color, 1.0);
+ // FragColor = vec4(scene.pointLights[0].position);
+ // FragColor = vec4(fragNormal, 1.0);
+ // FragColor = vec4(pbr.metallic, pbr.roughness, pbr.ao, 1.0);
+ // FragColor = scene.viewPos;
}
/* The below are from https://learnopengl.com/PBR/Lighting */
diff --git a/assets/shaders/pbr_params.vert b/assets/shaders/pbr_params.vert
index 01379d7..01d0cfe 100644
--- a/assets/shaders/pbr_params.vert
+++ b/assets/shaders/pbr_params.vert
@@ -19,8 +19,8 @@ layout(location = 2) out vec2 fragTexCoords;
void main() {
fragWorldPos = vec3(mvp.model * vec4(inPosition, 1.0));
- mat3 normalMatrix = transpose(inverse(mat3(mvp.model)));
- fragNormal = normalMatrix * inNormal;
+ fragNormal = mat3(transpose(inverse(mvp.model))) * inNormal;
+
fragTexCoords = inTexCoords;
gl_Position = mvp.proj * mvp.view * mvp.model * vec4(inPosition, 1.0);
diff --git a/examples/pbr_params/ex_pbr_params.c b/examples/pbr_params/ex_pbr_params.c
index e7b932f..18e0fc9 100644
--- a/examples/pbr_params/ex_pbr_params.c
+++ b/examples/pbr_params/ex_pbr_params.c
@@ -16,21 +16,21 @@
extern core g_core;
const vec3 pointlight_positions[4] = {
- { 10.0 / 5, 10.0 / 5, 10.0 / 5 },
- { -10.0 / 5, 10.0 / 5, 10.0 },
- { 10.0/ 5, -10.0 / 5, 10.0 },
- { -10.0 / 5, -10.0 / 5, 10.0 },
+ { 10.0 / 1., 10.0 / 1., 10.0 / 5 },
+ { -10.0 / 1., 10.0 / 1., 10.0 },
+ { 10.0 / 1., -10.0 / 1., 10.0 },
+ { -10.0 / 1., -10.0 / 1., 10.0 },
};
pbr_point_light point_lights[4];
// Lets define some constant PBR parameters here to test on one sphere with first
const rgba ALBEDO = RED_700;
-const f32 metallic = 1.0;
-const f32 roughness = 0.2;
-const f32 ao = 0.2;
+const f32 metallic = 0.7;
+const f32 roughness = 0.8;
+const f32 ao = 1.0;
const pbr_params_material_uniforms pbr_params = {
- .albedo = (vec3){ 1.0, 0.0, 0.0 }, .metallic = metallic, .roughness = roughness, .ao = ao
+ .albedo = (vec3){ 0.6, 0.0, 0.0 }, .metallic = metallic, .roughness = roughness, .ao = ao
};
int main() {
@@ -40,10 +40,11 @@ int main() {
for (int i = 0; i < 4; i++) {
point_lights[i].pos = pointlight_positions[i];
- point_lights[i].color = vec3(1, 1, 1);
+ // point_lights[i].color = vec3(0.25 * (i + 1), 0., 0.0);
+ point_lights[i].color = vec3(300.0, 300.0, 300.0);
}
- vec3 camera_pos = vec3(3.0, 3., 3.);
+ vec3 camera_pos = vec3(1.0, 1., -2.);
vec3 camera_front = vec3_normalise(vec3_negate(camera_pos));
camera cam = camera_create(camera_pos, camera_front, VEC3_Y, deg_to_rad(45.0));
@@ -82,7 +83,7 @@ int main() {
gpu_pipeline* pbr_pipeline = gpu_graphics_pipeline_create(pipeline_description);
// Geometry
- geometry_data sphere_data = geo_create_uvsphere(1.0, 12, 12);
+ geometry_data sphere_data = geo_create_uvsphere(1.0, 48, 48);
mesh sphere = mesh_create(&sphere_data, false);
pbr_params_bindgroup pbr_bind_data;
@@ -108,11 +109,12 @@ int main() {
pbr_bind_data.mvp_matrices =
(mvp_matrix_uniforms){ .model = model_affine, .view = view, .projection = proj };
pbr_bind_data.material = pbr_params;
- pbr_bind_data.lights =
- (pbr_params_light_uniforms){ .viewPos = cam.position,
- /* .pointLights = { point_lights[0], point_lights[1], */
- /* point_lights[2], point_lights[3] } */
- };
+ pbr_bind_data.lights = (pbr_params_light_uniforms){
+ .viewPos = vec4(cam.position.x, cam.position.y, cam.position.z, 1.0),
+ // .viewPos = cam.position,
+ .pointLights = { point_lights[0], point_lights[1],
+ point_lights[2], point_lights[3] }
+ };
pbr_uniforms.data = &pbr_bind_data;
encode_bind_shader_data(enc, 0, &pbr_uniforms);
diff --git a/src/maths/primitives.c b/src/maths/primitives.c
index 86855db..5d9c70f 100644
--- a/src/maths/primitives.c
+++ b/src/maths/primitives.c
@@ -159,7 +159,7 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
// Top point
vertex top = { .static_3d = { .position = vec3(0, radius, 0),
- .normal = vec3(0, radius, 0),
+ .normal = vec3_normalise(vec3(0, radius, 0)),
.tex_coords = vec2(0, 0) } };
vertex_darray_push(vertices, top);
@@ -173,13 +173,13 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
// theta should range from 0 to 2PI
f32 theta = TAU * ((f32)j / (f32)north_south_lines);
vec3 position = spherical_to_cartesian_coords(radius, theta, phi);
- f32 d = vec3_len(position);
+ // f32 d = vec3_len(position);
// print_vec3(position);
// printf("Phi %f Theta %f d %d\n", phi, theta, d);
// assert(d == radius); // all points on the sphere should be 'radius' away from the origin
vertex v = { .static_3d = {
.position = position,
- .normal = position, // normal vector on sphere is same as position
+ .normal = vec3_normalise(position), // normal vector on sphere is same as position
.tex_coords = vec2(0, 0) // TODO
} };
vertex_darray_push(vertices, v);
@@ -188,7 +188,7 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
// Bottom point
vertex bot = { .static_3d = { .position = vec3(0, -radius, 0),
- .normal = vec3(0, -radius, 0),
+ .normal = vec3_normalise(vec3(0, -radius, 0)),
.tex_coords = vec2(0, 0) } };
vertex_darray_push(vertices, bot);
@@ -235,8 +235,7 @@ geometry_data geo_create_uvsphere(f32 radius, u32 north_south_lines, u32 east_we
}
for (int i = 0; i < vertices->len; i++) {
-
- print_vec3(vertices->data[i].static_3d.normal);
+ // print_vec3(vertices->data[i].static_3d.normal);
}
geometry_data geo = {
diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/renderer/backends/opengl/backend_opengl.c
index eb9ad83..18e7d2a 100644
--- a/src/renderer/backends/opengl/backend_opengl.c
+++ b/src/renderer/backends/opengl/backend_opengl.c
@@ -97,11 +97,11 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
gpu_buffer* ubo_buf = BUFFER_GET(ubo_handle);
i32 blockIndex = glGetUniformBlockIndex(pipeline->shader_id, binding.label);
- /* printf("Block index for Matrices: %d", blockIndex); */
+ printf("Block index for Matrices: %d", blockIndex);
if (blockIndex < 0) {
WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
} else {
- DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
+ // DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
}
u32 blocksize;
glGetActiveUniformBlockiv(pipeline->shader_id, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
@@ -111,7 +111,7 @@ gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc descrip
glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
glBindBufferBase(GL_UNIFORM_BUFFER, binding_j, ubo_buf->id.ubo);
if (blockIndex != GL_INVALID_INDEX) {
- glUniformBlockBinding(pipeline->shader_id, blockIndex, 0);
+ glUniformBlockBinding(pipeline->shader_id, blockIndex, binding_j);
}
// Now we want to store a handle associated with the shader for this
@@ -185,25 +185,36 @@ void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipe
}
void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {
shader_data_layout sdl = data->shader_data_get_layout(data->data);
- printf("Binding %s shader data\n", sdl.name);
+ // printf("Binding %s shader data\n", sdl.name);
for (u32 i = 0; i < sdl.bindings_count; i++) {
shader_binding binding = sdl.bindings[i];
- print_shader_binding(binding);
+ // print_shader_binding(binding);
if (binding.type == SHADER_BINDING_BYTES) {
buffer_handle b = encoder->pipeline->uniform_bindings[i];
gpu_buffer* ubo_buf = BUFFER_GET(b);
+
+ i32 blockIndex = glGetUniformBlockIndex(encoder->pipeline->shader_id, binding.label);
+ if (blockIndex < 0) {
+ WARN("Couldn't retrieve block index for uniform block '%s'", binding.label);
+ } else {
+ // DEBUG("Retrived block index %d for %s", blockIndex, binding.label);
+ }
+
glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
+ glBindBufferBase(GL_UNIFORM_BUFFER, i, ubo_buf->id.ubo);
if (i == 2) {
- vec3* v = binding.data.bytes.data;
- print_vec3(*v);
+ pbr_params_light_uniforms* u = binding.data.bytes.data;
+ vec4* v = &u->viewPos;
(*v).x = 0.0;
(*v).y = 0.0;
(*v).z = 1.0;
+ // print_vec3(*v);
}
-
+ // glBindBufferBase(GL_UNIFORM_BUFFER, i, ubo_buf->id.ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, binding.data.bytes.data);
+
} else if (binding.type == SHADER_BINDING_TEXTURE) {
gpu_texture* tex = TEXTURE_GET(binding.data.texture.handle);
glActiveTexture(GL_TEXTURE0);
diff --git a/src/renderer/builtin_materials.h b/src/renderer/builtin_materials.h
index 8d84e53..7748599 100644
--- a/src/renderer/builtin_materials.h
+++ b/src/renderer/builtin_materials.h
@@ -44,16 +44,19 @@ typedef struct pbr_params_material_uniforms {
f32 metallic;
f32 roughness;
f32 ao;
+ f32 pad[2];
} pbr_params_material_uniforms;
typedef struct pbr_point_light {
vec3 pos;
+ f32 pad;
vec3 color;
+ f32 pad2;
} pbr_point_light;
typedef struct pbr_params_light_uniforms {
- vec3 viewPos;
- /* pbr_point_light pointLights[4]; */
+ pbr_point_light pointLights[4];
+ vec4 viewPos;
} pbr_params_light_uniforms;
typedef struct pbr_params_bindgroup {
@@ -81,13 +84,13 @@ static shader_data_layout pbr_params_shader_layout(void* data) {
.stores_data = has_data,
.data = { .bytes = { .size = sizeof(pbr_params_light_uniforms) } } };
- printf("Size %d \n", b3.data.bytes.size);
if (has_data) {
+ // printf("Size %d \n", b3.data.bytes.size);
b1.data.bytes.data = &d->mvp_matrices;
b2.data.bytes.data = &d->material;
/* d->lights.viewPos = vec3(0, 1, 0); */
b3.data.bytes.data = &d->lights;
- print_vec3(d->lights.viewPos);
+ // print_vec3(d->lights.viewPos);
}
return (shader_data_layout){ .name = "pbr_params", .bindings = { b1, b2, b3 }, .bindings_count = 3