You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-30 18:30:54 +00:00
OpenGL: Split the ubos for motion vectors into separate uniforms
This commit is contained in:
@@ -1477,6 +1477,19 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_update_scene_ubo(GLuint &p_ubo_buffer, GLuint p_index, uint32_t p_size, const void *p_source_data, String p_name) {
|
||||
if (p_ubo_buffer == 0) {
|
||||
glGenBuffers(1, &p_ubo_buffer);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, p_index, p_ubo_buffer);
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, p_ubo_buffer, p_size, p_source_data, GL_STREAM_DRAW, p_name);
|
||||
} else {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, p_index, p_ubo_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, p_size, p_source_data, GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
|
||||
// Needs to be called after _setup_lights so that directional_light_count is accurate.
|
||||
void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows, float p_shadow_bias) {
|
||||
Projection correction;
|
||||
@@ -1619,29 +1632,19 @@ void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_da
|
||||
scene_state.data.IBL_exposure_normalization = 1.0;
|
||||
}
|
||||
|
||||
if (scene_state.ubo_buffer == 0) {
|
||||
glGenBuffers(1, &scene_state.ubo_buffer);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.ubo_buffer, sizeof(SceneState::UBO) * 2, &scene_state.data, GL_STREAM_DRAW, "Scene state UBO");
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
} else {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_DATA_UNIFORM_LOCATION, scene_state.ubo_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::UBO) * 2, &scene_state.data, GL_STREAM_DRAW);
|
||||
_update_scene_ubo(scene_state.ubo_buffer, SCENE_DATA_UNIFORM_LOCATION, sizeof(SceneState::UBO), &scene_state.data, "Scene state UBO");
|
||||
if (p_render_data->view_count > 1) {
|
||||
_update_scene_ubo(scene_state.multiview_buffer, SCENE_MULTIVIEW_UNIFORM_LOCATION, sizeof(SceneState::MultiviewUBO), &scene_state.multiview_data, "Multiview UBO");
|
||||
}
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
if (scene_state.prev_data_state != 0) {
|
||||
void *source_data = scene_state.prev_data_state == 1 ? &scene_state.data : &scene_state.prev_data;
|
||||
_update_scene_ubo(scene_state.prev_ubo_buffer, SCENE_PREV_DATA_UNIFORM_LOCATION, sizeof(SceneState::UBO), source_data, "Previous scene state UBO");
|
||||
|
||||
if (p_render_data->view_count > 1) {
|
||||
if (scene_state.multiview_buffer == 0) {
|
||||
glGenBuffers(1, &scene_state.multiview_buffer);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
|
||||
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, scene_state.multiview_buffer, sizeof(SceneState::MultiviewUBO) * 2, &scene_state.multiview_data, GL_STREAM_DRAW, "Multiview UBO");
|
||||
} else {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, SCENE_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(SceneState::MultiviewUBO) * 2, &scene_state.multiview_data, GL_STREAM_DRAW);
|
||||
if (p_render_data->view_count > 1) {
|
||||
source_data = scene_state.prev_data_state == 1 ? &scene_state.multiview_data : &scene_state.prev_multiview_data;
|
||||
_update_scene_ubo(scene_state.prev_multiview_buffer, SCENE_PREV_MULTIVIEW_UNIFORM_LOCATION, sizeof(SceneState::MultiviewUBO), source_data, "Previous multiview UBO");
|
||||
}
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2408,6 +2411,17 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
||||
|
||||
scene_state.data.emissive_exposure_normalization = -1.0; // Use default exposure normalization.
|
||||
|
||||
bool enough_vertex_attribs_for_motion_blue = GLES3::Config::get_singleton()->max_vertex_attribs >= 22;
|
||||
if (rt && rt->overridden.velocity_fbo != 0 && enough_vertex_attribs_for_motion_blue) {
|
||||
// First frame we render motion vectors? Use our current data!
|
||||
if (scene_state.prev_data_state == 0) {
|
||||
scene_state.prev_data_state = 1;
|
||||
}
|
||||
} else {
|
||||
// Not using motion vectors? We don't need to load our data.
|
||||
scene_state.prev_data_state = 0;
|
||||
}
|
||||
|
||||
bool flip_y = !is_reflection_probe;
|
||||
|
||||
if (rt && rt->overridden.color.is_valid()) {
|
||||
@@ -2520,19 +2534,13 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
||||
scene_state.reset_gl_state();
|
||||
|
||||
GLuint motion_vectors_fbo = rt ? rt->overridden.velocity_fbo : 0;
|
||||
if (motion_vectors_fbo != 0 && GLES3::Config::get_singleton()->max_vertex_attribs >= 22) {
|
||||
if (motion_vectors_fbo != 0 && enough_vertex_attribs_for_motion_blue) {
|
||||
RENDER_TIMESTAMP("Motion Vectors Pass");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, motion_vectors_fbo);
|
||||
|
||||
Size2i motion_vectors_target_size = rt->velocity_target_size;
|
||||
glViewport(0, 0, motion_vectors_target_size.x, motion_vectors_target_size.y);
|
||||
|
||||
if (!scene_state.is_prev_data_stored) {
|
||||
scene_state.prev_data = scene_state.data;
|
||||
scene_state.prev_multiview_data = scene_state.multiview_data;
|
||||
scene_state.is_prev_data_stored = true;
|
||||
}
|
||||
|
||||
scene_state.enable_gl_depth_test(true);
|
||||
scene_state.enable_gl_depth_draw(true);
|
||||
scene_state.enable_gl_blend(false);
|
||||
@@ -2553,8 +2561,10 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
||||
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant, use_wireframe);
|
||||
_render_list_template<PASS_MODE_MOTION_VECTORS>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());
|
||||
|
||||
// Copy our current scene data to our previous scene data for use in the next frame.
|
||||
scene_state.prev_data = scene_state.data;
|
||||
scene_state.prev_multiview_data = scene_state.multiview_data;
|
||||
scene_state.prev_data_state = 2;
|
||||
}
|
||||
|
||||
GLuint fbo = 0;
|
||||
@@ -4602,10 +4612,18 @@ RasterizerSceneGLES3::~RasterizerSceneGLES3() {
|
||||
GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.ubo_buffer);
|
||||
}
|
||||
|
||||
if (scene_state.prev_ubo_buffer != 0) {
|
||||
GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.prev_ubo_buffer);
|
||||
}
|
||||
|
||||
if (scene_state.multiview_buffer != 0) {
|
||||
GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.multiview_buffer);
|
||||
}
|
||||
|
||||
if (scene_state.prev_multiview_buffer != 0) {
|
||||
GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.prev_multiview_buffer);
|
||||
}
|
||||
|
||||
if (scene_state.tonemap_buffer != 0) {
|
||||
GLES3::Utilities::get_singleton()->buffer_free_data(scene_state.tonemap_buffer);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ enum SceneUniformLocation {
|
||||
SCENE_POSITIONAL_SHADOW_UNIFORM_LOCATION,
|
||||
SCENE_DIRECTIONAL_SHADOW_UNIFORM_LOCATION,
|
||||
SCENE_EMPTY2, // Unused, put here to avoid conflicts with SKY_MULTIVIEW_UNIFORM_LOCATION.
|
||||
SCENE_PREV_DATA_UNIFORM_LOCATION,
|
||||
SCENE_PREV_MULTIVIEW_UNIFORM_LOCATION,
|
||||
};
|
||||
|
||||
enum SkyUniformLocation {
|
||||
@@ -94,6 +96,8 @@ enum SkyUniformLocation {
|
||||
SKY_EMPTY6, // Unused, put here to avoid conflicts with SCENE_POSITIONAL_SHADOW_UNIFORM_LOCATION.
|
||||
SKY_EMPTY7, // Unused, put here to avoid conflicts with SCENE_DIRECTIONAL_SHADOW_UNIFORM_LOCATION.
|
||||
SKY_MULTIVIEW_UNIFORM_LOCATION,
|
||||
SKY_EMPTY8, // Unused, put here to avoid conflicts with SCENE_PREV_DATA_UNIFORM_LOCATION.
|
||||
SKY_EMPTY9, // Unused, put here to avoid conflicts with SCENE_PREV_MULTIVIEW_UNIFORM_LOCATION.
|
||||
};
|
||||
|
||||
struct RenderDataGLES3 {
|
||||
@@ -463,12 +467,14 @@ private:
|
||||
UBO data;
|
||||
UBO prev_data;
|
||||
GLuint ubo_buffer = 0;
|
||||
GLuint prev_ubo_buffer = 0;
|
||||
MultiviewUBO multiview_data;
|
||||
MultiviewUBO prev_multiview_data;
|
||||
GLuint multiview_buffer = 0;
|
||||
GLuint prev_multiview_buffer = 0;
|
||||
GLuint tonemap_buffer = 0;
|
||||
|
||||
bool is_prev_data_stored = false;
|
||||
int prev_data_state = 0; // 0 = Motion vectors not used, 1 = use data (first frame only), 2 = use previous data
|
||||
|
||||
bool used_depth_prepass = false;
|
||||
|
||||
@@ -717,6 +723,8 @@ private:
|
||||
|
||||
RenderList render_list[RENDER_LIST_MAX];
|
||||
|
||||
void _update_scene_ubo(GLuint &p_ubo_buffer, GLuint p_index, uint32_t p_size, const void *p_source_data, String p_name = "");
|
||||
|
||||
void _setup_lights(const RenderDataGLES3 *p_render_data, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_omni_light_count, uint32_t &r_spot_light_count, uint32_t &r_directional_shadow_count);
|
||||
void _setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows, float p_shadow_bias = 0.0);
|
||||
void _fill_render_list(RenderListType p_render_list, const RenderDataGLES3 *p_render_data, PassMode p_pass_mode, bool p_append = false);
|
||||
|
||||
@@ -198,7 +198,7 @@ struct SceneData {
|
||||
float fog_aerial_perspective;
|
||||
float time;
|
||||
|
||||
mat3 radiance_inverse_xform;
|
||||
mat3x4 radiance_inverse_xform;
|
||||
|
||||
uint directional_light_count;
|
||||
float z_far;
|
||||
@@ -224,12 +224,16 @@ struct SceneData {
|
||||
bool pancake_shadows;
|
||||
};
|
||||
|
||||
// The containing data block is for historic reasons.
|
||||
layout(std140) uniform SceneDataBlock { // ubo:2
|
||||
SceneData data;
|
||||
SceneData prev_data;
|
||||
}
|
||||
scene_data_block;
|
||||
|
||||
#ifdef RENDER_MOTION_VECTORS
|
||||
layout(std140) uniform SceneData prev_scene_data; // ubo:12
|
||||
#endif
|
||||
|
||||
#ifndef RENDER_MOTION_VECTORS
|
||||
#ifdef USE_ADDITIVE_LIGHTING
|
||||
|
||||
@@ -456,10 +460,14 @@ struct MultiviewData {
|
||||
|
||||
layout(std140) uniform MultiviewDataBlock { // ubo:8
|
||||
MultiviewData data;
|
||||
MultiviewData prev_data;
|
||||
}
|
||||
multiview_data_block;
|
||||
#endif
|
||||
|
||||
#ifdef RENDER_MOTION_VECTORS
|
||||
layout(std140) uniform MultiviewData prev_multiview_data; // ubo:13
|
||||
#endif // RENDER_MOTION_VECTORS
|
||||
|
||||
#endif // USE_MULTIVIEW
|
||||
|
||||
uniform highp mat4 world_transform;
|
||||
uniform highp vec3 compressed_aabb_position;
|
||||
@@ -901,7 +909,7 @@ void main() {
|
||||
compressed_aabb_position,
|
||||
prev_world_transform,
|
||||
model_flags,
|
||||
scene_data_block.prev_data,
|
||||
prev_scene_data.data,
|
||||
#ifdef USE_INSTANCING
|
||||
input_instance_xform0, input_instance_xform1, input_instance_xform2,
|
||||
input_instance_color_custom_data,
|
||||
@@ -919,9 +927,9 @@ void main() {
|
||||
uv2_attrib,
|
||||
#endif
|
||||
#ifdef USE_MULTIVIEW
|
||||
multiview_data_block.prev_data.projection_matrix_view[ViewIndex],
|
||||
multiview_data_block.prev_data.inv_projection_matrix_view[ViewIndex],
|
||||
multiview_data_block.prev_data.eye_offset[ViewIndex].xyz,
|
||||
prev_multiview_data.projection_matrix_view[ViewIndex],
|
||||
prev_multiview_data.inv_projection_matrix_view[ViewIndex],
|
||||
prev_multiview_data.eye_offset[ViewIndex].xyz,
|
||||
#endif
|
||||
uv_scale,
|
||||
prev_clip_position);
|
||||
@@ -1146,7 +1154,7 @@ struct SceneData {
|
||||
float fog_aerial_perspective;
|
||||
float time;
|
||||
|
||||
mat3 radiance_inverse_xform;
|
||||
mat3x4 radiance_inverse_xform;
|
||||
|
||||
uint directional_light_count;
|
||||
float z_far;
|
||||
@@ -1174,7 +1182,6 @@ struct SceneData {
|
||||
|
||||
layout(std140) uniform SceneDataBlock { // ubo:2
|
||||
SceneData data;
|
||||
SceneData prev_data;
|
||||
}
|
||||
scene_data_block;
|
||||
|
||||
@@ -1187,7 +1194,6 @@ struct MultiviewData {
|
||||
|
||||
layout(std140) uniform MultiviewDataBlock { // ubo:8
|
||||
MultiviewData data;
|
||||
MultiviewData prev_data;
|
||||
}
|
||||
multiview_data_block;
|
||||
#endif
|
||||
@@ -2205,7 +2211,7 @@ void main() {
|
||||
#endif
|
||||
ref_vec = mix(ref_vec, normal, roughness * roughness);
|
||||
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
|
||||
ref_vec = scene_data_block.data.radiance_inverse_xform * ref_vec;
|
||||
ref_vec = mat3(scene_data_block.data.radiance_inverse_xform) * ref_vec;
|
||||
specular_light = textureLod(radiance_map, ref_vec, sqrt(roughness) * RADIANCE_MAX_LOD).rgb;
|
||||
specular_light = srgb_to_linear(specular_light);
|
||||
specular_light *= horizon * horizon;
|
||||
@@ -2250,7 +2256,7 @@ void main() {
|
||||
|
||||
#ifdef USE_RADIANCE_MAP
|
||||
if (scene_data_block.data.use_ambient_cubemap) {
|
||||
vec3 ambient_dir = scene_data_block.data.radiance_inverse_xform * normal;
|
||||
vec3 ambient_dir = mat3(scene_data_block.data.radiance_inverse_xform) * normal;
|
||||
vec3 cubemap_ambient = textureLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).rgb;
|
||||
cubemap_ambient = srgb_to_linear(cubemap_ambient);
|
||||
ambient_light = mix(ambient_light, cubemap_ambient * scene_data_block.data.ambient_light_color_energy.a, scene_data_block.data.ambient_color_sky_mix);
|
||||
|
||||
Reference in New Issue
Block a user