From 8732446237771494bfd84f08d44bfbb3c3dfb4d9 Mon Sep 17 00:00:00 2001 From: ternaryop8479 Date: Sat, 7 Mar 2026 13:32:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DPBR=E7=BA=B9=E7=90=86?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E4=B8=8E=E6=9D=90=E8=B4=A8=E5=80=BC=E6=B7=B7?= =?UTF-8?q?=E5=90=88=E9=97=AE=E9=A2=98=E5=8F=8AAO=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将纹理采样从乘法混合改为直接替换 - 添加Material结构的ao字段并在光照计算中正确应用 - 更新demo使用完整的PBR砖墙纹理 --- .../Bricks092_1K-JPG.mtlx | 42 +++++++++++++ .../Bricks092_1K-JPG.usdc | Bin 0 -> 2649 bytes examples/normal_map_cornell_box.cpp | 58 ++++++++++-------- shaders/raytracing.comp | 27 ++++---- src/core/raytracer.cpp | 3 +- 5 files changed, 92 insertions(+), 38 deletions(-) create mode 100644 examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.mtlx create mode 100644 examples/assets/normal_map_cornell_box/Bricks092_1K-JPG.usdc 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 0000000000000000000000000000000000000000..7ab300afd85f16719045c13cf2a07560b54872a2 GIT binary patch literal 2649 zcmbtWTW}ml6+Jz(vkyJ2QM403iN;D060xG?#1|GzD3IuMA*b~tN(1`T_M#_cVgxIL~z zi|o)zO2|B@7Z;-x;F*FoDneIN^Q*kNq%VgwR+gz{jNsqlBGvkB~e@ z7$+Ph93wnHI8OLq#yv>mcrG~cZ~QlZ50U)@L2NCSC!#I%kpO5Dcd$l%?7-SYdvHHl z+5*o}Ti}Um3p^Wb;UozK0;ezWeJ48C%Fo7k9zINY)YH@RQ=Vlk`J)ew%^x{4|7dO+ zu4mQLi&m}TnKmkBRS#=Hj&yhep*#7s<)dx}rswBOuVh;R^e|X-Jm~eZW!gb{S{-V4 zM+~Pv48w6(J!@exKsr6D9vK-`b78q=8EVF<>z1u%%!*~`f#ulh&|(m{{)tq|@J!My zo8+MG*#3y)Eu`EB&|5i%n~~J#P0vY@qtq}KOxyJI;90B>(q&T%hG)5fx_nd}Du=X& z`OvQz^KRLjuj>@FrPoH>)nP1|t1FII@lozzLKIi~Xi-kZ^lUhuZZDYdt-4z?v7*;% z2&{m*$Jr|?WeLHmYvQp2iU_?LUW1rmUo#f?N>h4@&eKtBbQqx@IQ1EQ)$}rYpu=}f z!>U@QH;avtS-oz;2?I9_{1blYRdvIpq&u$Z1(xZfXg(c;o|$$iK+C46^QKOrAvcvT zEOy}9pko-d(5G~vVpXf5PeW_80Ts)4Yvij=y8zqq>Us^H6D};;rtjkuc)_x(&Izjm z%U;9v2+b={SYb`~KIM2z)ta-iAJHnrLrByiB@qiCCLw+S;x0s=f!K>v%erTatmK(~ zSUZVltCXFxZY+HnnW|MYyP)`kD6V+ATi6YBBU$W5-giRJ=w)ibeS$@vV#mCN@-mZt zf@5V%{|2rleM6`02F?qQcyM`66ku8QMTI&QXY8vHor^kC8NhXLL9&0s|kz9-HdrXxOop3ROt zq=p6v-UGWvoz`o2PViEy6q z@F*C!9@0*db%Hb+VKR=dZ*6T+pa--mavlFZ#s`q05ei8IWmVuwV#(ZGi6~brCbJ1>MM`rV>ra-b zQ)0Lky%CLk5RC}eqY?31G!nTQjYu2vKV;#3S^T^5x83jUy`n_lQDSc^@xLmGzbGA- z)k~`IXI1=@8u_Ct{bBIJ-k$S&ji#BJgLLX)h*{I;N2D$=>9Es-?| zS}qxtB1E_2)X<|R`*Ricztsk4>*)!SMLTe!K#qCo8*v;3m zP|Tm6oxU?*qw%LiQ8wt2)7hEK9W$~`$LE?Ctzpj=TSLCt{KNTHbAE2Jc&cUNs^iT+ VkMm7?A(u_>wD<60Li9|7;oma+=uQ9t literal 0 HcmV?d00001 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);