Done with lights and shadows (wonder if i'm missing something..)
This commit is contained in:
parent
cacf9ebb7f
commit
a7078a4be9
|
@ -125,6 +125,7 @@ void RasterizerGLES3::begin_frame(){
|
|||
|
||||
storage->update_dirty_shaders();
|
||||
storage->update_dirty_materials();
|
||||
scene->iteration();
|
||||
|
||||
}
|
||||
|
||||
|
@ -258,7 +259,6 @@ void RasterizerGLES3::register_config() {
|
|||
GLOBAL_DEF("rendering/gles3/use_nearest_mipmap_filter",false);
|
||||
GLOBAL_DEF("rendering/gles3/anisotropic_filter_level",4.0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
RasterizerGLES3::RasterizerGLES3()
|
||||
|
|
|
@ -131,8 +131,10 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas,int p_size){
|
|||
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
|
||||
|
||||
//interpola nearest (though nvidia can improve this)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
// Remove artifact on the edges of the shadowmap
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
@ -559,11 +561,6 @@ RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
|
|||
light_instance->light=p_light;
|
||||
light_instance->light_ptr=storage->light_owner.getornull(p_light);
|
||||
|
||||
glGenBuffers(1, &light_instance->light_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, light_instance->light_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightInstance::LightDataUBO), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
ERR_FAIL_COND_V(!light_instance->light_ptr,RID());
|
||||
|
||||
light_instance->self=light_instance_owner.make_rid(light_instance);
|
||||
|
@ -818,9 +815,50 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
|
|||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_setup_light(LightInstance *p_light) {
|
||||
void RasterizerSceneGLES3::_setup_light(RenderList::Element *e) {
|
||||
|
||||
int omni_indices[16];
|
||||
int omni_count=0;
|
||||
int spot_indices[16];
|
||||
int spot_count=0;
|
||||
|
||||
int maxobj = MIN(16,state.max_forward_lights_per_object);
|
||||
|
||||
int lc = e->instance->light_instances.size();
|
||||
if (lc) {
|
||||
|
||||
const RID* lights=e->instance->light_instances.ptr();
|
||||
|
||||
for(int i=0;i<lc;i++) {
|
||||
LightInstance *li=light_instance_owner.getptr(lights[i]);
|
||||
if (li->last_pass!=render_pass) //not visible
|
||||
continue;
|
||||
|
||||
if (li->light_ptr->type==VS::LIGHT_OMNI) {
|
||||
if (omni_count<maxobj && e->instance->layer_mask&li->light_ptr->cull_mask) {
|
||||
omni_indices[omni_count++]=li->light_index;
|
||||
}
|
||||
}
|
||||
|
||||
if (li->light_ptr->type==VS::LIGHT_SPOT) {
|
||||
if (spot_count<maxobj && e->instance->layer_mask&li->light_ptr->cull_mask) {
|
||||
spot_indices[spot_count++]=li->light_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::OMNI_LIGHT_COUNT,omni_count);
|
||||
|
||||
if (omni_count) {
|
||||
glUniform1iv(state.scene_shader.get_uniform(SceneShaderGLES3::OMNI_LIGHT_INDICES),omni_count,omni_indices);
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::SPOT_LIGHT_COUNT,spot_count);
|
||||
if (spot_count) {
|
||||
glUniform1iv(state.scene_shader.get_uniform(SceneShaderGLES3::SPOT_LIGHT_INDICES),spot_count,spot_indices);
|
||||
}
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,3,p_light->light_ubo); //bind light uniform
|
||||
}
|
||||
|
||||
|
||||
|
@ -894,7 +932,7 @@ void RasterizerSceneGLES3::_set_cull(bool p_front,bool p_reverse_cull) {
|
|||
|
||||
|
||||
|
||||
void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_element_count,const Transform& p_view_transform,const CameraMatrix& p_projection,RasterizerStorageGLES3::Texture* p_base_env,bool p_reverse_cull,bool p_alpha_pass,bool p_shadow) {
|
||||
void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_element_count,const Transform& p_view_transform,const CameraMatrix& p_projection,RasterizerStorageGLES3::Texture* p_base_env,bool p_reverse_cull,bool p_alpha_pass,bool p_shadow,bool p_directional_add) {
|
||||
|
||||
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
|
||||
//p_reverse_cull=!p_reverse_cull;
|
||||
|
@ -906,7 +944,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
glBindBufferBase(GL_UNIFORM_BUFFER,0,state.scene_ubo); //bind globals ubo
|
||||
|
||||
|
||||
if (!p_shadow) {
|
||||
if (!p_shadow && !p_directional_add) {
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,2,state.env_radiance_ubo); //bind environment radiance info
|
||||
glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-1);
|
||||
glBindTexture(GL_TEXTURE_2D,state.brdf_texture);
|
||||
|
@ -934,114 +972,104 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
state.current_line_width=-1;
|
||||
state.current_depth_draw=-1;
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
RasterizerStorageGLES3::Material* prev_material=NULL;
|
||||
RasterizerStorageGLES3::Geometry* prev_geometry=NULL;
|
||||
VS::InstanceType prev_base_type = VS::INSTANCE_MAX;
|
||||
|
||||
int prev_light_type=-1;
|
||||
int prev_light_index=-1;
|
||||
int prev_blend=-1;
|
||||
int current_blend_mode=-1;
|
||||
|
||||
bool prev_additive=false;
|
||||
int prev_shading=-1;
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true); //by default unshaded (easier to set)
|
||||
|
||||
bool first=true;
|
||||
|
||||
for (int i=0;i<p_element_count;i++) {
|
||||
|
||||
RenderList::Element *e = p_elements[i];
|
||||
RasterizerStorageGLES3::Material* material= e->material;
|
||||
|
||||
bool rebind=i==0;
|
||||
bool rebind=first;
|
||||
|
||||
int light_type=(e->sort_key>>RenderList::SORT_KEY_LIGHT_TYPE_SHIFT)&0xF;
|
||||
int light_index=(e->sort_key>>RenderList::SORT_KEY_LIGHT_INDEX_SHIFT)&0xFFFF;
|
||||
|
||||
bool additive=false;
|
||||
int shading = (e->sort_key>>RenderList::SORT_KEY_SHADING_SHIFT)&RenderList::SORT_KEY_SHADING_MASK;
|
||||
|
||||
if (!p_shadow) {
|
||||
|
||||
if (light_type!=prev_light_type /* || receive_shadows_state!=prev_receive_shadows_state*/) {
|
||||
|
||||
if (material->shader->spatial.unshaded/* || current_debug==VS::SCENARIO_DEBUG_SHADELESS*/) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_DIRECTIONAL,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_OMNI,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_SPOT,false);
|
||||
|
||||
if (p_directional_add) {
|
||||
if (e->sort_key&RenderList::SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask&directional_light->light_ptr->cull_mask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
shading&=~1; //ignore the ignore directional for base pass
|
||||
}
|
||||
|
||||
if (shading!=prev_shading) {
|
||||
|
||||
if (e->sort_key&RenderList::SORT_KEY_UNSHADED_FLAG) {
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13,false);
|
||||
|
||||
|
||||
|
||||
//state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true);
|
||||
} else {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,light_type!=0xF);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_DIRECTIONAL,(light_type&3)==VS::LIGHT_DIRECTIONAL);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_OMNI,(light_type&0xF)==VS::LIGHT_OMNI);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_SPOT,(light_type&0xF)==VS::LIGHT_SPOT);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,!p_directional_add);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5,shadow_filter_mode==SHADOW_FILTER_PCF5);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13,shadow_filter_mode==SHADOW_FILTER_PCF13);
|
||||
|
||||
if ((light_type&3)==VS::LIGHT_DIRECTIONAL) {
|
||||
|
||||
if (light_instances[light_index]->light_ptr->shadow) {
|
||||
if (p_directional_add || (directional_light && (e->sort_key&RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG)==0)) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,true);
|
||||
|
||||
if (directional_light->light_ptr->shadow) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW,true);
|
||||
|
||||
switch(light_instances[light_index]->light_ptr->directional_shadow_mode) {
|
||||
switch(directional_light->light_ptr->directional_shadow_mode) {
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: break; //none
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2,true); break;
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4,true); break;
|
||||
}
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2,true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,directional_light->light_ptr->directional_blend_splits);
|
||||
break;
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4,true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,directional_light->light_ptr->directional_blend_splits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rebind=true;
|
||||
}
|
||||
|
||||
|
||||
if (!*e->additive_ptr) {
|
||||
|
||||
additive=false;
|
||||
*e->additive_ptr=true;
|
||||
} else {
|
||||
additive=true;
|
||||
}
|
||||
|
||||
bool desired_blend=false;
|
||||
int desired_blend_mode=RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
|
||||
|
||||
if (additive) {
|
||||
desired_blend=true;
|
||||
if (p_alpha_pass || p_directional_add) {
|
||||
int desired_blend_mode;
|
||||
if (p_directional_add) {
|
||||
desired_blend_mode=RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_ADD;
|
||||
} else {
|
||||
desired_blend=p_alpha_pass;
|
||||
desired_blend_mode=material->shader->spatial.blend_mode;
|
||||
}
|
||||
|
||||
if (prev_blend!=desired_blend) {
|
||||
|
||||
if (desired_blend) {
|
||||
glEnable(GL_BLEND);
|
||||
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
|
||||
glColorMask(1,1,1,0);
|
||||
}
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
glColorMask(1,1,1,1);
|
||||
}
|
||||
|
||||
prev_blend=desired_blend;
|
||||
}
|
||||
|
||||
if (desired_blend && desired_blend_mode!=current_blend_mode) {
|
||||
if (desired_blend_mode!=current_blend_mode) {
|
||||
|
||||
|
||||
switch(desired_blend_mode) {
|
||||
|
@ -1083,12 +1111,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
current_blend_mode=desired_blend_mode;
|
||||
}
|
||||
|
||||
if (light_index!=prev_light_index) {
|
||||
if (light_index!=0xFFFF) { //not unshaded
|
||||
_setup_light(light_instances[light_index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1098,17 +1123,16 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
// _rinfo.mat_change_count++;
|
||||
}
|
||||
|
||||
if (!(e->sort_key&RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
|
||||
_setup_light(e);
|
||||
}
|
||||
|
||||
|
||||
if (prev_base_type != e->instance->base_type || prev_geometry!=e->geometry) {
|
||||
|
||||
_setup_geometry(e);
|
||||
}
|
||||
|
||||
if (!p_shadow && (rebind || prev_additive!=additive)) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::NO_AMBIENT_LIGHT, additive);
|
||||
|
||||
}
|
||||
|
||||
_set_cull(e->sort_key&RenderList::SORT_KEY_MIRROR_FLAG,p_reverse_cull);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror?-1.0:1.0);
|
||||
|
@ -1120,9 +1144,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
prev_material=material;
|
||||
prev_base_type=e->instance->base_type;
|
||||
prev_geometry=e->geometry;
|
||||
prev_additive=additive;
|
||||
prev_light_type=light_type;
|
||||
prev_light_index=light_index;
|
||||
prev_shading=shading;
|
||||
first=false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -1133,14 +1156,14 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
|
|||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_CUBEMAP,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_DIRECTIONAL,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_OMNI,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_SPOT,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13,false);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1214,8 +1237,6 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
|||
e->material=m;
|
||||
e->instance=p_instance;
|
||||
e->owner=p_owner;
|
||||
e->additive=false;
|
||||
e->additive_ptr=&e->additive;
|
||||
e->sort_key=0;
|
||||
|
||||
if (e->geometry->last_pass!=render_pass) {
|
||||
|
@ -1223,6 +1244,9 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
|||
e->geometry->index=current_geometry_index++;
|
||||
}
|
||||
|
||||
if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask&e->instance->layer_mask)==0) {
|
||||
e->sort_key|=RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG;
|
||||
}
|
||||
|
||||
e->sort_key|=uint64_t(e->geometry->index)<<RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
|
||||
e->sort_key|=uint64_t(e->instance->base_type)<<RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT;
|
||||
|
@ -1247,7 +1271,6 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
|||
return;
|
||||
|
||||
copymem(oe,e,sizeof(RenderList::Element));
|
||||
oe->additive_ptr=&oe->additive;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1261,106 +1284,10 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
|||
|
||||
//e->light_type=0xFF; // no lights!
|
||||
|
||||
|
||||
|
||||
|
||||
if (shadow || m->shader->spatial.unshaded /*|| current_debug==VS::SCENARIO_DEBUG_SHADELESS*/) {
|
||||
|
||||
e->sort_key|=RenderList::SORT_KEY_LIGHT_INDEX_UNSHADED;
|
||||
e->sort_key|=uint64_t(0xF)<<RenderList::SORT_KEY_LIGHT_TYPE_SHIFT; //light type 0xF is no light?
|
||||
e->sort_key|=uint64_t(0xFFFF)<<RenderList::SORT_KEY_LIGHT_INDEX_SHIFT;
|
||||
} else {
|
||||
|
||||
bool duplicate=false;
|
||||
bool lit=false;
|
||||
|
||||
|
||||
for(int i=0;i<directional_light_instance_count;i++) {
|
||||
|
||||
/*
|
||||
if (directional_lights[i]->base->shadow_enabled) {
|
||||
light_type|=0x8;
|
||||
if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)
|
||||
light_type|=0x10;
|
||||
else if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS)
|
||||
light_type|=0x30;
|
||||
|
||||
e->sort_key|=RenderList::SORT_KEY_UNSHADED_FLAG;
|
||||
}
|
||||
*/
|
||||
|
||||
RenderList::Element *ec;
|
||||
if (duplicate) {
|
||||
ec = render_list.add_element();
|
||||
copymem(ec,e,sizeof(RenderList::Element));
|
||||
} else {
|
||||
|
||||
ec=e;
|
||||
duplicate=true;
|
||||
}
|
||||
|
||||
ec->additive_ptr=&e->additive;
|
||||
|
||||
ec->sort_key&=~RenderList::SORT_KEY_LIGHT_MASK;
|
||||
ec->sort_key|=uint64_t(directional_light_instances[i]->light_index) << RenderList::SORT_KEY_LIGHT_INDEX_SHIFT;
|
||||
ec->sort_key|=uint64_t(VS::LIGHT_DIRECTIONAL) << RenderList::SORT_KEY_LIGHT_TYPE_SHIFT; //this is zero byt whathever
|
||||
|
||||
if (directional_light_instances[i]->light_ptr->shadow) {
|
||||
//add proper flags for directional shadow mode
|
||||
ec->sort_key|=uint64_t(directional_light_instances[i]->light_ptr->directional_shadow_mode+1) << (RenderList::SORT_KEY_LIGHT_TYPE_SHIFT+2);
|
||||
}
|
||||
|
||||
lit=true;
|
||||
}
|
||||
|
||||
|
||||
const RID *liptr = p_instance->light_instances.ptr();
|
||||
int ilc=p_instance->light_instances.size();
|
||||
|
||||
|
||||
|
||||
for(int i=0;i<ilc;i++) {
|
||||
|
||||
LightInstance *li=light_instance_owner.getptr( liptr[i] );
|
||||
|
||||
if (!li || li->last_pass!=render_pass) //lit by light not in visible scene
|
||||
continue;
|
||||
|
||||
|
||||
// if (li->base->shadow_enabled) {
|
||||
// light_type|=0x8;
|
||||
// }
|
||||
|
||||
RenderList::Element *ec;
|
||||
if (duplicate) {
|
||||
|
||||
ec = render_list.add_element();
|
||||
copymem(ec,e,sizeof(RenderList::Element));
|
||||
} else {
|
||||
|
||||
duplicate=true;
|
||||
ec=e;
|
||||
}
|
||||
|
||||
ec->additive_ptr=&e->additive;
|
||||
|
||||
ec->sort_key&=~RenderList::SORT_KEY_LIGHT_MASK;
|
||||
ec->sort_key|=uint64_t(li->light_index) << RenderList::SORT_KEY_LIGHT_INDEX_SHIFT;
|
||||
ec->sort_key|=uint64_t(li->light_ptr->type) << RenderList::SORT_KEY_LIGHT_TYPE_SHIFT;
|
||||
|
||||
lit=true;
|
||||
}
|
||||
|
||||
|
||||
if (!lit) {
|
||||
e->sort_key&=~RenderList::SORT_KEY_LIGHT_MASK;
|
||||
e->sort_key|=uint64_t(0xE)<<RenderList::SORT_KEY_LIGHT_TYPE_SHIFT; //light type 0xE is no light found
|
||||
e->sort_key|=uint64_t(0xFFFF)<<RenderList::SORT_KEY_LIGHT_INDEX_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_draw_skybox(RID p_skybox,const CameraMatrix& p_projection,const Transform& p_transform,bool p_vflip,float p_scale) {
|
||||
|
@ -1534,49 +1461,43 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env,const CameraMatri
|
|||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cull_count,const Transform& p_camera_inverse_transform,const CameraMatrix& p_camera_projection,RID p_shadow_atlas) {
|
||||
void RasterizerSceneGLES3::_setup_directional_light(int p_index,const Transform& p_camera_inverse_transform) {
|
||||
|
||||
LightInstance *li = directional_lights[p_index];
|
||||
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
LightDataUBO ubo_data; //used for filling
|
||||
|
||||
directional_light_instance_count=0;
|
||||
light_instance_count=0;
|
||||
|
||||
for(int i=0;i<p_light_cull_count;i++) {
|
||||
|
||||
ERR_BREAK( i>=RenderList::MAX_LIGHTS );
|
||||
|
||||
LightInstance *li = light_instance_owner.getptr(p_light_cull_result[i]);
|
||||
|
||||
switch(li->light_ptr->type) {
|
||||
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
|
||||
ERR_FAIL_COND( directional_light_instance_count >= RenderList::MAX_LIGHTS);
|
||||
directional_light_instances[directional_light_instance_count++]=li;
|
||||
float sign = li->light_ptr->negative?-1:1;
|
||||
|
||||
Color linear_col = li->light_ptr->color.to_linear();
|
||||
li->light_ubo_data.light_color_energy[0]=linear_col.r;
|
||||
li->light_ubo_data.light_color_energy[1]=linear_col.g;
|
||||
li->light_ubo_data.light_color_energy[2]=linear_col.b;
|
||||
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
|
||||
ubo_data.light_color_energy[0]=linear_col.r*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[1]=linear_col.g*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[2]=linear_col.b*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[3]=0;
|
||||
|
||||
//omni, keep at 0
|
||||
li->light_ubo_data.light_pos_inv_radius[0]=0.0;
|
||||
li->light_ubo_data.light_pos_inv_radius[1]=0.0;
|
||||
li->light_ubo_data.light_pos_inv_radius[2]=0.0;
|
||||
li->light_ubo_data.light_pos_inv_radius[3]=0.0;
|
||||
ubo_data.light_pos_inv_radius[0]=0.0;
|
||||
ubo_data.light_pos_inv_radius[1]=0.0;
|
||||
ubo_data.light_pos_inv_radius[2]=0.0;
|
||||
ubo_data.light_pos_inv_radius[3]=0.0;
|
||||
|
||||
Vector3 direction = p_camera_inverse_transform.basis.xform(li->transform.basis.xform(Vector3(0,0,-1))).normalized();
|
||||
li->light_ubo_data.light_direction_attenuation[0]=direction.x;
|
||||
li->light_ubo_data.light_direction_attenuation[1]=direction.y;
|
||||
li->light_ubo_data.light_direction_attenuation[2]=direction.z;
|
||||
li->light_ubo_data.light_direction_attenuation[3]=1.0;
|
||||
ubo_data.light_direction_attenuation[0]=direction.x;
|
||||
ubo_data.light_direction_attenuation[1]=direction.y;
|
||||
ubo_data.light_direction_attenuation[2]=direction.z;
|
||||
ubo_data.light_direction_attenuation[3]=1.0;
|
||||
|
||||
ubo_data.light_params[0]=0;
|
||||
ubo_data.light_params[1]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
ubo_data.light_params[2]=0;
|
||||
ubo_data.light_params[3]=0;
|
||||
|
||||
Color shadow_color = li->light_ptr->shadow_color.to_linear();
|
||||
ubo_data.light_shadow_color[0]=shadow_color.r;
|
||||
ubo_data.light_shadow_color[1]=shadow_color.g;
|
||||
ubo_data.light_shadow_color[2]=shadow_color.b;
|
||||
ubo_data.light_shadow_color[3]=1.0;
|
||||
|
||||
li->light_ubo_data.light_params[0]=0;
|
||||
li->light_ubo_data.light_params[1]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
li->light_ubo_data.light_params[2]=0;
|
||||
li->light_ubo_data.light_params[3]=0;
|
||||
|
||||
if (li->light_ptr->shadow) {
|
||||
|
||||
|
@ -1637,7 +1558,7 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
|
||||
}
|
||||
|
||||
li->light_ubo_data.shadow_split_offsets[j]=1.0/li->shadow_transform[j].split;
|
||||
ubo_data.shadow_split_offsets[j]=1.0/li->shadow_transform[j].split;
|
||||
|
||||
Transform modelview = (p_camera_inverse_transform * li->shadow_transform[j].transform).inverse();
|
||||
|
||||
|
@ -1651,44 +1572,91 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
|
||||
CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[j].camera * modelview;
|
||||
|
||||
store_camera(shadow_mtx,&li->light_ubo_data.shadow_matrix1[16*j]);
|
||||
store_camera(shadow_mtx,&ubo_data.shadow_matrix1[16*j]);
|
||||
|
||||
li->light_ubo_data.light_clamp[0]=atlas_rect.pos.x;
|
||||
li->light_ubo_data.light_clamp[1]=atlas_rect.pos.y;
|
||||
li->light_ubo_data.light_clamp[2]=atlas_rect.size.x;
|
||||
li->light_ubo_data.light_clamp[3]=atlas_rect.size.y;
|
||||
ubo_data.light_clamp[0]=atlas_rect.pos.x;
|
||||
ubo_data.light_clamp[1]=atlas_rect.pos.y;
|
||||
ubo_data.light_clamp[2]=atlas_rect.size.x;
|
||||
ubo_data.light_clamp[3]=atlas_rect.size.y;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.directional_ubo);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightDataUBO), &ubo_data);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
directional_light=li;
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,3,state.directional_ubo);
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cull_count,const Transform& p_camera_inverse_transform,const CameraMatrix& p_camera_projection,RID p_shadow_atlas) {
|
||||
|
||||
|
||||
state.omni_light_count=0;
|
||||
state.spot_light_count=0;
|
||||
state.directional_light_count=0;
|
||||
|
||||
directional_light=NULL;
|
||||
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
|
||||
|
||||
for(int i=0;i<p_light_cull_count;i++) {
|
||||
|
||||
ERR_BREAK( i>=RenderList::MAX_LIGHTS );
|
||||
|
||||
LightInstance *li = light_instance_owner.getptr(p_light_cull_result[i]);
|
||||
|
||||
LightDataUBO ubo_data; //used for filling
|
||||
|
||||
switch(li->light_ptr->type) {
|
||||
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
|
||||
if (state.directional_light_count<RenderList::MAX_DIRECTIONAL_LIGHTS) {
|
||||
directional_lights[state.directional_light_count++]=li;
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
case VS::LIGHT_OMNI: {
|
||||
|
||||
float sign = li->light_ptr->negative?-1:1;
|
||||
|
||||
Color linear_col = li->light_ptr->color.to_linear();
|
||||
li->light_ubo_data.light_color_energy[0]=linear_col.r;
|
||||
li->light_ubo_data.light_color_energy[1]=linear_col.g;
|
||||
li->light_ubo_data.light_color_energy[2]=linear_col.b;
|
||||
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
|
||||
ubo_data.light_color_energy[0]=linear_col.r*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[1]=linear_col.g*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[2]=linear_col.b*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[3]=0;
|
||||
|
||||
|
||||
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
|
||||
|
||||
//directional, keep at 0
|
||||
li->light_ubo_data.light_pos_inv_radius[0]=pos.x;
|
||||
li->light_ubo_data.light_pos_inv_radius[1]=pos.y;
|
||||
li->light_ubo_data.light_pos_inv_radius[2]=pos.z;
|
||||
li->light_ubo_data.light_pos_inv_radius[3]=1.0/MAX(0.001,li->light_ptr->param[VS::LIGHT_PARAM_RANGE]);
|
||||
ubo_data.light_pos_inv_radius[0]=pos.x;
|
||||
ubo_data.light_pos_inv_radius[1]=pos.y;
|
||||
ubo_data.light_pos_inv_radius[2]=pos.z;
|
||||
ubo_data.light_pos_inv_radius[3]=1.0/MAX(0.001,li->light_ptr->param[VS::LIGHT_PARAM_RANGE]);
|
||||
|
||||
li->light_ubo_data.light_direction_attenuation[0]=0;
|
||||
li->light_ubo_data.light_direction_attenuation[1]=0;
|
||||
li->light_ubo_data.light_direction_attenuation[2]=0;
|
||||
li->light_ubo_data.light_direction_attenuation[3]=li->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
ubo_data.light_direction_attenuation[0]=0;
|
||||
ubo_data.light_direction_attenuation[1]=0;
|
||||
ubo_data.light_direction_attenuation[2]=0;
|
||||
ubo_data.light_direction_attenuation[3]=li->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
|
||||
li->light_ubo_data.light_params[0]=0;
|
||||
li->light_ubo_data.light_params[1]=0;
|
||||
li->light_ubo_data.light_params[2]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
li->light_ubo_data.light_params[3]=0;
|
||||
ubo_data.light_params[0]=0;
|
||||
ubo_data.light_params[1]=0;
|
||||
ubo_data.light_params[2]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
ubo_data.light_params[3]=0;
|
||||
|
||||
Color shadow_color = li->light_ptr->shadow_color.to_linear();
|
||||
ubo_data.light_shadow_color[0]=shadow_color.r;
|
||||
ubo_data.light_shadow_color[1]=shadow_color.g;
|
||||
ubo_data.light_shadow_color[2]=shadow_color.b;
|
||||
ubo_data.light_shadow_color[3]=1.0;
|
||||
|
||||
if (li->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) {
|
||||
// fill in the shadow information
|
||||
|
@ -1724,17 +1692,21 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
|
||||
Transform proj = (p_camera_inverse_transform * li->transform).inverse();
|
||||
|
||||
store_transform(proj,li->light_ubo_data.shadow_matrix1);
|
||||
store_transform(proj,ubo_data.shadow_matrix1);
|
||||
|
||||
li->light_ubo_data.light_params[3]=1.0; //means it has shadow
|
||||
li->light_ubo_data.light_clamp[0]=float(x)/atlas_size;
|
||||
li->light_ubo_data.light_clamp[1]=float(y)/atlas_size;
|
||||
li->light_ubo_data.light_clamp[2]=float(width)/atlas_size;
|
||||
li->light_ubo_data.light_clamp[3]=float(height)/atlas_size;
|
||||
ubo_data.light_params[3]=1.0; //means it has shadow
|
||||
ubo_data.light_clamp[0]=float(x)/atlas_size;
|
||||
ubo_data.light_clamp[1]=float(y)/atlas_size;
|
||||
ubo_data.light_clamp[2]=float(width)/atlas_size;
|
||||
ubo_data.light_clamp[3]=float(height)/atlas_size;
|
||||
|
||||
}
|
||||
|
||||
|
||||
li->light_index=state.omni_light_count;
|
||||
copymem(&state.omni_array_tmp[li->light_index*state.ubo_light_size],&ubo_data,state.ubo_light_size);
|
||||
state.omni_light_count++;
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
@ -1746,30 +1718,38 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
} break;
|
||||
case VS::LIGHT_SPOT: {
|
||||
|
||||
float sign = li->light_ptr->negative?-1:1;
|
||||
|
||||
Color linear_col = li->light_ptr->color.to_linear();
|
||||
li->light_ubo_data.light_color_energy[0]=linear_col.r;
|
||||
li->light_ubo_data.light_color_energy[1]=linear_col.g;
|
||||
li->light_ubo_data.light_color_energy[2]=linear_col.b;
|
||||
li->light_ubo_data.light_color_energy[3]=li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
|
||||
ubo_data.light_color_energy[0]=linear_col.r*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[1]=linear_col.g*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[2]=linear_col.b*sign*li->light_ptr->param[VS::LIGHT_PARAM_ENERGY];;
|
||||
ubo_data.light_color_energy[3]=0;
|
||||
|
||||
Vector3 pos = p_camera_inverse_transform.xform(li->transform.origin);
|
||||
|
||||
//directional, keep at 0
|
||||
li->light_ubo_data.light_pos_inv_radius[0]=pos.x;
|
||||
li->light_ubo_data.light_pos_inv_radius[1]=pos.y;
|
||||
li->light_ubo_data.light_pos_inv_radius[2]=pos.z;
|
||||
li->light_ubo_data.light_pos_inv_radius[3]=1.0/MAX(0.001,li->light_ptr->param[VS::LIGHT_PARAM_RANGE]);
|
||||
ubo_data.light_pos_inv_radius[0]=pos.x;
|
||||
ubo_data.light_pos_inv_radius[1]=pos.y;
|
||||
ubo_data.light_pos_inv_radius[2]=pos.z;
|
||||
ubo_data.light_pos_inv_radius[3]=1.0/MAX(0.001,li->light_ptr->param[VS::LIGHT_PARAM_RANGE]);
|
||||
|
||||
Vector3 direction = p_camera_inverse_transform.basis.xform(li->transform.basis.xform(Vector3(0,0,-1))).normalized();
|
||||
li->light_ubo_data.light_direction_attenuation[0]=direction.x;
|
||||
li->light_ubo_data.light_direction_attenuation[1]=direction.y;
|
||||
li->light_ubo_data.light_direction_attenuation[2]=direction.z;
|
||||
li->light_ubo_data.light_direction_attenuation[3]=li->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
ubo_data.light_direction_attenuation[0]=direction.x;
|
||||
ubo_data.light_direction_attenuation[1]=direction.y;
|
||||
ubo_data.light_direction_attenuation[2]=direction.z;
|
||||
ubo_data.light_direction_attenuation[3]=li->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
|
||||
li->light_ubo_data.light_params[0]=li->light_ptr->param[VS::LIGHT_PARAM_SPOT_ATTENUATION];
|
||||
li->light_ubo_data.light_params[1]=Math::cos(Math::deg2rad(li->light_ptr->param[VS::LIGHT_PARAM_SPOT_ANGLE]));
|
||||
li->light_ubo_data.light_params[2]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
li->light_ubo_data.light_params[3]=0;
|
||||
ubo_data.light_params[0]=li->light_ptr->param[VS::LIGHT_PARAM_SPOT_ATTENUATION];
|
||||
ubo_data.light_params[1]=Math::cos(Math::deg2rad(li->light_ptr->param[VS::LIGHT_PARAM_SPOT_ANGLE]));
|
||||
ubo_data.light_params[2]=li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
ubo_data.light_params[3]=0;
|
||||
|
||||
Color shadow_color = li->light_ptr->shadow_color.to_linear();
|
||||
ubo_data.light_shadow_color[0]=shadow_color.r;
|
||||
ubo_data.light_shadow_color[1]=shadow_color.g;
|
||||
ubo_data.light_shadow_color[2]=shadow_color.b;
|
||||
ubo_data.light_shadow_color[3]=1.0;
|
||||
|
||||
if (li->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) {
|
||||
// fill in the shadow information
|
||||
|
@ -1796,11 +1776,11 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
|
||||
Rect2 rect(float(x)/atlas_size,float(y)/atlas_size,float(width)/atlas_size,float(height)/atlas_size);
|
||||
|
||||
li->light_ubo_data.light_params[3]=1.0; //means it has shadow
|
||||
li->light_ubo_data.light_clamp[0]=rect.pos.x;
|
||||
li->light_ubo_data.light_clamp[1]=rect.pos.y;
|
||||
li->light_ubo_data.light_clamp[2]=rect.size.x;
|
||||
li->light_ubo_data.light_clamp[3]=rect.size.y;
|
||||
ubo_data.light_params[3]=1.0; //means it has shadow
|
||||
ubo_data.light_clamp[0]=rect.pos.x;
|
||||
ubo_data.light_clamp[1]=rect.pos.y;
|
||||
ubo_data.light_clamp[2]=rect.size.x;
|
||||
ubo_data.light_clamp[3]=rect.size.y;
|
||||
|
||||
Transform modelview = (p_camera_inverse_transform * li->transform).inverse();
|
||||
|
||||
|
@ -1811,10 +1791,15 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
|
||||
CameraMatrix shadow_mtx = rectm * bias * li->shadow_transform[0].camera * modelview;
|
||||
|
||||
store_camera(shadow_mtx,li->light_ubo_data.shadow_matrix1);
|
||||
store_camera(shadow_mtx,ubo_data.shadow_matrix1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
li->light_index=state.spot_light_count;
|
||||
copymem(&state.spot_array_tmp[li->light_index*state.ubo_light_size],&ubo_data,state.ubo_light_size);
|
||||
state.spot_light_count++;
|
||||
|
||||
#if 0
|
||||
if (li->light_ptr->shadow_enabled) {
|
||||
CameraMatrix bias;
|
||||
|
@ -1829,24 +1814,34 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
|
|||
}
|
||||
|
||||
|
||||
/* make light hash */
|
||||
|
||||
// actually, not really a hash, but helps to sort the lights
|
||||
// and avoid recompiling redudant shader versions
|
||||
|
||||
|
||||
li->last_pass=render_pass;
|
||||
li->light_index=i;
|
||||
|
||||
//update UBO for forward rendering, blit to texture for clustered
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, li->light_ubo);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightInstance::LightDataUBO), &li->light_ubo_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (state.omni_light_count) {
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.omni_array_ubo);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, state.omni_light_count*state.ubo_light_size, state.omni_array_tmp);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
light_instances[i]=li;
|
||||
light_instance_count++;
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,4,state.omni_array_ubo);
|
||||
}
|
||||
|
||||
if (state.spot_light_count) {
|
||||
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.spot_array_ubo);
|
||||
glBufferSubData(GL_UNIFORM_BUFFER, 0, state.spot_light_count*state.ubo_light_size, state.spot_array_tmp);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER,5,state.spot_array_ubo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::_copy_screen() {
|
||||
|
@ -1969,6 +1964,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
|||
//first of all, make a new render pass
|
||||
render_pass++;
|
||||
|
||||
|
||||
//fill up ubo
|
||||
|
||||
Environment *env = environment_owner.getornull(p_environment);
|
||||
|
@ -2075,7 +2071,20 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
|||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
_render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false,false);
|
||||
if (state.directional_light_count==0) {
|
||||
directional_light=NULL;
|
||||
_render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false,false,false);
|
||||
} else {
|
||||
for(int i=0;i<state.directional_light_count;i++) {
|
||||
directional_light=directional_lights[i];
|
||||
if (i>0) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
_setup_directional_light(i,p_cam_transform.affine_inverse());
|
||||
_render_list(render_list.elements,render_list.element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,false,false,i>0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
|
||||
|
@ -2107,9 +2116,20 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
|||
|
||||
render_list.sort_by_depth(true);
|
||||
|
||||
_render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,true,false);
|
||||
|
||||
|
||||
if (state.directional_light_count==0) {
|
||||
directional_light=NULL;
|
||||
_render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,true,false,false);
|
||||
} else {
|
||||
for(int i=0;i<state.directional_light_count;i++) {
|
||||
directional_light=directional_lights[i];
|
||||
_setup_directional_light(i,p_cam_transform.affine_inverse());
|
||||
_render_list(&render_list.elements[render_list.max_elements-render_list.alpha_element_count],render_list.alpha_element_count,p_cam_transform,p_cam_projection,env_radiance_tex,false,true,false,i>0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_copy_to_front_buffer(env);
|
||||
|
||||
/* if (shadow_atlas) {
|
||||
|
@ -2123,7 +2143,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
|||
|
||||
}
|
||||
*/
|
||||
if (directional_shadow.fbo) {
|
||||
if (false && directional_shadow.fbo) {
|
||||
|
||||
//_copy_texture_to_front_buffer(shadow_atlas->depth);
|
||||
storage->canvas->canvas_begin();
|
||||
|
@ -2285,6 +2305,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa
|
|||
|
||||
render_pass++;
|
||||
|
||||
directional_light=NULL;
|
||||
|
||||
LightInstance *light_instance = light_instance_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
RasterizerStorageGLES3::Light *light = storage->light_owner.getornull(light_instance->light);
|
||||
|
@ -2512,7 +2534,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa
|
|||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW,true);
|
||||
|
||||
_render_list(render_list.elements,render_list.element_count,light_transform,light_projection,NULL,!flip_facing,false,true);
|
||||
_render_list(render_list.elements,render_list.element_count,light_transform,light_projection,NULL,!flip_facing,false,true,false);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW,false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW_DUAL_PARABOLOID,false);
|
||||
|
@ -2593,7 +2615,6 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
|
|||
}
|
||||
|
||||
|
||||
glDeleteBuffers(1,&light_instance->light_ubo);
|
||||
light_instance_owner.free(p_rid);
|
||||
memdelete(light_instance);
|
||||
|
||||
|
@ -2860,6 +2881,53 @@ void RasterizerSceneGLES3::initialize() {
|
|||
ERR_PRINT("Directional shadow framebuffer status invalid");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
//spot and omni ubos
|
||||
|
||||
int max_ubo_size;
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE,&max_ubo_size);
|
||||
const int ubo_light_size=160;
|
||||
state.ubo_light_size=ubo_light_size;
|
||||
state.max_ubo_lights=max_ubo_size/ubo_light_size;
|
||||
|
||||
state.spot_array_tmp = (uint8_t*)memalloc(ubo_light_size*state.max_ubo_lights);
|
||||
state.omni_array_tmp = (uint8_t*)memalloc(ubo_light_size*state.max_ubo_lights);
|
||||
|
||||
|
||||
glGenBuffers(1, &state.spot_array_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.spot_array_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, ubo_light_size*state.max_ubo_lights, NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glGenBuffers(1, &state.omni_array_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.omni_array_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, ubo_light_size*state.max_ubo_lights, NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
glGenBuffers(1, &state.directional_ubo);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, state.directional_ubo);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(LightDataUBO), NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
|
||||
state.max_forward_lights_per_object=8;
|
||||
|
||||
state.scene_shader.add_custom_define("#define MAX_LIGHT_DATA_STRUCTS "+itos(state.max_ubo_lights)+"\n");
|
||||
state.scene_shader.add_custom_define("#define MAX_FORWARD_LIGHTS "+itos(state.max_forward_lights_per_object)+"\n");
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
GLOBAL_DEF("rendering/gles3/shadow_filter_mode",1);
|
||||
Globals::get_singleton()->set_custom_property_info("rendering/gles3/shadow_filter_mode",PropertyInfo(Variant::INT,"rendering/gles3/shadow_filter_mode",PROPERTY_HINT_ENUM,"Disabled,PCF5,PCF13"));
|
||||
shadow_filter_mode=SHADOW_FILTER_NEAREST;
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::iteration() {
|
||||
|
||||
shadow_filter_mode=ShadowFilterMode(int(Globals::get_singleton()->get("rendering/gles3/shadow_filter_mode")));
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::finalize(){
|
||||
|
|
|
@ -8,6 +8,15 @@
|
|||
class RasterizerSceneGLES3 : public RasterizerScene {
|
||||
public:
|
||||
|
||||
enum ShadowFilterMode {
|
||||
SHADOW_FILTER_NEAREST,
|
||||
SHADOW_FILTER_PCF5,
|
||||
SHADOW_FILTER_PCF13,
|
||||
};
|
||||
|
||||
|
||||
ShadowFilterMode shadow_filter_mode;
|
||||
|
||||
uint64_t shadow_atlas_realloc_tolerance_msec;
|
||||
|
||||
|
||||
|
@ -27,6 +36,7 @@ public:
|
|||
struct State {
|
||||
|
||||
|
||||
|
||||
bool texscreen_copied;
|
||||
int current_blend_mode;
|
||||
float current_line_width;
|
||||
|
@ -73,6 +83,22 @@ public:
|
|||
GLuint skybox_verts;
|
||||
GLuint skybox_array;
|
||||
|
||||
GLuint directional_ubo;
|
||||
|
||||
GLuint spot_array_ubo;
|
||||
GLuint omni_array_ubo;
|
||||
|
||||
uint32_t ubo_light_size;
|
||||
uint8_t *spot_array_tmp;
|
||||
uint8_t *omni_array_tmp;
|
||||
|
||||
int max_ubo_lights;
|
||||
int max_forward_lights_per_object;
|
||||
|
||||
int spot_light_count;
|
||||
int omni_light_count;
|
||||
int directional_light_count;
|
||||
|
||||
bool cull_front;
|
||||
|
||||
} state;
|
||||
|
@ -204,6 +230,22 @@ public:
|
|||
|
||||
/* LIGHT INSTANCE */
|
||||
|
||||
struct LightDataUBO {
|
||||
|
||||
float light_pos_inv_radius[4];
|
||||
float light_direction_attenuation[4];
|
||||
float light_color_energy[4];
|
||||
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
|
||||
float light_clamp[4];
|
||||
float light_shadow_color[4];
|
||||
float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
|
||||
float shadow_matrix2[16];
|
||||
float shadow_matrix3[16];
|
||||
float shadow_matrix4[16];
|
||||
float shadow_split_offsets[4];
|
||||
|
||||
};
|
||||
|
||||
struct LightInstance : public RID_Data {
|
||||
|
||||
struct ShadowTransform {
|
||||
|
@ -214,20 +256,6 @@ public:
|
|||
float split;
|
||||
};
|
||||
|
||||
struct LightDataUBO {
|
||||
|
||||
float light_pos_inv_radius[4];
|
||||
float light_direction_attenuation[4];
|
||||
float light_color_energy[4];
|
||||
float light_params[4]; //cone attenuation, specular, shadow darkening,
|
||||
float light_clamp[4]; //cone attenuation, specular, shadow darkening,
|
||||
float shadow_split_offsets[4];
|
||||
float shadow_matrix1[16];
|
||||
float shadow_matrix2[16];
|
||||
float shadow_matrix3[16];
|
||||
float shadow_matrix4[16];
|
||||
|
||||
} light_ubo_data;
|
||||
|
||||
|
||||
ShadowTransform shadow_transform[4];
|
||||
|
@ -241,8 +269,6 @@ public:
|
|||
Vector3 spot_vector;
|
||||
float linear_att;
|
||||
|
||||
GLuint light_ubo;
|
||||
|
||||
uint64_t shadow_pass;
|
||||
uint64_t last_scene_pass;
|
||||
uint64_t last_scene_shadow_pass;
|
||||
|
@ -280,14 +306,16 @@ public:
|
|||
SORT_FLAG_INSTANCING=2,
|
||||
MAX_DIRECTIONAL_LIGHTS=16,
|
||||
MAX_LIGHTS=4096,
|
||||
SORT_KEY_DEPTH_LAYER_SHIFT=58,
|
||||
SORT_KEY_LIGHT_TYPE_SHIFT=54, //type is most important
|
||||
SORT_KEY_LIGHT_INDEX_SHIFT=38, //type is most important
|
||||
SORT_KEY_LIGHT_INDEX_UNSHADED=uint64_t(0xF) << SORT_KEY_LIGHT_TYPE_SHIFT, //type is most important
|
||||
SORT_KEY_LIGHT_MASK=(uint64_t(0xFFFFF) << SORT_KEY_LIGHT_INDEX_SHIFT), //type is most important
|
||||
SORT_KEY_MATERIAL_INDEX_SHIFT=22,
|
||||
SORT_KEY_GEOMETRY_INDEX_SHIFT=6,
|
||||
SORT_KEY_GEOMETRY_TYPE_SHIFT=2,
|
||||
|
||||
|
||||
SORT_KEY_DEPTH_LAYER_SHIFT=60,
|
||||
SORT_KEY_UNSHADED_FLAG=uint64_t(1)<<59,
|
||||
SORT_KEY_NO_DIRECTIONAL_FLAG=uint64_t(1)<<58,
|
||||
SORT_KEY_SHADING_SHIFT=58,
|
||||
SORT_KEY_SHADING_MASK=3,
|
||||
SORT_KEY_MATERIAL_INDEX_SHIFT=40,
|
||||
SORT_KEY_GEOMETRY_INDEX_SHIFT=20,
|
||||
SORT_KEY_GEOMETRY_TYPE_SHIFT=15,
|
||||
SORT_KEY_SKELETON_FLAG=2,
|
||||
SORT_KEY_MIRROR_FLAG=1
|
||||
|
||||
|
@ -302,8 +330,6 @@ public:
|
|||
RasterizerStorageGLES3::Material *material;
|
||||
RasterizerStorageGLES3::GeometryOwner *owner;
|
||||
uint64_t sort_key;
|
||||
bool *additive_ptr;
|
||||
bool additive;
|
||||
|
||||
};
|
||||
|
||||
|
@ -314,6 +340,7 @@ public:
|
|||
int element_count;
|
||||
int alpha_element_count;
|
||||
|
||||
|
||||
void clear() {
|
||||
|
||||
element_count=0;
|
||||
|
@ -399,12 +426,10 @@ public:
|
|||
};
|
||||
|
||||
|
||||
LightInstance *directional_light;
|
||||
LightInstance *directional_lights[RenderList::MAX_DIRECTIONAL_LIGHTS];
|
||||
|
||||
LightInstance *directional_light_instances[RenderList::MAX_DIRECTIONAL_LIGHTS];
|
||||
int directional_light_instance_count;
|
||||
|
||||
LightInstance *light_instances[RenderList::MAX_LIGHTS];
|
||||
int light_instance_count;
|
||||
|
||||
RenderList render_list;
|
||||
|
||||
|
@ -414,9 +439,9 @@ public:
|
|||
_FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection);
|
||||
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
|
||||
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
|
||||
_FORCE_INLINE_ void _setup_light(LightInstance *p_light);
|
||||
_FORCE_INLINE_ void _setup_light(RenderList::Element *e);
|
||||
|
||||
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, RasterizerStorageGLES3::Texture *p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow);
|
||||
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, RasterizerStorageGLES3::Texture *p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add);
|
||||
|
||||
|
||||
_FORCE_INLINE_ void _add_geometry( RasterizerStorageGLES3::Geometry* p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner,int p_material,bool p_shadow);
|
||||
|
@ -424,6 +449,7 @@ public:
|
|||
void _draw_skybox(RID p_skybox, const CameraMatrix& p_projection, const Transform& p_transform, bool p_vflip, float p_scale);
|
||||
|
||||
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform& p_cam_transform);
|
||||
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transform);
|
||||
void _setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, const CameraMatrix& p_camera_projection, RID p_shadow_atlas);
|
||||
void _copy_screen();
|
||||
void _copy_to_front_buffer(Environment *env);
|
||||
|
@ -439,6 +465,7 @@ public:
|
|||
|
||||
virtual void set_scene_pass(uint64_t p_pass);
|
||||
|
||||
void iteration();
|
||||
void initialize();
|
||||
void finalize();
|
||||
RasterizerSceneGLES3();
|
||||
|
|
|
@ -3169,7 +3169,6 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
|
|||
light->param[VS::LIGHT_PARAM_RANGE]=1.0;
|
||||
light->param[VS::LIGHT_PARAM_SPOT_ANGLE]=45;
|
||||
light->param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE]=0;
|
||||
light->param[VS::LIGHT_PARAM_SHADOW_DARKNESS]=0;
|
||||
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET]=0.1;
|
||||
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET]=0.3;
|
||||
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET]=0.6;
|
||||
|
@ -3184,6 +3183,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
|
|||
light->directional_shadow_mode=VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
|
||||
light->omni_shadow_mode=VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
|
||||
light->omni_shadow_detail=VS::LIGHT_OMNI_SHADOW_DETAIL_VERTICAL;
|
||||
light->directional_blend_splits=false;
|
||||
|
||||
light->version=0;
|
||||
|
||||
|
@ -3207,7 +3207,6 @@ void RasterizerStorageGLES3::light_set_param(RID p_light,VS::LightParam p_param,
|
|||
case VS::LIGHT_PARAM_RANGE:
|
||||
case VS::LIGHT_PARAM_SPOT_ANGLE:
|
||||
case VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE:
|
||||
case VS::LIGHT_PARAM_SHADOW_DARKNESS:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
|
||||
case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
|
||||
|
@ -3230,20 +3229,22 @@ void RasterizerStorageGLES3::light_set_shadow(RID p_light,bool p_enabled){
|
|||
|
||||
light->version++;
|
||||
light->instance_change_notify();
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_set_shadow_color(RID p_light,const Color& p_color) {
|
||||
|
||||
Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
light->shadow_color=p_color;
|
||||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_set_projector(RID p_light,RID p_texture){
|
||||
|
||||
Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
|
||||
}
|
||||
void RasterizerStorageGLES3::light_set_attenuation_texure(RID p_light,RID p_texture){
|
||||
|
||||
Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
light->projector=p_texture;
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_set_negative(RID p_light,bool p_enable){
|
||||
|
@ -3263,12 +3264,6 @@ void RasterizerStorageGLES3::light_set_cull_mask(RID p_light,uint32_t p_mask){
|
|||
light->version++;
|
||||
light->instance_change_notify();
|
||||
|
||||
}
|
||||
void RasterizerStorageGLES3::light_set_shader(RID p_light,RID p_shader){
|
||||
|
||||
Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode) {
|
||||
|
@ -3315,6 +3310,26 @@ void RasterizerStorageGLES3::light_directional_set_shadow_mode(RID p_light,VS::L
|
|||
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::light_directional_set_blend_splits(RID p_light,bool p_enable) {
|
||||
|
||||
Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
light->directional_blend_splits=p_enable;
|
||||
light->version++;
|
||||
light->instance_change_notify();
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool RasterizerStorageGLES3::light_directional_get_blend_splits(RID p_light) const {
|
||||
|
||||
const Light * light = light_owner.getornull(p_light);
|
||||
ERR_FAIL_COND_V(!light,false);
|
||||
|
||||
return light->directional_blend_splits;
|
||||
}
|
||||
|
||||
VS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_shadow_mode(RID p_light) {
|
||||
|
||||
const Light * light = light_owner.getornull(p_light);
|
||||
|
|
|
@ -634,12 +634,15 @@ public:
|
|||
VS::LightType type;
|
||||
float param[VS::LIGHT_PARAM_MAX];
|
||||
Color color;
|
||||
Color shadow_color;
|
||||
RID projector;
|
||||
bool shadow;
|
||||
bool negative;
|
||||
uint32_t cull_mask;
|
||||
VS::LightOmniShadowMode omni_shadow_mode;
|
||||
VS::LightOmniShadowDetail omni_shadow_detail;
|
||||
VS::LightDirectionalShadowMode directional_shadow_mode;
|
||||
bool directional_blend_splits;
|
||||
uint64_t version;
|
||||
};
|
||||
|
||||
|
@ -650,17 +653,19 @@ public:
|
|||
virtual void light_set_color(RID p_light,const Color& p_color);
|
||||
virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value);
|
||||
virtual void light_set_shadow(RID p_light,bool p_enabled);
|
||||
virtual void light_set_shadow_color(RID p_light,const Color& p_color);
|
||||
virtual void light_set_projector(RID p_light,RID p_texture);
|
||||
virtual void light_set_attenuation_texure(RID p_light,RID p_texture);
|
||||
virtual void light_set_negative(RID p_light,bool p_enable);
|
||||
virtual void light_set_cull_mask(RID p_light,uint32_t p_mask);
|
||||
virtual void light_set_shader(RID p_light,RID p_shader);
|
||||
|
||||
|
||||
virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode);
|
||||
|
||||
virtual void light_omni_set_shadow_detail(RID p_light,VS::LightOmniShadowDetail p_detail);
|
||||
|
||||
virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode);
|
||||
virtual void light_directional_set_blend_splits(RID p_light,bool p_enable);
|
||||
virtual bool light_directional_get_blend_splits(RID p_light) const;
|
||||
|
||||
virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
|
||||
virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
|
||||
|
||||
|
|
|
@ -228,8 +228,15 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
int define_line_ofs=1;
|
||||
|
||||
for(int i=0;i<custom_defines.size();i++) {
|
||||
|
||||
strings.push_back(custom_defines[i].get_data());
|
||||
define_line_ofs++;
|
||||
}
|
||||
|
||||
for(int j=0;j<conditional_count;j++) {
|
||||
|
||||
bool enable=((1<<j)&conditional_version.version);
|
||||
|
@ -243,6 +250,8 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//keep them around during the function
|
||||
CharString code_string;
|
||||
CharString code_string2;
|
||||
|
|
|
@ -175,6 +175,8 @@ private:
|
|||
CharString vertex_code2;
|
||||
CharString vertex_code3;
|
||||
|
||||
Vector<CharString> custom_defines;
|
||||
|
||||
int base_material_tex_index;
|
||||
|
||||
Version * get_current_version();
|
||||
|
@ -357,6 +359,10 @@ public:
|
|||
|
||||
void set_base_material_tex_index(int p_idx);
|
||||
|
||||
void add_custom_define(const String& p_define) {
|
||||
custom_defines.push_back(p_define.utf8());
|
||||
}
|
||||
|
||||
virtual ~ShaderGLES3();
|
||||
|
||||
};
|
||||
|
|
|
@ -68,24 +68,26 @@ layout(std140) uniform SceneData { //ubo:0
|
|||
|
||||
uniform highp mat4 world_transform;
|
||||
|
||||
#ifdef USE_FORWARD_LIGHTING
|
||||
#ifdef USE_LIGHT_DIRECTIONAL
|
||||
|
||||
layout(std140) uniform LightData { //ubo:3
|
||||
layout(std140) uniform DirectionalLightData { //ubo:3
|
||||
|
||||
highp vec4 light_pos_inv_radius;
|
||||
mediump vec4 light_direction_attenuation;
|
||||
mediump vec4 light_color_energy;
|
||||
mediump vec4 light_params; //cone attenuation, specular, shadow darkening,
|
||||
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
|
||||
mediump vec4 light_clamp;
|
||||
mediump vec4 shadow_split_offsets;
|
||||
mediump vec4 shadow_color;
|
||||
highp mat4 shadow_matrix1;
|
||||
highp mat4 shadow_matrix2;
|
||||
highp mat4 shadow_matrix3;
|
||||
highp mat4 shadow_matrix4;
|
||||
mediump vec4 shadow_split_offsets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Varyings */
|
||||
|
||||
out highp vec3 vertex_interp;
|
||||
|
@ -343,30 +345,71 @@ layout(std140) uniform SceneData {
|
|||
|
||||
};
|
||||
|
||||
//directional light data
|
||||
|
||||
#ifdef USE_FORWARD_LIGHTING
|
||||
#ifdef USE_LIGHT_DIRECTIONAL
|
||||
|
||||
layout(std140) uniform LightData {
|
||||
layout(std140) uniform DirectionalLightData {
|
||||
|
||||
highp vec4 light_pos_inv_radius;
|
||||
mediump vec4 light_direction_attenuation;
|
||||
mediump vec4 light_color_energy;
|
||||
mediump vec4 light_params; //cone attenuation, specular, shadow darkening, shadow enabled
|
||||
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
|
||||
mediump vec4 light_clamp;
|
||||
mediump vec4 shadow_split_offsets;
|
||||
mediump vec4 shadow_color;
|
||||
highp mat4 shadow_matrix1;
|
||||
highp mat4 shadow_matrix2;
|
||||
highp mat4 shadow_matrix3;
|
||||
highp mat4 shadow_matrix4;
|
||||
mediump vec4 shadow_split_offsets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
uniform highp sampler2DShadow directional_shadow; //texunit:-4
|
||||
|
||||
#endif
|
||||
|
||||
//omni and spot
|
||||
|
||||
struct LightData {
|
||||
|
||||
highp vec4 light_pos_inv_radius;
|
||||
mediump vec4 light_direction_attenuation;
|
||||
mediump vec4 light_color_energy;
|
||||
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
|
||||
mediump vec4 light_clamp;
|
||||
mediump vec4 shadow_color;
|
||||
highp mat4 shadow_matrix;
|
||||
|
||||
};
|
||||
|
||||
|
||||
layout(std140) uniform OmniLightData { //ubo:4
|
||||
|
||||
LightData omni_lights[MAX_LIGHT_DATA_STRUCTS];
|
||||
};
|
||||
|
||||
layout(std140) uniform SpotLightData { //ubo:5
|
||||
|
||||
LightData spot_lights[MAX_LIGHT_DATA_STRUCTS];
|
||||
};
|
||||
|
||||
|
||||
uniform highp sampler2DShadow shadow_atlas; //texunit:-3
|
||||
|
||||
|
||||
#ifdef USE_FORWARD_LIGHTING
|
||||
|
||||
uniform int omni_light_indices[MAX_FORWARD_LIGHTS];
|
||||
uniform int omni_light_count;
|
||||
|
||||
uniform int spot_light_indices[MAX_FORWARD_LIGHTS];
|
||||
uniform int spot_light_count;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef USE_MULTIPLE_RENDER_TARGETS
|
||||
|
||||
layout(location=0) out vec4 diffuse_buffer;
|
||||
|
@ -415,18 +458,51 @@ float specularGGX(vec3 N, vec3 V, vec3 L, float roughness, float F0)
|
|||
return dotNL * D * F * vis;
|
||||
}
|
||||
|
||||
void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 diffuse_color, vec3 specular_color, float roughness, float attenuation, inout vec3 diffuse, inout vec3 specular) {
|
||||
void light_compute(vec3 normal, vec3 light_vec,vec3 eye_vec,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float roughness, inout vec3 diffuse, inout vec3 specular) {
|
||||
|
||||
diffuse += max(0.0,dot(normal,light_vec)) * diffuse_color * attenuation;
|
||||
diffuse += max(0.0,dot(normal,light_vec)) * light_color * diffuse_color;
|
||||
//specular += specular_ggx( roughness, max(0.0,dot(normal,eye_vec)) ) * specular_color * attenuation;
|
||||
float s = roughness > 0.0 ? specularGGX(normal,eye_vec,light_vec,roughness,1.0) : 0.0;
|
||||
specular += s * specular_color * attenuation;
|
||||
specular += s * light_color * specular_color;
|
||||
}
|
||||
|
||||
|
||||
float sample_shadow(highp sampler2DShadow shadow, vec2 shadow_pixel_size, vec2 pos, float depth, vec4 clamp_rect) {
|
||||
|
||||
#ifdef SHADOW_MODE_PCF_13
|
||||
|
||||
float avg=textureProj(shadow,vec4(pos,depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,-shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x*2.0,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x*2.0,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y*2.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y*2.0),depth,1.0));
|
||||
return avg*(1.0/13.0);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_MODE_PCF_5
|
||||
|
||||
float avg=textureProj(shadow,vec4(pos,depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(shadow_pixel_size.x,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(-shadow_pixel_size.x,0.0),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,shadow_pixel_size.y),depth,1.0));
|
||||
avg+=textureProj(shadow,vec4(pos+vec2(0.0,-shadow_pixel_size.y),depth,1.0));
|
||||
return avg*(1.0/5.0);
|
||||
#endif
|
||||
|
||||
#if !defined(SHADOW_MODE_PCF_5) && !defined(SHADOW_MODE_PCF_13)
|
||||
|
||||
return textureProj(shadow,vec4(pos,depth,1.0));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef RENDER_SHADOW_DUAL_PARABOLOID
|
||||
|
@ -435,6 +511,73 @@ in highp float dp_clip;
|
|||
|
||||
#endif
|
||||
|
||||
void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
|
||||
float normalized_distance = length( light_rel_vec )*omni_lights[idx].light_pos_inv_radius.w;
|
||||
vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w ));
|
||||
|
||||
if (omni_lights[idx].light_params.w>0.5) {
|
||||
//there is a shadowmap
|
||||
|
||||
highp vec3 splane=(omni_lights[idx].shadow_matrix * vec4(vertex,1.0)).xyz;
|
||||
float shadow_len=length(splane);
|
||||
splane=normalize(splane);
|
||||
vec4 clamp_rect=omni_lights[idx].light_clamp;
|
||||
|
||||
if (splane.z>=0.0) {
|
||||
|
||||
splane.z+=1.0;
|
||||
|
||||
clamp_rect.y+=clamp_rect.w;
|
||||
|
||||
} else {
|
||||
|
||||
splane.z=1.0 - splane.z;
|
||||
|
||||
//if (clamp_rect.z<clamp_rect.w) {
|
||||
// clamp_rect.x+=clamp_rect.z;
|
||||
//} else {
|
||||
// clamp_rect.y+=clamp_rect.w;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
splane.xy/=splane.z;
|
||||
splane.xy=splane.xy * 0.5 + 0.5;
|
||||
splane.z = shadow_len * omni_lights[idx].light_pos_inv_radius.w;
|
||||
|
||||
splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw;
|
||||
|
||||
light_attenuation*=mix(omni_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect));
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
|
||||
|
||||
}
|
||||
|
||||
void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 albedo, vec3 specular, float roughness, inout vec3 diffuse_light, inout vec3 specular_light) {
|
||||
|
||||
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
|
||||
float normalized_distance = length( light_rel_vec )*spot_lights[idx].light_pos_inv_radius.w;
|
||||
vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), spot_lights[idx].light_direction_attenuation.w ));
|
||||
vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz;
|
||||
float spot_cutoff=spot_lights[idx].light_params.y;
|
||||
float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff);
|
||||
float rim = (1.0 - scos) / (1.0 - spot_cutoff);
|
||||
light_attenuation *= 1.0 - pow( rim, spot_lights[idx].light_params.x);
|
||||
|
||||
if (spot_lights[idx].light_params.w>0.5) {
|
||||
//there is a shadowmap
|
||||
highp vec4 splane=(spot_lights[idx].shadow_matrix * vec4(vertex,1.0));
|
||||
splane.xyz/=splane.w;
|
||||
light_attenuation*=mix(spot_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp));
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
|
||||
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef RENDER_SHADOW_DUAL_PARABOLOID
|
||||
|
@ -561,9 +704,9 @@ FRAGMENT_SHADER_CODE
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef USE_FORWARD_DIRECTIONAL
|
||||
#ifdef USE_LIGHT_DIRECTIONAL
|
||||
|
||||
float light_attenuation=1.0;
|
||||
vec3 light_attenuation=vec3(1.0);
|
||||
|
||||
#ifdef LIGHT_DIRECTIONAL_SHADOW
|
||||
|
||||
|
@ -589,7 +732,6 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
ambient_light=vec3(1.0,0.4,0.4);
|
||||
|
||||
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
|
@ -603,7 +745,6 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
ambient_light=vec3(0.4,1.0,0.4);
|
||||
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
splane=(shadow_matrix3 * vec4(vertex,1.0));
|
||||
|
@ -619,7 +760,6 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0));
|
||||
pssm_coord=splane.xyz/splane.w;
|
||||
ambient_light=vec3(0.4,0.4,1.0);
|
||||
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
splane=(shadow_matrix4 * vec4(vertex,1.0));
|
||||
|
@ -678,12 +818,12 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
|
||||
//one one sample
|
||||
light_attenuation=sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp);
|
||||
light_attenuation=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp));
|
||||
|
||||
|
||||
#if defined(LIGHT_USE_PSSM_BLEND)
|
||||
if (use_blend) {
|
||||
float light_attenuation2=sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp);
|
||||
vec3 light_attenuation2=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp));
|
||||
light_attenuation=mix(light_attenuation,light_attenuation2,pssm_blend);
|
||||
}
|
||||
#endif
|
||||
|
@ -692,85 +832,25 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
#endif //LIGHT_DIRECTIONAL_SHADOW
|
||||
|
||||
light_compute(normal,-light_direction_attenuation.xyz,eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
|
||||
light_compute(normal,-light_direction_attenuation.xyz,eye_vec,light_color_energy.rgb*light_attenuation,albedo,specular,roughness,diffuse_light,specular_light);
|
||||
|
||||
|
||||
#endif //USE_FORWARD_DIRECTIONAL
|
||||
#endif //#USE_LIGHT_DIRECTIONAL
|
||||
|
||||
|
||||
#ifdef USE_FORWARD_OMNI
|
||||
|
||||
vec3 light_rel_vec = light_pos_inv_radius.xyz-vertex;
|
||||
float normalized_distance = length( light_rel_vec )*light_pos_inv_radius.w;
|
||||
float light_attenuation = pow( max(1.0 - normalized_distance, 0.0), light_direction_attenuation.w );
|
||||
|
||||
if (light_params.w>0.5) {
|
||||
//there is a shadowmap
|
||||
|
||||
highp vec3 splane=(shadow_matrix1 * vec4(vertex,1.0)).xyz;
|
||||
float shadow_len=length(splane);
|
||||
splane=normalize(splane);
|
||||
vec4 clamp_rect=light_clamp;
|
||||
|
||||
if (splane.z>=0.0) {
|
||||
|
||||
splane.z+=1.0;
|
||||
|
||||
clamp_rect.y+=clamp_rect.w;
|
||||
|
||||
} else {
|
||||
|
||||
splane.z=1.0 - splane.z;
|
||||
|
||||
//if (clamp_rect.z<clamp_rect.w) {
|
||||
// clamp_rect.x+=clamp_rect.z;
|
||||
//} else {
|
||||
// clamp_rect.y+=clamp_rect.w;
|
||||
//}
|
||||
#ifdef USE_FORWARD_LIGHTING
|
||||
|
||||
for(int i=0;i<omni_light_count;i++) {
|
||||
light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light);
|
||||
}
|
||||
|
||||
splane.xy/=splane.z;
|
||||
splane.xy=splane.xy * 0.5 + 0.5;
|
||||
splane.z = shadow_len * light_pos_inv_radius.w;
|
||||
|
||||
splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw;
|
||||
|
||||
light_attenuation*=sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect);
|
||||
for(int i=0;i<spot_light_count;i++) {
|
||||
light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,albedo,specular,roughness,diffuse_light,specular_light);
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
|
||||
#endif
|
||||
|
||||
|
||||
#endif //USE_FORWARD_OMNI
|
||||
|
||||
#ifdef USE_FORWARD_SPOT
|
||||
|
||||
vec3 light_rel_vec = light_pos_inv_radius.xyz-vertex;
|
||||
float normalized_distance = length( light_rel_vec )*light_pos_inv_radius.w;
|
||||
float light_attenuation = pow( max(1.0 - normalized_distance, 0.0), light_direction_attenuation.w );
|
||||
vec3 spot_dir = light_direction_attenuation.xyz;
|
||||
float spot_cutoff=light_params.y;
|
||||
float scos = max(dot(-normalize(light_rel_vec), spot_dir),spot_cutoff);
|
||||
float rim = (1.0 - scos) / (1.0 - spot_cutoff);
|
||||
light_attenuation *= 1.0 - pow( rim, light_params.x);
|
||||
|
||||
if (light_params.w>0.5) {
|
||||
//there is a shadowmap
|
||||
|
||||
highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0));
|
||||
splane.xyz/=splane.w;
|
||||
// splane.xy=splane.xy*0.5+0.5;
|
||||
|
||||
//splane.xy=light_clamp.xy+splane.xy*light_clamp.zw;
|
||||
light_attenuation*=sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,light_clamp);
|
||||
|
||||
}
|
||||
|
||||
light_compute(normal,normalize(light_rel_vec),eye_vec,albedo,specular,roughness,light_attenuation,diffuse_light,specular_light);
|
||||
|
||||
#endif //USE_FORWARD_SPOT
|
||||
|
||||
|
||||
|
||||
#if defined(USE_LIGHT_SHADER_CODE)
|
||||
|
|
|
@ -102,6 +102,17 @@ Color Light::get_color() const{
|
|||
return color;
|
||||
}
|
||||
|
||||
void Light::set_shadow_color(const Color& p_shadow_color){
|
||||
|
||||
shadow_color=p_shadow_color;
|
||||
VS::get_singleton()->light_set_shadow_color(light,p_shadow_color);
|
||||
}
|
||||
|
||||
Color Light::get_shadow_color() const{
|
||||
|
||||
return shadow_color;
|
||||
}
|
||||
|
||||
|
||||
AABB Light::get_aabb() const {
|
||||
|
||||
|
@ -197,18 +208,18 @@ void Light::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_color","color"), &Light::set_color );
|
||||
ObjectTypeDB::bind_method(_MD("get_color"), &Light::get_color );
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color"), _SCS("set_color"), _SCS("get_color"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask"), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/darkness"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_DARKNESS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/normal_bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias_split_scale"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"), &Light::set_shadow_color );
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_color"), &Light::get_shadow_color );
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "light/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_color"), _SCS("get_color"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_ENERGY);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "light/negative"), _SCS("set_negative"), _SCS("is_negative"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "light/specular",PROPERTY_HINT_RANGE,"0,1,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SPECULAR);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "shadow/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_shadow_color"), _SCS("get_shadow_color"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
|
||||
|
||||
BIND_CONSTANT( PARAM_ENERGY );
|
||||
|
@ -218,7 +229,6 @@ void Light::_bind_methods() {
|
|||
BIND_CONSTANT( PARAM_SPOT_ANGLE );
|
||||
BIND_CONSTANT( PARAM_SPOT_ATTENUATION );
|
||||
BIND_CONSTANT( PARAM_SHADOW_MAX_DISTANCE );
|
||||
BIND_CONSTANT( PARAM_SHADOW_DARKNESS );
|
||||
BIND_CONSTANT( PARAM_SHADOW_SPLIT_1_OFFSET );
|
||||
BIND_CONSTANT( PARAM_SHADOW_SPLIT_2_OFFSET );
|
||||
BIND_CONSTANT( PARAM_SHADOW_SPLIT_3_OFFSET );
|
||||
|
@ -250,7 +260,6 @@ Light::Light(VisualServer::LightType p_type) {
|
|||
set_param(PARAM_SPOT_ANGLE,45);
|
||||
set_param(PARAM_SPOT_ATTENUATION,1);
|
||||
set_param(PARAM_SHADOW_MAX_DISTANCE,0);
|
||||
set_param(PARAM_SHADOW_DARKNESS,0);
|
||||
set_param(PARAM_SHADOW_SPLIT_1_OFFSET,0.1);
|
||||
set_param(PARAM_SHADOW_SPLIT_2_OFFSET,0.2);
|
||||
set_param(PARAM_SHADOW_SPLIT_3_OFFSET,0.5);
|
||||
|
@ -291,6 +300,7 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
|
|||
void DirectionalLight::set_blend_splits(bool p_enable) {
|
||||
|
||||
blend_splits=p_enable;
|
||||
VS::get_singleton()->light_directional_set_blend_splits(light,p_enable);
|
||||
}
|
||||
|
||||
bool DirectionalLight::is_blend_splits_enabled() const {
|
||||
|
@ -307,11 +317,13 @@ void DirectionalLight::_bind_methods() {
|
|||
ObjectTypeDB::bind_method( _MD("set_blend_splits","enabled"),&DirectionalLight::set_blend_splits);
|
||||
ObjectTypeDB::bind_method( _MD("is_blend_splits_enabled"),&DirectionalLight::is_blend_splits_enabled);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "directional/shadow_mode",PROPERTY_HINT_ENUM,"Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_2"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional/split_3"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "directional/blend_splits"), _SCS("set_blend_splits"), _SCS("is_blend_splits_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "directional_shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,PSSM 2 Splits,PSSM 4 Splits"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_1",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_1_OFFSET);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_2",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_2_OFFSET);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/split_3",PROPERTY_HINT_RANGE,"0,1,0.001"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_SPLIT_3_OFFSET);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "directional_shadow/blend_splits"), _SCS("set_blend_splits"), _SCS("is_blend_splits_enabled"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/normal_bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_NORMAL_BIAS);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "directional_shadow/bias_split_scale",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS_SPLIT_SCALE);
|
||||
|
||||
BIND_CONSTANT( SHADOW_ORTHOGONAL );
|
||||
BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
|
||||
|
@ -358,8 +370,8 @@ void OmniLight::_bind_methods() {
|
|||
ObjectTypeDB::bind_method( _MD("set_shadow_detail","detail"),&OmniLight::set_shadow_detail);
|
||||
ObjectTypeDB::bind_method( _MD("get_shadow_detail"),&OmniLight::get_shadow_detail);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "omni/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_mode",PROPERTY_HINT_ENUM,"Dual Paraboloid,Cube"), _SCS("set_shadow_mode"), _SCS("get_shadow_mode"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "omni/shadow_detail",PROPERTY_HINT_ENUM,"Vertical,Horizontal"), _SCS("set_shadow_detail"), _SCS("get_shadow_detail"));
|
||||
|
||||
|
@ -374,10 +386,10 @@ OmniLight::OmniLight() : Light( VisualServer::LIGHT_OMNI ) {
|
|||
|
||||
void SpotLight::_bind_methods() {
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/range"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_angle"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_attenuation"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/range",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_RANGE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_ATTENUATION);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_angle",PROPERTY_HINT_RANGE,"0,180,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ANGLE);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "spot/spot_attenuation",PROPERTY_HINT_EXP_EASING), _SCS("set_param"), _SCS("get_param"), PARAM_SPOT_ATTENUATION);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ public:
|
|||
PARAM_SPOT_ANGLE = VS::LIGHT_PARAM_SPOT_ANGLE,
|
||||
PARAM_SPOT_ATTENUATION = VS::LIGHT_PARAM_SPOT_ATTENUATION,
|
||||
PARAM_SHADOW_MAX_DISTANCE = VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE,
|
||||
PARAM_SHADOW_DARKNESS = VS::LIGHT_PARAM_SHADOW_DARKNESS,
|
||||
PARAM_SHADOW_SPLIT_1_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
|
||||
PARAM_SHADOW_SPLIT_2_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
|
||||
PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
|
||||
|
@ -66,6 +65,7 @@ private:
|
|||
|
||||
Color color;
|
||||
float param[PARAM_MAX];
|
||||
Color shadow_color;
|
||||
bool shadow;
|
||||
bool negative;
|
||||
uint32_t cull_mask;
|
||||
|
@ -107,6 +107,9 @@ public:
|
|||
void set_color(const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
void set_shadow_color(const Color& p_shadow_color);
|
||||
Color get_shadow_color() const;
|
||||
|
||||
|
||||
virtual AABB get_aabb() const;
|
||||
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
|
||||
|
|
|
@ -78,6 +78,7 @@ public:
|
|||
Transform transform;
|
||||
|
||||
int depth_layer;
|
||||
uint32_t layer_mask;
|
||||
|
||||
//RID sampled_light;
|
||||
|
||||
|
@ -114,6 +115,7 @@ public:
|
|||
billboard=false;
|
||||
billboard_y=false;
|
||||
depth_layer=0;
|
||||
layer_mask=1;
|
||||
|
||||
}
|
||||
};
|
||||
|
@ -295,16 +297,17 @@ public:
|
|||
virtual void light_set_color(RID p_light,const Color& p_color)=0;
|
||||
virtual void light_set_param(RID p_light,VS::LightParam p_param,float p_value)=0;
|
||||
virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
|
||||
virtual void light_set_shadow_color(RID p_light,const Color& p_color)=0;
|
||||
virtual void light_set_projector(RID p_light,RID p_texture)=0;
|
||||
virtual void light_set_attenuation_texure(RID p_light,RID p_texture)=0;
|
||||
virtual void light_set_negative(RID p_light,bool p_enable)=0;
|
||||
virtual void light_set_cull_mask(RID p_light,uint32_t p_mask)=0;
|
||||
virtual void light_set_shader(RID p_light,RID p_shader)=0;
|
||||
|
||||
virtual void light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode)=0;
|
||||
virtual void light_omni_set_shadow_detail(RID p_light,VS::LightOmniShadowDetail p_detail)=0;
|
||||
|
||||
virtual void light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode)=0;
|
||||
virtual void light_directional_set_blend_splits(RID p_light,bool p_enable)=0;
|
||||
virtual bool light_directional_get_blend_splits(RID p_light) const=0;
|
||||
|
||||
virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light)=0;
|
||||
virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light)=0;
|
||||
|
|
|
@ -757,16 +757,16 @@ public:
|
|||
BIND2(light_set_color,RID,const Color&)
|
||||
BIND3(light_set_param,RID ,LightParam ,float )
|
||||
BIND2(light_set_shadow,RID ,bool )
|
||||
BIND2(light_set_shadow_color,RID ,const Color& )
|
||||
BIND2(light_set_projector,RID,RID )
|
||||
BIND2(light_set_attenuation_texure,RID,RID )
|
||||
BIND2(light_set_negative,RID,bool )
|
||||
BIND2(light_set_cull_mask,RID ,uint32_t )
|
||||
BIND2(light_set_shader,RID ,RID )
|
||||
|
||||
BIND2(light_omni_set_shadow_mode,RID,LightOmniShadowMode)
|
||||
BIND2(light_omni_set_shadow_detail,RID,LightOmniShadowDetail)
|
||||
|
||||
BIND2(light_directional_set_shadow_mode,RID,LightDirectionalShadowMode)
|
||||
BIND2(light_directional_set_blend_splits,RID,bool)
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
|
|
|
@ -1165,7 +1165,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance,Camer
|
|||
|
||||
float texture_size=VSG::scene_render->get_directional_light_shadow_size(light->instance);
|
||||
|
||||
bool overlap = false;//rasterizer->light_instance_get_pssm_shadow_overlap(p_light->light_info->instance);
|
||||
bool overlap = VSG::storage->light_directional_get_blend_splits(p_instance->base);
|
||||
|
||||
for (int i=0;i<splits;i++) {
|
||||
|
||||
|
|
|
@ -204,7 +204,6 @@ public:
|
|||
float extra_margin;
|
||||
uint32_t object_ID;
|
||||
bool visible;
|
||||
uint32_t layer_mask;
|
||||
|
||||
float lod_begin;
|
||||
float lod_end;
|
||||
|
@ -253,7 +252,6 @@ public:
|
|||
|
||||
object_ID=0;
|
||||
visible=true;
|
||||
layer_mask=1;
|
||||
|
||||
lod_begin=0;
|
||||
lod_end=0;
|
||||
|
|
|
@ -357,7 +357,6 @@ public:
|
|||
LIGHT_PARAM_SPOT_ANGLE,
|
||||
LIGHT_PARAM_SPOT_ATTENUATION,
|
||||
LIGHT_PARAM_SHADOW_MAX_DISTANCE,
|
||||
LIGHT_PARAM_SHADOW_DARKNESS,
|
||||
LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET,
|
||||
LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET,
|
||||
LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
|
||||
|
@ -372,11 +371,10 @@ public:
|
|||
virtual void light_set_color(RID p_light,const Color& p_color)=0;
|
||||
virtual void light_set_param(RID p_light,LightParam p_param,float p_value)=0;
|
||||
virtual void light_set_shadow(RID p_light,bool p_enabled)=0;
|
||||
virtual void light_set_shadow_color(RID p_light,const Color& p_color)=0;
|
||||
virtual void light_set_projector(RID p_light,RID p_texture)=0;
|
||||
virtual void light_set_attenuation_texure(RID p_light,RID p_texture)=0;
|
||||
virtual void light_set_negative(RID p_light,bool p_enable)=0;
|
||||
virtual void light_set_cull_mask(RID p_light,uint32_t p_mask)=0;
|
||||
virtual void light_set_shader(RID p_light,RID p_shader)=0;
|
||||
|
||||
// omni light
|
||||
enum LightOmniShadowMode {
|
||||
|
@ -402,6 +400,7 @@ public:
|
|||
};
|
||||
|
||||
virtual void light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode)=0;
|
||||
virtual void light_directional_set_blend_splits(RID p_light,bool p_enable)=0;
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
|
|
Loading…
Reference in New Issue