Add AO debug view, and PBR subgroup

This commit is contained in:
Xtarsia 2025-11-23 16:23:51 +00:00 committed by Cory Petkovsek
parent de3de15dd4
commit e6ffd6cdca
11 changed files with 145 additions and 50 deletions

View File

@ -223,6 +223,9 @@
<None Include="src\shaders\debug_views.glsl" />
<None Include="src\shaders\main.glsl" />
<None Include="src\shaders\overlays.glsl" />
<None Include="src\shaders\pbr_views.glsl">
<FileType>Document</FileType>
</None>
<None Include="src\shaders\samplers.glsl" />
<None Include="src\shaders\backgrounds.glsl" />
<None Include="src\shaders\editor_functions.glsl" />

View File

@ -271,6 +271,9 @@
<None Include="doc\docs\programming_languages.rst">
<Filter>2. Docs</Filter>
</None>
<None Include="src\shaders\pbr_views.glsl">
<Filter>4. Shaders</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Text Include=".readthedocs.yaml">

View File

@ -210,33 +210,4 @@ group_uniforms;
AO = 1.0;
}
//INSERT: DEBUG_TEXTURE_HEIGHT
// Show height textures
{
ALBEDO = vec3(mat.albedo_height.a);
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: DEBUG_TEXTURE_NORMAL
// Show normal map textures
{
ALBEDO = fma(normalize(mat.normal_rough.xzy), vec3(0.5), vec3(0.5));
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: DEBUG_TEXTURE_ROUGHNESS
// Show roughness textures
{
ALBEDO = vec3(mat.normal_rough.a);
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
)"

View File

@ -383,7 +383,9 @@ void accumulate_material(vec3 base_ddx, vec3 base_ddy, const float weight, const
mat.total_weight += id_weight;
}
}
)"
R"(
void fragment() {
// Recover UVs
vec2 uv = UV;

View File

@ -0,0 +1,57 @@
// Copyright © 2025 Cory Petkovsek, Roope Palmroos, and Contributors.
// These special inserts are injected into the shader code at the end of fragment().
// Variables should be prefaced with __ to avoid name conflicts.
R"(
//INSERT: PBR_TEXTURE_ALBEDO
// Show height textures
{
ALBEDO = mat.albedo_height.rgb;
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: PBR_TEXTURE_HEIGHT
// Show height textures
{
ALBEDO = vec3(mat.albedo_height.a);
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: PBR_TEXTURE_NORMAL
// Show normal map textures
{
ALBEDO = fma(normalize(mat.normal_rough.xzy), vec3(0.5), vec3(0.5));
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: PBR_TEXTURE_ROUGHNESS
// Show roughness textures
{
ALBEDO = vec3(mat.normal_rough.a);
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
//INSERT: PBR_TEXTURE_AO
// Show normal map decoded AO value
{
ALBEDO = vec3(mat.ao);
ROUGHNESS = 0.7;
SPECULAR = 0.;
NORMAL_MAP = vec3(0.5, 0.5, 1.0);
AO = 1.0;
}
)"

View File

@ -1177,12 +1177,18 @@ void Terrain3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_show_colormap"), &Terrain3D::get_show_colormap);
ClassDB::bind_method(D_METHOD("set_show_roughmap", "enabled"), &Terrain3D::set_show_roughmap);
ClassDB::bind_method(D_METHOD("get_show_roughmap"), &Terrain3D::get_show_roughmap);
// PBR Views
ClassDB::bind_method(D_METHOD("set_show_texture_albedo", "enabled"), &Terrain3D::set_show_texture_albedo);
ClassDB::bind_method(D_METHOD("get_show_texture_albedo"), &Terrain3D::get_show_texture_albedo);
ClassDB::bind_method(D_METHOD("set_show_texture_height", "enabled"), &Terrain3D::set_show_texture_height);
ClassDB::bind_method(D_METHOD("get_show_texture_height"), &Terrain3D::get_show_texture_height);
ClassDB::bind_method(D_METHOD("set_show_texture_normal", "enabled"), &Terrain3D::set_show_texture_normal);
ClassDB::bind_method(D_METHOD("get_show_texture_normal"), &Terrain3D::get_show_texture_normal);
ClassDB::bind_method(D_METHOD("set_show_texture_rough", "enabled"), &Terrain3D::set_show_texture_rough);
ClassDB::bind_method(D_METHOD("get_show_texture_rough"), &Terrain3D::get_show_texture_rough);
ClassDB::bind_method(D_METHOD("set_show_texture_ao", "enabled"), &Terrain3D::set_show_texture_ao);
ClassDB::bind_method(D_METHOD("get_show_texture_ao"), &Terrain3D::get_show_texture_ao);
// Utility
ClassDB::bind_method(D_METHOD("get_intersection", "src_pos", "direction", "gpu_mode"), &Terrain3D::get_intersection, DEFVAL(false));
@ -1253,9 +1259,13 @@ void Terrain3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_control_scale"), "set_show_control_scale", "get_show_control_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_colormap"), "set_show_colormap", "get_show_colormap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_roughmap"), "set_show_roughmap", "get_show_roughmap");
ADD_SUBGROUP("PBR", "show_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_albedo"), "set_show_texture_albedo", "get_show_texture_albedo");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_height"), "set_show_texture_height", "get_show_texture_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_normal"), "set_show_texture_normal", "get_show_texture_normal");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_rough"), "set_show_texture_rough", "get_show_texture_rough");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_ao"), "set_show_texture_ao", "get_show_texture_ao");
ADD_SIGNAL(MethodInfo("material_changed"));
ADD_SIGNAL(MethodInfo("assets_changed"));

View File

@ -253,12 +253,18 @@ public:
bool get_show_colormap() const { return _material.is_valid() ? _material->get_show_colormap() : false; }
void set_show_roughmap(const bool p_enabled) { _material.is_valid() ? _material->set_show_roughmap(p_enabled) : void(); }
bool get_show_roughmap() const { return _material.is_valid() ? _material->get_show_roughmap() : false; }
// PBR View Aliases
void set_show_texture_albedo(const bool p_enabled) { _material.is_valid() ? _material->set_show_texture_albedo(p_enabled) : void(); }
bool get_show_texture_albedo() const { return _material.is_valid() ? _material->get_show_texture_albedo() : false; }
void set_show_texture_height(const bool p_enabled) { _material.is_valid() ? _material->set_show_texture_height(p_enabled) : void(); }
bool get_show_texture_height() const { return _material.is_valid() ? _material->get_show_texture_height() : false; }
void set_show_texture_normal(const bool p_enabled) { _material.is_valid() ? _material->set_show_texture_normal(p_enabled) : void(); }
bool get_show_texture_normal() const { return _material.is_valid() ? _material->get_show_texture_normal() : false; }
void set_show_texture_rough(const bool p_enabled) { _material.is_valid() ? _material->set_show_texture_rough(p_enabled) : void(); }
bool get_show_texture_rough() const { return _material.is_valid() ? _material->get_show_texture_rough() : false; }
void set_show_texture_ao(const bool p_enabled) { _material.is_valid() ? _material->set_show_texture_ao(p_enabled) : void(); }
bool get_show_texture_ao() const { return _material.is_valid() ? _material->get_show_texture_ao() : false; }
protected:
void _notification(const int p_what);

View File

@ -33,11 +33,14 @@ void Terrain3DMaterial::_preload_shaders() {
#include "shaders/dual_scaling.glsl"
, "dual_scaling");
_parse_shader(
#include "shaders/overlays.glsl"
, "overlays");
_parse_shader(
#include "shaders/debug_views.glsl"
, "debug_views");
_parse_shader(
#include "shaders/overlays.glsl"
, "overlays");
#include "shaders/pbr_views.glsl"
, "pbr_views");
_parse_shader(
#include "shaders/editor_functions.glsl"
, "editor_functions");
@ -357,14 +360,21 @@ String Terrain3DMaterial::_inject_editor_code(const String &p_shader) const {
if (_debug_view_roughmap) {
insert_names.push_back("DEBUG_ROUGHMAP");
}
if (_debug_view_tex_height) {
insert_names.push_back("DEBUG_TEXTURE_HEIGHT");
// PBR views
if (_pbr_view_tex_albedo) {
insert_names.push_back("PBR_TEXTURE_ALBEDO");
}
if (_debug_view_tex_normal) {
insert_names.push_back("DEBUG_TEXTURE_NORMAL");
if (_pbr_view_tex_height) {
insert_names.push_back("PBR_TEXTURE_HEIGHT");
}
if (_debug_view_tex_rough) {
insert_names.push_back("DEBUG_TEXTURE_ROUGHNESS");
if (_pbr_view_tex_normal) {
insert_names.push_back("PBR_TEXTURE_NORMAL");
}
if (_pbr_view_tex_ao) {
insert_names.push_back("PBR_TEXTURE_AO");
}
if (_pbr_view_tex_rough) {
insert_names.push_back("PBR_TEXTURE_ROUGHNESS");
}
// Overlays
if (_show_contours) {
@ -764,24 +774,36 @@ void Terrain3DMaterial::set_show_roughmap(const bool p_enabled) {
_update_shader();
}
void Terrain3DMaterial::set_show_texture_albedo(const bool p_enabled) {
SET_IF_DIFF(_pbr_view_tex_albedo, p_enabled);
LOG(INFO, "Enable show_texture_albedo: ", p_enabled);
_update_shader();
}
void Terrain3DMaterial::set_show_texture_height(const bool p_enabled) {
SET_IF_DIFF(_debug_view_tex_height, p_enabled);
SET_IF_DIFF(_pbr_view_tex_height, p_enabled);
LOG(INFO, "Enable show_texture_height: ", p_enabled);
_update_shader();
}
void Terrain3DMaterial::set_show_texture_normal(const bool p_enabled) {
SET_IF_DIFF(_debug_view_tex_normal, p_enabled);
SET_IF_DIFF(_pbr_view_tex_normal, p_enabled);
LOG(INFO, "Enable show_texture_normal: ", p_enabled);
_update_shader();
}
void Terrain3DMaterial::set_show_texture_rough(const bool p_enabled) {
SET_IF_DIFF(_debug_view_tex_rough, p_enabled);
SET_IF_DIFF(_pbr_view_tex_rough, p_enabled);
LOG(INFO, "Enable show_texture_rough: ", p_enabled);
_update_shader();
}
void Terrain3DMaterial::set_show_texture_ao(const bool p_enabled) {
SET_IF_DIFF(_pbr_view_tex_ao, p_enabled);
LOG(INFO, "Enable show_texture_ao: ", p_enabled);
_update_shader();
}
Error Terrain3DMaterial::save(const String &p_path) {
if (p_path.is_empty() && get_path().is_empty()) {
return ERR_FILE_NOT_FOUND;
@ -1012,10 +1034,16 @@ void Terrain3DMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_show_colormap"), &Terrain3DMaterial::get_show_colormap);
ClassDB::bind_method(D_METHOD("set_show_roughmap", "enabled"), &Terrain3DMaterial::set_show_roughmap);
ClassDB::bind_method(D_METHOD("get_show_roughmap"), &Terrain3DMaterial::get_show_roughmap);
// PBR Views
ClassDB::bind_method(D_METHOD("set_show_texture_albedo", "enabled"), &Terrain3DMaterial::set_show_texture_albedo);
ClassDB::bind_method(D_METHOD("get_show_texture_albedo"), &Terrain3DMaterial::get_show_texture_albedo);
ClassDB::bind_method(D_METHOD("set_show_texture_height", "enabled"), &Terrain3DMaterial::set_show_texture_height);
ClassDB::bind_method(D_METHOD("get_show_texture_height"), &Terrain3DMaterial::get_show_texture_height);
ClassDB::bind_method(D_METHOD("set_show_texture_normal", "enabled"), &Terrain3DMaterial::set_show_texture_normal);
ClassDB::bind_method(D_METHOD("get_show_texture_normal"), &Terrain3DMaterial::get_show_texture_normal);
ClassDB::bind_method(D_METHOD("set_show_texture_ao", "enabled"), &Terrain3DMaterial::set_show_texture_ao);
ClassDB::bind_method(D_METHOD("get_show_texture_ao"), &Terrain3DMaterial::get_show_texture_ao);
ClassDB::bind_method(D_METHOD("set_show_texture_rough", "enabled"), &Terrain3DMaterial::set_show_texture_rough);
ClassDB::bind_method(D_METHOD("get_show_texture_rough"), &Terrain3DMaterial::get_show_texture_rough);
@ -1050,7 +1078,12 @@ void Terrain3DMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_control_scale", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_control_scale", "get_show_control_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_colormap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_colormap", "get_show_colormap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_roughmap", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_roughmap", "get_show_roughmap");
// Hidden in Material, aliased in Terrain3D
//ADD_SUBGROUP("PBR Views", "show_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_albedo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_texture_albedo", "get_show_texture_albedo");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_height", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_texture_height", "get_show_texture_height");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_normal", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_texture_normal", "get_show_texture_normal");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_ao", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_texture_ao", "get_show_texture_ao");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_texture_rough", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_show_texture_rough", "get_show_texture_rough");
}

View File

@ -64,9 +64,13 @@ private:
bool _debug_view_holes = false;
bool _debug_view_colormap = false;
bool _debug_view_roughmap = false;
bool _debug_view_tex_height = false;
bool _debug_view_tex_normal = false;
bool _debug_view_tex_rough = false;
// PBR Views
bool _pbr_view_tex_albedo = false;
bool _pbr_view_tex_height = false;
bool _pbr_view_tex_normal = false;
bool _pbr_view_tex_ao = false;
bool _pbr_view_tex_rough = false;
// Functions
void _preload_shaders();
@ -146,12 +150,18 @@ public:
bool get_show_colormap() const { return _debug_view_colormap; }
void set_show_roughmap(const bool p_enabled);
bool get_show_roughmap() const { return _debug_view_roughmap; }
// PBR Views
void set_show_texture_albedo(const bool p_enabled);
bool get_show_texture_albedo() const { return _pbr_view_tex_albedo; }
void set_show_texture_height(const bool p_enabled);
bool get_show_texture_height() const { return _debug_view_tex_height; }
bool get_show_texture_height() const { return _pbr_view_tex_height; }
void set_show_texture_normal(const bool p_enabled);
bool get_show_texture_normal() const { return _debug_view_tex_normal; }
bool get_show_texture_normal() const { return _pbr_view_tex_normal; }
void set_show_texture_rough(const bool p_enabled);
bool get_show_texture_rough() const { return _debug_view_tex_rough; }
bool get_show_texture_rough() const { return _pbr_view_tex_rough; }
void set_show_texture_ao(const bool p_enabled);
bool get_show_texture_ao() const { return _pbr_view_tex_ao; }
Error save(const String &p_path = "");

View File

@ -374,7 +374,7 @@ Ref<Image> Terrain3DUtil::load_image(const String &p_file_name, const int p_cach
* If p_invert_alpha is true, the destination alpha channel will be 1.0 - input source channel.
*/
Ref<Image> Terrain3DUtil::pack_image(const Ref<Image> &p_src_rgb, const Ref<Image> &p_src_a, const Ref<Image> &p_src_ao,
const bool p_invert_green, const bool p_invert_alpha, const bool p_normalize_alpha, const int p_alpha_channel, const int p_occlusion_channel) {
const bool p_invert_green, const bool p_invert_alpha, const bool p_normalize_alpha, const int p_alpha_channel, const int p_ao_channel) {
if (!p_src_rgb.is_valid() || !p_src_a.is_valid()) {
LOG(ERROR, "Provided images are not valid. Cannot pack");
return Ref<Image>();
@ -433,7 +433,7 @@ Ref<Image> Terrain3DUtil::pack_image(const Ref<Image> &p_src_rgb, const Ref<Imag
}
if (pack_ao) {
// Compress range to avoid low AO values completely destroying normal vector precision - recovered in shader.
real_t ao = sqrt(p_src_ao->get_pixel(x, y)[p_occlusion_channel]) * 0.5 + 0.5;
real_t ao = sqrt(p_src_ao->get_pixel(x, y)[p_ao_channel]) * 0.5 + 0.5;
col.r = col.r * ao + (1.0f - ao) * 0.5f;
col.g = col.g * ao + (1.0f - ao) * 0.5f;
col.b = col.b * ao + (1.0f - ao) * 0.5f;
@ -554,6 +554,6 @@ void Terrain3DUtil::_bind_methods() {
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("get_thumbnail", "image", "size"), &Terrain3DUtil::get_thumbnail, DEFVAL(V2I(256)));
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("get_filled_image", "size", "color", "create_mipmaps", "format"), &Terrain3DUtil::get_filled_image);
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("load_image", "file_name", "cache_mode", "r16_height_range", "r16_size"), &Terrain3DUtil::load_image, DEFVAL(ResourceLoader::CACHE_MODE_IGNORE), DEFVAL(Vector2(0.f, 255.f)), DEFVAL(V2I_ZERO));
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("pack_image", "src_rgb", "src_a", "invert_green", "invert_alpha", "normalize_alpha", "alpha_channel"), &Terrain3DUtil::pack_image, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(0));
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("pack_image", "src_rgb", "src_a", "src_ao", "invert_green", "invert_alpha", "normalize_alpha", "alpha_channel", "ao_channel"), &Terrain3DUtil::pack_image, DEFVAL(false), DEFVAL(false), DEFVAL(false), DEFVAL(0), DEFVAL(0));
ClassDB::bind_static_method("Terrain3DUtil", D_METHOD("luminance_to_height", "src_rgb"), &Terrain3DUtil::luminance_to_height);
}

View File

@ -53,7 +53,7 @@ public:
const bool p_invert_alpha = false,
const bool p_normalize_alpha = false,
const int p_alpha_channel = 0,
const int p_occlusion_channel = 0);
const int p_ao_channel = 0);
static Ref<Image> luminance_to_height(const Ref<Image> &p_src_rgb);
static void benchmark(Terrain3D *p_terrain);