summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--scene/3d/gi_probe.cpp101
-rw-r--r--scene/3d/gi_probe.h7
-rw-r--r--scene/resources/material.cpp2
-rw-r--r--scene/resources/texture.cpp5
-rw-r--r--servers/visual/rasterizer.h5
-rw-r--r--servers/visual/visual_server_raster.h3
-rw-r--r--servers/visual/visual_server_scene.cpp6
-rw-r--r--servers/visual_server.h3
13 files changed, 215 insertions, 66 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) {
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 1d40202318..e3c8ba09fc 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -64,6 +64,19 @@ float GIProbeData::get_energy() const{
}
+
+void GIProbeData::set_bias(float p_range) {
+
+ VS::get_singleton()->gi_probe_set_bias(probe,p_range);
+}
+
+float GIProbeData::get_bias() const{
+
+ return VS::get_singleton()->gi_probe_get_bias(probe);
+
+}
+
+
void GIProbeData::set_propagation(float p_range) {
VS::get_singleton()->gi_probe_set_propagation(probe,p_range);
@@ -133,6 +146,9 @@ void GIProbeData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_energy","energy"),&GIProbeData::set_energy);
ClassDB::bind_method(D_METHOD("get_energy"),&GIProbeData::get_energy);
+ ClassDB::bind_method(D_METHOD("set_bias","bias"),&GIProbeData::set_bias);
+ ClassDB::bind_method(D_METHOD("get_bias"),&GIProbeData::get_bias);
+
ClassDB::bind_method(D_METHOD("set_propagation","propagation"),&GIProbeData::set_propagation);
ClassDB::bind_method(D_METHOD("get_propagation"),&GIProbeData::get_propagation);
@@ -149,6 +165,7 @@ void GIProbeData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_INT_ARRAY,"dynamic_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_dynamic_data","get_dynamic_data");
ADD_PROPERTY(PropertyInfo(Variant::INT,"dynamic_range",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_dynamic_range","get_dynamic_range");
ADD_PROPERTY(PropertyInfo(Variant::REAL,"energy",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_energy","get_energy");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL,"bias",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_bias","get_bias");
ADD_PROPERTY(PropertyInfo(Variant::REAL,"propagation",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_propagation","get_propagation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"interior",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_interior","is_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"compress",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),"set_compress","is_compressed");
@@ -230,6 +247,18 @@ float GIProbe::get_energy() const {
return energy;
}
+void GIProbe::set_bias(float p_bias) {
+
+ bias=p_bias;
+ if (probe_data.is_valid()) {
+ probe_data->set_bias(bias);
+ }
+}
+float GIProbe::get_bias() const {
+
+ return bias;
+}
+
void GIProbe::set_propagation(float p_propagation) {
propagation=p_propagation;
@@ -466,7 +495,8 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V
int closest_axis;
float closest_dot;
- Vector3 normal = Plane(p_vtx[0],p_vtx[1],p_vtx[2]).normal;
+ Plane plane = Plane(p_vtx[0],p_vtx[1],p_vtx[2]);
+ Vector3 normal = plane.normal;
for(int i=0;i<3;i++) {
@@ -479,6 +509,7 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V
}
}
+
Vector3 axis;
axis[closest_axis]=1.0;
Vector3 t1;
@@ -517,30 +548,23 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V
Vector3 ray_from = from + (t1+t2)*0.5 - axis * p_aabb.size[closest_axis];
Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis]*2;
+ if (normal.dot(ray_from-ray_to)<0) {
+ SWAP(ray_from,ray_to);
+ }
+
Vector3 intersection;
- if (!Geometry::ray_intersects_triangle(ray_from,ray_to,p_vtx[0],p_vtx[1],p_vtx[2],&intersection)) {
- //no intersect? look in edges
-
- float closest_dist=1e20;
- for(int j=0;j<3;j++) {
- Vector3 c;
- Vector3 inters;
- Geometry::get_closest_points_between_segments(p_vtx[j],p_vtx[(j+1)%3],ray_from,ray_to,inters,c);
- if (c==inters) {
- closest_dist=0;
- intersection=inters;
-
- } else {
- float d=c.distance_to(intersection);
- if (j==0 || d<closest_dist) {
- closest_dist=d;
- intersection=inters;
- }
- }
+ if (!plane.intersects_segment(ray_from,ray_to,&intersection)) {
+ if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) {
+ intersection = plane.project(ray_from);
+ } else {
+
+ intersection = plane.project(ray_to);
}
}
+ intersection=Face3(p_vtx[0],p_vtx[1],p_vtx[2]).get_closest_point_to(intersection);
+
Vector2 uv = get_uv(intersection,p_vtx,p_uv);
@@ -1245,26 +1269,30 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug){
}
- Ref<GIProbeData> probe_data;
- probe_data.instance();
- probe_data->set_bounds(Rect3(-extents,extents*2.0));
- probe_data->set_cell_size(baker.po2_bounds.size[longest_axis]/baker.axis_cell_size[longest_axis]);
- probe_data->set_dynamic_data(data);
- probe_data->set_dynamic_range(dynamic_range);
- probe_data->set_energy(energy);
- probe_data->set_interior(interior);
- probe_data->set_compress(compress);
- probe_data->set_to_cell_xform(baker.to_cell_space);
-
- set_probe_data(probe_data);
+ if (p_create_visual_debug) {
+ _create_debug_mesh(&baker);
+ } else {
+ Ref<GIProbeData> probe_data;
+ probe_data.instance();
+ probe_data->set_bounds(Rect3(-extents,extents*2.0));
+ probe_data->set_cell_size(baker.po2_bounds.size[longest_axis]/baker.axis_cell_size[longest_axis]);
+ probe_data->set_dynamic_data(data);
+ probe_data->set_dynamic_range(dynamic_range);
+ probe_data->set_energy(energy);
+ probe_data->set_bias(bias);
+ probe_data->set_propagation(propagation);
+ probe_data->set_interior(interior);
+ probe_data->set_compress(compress);
+ probe_data->set_to_cell_xform(baker.to_cell_space);
- if (p_create_visual_debug) {
- //_create_debug_mesh(&baker);
+ set_probe_data(probe_data);
}
+
+
}
@@ -1436,6 +1464,9 @@ void GIProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_energy","max"),&GIProbe::set_energy);
ClassDB::bind_method(D_METHOD("get_energy"),&GIProbe::get_energy);
+ ClassDB::bind_method(D_METHOD("set_bias","max"),&GIProbe::set_bias);
+ ClassDB::bind_method(D_METHOD("get_bias"),&GIProbe::get_bias);
+
ClassDB::bind_method(D_METHOD("set_propagation","max"),&GIProbe::set_propagation);
ClassDB::bind_method(D_METHOD("get_propagation"),&GIProbe::get_propagation);
@@ -1454,6 +1485,7 @@ void GIProbe::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::INT,"dynamic_range",PROPERTY_HINT_RANGE,"1,16,1"),"set_dynamic_range","get_dynamic_range");
ADD_PROPERTY( PropertyInfo(Variant::REAL,"energy",PROPERTY_HINT_RANGE,"0,16,0.01"),"set_energy","get_energy");
ADD_PROPERTY( PropertyInfo(Variant::REAL,"propagation",PROPERTY_HINT_RANGE,"0,1,0.01"),"set_propagation","get_propagation");
+ ADD_PROPERTY( PropertyInfo(Variant::REAL,"bias",PROPERTY_HINT_RANGE,"0,4,0.001"),"set_bias","get_bias");
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"interior"),"set_interior","is_interior");
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"compress"),"set_compress","is_compressed");
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"data",PROPERTY_HINT_RESOURCE_TYPE,"GIProbeData"),"set_probe_data","get_probe_data");
@@ -1471,6 +1503,7 @@ GIProbe::GIProbe() {
subdiv=SUBDIV_128;
dynamic_range=4;
energy=1.0;
+ bias=0.4;
propagation=1.0;
extents=Vector3(10,10,10);
color_scan_cell_width=4;
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index f03a558908..0f003d7cb1 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -38,6 +38,9 @@ public:
void set_energy(float p_range);
float get_energy() const;
+ void set_bias(float p_range);
+ float get_bias() const;
+
void set_interior(bool p_enable);
bool is_interior() const;
@@ -137,6 +140,7 @@ private:
Vector3 extents;
int dynamic_range;
float energy;
+ float bias;
float propagation;
bool interior;
bool compress;
@@ -176,6 +180,9 @@ public:
void set_energy(float p_energy);
float get_energy() const;
+ void set_bias(float p_bias);
+ float get_bias() const;
+
void set_propagation(float p_propagation);
float get_propagation() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index b7c8b1664d..3780c466a5 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -339,7 +339,7 @@ void FixedSpatialMaterial::_update_shader() {
code+="\tROUGHNESS = specular_tex.a * roughness;\n";
} else {
code+="\tvec4 specular_tex = texture(texture_specular,UV);\n";
- code+="\tSPECULAR = vec3(metalness * specular_tex.r);\n";
+ code+="\tSPECULAR = vec3(ALBEDO.rgb * metalness * specular_tex.r);\n";
code+="\tROUGHNESS = specular_tex.a * roughness;\n";
}
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index e3a856ad4f..62feb7b37c 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -559,6 +559,11 @@ Error StreamTexture::_load_data(const String& p_path,int &tw,int &th,int& flags,
int total_size=0;
for(int i=0;i<mipmaps;i++) {
+
+ if (i>0) {
+ size = f->get_32();
+ }
+
PoolVector<uint8_t> pv;
pv.resize(size);
{
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 21f7f0769f..dd22986865 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -432,6 +432,9 @@ public:
virtual void gi_probe_set_energy(RID p_probe,float p_range)=0;
virtual float gi_probe_get_energy(RID p_probe) const=0;
+ virtual void gi_probe_set_bias(RID p_probe,float p_range)=0;
+ virtual float gi_probe_get_bias(RID p_probe) const=0;
+
virtual void gi_probe_set_propagation(RID p_probe,float p_range)=0;
virtual float gi_probe_get_propagation(RID p_probe) const=0;
@@ -519,6 +522,8 @@ public:
virtual bool has_os_feature(const String& p_feature) const=0;
+ virtual void update_dirty_resources()=0;
+
static RasterizerStorage*base_signleton;
RasterizerStorage();
virtual ~RasterizerStorage() {}
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index ad0cb664c5..7d547e1862 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -825,6 +825,9 @@ public:
BIND2(gi_probe_set_energy,RID,float)
BIND1RC(float,gi_probe_get_energy,RID)
+ BIND2(gi_probe_set_bias,RID,float)
+ BIND1RC(float,gi_probe_get_bias,RID)
+
BIND2(gi_probe_set_propagation,RID,float)
BIND1RC(float,gi_probe_get_propagation,RID)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index c54f3dbca5..6f7b2e3aed 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1556,9 +1556,11 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance,const
cull_count--;
SWAP(instance_shadow_cull_result[j],instance_shadow_cull_result[cull_count]);
j--;
+ continue;
}
+
instance->transformed_aabb.project_range_in_plane(Plane(z_vec,0),min,max);
if (max>z_max)
z_max=max;
@@ -3475,6 +3477,7 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else if (p_instance->base_type==VS::INSTANCE_MULTIMESH) {
RID mesh = VSG::storage->multimesh_get_mesh(p_instance->base);
if (mesh.is_valid()) {
+
bool cast_shadows=false;
int sc = VSG::storage->mesh_get_surface_count(mesh);
@@ -3491,6 +3494,7 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
cast_shadows=true;
break;
}
+
}
if (!cast_shadows) {
@@ -3538,6 +3542,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
void VisualServerScene::update_dirty_instances() {
+ VSG::storage->update_dirty_resources();
+
while(_instance_update_list.first()) {
_update_dirty_instance( _instance_update_list.first()->self() );
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 5c835c2287..08cf34a653 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -475,6 +475,9 @@ public:
virtual void gi_probe_set_energy(RID p_probe,float p_range)=0;
virtual float gi_probe_get_energy(RID p_probe) const=0;
+ virtual void gi_probe_set_bias(RID p_probe,float p_range)=0;
+ virtual float gi_probe_get_bias(RID p_probe) const=0;
+
virtual void gi_probe_set_propagation(RID p_probe,float p_range)=0;
virtual float gi_probe_get_propagation(RID p_probe) const=0;