|
@@ -62,6 +62,7 @@ RID RasterizerSceneGLES2::shadow_atlas_create() {
|
|
|
ShadowAtlas *shadow_atlas = memnew(ShadowAtlas);
|
|
|
shadow_atlas->fbo = 0;
|
|
|
shadow_atlas->depth = 0;
|
|
|
+ shadow_atlas->color = 0;
|
|
|
shadow_atlas->size = 0;
|
|
|
shadow_atlas->smallest_subdiv = 0;
|
|
|
|
|
@@ -86,9 +87,13 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
|
|
if (shadow_atlas->fbo) {
|
|
|
glDeleteTextures(1, &shadow_atlas->depth);
|
|
|
glDeleteFramebuffers(1, &shadow_atlas->fbo);
|
|
|
+ if (shadow_atlas->color) {
|
|
|
+ glDeleteTextures(1, &shadow_atlas->color);
|
|
|
+ }
|
|
|
|
|
|
shadow_atlas->fbo = 0;
|
|
|
shadow_atlas->depth = 0;
|
|
|
+ shadow_atlas->color = 0;
|
|
|
}
|
|
|
|
|
|
// erase shadow atlast references from lights
|
|
@@ -119,6 +124,16 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
|
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0);
|
|
|
|
|
|
+ if (storage->config.use_rgba_3d_shadows) {
|
|
|
+ glGenTextures(1, &shadow_atlas->color);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shadow_atlas->size, shadow_atlas->size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shadow_atlas->color, 0);
|
|
|
+ }
|
|
|
glViewport(0, 0, shadow_atlas->size, shadow_atlas->size);
|
|
|
|
|
|
glDepthMask(GL_TRUE);
|
|
@@ -459,10 +474,10 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
|
|
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
glGenFramebuffers(1, &rpi->fbo[i]);
|
|
|
+ glGenTextures(1, &rpi->color[i]);
|
|
|
}
|
|
|
|
|
|
- glGenFramebuffers(1, &rpi->fbo_blur);
|
|
|
- glGenRenderbuffers(1, &rpi->depth);
|
|
|
+ glGenTextures(1, &rpi->depth);
|
|
|
rpi->cubemap = 0;
|
|
|
//glGenTextures(1, &rpi->cubemap);
|
|
|
|
|
@@ -510,9 +525,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
|
|
|
GLenum type = GL_UNSIGNED_BYTE;
|
|
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
+
|
|
|
+ glBindTexture(GL_TEXTURE_2D, rpi->depth);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
|
|
+
|
|
|
if (rpi->cubemap != 0) {
|
|
|
glDeleteTextures(1, &rpi->cubemap);
|
|
|
}
|
|
|
+
|
|
|
glGenTextures(1, &rpi->cubemap);
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
|
|
|
#if 1
|
|
@@ -523,17 +543,15 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
|
|
|
|
|
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
|
|
|
|
|
- glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
|
|
|
-#ifdef JAVASCRIPT_ENABLED
|
|
|
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
|
|
|
-#else
|
|
|
- glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
|
|
|
-#endif
|
|
|
-
|
|
|
+ //Generate framebuffers for rendering
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
|
|
|
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
|
|
|
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, rpi->color[i]);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size, 0, format, type, NULL);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rpi->color[i], 0);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rpi->depth, 0);
|
|
|
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
+ ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
|
|
|
}
|
|
|
|
|
|
#else
|
|
@@ -570,6 +588,8 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
|
|
|
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);
|
|
|
+
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
@@ -579,6 +599,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
|
|
|
|
|
|
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
|
|
|
ERR_FAIL_COND_V(!rpi, false);
|
|
|
+ ERR_FAIL_COND_V(rpi->current_resolution == 0, false);
|
|
|
|
|
|
int size = rpi->probe_ptr->resolution;
|
|
|
|
|
@@ -596,16 +617,23 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ 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
|
|
|
+
|
|
|
+ //first of all, copy rendered textures to cubemap
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
|
|
|
+ glViewport(0, 0, size, size);
|
|
|
+ glCopyTexImage2D(_cube_side_enum[i], 0, GL_RGB, 0, 0, size, size, 0);
|
|
|
+ }
|
|
|
+ //do filtering
|
|
|
//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;
|
|
@@ -613,13 +641,20 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
|
|
|
storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, false);
|
|
|
storage->shaders.cubemap_filter.bind();
|
|
|
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->resources.mipmap_blur_fbo);
|
|
|
+
|
|
|
//blur
|
|
|
while (size >= 1) {
|
|
|
|
|
|
+ glActiveTexture(GL_TEXTURE3);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, storage->resources.mipmap_blur_color);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, storage->resources.mipmap_blur_color, 0);
|
|
|
+ glViewport(0, 0, size, size);
|
|
|
+ glActiveTexture(GL_TEXTURE0);
|
|
|
+
|
|
|
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);
|
|
@@ -627,6 +662,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
|
|
|
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::Z_FLIP, false);
|
|
|
|
|
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
|
+ glCopyTexImage2D(_cube_side_enum[i], lod, GL_RGB, 0, 0, size, size, 0);
|
|
|
}
|
|
|
|
|
|
size >>= 1;
|
|
@@ -635,9 +671,14 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
|
|
|
}
|
|
|
|
|
|
// restore ranges
|
|
|
-
|
|
|
+ glActiveTexture(GL_TEXTURE0);
|
|
|
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
|
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
+ glActiveTexture(GL_TEXTURE3); //back to panorama
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
+ glActiveTexture(GL_TEXTURE1);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -1751,7 +1792,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
|
|
|
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);
|
|
|
+ if (storage->config.use_rgba_3d_shadows) {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
|
|
|
+ } else {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
|
|
|
+ }
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
|
|
|
}
|
|
@@ -1763,7 +1808,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
|
|
|
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);
|
|
|
+ if (storage->config.use_rgba_3d_shadows) {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
|
|
|
+ } else {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
|
|
+ }
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
|
|
|
}
|
|
@@ -1774,7 +1823,11 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
|
|
|
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);
|
|
|
+ if (storage->config.use_rgba_3d_shadows) {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->color);
|
|
|
+ } else {
|
|
|
+ glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
|
|
+ }
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
|
|
|
state.scene_shader.set_conditional(SceneShaderGLES2::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
|
|
|
}
|
|
@@ -2041,7 +2094,7 @@ void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1
|
|
|
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_EXTERIOR, p_refprobe2->probe_ptr->interior);
|
|
|
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE2_INTENSITY, p_refprobe2->probe_ptr->intensity);
|
|
|
|
|
|
Color ambient;
|
|
@@ -2737,6 +2790,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
|
|
|
|
|
if (probe_interior) {
|
|
|
env_radiance_tex = 0; //do not use radiance texture on interiors
|
|
|
+ state.default_ambient = Color(0, 0, 0, 1); //black as default ambient for interior
|
|
|
}
|
|
|
|
|
|
// render opaque things first
|
|
@@ -2994,7 +3048,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
|
|
|
|
glDepthMask(GL_TRUE);
|
|
|
- glColorMask(0, 0, 0, 0);
|
|
|
+ if (!storage->config.use_rgba_3d_shadows) {
|
|
|
+ glColorMask(0, 0, 0, 0);
|
|
|
+ }
|
|
|
|
|
|
if (custom_vp_size) {
|
|
|
glViewport(0, 0, custom_vp_size, custom_vp_size);
|
|
@@ -3070,7 +3126,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
|
|
|
if (storage->frame.current_rt) {
|
|
|
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
|
|
|
}
|
|
|
- glColorMask(1, 1, 1, 1);
|
|
|
+ if (!storage->config.use_rgba_3d_shadows) {
|
|
|
+ glColorMask(1, 1, 1, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
|
|
@@ -3108,6 +3166,16 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
|
|
|
|
|
|
ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.get(p_rid);
|
|
|
|
|
|
+ for (int i = 0; i < 6; i++) {
|
|
|
+ glDeleteFramebuffers(1, &reflection_instance->fbo[i]);
|
|
|
+ glDeleteTextures(1, &reflection_instance->color[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (reflection_instance->cubemap != 0) {
|
|
|
+ glDeleteTextures(1, &reflection_instance->cubemap);
|
|
|
+ }
|
|
|
+ glDeleteTextures(1, &reflection_instance->depth);
|
|
|
+
|
|
|
reflection_probe_release_atlas_index(p_rid);
|
|
|
reflection_probe_instance_owner.free(p_rid);
|
|
|
memdelete(reflection_instance);
|
|
@@ -3124,6 +3192,8 @@ void RasterizerSceneGLES2::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_dra
|
|
|
|
|
|
void RasterizerSceneGLES2::initialize() {
|
|
|
state.scene_shader.init();
|
|
|
+
|
|
|
+ state.scene_shader.set_conditional(SceneShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_3d_shadows);
|
|
|
state.cube_to_dp_shader.init();
|
|
|
|
|
|
render_list.init();
|
|
@@ -3202,6 +3272,7 @@ void RasterizerSceneGLES2::initialize() {
|
|
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
|
|
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
+
|
|
|
glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
|
|
}
|
|
|
|
|
@@ -3245,6 +3316,17 @@ void RasterizerSceneGLES2::initialize() {
|
|
|
|
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, directional_shadow.depth, 0);
|
|
|
|
|
|
+ if (storage->config.use_rgba_3d_shadows) {
|
|
|
+ glGenTextures(1, &directional_shadow.color);
|
|
|
+ glBindTexture(GL_TEXTURE_2D, directional_shadow.color);
|
|
|
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, directional_shadow.size, directional_shadow.size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
|
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
|
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, directional_shadow.color, 0);
|
|
|
+ }
|
|
|
+
|
|
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
|
|
ERR_PRINT("Directional shadow framebuffer status invalid");
|