diff options
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 23 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 310 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 17 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 214 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 40 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 88 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/copy.glsl | 27 | ||||
-rw-r--r-- | drivers/gles3/shaders/cubemap_filter.glsl | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 70 |
11 files changed, 579 insertions, 220 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index b2228a6cfa..c10c5fee65 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -914,6 +914,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const } + if (shader_ptr && shader_ptr!=shader_cache) { state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); @@ -925,6 +926,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const int tc = material_ptr->textures.size(); RID* textures = material_ptr->textures.ptr(); + ShaderLanguage::ShaderNode::Uniform::Hint* texture_hints = shader_ptr->texture_hints.ptr(); for(int i=0;i<tc;i++) { @@ -932,11 +934,30 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list,int p_z,const RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull( textures[i] ); if (!t) { + + switch(texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { + glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { + glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex); + } break; + default: { + glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); + } break; + } + //check hints - glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); + continue; } + if (storage->config.srgb_decode_supported && t->using_srgb) { + //no srgb in 2D + glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT); + t->using_srgb=false; + } + glBindTexture(t->target,t->tex_id); } diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 83c40edc1d..e838020c45 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -253,10 +253,8 @@ void RasterizerGLES3::make_current() { void RasterizerGLES3::register_config() { - GLOBAL_DEF("rendering/gles3/framebuffer_format",RasterizerStorageGLES3::FBO_FORMAT_FLOAT); - Globals::get_singleton()->set_custom_property_info("rendering/gles3/framebuffer_format",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"16 Bits,32 Bits,Half Float")); - GLOBAL_DEF("rendering/gles3/lighting_technique",1); - Globals::get_singleton()->set_custom_property_info("rendering/gles3/lighting_technique",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Forward,Deferred")); + GLOBAL_DEF("rendering/gles3/render_architecture",0); + Globals::get_singleton()->set_custom_property_info("rendering/gles3/render_architecture",PropertyInfo(Variant::INT,"",PROPERTY_HINT_ENUM,"Desktop,Mobile")); GLOBAL_DEF("rendering/gles3/use_nearest_mipmap_filter",false); GLOBAL_DEF("rendering/gles3/anisotropic_filter_level",4.0); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index aadf9e6336..f7baf1a30b 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -150,27 +150,19 @@ void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_b } -void RasterizerSceneGLES3::environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper){ +void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, bool p_enable, float p_exposure, float p_white, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale, VS::EnvironmentToneMapper p_tone_mapper){ } -void RasterizerSceneGLES3::environment_set_brightness(RID p_env,bool p_enable,float p_brightness){ -} -void RasterizerSceneGLES3::environment_set_contrast(RID p_env,bool p_enable,float p_contrast){ +void RasterizerSceneGLES3::environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp) { -} -void RasterizerSceneGLES3::environment_set_saturation(RID p_env,bool p_enable,float p_saturation){ } -void RasterizerSceneGLES3::environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp){ - -} - - RID RasterizerSceneGLES3::light_instance_create(RID p_light) { + print_line("hello light"); LightInstance *light_instance = memnew( LightInstance ); light_instance->light=p_light; @@ -204,6 +196,29 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m glEnable(GL_CULL_FACE); } + if (state.current_line_width!=p_material->line_width) { + glLineWidth(p_material->line_width); + state.current_line_width=p_material->line_width; + } + + if (state.current_depth_draw!=p_material->shader->spatial.depth_draw_mode) { + switch(p_material->shader->spatial.depth_draw_mode) { + case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS: + case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_OPAQUE: { + + glDepthMask(!p_alpha_pass); + } break; + case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALWAYS: { + glDepthMask(GL_TRUE); + } break; + case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_NEVER: { + glDepthMask(GL_FALSE); + } break; + } + + state.current_depth_draw=p_material->shader->spatial.depth_draw_mode; + } + //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); /* @@ -216,7 +231,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m //if (p_material->line_width) // glLineWidth(p_material->line_width); - +#if 0 //blend mode if (state.current_blend_mode!=p_material->shader->spatial.blend_mode) { @@ -256,7 +271,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m state.current_blend_mode=p_material->shader->spatial.blend_mode; } - +#endif //material parameters @@ -273,6 +288,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m int tc = p_material->textures.size(); RID* textures = p_material->textures.ptr(); + ShaderLanguage::ShaderNode::Uniform::Hint* texture_hints = p_material->shader->texture_hints.ptr(); for(int i=0;i<tc;i++) { @@ -281,11 +297,48 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull( textures[i] ); if (!t) { //check hints + switch(texture_hints[i]) { + case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: { + glBindTexture(GL_TEXTURE_2D,storage->resources.black_tex); + } break; + case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: { + glBindTexture(GL_TEXTURE_2D,storage->resources.normal_tex); + } break; + default: { + glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); + } break; + } glBindTexture(GL_TEXTURE_2D,storage->resources.white_tex); continue; } + if (storage->config.srgb_decode_supported) { + //if SRGB decode extension is present, simply switch the texture to whathever is needed + bool must_srgb=false; + + if (t->srgb && texture_hints[i]==ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO) { + must_srgb=true; + } + + if (t->using_srgb!=must_srgb) { + if (must_srgb) { + glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT); +#ifdef TOOLS_ENABLED + if (!(t->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) { + t->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR; + //notify that texture must be set to linear beforehand, so it works in other platforms when exported + } +#endif + + } else { + glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT); + } + t->using_srgb=must_srgb; + } + } + + glBindTexture(t->target,t->tex_id); } @@ -348,7 +401,60 @@ void RasterizerSceneGLES3::_setup_light(LightInstance *p_light) { glBindBufferBase(GL_UNIFORM_BUFFER,3,p_light->light_ubo); //bind light uniform } +void RasterizerSceneGLES3::_setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection) { + + if (p_instance->billboard || p_instance->billboard_y || p_instance->depth_scale) { + + Transform xf=p_instance->transform; + if (p_instance->depth_scale) { + + if (p_projection.matrix[3][3]) { + //orthogonal matrix, try to do about the same + //with viewport size + //real_t w = Math::abs( 1.0/(2.0*(p_projection.matrix[0][0])) ); + real_t h = Math::abs( 1.0/(2.0*p_projection.matrix[1][1]) ); + float sc = (h*2.0); //consistent with Y-fov + xf.basis.scale( Vector3(sc,sc,sc)); + } else { + //just scale by depth + real_t sc = Plane(p_view_transform.origin,-p_view_transform.get_basis().get_axis(2)).distance_to(xf.origin); + xf.basis.scale( Vector3(sc,sc,sc)); + } + } + + if (p_instance->billboard) { + + Vector3 scale = xf.basis.get_scale(); + + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) { + xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), -p_view_transform.get_basis().get_axis(1)); + } else { + xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), p_view_transform.get_basis().get_axis(1)); + } + + xf.basis.scale(scale); + } + + if (p_instance->billboard_y) { + + Vector3 scale = xf.basis.get_scale(); + Vector3 look_at = p_view_transform.get_origin(); + look_at.y = 0.0; + Vector3 look_at_norm = look_at.normalized(); + if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) { + xf.set_look_at(xf.origin,xf.origin + look_at_norm, Vector3(0.0, -1.0, 0.0)); + } else { + xf.set_look_at(xf.origin,xf.origin + look_at_norm, Vector3(0.0, 1.0, 0.0)); + } + xf.basis.scale(scale); + } + state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, xf); + + } else { + state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, p_instance->transform); + } +} void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_element_count,const Transform& p_view_transform,const CameraMatrix& p_projection,RasterizerStorageGLES3::Texture* p_base_env,bool p_reverse_cull,bool p_alpha_pass) { @@ -372,12 +478,18 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-2); glBindTexture(p_base_env->target,p_base_env->tex_id); state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_CUBEMAP,true); + } else { + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_CUBEMAP,false); + } + state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON,false); state.current_blend_mode=-1; + state.current_line_width=-1; + state.current_depth_draw=-1; glDisable(GL_BLEND); @@ -390,6 +502,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e int prev_blend=-1; int current_blend_mode=-1; + bool prev_additive=false; + for (int i=0;i<p_element_count;i++) { RenderList::Element *e = p_elements[i]; @@ -554,10 +668,16 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e _setup_geometry(e); } + if (rebind || prev_additive!=additive) { + state.scene_shader.set_uniform(SceneShaderGLES3::NO_AMBIENT_LIGHT, additive); + + } + // _set_cull(e->mirror,p_reverse_cull); state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror?-1.0:1.0); - state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform); + + _setup_transform(e->instance,p_view_transform,p_projection); // _render(e->geometry, material, skeleton,e->owner,e->instance->transform); @@ -567,6 +687,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e prev_material=material; prev_base_type=e->instance->base_type; prev_geometry=e->geometry; + prev_additive=additive; + prev_light_type=light_type; + prev_light_index=light_index; + } //print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count)); @@ -824,6 +948,19 @@ void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,CameraMatrix& p_projection, glActiveTexture(GL_TEXTURE0); glBindTexture(tex->target,tex->tex_id); + + if (storage->config.srgb_decode_supported && tex->srgb && !tex->using_srgb) { + + glTexParameteri(tex->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT); + tex->using_srgb=true; +#ifdef TOOLS_ENABLED + if (!(tex->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) { + tex->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR; + //notify that texture must be set to linear beforehand, so it works in other platforms when exported + } +#endif + } + glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); @@ -876,6 +1013,7 @@ void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,CameraMatrix& p_projection, glDrawArrays(GL_TRIANGLE_FAN,0,4); glBindVertexArray(0); + glColorMask(1,1,1,1); storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP,false); @@ -977,9 +1115,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu ERR_FAIL_COND( directional_light_instance_count >= RenderList::MAX_LIGHTS); directional_light_instances[directional_light_instance_count++]=li; - li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r; - li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g; - li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b; + Color linear_col = li->light_ptr->color.to_linear(); + li->light_ubo_data.light_color_energy[0]=linear_col.r; + li->light_ubo_data.light_color_energy[1]=linear_col.g; + li->light_ubo_data.light_color_energy[2]=linear_col.b; li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; //omni, keep at 0 @@ -1018,9 +1157,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu } break; case VS::LIGHT_OMNI: { - li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r; - li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g; - li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b; + Color linear_col = li->light_ptr->color.to_linear(); + li->light_ubo_data.light_color_energy[0]=linear_col.r; + li->light_ubo_data.light_color_energy[1]=linear_col.g; + li->light_ubo_data.light_color_energy[2]=linear_col.b; li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin); @@ -1050,9 +1190,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu } break; case VS::LIGHT_SPOT: { - li->light_ubo_data.light_color_energy[0]=li->light_ptr->color.r; - li->light_ubo_data.light_color_energy[1]=li->light_ptr->color.g; - li->light_ubo_data.light_color_energy[2]=li->light_ptr->color.b; + Color linear_col = li->light_ptr->color.to_linear(); + li->light_ubo_data.light_color_energy[0]=linear_col.r; + li->light_ubo_data.light_color_energy[1]=linear_col.g; + li->light_ubo_data.light_color_energy[2]=linear_col.b; li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY]; Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin); @@ -1108,6 +1249,51 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu } +void RasterizerSceneGLES3::_copy_screen() { + + glBindVertexArray(storage->resources.quadie_array); + glDrawArrays(GL_TRIANGLE_FAN,0,4); + glBindVertexArray(0); + +} + +void RasterizerSceneGLES3::_copy_to_front_buffer(Environment *env) { + + //copy to front buffer + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo); + + glDepthMask(GL_FALSE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDepthFunc(GL_LEQUAL); + glColorMask(1,1,1,1); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse); + + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA,true); + + if (!env) { + //no environment, simply convert from linear to srgb + storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,true); + } else { + storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,true); + + } + + storage->shaders.copy.bind(); + + _copy_screen(); + + + //turn off everything used + storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB,false); + storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA,false); + + +} + void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,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_directional_lights,int p_directional_light_count,RID p_environment){ //first of all, make a new render pass @@ -1125,6 +1311,8 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM current_material_index=0; + bool use_mrt=false; + //fill list for(int i=0;i<p_cull_count;i++) { @@ -1166,43 +1354,58 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); + + RasterizerStorageGLES3::Texture* env_radiance_tex=NULL; + + if (use_mrt) { + + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,true); + + Color black(0,0,0,0); + glClearBufferfv(GL_COLOR,1,black.components); // specular + glClearBufferfv(GL_COLOR,2,black.components); // normal metal rough + + } else { + + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false); + + } + + glClearDepth(1.0); - glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo); + glClear(GL_DEPTH_BUFFER_BIT); - RasterizerStorageGLES3::Texture* env_radiance_tex; + Color clear_color(0,0,0,0); if (!env || env->bg_mode==VS::ENV_BG_CLEAR_COLOR) { if (storage->frame.clear_request) { - glClearColor( storage->frame.clear_request_color.r, storage->frame.clear_request_color.g, storage->frame.clear_request_color.b, storage->frame.clear_request_color.a ); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + clear_color = storage->frame.clear_request_color.to_linear(); storage->frame.clear_request=false; } } else if (env->bg_mode==VS::ENV_BG_COLOR) { - - glClearColor( env->bg_color.r, env->bg_color.g, env->bg_color.b, env->bg_color.a ); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + clear_color = env->bg_color.to_linear(); storage->frame.clear_request=false; } else if (env->bg_mode==VS::ENV_BG_SKYBOX) { if (env->skybox_radiance.is_valid()) { env_radiance_tex = storage->texture_owner.getornull(env->skybox_radiance); } - glClear(GL_DEPTH_BUFFER_BIT); storage->frame.clear_request=false; } else { - glClear(GL_DEPTH_BUFFER_BIT); storage->frame.clear_request=false; - } - state.current_depth_test=true; - state.current_depth_mask=true; + glClearBufferfv(GL_COLOR,0,clear_color.components); // specular + + state.texscreen_copied=false; glBlendEquation(GL_FUNC_ADD); @@ -1214,43 +1417,33 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM } glDisable(GL_BLEND); - //current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; - render_list.sort_by_key(false); - //_render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting); -/* - if (draw_tex_background) { - - //most 3D vendors recommend drawing a texture bg or skybox here, - //after opaque geometry has been drawn - //so the zbuffer can get rid of most pixels - _draw_tex_bg(); - } -*/ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } -// glDisable(GL_BLEND); -// current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX; -// state.scene_shader.set_conditional(SceneShaderGLES3::USE_GLOW,false); -// if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { -// glColorMask(1,1,1,0); //don't touch alpha -// } - - _render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false); + if (env && env->bg_mode==VS::ENV_BG_SKYBOX) { + if (use_mrt) { + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo); //switch to alpha fbo for skybox, only diffuse/ambient matters + } + _draw_skybox(env->skybox_color,p_cam_projection,p_cam_transform,storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP],env->skybox_scale); } + + + + //_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true); //glColorMask(1,1,1,1); @@ -1261,12 +1454,14 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,CameraM glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); - glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo); + glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo); render_list.sort_by_depth(true); - _render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false); + _render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,true); + + _copy_to_front_buffer(env); #if 0 if (use_fb) { @@ -1418,6 +1613,7 @@ bool RasterizerSceneGLES3::free(RID p_rid) { if (light_instance_owner.owns(p_rid)) { + print_line("bye light"); LightInstance *light_instance = light_instance_owner.getptr(p_rid); glDeleteBuffers(1,&light_instance->light_ubo); light_instance_owner.free(p_rid); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 4b1b77f13c..5457b5cde3 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -18,10 +18,11 @@ public: struct State { - bool current_depth_test; - bool current_depth_mask; + bool texscreen_copied; int current_blend_mode; + float current_line_width; + int current_depth_draw; SceneShaderGLES3 scene_shader; @@ -57,6 +58,8 @@ public: GLuint skybox_verts; GLuint skybox_array; + + } state; @@ -109,11 +112,8 @@ public: virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode); virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture); - virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,VS::EnvironmentToneMapper p_tone_mapper); - virtual void environment_set_brightness(RID p_env,bool p_enable,float p_brightness); - virtual void environment_set_contrast(RID p_env,bool p_enable,float p_contrast); - virtual void environment_set_saturation(RID p_env,bool p_enable,float p_saturation); - virtual void environment_set_color_correction(RID p_env,bool p_enable,RID p_ramp); + virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale,VS::EnvironmentToneMapper p_tone_mapper); + virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp); /* LIGHT INSTANCE */ @@ -314,6 +314,7 @@ public: RenderList render_list; _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material* p_material,bool p_alpha_pass); + _FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e); _FORCE_INLINE_ void _render_geometry(RenderList::Element *e); _FORCE_INLINE_ void _setup_light(LightInstance *p_light); @@ -327,6 +328,8 @@ public: void _setup_environment(Environment *env,CameraMatrix& p_cam_projection, const Transform& p_cam_transform); void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform); + void _copy_screen(); + void _copy_to_front_buffer(Environment *env); virtual void render_scene(const Transform& p_cam_transform,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_directional_lights,int p_directional_light_count,RID p_environment); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 1141a605c5..a678c460f5 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -57,9 +57,6 @@ #define _EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#define _TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define _DECODE_EXT 0x8A49 -#define _SKIP_DECODE_EXT 0x8A4A #define _GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE @@ -679,8 +676,10 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture,const Image& p_image if (texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT); + texture->using_srgb=true; } else { glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT); + texture->using_srgb=false; } } @@ -892,8 +891,10 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture,uint32_t p_flags) { if (texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT); + texture->using_srgb=true; } else { glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_SKIP_DECODE_EXT); + texture->using_srgb=false; } } @@ -1024,6 +1025,19 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source,int p_r glActiveTexture(GL_TEXTURE0); glBindTexture(texture->target, texture->tex_id); + if (config.srgb_decode_supported && texture->srgb && !texture->using_srgb) { + + glTexParameteri(texture->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT); + texture->using_srgb=true; +#ifdef TOOLS_ENABLED + if (!(texture->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) { + texture->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR; + //notify that texture must be set to linear beforehand, so it works in other platforms when exported + } +#endif + } + + glActiveTexture(GL_TEXTURE1); GLuint new_cubemap; glGenTextures(1, &new_cubemap); @@ -1302,6 +1316,7 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const { p_shader->ubo_size=gen_code.uniform_total_size; p_shader->ubo_offsets=gen_code.uniform_offsets; p_shader->texture_count=gen_code.texture_uniforms.size(); + p_shader->texture_hints=gen_code.texture_hints; //all materials using this shader will have to be invalidated, unfortunately @@ -1510,7 +1525,17 @@ Variant RasterizerStorageGLES3::material_get_param(RID p_material, const StringN return Variant(); } -_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant& value, uint8_t *data) { +void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_width) { + + Material *material = material_owner.get( p_material ); + ERR_FAIL_COND(!material); + + material->line_width=p_width; + + +} + +_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant& value, uint8_t *data,bool p_linear_color) { switch(type) { case ShaderLanguage::TYPE_BOOL: { @@ -1683,6 +1708,10 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy if (value.get_type()==Variant::COLOR) { Color v=value; + if (p_linear_color) { + v=v.to_linear(); + } + gui[0]=v.r; gui[1]=v.g; gui[2]=v.b; @@ -2019,7 +2048,7 @@ void RasterizerStorageGLES3::_update_material(Material* material) { if (V) { //user provided - _fill_std140_variant_ubo_value(E->get().type,V->get(),data); + _fill_std140_variant_ubo_value(E->get().type,V->get(),data,material->shader->mode==VS::SHADER_SPATIAL); } else if (E->get().default_value.size()){ //default value _fill_std140_ubo_value(E->get().type,E->get().default_value,data); @@ -2641,9 +2670,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface){ Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND(surface->index_array_len==0); - - glDeleteBuffers(1,&surface->array_id); + glDeleteBuffers(1,&surface->vertex_id); if (surface->index_id) { glDeleteBuffers(1,&surface->index_id); } @@ -3211,14 +3238,14 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) { rt->back.fbo=0; } - if (rt->deferred.fbo) { - glDeleteFramebuffers(1,&rt->deferred.fbo); - glDeleteFramebuffers(1,&rt->deferred.fbo_color); - glDeleteTextures(1,&rt->deferred.albedo_ao); - glDeleteTextures(1,&rt->deferred.normal_special); - glDeleteTextures(1,&rt->deferred.metal_rough_motion); - rt->deferred.fbo=0; - rt->deferred.fbo_color=0; + if (rt->buffers.fbo) { + glDeleteFramebuffers(1,&rt->buffers.fbo); + glDeleteFramebuffers(1,&rt->buffers.alpha_fbo); + glDeleteTextures(1,&rt->buffers.diffuse); + glDeleteTextures(1,&rt->buffers.specular); + glDeleteTextures(1,&rt->buffers.normal_sr); + rt->buffers.fbo=0; + rt->buffers.alpha_fbo=0; } if (rt->depth) { @@ -3239,26 +3266,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ if (rt->width<=0 || rt->height<=0) return; - glActiveTexture(GL_TEXTURE0); - - glGenFramebuffers(1, &rt->front.fbo); - glBindFramebuffer(GL_FRAMEBUFFER, rt->front.fbo); - - - glGenRenderbuffers(1, &rt->depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->depth ); - if (config.fbo_format==FBO_FORMAT_16_BITS) { - glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16, rt->width, rt->height); - } else { - glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8, rt->width, rt->height); - } - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - glBindRenderbuffer(GL_RENDERBUFFER, 0 ); - - - glGenTextures(1, &rt->front.color); - glBindTexture(GL_TEXTURE_2D, rt->front.color); - GLuint color_internal_format; GLuint color_format; @@ -3266,21 +3273,8 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ Image::Format image_format; - if (config.fbo_format==FBO_FORMAT_16_BITS) { - if (rt->flags[RENDER_TARGET_TRANSPARENT]) { - color_internal_format=GL_RGB5_A1; - color_format=GL_RGBA; - color_type=GL_UNSIGNED_SHORT_5_5_5_1; - image_format=Image::FORMAT_RGBA5551; - } else { - color_internal_format=GL_RGB565; - color_format=GL_RGB; - color_type=GL_UNSIGNED_SHORT_5_6_5; - image_format=Image::FORMAT_RGB565; - } - - } else if (config.fbo_format==FBO_FORMAT_32_BITS || (config.fbo_format==FBO_FORMAT_FLOAT && rt->flags[RENDER_TARGET_NO_3D])) { + if (config.render_arch==RENDER_ARCH_MOBILE || rt->flags[RENDER_TARGET_NO_3D]) { if (rt->flags[RENDER_TARGET_TRANSPARENT]) { color_internal_format=GL_RGBA8; @@ -3293,53 +3287,75 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ color_type=GL_UNSIGNED_INT_2_10_10_10_REV; image_format=Image::FORMAT_RGBA8;//todo } - } else if (config.fbo_format==FBO_FORMAT_FLOAT) { - + } else { color_internal_format=GL_RGBA16F; color_format=GL_RGBA; color_type=GL_HALF_FLOAT; image_format=Image::FORMAT_RGBAH; } - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL); + { + /* FRONT FBO */ - 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, rt->front.color, 0); + glActiveTexture(GL_TEXTURE0); + + glGenFramebuffers(1, &rt->front.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->front.fbo); + + + glGenRenderbuffers(1, &rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth ); + + + glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8, rt->width, rt->height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, 0 ); + + + glGenTextures(1, &rt->front.color); + glBindTexture(GL_TEXTURE_2D, rt->front.color); + + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, 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, rt->front.color, 0); - { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo); ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE ); - } - Texture *tex = texture_owner.get(rt->texture); - tex->format=image_format; - tex->gl_format_cache=color_format; - tex->gl_type_cache=color_type; - tex->gl_internal_format_cache=color_internal_format; - tex->tex_id=rt->front.color; - tex->width=rt->width; - tex->alloc_width=rt->width; - tex->height=rt->height; - tex->alloc_height=rt->height; + Texture *tex = texture_owner.get(rt->texture); + tex->format=image_format; + tex->gl_format_cache=color_format; + tex->gl_type_cache=color_type; + tex->gl_internal_format_cache=color_internal_format; + tex->tex_id=rt->front.color; + tex->width=rt->width; + tex->alloc_width=rt->width; + tex->height=rt->height; + tex->alloc_height=rt->height; + + texture_set_flags(rt->texture,tex->flags); + + } - texture_set_flags(rt->texture,tex->flags); + + /* BACK FBO */ if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) { glGenFramebuffers(1, &rt->back.fbo); glBindFramebuffer(GL_FRAMEBUFFER, rt->back.fbo); - + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth ); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); glGenTextures(1, &rt->back.color); glBindTexture(GL_TEXTURE_2D, rt->back.color); - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -3357,43 +3373,42 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ } } + if (config.render_arch==RENDER_ARCH_DESKTOP && !rt->flags[RENDER_TARGET_NO_3D]) { - if (config.fbo_deferred && !rt->flags[RENDER_TARGET_NO_3D]) { - //regular fbo - glGenFramebuffers(1, &rt->deferred.fbo); - glBindFramebuffer(GL_FRAMEBUFFER, rt->deferred.fbo); + glGenFramebuffers(1, &rt->buffers.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.fbo); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - glGenTextures(1, &rt->deferred.albedo_ao); - glBindTexture(GL_TEXTURE_2D, rt->deferred.albedo_ao); + glGenTextures(1, &rt->buffers.diffuse); + glBindTexture(GL_TEXTURE_2D, rt->buffers.diffuse); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 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, rt->deferred.albedo_ao, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0); - glGenTextures(1, &rt->deferred.metal_rough_motion); - glBindTexture(GL_TEXTURE_2D, rt->deferred.metal_rough_motion); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glGenTextures(1, &rt->buffers.specular); + glBindTexture(GL_TEXTURE_2D, rt->buffers.specular); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rt->width, rt->height, 0, GL_RGBA, GL_HALF_FLOAT, 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_ATTACHMENT1, GL_TEXTURE_2D, rt->deferred.metal_rough_motion, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->buffers.specular, 0); - glGenTextures(1, &rt->deferred.normal_special); - glBindTexture(GL_TEXTURE_2D, rt->deferred.normal_special); + glGenTextures(1, &rt->buffers.normal_sr); + glBindTexture(GL_TEXTURE_2D, rt->buffers.normal_sr); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 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_ATTACHMENT2, GL_TEXTURE_2D, rt->deferred.normal_special, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->buffers.normal_sr, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); @@ -3402,19 +3417,15 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ if (status != GL_FRAMEBUFFER_COMPLETE) { _render_target_clear(rt); ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE ); - } + } - //regular fbo with color attachment (needed for emission or objects rendered as forward) - glGenFramebuffers(1, &rt->deferred.fbo_color); - glBindFramebuffer(GL_FRAMEBUFFER, rt->deferred.fbo_color); + //alpha fbo + glGenFramebuffers(1, &rt->buffers.alpha_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.alpha_fbo); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->deferred.albedo_ao, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->deferred.metal_rough_motion, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->deferred.normal_special, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, rt->front.color, 0); - + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo); @@ -3423,6 +3434,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){ _render_target_clear(rt); ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE ); } + } @@ -3797,8 +3809,8 @@ bool RasterizerStorageGLES3::free(RID p_rid){ void RasterizerStorageGLES3::initialize() { - config.fbo_format=FBOFormat(int(Globals::get_singleton()->get("rendering/gles3/framebuffer_format"))); - config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique")); + config.render_arch=RENDER_ARCH_DESKTOP; + //config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique")); config.system_fbo=0; @@ -3925,10 +3937,10 @@ void RasterizerStorageGLES3::initialize() { glGenVertexArrays(1,&resources.quadie_array); glBindVertexArray(resources.quadie_array); glBindBuffer(GL_ARRAY_BUFFER,resources.quadie); - glVertexAttribPointer(0,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,0); + glVertexAttribPointer(VS::ARRAY_VERTEX,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,0); glEnableVertexAttribArray(0); - glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,((uint8_t*)NULL)+8); - glEnableVertexAttribArray(1); + glVertexAttribPointer(VS::ARRAY_TEX_UV,2,GL_FLOAT,GL_FALSE,sizeof(float)*4,((uint8_t*)NULL)+8); + glEnableVertexAttribArray(4); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); //unbind } diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index f052aa8019..b12c2d93b6 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -13,6 +13,9 @@ class RasterizerCanvasGLES3; class RasterizerSceneGLES3; +#define _TEXTURE_SRGB_DECODE_EXT 0x8A48 +#define _DECODE_EXT 0x8A49 +#define _SKIP_DECODE_EXT 0x8A4A class RasterizerStorageGLES3 : public RasterizerStorage { public: @@ -20,16 +23,15 @@ public: RasterizerCanvasGLES3 *canvas; RasterizerSceneGLES3 *scene; - enum FBOFormat { - FBO_FORMAT_16_BITS, - FBO_FORMAT_32_BITS, - FBO_FORMAT_FLOAT, + enum RenderArchitecture { + RENDER_ARCH_MOBILE, + RENDER_ARCH_DESKTOP, }; struct Config { - FBOFormat fbo_format; - bool fbo_deferred; + RenderArchitecture render_arch; + GLuint system_fbo; //on some devices, such as apple, screen is rendered to yet another fbo. bool shrink_textures_x2; @@ -135,12 +137,15 @@ public: bool active; GLuint tex_id; + bool using_srgb; + uint16_t stored_cube_sides; RenderTarget *render_target; Texture() { + using_srgb=false; stored_cube_sides=0; ignore_mipmaps=false; render_target=NULL; @@ -218,6 +223,8 @@ public: Map<StringName,RID> default_textures; + Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; + bool valid; String path; @@ -319,12 +326,14 @@ public: SelfList<Material> list; SelfList<Material> dirty_list; Vector<RID> textures; + float line_width; uint32_t index; uint64_t last_pass; Material() : list(this), dirty_list(this) { shader=NULL; + line_width=1.0; ubo_id=0; ubo_size=0; last_pass=0; @@ -346,6 +355,8 @@ public: virtual void material_set_param(RID p_material, const StringName& p_param, const Variant& p_value); virtual Variant material_get_param(RID p_material, const StringName& p_param) const; + virtual void material_set_line_width(RID p_material, float p_width); + void _update_material(Material* material); void update_dirty_materials(); @@ -655,14 +666,13 @@ public: GLuint depth; - struct Deferred { + struct Buffers { GLuint fbo; - GLuint fbo_color; - - GLuint albedo_ao; - GLuint metal_rough_motion; - GLuint normal_special; - } deferred; + GLuint alpha_fbo; //single buffer, just diffuse (for alpha pass) + GLuint specular; + GLuint diffuse; + GLuint normal_sr; + } buffers; int width,height; @@ -679,8 +689,8 @@ public: depth=0; front.fbo=0; back.fbo=0; - deferred.fbo=0; - deferred.fbo_color=0; + buffers.fbo=0; + buffers.alpha_fbo=0; used_in_frame=false; flags[RENDER_TARGET_VFLIP]=false; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index da8f6689d0..0dff53bfb9 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -75,25 +75,81 @@ static String _mkid(const String& p_id) { return "m_"+p_id; } +static String f2sp0(float p_float) { + + if (int(p_float)==p_float) + return itos(p_float)+".0"; + else + return rtoss(p_float); +} + static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value>& p_values) { switch(p_type) { case SL::TYPE_BOOL: return p_values[0].boolean?"true":"false"; - case SL::TYPE_BVEC2: return String()+"bvec2("+(p_values[0].boolean?"true":"false")+(p_values[1].boolean?"true":"false")+")"; - case SL::TYPE_BVEC3: return String()+"bvec3("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+")"; - case SL::TYPE_BVEC4: return String()+"bvec4("+(p_values[0].boolean?"true":"false")+","+(p_values[1].boolean?"true":"false")+","+(p_values[2].boolean?"true":"false")+","+(p_values[3].boolean?"true":"false")+")"; - case SL::TYPE_INT: return rtos(p_values[0].sint); - case SL::TYPE_IVEC2: return String()+"ivec2("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+")"; - case SL::TYPE_IVEC3: return String()+"ivec3("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+")"; - case SL::TYPE_IVEC4: return String()+"ivec4("+rtos(p_values[0].sint)+","+rtos(p_values[1].sint)+","+rtos(p_values[2].sint)+","+rtos(p_values[3].sint)+")"; - case SL::TYPE_UINT: return rtos(p_values[0].real); - case SL::TYPE_UVEC2: return String()+"uvec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")"; - case SL::TYPE_UVEC3: return String()+"uvec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")"; - case SL::TYPE_UVEC4: return String()+"uvec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")"; - case SL::TYPE_FLOAT: return rtos(p_values[0].real); - case SL::TYPE_VEC2: return String()+"vec2("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+")"; - case SL::TYPE_VEC3: return String()+"vec3("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+")"; - case SL::TYPE_VEC4: return String()+"vec4("+rtos(p_values[0].real)+","+rtos(p_values[1].real)+","+rtos(p_values[2].real)+","+rtos(p_values[3].real)+")"; + case SL::TYPE_BVEC2: + case SL::TYPE_BVEC3: + case SL::TYPE_BVEC4: { + + + String text="bvec"+itos(p_type-SL::TYPE_BOOL+1)+"("; + for(int i=0;i<p_values.size();i++) { + if (i>0) + text+=","; + + text+=p_values[i].boolean?"true":"false"; + } + text+=")"; + return text; + } + + case SL::TYPE_INT: return itos(p_values[0].sint); + case SL::TYPE_IVEC2: + case SL::TYPE_IVEC3: + case SL::TYPE_IVEC4: { + + String text="ivec"+itos(p_type-SL::TYPE_INT+1)+"("; + for(int i=0;i<p_values.size();i++) { + if (i>0) + text+=","; + + text+=itos(p_values[i].sint); + } + text+=")"; + return text; + + } break; + case SL::TYPE_UINT: return itos(p_values[0].uint)+"u"; + case SL::TYPE_UVEC2: + case SL::TYPE_UVEC3: + case SL::TYPE_UVEC4: { + + String text="uvec"+itos(p_type-SL::TYPE_UINT+1)+"("; + for(int i=0;i<p_values.size();i++) { + if (i>0) + text+=","; + + text+=itos(p_values[i].uint)+"u"; + } + text+=")"; + return text; + } break; + case SL::TYPE_FLOAT: return f2sp0(p_values[0].real)+"f"; + case SL::TYPE_VEC2: + case SL::TYPE_VEC3: + case SL::TYPE_VEC4: { + + String text="vec"+itos(p_type-SL::TYPE_FLOAT+1)+"("; + for(int i=0;i<p_values.size();i++) { + if (i>0) + text+=","; + + text+=f2sp0(p_values[i].real); + } + text+=")"; + return text; + + } break; default: ERR_FAIL_V(String()); } } @@ -189,6 +245,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } r_gen_code.texture_uniforms.resize(max_texture_uniforms); + r_gen_code.texture_hints.resize(max_texture_uniforms); Vector<int> uniform_sizes; uniform_sizes.resize(max_uniforms); @@ -209,6 +266,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener r_gen_code.vertex_global+=ucode; r_gen_code.fragment_global+=ucode; r_gen_code.texture_uniforms[E->get().texture_order]=_mkid(E->key()); + r_gen_code.texture_hints[E->get().texture_order]=E->get().hint; } else { if (r_gen_code.uniforms.empty()) { diff --git a/drivers/gles3/shader_compiler_gles3.h b/drivers/gles3/shader_compiler_gles3.h index ad51b99927..dcea82d773 100644 --- a/drivers/gles3/shader_compiler_gles3.h +++ b/drivers/gles3/shader_compiler_gles3.h @@ -21,6 +21,8 @@ public: Vector<CharString> defines; Vector<StringName> texture_uniforms; + Vector<ShaderLanguage::ShaderNode::Uniform::Hint> texture_hints; + Vector<uint32_t> uniform_offsets; uint32_t uniform_total_size; String uniforms; diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl index eb58d66431..79982ecf25 100644 --- a/drivers/gles3/shaders/copy.glsl +++ b/drivers/gles3/shaders/copy.glsl @@ -5,9 +5,9 @@ layout(location=0) in highp vec4 vertex_attrib; #ifdef USE_CUBEMAP layout(location=4) in vec3 cube_in; #else -layout(location=4) in vec2 uv_in; // attrib:4 +layout(location=4) in vec2 uv_in; #endif -layout(location=5) in vec2 uv2_in; // attrib:5 +layout(location=5) in vec2 uv2_in; #ifdef USE_CUBEMAP out vec3 cube_interp; @@ -40,6 +40,15 @@ uniform sampler2D source; //texunit:0 #endif +float sRGB_gamma_correct(float c){ + float a = 0.055; + if(c < 0.0031308) + return 12.92*c; + else + return (1.0+a)*pow(c, 1.0/2.4) - a; +} + + uniform float stuff; in vec2 uv2_interp; @@ -57,6 +66,20 @@ void main() { vec4 color = texture( source, uv_interp ); #endif +#ifdef LINEAR_TO_SRGB + //regular Linear -> SRGB conversion + vec3 a = vec3(0.055); + color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308))); +#endif + +#ifdef DEBUG_GRADIENT + color.rg=uv_interp; + color.b=0.0; +#endif + +#ifdef DISABLE_ALPHA + color.a=1.0; +#endif frag_color = color; } diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index d3d4cbd435..998a59833e 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -3,7 +3,7 @@ layout(location=0) in highp vec2 vertex; -layout(location=1) in highp vec2 uv; +layout(location=4) in highp vec2 uv; out highp vec2 uv_interp; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 3f94252606..60ac015a17 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -269,11 +269,16 @@ in vec3 normal_interp; /* PBR CHANNELS */ +//used on forward mainly +uniform bool no_ambient_light; + + #ifdef USE_RADIANCE_CUBEMAP uniform sampler2D brdf_texture; //texunit:-1 uniform samplerCube radiance_cube; //texunit:-2 + layout(std140) uniform Radiance { //ubo:2 mat4 radiance_inverse_xform; @@ -346,8 +351,18 @@ in mediump vec4 forward_shadow_pos4; #endif +#ifdef USE_MULTIPLE_RENDER_TARGETS + +layout(location=0) out vec4 diffuse_buffer; +layout(location=1) out vec4 specular_buffer; +layout(location=2) out vec4 normal_mr_buffer; + +#else + layout(location=0) out vec4 frag_color; +#endif + // GGX Specular // Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl @@ -470,39 +485,46 @@ FRAGMENT_SHADER_CODE /////////////////////// LIGHTING ////////////////////////////// vec3 specular_light = vec3(0.0,0.0,0.0); - vec3 ambient_light = ambient_light_color.rgb; + vec3 ambient_light; vec3 diffuse_light = vec3(0.0,0.0,0.0); vec3 eye_vec = -normalize( vertex_interp ); #ifdef USE_RADIANCE_CUBEMAP - { + if (no_ambient_light) { + ambient_light=vec3(0.0,0.0,0.0); + } else { + { - float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); - vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy; + float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); + vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy; - float lod = roughness * 5.0; - vec3 r = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n); - r=normalize((radiance_inverse_xform * vec4(r,0.0)).xyz); - vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y); + float lod = roughness * 5.0; + vec3 r = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n); + r=normalize((radiance_inverse_xform * vec4(r,0.0)).xyz); + vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y); - specular_light=mix(albedo,radiance,specular); + specular_light=mix(albedo,radiance,specular); - } + } - { + { - vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); - vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz; + vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz); + vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz; - ambient_light=mix(ambient_light,env_ambient,radiance_ambient_contribution); + ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution); + } } - #else - ambient_light=albedo; + if (no_ambient_light){ + ambient_light=vec3(0.0,0.0,0.0); + } else { + ambient_light=ambient_light_color.rgb; + } #endif @@ -538,11 +560,25 @@ LIGHT_SHADER_CODE } #endif -#ifdef SHADELESS +#ifdef USE_MULTIPLE_RENDER_TARGETS + + //approximate ambient scale for SSAO, since we will lack full ambient + float max_ambient=max(ambient_light.r,max(ambient_light.g,ambient_light.b)); + float max_diffuse=max(diffuse_light.r,max(diffuse_light.g,diffuse_light.b)); + float total_ambient = max_ambient+max_diffuse; + float ambient_scale = (total_ambient>0.0) ? max_ambient/total_ambient : 0.0; + diffuse_buffer=vec4(diffuse_light+ambient_light,ambient_scale); + specular_buffer=vec4(specular_light,0.0); + normal_mr_buffer=vec4(normal.x,normal.y,max(specular.r,max(specular.g,specular.b)),roughness); + +#else + +#ifdef SHADELESS frag_color=vec4(albedo,alpha); #else frag_color=vec4(ambient_light+diffuse_light+specular_light,alpha); +#endif #endif |