summaryrefslogtreecommitdiffstats
path: root/drivers/gles2/rasterizer_scene_gles2.cpp
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2018-09-28 16:40:20 -0300
committerJuan Linietsky <reduzio@gmail.com>2018-09-28 16:42:47 -0300
commitf2ed26d71e20b92dbf21693eeea36ccfcc50ced6 (patch)
tree641b343f7fac36eb4b951c6effb33dbb5a86a51a /drivers/gles2/rasterizer_scene_gles2.cpp
parent40c3c8745df3d08065802762e236beeaa6aa1345 (diff)
downloadredot-engine-f2ed26d71e20b92dbf21693eeea36ccfcc50ced6.tar.gz
Reflection probe support in GLES2 back-end.
Diffstat (limited to 'drivers/gles2/rasterizer_scene_gles2.cpp')
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp341
1 files changed, 319 insertions, 22 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 7b05d9a231..63a71f2ba8 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -437,29 +437,182 @@ void RasterizerSceneGLES2::reflection_atlas_set_subdivision(RID p_ref_atlas, int
////////////////////////////////////////////////////
RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
- return RID();
+
+ RasterizerStorageGLES2::ReflectionProbe *probe = storage->reflection_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND_V(!probe, RID());
+
+ ReflectionProbeInstance *rpi = memnew(ReflectionProbeInstance);
+
+ rpi->probe_ptr = probe;
+ rpi->self = reflection_probe_instance_owner.make_rid(rpi);
+ rpi->probe = p_probe;
+ rpi->reflection_atlas_index = -1;
+ rpi->render_step = -1;
+ rpi->last_pass = 0;
+ rpi->current_resolution = 0;
+ rpi->dirty = true;
+
+ rpi->last_pass = 0;
+ rpi->index = 0;
+
+ for (int i = 0; i < 6; i++) {
+ glGenFramebuffers(1, &rpi->fbo[i]);
+ }
+
+ glGenFramebuffers(1, &rpi->fbo_blur);
+ glGenRenderbuffers(1, &rpi->depth);
+ glGenTextures(1, &rpi->cubemap);
+
+ return rpi->self;
}
void RasterizerSceneGLES2::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {
+
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!rpi);
+ rpi->transform = p_transform;
}
void RasterizerSceneGLES2::reflection_probe_release_atlas_index(RID p_instance) {
}
bool RasterizerSceneGLES2::reflection_probe_instance_needs_redraw(RID p_instance) {
- return false;
+ const ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!rpi, false);
+
+ bool need_redraw = rpi->probe_ptr->resolution != rpi->current_resolution || rpi->dirty || rpi->probe_ptr->update_mode == VS::REFLECTION_PROBE_UPDATE_ALWAYS;
+ rpi->dirty = false;
+ return need_redraw;
}
bool RasterizerSceneGLES2::reflection_probe_instance_has_reflection(RID p_instance) {
- return false;
+ return true;
}
bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
- return false;
+
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!rpi, false);
+
+ rpi->render_step = 0;
+
+ if (rpi->probe_ptr->resolution != rpi->current_resolution) {
+
+ //update cubemap if resolution changed
+ int size = rpi->probe_ptr->resolution;
+ rpi->current_resolution = size;
+
+ int lod = 0;
+
+ GLenum internal_format = GL_RGBA;
+ GLenum format = GL_RGBA;
+ GLenum type = GL_UNSIGNED_BYTE;
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
+
+ // Set the initial (empty) mipmaps, all need to be set for this to work in GLES2, even if later wont be used.
+ while (size >= 1) {
+
+ for (int i = 0; i < 6; i++) {
+ glTexImage2D(_cube_side_enum[i], lod, internal_format, size, size, 0, format, type, NULL);
+ if (size == rpi->current_resolution) {
+ //adjust framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
+ glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
+
+#ifdef DEBUG_ENABLED
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
+#endif
+ }
+ }
+
+ lod++;
+
+ size >>= 1;
+ }
+
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ }
+
+ return true;
}
bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_instance) {
- return false;
+
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
+ ERR_FAIL_COND_V(!rpi, false);
+
+ int size = rpi->probe_ptr->resolution;
+
+ {
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glDisable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+ glDepthMask(GL_FALSE);
+
+ for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
+ glDisableVertexAttribArray(i);
+ }
+ }
+
+ //vdc cache
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.radical_inverse_vdc_cache_tex);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo_blur);
+ // now render to the framebuffer, mipmap level for mipmap level
+ int lod = 1;
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //use linear, no mipmaps so it does not read from what is being written to
+
+ size >>= 1;
+ int mipmaps = 6;
+ int mm_level = mipmaps - 1;
+
+ storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
+ storage->shaders.cubemap_filter.bind();
+
+ //blur
+ while (size >= 1) {
+
+ for (int i = 0; i < 6; i++) {
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, lod);
+
+ glViewport(0, 0, size, size);
+ storage->bind_quad_array();
+ storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
+ float roughness = CLAMP(lod / (float)(mipmaps - 1), 0, 1);
+ storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::ROUGHNESS, roughness);
+ storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ size >>= 1;
+
+ mm_level--;
+
+ lod++;
+ }
+
+ // restore ranges
+
+ glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return true;
}
/* ENVIRONMENT API */
@@ -779,17 +932,37 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
e->material_index = e->material->index;
- e->refprobe_0_index = 0xFF; //refprobe disabled by default
- e->refprobe_1_index = 0xFF; //refprobe disabled by default
+ e->refprobe_0_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default
+ e->refprobe_1_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default
if (!p_depth_pass) {
e->depth_layer = e->instance->depth_layer;
e->priority = p_material->render_priority;
- //if (e->instance->reflection_probe_instances.size() > 0 ) {
- // RasterizerStorageGLES2::
- //}
+ int rpsize = e->instance->reflection_probe_instances.size();
+ if (rpsize > 0) {
+ bool first = true;
+ for (int i = 0; i < rpsize; i++) {
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(e->instance->reflection_probe_instances[i]);
+ if (rpi->last_pass != render_pass) {
+ continue;
+ }
+ if (first) {
+ e->refprobe_0_index = rpi->index;
+ first = false;
+ } else {
+ e->refprobe_1_index = rpi->index;
+ break;
+ }
+ }
+
+ if (e->refprobe_0_index > e->refprobe_1_index) { //if both are valid, swap them to keep order as best as possible
+ uint16_t tmp = e->refprobe_0_index;
+ e->refprobe_0_index = e->refprobe_1_index;
+ e->refprobe_1_index = tmp;
+ }
+ }
//add directional lights
@@ -1505,7 +1678,7 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
}
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, p_light->light_ptr->directional_blend_splits);
- if (p_light->light_ptr->shadow) {
+ if (!state.render_no_shadows && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
@@ -1517,7 +1690,7 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
case VS::LIGHT_OMNI: {
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_OMNI, true);
- if (shadow_atlas && p_light->light_ptr->shadow) {
+ if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
@@ -1528,7 +1701,7 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
case VS::LIGHT_SPOT: {
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_SPOT, true);
- if (shadow_atlas && p_light->light_ptr->shadow) {
+ if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
@@ -1562,7 +1735,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
CameraMatrix matrices[4];
- if (light_ptr->shadow && directional_shadow.depth) {
+ if (!state.render_no_shadows && light_ptr->shadow && directional_shadow.depth) {
int shadow_count = 0;
Color split_offsets;
@@ -1657,7 +1830,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
attenuation.a = light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_ATTENUATION, attenuation);
- if (light_ptr->shadow && shadow_atlas->shadow_owners.has(light->self)) {
+ if (!state.render_no_shadows && light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(light->self)) {
uint32_t key = shadow_atlas->shadow_owners[light->self];
@@ -1719,7 +1892,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPOT_ANGLE, angle);
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_RANGE, range);
- if (light->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(light->self)) {
+ if (!state.render_no_shadows && light->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(light->self)) {
uint32_t key = shadow_atlas->shadow_owners[light->self];
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x03;
@@ -1768,13 +1941,60 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
}
}
+void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env) {
+
+ if (p_refprobe1) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_USE_BOX_PROJECT, p_refprobe1->probe_ptr->box_projection);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_BOX_EXTENTS, p_refprobe1->probe_ptr->extents);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_BOX_OFFSET, p_refprobe1->probe_ptr->origin_offset);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_EXTERIOR, !p_refprobe1->probe_ptr->interior);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_INTENSITY, p_refprobe1->probe_ptr->intensity);
+
+ Color ambient;
+ if (p_refprobe1->probe_ptr->interior) {
+ ambient = p_refprobe1->probe_ptr->interior_ambient * p_refprobe1->probe_ptr->interior_ambient_energy;
+ ambient.a = p_refprobe1->probe_ptr->interior_ambient_probe_contrib;
+ } else if (p_env) {
+ ambient = p_env->ambient_color * p_env->ambient_energy;
+ ambient.a = p_env->ambient_sky_contribution;
+ }
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_AMBIENT, ambient);
+
+ Transform proj = (p_view_transform.inverse() * p_refprobe1->transform).affine_inverse();
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_LOCAL_MATRIX, proj);
+ }
+
+ if (p_refprobe2) {
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_USE_BOX_PROJECT, p_refprobe2->probe_ptr->box_projection);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_EXTENTS, p_refprobe2->probe_ptr->extents);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_BOX_OFFSET, p_refprobe2->probe_ptr->origin_offset);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_EXTERIOR, !p_refprobe2->probe_ptr->interior);
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_INTENSITY, p_refprobe2->probe_ptr->intensity);
+
+ Color ambient;
+ if (p_refprobe2->probe_ptr->interior) {
+ ambient = p_refprobe2->probe_ptr->interior_ambient * p_refprobe2->probe_ptr->interior_ambient_energy;
+ ambient.a = p_refprobe2->probe_ptr->interior_ambient_probe_contrib;
+ } else if (p_env) {
+ ambient = p_env->ambient_color * p_env->ambient_energy;
+ ambient.a = p_env->ambient_sky_contribution;
+ }
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_AMBIENT, ambient);
+
+ Transform proj = (p_view_transform.inverse() * p_refprobe2->transform).affine_inverse();
+
+ state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_LOCAL_MATRIX, proj);
+ }
+}
+
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
- Vector2 screen_pixel_size;
- screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
- screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
+ Vector2 screen_pixel_size = state.screen_pixel_size;
bool use_radiance_map = false;
if (!p_shadow && p_base_env) {
@@ -1797,6 +2017,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool prev_base_pass = false;
LightInstance *prev_light = NULL;
bool prev_vertex_lit = false;
+ ReflectionProbeInstance *prev_refprobe_1 = NULL;
+ ReflectionProbeInstance *prev_refprobe_2 = NULL;
int prev_blend_mode = -2; //will always catch the first go
@@ -1815,6 +2037,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool accum_pass = *e->use_accum_ptr;
*e->use_accum_ptr = true; //set to accum for next time this is found
LightInstance *light = NULL;
+ ReflectionProbeInstance *refprobe_1 = NULL;
+ ReflectionProbeInstance *refprobe_2 = NULL;
if (!p_shadow) {
@@ -1911,6 +2135,27 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, vertex_lit);
prev_vertex_lit = vertex_lit;
}
+
+ if (!unshaded && !accum_pass && e->refprobe_0_index != RenderList::MAX_REFLECTION_PROBES) {
+ refprobe_1 = reflection_probe_instances[e->refprobe_0_index];
+ }
+ if (!unshaded && !accum_pass && e->refprobe_1_index != RenderList::MAX_REFLECTION_PROBES) {
+ refprobe_2 = reflection_probe_instances[e->refprobe_1_index];
+ }
+
+ if (refprobe_1 != prev_refprobe_1 || refprobe_2 != prev_refprobe_2) {
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE1, refprobe_1 != NULL);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, refprobe_2 != NULL);
+ if (refprobe_1 != NULL && refprobe_1 != prev_refprobe_1) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, refprobe_1->cubemap);
+ }
+ if (refprobe_2 != NULL && refprobe_2 != prev_refprobe_2) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, refprobe_2->cubemap);
+ }
+ rebind = true;
+ }
}
bool instancing = e->instancing;
@@ -1975,6 +2220,10 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (light) {
_setup_light(light, shadow_atlas, p_view_transform);
}
+
+ if (refprobe_1 || refprobe_2) {
+ _setup_refprobes(refprobe_1, refprobe_2, p_view_transform, p_env);
+ }
}
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, view_transform_inverse);
@@ -1997,6 +2246,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
prev_skeleton = skeleton;
prev_instancing = instancing;
prev_light = light;
+ prev_refprobe_1 = refprobe_1;
+ prev_refprobe_2 = refprobe_2;
}
_setup_light_type(NULL, NULL); //clear light stuff
@@ -2007,6 +2258,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false);
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE1, false);
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, false);
}
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
@@ -2101,6 +2354,36 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
+ GLuint current_fb = 0;
+ Environment *env = NULL;
+
+ int viewport_width, viewport_height;
+
+ if (p_reflection_probe.is_valid()) {
+ ReflectionProbeInstance *probe = reflection_probe_instance_owner.getornull(p_reflection_probe);
+ ERR_FAIL_COND(!probe);
+ state.render_no_shadows = !probe->probe_ptr->enable_shadows;
+
+ if (!probe->probe_ptr->interior) { //use env only if not interior
+ env = environment_owner.getornull(p_environment);
+ }
+
+ current_fb = probe->fbo[p_reflection_probe_pass];
+ state.screen_pixel_size.x = 1.0 / probe->probe_ptr->resolution;
+ state.screen_pixel_size.y = 1.0 / probe->probe_ptr->resolution;
+
+ viewport_width = probe->probe_ptr->resolution;
+ viewport_height = probe->probe_ptr->resolution;
+
+ } else {
+ state.render_no_shadows = false;
+ current_fb = storage->frame.current_rt->fbo;
+ env = environment_owner.getornull(p_environment);
+ state.screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
+ state.screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
+ viewport_width = storage->frame.current_rt->width;
+ viewport_height = storage->frame.current_rt->height;
+ }
//push back the directional lights
if (p_light_cull_count) {
@@ -2133,10 +2416,21 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
render_light_instance_count = 0;
}
- glEnable(GL_BLEND);
+ if (p_reflection_probe_cull_count) {
+
+ reflection_probe_instances = (ReflectionProbeInstance **)alloca(sizeof(ReflectionProbeInstance *) * p_reflection_probe_cull_count);
- GLuint current_fb = storage->frame.current_rt->fbo;
- Environment *env = environment_owner.getornull(p_environment);
+ for (int i = 0; i < p_reflection_probe_cull_count; i++) {
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_reflection_probe_cull_result[i]);
+ ERR_CONTINUE(!rpi);
+ rpi->last_pass = render_pass + 1; //will be incremented later
+ rpi->index = i;
+ reflection_probe_instances[i] = rpi;
+ }
+
+ } else {
+ reflection_probe_instances = NULL;
+ }
// render list stuff
@@ -2146,6 +2440,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// other stuff
glBindFramebuffer(GL_FRAMEBUFFER, current_fb);
+ glViewport(0, 0, viewport_width, viewport_height);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
@@ -2247,6 +2542,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
+ state.render_no_shadows = false;
+
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);