diff --git a/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.mtlx b/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.mtlx new file mode 100644 index 0000000..a2a41ae --- /dev/null +++ b/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.mtlx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.usdc b/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.usdc new file mode 100644 index 0000000..7ab300a Binary files /dev/null and b/examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.usdc differ diff --git a/examples/normal_map_cornell_box.cpp b/examples/normal_map_cornell_box.cpp index ee41d70..875cc95 100644 --- a/examples/normal_map_cornell_box.cpp +++ b/examples/normal_map_cornell_box.cpp @@ -1,13 +1,6 @@ -#include -#include -#include -#include -#include -#include -#include -#include #include #include +#include #include #include #include @@ -223,31 +216,48 @@ void setup_cornell_box() { metal_material->set_type(MaterialType::METAL); uint metal_id = g_scene->add_material(metal_material); - // 5: Textured material with normal map (for short box) + // 5: Textured material with PBR textures (for short box) auto textured_material = std::make_shared(); - textured_material->set_albedo(Vec3(1.0f, 1.0f, 1.0f)); - textured_material->set_metallic(1.0f); - textured_material->set_roughness(1.0f); - // textured_material->set_type(MaterialType::DIFFUSE); - textured_material->set_type(MaterialType::METAL); + textured_material->set_albedo(Vec3(1.0f, 0.0f, 1.0f)); + metal_material->set_metallic(1.0f); + metal_material->set_roughness(0.0f); + // textured_material->set_metallic(0.0f); + // textured_material->set_roughness(0.0f); + textured_material->set_type(MaterialType::DIFFUSE); - // Load textures - // auto albedo_tex = std::make_shared(); - // if (albedo_tex->load_from_file("examples/assets/normal_map_cornell_box/albedo.png")) { - // textured_material->set_albedo_texture(albedo_tex); - // ARE_LOG_INFO("Loaded albedo texture"); - // } else { - // ARE_LOG_WARN("Failed to load albedo texture"); - // } + // Load PBR textures + auto albedo_tex = std::make_shared(); + if (albedo_tex->load_from_file("examples/assets/normal_map_cornell_box/Bricks092_1K-JPG_Color.jpg")) { + textured_material->set_albedo_texture(albedo_tex); + ARE_LOG_INFO("Loaded albedo texture"); + } else { + ARE_LOG_WARN("Failed to load albedo texture"); + } auto normal_tex = std::make_shared(); - if (normal_tex->load_from_file("examples/assets/normal_map_cornell_box/normal.png")) { + if (normal_tex->load_from_file("examples/assets/normal_map_cornell_box/Bricks092_1K-JPG_NormalGL.jpg")) { textured_material->set_normal_texture(normal_tex); ARE_LOG_INFO("Loaded normal texture"); } else { ARE_LOG_WARN("Failed to load normal texture"); } + auto roughness_tex = std::make_shared(); + if (roughness_tex->load_from_file("examples/assets/normal_map_cornell_box/Bricks092_1K-JPG_Roughness.jpg")) { + textured_material->set_roughness_texture(roughness_tex); + ARE_LOG_INFO("Loaded roughness texture"); + } else { + ARE_LOG_WARN("Failed to load roughness texture"); + } + + auto ao_tex = std::make_shared(); + if (ao_tex->load_from_file("examples/assets/normal_map_cornell_box/Bricks092_1K-JPG_AmbientOcclusion.jpg")) { + textured_material->set_ao_texture(ao_tex); + ARE_LOG_INFO("Loaded AO texture"); + } else { + ARE_LOG_WARN("Failed to load AO texture"); + } + uint textured_id = g_scene->add_material(textured_material); // 6: Glass/Dielectric (refraction) @@ -298,7 +308,7 @@ void setup_cornell_box() { Vec3(room_size, -room_size, -room_size), Vec3(0.0f, 0.0f, 1.0f), metal_id); - // white_id); + // white_id); back_wall->upload_to_gpu(); g_scene->add_mesh(back_wall); diff --git a/shaders/raytracing.comp b/shaders/raytracing.comp index 3b931b1..ae32e13 100644 --- a/shaders/raytracing.comp +++ b/shaders/raytracing.comp @@ -43,8 +43,8 @@ struct Material { float roughness; int type; float ior; + float ao; // ambient occlusion float padding1; - float padding2; uint texture_handles[6]; }; @@ -458,9 +458,9 @@ vec3 apply_normal_map(vec3 normal, vec2 texcoord, vec3 tangent, uint normal_hand void apply_material_textures(inout Material mat, inout vec3 normal, vec2 texcoord, vec3 tangent) { if (!u_enable_textures) return; - // Albedo texture + // Albedo texture (replace) if (mat.texture_handles[0] != 0) { - mat.albedo *= sample_texture_array(0, int(mat.texture_handles[0]), texcoord).rgb; + mat.albedo = sample_texture_array(0, int(mat.texture_handles[0]), texcoord).rgb; } // Normal map @@ -468,25 +468,24 @@ void apply_material_textures(inout Material mat, inout vec3 normal, vec2 texcoor normal = apply_normal_map(normal, texcoord, tangent, mat.texture_handles[1]); } - // Metallic texture + // Metallic texture (replace) if (mat.texture_handles[2] != 0) { - mat.metallic *= sample_texture_array(2, int(mat.texture_handles[2]), texcoord).r; + mat.metallic = sample_texture_array(2, int(mat.texture_handles[2]), texcoord).r; } - // Roughness texture + // Roughness texture (replace) if (mat.texture_handles[3] != 0) { - mat.roughness *= sample_texture_array(3, int(mat.texture_handles[3]), texcoord).r; + mat.roughness = sample_texture_array(3, int(mat.texture_handles[3]), texcoord).r; } - // AO texture (multiply) + // AO texture (store in material, apply during lighting) if (mat.texture_handles[4] != 0) { - float ao = sample_texture_array(4, int(mat.texture_handles[4]), texcoord).r; - mat.albedo *= ao; + mat.ao = sample_texture_array(4, int(mat.texture_handles[4]), texcoord).r; } - // Emission texture (add) + // Emission texture (replace) if (mat.texture_handles[5] != 0) { - mat.emission += sample_texture_array(5, int(mat.texture_handles[5]), texcoord).rgb; + mat.emission = sample_texture_array(5, int(mat.texture_handles[5]), texcoord).rgb; } } @@ -623,7 +622,8 @@ vec3 eval_direct_lighting(inout HitInfo hit, Material mat, inout uint seed) { float pdf_light = 1.0 / float(u_light_count); vec3 brdf = mat.albedo * INV_PI; - return brdf * radiance * n_dot_l / max(pdf_light, EPSILON); + // Apply AO to the final lighting + return brdf * radiance * n_dot_l * mat.ao / max(pdf_light, EPSILON); } // ============================================================================ @@ -641,6 +641,7 @@ Material fetch_material(uint material_id) { m.roughness = 0.5; m.type = MATERIAL_DIFFUSE; m.ior = 1.5; + m.ao = 1.0; // default: no AO return m; } diff --git a/src/core/raytracer.cpp b/src/core/raytracer.cpp index 38cd735..1945ca8 100644 --- a/src/core/raytracer.cpp +++ b/src/core/raytracer.cpp @@ -306,8 +306,8 @@ void RayTracer::upload_scene_data_(const Scene &scene) { float roughness; int type; float ior; + float ao; float padding1; - float padding2; uint texture_handles[6]; }; @@ -322,6 +322,7 @@ void RayTracer::upload_scene_data_(const Scene &scene) { data.roughness = mat->get_roughness(); data.type = static_cast(mat->get_type()); data.ior = mat->get_ior(); + data.ao = 1.0f; // default: no AO // Texture array indices (0 = no texture, 1+ = index into array) data.texture_handles[0] = mat->get_texture_index(TextureSlot::ALBEDO);