diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-05-04 22:50:23 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-05-04 22:50:23 -0300 |
commit | 72ae89c5aa8da9110ec8f89e5558d5d04935f3b5 (patch) | |
tree | 453b2c8b8cc0edc588cee2dd3e440b30ff729ae2 /drivers | |
parent | 3c17e0c91548299b60a6d3998eadb303418512cc (diff) |
Lots of 3D improvements:
-Object Manipulator Gizmo keeps proper scale in all windows and projections, (configurable on settings too).
-Manipulator gizmos for other objects (camera, shapes, etc) massively improved and bug-fixed.
-Manipulator gizmos are different for edited object and other objects.
-Properly highlight manipulator gizmo handles when hovered.
-Fixed bugs in fragment program when using more than 1 light together.
-Reload png/jpg files automatically in editor if edited externally.
-Added 4-stages Parallel Split Shadow Mapping, to improve shadow quality in large scenarios
-Added PCF13 to improve smoothness of shadow borders
-General optimization of directional light shadow mapping for Orthogonal,PSM and PSSM.
-Fixed normal mapping when importing DAE files, works nicely now.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles1/rasterizer_gles1.cpp | 21 | ||||
-rw-r--r-- | drivers/gles1/rasterizer_gles1.h | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.cpp | 132 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_gles2.h | 19 | ||||
-rw-r--r-- | drivers/gles2/shaders/material.glsl | 105 |
5 files changed, 239 insertions, 42 deletions
diff --git a/drivers/gles1/rasterizer_gles1.cpp b/drivers/gles1/rasterizer_gles1.cpp index 3ffebd4703..60c88af508 100644 --- a/drivers/gles1/rasterizer_gles1.cpp +++ b/drivers/gles1/rasterizer_gles1.cpp @@ -1982,6 +1982,9 @@ AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh) const { Mesh *mesh = mesh_owner.get( p_mesh ); ERR_FAIL_COND_V(!mesh,AABB()); + if (mesh->custom_aabb!=AABB()) + return mesh->custom_aabb; + AABB aabb; for (int i=0;i<mesh->surfaces.size();i++) { @@ -1995,6 +1998,24 @@ AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh) const { return aabb; } +void RasterizerGLES1::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) { + + Mesh *mesh = mesh_owner.get( p_mesh ); + ERR_FAIL_COND(!mesh); + + mesh->custom_aabb=p_aabb; + +} + +AABB RasterizerGLES1::mesh_get_custom_aabb(RID p_mesh) const { + + const Mesh *mesh = mesh_owner.get( p_mesh ); + ERR_FAIL_COND_V(!mesh,AABB()); + + return mesh->custom_aabb; +} + + /* MULTIMESH API */ RID RasterizerGLES1::multimesh_create() { diff --git a/drivers/gles1/rasterizer_gles1.h b/drivers/gles1/rasterizer_gles1.h index e7e3200bbc..dbb411c8a3 100644 --- a/drivers/gles1/rasterizer_gles1.h +++ b/drivers/gles1/rasterizer_gles1.h @@ -323,6 +323,7 @@ class RasterizerGLES1 : public Rasterizer { Vector<Surface*> surfaces; int morph_target_count; VS::MorphTargetMode morph_target_mode; + AABB custom_aabb; mutable uint64_t last_pass; Mesh() { @@ -938,6 +939,9 @@ public: virtual AABB mesh_get_aabb(RID p_mesh) const; + virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); + virtual AABB mesh_get_custom_aabb(RID p_mesh) const; + /* MULTIMESH API */ virtual RID multimesh_create(); diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 58abb71a12..2fffbb823e 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -2241,6 +2241,9 @@ AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const { Mesh *mesh = mesh_owner.get( p_mesh ); ERR_FAIL_COND_V(!mesh,AABB()); + if (mesh->custom_aabb!=AABB()) + return mesh->custom_aabb; + AABB aabb; for (int i=0;i<mesh->surfaces.size();i++) { @@ -2253,6 +2256,24 @@ AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const { return aabb; } + + +void RasterizerGLES2::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) { + + Mesh *mesh = mesh_owner.get( p_mesh ); + ERR_FAIL_COND(!mesh); + + mesh->custom_aabb=p_aabb; + +} + +AABB RasterizerGLES2::mesh_get_custom_aabb(RID p_mesh) const { + + const Mesh *mesh = mesh_owner.get( p_mesh ); + ERR_FAIL_COND_V(!mesh,AABB()); + + return mesh->custom_aabb; +} /* MULTIMESH API */ RID RasterizerGLES2::multimesh_create() { @@ -3114,7 +3135,8 @@ Rasterizer::ShadowType RasterizerGLES2::light_instance_get_shadow_type(RID p_lig case VS::LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE:{ return SHADOW_PSM; } break; - case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT:{ + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:{ return SHADOW_PSSM; } break; } @@ -3131,9 +3153,13 @@ int RasterizerGLES2::light_instance_get_shadow_passes(RID p_light_instance) cons LightInstance *lighti = light_instance_owner.get( p_light_instance ); ERR_FAIL_COND_V(!lighti,0); - if (lighti->base->type==VS::LIGHT_OMNI || (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT)) + + if (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + + return 4; // dp4 + } else if (lighti->base->type==VS::LIGHT_OMNI || (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)) { return 2; // dp - else + } else return 1; } @@ -3145,6 +3171,10 @@ void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance, ERR_FAIL_COND(lighti->base->type!=VS::LIGHT_DIRECTIONAL); // ERR_FAIL_INDEX(p_index,1); + lighti->custom_projection[p_index]=p_camera; + lighti->custom_transform[p_index]=p_transform; + lighti->shadow_split[p_index]=1.0/p_split_far; +#if 0 if (p_index==0) { lighti->custom_projection=p_camera; lighti->custom_transform=p_transform; @@ -3161,7 +3191,7 @@ void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance, lighti->shadow_split2=p_split_far; } - +#endif } int RasterizerGLES2::light_instance_get_shadow_size(RID p_light_instance, int p_index) const{ @@ -3407,6 +3437,7 @@ void RasterizerGLES2::begin_frame() { //fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting"); 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"))); window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height ); @@ -3675,18 +3706,21 @@ void RasterizerGLES2::add_light( RID p_light_instance ) { if (li->base->shadow_enabled) { CameraMatrix bias; bias.set_light_bias(); - Transform modelview=Transform(camera_transform_inverse * li->custom_transform).inverse(); - li->shadow_projection = bias * li->custom_projection * modelview; - Transform modelview2=Transform(camera_transform_inverse * li->custom_transform2).inverse(); - li->shadow_projection2 = bias * li->custom_projection2 * modelview2; + int passes=light_instance_get_shadow_passes(p_light_instance); + + for(int i=0;i<passes;i++) { + Transform modelview=Transform(camera_transform_inverse * li->custom_transform[i]).inverse(); + li->shadow_projection[i] = bias * li->custom_projection[i] * modelview; + } + lights_use_shadow=true; } } break; case VS::LIGHT_OMNI: { if (li->base->shadow_enabled) { - li->shadow_projection = Transform(camera_transform_inverse * li->transform).inverse(); + li->shadow_projection[0] = Transform(camera_transform_inverse * li->transform).inverse(); lights_use_shadow=true; } } break; @@ -3696,7 +3730,7 @@ void RasterizerGLES2::add_light( RID p_light_instance ) { CameraMatrix bias; bias.set_light_bias(); Transform modelview=Transform(camera_transform_inverse * li->transform).inverse(); - li->shadow_projection = bias * li->projection * modelview; + li->shadow_projection[0] = bias * li->projection * modelview; lights_use_shadow=true; } } break; @@ -3954,8 +3988,10 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD light_types[i]=VS::LIGHT_DIRECTIONAL; if (directional_lights[i]->base->shadow_enabled) { light_types[i]|=0x8; - if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT) + if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) light_types[i]|=0x10; + else if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) + light_types[i]|=0x30; } @@ -4152,7 +4188,8 @@ 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,use_shadow_pcf); + 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); @@ -4379,16 +4416,27 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) { //} - material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection); + 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 (li->base->type==VS::LIGHT_DIRECTIONAL && li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT) { + if (li->base->type==VS::LIGHT_DIRECTIONAL) { + + if (li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { + + material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection[1]); + material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,Vector3(li->shadow_split[0],li->shadow_split[1],li->shadow_split[2])); + } else if (li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + + + material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection[1]); + material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX3,li->shadow_projection[2]); + material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX4,li->shadow_projection[3]); + material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,Vector3(li->shadow_split[0],li->shadow_split[1],li->shadow_split[2])); - material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection2); - material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,li->shadow_split); + } //print_line("shadow split: "+rtos(li->shadow_split)); - } + } else material_shader.set_uniform(MaterialShaderGLES2::SHADOW_DARKENING,li->base->vars[VS::LIGHT_PARAM_SHADOW_DARKENING]); //matrix @@ -5126,6 +5174,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false); + material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false); material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false); } @@ -5179,6 +5228,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false); + material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false); material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,true); } else { material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL,(light_type&0x3)==VS::LIGHT_DIRECTIONAL); @@ -5186,6 +5236,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,(light_type&0x3)==VS::LIGHT_SPOT); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,(light_type&0x8)); material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,(light_type&0x10)); + material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,(light_type&0x20)); material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false); } @@ -6010,18 +6061,45 @@ void RasterizerGLES2::end_shadow_map() { case VS::LIGHT_DIRECTIONAL: { - if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT) { + if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + + cm = shadow->custom_projection[shadow_pass]; + light_transform=shadow->custom_transform[shadow_pass]; + + 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); + } 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); + + } 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); + } 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); + + } + + glEnable(GL_SCISSOR_TEST); + + } else if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { if (shadow_pass==0) { - cm = shadow->custom_projection; - light_transform=shadow->custom_transform; + 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); } else { - cm = shadow->custom_projection2; - light_transform=shadow->custom_transform2; + 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); @@ -6030,8 +6108,8 @@ void RasterizerGLES2::end_shadow_map() { glEnable(GL_SCISSOR_TEST); } else { - cm = shadow->custom_projection; - light_transform=shadow->custom_transform; + cm = shadow->custom_projection[0]; + light_transform=shadow->custom_transform[0]; glViewport(0, 0, sb->size, sb->size); } @@ -7993,9 +8071,11 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo p_default_fragment_lighting=false; fragment_lighting=GLOBAL_DEF("rasterizer/use_fragment_lighting",true); read_depth_supported=true; //todo check for extension - use_shadow_pcf=GLOBAL_DEF("rasterizer/use_shadow_pcf",true); + 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")); + use_shadow_mapping=true; - use_fast_texture_filter=GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true); + use_fast_texture_filter=!bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true)); skel_default.resize(1024*4); for(int i=0;i<1024/3;i++) { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index f18bdd1ff7..673297dd51 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -80,6 +80,8 @@ class RasterizerGLES2 : public Rasterizer { bool read_depth_supported; bool use_framebuffers; bool use_shadow_mapping; + ShadowFilterTechnique shadow_filter; + bool use_shadow_esm; bool use_shadow_pcf; bool use_hw_skeleton_xform; @@ -374,6 +376,7 @@ class RasterizerGLES2 : public Rasterizer { Vector<Surface*> surfaces; int morph_target_count; VS::MorphTargetMode morph_target_mode; + AABB custom_aabb; mutable uint64_t last_pass; Mesh() { @@ -659,11 +662,8 @@ class RasterizerGLES2 : public Rasterizer { Transform transform; CameraMatrix projection; - Transform custom_transform; - CameraMatrix custom_projection; - - Transform custom_transform2; - CameraMatrix custom_projection2; + Transform custom_transform[4]; + CameraMatrix custom_projection[4]; Vector3 light_vector; Vector3 spot_vector; @@ -675,11 +675,9 @@ class RasterizerGLES2 : public Rasterizer { Vector2 dp; - CameraMatrix shadow_projection; - CameraMatrix shadow_projection2; + CameraMatrix shadow_projection[4]; + float shadow_split[4]; - float shadow_split; - float shadow_split2; ShadowBuffer* near_shadow_buffer; @@ -1183,6 +1181,9 @@ public: virtual AABB mesh_get_aabb(RID p_mesh) const; + virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb); + virtual AABB mesh_get_custom_aabb(RID p_mesh) const; + /* MULTIMESH API */ virtual RID multimesh_create(); diff --git a/drivers/gles2/shaders/material.glsl b/drivers/gles2/shaders/material.glsl index 9c2fbaee6c..1794f18801 100644 --- a/drivers/gles2/shaders/material.glsl +++ b/drivers/gles2/shaders/material.glsl @@ -140,6 +140,12 @@ varying highp vec4 shadow_coord; uniform highp mat4 shadow_matrix2; varying highp vec4 shadow_coord2; #endif +#ifdef LIGHT_USE_PSSM4 +uniform highp mat4 shadow_matrix3; +varying highp vec4 shadow_coord3; +uniform highp mat4 shadow_matrix4; +varying highp vec4 shadow_coord4; +#endif #endif @@ -290,6 +296,22 @@ VERTEX_SHADER_CODE shadow_coord2.xyz/=shadow_coord2.w; shadow_coord2.y*=0.5; #endif +#ifdef LIGHT_USE_PSSM4 + shadow_coord.x*=0.5; + shadow_coord2.x*=0.5; + + shadow_coord3 = shadow_matrix3 * vec4(vertex_interp,1.0); + shadow_coord3.xyz/=shadow_coord3.w; + shadow_coord3.xy*=vec2(0.5); + shadow_coord3.xy+=vec2(0.5); + + shadow_coord4 = shadow_matrix4 * vec4(vertex_interp,1.0); + shadow_coord4.xyz/=shadow_coord4.w; + shadow_coord4.xy*=vec2(0.5); + shadow_coord4.x+=0.5; + +#endif + #endif #ifdef USE_FOG @@ -428,7 +450,7 @@ varying vec4 var2_interp; #endif #ifdef LIGHT_USE_PSSM -uniform float light_pssm_split; +uniform vec3 light_pssm_split; #endif varying vec3 vertex_interp; @@ -504,6 +526,11 @@ varying highp vec4 shadow_coord; #ifdef LIGHT_USE_PSSM varying highp vec4 shadow_coord2; #endif +#ifdef LIGHT_USE_PSSM4 +varying highp vec4 shadow_coord3; +varying highp vec4 shadow_coord4; +#endif + uniform highp sampler2D shadow_texture; uniform highp vec2 shadow_texel_size; @@ -523,6 +550,29 @@ uniform float shadow_darkening; #ifdef USE_SHADOW_PCF +#ifdef USE_SHADOW_PCF_HQ + + +float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) { + + float avg=(SHADOW_DEPTH(shadow_texture,coord) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,0.0)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,0.0)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,-shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,-shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x*2.0,0.0)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x*2.0,0.0)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y*2.0)) < refdepth ? 0.0 : 1.0); + avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y*2.0)) < refdepth ? 0.0 : 1.0); + return avg*(1.0/13.0); +} + +#else + float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) { float avg=(SHADOW_DEPTH(shadow_texture,coord) < refdepth ? 0.0 : 1.0); @@ -530,9 +580,13 @@ float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) { avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,0.0)) < refdepth ? 0.0 : 1.0); avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y)) < refdepth ? 0.0 : 1.0); - return avg*0.2; + return avg*0.2; } +#endif + + + /* 16x averaging @@ -697,7 +751,7 @@ FRAGMENT_SHADER_CODE #if 0 highp vec3 splane = vec3(0.0,0.0,0.0); - if (gl_FragCoord.w > light_pssm_split) { + if (gl_FragCoord.w > light_pssm_split.x) { splane = shadow_coord.xyz; splane.y+=1.0; @@ -711,19 +765,56 @@ FRAGMENT_SHADER_CODE /* float sa_a = SAMPLE_SHADOW_TEX(shadow_coord.xy,shadow_coord.z); float sa_b = SAMPLE_SHADOW_TEX(shadow_coord2.xy,shadow_coord2.z); - if (gl_FragCoord.w > light_pssm_split) { + if (gl_FragCoord.w > light_pssm_split.x) { shadow_attenuation=sa_a; } else { shadow_attenuation=sa_b; } */ - if (gl_FragCoord.w > light_pssm_split) { - shadow_attenuation=SAMPLE_SHADOW_TEX(shadow_coord.xy,shadow_coord.z); + vec2 pssm_coord; + float pssm_z; + +#ifdef LIGHT_USE_PSSM4 + + + if (gl_FragCoord.w > light_pssm_split.y) { + + if (gl_FragCoord.w > light_pssm_split.x) { + pssm_coord=shadow_coord.xy; + pssm_z=shadow_coord.z; + + } else { + pssm_coord=shadow_coord2.xy; + pssm_z=shadow_coord2.z; + } + } else { + + + if (gl_FragCoord.w > light_pssm_split.z) { + pssm_coord=shadow_coord3.xy; + pssm_z=shadow_coord3.z; + } else { + pssm_coord=shadow_coord4.xy; + pssm_z=shadow_coord4.z; + } + } + +#else + + if (gl_FragCoord.w > light_pssm_split.x) { + pssm_coord=shadow_coord.xy; + pssm_z=shadow_coord.z; + } else { - shadow_attenuation=SAMPLE_SHADOW_TEX(shadow_coord2.xy,shadow_coord2.z); + pssm_coord=shadow_coord2.xy; + pssm_z=shadow_coord2.z; } +#endif + + //one one sample + shadow_attenuation=SAMPLE_SHADOW_TEX(pssm_coord,pssm_z); #endif |