You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Fix sky rendering with multiview in OpenGL
This commit is contained in:
@@ -731,6 +731,11 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_render_data->view_count > 1) {
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!sky->radiance) {
|
if (!sky->radiance) {
|
||||||
_invalidate_sky(sky);
|
_invalidate_sky(sky);
|
||||||
_update_dirty_skys();
|
_update_dirty_skys();
|
||||||
@@ -738,7 +743,7 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier) {
|
void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier, bool p_use_multiview, bool p_flip_y) {
|
||||||
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
|
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
|
||||||
ERR_FAIL_COND(p_env.is_null());
|
ERR_FAIL_COND(p_env.is_null());
|
||||||
|
|
||||||
@@ -748,6 +753,11 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
|
|||||||
GLES3::SkyMaterialData *material_data = nullptr;
|
GLES3::SkyMaterialData *material_data = nullptr;
|
||||||
RID sky_material;
|
RID sky_material;
|
||||||
|
|
||||||
|
uint64_t spec_constants = p_use_multiview ? SkyShaderGLES3::USE_MULTIVIEW : 0;
|
||||||
|
if (p_flip_y) {
|
||||||
|
spec_constants |= SkyShaderGLES3::USE_INVERTED_Y;
|
||||||
|
}
|
||||||
|
|
||||||
RS::EnvironmentBG background = environment_get_background(p_env);
|
RS::EnvironmentBG background = environment_get_background(p_env);
|
||||||
|
|
||||||
if (sky) {
|
if (sky) {
|
||||||
@@ -792,16 +802,21 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
|
|||||||
sky_transform.invert();
|
sky_transform.invert();
|
||||||
sky_transform = sky_transform * p_transform.basis;
|
sky_transform = sky_transform * p_transform.basis;
|
||||||
|
|
||||||
bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
bool success = material_storage->shaders.sky_shader.version_bind_shader(shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::ORIENTATION, sky_transform, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::PROJECTION, camera.columns[2][0], camera.columns[0][0], camera.columns[2][1], camera.columns[1][1], shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::POSITION, p_transform.origin, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::TIME, time, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND);
|
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
|
||||||
|
|
||||||
|
if (p_use_multiview) {
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
glBindVertexArray(sky_globals.screen_triangle_array);
|
glBindVertexArray(sky_globals.screen_triangle_array);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
@@ -1975,7 +1990,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||||||
scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
|
scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
|
||||||
scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
|
scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;
|
||||||
|
|
||||||
_draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier);
|
_draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier, p_camera_data->view_count > 1, flip_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Render 3D Transparent Pass");
|
RENDER_TIMESTAMP("Render 3D Transparent Pass");
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ enum SkyUniformLocation {
|
|||||||
SKY_EMPTY, // Unused, put here to avoid conflicts with SCENE_DATA_UNIFORM_LOCATION.
|
SKY_EMPTY, // Unused, put here to avoid conflicts with SCENE_DATA_UNIFORM_LOCATION.
|
||||||
SKY_MATERIAL_UNIFORM_LOCATION,
|
SKY_MATERIAL_UNIFORM_LOCATION,
|
||||||
SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION,
|
SKY_DIRECTIONAL_LIGHT_UNIFORM_LOCATION,
|
||||||
|
SKY_MULTIVIEW_UNIFORM_LOCATION,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RenderDataGLES3 {
|
struct RenderDataGLES3 {
|
||||||
@@ -570,7 +571,7 @@ protected:
|
|||||||
void _update_dirty_skys();
|
void _update_dirty_skys();
|
||||||
void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier);
|
void _update_sky_radiance(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier);
|
||||||
void _filter_sky_radiance(Sky *p_sky, int p_base_layer);
|
void _filter_sky_radiance(Sky *p_sky, int p_base_layer);
|
||||||
void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier);
|
void _draw_sky(RID p_env, const Projection &p_projection, const Transform3D &p_transform, float p_luminance_multiplier, bool p_use_multiview, bool p_flip_y);
|
||||||
void _free_sky_data(Sky *p_sky);
|
void _free_sky_data(Sky *p_sky);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ mode_cubemap_quarter_res = #define USE_CUBEMAP_PASS \n#define USE_QUARTER_RES_PA
|
|||||||
|
|
||||||
#[specializations]
|
#[specializations]
|
||||||
|
|
||||||
|
USE_MULTIVIEW = false
|
||||||
|
USE_INVERTED_Y = true
|
||||||
|
|
||||||
#[vertex]
|
#[vertex]
|
||||||
|
|
||||||
layout(location = 0) in vec2 vertex_attrib;
|
layout(location = 0) in vec2 vertex_attrib;
|
||||||
@@ -19,7 +22,11 @@ out vec2 uv_interp;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
uv_interp = vertex_attrib;
|
uv_interp = vertex_attrib;
|
||||||
|
#ifdef USE_INVERTED_Y
|
||||||
gl_Position = vec4(uv_interp, 1.0, 1.0);
|
gl_Position = vec4(uv_interp, 1.0, 1.0);
|
||||||
|
#else
|
||||||
|
gl_Position = vec4(uv_interp.x, uv_interp.y * -1.0, 1.0, 1.0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
@@ -37,6 +44,9 @@ uniform samplerCube radiance; //texunit:-1
|
|||||||
#ifdef USE_CUBEMAP_PASS
|
#ifdef USE_CUBEMAP_PASS
|
||||||
uniform samplerCube half_res; //texunit:-2
|
uniform samplerCube half_res; //texunit:-2
|
||||||
uniform samplerCube quarter_res; //texunit:-3
|
uniform samplerCube quarter_res; //texunit:-3
|
||||||
|
#elif defined(USE_MULTIVIEW)
|
||||||
|
uniform sampler2DArray half_res; //texunit:-2
|
||||||
|
uniform sampler2DArray quarter_res; //texunit:-3
|
||||||
#else
|
#else
|
||||||
uniform sampler2D half_res; //texunit:-2
|
uniform sampler2D half_res; //texunit:-2
|
||||||
uniform sampler2D quarter_res; //texunit:-3
|
uniform sampler2D quarter_res; //texunit:-3
|
||||||
@@ -102,6 +112,15 @@ uniform float fog_density;
|
|||||||
uniform float z_far;
|
uniform float z_far;
|
||||||
uniform uint directional_light_count;
|
uniform uint directional_light_count;
|
||||||
|
|
||||||
|
#ifdef USE_MULTIVIEW
|
||||||
|
layout(std140) uniform MultiviewData { // ubo:5
|
||||||
|
highp mat4 projection_matrix_view[MAX_VIEWS];
|
||||||
|
highp mat4 inv_projection_matrix_view[MAX_VIEWS];
|
||||||
|
highp vec4 eye_offset[MAX_VIEWS];
|
||||||
|
}
|
||||||
|
multiview_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
layout(location = 0) out vec4 frag_color;
|
layout(location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
#ifdef USE_DEBANDING
|
#ifdef USE_DEBANDING
|
||||||
@@ -115,9 +134,20 @@ vec3 interleaved_gradient_noise(vec2 pos) {
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec3 cube_normal;
|
vec3 cube_normal;
|
||||||
|
#ifdef USE_MULTIVIEW
|
||||||
|
// In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
|
||||||
|
vec4 unproject = vec4(uv_interp.x, uv_interp.y, 1.0, 1.0);
|
||||||
|
vec4 unprojected = multiview_data.inv_projection_matrix_view[ViewIndex] * unproject;
|
||||||
|
cube_normal = unprojected.xyz / unprojected.w;
|
||||||
|
cube_normal += multiview_data.eye_offset[ViewIndex].xyz;
|
||||||
|
#else
|
||||||
cube_normal.z = -1.0;
|
cube_normal.z = -1.0;
|
||||||
cube_normal.x = (uv_interp.x + projection.x) / projection.y;
|
cube_normal.x = (uv_interp.x + projection.x) / projection.y;
|
||||||
cube_normal.y = (-uv_interp.y - projection.z) / projection.w;
|
cube_normal.y = (-uv_interp.y - projection.z) / projection.w;
|
||||||
|
#endif
|
||||||
|
#ifndef USE_INVERTED_Y
|
||||||
|
cube_normal.y *= -1.0;
|
||||||
|
#endif
|
||||||
cube_normal = mat3(orientation) * cube_normal;
|
cube_normal = mat3(orientation) * cube_normal;
|
||||||
cube_normal = normalize(cube_normal);
|
cube_normal = normalize(cube_normal);
|
||||||
|
|
||||||
@@ -146,11 +176,19 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#ifdef USES_HALF_RES_COLOR
|
#ifdef USES_HALF_RES_COLOR
|
||||||
|
#ifdef USE_MULTIVIEW
|
||||||
|
half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0);
|
||||||
|
#else
|
||||||
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef USES_QUARTER_RES_COLOR
|
#ifdef USES_QUARTER_RES_COLOR
|
||||||
|
#ifdef USE_MULTIVIEW
|
||||||
|
quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0);
|
||||||
|
#else
|
||||||
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user