summaryrefslogtreecommitdiff
path: root/drivers/gles2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gles2')
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp526
-rw-r--r--drivers/gles2/rasterizer_gles2.h86
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp7
-rw-r--r--drivers/gles2/shader_compiler_gles2.h1
-rw-r--r--drivers/gles2/shader_gles2.cpp8
-rw-r--r--drivers/gles2/shaders/canvas.glsl3
-rw-r--r--drivers/gles2/shaders/copy.glsl113
-rw-r--r--drivers/gles2/shaders/material.glsl125
8 files changed, 787 insertions, 82 deletions
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 58abb71a12..74a82e1a5c 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -952,7 +952,11 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) {
Texture *texture = texture_owner.get( p_texture );
ERR_FAIL_COND(!texture);
- ERR_FAIL_COND(texture->render_target);
+ if (texture->render_target) {
+
+ p_flags&=VS::TEXTURE_FLAG_FILTER;//can change only filter
+ }
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
@@ -2241,6 +2245,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 +2260,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() {
@@ -2464,6 +2489,156 @@ int RasterizerGLES2::multimesh_get_visible_instances(RID p_multimesh) const {
}
+/* IMMEDIATE API */
+
+
+RID RasterizerGLES2::immediate_create() {
+
+ Immediate *im = memnew( Immediate );
+ return immediate_owner.make_rid(im);
+
+}
+
+void RasterizerGLES2::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(im->building);
+
+ Immediate::Chunk ic;
+ ic.texture=p_texture;
+ ic.primitive=p_rimitive;
+ im->chunks.push_back(ic);
+ im->mask=0;
+ im->building=true;
+
+
+}
+void RasterizerGLES2::immediate_vertex(RID p_immediate,const Vector3& p_vertex){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ Immediate::Chunk *c = &im->chunks.back()->get();
+
+
+ if (c->vertices.empty() && im->chunks.size()==1) {
+
+ im->aabb.pos=p_vertex;
+ im->aabb.size=Vector3();
+ } else {
+ im->aabb.expand_to(p_vertex);
+ }
+
+ if (im->mask&VS::ARRAY_FORMAT_NORMAL)
+ c->normals.push_back(chunk_normal);
+ if (im->mask&VS::ARRAY_FORMAT_TANGENT)
+ c->tangents.push_back(chunk_tangent);
+ if (im->mask&VS::ARRAY_FORMAT_COLOR)
+ c->colors.push_back(chunk_color);
+ if (im->mask&VS::ARRAY_FORMAT_TEX_UV)
+ c->uvs.push_back(chunk_uv);
+ if (im->mask&VS::ARRAY_FORMAT_TEX_UV2)
+ c->uvs2.push_back(chunk_uv2);
+ im->mask|=VS::ARRAY_FORMAT_VERTEX;
+ c->vertices.push_back(p_vertex);
+
+}
+
+
+void RasterizerGLES2::immediate_normal(RID p_immediate,const Vector3& p_normal){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->mask|=VS::ARRAY_FORMAT_NORMAL;
+ chunk_normal=p_normal;
+
+}
+void RasterizerGLES2::immediate_tangent(RID p_immediate,const Plane& p_tangent){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->mask|=VS::ARRAY_FORMAT_TANGENT;
+ chunk_tangent=p_tangent;
+
+}
+void RasterizerGLES2::immediate_color(RID p_immediate,const Color& p_color){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->mask|=VS::ARRAY_FORMAT_COLOR;
+ chunk_color=p_color;
+
+}
+void RasterizerGLES2::immediate_uv(RID p_immediate,const Vector2& tex_uv){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->mask|=VS::ARRAY_FORMAT_TEX_UV;
+ chunk_uv=tex_uv;
+
+}
+void RasterizerGLES2::immediate_uv2(RID p_immediate,const Vector2& tex_uv){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->mask|=VS::ARRAY_FORMAT_TEX_UV2;
+ chunk_uv2=tex_uv;
+
+}
+
+void RasterizerGLES2::immediate_end(RID p_immediate){
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(!im->building);
+
+ im->building=false;
+
+}
+void RasterizerGLES2::immediate_clear(RID p_immediate) {
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ ERR_FAIL_COND(im->building);
+
+ im->chunks.clear();
+}
+
+AABB RasterizerGLES2::immediate_get_aabb(RID p_immediate) const {
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND_V(!im,AABB());
+ return im->aabb;
+}
+
+void RasterizerGLES2::immediate_set_material(RID p_immediate,RID p_material) {
+
+ Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!im);
+ im->material=p_material;
+
+}
+
+RID RasterizerGLES2::immediate_get_material(RID p_immediate) const {
+
+ const Immediate *im = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND_V(!im,RID());
+ return im->material;
+
+}
+
/* PARTICLES API */
@@ -3114,7 +3289,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 +3307,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 +3325,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 +3345,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 +3591,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 +3860,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 +3884,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;
@@ -3755,9 +3943,16 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
//print_line("UCF: "+itos(p_shader->uniforms.size()));
+ int first_tex_index=0xFFFFF;
+ p_shader->first_texture=StringName();
+
for(Map<StringName,ShaderLanguage::Uniform>::Element *E=p_shader->uniforms.front();E;E=E->next()) {
uniform_names.push_back("_"+String(E->key()));
+ if (E->get().type==ShaderLanguage::TYPE_TEXTURE && E->get().order<first_tex_index) {
+ p_shader->first_texture=E->key();
+ first_tex_index=E->get().order;
+ }
}
if (p_shader->mode==VS::SHADER_MATERIAL) {
@@ -3781,6 +3976,9 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
if (flags.uses_screen_uv) {
enablers.push_back("#define ENABLE_SCREEN_UV\n");
}
+ if (flags.uses_discard) {
+ enablers.push_back("#define ENABLE_DISCARD\n");
+ }
material_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names,enablers);
} else {
@@ -3789,6 +3987,8 @@ void RasterizerGLES2::_update_shader( Shader* p_shader) const {
p_shader->valid=true;
p_shader->has_alpha=flags.uses_alpha || flags.uses_texscreen;
+ p_shader->writes_vertex=flags.vertex_code_writes_vertex;
+ p_shader->uses_discard=flags.uses_discard;
p_shader->has_texscreen=flags.uses_texscreen;
p_shader->has_screen_uv=flags.uses_screen_uv;
p_shader->can_zpass=!flags.uses_discard && !flags.vertex_code_writes_vertex;
@@ -3849,16 +4049,19 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
RenderList *render_list=NULL;
- bool has_alpha = m->blend_mode!=VS::MATERIAL_BLEND_MODE_MIX || (m->shader_cache && m->shader_cache->has_alpha) || m->flags[VS::MATERIAL_FLAG_ONTOP];
+ bool has_base_alpha=(m->shader_cache && m->shader_cache->has_alpha);
+ bool has_blend_alpha=m->blend_mode!=VS::MATERIAL_BLEND_MODE_MIX || m->flags[VS::MATERIAL_FLAG_ONTOP];
+ bool has_alpha = has_base_alpha || has_blend_alpha;
if (shadow) {
- if (has_alpha)
+ if (has_blend_alpha || (has_base_alpha && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]))
return; //bye
- if (true) {
- m = shadow_mat_ptr; //for now do this always
+ if (m->shader_cache && !m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && !m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) {
+ //shader does not use discard and does not write a vertex position, use generic material
+ m = shadow_mat_ptr;
if (m->last_pass!=frame) {
if (m->shader.is_valid()) {
@@ -3901,6 +4104,9 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
RenderList::Element *e = render_list->add_element();
+ if (!e)
+ return;
+
e->geometry=p_geometry;
e->geometry_cmp=p_geometry_cmp;
e->material=m;
@@ -3936,6 +4142,18 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
e->light_type=0xFF; // no lights!
e->light=0xFFFF;
+ if (!shadow && !has_blend_alpha && has_alpha && m->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS]) {
+
+ //if nothing exists, add this element as opaque too
+ RenderList::Element *oe = opaque_render_list.add_element();
+
+ if (!oe)
+ return;
+
+ memcpy(oe,e,sizeof(RenderList::Element));
+ oe->additive_ptr=&oe->additive;
+ }
+
if (shadow || m->flags[VS::MATERIAL_FLAG_UNSHADED]) {
e->light_type=0x7F; //unshaded is zero
@@ -3954,8 +4172,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;
}
@@ -4058,6 +4278,17 @@ void RasterizerGLES2::add_multimesh( const RID& p_multimesh, const InstanceData
}
+void RasterizerGLES2::add_immediate( const RID& p_immediate, const InstanceData *p_data) {
+
+
+ Immediate *immediate = immediate_owner.get(p_immediate);
+ ERR_FAIL_COND(!immediate);
+
+ _add_geometry(immediate,p_data,immediate,NULL);
+
+}
+
+
void RasterizerGLES2::add_particles( const RID& p_particle_instance, const InstanceData *p_data){
//print_line("adding particles");
@@ -4129,7 +4360,7 @@ _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_
}
-bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material *p_material,bool p_no_const_light) {
+bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material *p_material,bool p_no_const_light,bool p_opaque_pass) {
if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED]) {
glDisable(GL_CULL_FACE);
@@ -4152,14 +4383,23 @@ 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);
+ if (p_opaque_pass && p_material->hints[VS::MATERIAL_HINT_OPAQUE_PRE_PASS] && p_material->shader_cache && p_material->shader_cache->has_alpha) {
+
+ material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA,true);
+ } else {
+ material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA,false);
+
+ }
+
if (!shadow) {
bool depth_test=!p_material->flags[VS::MATERIAL_FLAG_ONTOP];
- bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW];
+ bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW] && (p_opaque_pass || !p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]);
if (current_depth_mask!=depth_write) {
current_depth_mask=depth_write;
@@ -4235,6 +4475,10 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
if (t) {
if (t->render_target)
t->render_target->last_pass=frame;
+ if (E->key()==p_material->shader_cache->first_texture) {
+ tc0_idx=texcoord;
+ tc0_id_cache=t->tex_id;
+ }
glBindTexture(t->target,t->tex_id);
} else
glBindTexture(GL_TEXTURE_2D,white_tex); //no texture
@@ -4379,16 +4623,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_projection2);
- material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,li->shadow_split);
+ 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]));
+
+ }
//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
@@ -4967,6 +5222,109 @@ void RasterizerGLES2::_render(const Geometry *p_geometry,const Material *p_mater
};
}
} break;
+ case Geometry::GEOMETRY_IMMEDIATE: {
+
+ bool restore_tex=false;
+ const Immediate *im = static_cast<const Immediate*>( p_geometry );
+ if (im->building) {
+ return;
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ for(const List<Immediate::Chunk>::Element *E=im->chunks.front();E;E=E->next()) {
+
+ const Immediate::Chunk &c=E->get();
+ if (c.vertices.empty()) {
+ continue;
+ }
+ for(int i=0;i<c.vertices.size();i++)
+
+ if (c.texture.is_valid() && texture_owner.owns(c.texture)) {
+
+ const Texture *t = texture_owner.get(c.texture);
+ glActiveTexture(GL_TEXTURE0+tc0_idx);
+ glBindTexture(t->target,t->tex_id);
+ restore_tex=true;
+
+
+ } else if (restore_tex) {
+
+ glActiveTexture(GL_TEXTURE0+tc0_idx);
+ glBindTexture(GL_TEXTURE_2D,tc0_id_cache);
+ restore_tex=false;
+ }
+
+ if (!c.normals.empty()) {
+
+ glEnableVertexAttribArray(VS::ARRAY_NORMAL);
+ glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false,sizeof(Vector3),c.normals.ptr());
+
+ } else {
+
+ glDisableVertexAttribArray(VS::ARRAY_NORMAL);
+ }
+
+ if (!c.tangents.empty()) {
+
+ glEnableVertexAttribArray(VS::ARRAY_TANGENT);
+ glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false,sizeof(Plane),c.tangents.ptr());
+
+ } else {
+
+ glDisableVertexAttribArray(VS::ARRAY_TANGENT);
+ }
+
+ if (!c.colors.empty()) {
+
+ glEnableVertexAttribArray(VS::ARRAY_COLOR);
+ glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false,sizeof(Color),c.colors.ptr());
+
+ } else {
+
+ glDisableVertexAttribArray(VS::ARRAY_COLOR);
+ _set_color_attrib(Color(1, 1, 1,1));
+ }
+
+
+ if (!c.uvs.empty()) {
+
+ glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
+ glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false,sizeof(Vector2),c.uvs.ptr());
+
+ } else {
+
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
+ }
+
+ if (!c.uvs2.empty()) {
+
+ glEnableVertexAttribArray(VS::ARRAY_TEX_UV2);
+ glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false,sizeof(Vector2),c.uvs2.ptr());
+
+ } else {
+
+ glDisableVertexAttribArray(VS::ARRAY_TEX_UV2);
+ }
+
+
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false,sizeof(Vector3),c.vertices.ptr());
+ glDrawArrays(gl_primitive[c.primitive],0,c.vertices.size());
+
+
+ }
+
+
+ if (restore_tex) {
+
+ glActiveTexture(GL_TEXTURE0+tc0_idx);
+ glBindTexture(GL_TEXTURE_2D,tc0_id_cache);
+ restore_tex=false;
+ }
+
+
+ } break;
case Geometry::GEOMETRY_PARTICLES: {
@@ -5126,11 +5484,13 @@ 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);
}
+ bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass;
bool prev_blend=false;
glDisable(GL_BLEND);
@@ -5151,7 +5511,6 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (!shadow) {
if (texscreen_used && !texscreen_copied && material->shader_cache && material->shader_cache->valid && material->shader_cache->has_texscreen) {
-
texscreen_copied=true;
_copy_to_texscreen();
@@ -5179,6 +5538,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 +5546,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);
}
@@ -5196,11 +5557,15 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (!*e->additive_ptr) {
additive=false;
- *e->additive_ptr=true;
+ *e->additive_ptr=true;
} else {
additive=true;
}
+ if (stores_glow)
+ material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,!additive);
+
+
bool desired_blend=false;
VS::MaterialBlendMode desired_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
@@ -5216,8 +5581,10 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (desired_blend) {
glEnable(GL_BLEND);
+ glColorMask(1,1,1,0);
} else {
glDisable(GL_BLEND);
+ glColorMask(1,1,1,1);
}
prev_blend=desired_blend;
@@ -5278,7 +5645,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
if (material!=prev_material || rebind) {
- rebind = _setup_material(e->geometry,material,additive);
+ rebind = _setup_material(e->geometry,material,additive,!p_alpha_pass);
DEBUG_TEST_ERROR("Setup material");
_rinfo.mat_change_count++;
@@ -5471,9 +5838,12 @@ void RasterizerGLES2::_process_glow_bloom() {
_copy_screen_quad();
copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_COPY,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false);
int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES];
Vector2 psize(1.0/framebuffer.blur_size,1.0/framebuffer.blur_size);
+ float pscale = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_SCALE];
+ float pmag = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH];
+
for(int i=0;i<passes;i++) {
@@ -5496,6 +5866,8 @@ void RasterizerGLES2::_process_glow_bloom() {
copy_shader.set_conditional(CopyShaderGLES2::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,pmag);
_draw_gui_primitive(4,dst_pos,NULL,src_uv);
@@ -5506,6 +5878,8 @@ void RasterizerGLES2::_process_glow_bloom() {
copy_shader.set_conditional(CopyShaderGLES2::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,pmag);
_draw_gui_primitive(4,dst_pos,NULL,src_uv);
@@ -5634,6 +6008,8 @@ void RasterizerGLES2::_draw_tex_bg() {
copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE,false);
}
+ copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA,true);
+
copy_shader.bind();
if (current_env->bg_mode==VS::ENV_BG_TEXTURE || current_env->bg_mode==VS::ENV_BG_TEXTURE_RGBE) {
@@ -5646,6 +6022,7 @@ void RasterizerGLES2::_draw_tex_bg() {
if (current_env->fx_enabled[VS::ENV_FX_HDR])
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]));
Vector3 vertices[4]={
Vector3(-1,-1,1),
@@ -5715,6 +6092,7 @@ void RasterizerGLES2::_draw_tex_bg() {
copy_shader.set_conditional(CopyShaderGLES2::USE_ENERGY,false);
copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE,false);
copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP,false);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA,false);
}
void RasterizerGLES2::end_scene() {
@@ -5795,7 +6173,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");
- float a = use_fb ? 0.0 : 1.0;
+ 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);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
@@ -5843,7 +6221,7 @@ void RasterizerGLES2::end_scene() {
glDisable(GL_BLEND);
current_blend_mode=VS::MATERIAL_BLEND_MODE_MIX;
- material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
+ //material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
opaque_render_list.sort_mat_light_type_flags();
_render_list_forward(&opaque_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting);
@@ -5864,7 +6242,7 @@ void RasterizerGLES2::end_scene() {
}
alpha_render_list.sort_z();
- _render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,false,true);
+ _render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
glColorMask(1,1,1,1);
// material_shader.set_conditional( MaterialShaderGLES2::USE_FOG,false);
@@ -5894,17 +6272,25 @@ void RasterizerGLES2::end_scene() {
_process_hdr();
}
if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
- _process_glow_bloom();
+ _process_glow_bloom();
+ int glow_transfer_mode=current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE];
+ if (glow_transfer_mode==1)
+ copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,true);
+ if (glow_transfer_mode==2)
+ copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,true);
}
glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer);
+ Size2 size;
if (current_rt) {
glBindFramebuffer(GL_FRAMEBUFFER, current_rt->fbo);
glViewport( 0,0,viewport.width,viewport.height);
+ size=Size2(viewport.width,viewport.height);
} else {
glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height );
+ size=Size2(viewport.width,viewport.height);
}
//time to copy!!!
@@ -5913,6 +6299,7 @@ void RasterizerGLES2::end_scene() {
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);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]);
copy_shader.bind();
//copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0);
@@ -5934,6 +6321,9 @@ void RasterizerGLES2::end_scene() {
}
+ if (current_env && current_env->fx_enabled[VS::ENV_FX_FXAA])
+ copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Size2(1.0/size.x,1.0/size.y));
+
if (current_env && current_env->fx_enabled[VS::ENV_FX_BCS]) {
@@ -5957,6 +6347,9 @@ void RasterizerGLES2::end_scene() {
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);
+ copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false);
+ 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);
@@ -6010,18 +6403,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) {
- cm = shadow->custom_projection;
- light_transform=shadow->custom_transform;
+ 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[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 +6450,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);
}
@@ -6122,8 +6542,8 @@ void RasterizerGLES2::end_shadow_map() {
//glDisable(GL_POLYGON_OFFSET_FILL);
- if (!use_rgba_shadowmaps)
- glColorMask(1, 1, 1, 1);
+ //if (!use_rgba_shadowmaps)
+ glColorMask(1, 1, 1, 1);
DEBUG_TEST_ERROR("Drawing Shadow");
shadow=NULL;
@@ -6342,7 +6762,10 @@ void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) {
case VS::MATERIAL_BLEND_MODE_MUL: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-
+ } break;
+ case VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA: {
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
} break;
}
@@ -6853,6 +7276,10 @@ bool RasterizerGLES2::is_mesh(const RID& p_rid) const {
return mesh_owner.owns(p_rid);
}
+bool RasterizerGLES2::is_immediate(const RID& p_rid) const {
+
+ return immediate_owner.owns(p_rid);
+}
bool RasterizerGLES2::is_multimesh(const RID& p_rid) const {
return multimesh_owner.owns(p_rid);
@@ -6977,6 +7404,13 @@ void RasterizerGLES2::free(const RID& p_rid) {
multimesh_owner.free(p_rid);
memdelete(multimesh);
+ } else if (immediate_owner.owns(p_rid)) {
+
+ Immediate *immediate = immediate_owner.get(p_rid);
+ ERR_FAIL_COND(!immediate);
+
+ immediate_owner.free(p_rid);
+ memdelete(immediate);
} else if (particles_owner.owns(p_rid)) {
Particles *particles = particles_owner.get(p_rid);
@@ -7993,9 +8427,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++) {
@@ -8022,6 +8458,8 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
draw_next_frame=false;
use_framebuffers=true;
framebuffer.active=false;
+ tc0_id_cache=0;
+ tc0_idx=0;
};
RasterizerGLES2::~RasterizerGLES2() {
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index f18bdd1ff7..0fee8bf918 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;
@@ -171,8 +173,11 @@ class RasterizerGLES2 : public Rasterizer {
bool can_zpass;
bool has_texscreen;
bool has_screen_uv;
+ bool writes_vertex;
+ bool uses_discard;
Map<StringName,ShaderLanguage::Uniform> uniforms;
+ StringName first_texture;
SelfList<Shader> dirty_list;
@@ -188,6 +193,8 @@ class RasterizerGLES2 : public Rasterizer {
can_zpass=true;
has_texscreen=false;
has_screen_uv=false;
+ writes_vertex=false;
+ uses_discard=false;
}
@@ -233,6 +240,7 @@ class RasterizerGLES2 : public Rasterizer {
flags[VS::MATERIAL_FLAG_VISIBLE]=true;
for(int i=0;i<VS::MATERIAL_HINT_MAX;i++)
hints[i]=false;
+ hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]=true;
line_width=1;
has_alpha=false;
@@ -254,7 +262,7 @@ class RasterizerGLES2 : public Rasterizer {
enum Type {
GEOMETRY_INVALID,
GEOMETRY_SURFACE,
- GEOMETRY_POLY,
+ GEOMETRY_IMMEDIATE,
GEOMETRY_PARTICLES,
GEOMETRY_MULTISURFACE,
};
@@ -374,6 +382,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() {
@@ -454,6 +463,31 @@ class RasterizerGLES2 : public Rasterizer {
mutable RID_Owner<MultiMesh> multimesh_owner;
mutable SelfList<MultiMesh>::List _multimesh_dirty_list;
+ struct Immediate : public Geometry {
+
+ struct Chunk {
+
+ RID texture;
+ VS::PrimitiveType primitive;
+ Vector<Vector3> vertices;
+ Vector<Vector3> normals;
+ Vector<Plane> tangents;
+ Vector<Color> colors;
+ Vector<Vector2> uvs;
+ Vector<Vector2> uvs2;
+ };
+
+ List<Chunk> chunks;
+ bool building;
+ int mask;
+ AABB aabb;
+
+ Immediate() { type=GEOMETRY_IMMEDIATE; building=false;}
+
+ };
+
+ mutable RID_Owner<Immediate> immediate_owner;
+
struct Particles : public Geometry {
ParticleSystemSW data; // software particle system
@@ -582,11 +616,15 @@ class RasterizerGLES2 : public Rasterizer {
bg_param[VS::ENV_BG_PARAM_CUBEMAP]=RID();
bg_param[VS::ENV_BG_PARAM_ENERGY]=1.0;
bg_param[VS::ENV_BG_PARAM_SCALE]=1.0;
+ bg_param[VS::ENV_BG_PARAM_GLOW]=0.0;
for(int i=0;i<VS::ENV_FX_MAX;i++)
fx_enabled[i]=false;
fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]=1;
+ fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_SCALE]=1.0;
+ fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH]=1.0;
+ fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE]=0;
fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM]=0.0;
fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD]=0.5;
fx_param[VS::ENV_FX_PARAM_DOF_BLUR_PASSES]=1;
@@ -659,11 +697,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 +710,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;
@@ -934,7 +967,7 @@ class RasterizerGLES2 : public Rasterizer {
void _setup_light(uint16_t p_light);
_FORCE_INLINE_ void _setup_shader_params(const Material *p_material);
- bool _setup_material(const Geometry *p_geometry,const Material *p_material,bool p_no_const_light);
+ bool _setup_material(const Geometry *p_geometry, const Material *p_material, bool p_no_const_light, bool p_opaque_pass);
void _setup_skeleton(const Skeleton *p_skeleton);
@@ -1098,6 +1131,16 @@ class RasterizerGLES2 : public Rasterizer {
void _copy_screen_quad();
void _copy_to_texscreen();
+
+ Vector3 chunk_vertex;
+ Vector3 chunk_normal;
+ Plane chunk_tangent;
+ Color chunk_color;
+ Vector2 chunk_uv;
+ Vector2 chunk_uv2;
+ GLuint tc0_id_cache;
+ GLuint tc0_idx;
+
public:
/* TEXTURE API */
@@ -1183,6 +1226,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();
@@ -1204,6 +1250,22 @@ public:
virtual void multimesh_set_visible_instances(RID p_multimesh,int p_visible);
virtual int multimesh_get_visible_instances(RID p_multimesh) const;
+ /* IMMEDIATE API */
+
+ virtual RID immediate_create();
+ virtual void immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture=RID());
+ virtual void immediate_vertex(RID p_immediate,const Vector3& p_vertex);
+ virtual void immediate_normal(RID p_immediate,const Vector3& p_normal);
+ virtual void immediate_tangent(RID p_immediate,const Plane& p_tangent);
+ virtual void immediate_color(RID p_immediate,const Color& p_color);
+ virtual void immediate_uv(RID p_immediate,const Vector2& tex_uv);
+ virtual void immediate_uv2(RID p_immediate,const Vector2& tex_uv);
+ virtual void immediate_end(RID p_immediate);
+ virtual void immediate_clear(RID p_immediate);
+ virtual AABB immediate_get_aabb(RID p_immediate) const;
+ virtual void immediate_set_material(RID p_immediate,RID p_material);
+ virtual RID immediate_get_material(RID p_immediate) const;
+
/* PARTICLES API */
virtual RID particles_create();
@@ -1363,6 +1425,7 @@ public:
virtual void add_mesh( const RID& p_mesh, const InstanceData *p_data);
virtual void add_multimesh( const RID& p_multimesh, const InstanceData *p_data);
+ virtual void add_immediate( const RID& p_immediate, const InstanceData *p_data);
virtual void add_particles( const RID& p_particle_instance, const InstanceData *p_data);
virtual void end_scene();
@@ -1410,6 +1473,7 @@ public:
virtual bool is_texture(const RID& p_rid) const;
virtual bool is_material(const RID& p_rid) const;
virtual bool is_mesh(const RID& p_rid) const;
+ virtual bool is_immediate(const RID& p_rid) const;
virtual bool is_multimesh(const RID& p_rid) const;
virtual bool is_particles(const RID &p_beam) const;
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 6dc6259fef..db63c3aeba 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -145,6 +145,12 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
} break;
case SL::Node::TYPE_VARIABLE: {
SL::VariableNode *vnode=(SL::VariableNode*)p_node;
+ if (type==ShaderLanguage::SHADER_MATERIAL_VERTEX) {
+
+ if (vnode->name==vname_vertex && p_assign_left) {
+ vertex_code_writes_vertex=true;
+ }
+ }
if (type==ShaderLanguage::SHADER_MATERIAL_FRAGMENT) {
if (vnode->name==vname_discard) {
@@ -644,5 +650,6 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
vname_binormal_interp="BINORMAL";
vname_var1_interp="VAR1";
vname_var2_interp="VAR2";
+ vname_vertex="VERTEX";
}
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index 2f4aa7647e..d683f5b4f3 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -61,6 +61,7 @@ private:
StringName vname_binormal_interp;
StringName vname_var1_interp;
StringName vname_var2_interp;
+ StringName vname_vertex;
Map<StringName,ShaderLanguage::Uniform> *uniforms;
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index d665fddd2c..bcd3e6ad4b 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -315,6 +315,7 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() {
for(int i=0;i<cc->custom_defines.size();i++) {
strings.push_back(cc->custom_defines[i]);
+ DEBUG_PRINT("CD #"+itos(i)+": "+String(cc->custom_defines[i]));
}
}
@@ -349,9 +350,11 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() {
strings.push_back(vertex_code2.get_data());
#ifdef DEBUG_SHADER
+
+ DEBUG_PRINT("\nVertex Code:\n\n"+String(code_string.get_data()));
for(int i=0;i<strings.size();i++) {
- print_line("vert strings "+itos(i)+":"+String(strings[i]));
+ //print_line("vert strings "+itos(i)+":"+String(strings[i]));
}
#endif
@@ -435,9 +438,10 @@ ShaderGLES2::Version* ShaderGLES2::get_current_version() {
strings.push_back(fragment_code2.get_data());
#ifdef DEBUG_SHADER
+ DEBUG_PRINT("\nFragment Code:\n\n"+String(code_string.get_data()));
for(int i=0;i<strings.size();i++) {
- print_line("frag strings "+itos(i)+":"+String(strings[i]));
+ //print_line("frag strings "+itos(i)+":"+String(strings[i]));
}
#endif
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 66bdf15db4..f36741d586 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -64,6 +64,9 @@ void main() {
highp float enc32 = dot( color,highp vec4(1.0 / (256.0 * 256.0 * 256.0),1.0 / (256.0 * 256.0),1.0 / 256.0,1) );
color = vec4(vec3(enc32),1.0);
#endif
+
+// color.rgb*=color.a;
gl_FragColor = color;
+
}
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index d4b0c31b7d..2f1b349618 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -99,6 +99,8 @@ uniform float bloom_treshold;
#if defined(BLUR_V_PASS) || defined(BLUR_H_PASS) || defined(USE_HDR_REDUCE)
uniform vec2 pixel_size;
+uniform float pixel_scale;
+uniform float blur_magnitude;
#ifdef USE_HDR_STORE
@@ -110,6 +112,11 @@ uniform sampler2D source_vd_lum;
#endif
+//endif
+#elif defined(USE_FXAA)
+
+uniform vec2 pixel_size;
+
#endif
#ifdef USE_ENERGY
@@ -118,6 +125,10 @@ uniform highp float energy;
#endif
+#ifdef USE_CUSTOM_ALPHA
+uniform float custom_alpha;
+#endif
+
void main() {
@@ -129,6 +140,55 @@ void main() {
vec4 color = texture2D( source, uv_interp );
#endif
+
+#ifdef USE_FXAA
+
+#define FXAA_REDUCE_MIN (1.0/ 128.0)
+#define FXAA_REDUCE_MUL (1.0 / 8.0)
+#define FXAA_SPAN_MAX 8.0
+
+ {
+ vec3 rgbNW = texture2D(source, uv_interp + vec2(-1.0, -1.0) * pixel_size).xyz;
+ vec3 rgbNE = texture2D(source, uv_interp + vec2(1.0, -1.0) * pixel_size).xyz;
+ vec3 rgbSW = texture2D(source, uv_interp + vec2(-1.0, 1.0) * pixel_size).xyz;
+ vec3 rgbSE = texture2D(source, uv_interp + vec2(1.0, 1.0) * pixel_size).xyz;
+ vec3 rgbM = color.rgb;
+ vec3 luma = vec3(0.299, 0.587, 0.114);
+ float lumaNW = dot(rgbNW, luma);
+ float lumaNE = dot(rgbNE, luma);
+ float lumaSW = dot(rgbSW, luma);
+ float lumaSE = dot(rgbSE, luma);
+ float lumaM = dot(rgbM, luma);
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+ vec2 dir;
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
+ (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
+
+ float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+ dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
+ max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
+ dir * rcpDirMin)) * pixel_size;
+
+ vec3 rgbA = 0.5 * (
+ texture2D(source, uv_interp + dir * (1.0 / 3.0 - 0.5)).xyz +
+ texture2D(source, uv_interp + dir * (2.0 / 3.0 - 0.5)).xyz);
+ vec3 rgbB = rgbA * 0.5 + 0.25 * (
+ texture2D(source, uv_interp + dir * -0.5).xyz +
+ texture2D(source, uv_interp + dir * 0.5).xyz);
+
+ float lumaB = dot(rgbB, luma);
+ if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ color.rgb = rgbA;
+ else
+ color.rgb = rgbB;
+ }
+
+#endif
//color.rg=uv_interp;
#ifdef USE_BCS
@@ -141,28 +201,28 @@ void main() {
#ifdef BLUR_V_PASS
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-3.0));
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-2.0));
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-1.0));
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*1.0));
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*2.0));
- color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*3.0));
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-3.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-2.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*-1.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*1.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*2.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(0.0,pixel_size.y*3.0)*pixel_scale);
- color*=(1.0/7.0);
+ color*=(1.0/7.0)*blur_magnitude;
#endif
#ifdef BLUR_H_PASS
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*-3.0,0.0));
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*-2.0,0.0));
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*-1.0,0.0));
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*1.0,0.0));
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*2.0,0.0));
- color+=texture2D(source,uv_interp+vec2(pixel_size.x*3.0,0.0));
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*-3.0,0.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*-2.0,0.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*-1.0,0.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*1.0,0.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*2.0,0.0)*pixel_scale);
+ color+=texture2D(source,uv_interp+vec2(pixel_size.x*3.0,0.0)*pixel_scale);
- color*=(1.0/7.0);
+ color*=(1.0/7.0)*blur_magnitude;
#endif
@@ -195,7 +255,29 @@ void main() {
vec4 glow = texture2D( glow_source, uv2_interp );
+#ifdef USE_GLOW_SCREEN
+
+ color.rgb = clamp((color.rgb + glow.rgb) - (color.rgb * glow.rgb), 0.0, 1.0);
+
+#endif
+
+#ifdef USE_GLOW_SOFTLIGHT
+
+ {
+
+ glow.rgb = (glow.rgb * 0.5) + 0.5;
+ color.r = (glow.r <= 0.5) ? (color.r - (1.0 - 2.0 * glow.r) * color.r * (1.0 - color.r)) : (((glow.r > 0.5) && (color.r <= 0.25)) ? (color.r + (2.0 * glow.r - 1.0) * (4.0 * color.r * (4.0 * color.r + 1.0) * (color.r - 1.0) + 7.0 * color.r)) : (color.r + (2.0 * glow.r - 1.0) * (sqrt(color.r) - color.r)));
+ color.g = (glow.g <= 0.5) ? (color.g - (1.0 - 2.0 * glow.g) * color.g * (1.0 - color.g)) : (((glow.g > 0.5) && (color.g <= 0.25)) ? (color.g + (2.0 * glow.g - 1.0) * (4.0 * color.g * (4.0 * color.g + 1.0) * (color.g - 1.0) + 7.0 * color.g)) : (color.g + (2.0 * glow.g - 1.0) * (sqrt(color.g) - color.g)));
+ color.b = (glow.b <= 0.5) ? (color.b - (1.0 - 2.0 * glow.b) * color.b * (1.0 - color.b)) : (((glow.b > 0.5) && (color.b <= 0.25)) ? (color.b + (2.0 * glow.b - 1.0) * (4.0 * color.b * (4.0 * color.b + 1.0) * (color.b - 1.0) + 7.0 * color.b)) : (color.b + (2.0 * glow.b - 1.0) * (sqrt(color.b) - color.b)));
+ }
+
+#endif
+
+#if !defined(USE_GLOW_SCREEN) && !defined(USE_GLOW_SOFTLIGHT)
color.rgb+=glow.rgb;
+#endif
+
+
#endif
@@ -253,6 +335,9 @@ void main() {
color.a=1.0;
#endif
+#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 9c2fbaee6c..a919e3b1e2 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
@@ -364,6 +386,7 @@ VERTEX_SHADER_CODE
specular_interp=vec3(0.0);
}
}
+
#else
#ifdef SHADELESS
@@ -428,7 +451,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 +527,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 +551,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 +581,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
@@ -668,21 +723,28 @@ void main() {
-#ifdef FRAGMENT_SHADER_CODE_USE_DISCARD
- float discard_=0.0;
+#if defined(ENABLE_DISCARD)
+ bool discard_=false;
#endif
FRAGMENT_SHADER_CODE
-#ifdef FRAGMENT_SHADER_CODE_USE_DISCARD
- if (discard_>0.0) {
+#if defined(ENABLE_DISCARD)
+ if (discard_) {
//easy to eliminate dead code
discard;
}
#endif
+#ifdef ENABLE_CLIP_ALPHA
+ if (diffuse.a<0.99) {
+ //used for doublepass and shadowmapping
+ discard;
+ }
+#endif
+
float shadow_attenuation = 1.0;
@@ -697,7 +759,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 +773,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
@@ -811,7 +910,10 @@ FRAGMENT_SHADER_CODE
# if !defined(LIGHT_TYPE_DIRECTIONAL) && !defined(LIGHT_TYPE_OMNI) && !defined (LIGHT_TYPE_SPOT)
//none
+#ifndef SHADELESS
diffuse.rgb=vec3(0.0,0.0,0.0);
+#endif
+
# endif
diffuse.rgb+=const_light_mult*emission;
@@ -868,6 +970,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_HDR
diffuse.rgb*=0.25;
#endif
+
gl_FragColor = diffuse;
#endif
}