summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2014-05-04 22:50:23 -0300
committerJuan Linietsky <reduzio@gmail.com>2014-05-04 22:50:23 -0300
commit72ae89c5aa8da9110ec8f89e5558d5d04935f3b5 (patch)
tree453b2c8b8cc0edc588cee2dd3e440b30ff729ae2 /drivers
parent3c17e0c91548299b60a6d3998eadb303418512cc (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.cpp21
-rw-r--r--drivers/gles1/rasterizer_gles1.h4
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp132
-rw-r--r--drivers/gles2/rasterizer_gles2.h19
-rw-r--r--drivers/gles2/shaders/material.glsl105
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