summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles1/rasterizer_gles1.cpp5
-rw-r--r--drivers/gles1/rasterizer_gles1.h2
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp295
-rw-r--r--drivers/gles2/rasterizer_gles2.h8
-rw-r--r--drivers/gles2/shader_gles2.h2
-rw-r--r--drivers/gles2/shaders/copy.glsl157
-rw-r--r--drivers/gles2/shaders/material.glsl61
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