fix: 修复PBR纹理属性与材质值混合问题及AO实现
- 将纹理采样从乘法混合改为直接替换 - 添加Material结构的ao字段并在光照计算中正确应用 - 更新demo使用完整的PBR砖墙纹理master
parent
330fdcf43d
commit
8732446237
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0"?>
|
||||
<materialx version="1.38" fileprefix="./">
|
||||
<standard_surface xpos="6.159420" name="Bricks092_1K_JPG_StandardSurface" ypos="-1.879310" type="surfaceshader">
|
||||
<input name="specular" value="0" type="float" />
|
||||
<input name="coat" value="1" type="float" />
|
||||
<input name="coat_color" value="1, 1, 1" type="color3" />
|
||||
<input name="base" value="1" type="float" />
|
||||
<input nodename="Bricks092_1K_JPG_Color" name="base_color" type="color3" />
|
||||
<input nodename="normalmap" name="normal" type="vector3" />
|
||||
<input nodename="normalmap" name="coat_normal" type="vector3" />
|
||||
<input nodename="Bricks092_1K_JPG_Roughness" name="specular_roughness" type="float" />
|
||||
<input nodename="Bricks092_1K_JPG_Roughness" name="coat_roughness" type="float" />
|
||||
</standard_surface>
|
||||
<surfacematerial xpos="8.695652" name="Bricks092_1K_JPG" ypos="0.000000" type="material">
|
||||
<input nodename="Bricks092_1K_JPG_StandardSurface" name="surfaceshader" type="surfaceshader" />
|
||||
<input nodename="displacement" name="displacementshader" type="displacementshader" />
|
||||
</surfacematerial>
|
||||
<tiledimage xpos="3.623188" name="Bricks092_1K_JPG_Color" ypos="-3.103448" type="color3">
|
||||
<input name="file" value="Bricks092_1K-JPG_Color.jpg" colorspace="srgb_texture" type="filename" />
|
||||
<input name="uvtiling" value="1.0, 1.0" type="vector2" />
|
||||
</tiledimage>
|
||||
<tiledimage xpos="3.623188" name="Bricks092_1K_JPG_Displacement" ypos="5.163793" type="float">
|
||||
<input name="file" value="Bricks092_1K-JPG_Displacement.jpg" type="filename" />
|
||||
<input name="uvtiling" value="1.0, 1.0" type="vector2" />
|
||||
</tiledimage>
|
||||
<displacement xpos="6.159420" name="displacement" ypos="1.879310" type="displacementshader">
|
||||
<input nodename="Bricks092_1K_JPG_Displacement" name="displacement" type="float" />
|
||||
<input name="scale" value="1.0" type="float" />
|
||||
</displacement>
|
||||
<tiledimage xpos="1.086957" name="Bricks092_1K_JPG_NormalGL" ypos="0.879310" type="vector3">
|
||||
<input name="file" value="Bricks092_1K-JPG_NormalGL.jpg" type="filename" />
|
||||
<input name="uvtiling" value="1.0, 1.0" type="vector2" />
|
||||
</tiledimage>
|
||||
<normalmap xpos="3.623188" name="normalmap" ypos="3.586207" type="vector3">
|
||||
<input nodename="Bricks092_1K_JPG_NormalGL" name="in" type="vector3" />
|
||||
<input name="scale" value="1.0" type="float" />
|
||||
</normalmap>
|
||||
<tiledimage xpos="3.623188" name="Bricks092_1K_JPG_Roughness" ypos="-0.413793" type="float">
|
||||
<input name="file" value="Bricks092_1K-JPG_Roughness.jpg" type="filename" />
|
||||
<input name="uvtiling" value="1.0, 1.0" type="vector2" />
|
||||
</tiledimage>
|
||||
</materialx>
|
||||
Binary file not shown.
|
|
@ -1,13 +1,6 @@
|
|||
#include <core/renderer.h>
|
||||
#include <scene/scene.h>
|
||||
#include <scene/camera.h>
|
||||
#include <scene/mesh.h>
|
||||
#include <scene/material.h>
|
||||
#include <scene/light.h>
|
||||
#include <resource/texture.h>
|
||||
#include <utils/logger.h>
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <core/renderer.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
|
@ -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<Material>();
|
||||
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<are::Texture>();
|
||||
// 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<are::Texture>();
|
||||
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<are::Texture>();
|
||||
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<are::Texture>();
|
||||
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<are::Texture>();
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<int>(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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue