From f721d684fb868474eb4c153b7c4f48b81fecde44 Mon Sep 17 00:00:00 2001 From: Bastiaan Olij Date: Tue, 20 Jan 2026 09:05:27 +1100 Subject: [PATCH] Apply fixed size properly for mono/stereo rendering. (cherry picked from commit aac883849e835eb8ff4e3bf2a0737355b55784e5) --- drivers/gles3/shaders/scene.glsl | 12 ++++++++++++ drivers/gles3/storage/material_storage.cpp | 1 + scene/resources/material.cpp | 10 +++++++++- scene/resources/visual_shader.cpp | 3 +++ .../scene_shader_forward_clustered.cpp | 1 + .../forward_mobile/scene_shader_forward_mobile.cpp | 1 + .../forward_clustered/scene_forward_clustered.glsl | 12 ++++++++++++ .../shaders/forward_mobile/scene_forward_mobile.glsl | 12 ++++++++++++ servers/rendering/shader_types.cpp | 1 + 9 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 34d768c974..b6b0cc40a9 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -48,6 +48,12 @@ RENDER_MOTION_VECTORS = false #define SHADER_IS_SRGB true #define SHADER_SPACE_FAR -1.0 +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + #if defined(RENDER_SHADOWS) || defined(RENDER_SHADOWS_LINEAR) #define IN_SHADOW_PASS true #else @@ -1021,6 +1027,12 @@ void main() { #define SHADER_IS_SRGB true #define SHADER_SPACE_FAR -1.0 +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + #if defined(RENDER_SHADOWS) || defined(RENDER_SHADOWS_LINEAR) #define IN_SHADOW_PASS true #else diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 138a6c4519..2a11a1c5ee 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -1328,6 +1328,7 @@ MaterialStorage::MaterialStorage() { actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data_block.data.camera_visible_layers"; actions.renames["NODE_POSITION_VIEW"] = "(scene_data_block.data.view_matrix * model_matrix)[3].xyz"; + actions.renames["IS_MULTIVIEW"] = "OUTPUT_IS_MULTIVIEW"; actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "uint(0)"; actions.renames["VIEW_RIGHT"] = "uint(1)"; diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 043279a6c9..42f09aa397 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1367,7 +1367,15 @@ void vertex() {)"; MODELVIEW_MATRIX[2] *= sc; } else { // Scale by depth. - float sc = -(MODELVIEW_MATRIX)[3].z; + float sc; + if (IS_MULTIVIEW) { + // Assuming stereo rendering. + // Moving in the z-plane gives the illusion of the object growing/shrinking in size. + // We need to take the full distance to camera to compensate. + sc = length((MODELVIEW_MATRIX)[3].xyz); + } else { + sc = -(MODELVIEW_MATRIX)[3].z; + } MODELVIEW_MATRIX[0] *= sc; MODELVIEW_MATRIX[1] *= sc; MODELVIEW_MATRIX[2] *= sc; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index f5c07c8ffe..ce2e679f01 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -3299,6 +3299,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR_3D, "vertex", "VERTEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "vertex_id", "VERTEX_ID" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "is_multiview", "IS_MULTIVIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, @@ -3332,6 +3333,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "uv2", "UV2" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "vertex", "VERTEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "view", "VIEW" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "is_multiview", "IS_MULTIVIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_index", "VIEW_INDEX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "view_mono_left", "VIEW_MONO_LEFT" }, @@ -3366,6 +3368,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_3D, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "view_matrix", "VIEW_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR_2D, "viewport_size", "VIEWPORT_SIZE" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "is_multiview", "IS_MULTIVIEW" }, // Canvas Item diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 82a686bd1f..3f88581b6b 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -785,6 +785,7 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers"; actions.renames["NODE_POSITION_VIEW"] = "(read_view_matrix * read_model_matrix)[3].xyz"; + actions.renames["IS_MULTIVIEW"] = "OUTPUT_IS_MULTIVIEW"; actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index ddbcc4b0ed..8279cd63d9 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -719,6 +719,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.renames["CAMERA_VISIBLE_LAYERS"] = "scene_data.camera_visible_layers"; actions.renames["NODE_POSITION_VIEW"] = "(read_view_matrix * read_model_matrix)[3].xyz"; + actions.renames["IS_MULTIVIEW"] = "OUTPUT_IS_MULTIVIEW"; actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_RIGHT"] = "1"; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 2a5f6350c1..4b66ac7426 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -12,6 +12,12 @@ #define SHADER_IS_SRGB false #define SHADER_SPACE_FAR 0.0 +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + /* INPUT ATTRIBS */ // Always contains vertex position in XYZ, can contain tangent angle in W. @@ -863,6 +869,12 @@ void main() { #define SHADER_IS_SRGB false #define SHADER_SPACE_FAR 0.0 +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + /* Include half precision types. */ #include "../half_inc.glsl" diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index a1eb7aee5f..a11de549d3 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -19,6 +19,12 @@ #define IN_SHADOW_PASS false #endif +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + /* INPUT ATTRIBS */ // Always contains vertex position in XYZ, can contain tangent angle in W. @@ -826,6 +832,12 @@ void main() { #define IN_SHADOW_PASS false #endif +#ifdef USE_MULTIVIEW +#define OUTPUT_IS_MULTIVIEW true +#else +#define OUTPUT_IS_MULTIVIEW false +#endif + /* Include half precision types. */ #include "../half_inc.glsl" diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index edc2c550f9..af6948c45d 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -84,6 +84,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constvt(ShaderLanguage::TYPE_FLOAT, { e_scalar }); shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["CLIP_SPACE_FAR"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["IS_MULTIVIEW"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;