diff options
Diffstat (limited to 'drivers/gles2/rasterizer_scene_gles2.cpp')
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 132 |
1 files changed, 107 insertions, 25 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index a7becdde24..de77c2c63e 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -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"); |