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 <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <core/renderer.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
@ -223,31 +216,48 @@ void setup_cornell_box() {
|
||||||
metal_material->set_type(MaterialType::METAL);
|
metal_material->set_type(MaterialType::METAL);
|
||||||
uint metal_id = g_scene->add_material(metal_material);
|
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>();
|
auto textured_material = std::make_shared<Material>();
|
||||||
textured_material->set_albedo(Vec3(1.0f, 1.0f, 1.0f));
|
textured_material->set_albedo(Vec3(1.0f, 0.0f, 1.0f));
|
||||||
textured_material->set_metallic(1.0f);
|
metal_material->set_metallic(1.0f);
|
||||||
textured_material->set_roughness(1.0f);
|
metal_material->set_roughness(0.0f);
|
||||||
// textured_material->set_type(MaterialType::DIFFUSE);
|
// textured_material->set_metallic(0.0f);
|
||||||
textured_material->set_type(MaterialType::METAL);
|
// textured_material->set_roughness(0.0f);
|
||||||
|
textured_material->set_type(MaterialType::DIFFUSE);
|
||||||
|
|
||||||
// Load textures
|
// Load PBR textures
|
||||||
// auto albedo_tex = std::make_shared<are::Texture>();
|
auto albedo_tex = std::make_shared<are::Texture>();
|
||||||
// if (albedo_tex->load_from_file("examples/assets/normal_map_cornell_box/albedo.png")) {
|
if (albedo_tex->load_from_file("examples/assets/normal_map_cornell_box/Bricks092_1K-JPG_Color.jpg")) {
|
||||||
// textured_material->set_albedo_texture(albedo_tex);
|
textured_material->set_albedo_texture(albedo_tex);
|
||||||
// ARE_LOG_INFO("Loaded albedo texture");
|
ARE_LOG_INFO("Loaded albedo texture");
|
||||||
// } else {
|
} else {
|
||||||
// ARE_LOG_WARN("Failed to load albedo texture");
|
ARE_LOG_WARN("Failed to load albedo texture");
|
||||||
// }
|
}
|
||||||
|
|
||||||
auto normal_tex = std::make_shared<are::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);
|
textured_material->set_normal_texture(normal_tex);
|
||||||
ARE_LOG_INFO("Loaded normal texture");
|
ARE_LOG_INFO("Loaded normal texture");
|
||||||
} else {
|
} else {
|
||||||
ARE_LOG_WARN("Failed to load normal texture");
|
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);
|
uint textured_id = g_scene->add_material(textured_material);
|
||||||
|
|
||||||
// 6: Glass/Dielectric (refraction)
|
// 6: Glass/Dielectric (refraction)
|
||||||
|
|
|
||||||
|
|
@ -43,8 +43,8 @@ struct Material {
|
||||||
float roughness;
|
float roughness;
|
||||||
int type;
|
int type;
|
||||||
float ior;
|
float ior;
|
||||||
|
float ao; // ambient occlusion
|
||||||
float padding1;
|
float padding1;
|
||||||
float padding2;
|
|
||||||
uint texture_handles[6];
|
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) {
|
void apply_material_textures(inout Material mat, inout vec3 normal, vec2 texcoord, vec3 tangent) {
|
||||||
if (!u_enable_textures) return;
|
if (!u_enable_textures) return;
|
||||||
|
|
||||||
// Albedo texture
|
// Albedo texture (replace)
|
||||||
if (mat.texture_handles[0] != 0) {
|
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
|
// 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]);
|
normal = apply_normal_map(normal, texcoord, tangent, mat.texture_handles[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metallic texture
|
// Metallic texture (replace)
|
||||||
if (mat.texture_handles[2] != 0) {
|
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) {
|
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) {
|
if (mat.texture_handles[4] != 0) {
|
||||||
float ao = sample_texture_array(4, int(mat.texture_handles[4]), texcoord).r;
|
mat.ao = sample_texture_array(4, int(mat.texture_handles[4]), texcoord).r;
|
||||||
mat.albedo *= ao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emission texture (add)
|
// Emission texture (replace)
|
||||||
if (mat.texture_handles[5] != 0) {
|
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);
|
float pdf_light = 1.0 / float(u_light_count);
|
||||||
vec3 brdf = mat.albedo * INV_PI;
|
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.roughness = 0.5;
|
||||||
m.type = MATERIAL_DIFFUSE;
|
m.type = MATERIAL_DIFFUSE;
|
||||||
m.ior = 1.5;
|
m.ior = 1.5;
|
||||||
|
m.ao = 1.0; // default: no AO
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -306,8 +306,8 @@ void RayTracer::upload_scene_data_(const Scene &scene) {
|
||||||
float roughness;
|
float roughness;
|
||||||
int type;
|
int type;
|
||||||
float ior;
|
float ior;
|
||||||
|
float ao;
|
||||||
float padding1;
|
float padding1;
|
||||||
float padding2;
|
|
||||||
uint texture_handles[6];
|
uint texture_handles[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -322,6 +322,7 @@ void RayTracer::upload_scene_data_(const Scene &scene) {
|
||||||
data.roughness = mat->get_roughness();
|
data.roughness = mat->get_roughness();
|
||||||
data.type = static_cast<int>(mat->get_type());
|
data.type = static_cast<int>(mat->get_type());
|
||||||
data.ior = mat->get_ior();
|
data.ior = mat->get_ior();
|
||||||
|
data.ao = 1.0f; // default: no AO
|
||||||
|
|
||||||
// Texture array indices (0 = no texture, 1+ = index into array)
|
// Texture array indices (0 = no texture, 1+ = index into array)
|
||||||
data.texture_handles[0] = mat->get_texture_index(TextureSlot::ALBEDO);
|
data.texture_handles[0] = mat->get_texture_index(TextureSlot::ALBEDO);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue