diff options
-rw-r--r-- | assets/shaders/pbr_params.frag | 71 | ||||
-rw-r--r-- | assets/shaders/pbr_params.vert | 4 | ||||
-rw-r--r-- | examples/pbr_params/ex_pbr_params.c | 34 | ||||
-rw-r--r-- | src/maths/primitives.c | 11 | ||||
-rw-r--r-- | src/renderer/backends/opengl/backend_opengl.c | 27 | ||||
-rw-r--r-- | src/renderer/builtin_materials.h | 11 |
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 |