summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp7
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp18
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp83
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h21
-rw-r--r--drivers/gles3/shaders/scene.glsl20
5 files changed, 118 insertions, 31 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index e1ddad0dc9..eb58759c47 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -167,7 +167,6 @@ void RasterizerGLES3::initialize() {
void RasterizerGLES3::begin_frame(){
-
uint64_t tick = OS::get_singleton()->get_ticks_usec();
double time_total = double(tick)/1000000.0;
@@ -186,12 +185,8 @@ void RasterizerGLES3::begin_frame(){
storage->frame.prev_tick=tick;
+ storage->update_dirty_resources();
- storage->update_dirty_multimeshes();
- storage->update_dirty_skeletons();
- storage->update_dirty_shaders();
- storage->update_dirty_materials();
- storage->update_particles();
storage->info.render_object_count=0;
storage->info.render_material_switch_count=0;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index a0d486661b..bbbe9351ec 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1387,6 +1387,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
int amount = MAX(multi_mesh->size,multi_mesh->visible_instances);
+
if (s->index_array_len>0) {
glDrawElementsInstanced(gl_primitive[s->primitive],s->index_array_len, (s->array_len>=(1<<16))?GL_UNSIGNED_INT:GL_UNSIGNED_SHORT,0,amount);
@@ -1610,6 +1611,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform&
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER1, gipi->probe?gipi->probe->dynamic_range*gipi->probe->energy:0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS1, gipi->probe?gipi->probe->bias:0.0);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT1, gipi->probe?!gipi->probe->interior:false);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE1, gipi->cell_size_cache);
if (gi_probe_count>1) {
@@ -1622,6 +1624,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform&
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE2, gipi2->cell_size_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER2, gipi2->probe?gipi2->probe->dynamic_range*gipi2->probe->energy:0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS2, gipi2->probe?gipi2->probe->bias:0.0);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT2, gipi2->probe?!gipi2->probe->interior:false);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, true );
} else {
@@ -1939,6 +1942,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
if (e->owner != prev_owner || prev_base_type != e->instance->base_type || prev_geometry!=e->geometry) {
+
_setup_geometry(e);
storage->info.render_surface_switch_count++;
@@ -2881,6 +2885,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase** p_cull_result,int p_
RasterizerStorageGLES3::MultiMesh *multi_mesh = storage->multimesh_owner.getptr(inst->base);
ERR_CONTINUE(!multi_mesh);
+
if (multi_mesh->size==0 || multi_mesh->visible_instances==0)
continue;
@@ -2896,6 +2901,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase** p_cull_result,int p_
_add_geometry(s,inst,multi_mesh,-1,p_shadow);
}
+
} break;
case VS::INSTANCE_IMMEDIATE: {
@@ -3777,7 +3783,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
state.used_contact_shadows=true;
- if (storage->frame.current_rt && true) { //detect with state.used_contact_shadows too
+ if ( storage->frame.current_rt && true) { //detect with state.used_contact_shadows too
//pre z pass
@@ -4096,11 +4102,11 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
if (false && env_radiance_tex) {
- //_copy_texture_to_front_buffer(shadow_atlas->depth);
- storage->canvas->canvas_begin();
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D,env_radiance_tex);
- storage->canvas->draw_generic_textured_rect(Rect2(0,0,storage->frame.current_rt->width/2,storage->frame.current_rt->height/2),Rect2(0,0,1,1));
+ //_copy_texture_to_front_buffer(shadow_atlas->depth);
+ storage->canvas->canvas_begin();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D,env_radiance_tex);
+ storage->canvas->draw_generic_textured_rect(Rect2(0,0,storage->frame.current_rt->width/2,storage->frame.current_rt->height/2),Rect2(0,0,1,1));
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 06daebbf82..6ae7ef86c4 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2320,6 +2320,7 @@ void RasterizerStorageGLES3::_update_material(Material* material) {
bool is_animated = false;
if (material->shader && material->shader->mode==VS::SHADER_SPATIAL) {
+
if (!material->shader->spatial.uses_alpha && material->shader->spatial.blend_mode==Shader::Spatial::BLEND_MODE_MIX) {
can_cast_shadow=true;
}
@@ -2332,20 +2333,19 @@ void RasterizerStorageGLES3::_update_material(Material* material) {
is_animated=true;
}
- }
+ if (can_cast_shadow!=material->can_cast_shadow_cache || is_animated!=material->is_animated_cache) {
+ material->can_cast_shadow_cache=can_cast_shadow;
+ material->is_animated_cache=is_animated;
- if (can_cast_shadow!=material->can_cast_shadow_cache || is_animated!=material->is_animated_cache) {
- material->can_cast_shadow_cache=can_cast_shadow;
- material->is_animated_cache=is_animated;
+ for(Map<Geometry*,int>::Element *E=material->geometry_owners.front();E;E=E->next()) {
+ E->key()->material_changed_notify();
+ }
- for(Map<Geometry*,int>::Element *E=material->geometry_owners.front();E;E=E->next()) {
- E->key()->material_changed_notify();
- }
+ for(Map<RasterizerScene::InstanceBase*,int>::Element *E=material->instance_owners.front();E;E=E->next()) {
+ E->key()->base_material_changed();
+ }
- for(Map<RasterizerScene::InstanceBase*,int>::Element *E=material->instance_owners.front();E;E=E->next()) {
- E->key()->base_material_changed();
}
-
}
}
@@ -3619,8 +3619,23 @@ void RasterizerStorageGLES3::multimesh_set_mesh(RID p_multimesh,RID p_mesh){
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
+ if (multimesh->mesh.is_valid()) {
+ Mesh *mesh = mesh_owner.getornull(multimesh->mesh);
+ if (mesh) {
+ mesh->multimeshes.remove(&multimesh->mesh_list);
+ }
+ }
+
multimesh->mesh=p_mesh;
+
+ if (multimesh->mesh.is_valid()) {
+ Mesh *mesh = mesh_owner.getornull(multimesh->mesh);
+ if (mesh) {
+ mesh->multimeshes.add(&multimesh->mesh_list);
+ }
+ }
+
multimesh->dirty_aabb=true;
if (!multimesh->update_list.in_list()) {
@@ -4778,6 +4793,7 @@ RID RasterizerStorageGLES3::gi_probe_create() {
gip->dynamic_range=1.0;
gip->energy=1.0;
gip->propagation=1.0;
+ gip->bias=0.4;
gip->interior=false;
gip->compress=false;
gip->version=1;
@@ -4883,6 +4899,16 @@ void RasterizerStorageGLES3::gi_probe_set_energy(RID p_probe,float p_range){
}
+
+void RasterizerStorageGLES3::gi_probe_set_bias(RID p_probe,float p_range){
+
+ GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND(!gip);
+
+ gip->bias=p_range;
+
+}
+
void RasterizerStorageGLES3::gi_probe_set_propagation(RID p_probe,float p_range){
GIProbe *gip = gi_probe_owner.getornull(p_probe);
@@ -4936,6 +4962,15 @@ float RasterizerStorageGLES3::gi_probe_get_energy(RID p_probe) const{
return gip->energy;
}
+float RasterizerStorageGLES3::gi_probe_get_bias(RID p_probe) const{
+
+ const GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND_V(!gip,0);
+
+ return gip->bias;
+}
+
+
float RasterizerStorageGLES3::gi_probe_get_propagation(RID p_probe) const{
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
@@ -6265,6 +6300,18 @@ bool RasterizerStorageGLES3::free(RID p_rid){
mesh->instance_remove_deps();
mesh_clear(p_rid);
+ while(mesh->multimeshes.first()) {
+ MultiMesh *multimesh = mesh->multimeshes.first()->self();
+ multimesh->mesh=RID();
+ multimesh->dirty_aabb=true;
+ mesh->multimeshes.remove(mesh->multimeshes.first());
+
+ if (!multimesh->update_list.in_list()) {
+ multimesh_update_list.add(&multimesh->update_list);
+ }
+
+ }
+
mesh_owner.free(p_rid);
memdelete(mesh);
@@ -6274,9 +6321,17 @@ bool RasterizerStorageGLES3::free(RID p_rid){
MultiMesh *multimesh = multimesh_owner.get(p_rid);
multimesh->instance_remove_deps();
+ if (multimesh->mesh.is_valid()) {
+ Mesh *mesh = mesh_owner.getornull(multimesh->mesh);
+ if (mesh) {
+ mesh->multimeshes.remove(&multimesh->mesh_list);
+ }
+ }
+
multimesh_allocate(p_rid,0,VS::MULTIMESH_TRANSFORM_2D,VS::MULTIMESH_COLOR_NONE); //frees multimesh
update_dirty_multimeshes();
+
multimesh_owner.free(p_rid);
memdelete(multimesh);
} else if (immediate_owner.owns(p_rid)) {
@@ -6568,6 +6623,14 @@ void RasterizerStorageGLES3::finalize() {
}
+void RasterizerStorageGLES3::update_dirty_resources() {
+
+ update_dirty_multimeshes();
+ update_dirty_skeletons();
+ update_dirty_shaders();
+ update_dirty_materials();
+ update_particles();
+}
RasterizerStorageGLES3::RasterizerStorageGLES3()
{
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 07998886a8..e8cff3711c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -567,6 +567,7 @@ public:
virtual void material_changed_notify() {
mesh->instance_material_change_notify();
+ mesh->update_multimeshes();
}
Surface() {
@@ -591,6 +592,7 @@ public:
}
};
+ class MultiMesh;
struct Mesh : public GeometryOwner {
@@ -600,6 +602,17 @@ public:
VS::BlendShapeMode blend_shape_mode;
Rect3 custom_aabb;
mutable uint64_t last_pass;
+ SelfList<MultiMesh>::List multimeshes;
+
+ _FORCE_INLINE_ void update_multimeshes() {
+
+ SelfList<MultiMesh> *mm = multimeshes.first();
+ while(mm) {
+ mm->self()->instance_material_change_notify();
+ mm=mm->next();
+ }
+ }
+
Mesh() {
blend_shape_mode=VS::BLEND_SHAPE_MODE_NORMALIZED;
blend_shape_count=0;
@@ -659,6 +672,7 @@ public:
Vector<float> data;
Rect3 aabb;
SelfList<MultiMesh> update_list;
+ SelfList<MultiMesh> mesh_list;
GLuint buffer;
int visible_instances;
@@ -668,7 +682,7 @@ public:
bool dirty_aabb;
bool dirty_data;
- MultiMesh() : update_list(this) {
+ MultiMesh() : update_list(this), mesh_list(this) {
dirty_aabb=true;
dirty_data=true;
xform_floats=0;
@@ -921,6 +935,7 @@ public:
int dynamic_range;
float energy;
+ float bias;
float propagation;
bool interior;
bool compress;
@@ -954,6 +969,9 @@ public:
virtual void gi_probe_set_energy(RID p_probe,float p_range);
virtual float gi_probe_get_energy(RID p_probe) const;
+ virtual void gi_probe_set_bias(RID p_probe,float p_range);
+ virtual float gi_probe_get_bias(RID p_probe) const;
+
virtual void gi_probe_set_propagation(RID p_probe,float p_range);
virtual float gi_probe_get_propagation(RID p_probe) const;
@@ -1259,6 +1277,7 @@ public:
virtual bool has_os_feature(const String& p_feature) const;
+ virtual void update_dirty_resources();
RasterizerStorageGLES3();
};
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 200c0c0cac..3d81cc5a50 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -931,6 +931,7 @@ uniform highp mat4 gi_probe_xform1;
uniform highp vec3 gi_probe_bounds1;
uniform highp vec3 gi_probe_cell_size1;
uniform highp float gi_probe_multiplier1;
+uniform highp float gi_probe_bias1;
uniform bool gi_probe_blend_ambient1;
uniform mediump sampler3D gi_probe2; //texunit:-7
@@ -938,13 +939,14 @@ uniform highp mat4 gi_probe_xform2;
uniform highp vec3 gi_probe_bounds2;
uniform highp vec3 gi_probe_cell_size2;
uniform highp float gi_probe_multiplier2;
+uniform highp float gi_probe_bias2;
uniform bool gi_probe2_enabled;
uniform bool gi_probe_blend_ambient2;
-vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, bool blend_ambient, vec3 direction, float tan_half_angle, float max_distance) {
+vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, bool blend_ambient, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
- float dist = dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0;
+ float dist = p_bias;//1.0; //dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0;
float alpha=0.0;
vec3 color = vec3(0.0);
@@ -957,12 +959,14 @@ vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, b
dist += diameter * 0.5;
}
- //color.rgb = mix(color.rgb,mix(ambient,color.rgb,alpha),blend_ambient);
+ if (blend_ambient) {
+ color.rgb = mix(ambient,color.rgb,min(1.0,alpha/0.95));
+ }
return color;
}
-void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness, out vec4 out_spec, out vec4 out_diff) {
+void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias, out vec4 out_spec, out vec4 out_diff) {
@@ -1023,7 +1027,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
for(int i=0;i<MAX_CONE_DIRS;i++) {
vec3 dir = normalize( (probe_xform * vec4(pos + normal_mtx * cone_dirs[i],1.0)).xyz - probe_pos);
- light+=cone_weights[i] * voxel_cone_trace(probe,cell_size,probe_pos,ambient,blend_ambient,dir,cone_angle_tan,max_distance);
+ light+=cone_weights[i] * voxel_cone_trace(probe,cell_size,probe_pos,ambient,blend_ambient,dir,cone_angle_tan,max_distance,p_bias);
}
@@ -1033,7 +1037,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
//irradiance
- vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,max(min_ref_tan,tan(roughness * 0.5 * M_PI)) ,max_distance);
+ vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,max(min_ref_tan,tan(roughness * 0.5 * M_PI)) ,max_distance,p_bias);
irr_light *= multiplier;
//irr_light=vec3(0.0);
@@ -1064,11 +1068,11 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, in
out_specular = vec3(0.0);
- gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,spec_accum,diff_accum);
+ gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,spec_accum,diff_accum);
if (gi_probe2_enabled) {
- gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,spec_accum,diff_accum);
+ gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,spec_accum,diff_accum);
}
if (diff_accum.a>0.0) {