diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-15 17:59:02 +1000 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-15 17:59:02 +1000 |
commit | b3b19f081231c7c13322c7b0d577afb6084d48df (patch) | |
tree | 0bec011f39175c3f168571dd135f3c653f91a21e | |
parent | c5808488875484aca814bfc8e526f37f3f447166 (diff) |
point lights for pbr example
-rw-r--r-- | assets/shaders/pbr_params.frag | 63 | ||||
-rw-r--r-- | assets/shaders/pbr_params.vert | 2 | ||||
-rw-r--r-- | examples/cube/ex_cube.c | 8 | ||||
-rw-r--r-- | examples/pbr_params/ex_pbr_params.c | 27 | ||||
-rw-r--r-- | src/renderer/builtin_materials.h | 8 |
5 files changed, 77 insertions, 31 deletions
diff --git a/assets/shaders/pbr_params.frag b/assets/shaders/pbr_params.frag index d467aa8..068fb3c 100644 --- a/assets/shaders/pbr_params.frag +++ b/assets/shaders/pbr_params.frag @@ -1,10 +1,10 @@ -#version 410 +#version 410 core out vec4 FragColor; -in vec3 WorldPos; -in vec3 Normal; -in vec2 TexCoords; +in vec3 fragWorldPos; +in vec3 fragNormal; +in vec2 fragTexCoords; struct PointLight { vec3 position; @@ -35,22 +35,45 @@ float GeometrySchlickGGX(float NdotV, float roughness); float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness); void main() { - vec3 norm = normalize(Normal); - vec3 viewDir = normalize(scene.viewPos - WorldPos); - - // vec3 radiance = vec3(0.0); // denoted L in the radiance equation - // for (int i = 0; i < 4; i++) { - // vec3 lightVec = normalize(pointLights[i].position - WorldPos); - // vec3 halfway = normalize(Normal + lightVec); - // float distance = length(pointLights[i].position - WorldPos); - // float attenuation = 1.0 / (distance * distance); - // vec3 radiance = pointLights[i].color * attenuation; - - // vec3 F0 = vec3(0.04); - // F0 = mix(F0, albedo, metallic); - // vec3 F = fresnelSchlick(max(dot(halfway, lightVec), 0.0), F0); - // } - + vec3 norm = normalize(fragNormal); + vec3 viewDir = normalize(scene.viewPos - fragWorldPos); + + 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; + } + + vec3 ambient = vec3(0.03) * pbr.albedo * pbr.ao; + vec3 color = ambient + Lo; + + // color = color / (color + vec3(1.0)); + // color = pow(color, vec3(1.0/2.2)); + + // FragColor = vec4(color, 1.0); FragColor = vec4(1.0); } diff --git a/assets/shaders/pbr_params.vert b/assets/shaders/pbr_params.vert index 0908246..e3cbe96 100644 --- a/assets/shaders/pbr_params.vert +++ b/assets/shaders/pbr_params.vert @@ -1,4 +1,4 @@ -#version 410 +#version 410 core // Vertex attributes layout(location = 0) in vec3 inPosition; diff --git a/examples/cube/ex_cube.c b/examples/cube/ex_cube.c index 26e6b71..2cd0a51 100644 --- a/examples/cube/ex_cube.c +++ b/examples/cube/ex_cube.c @@ -18,10 +18,10 @@ extern core g_core; // Scene / light setup const vec3 pointlight_positions[4] = { - { -10.0, 10.0, 10.0}, - { 10.0, 10.0, 10.0}, - { -10.0, -10.0, 10.0}, - { 10.0, -10.0, 10.0}, + { -10.0, 10.0, 10.0 }, + { 10.0, 10.0, 10.0 }, + { -10.0, -10.0, 10.0 }, + { 10.0, -10.0, 10.0 }, }; point_light point_lights[4]; diff --git a/examples/pbr_params/ex_pbr_params.c b/examples/pbr_params/ex_pbr_params.c index 583fd12..0ac784d 100644 --- a/examples/pbr_params/ex_pbr_params.c +++ b/examples/pbr_params/ex_pbr_params.c @@ -15,19 +15,34 @@ extern core g_core; +const vec3 pointlight_positions[4] = { + { 10.0, 10.0, 10.0 }, + { -10.0, 10.0, 10.0 }, + { 10.0, -10.0, 10.0 }, + { -10.0, -10.0, 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 = 0.0; const f32 roughness = 0.8; const f32 ao = 0.2; -const pbr_params_material_uniforms pbr_params = {.albedo = (vec3){0.5,0.5,0.5}, .metallic = metallic, .roughness = roughness, .ao = ao}; +const pbr_params_material_uniforms pbr_params = { + .albedo = (vec3){ 0.5, 0.5, 0.5 }, .metallic = metallic, .roughness = roughness, .ao = ao +}; int main() { core_bringup(); arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024); + for (int i = 0; i < 4; i++) { + point_lights[i].pos = pointlight_positions[i]; + point_lights[i].color = vec3(1, 1, 1); + } + vec3 camera_pos = vec3(3.0, 3., 3.); vec3 camera_front = vec3_normalise(vec3_negate(camera_pos)); camera cam = camera_create(camera_pos, camera_front, VEC3_Y, deg_to_rad(45.0)); @@ -61,7 +76,7 @@ int main() { .code = fragment_shader.contents, .is_spirv = false }, .renderpass = renderpass, - .wireframe = false, + .wireframe = true, .depth_test = false }; gpu_pipeline* pbr_pipeline = gpu_graphics_pipeline_create(pipeline_description); @@ -90,9 +105,13 @@ int main() { camera_view_projection(&cam, 1000, 1000, &view, &proj); // Feed shader data - pbr_bind_data.mvp_matrices = (mvp_matrix_uniforms){.model = model_affine, .view = view, .projection = proj}; + 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 /* TODO: point lights*/}; + 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_uniforms.data = &pbr_bind_data; encode_bind_shader_data(enc, 0, &pbr_uniforms); diff --git a/src/renderer/builtin_materials.h b/src/renderer/builtin_materials.h index c284acc..740ab3d 100644 --- a/src/renderer/builtin_materials.h +++ b/src/renderer/builtin_materials.h @@ -44,10 +44,14 @@ typedef struct pbr_params_material_uniforms { f32 ao; } pbr_params_material_uniforms; +typedef struct pbr_point_light { + vec3 pos; + vec3 color; +} pbr_point_light; + typedef struct pbr_params_light_uniforms { vec3 viewPos; - // TODO: PointLights - + pbr_point_light pointLights[4]; } pbr_params_light_uniforms; typedef struct pbr_params_bindgroup { |