diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles1/rasterizer_gles1.cpp | 5 | ||||
-rw-r--r-- | drivers/gles1/rasterizer_gles1.h | 2 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 295 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 8 | ||||
-rw-r--r-- | drivers/gles2/shader_gles2.h | 2 | ||||
-rw-r--r-- | drivers/gles2/shaders/copy.glsl | 157 | ||||
-rw-r--r-- | drivers/gles2/shaders/material.glsl | 61 |
7 files changed, 452 insertions, 78 deletions
diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index 9e13f12abe..9a6c928711 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -2847,6 +2847,11 @@ int RasterizerGLES1::light_instance_get_shadow_passes(RID p_light_instance) cons return 0; } +bool RasterizerGLES1::light_instance_get_pssm_shadow_overlap(RID p_light_instance) const { + + return false; +} + void RasterizerGLES1::light_instance_set_custom_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near,float p_split_far) { LightInstance *lighti = light_instance_owner.get( p_light_instance ); diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index 323d00a467..10b2d7694d 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -482,7 +482,6 @@ class RasterizerGLES1 : public Rasterizer { fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS]=1.0; fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST]=1.0; fx_param[VS::ENV_FX_PARAM_BCS_SATURATION]=1.0; - fx_param[VS::ENV_FX_PARAM_GAMMA]=1.0; } @@ -1100,6 +1099,7 @@ public: virtual bool light_instance_assign_shadow(RID p_light_instance); virtual ShadowType light_instance_get_shadow_type(RID p_light_instance) const; virtual int light_instance_get_shadow_passes(RID p_light_instance) const; + virtual bool light_instance_get_pssm_shadow_overlap(RID p_light_instance) const; virtual void light_instance_set_custom_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near=0,float p_split_far=0); virtual int light_instance_get_shadow_size(RID p_light_instance, int p_index=0) const { return 1; } diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 91b82d1999..307db4b762 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -43,6 +43,11 @@ #define _GL_HALF_FLOAT_OES 0x8D61 #endif +#define _GL_RGBA16F_EXT 0x881A +#define _GL_RGB16F_EXT 0x881B +#define _GL_RG16F_EXT 0x822F +#define _GL_R16F_EXT 0x822D +#define _GL_R32F_EXT 0x822E #define _DEPTH_COMPONENT24_OES 0x81A6 @@ -3317,6 +3322,11 @@ int RasterizerGLES2::light_instance_get_shadow_passes(RID p_light_instance) cons return 1; } +bool RasterizerGLES2::light_instance_get_pssm_shadow_overlap(RID p_light_instance) const { + + return shadow_filter>=SHADOW_FILTER_ESM; +} + void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near,float p_split_far) { LightInstance *lighti = light_instance_owner.get( p_light_instance ); @@ -3590,9 +3600,10 @@ void RasterizerGLES2::begin_frame() { glFrontFace(GL_CW); //fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting"); +#ifdef TOOLS_ENABLED canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false)); shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter"))); - +#endif window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); @@ -4302,6 +4313,13 @@ void RasterizerGLES2::add_particles( const RID& p_particle_instance, const Insta } +Color RasterizerGLES2::_convert_color(const Color& p_color) { + + if (current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]) + return p_color.to_linear(); + else + return p_color; +} void RasterizerGLES2::_set_cull(bool p_front,bool p_reverse_cull) { @@ -4383,9 +4401,9 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material //all goes to false by default material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PASS,shadow!=NULL); - material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF,shadow_filter!=SHADOW_FILTER_NONE); - material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter>SHADOW_FILTER_PCF5); - //material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,true); + material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF,shadow_filter==SHADOW_FILTER_PCF5 || shadow_filter==SHADOW_FILTER_PCF13); + material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter==SHADOW_FILTER_PCF13); + material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,shadow_filter==SHADOW_FILTER_ESM); if (p_opaque_pass && p_material->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS] && p_material->shader_cache && p_material->shader_cache->has_alpha) { @@ -4484,6 +4502,9 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material glBindTexture(GL_TEXTURE_2D,white_tex); //no texture texcoord++; + } else if (E->get().value.get_type()==Variant::COLOR){ + Color c = E->get().value; + material_shader.set_custom_uniform(E->get().index,_convert_color(c)); } else { material_shader.set_custom_uniform(E->get().index,E->get().value); } @@ -4534,6 +4555,8 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material Color col_begin = current_env->fx_param[VS::ENV_FX_PARAM_FOG_BEGIN_COLOR]; Color col_end = current_env->fx_param[VS::ENV_FX_PARAM_FOG_END_COLOR]; + col_begin=_convert_color(col_begin); + col_end=_convert_color(col_end); float from = current_env->fx_param[VS::ENV_FX_PARAM_FOG_BEGIN]; float zf = camera_z_far; float curve = current_env->fx_param[VS::ENV_FX_PARAM_FOG_ATTENUATION]; @@ -4588,11 +4611,14 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { LightInstance *li=light_instances[p_light]; Light *l=li->base; + Color col_ambient=_convert_color(l->colors[VS::LIGHT_COLOR_AMBIENT]); + Color col_diffuse=_convert_color(l->colors[VS::LIGHT_COLOR_DIFFUSE]); + Color col_specular=_convert_color(l->colors[VS::LIGHT_COLOR_SPECULAR]); for(int j=0;j<3;j++) { - light_data[VL_LIGHT_AMBIENT][j]=l->colors[VS::LIGHT_COLOR_AMBIENT][j]; - light_data[VL_LIGHT_DIFFUSE][j]=l->colors[VS::LIGHT_COLOR_DIFFUSE][j]; - light_data[VL_LIGHT_SPECULAR][j]=l->colors[VS::LIGHT_COLOR_SPECULAR][j]; + light_data[VL_LIGHT_AMBIENT][j]=col_ambient[j]; + light_data[VL_LIGHT_DIFFUSE][j]=col_diffuse[j]; + light_data[VL_LIGHT_SPECULAR][j]=col_specular[j]; } if (l->type!=VS::LIGHT_OMNI) { @@ -4626,6 +4652,8 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection[0]); material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE,Vector2(1.0,1.0)/li->near_shadow_buffer->size); material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,7); + if (shadow_filter==SHADOW_FILTER_ESM) + material_shader.set_uniform(MaterialShaderGLES2::ESM_MULTIPLIER,float(li->base->vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER])); if (li->base->type==VS::LIGHT_DIRECTIONAL) { @@ -6064,7 +6092,7 @@ void RasterizerGLES2::_draw_tex_bg() { } float nrg =float(current_env->bg_param[VS::ENV_BG_PARAM_ENERGY]); - if (current_env->fx_enabled[VS::ENV_FX_HDR]) + if (current_env->fx_enabled[VS::ENV_FX_HDR] && !use_fp16_fb) nrg*=0.25; //go down a quarter for hdr copy_shader.set_uniform(CopyShaderGLES2::ENERGY,nrg); copy_shader.set_uniform(CopyShaderGLES2::CUSTOM_ALPHA,float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW])); @@ -6178,7 +6206,7 @@ void RasterizerGLES2::end_scene() { glViewport( 0,0,viewport.width / framebuffer.scale, viewport.height / framebuffer.scale ); glScissor( 0,0,viewport.width / framebuffer.scale, viewport.height / framebuffer.scale ); - material_shader.set_conditional(MaterialShaderGLES2::USE_HDR,current_env && current_env->fx_enabled[VS::ENV_FX_HDR]); + material_shader.set_conditional(MaterialShaderGLES2::USE_8BIT_HDR,!use_fp16_fb && current_env && current_env->fx_enabled[VS::ENV_FX_HDR]); } else { if (current_rt) { @@ -6218,6 +6246,7 @@ void RasterizerGLES2::end_scene() { bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR]; else bgcolor = Globals::get_singleton()->get("render/default_clear_color"); + bgcolor = _convert_color(bgcolor); float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0; glClearColor(bgcolor.r,bgcolor.g,bgcolor.b,a); _glClearDepth(1.0); @@ -6237,7 +6266,8 @@ void RasterizerGLES2::end_scene() { } } else { - glClearColor(0.3,0.3,0.3,1.0); + Color c = _convert_color(Color(0.3,0.3,0.3)); + glClearColor(c.r,c.g,c.b,0.0); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); } @@ -6340,7 +6370,7 @@ void RasterizerGLES2::end_scene() { //time to copy!!! copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,current_env && current_env->fx_enabled[VS::ENV_FX_BCS]); - copy_shader.set_conditional(CopyShaderGLES2::USE_GAMMA,current_env && current_env->fx_enabled[VS::ENV_FX_GAMMA]); + copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]); copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,current_env && current_env->fx_enabled[VS::ENV_FX_HDR]); copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,true); @@ -6378,9 +6408,7 @@ void RasterizerGLES2::end_scene() { bcs.z=current_env->fx_param[VS::ENV_FX_PARAM_BCS_SATURATION]; copy_shader.set_uniform(CopyShaderGLES2::BCS,bcs); } - if (current_env && current_env->fx_enabled[VS::ENV_FX_GAMMA]) { - copy_shader.set_uniform(CopyShaderGLES2::GAMMA,float(current_env->fx_param[VS::ENV_FX_PARAM_GAMMA])); - } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, framebuffer.color ); glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); @@ -6388,7 +6416,7 @@ void RasterizerGLES2::end_scene() { _copy_screen_quad(); copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_GAMMA,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,false); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,false); copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,false); @@ -6396,7 +6424,7 @@ void RasterizerGLES2::end_scene() { copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,false); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,false); - material_shader.set_conditional(MaterialShaderGLES2::USE_HDR,false); + material_shader.set_conditional(MaterialShaderGLES2::USE_8BIT_HDR,false); if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR] && GLOBAL_DEF("rasterizer/debug_hdr",false)) { @@ -6443,6 +6471,7 @@ void RasterizerGLES2::end_shadow_map() { float dp_direction=0.0; bool flip_facing=false; + Rect2 vp_rect; switch(shadow->base->type) { @@ -6455,24 +6484,30 @@ void RasterizerGLES2::end_shadow_map() { if (shadow_pass==0) { - glViewport(0, sb->size*0.5, sb->size*0.5, sb->size*0.5); - glScissor(0, sb->size*0.5, sb->size*0.5, sb->size*0.5); + vp_rect=Rect2(0, sb->size/2, sb->size/2, sb->size/2); + glViewport(0, sb->size/2, sb->size/2, sb->size/2); + glScissor(0, sb->size/2, sb->size/2, sb->size/2); } else if (shadow_pass==1) { - glViewport(0, 0, sb->size*0.5, sb->size*0.5); - glScissor(0, 0, sb->size*0.5, sb->size*0.5); + vp_rect=Rect2(0, 0, sb->size/2, sb->size/2); + glViewport(0, 0, sb->size/2, sb->size/2); + glScissor(0, 0, sb->size/2, sb->size/2); } else if (shadow_pass==2) { - glViewport(sb->size*0.5, sb->size*0.5, sb->size*0.5, sb->size*0.5); - glScissor(sb->size*0.5, sb->size*0.5, sb->size*0.5, sb->size*0.5); + vp_rect=Rect2(sb->size/2, sb->size/2, sb->size/2, sb->size/2); + glViewport(sb->size/2, sb->size/2, sb->size/2, sb->size/2); + glScissor(sb->size/2, sb->size/2, sb->size/2, sb->size/2); } else if (shadow_pass==3) { - glViewport(sb->size*0.5, 0, sb->size*0.5, sb->size*0.5); - glScissor(sb->size*0.5, 0, sb->size*0.5, sb->size*0.5); + vp_rect=Rect2(sb->size/2, 0, sb->size/2, sb->size/2); + glViewport(sb->size/2, 0, sb->size/2, sb->size/2); + glScissor(sb->size/2, 0, sb->size/2, sb->size/2); } + + glEnable(GL_SCISSOR_TEST); } else if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { @@ -6481,14 +6516,16 @@ void RasterizerGLES2::end_shadow_map() { cm = shadow->custom_projection[0]; light_transform=shadow->custom_transform[0]; - glViewport(0, sb->size*0.5, sb->size, sb->size*0.5); - glScissor(0, sb->size*0.5, sb->size, sb->size*0.5); + vp_rect=Rect2(0, sb->size/2, sb->size, sb->size/2); + glViewport(0, sb->size/2, sb->size, sb->size/2); + glScissor(0, sb->size/2, sb->size, sb->size/2); } else { cm = shadow->custom_projection[1]; light_transform=shadow->custom_transform[1]; - glViewport(0, 0, sb->size, sb->size*0.5); - glScissor(0, 0, sb->size, sb->size*0.5); + vp_rect=Rect2(0, 0, sb->size, sb->size/2); + glViewport(0, 0, sb->size, sb->size/2); + glScissor(0, 0, sb->size, sb->size/2); } @@ -6497,6 +6534,7 @@ void RasterizerGLES2::end_shadow_map() { } else { cm = shadow->custom_projection[0]; light_transform=shadow->custom_transform[0]; + vp_rect=Rect2(0, 0, sb->size, sb->size); glViewport(0, 0, sb->size, sb->size); } @@ -6527,11 +6565,13 @@ void RasterizerGLES2::end_shadow_map() { shadow->dp.y=dp_direction; if (shadow_pass==0) { - glViewport(0, sb->size*0.5, sb->size, sb->size*0.5); - glScissor(0, sb->size*0.5, sb->size, sb->size*0.5); + vp_rect=Rect2(0, sb->size/2, sb->size, sb->size/2); + glViewport(0, sb->size/2, sb->size, sb->size/2); + glScissor(0, sb->size/2, sb->size, sb->size/2); } else { - glViewport(0, 0, sb->size, sb->size*0.5); - glScissor(0, 0, sb->size, sb->size*0.5); + vp_rect=Rect2(0, 0, sb->size, sb->size/2); + glViewport(0, 0, sb->size, sb->size/2); + glScissor(0, 0, sb->size, sb->size/2); } glEnable(GL_SCISSOR_TEST); shadow->projection=cm; @@ -6565,6 +6605,7 @@ void RasterizerGLES2::end_shadow_map() { z_far=cm.get_z_far(); glViewport(0, 0, sb->size, sb->size); + vp_rect=Rect2(0, 0, sb->size, sb->size); _glClearDepth(1.0f); glClearColor(1,1,1,1); if (use_rgba_shadowmaps) @@ -6583,16 +6624,124 @@ void RasterizerGLES2::end_shadow_map() { material_shader.set_conditional(MaterialShaderGLES2::USE_DUAL_PARABOLOID,false); - glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); - //glDisable(GL_POLYGON_OFFSET_FILL); - //if (!use_rgba_shadowmaps) - glColorMask(1, 1, 1, 1); + + if (shadow_filter==SHADOW_FILTER_ESM) { + + copy_shader.set_conditional(CopyShaderGLES2::USE_RGBA_DEPTH,use_rgba_shadowmaps); + copy_shader.set_conditional(CopyShaderGLES2::USE_HIGHP_SOURCE,!use_rgba_shadowmaps); + + Vector2 psize(1.0/sb->size,1.0/sb->size); + float pscale = 1.0; + int passes=shadow->base->vars[VS::LIGHT_PARAM_SHADOW_BLUR_PASSES]; + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); +#ifdef GLEW_ENABLED + glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); +#endif + + for(int i=0;i<VS::ARRAY_MAX;i++) { + glDisableVertexAttribArray(i); + } + glBindBuffer(GL_ARRAY_BUFFER,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); + glDisable(GL_SCISSOR_TEST); + + if (!use_rgba_shadowmaps) { + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glDepthMask(true); + } else { + glDisable(GL_DEPTH_TEST); + } + + for(int i=0;i<passes;i++) { + + + Vector2 src_sb_uv[4]={ + (vp_rect.pos+Vector2(0,vp_rect.size.y))/sb->size, + (vp_rect.pos+vp_rect.size)/sb->size, + (vp_rect.pos+Vector2(vp_rect.size.x,0))/sb->size, + (vp_rect.pos)/sb->size + }; +/* + Vector2 src_uv[4]={ + Vector2( 0, 1), + Vector2( 1, 1), + Vector2( 1, 0), + Vector2( 0, 0) + }; +*/ + static const Vector2 dst_pos[4]={ + Vector2(-1, 1), + Vector2( 1, 1), + Vector2( 1,-1), + Vector2(-1,-1) + }; + + glBindFramebuffer(GL_FRAMEBUFFER, blur_shadow_buffer.fbo); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, sb->depth); +#ifdef GLEW_ENABLED + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); +#endif + + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS,true); + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,false); + + copy_shader.bind(); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,psize); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE,pscale); + copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE,1); + //copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0); + glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); + + + _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv); + + + Vector2 src_bb_uv[4]={ + (vp_rect.pos+Vector2(0,vp_rect.size.y))/blur_shadow_buffer.size, + (vp_rect.pos+vp_rect.size)/blur_shadow_buffer.size, + (vp_rect.pos+Vector2(vp_rect.size.x,0))/blur_shadow_buffer.size, + (vp_rect.pos)/blur_shadow_buffer.size, + }; + + glBindFramebuffer(GL_FRAMEBUFFER, sb->fbo); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, blur_shadow_buffer.depth); +#ifdef GLEW_ENABLED + + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); +#endif + + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS,false); + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,true); + copy_shader.bind(); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,psize); + copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE,pscale); + copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE,1); + glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0); + + _draw_gui_primitive(4,dst_pos,NULL,src_bb_uv); + + + } + + glDepthFunc(GL_LEQUAL); + copy_shader.set_conditional(CopyShaderGLES2::USE_RGBA_DEPTH,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_HIGHP_SOURCE,false); + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS,false); + copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,false); + + } DEBUG_TEST_ERROR("Drawing Shadow"); shadow=NULL; - + glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer); + glColorMask(1, 1, 1, 1); + //glDisable(GL_POLYGON_OFFSET_FILL); } @@ -6635,23 +6784,14 @@ void RasterizerGLES2::_debug_draw_shadows_type(Vector<ShadowBuffer>& p_shadows,P // Size2 debug_size(512,512); - for (int i=0;i<p_shadows.size();i++) { + int useblur=shadow_filter==SHADOW_FILTER_ESM?1:0; + for (int i=0;i<p_shadows.size()+useblur;i++) { - ShadowBuffer *sb=&p_shadows[i]; + ShadowBuffer *sb=i==p_shadows.size()?&blur_shadow_buffer:&p_shadows[i]; - if (!sb->owner) + if (!sb->owner && i!=p_shadows.size()) continue; - - if (sb->owner->base->type==VS::LIGHT_DIRECTIONAL) { - - //if (sb->owner->shadow_pass!=scene_pass-1) - // continue; - } else { - - //if (sb->owner->shadow_pass!=frame) - // continue; - } _debug_draw_shadow(sb->depth, Rect2( ofs, debug_size )); ofs.x+=debug_size.x; if ( (ofs.x+debug_size.x) > viewport.width ) { @@ -7560,6 +7700,11 @@ bool RasterizerGLES2::ShadowBuffer::init(int p_size,bool p_use_depth) { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); +#ifdef GLEW_ENABLED + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +#endif + // Attach the depth texture to FBO depth attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); @@ -7778,9 +7923,17 @@ void RasterizerGLES2::_update_framebuffer() { #endif //color + + GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA; + GLuint format_rgb = use_fp16_fb?_GL_RGB16F_EXT:GL_RGB; + GLuint format_type = use_fp16_fb?_GL_HALF_FLOAT_OES:GL_UNSIGNED_BYTE; + GLuint format_luminance = use_fp16_fb?_GL_R32F_EXT:GL_RGBA; + GLuint format_luminance_type = use_fp16_fb?GL_FLOAT:GL_UNSIGNED_BYTE; + GLuint format_luminance_components = use_fp16_fb?GL_RED:GL_RGBA; + glGenTextures(1, &framebuffer.color); glBindTexture(GL_TEXTURE_2D, framebuffer.color); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, framebuffer.width, framebuffer.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, GL_RGBA, format_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -7814,7 +7967,7 @@ void RasterizerGLES2::_update_framebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.sample_fbo); glGenTextures(1, &framebuffer.sample_color); glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, framebuffer.width, framebuffer.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, GL_RGBA, format_type, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -7873,8 +8026,8 @@ void RasterizerGLES2::_update_framebuffer() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, size, size, 0, + GL_RGBA, format_type, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer.blur[i].color, 0); @@ -7922,8 +8075,8 @@ void RasterizerGLES2::_update_framebuffer() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lb.size, lb.size, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, format_luminance, lb.size, lb.size, 0, + format_luminance_components, format_luminance_type, NULL); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, lb.color, 0); @@ -8052,6 +8205,7 @@ void RasterizerGLES2::init() { // framebuffer.blur[1].fbo=false; framebuffer.active=false; + //do a single initial clear glClearColor(0,0,0,1); //glClearDepth(1.0); @@ -8086,8 +8240,9 @@ void RasterizerGLES2::init() { use_attribute_instancing=true; #ifdef OSX_ENABLED use_rgba_shadowmaps=true; + use_fp16_fb=false; #else - use_rgba_shadowmaps=false; + #endif use_half_float=true; @@ -8098,6 +8253,9 @@ void RasterizerGLES2::init() { } read_depth_supported=extensions.has("GL_OES_depth_texture"); use_rgba_shadowmaps=!read_depth_supported; + if (shadow_filter>=SHADOW_FILTER_ESM && !extensions.has("GL_EXT_frag_depth")) { + use_rgba_shadowmaps=true; //no other way, go back to rgba + } pvr_supported=extensions.has("GL_IMG_texture_compression_pvrtc"); etc_supported=extensions.has("GL_OES_compressed_ETC1_RGB8_texture"); use_depth24 = extensions.has("GL_OES_depth24"); @@ -8131,6 +8289,10 @@ void RasterizerGLES2::init() { use_attribute_instancing=false; } + if (use_fp16_fb) { + use_fp16_fb=extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float"); + } + //etc_supported=false; use_hw_skeleton_xform=false; @@ -8150,15 +8312,19 @@ void RasterizerGLES2::init() { //don't use a shadowbuffer too big in GLES, this should be the maximum int max_shadow_size = GLOBAL_DEF("rasterizer/max_shadow_buffer_size",1024);//nearest_power_of_2(MIN(vm.width,vm.height))/2; - while(max_shadow_size>=16) { + int smsize=max_shadow_size; + while(smsize>=16) { ShadowBuffer sb; - bool s = sb.init(max_shadow_size,!use_rgba_shadowmaps); + bool s = sb.init(smsize,!use_rgba_shadowmaps); if (s) near_shadow_buffers.push_back(sb); - max_shadow_size/=2; + smsize/=2; } + blur_shadow_buffer.init(max_shadow_size,!use_rgba_shadowmaps); + + //material_shader material_shader.set_conditional(MaterialShaderGLES2::USE_DEPTH_SHADOWS,!use_rgba_shadowmaps); @@ -8168,6 +8334,9 @@ void RasterizerGLES2::init() { shadow_material = material_create(); //empty with nothing shadow_mat_ptr = material_owner.get(shadow_material); overdraw_material = create_overdraw_debug_material(); + copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR,!use_fp16_fb); + + canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false)); npo2_textures_available=true; //fragment_lighting=false; @@ -8423,6 +8592,8 @@ void RasterizerGLES2::reload_vram() { near_shadow_buffers[i].init(near_shadow_buffers[i].size,!use_rgba_shadowmaps); } + blur_shadow_buffer.init(near_shadow_buffers[0].size,!use_rgba_shadowmaps); + canvas_shader.clear_caches(); @@ -8473,8 +8644,8 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo fragment_lighting=GLOBAL_DEF("rasterizer/use_fragment_lighting",true); read_depth_supported=true; //todo check for extension shadow_filter=ShadowFilterTechnique((int)(GLOBAL_DEF("rasterizer/shadow_filter",SHADOW_FILTER_PCF5))); - Globals::get_singleton()->set_custom_property_info("rasterizer/shadow_filter",PropertyInfo(Variant::INT,"rasterizer/shadow_filter",PROPERTY_HINT_ENUM,"None,PCF5,PCF13,ESM,VSM")); - + Globals::get_singleton()->set_custom_property_info("rasterizer/shadow_filter",PropertyInfo(Variant::INT,"rasterizer/shadow_filter",PROPERTY_HINT_ENUM,"None,PCF5,PCF13,ESM")); + use_fp16_fb=bool(GLOBAL_DEF("rasterizer/fp16_framebuffer",true)); use_shadow_mapping=true; use_fast_texture_filter=!bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true)); skel_default.resize(1024*4); diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 0fee8bf918..dce096b29e 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -80,6 +80,7 @@ class RasterizerGLES2 : public Rasterizer { bool read_depth_supported; bool use_framebuffers; bool use_shadow_mapping; + bool use_fp16_fb; ShadowFilterTechnique shadow_filter; bool use_shadow_esm; @@ -585,6 +586,8 @@ class RasterizerGLES2 : public Rasterizer { vars[VS::LIGHT_PARAM_SHADOW_DARKENING]=0.0; vars[VS::LIGHT_PARAM_SHADOW_Z_OFFSET]=0.2; vars[VS::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE]=1.4; + vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER]=60.0; + vars[VS::LIGHT_PARAM_SHADOW_BLUR_PASSES]=1; colors[VS::LIGHT_COLOR_AMBIENT]=Color(0,0,0); colors[VS::LIGHT_COLOR_DIFFUSE]=Color(1,1,1); colors[VS::LIGHT_COLOR_SPECULAR]=Color(1,1,1); @@ -645,7 +648,6 @@ class RasterizerGLES2 : public Rasterizer { fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS]=1.0; fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST]=1.0; fx_param[VS::ENV_FX_PARAM_BCS_SATURATION]=1.0; - fx_param[VS::ENV_FX_PARAM_GAMMA]=1.0; } @@ -998,6 +1000,8 @@ class RasterizerGLES2 : public Rasterizer { }; Vector<ShadowBuffer> near_shadow_buffers; + ShadowBuffer blur_shadow_buffer; + Vector<ShadowBuffer> far_shadow_buffers; LightInstance *shadow; @@ -1100,6 +1104,7 @@ class RasterizerGLES2 : public Rasterizer { bool cull_front; bool lights_use_shadow; _FORCE_INLINE_ void _set_cull(bool p_front,bool p_reverse_cull=false); + _FORCE_INLINE_ Color _convert_color(const Color& p_color); void _process_glow_bloom(); void _process_hdr(); @@ -1376,6 +1381,7 @@ public: virtual ShadowType light_instance_get_shadow_type(RID p_light_instance,bool p_far=false) const; virtual int light_instance_get_shadow_passes(RID p_light_instance) const; + virtual bool light_instance_get_pssm_shadow_overlap(RID p_light_instance) const; virtual void light_instance_set_shadow_transform(RID p_light_instance, int p_index, const CameraMatrix& p_camera, const Transform& p_transform, float p_split_near=0,float p_split_far=0); virtual int light_instance_get_shadow_size(RID p_light_instance, int p_index=0) const; diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h index bb99862b9e..17d893e349 100644 --- a/drivers/gles2/shader_gles2.h +++ b/drivers/gles2/shader_gles2.h @@ -308,6 +308,8 @@ public: uniforms_dirty = true; }; + uint32_t get_version() const { return new_conditional_version.version; } + void set_uniform_camera(int p_idx, const CameraMatrix& p_mat) { uniform_cameras[p_idx] = p_mat; diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index 2f1b349618..6d78c69e50 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -54,8 +54,12 @@ varying vec3 cube_interp; uniform samplerCube source_cube; #else varying vec2 uv_interp; +#ifdef HIGHP_SOURCE +uniform highp sampler2D source; +#else uniform sampler2D source; #endif +#endif varying vec2 uv2_interp; #ifdef USE_GLOW @@ -83,12 +87,6 @@ uniform vec3 bcs; #endif -#ifdef USE_GAMMA - -uniform float gamma; - -#endif - #ifdef USE_GLOW_COPY uniform float bloom; @@ -96,7 +94,7 @@ uniform float bloom_treshold; #endif -#if defined(BLUR_V_PASS) || defined(BLUR_H_PASS) || defined(USE_HDR_REDUCE) +#if defined(SHADOW_BLUR_V_PASS) || defined(SHADOW_BLUR_H_PASS) || defined(BLUR_V_PASS) || defined(BLUR_H_PASS) || defined(USE_HDR_REDUCE) uniform vec2 pixel_size; uniform float pixel_scale; @@ -133,6 +131,17 @@ uniform float custom_alpha; void main() { //vec4 color = color_interp; +#ifdef USE_HIGHP_SOURCE + +#ifdef USE_CUBEMAP + highp vec4 color = textureCube( source_cube, normalize(cube_interp) ); + +#else + highp vec4 color = texture2D( source, uv_interp ); +#endif + +#else + #ifdef USE_CUBEMAP vec4 color = textureCube( source_cube, normalize(cube_interp) ); @@ -141,6 +150,8 @@ void main() { #endif +#endif + #ifdef USE_FXAA #define FXAA_REDUCE_MIN (1.0/ 128.0) @@ -226,17 +237,103 @@ void main() { #endif +#ifdef SHADOW_BLUR_V_PASS + +#ifdef USE_RGBA_DEPTH + +#define VEC42DEPTH(m_vec4) dot(m_vec4,vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1)) + + highp float depth = VEC42DEPTH(color)*0.383; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-3.0)*pixel_scale))*0.006; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-2.0)*pixel_scale))*0.061; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-1.0)*pixel_scale))*0.242; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*1.0)*pixel_scale))*0.242; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*2.0)*pixel_scale))*0.061; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(0.0,pixel_size.y*3.0)*pixel_scale))*0.006; + highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); + comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); + color=comp; + +#else + + highp float depth = color.r*0.383; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-3.0)*pixel_scale).r*0.006; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-2.0)*pixel_scale).r*0.061; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-1.0)*pixel_scale).r*0.242; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*1.0)*pixel_scale).r*0.242; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*2.0)*pixel_scale).r*0.061; + depth+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*3.0)*pixel_scale).r*0.006; + +#ifdef USE_GLES_OVER_GL + gl_FragDepth = depth; + +#else + gl_FragDepthEXT = depth; +#endif + + return; +#endif + +#endif + +#ifdef SHADOW_BLUR_H_PASS + + +#ifdef USE_RGBA_DEPTH + +#define VEC42DEPTH(m_vec4) dot(m_vec4,vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1)) + + highp float depth = VEC42DEPTH(color)*0.383; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*-3.0,0.0)*pixel_scale))*0.006; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*-2.0,0.0)*pixel_scale))*0.061; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*-1.0,0.0)*pixel_scale))*0.242; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*1.0,0.0)*pixel_scale))*0.242; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*2.0,0.0)*pixel_scale))*0.061; + depth+=VEC42DEPTH(texture2D(source,uv_interp+vec2(pixel_size.x*3.0,0.0)*pixel_scale))*0.006; + highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); + comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); + color=comp; +#else + + + highp float depth = color.r*0.383; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*-3.0,0.0)*pixel_scale).r*0.006; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*-2.0,0.0)*pixel_scale).r*0.061; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*-1.0,0.0)*pixel_scale).r*0.242; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*1.0,0.0)*pixel_scale).r*0.242; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*2.0,0.0)*pixel_scale).r*0.061; + depth+=texture2D(source,uv_interp+vec2(pixel_size.x*3.0,0.0)*pixel_scale).r*0.006; + +#ifdef USE_GLES_OVER_GL + gl_FragDepth = depth; +#else + gl_FragDepthEXT = depth; +#endif + + return; + +#endif + +#endif + #ifdef USE_HDR + +#ifdef USE_8BIT_HDR highp vec4 _mult = vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1); highp float hdr_lum = dot(texture2D( hdr_source, vec2(0.0) ), _mult ); color.rgb*=LUM_RANGE; hdr_lum*=LUM_RANGE; //restore to full range +#else + highp float hdr_lum = texture2D( hdr_source, vec2(0.0) ).r; +#endif + highp float tone_scale = tonemap_exposure / hdr_lum; //only linear supported color.rgb*=tone_scale; #endif + #ifdef USE_GLOW_COPY highp vec3 glowcol = color.rgb*color.a+step(bloom_treshold,dot(vec3(0.3333,0.3333,0.3333),color.rgb))*bloom*color.rgb; @@ -281,10 +378,15 @@ void main() { #endif -#ifdef USE_GAMMA - - color.rgb = pow(color.rgb,gamma); +#ifdef USE_SRGB + { //i have my doubts about how fast this is + color.rgb = min(color.rgb,vec3(1.0)); //clamp just in case + vec3 S1 = sqrt(color.rgb); + vec3 S2 = sqrt(S1); + vec3 S3 = sqrt(S2); + color.rgb = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.225411470 * color.rgb; + } #endif @@ -292,13 +394,20 @@ void main() { //highp float lum = dot(color.rgb,highp vec3(1.0/3.0,1.0/3.0,1.0/3.0)); highp float lum = max(color.r,max(color.g,color.b)); +#ifdef USE_8BIT_HDR highp vec4 comp = fract(lum * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); color=comp; +#else + color.rgb=vec3(lum); +#endif + + #endif #ifdef USE_HDR_REDUCE +#ifdef USE_8BIT_HDR highp vec4 _multcv = vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0, 1.0); highp float lum_accum = dot(color,_multcv ); lum_accum += dot(texture2D( source, uv_interp+vec2(-pixel_size.x,-pixel_size.y) ),_multcv ); @@ -310,16 +419,42 @@ void main() { lum_accum += dot(texture2D( source, uv_interp+vec2(0.0,pixel_size.y) ),_multcv ); lum_accum += dot(texture2D( source, uv_interp+vec2(pixel_size.x,pixel_size.y) ),_multcv ); lum_accum/=9.0; +#else + + highp float lum_accum = color.r; + lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,-pixel_size.y) ).r; + lum_accum += texture2D( source, uv_interp+vec2(0.0,-pixel_size.y) ).r; + lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,-pixel_size.y) ).r; + lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,0.0) ).r; + lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,0.0) ).r; + lum_accum += texture2D( source, uv_interp+vec2(-pixel_size.x,pixel_size.y) ).r; + lum_accum += texture2D( source, uv_interp+vec2(0.0,pixel_size.y) ).r; + lum_accum += texture2D( source, uv_interp+vec2(pixel_size.x,pixel_size.y) ).r; + lum_accum/=9.0; + +#endif #ifdef USE_HDR_STORE +#ifdef USE_8BIT_HDR highp float vd_lum = dot(texture2D( source_vd_lum, vec2(0.0) ), _multcv ); lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance*(1.0/LUM_RANGE),max_luminance*(1.0/LUM_RANGE)); +#else + highp float vd_lum=texture2D( source_vd_lum, vec2(0.0) ); + lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance,max_luminance); +#endif + #endif +#ifdef USE_8BIT_HDR highp vec4 comp = fract(lum_accum * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0)); comp -= comp.xxyz * vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0); color=comp; +#else + color.rgb=vec3(lum_accum); +#endif + + #endif #ifdef USE_RGBE @@ -338,6 +473,8 @@ void main() { #ifdef USE_CUSTOM_ALPHA color.a=custom_alpha; #endif + + gl_FragColor = color; } diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 7ed59ae9cd..3aed9820ed 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -342,7 +342,7 @@ VERTEX_SHADER_CODE #ifdef USE_FOG - fog_interp.a = pow( clamp( (-vertex_interp.z-fog_params.x)/(fog_params.y-fog_params.x), 0.0, 1.0 ), fog_params.z ); + fog_interp.a = pow( clamp( (length(vertex_interp)-fog_params.x)/(fog_params.y-fog_params.x), 0.0, 1.0 ), fog_params.z ); fog_interp.rgb = mix( fog_color_begin, fog_color_end, fog_interp.a ); #endif @@ -666,9 +666,14 @@ float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) { #ifdef USE_SHADOW_ESM +uniform float esm_multiplier; float SAMPLE_SHADOW_TEX(vec2 p_uv,float p_depth) { +#if defined (USE_DEPTH_SHADOWS) + //these only are used if interpolation exists + highp float occluder = SHADOW_DEPTH(shadow_texture, p_uv); +#else vec2 unnormalized = p_uv/shadow_texel_size; vec2 fractional = fract(unnormalized); unnormalized = floor(unnormalized); @@ -681,7 +686,8 @@ float SAMPLE_SHADOW_TEX(vec2 p_uv,float p_depth) { highp float occluder = (exponent.w + (exponent.x - exponent.w) * fractional.y); occluder = occluder + ((exponent.z + (exponent.y - exponent.z) * fractional.y) - occluder)*fractional.x; - return clamp(exp(28.0 * ( occluder - p_depth )),0.0,1.0); +#endif + return clamp(exp(esm_multiplier* ( occluder - p_depth )),0.0,1.0); } @@ -818,7 +824,7 @@ FRAGMENT_SHADER_CODE vec3 col_up=texture2D(ambient_octree_tex,octant_uv).rgb; octant_uv.y+=ambient_octree_pix_size.y*2.0; vec3 col_down=texture2D(ambient_octree_tex,octant_uv).rgb; - ambientmap_color=mix(col_down,col_up,1.0-sub.z); + ambientmap_color=mix(col_up,col_down,sub.z); ambientmap_color*=diffuse.rgb; @@ -866,6 +872,15 @@ FRAGMENT_SHADER_CODE vec2 pssm_coord; float pssm_z; +#if defined(LIGHT_USE_PSSM) && defined(USE_SHADOW_ESM) +#define USE_PSSM_BLEND + float pssm_blend; + vec2 pssm_coord_2; + float pssm_z_2; + vec3 light_pssm_split_inv = 1.0/light_pssm_split; + float w_inv = 1.0/gl_FragCoord.w; +#endif + #ifdef LIGHT_USE_PSSM4 @@ -874,10 +889,21 @@ FRAGMENT_SHADER_CODE if (gl_FragCoord.w > light_pssm_split.x) { pssm_coord=shadow_coord.xy; pssm_z=shadow_coord.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord2.xy; + pssm_z_2=shadow_coord2.z; + pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv); +#endif } else { pssm_coord=shadow_coord2.xy; pssm_z=shadow_coord2.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord3.xy; + pssm_z_2=shadow_coord3.z; + pssm_blend=smoothstep(light_pssm_split_inv.x,light_pssm_split_inv.y,w_inv); +#endif + } } else { @@ -885,9 +911,21 @@ FRAGMENT_SHADER_CODE if (gl_FragCoord.w > light_pssm_split.z) { pssm_coord=shadow_coord3.xy; pssm_z=shadow_coord3.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord4.xy; + pssm_z_2=shadow_coord4.z; + pssm_blend=smoothstep(light_pssm_split_inv.y,light_pssm_split_inv.z,w_inv); +#endif + } else { pssm_coord=shadow_coord4.xy; pssm_z=shadow_coord4.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord4.xy; + pssm_z_2=shadow_coord4.z; + pssm_blend=0.0; +#endif + } } @@ -896,16 +934,31 @@ FRAGMENT_SHADER_CODE if (gl_FragCoord.w > light_pssm_split.x) { pssm_coord=shadow_coord.xy; pssm_z=shadow_coord.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord2.xy; + pssm_z_2=shadow_coord2.z; + pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv); +#endif } else { pssm_coord=shadow_coord2.xy; pssm_z=shadow_coord2.z; +#if defined(USE_PSSM_BLEND) + pssm_coord_2=shadow_coord2.xy; + pssm_z_2=shadow_coord2.z; + pssm_blend=0.0; +#endif + } #endif //one one sample shadow_attenuation=SAMPLE_SHADOW_TEX(pssm_coord,pssm_z); +#if defined(USE_PSSM_BLEND) + shadow_attenuation=mix(shadow_attenuation,SAMPLE_SHADOW_TEX(pssm_coord_2,pssm_z_2),pssm_blend); +#endif + #endif @@ -1054,7 +1107,7 @@ FRAGMENT_SHADER_CODE diffuse.a=glow; #endif -#ifdef USE_HDR +#ifdef USE_8BIT_HDR diffuse.rgb*=0.25; #endif |