diff options
author | Juan Linietsky <reduzio@gmail.com> | 2016-12-22 10:00:15 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2016-12-22 10:00:15 -0300 |
commit | f9603d82365823938129e68823a19739a3dd0b23 (patch) | |
tree | ea679907dd39ad85fe3171e73fb149c910dc4b16 | |
parent | 37f558cd7b2308f6442f74c5265f12425d9887c8 (diff) |
can bake for omni and spotlight
store normal when baking
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 39 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 3 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 41 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 13 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 29 | ||||
-rw-r--r-- | scene/3d/gi_probe.cpp | 129 | ||||
-rw-r--r-- | scene/3d/gi_probe.h | 27 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 3 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 11 | ||||
-rw-r--r-- | servers/visual/visual_server_raster.h | 10 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 207 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.h | 4 | ||||
-rw-r--r-- | servers/visual_server.h | 10 |
14 files changed, 440 insertions, 92 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index cb42790e67..bf3b902c5c 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -130,9 +130,9 @@ void RasterizerGLES3::initialize() { ERR_PRINT("Error initializing GLAD"); } -// glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); -// glDebugMessageCallbackARB(_gl_debug_print, NULL); -// glEnable(_EXT_DEBUG_OUTPUT); + glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + glDebugMessageCallbackARB(_gl_debug_print, NULL); + glEnable(_EXT_DEBUG_OUTPUT); #endif diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 675b6f228d..1a63d451b1 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -100,6 +100,8 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas,int p_size){ shadow_atlas->depth=0; shadow_atlas->fbo=0; + + print_line("erasing atlas"); } for(int i=0;i<4;i++) { //clear subdivisions @@ -130,19 +132,18 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas,int p_size){ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_atlas->size, shadow_atlas->size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); - //interpola nearest (though nvidia can improve this) 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); - // We'll use a depth texture to store the depths in the shadow map - // Attach the depth texture to FBO depth attachment point glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadow_atlas->depth, 0); + + glViewport(0,0,shadow_atlas->size,shadow_atlas->size); + glClearDepth(0); + glClear(GL_DEPTH_BUFFER_BIT); + } } @@ -523,12 +524,19 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas,int p_size) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); + mmsize=reflection_atlas->size; for(int i=0;i<6;i++) { glGenFramebuffers(1, &reflection_atlas->fbo[i]); glBindFramebuffer(GL_FRAMEBUFFER, reflection_atlas->fbo[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, reflection_atlas->color, i); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + ERR_CONTINUE(status!=GL_FRAMEBUFFER_COMPLETE); + glDisable(GL_SCISSOR_TEST); glViewport(0,0,mmsize,mmsize); glClearColor(0,0,0,0); @@ -538,8 +546,6 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas,int p_size) } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); } @@ -1020,11 +1026,12 @@ RID RasterizerSceneGLES3::gi_probe_instance_create() { return gi_probe_instance_owner.make_rid(gipi); } -void RasterizerSceneGLES3::gi_probe_instance_set_light_data(RID p_probe,RID p_data) { +void RasterizerSceneGLES3::gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) { GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_probe); ERR_FAIL_COND(!gipi); gipi->data=p_data; + gipi->probe=storage->gi_probe_owner.getornull(p_base); if (p_data.is_valid()) { RasterizerStorageGLES3::GIProbeData *gipd = storage->gi_probe_data_owner.getornull(p_data); ERR_FAIL_COND(!gipd); @@ -1571,6 +1578,8 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform& glBindTexture(GL_TEXTURE_3D,gipi->tex_cache); 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_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) { @@ -1581,7 +1590,8 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform& state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_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_BLEND_AMBIENT2, gipi2->probe?!gipi2->probe->interior:false); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, true ); } else { @@ -4209,7 +4219,6 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa fbo=shadow_atlas->fbo; vp_height=shadow_atlas->size; - uint32_t key = shadow_atlas->shadow_owners[p_light]; uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT)&0x3; @@ -4299,24 +4308,22 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa render_list.sort_by_depth(false); //shadow is front to back for performance glDepthMask(true); - glColorMask(0,0,0,0); + glColorMask(1,1,1,1); glDisable(GL_BLEND); glDisable(GL_DITHER); glEnable(GL_DEPTH_TEST); - glBindFramebuffer(GL_FRAMEBUFFER,fbo); if (custom_vp_size) { glViewport(0,0,custom_vp_size,custom_vp_size); glScissor(0,0,custom_vp_size,custom_vp_size); + } else { glViewport(x,y,width,height); glScissor(x,y,width,height); } - //glViewport(x,vp_height-(height+y),width,height); - //glScissor(x,vp_height-(height+y),width,height); glEnable(GL_SCISSOR_TEST); glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT); @@ -4331,7 +4338,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,false,false); + _render_list(render_list.elements,render_list.element_count,light_transform,light_projection,0,!flip_facing,false,true,false,false); state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW,false); state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW_DUAL_PARABOLOID,false); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index ce869da131..31d9964ab0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -531,6 +531,7 @@ public: struct GIProbeInstance : public RID_Data { RID data; + RasterizerStorageGLES3::GIProbe *probe; GLuint tex_cache; Vector3 cell_size_cache; Vector3 bounds; @@ -542,7 +543,7 @@ public: mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner; virtual RID gi_probe_instance_create(); - virtual void gi_probe_instance_set_light_data(RID p_probe,RID p_data); + virtual void gi_probe_instance_set_light_data(RID p_probe,RID p_base,RID p_data); virtual void gi_probe_instance_set_transform_to_data(RID p_probe,const Transform& p_xform); virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 9edc37fe3b..fe8373b20d 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -4695,6 +4695,8 @@ RID RasterizerStorageGLES3::gi_probe_create() { gip->data_depth=0; gip->bounds=AABB(Vector3(),Vector3(1,1,1)); gip->dynamic_range=1.0; + gip->energy=1.0; + gip->interior=false; gip->version=1; gip->cell_size=1.0; @@ -4773,7 +4775,7 @@ DVector<int> RasterizerStorageGLES3::gi_probe_get_dynamic_data(RID p_probe) cons return gip->dynamic_data; } -void RasterizerStorageGLES3::gi_probe_set_dynamic_range(RID p_probe,float p_range){ +void RasterizerStorageGLES3::gi_probe_set_dynamic_range(RID p_probe,int p_range){ GIProbe *gip = gi_probe_owner.getornull(p_probe); ERR_FAIL_COND(!gip); @@ -4781,7 +4783,7 @@ void RasterizerStorageGLES3::gi_probe_set_dynamic_range(RID p_probe,float p_rang gip->dynamic_range=p_range; } -float RasterizerStorageGLES3::gi_probe_get_dynamic_range(RID p_probe) const{ +int RasterizerStorageGLES3::gi_probe_get_dynamic_range(RID p_probe) const{ const GIProbe *gip = gi_probe_owner.getornull(p_probe); ERR_FAIL_COND_V(!gip,0); @@ -4789,6 +4791,41 @@ float RasterizerStorageGLES3::gi_probe_get_dynamic_range(RID p_probe) const{ return gip->dynamic_range; } +void RasterizerStorageGLES3::gi_probe_set_energy(RID p_probe,float p_range){ + + GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND(!gip); + + gip->energy=p_range; + +} + +void RasterizerStorageGLES3::gi_probe_set_interior(RID p_probe,bool p_enable) { + + GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND(!gip); + + gip->interior=p_enable; + +} + +bool RasterizerStorageGLES3::gi_probe_is_interior(RID p_probe) const{ + + const GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND_V(!gip,false); + + return gip->interior; + +} + +float RasterizerStorageGLES3::gi_probe_get_energy(RID p_probe) const{ + + const GIProbe *gip = gi_probe_owner.getornull(p_probe); + ERR_FAIL_COND_V(!gip,0); + + return gip->energy; +} + void RasterizerStorageGLES3::gi_probe_set_static_data(RID p_gi_probe,const DVector<uint8_t>& p_data,VS::GIProbeDataFormat p_format,int p_width,int p_height,int p_depth) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 5d07d0be87..c51cd8d90b 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -890,7 +890,9 @@ public: Transform to_cell; float cell_size; - float dynamic_range; + int dynamic_range; + float energy; + bool interior; uint32_t version; @@ -921,9 +923,14 @@ public: virtual void gi_probe_set_dynamic_data(RID p_probe,const DVector<int>& p_data); virtual DVector<int> gi_probe_get_dynamic_data(RID p_probe) const; - virtual void gi_probe_set_dynamic_range(RID p_probe,float p_range); - virtual float gi_probe_get_dynamic_range(RID p_probe) const; + virtual void gi_probe_set_dynamic_range(RID p_probe,int p_range); + virtual int gi_probe_get_dynamic_range(RID p_probe) const; + + 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_interior(RID p_probe,bool p_enable); + virtual bool gi_probe_is_interior(RID p_probe) const; virtual void gi_probe_set_static_data(RID p_gi_probe,const DVector<uint8_t>& p_data,VS::GIProbeDataFormat p_format,int p_width,int p_height,int p_depth); virtual DVector<uint8_t> gi_probe_get_static_data(RID p_gi_probe) const; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index c9de56be4f..2dfbbd340d 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -845,14 +845,18 @@ uniform mediump sampler3D gi_probe1; //texunit:-6 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 bool gi_probe_blend_ambient1; uniform mediump sampler3D gi_probe2; //texunit:-7 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 bool gi_probe2_enabled; +uniform bool gi_probe_blend_ambient2; -vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, 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 dist = dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0; @@ -868,10 +872,12 @@ vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 direction, dist += diameter * 0.5; } + color.rgb = mix(color.rgb,mix(ambient,color.rgb,alpha),blend_ambient); + return color.rgb; } -void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, 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, out vec4 out_spec, out vec4 out_diff) { @@ -928,15 +934,19 @@ 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,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); } + light*=multiplier; + out_diff = vec4(light*blend,blend); //irradiance - vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,ref_vec,tan(roughness * 0.5 * M_PI) ,max_distance); + vec3 irr_light = voxel_cone_trace(probe,cell_size,probe_pos,environment,blend_ambient,ref_vec,tan(roughness * 0.5 * M_PI) ,max_distance); + + irr_light *= multiplier; //irr_light=vec3(0.0); out_spec = vec4(irr_light*blend,blend); @@ -958,11 +968,18 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, in vec4 diff_accum = vec4(0.0); vec4 spec_accum = vec4(0.0); - gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,normal_mat,ref_vec,roughness,spec_accum,diff_accum); + vec3 ambient = out_ambient; + out_ambient = vec3(0.0); + + vec3 environment = out_specular; + + 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); if (gi_probe2_enabled) { - gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,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,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 ce360859d6..93d3e51a8e 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -53,12 +53,35 @@ DVector<int> GIProbeData::get_dynamic_data() const{ return VS::get_singleton()->gi_probe_get_dynamic_data(probe); } -void GIProbeData::set_dynamic_range(float p_range){ +void GIProbeData::set_dynamic_range(int p_range){ VS::get_singleton()->gi_probe_set_dynamic_range(probe,p_range); } -float GIProbeData::get_dynamic_range() const{ + +void GIProbeData::set_energy(float p_range) { + + VS::get_singleton()->gi_probe_set_energy(probe,p_range); +} + +float GIProbeData::get_energy() const{ + + return VS::get_singleton()->gi_probe_get_energy(probe); + +} + +void GIProbeData::set_interior(bool p_enable) { + + VS::get_singleton()->gi_probe_set_interior(probe,p_enable); + +} + +bool GIProbeData::is_interior() const{ + + return VS::get_singleton()->gi_probe_is_interior(probe); +} + +int GIProbeData::get_dynamic_range() const{ return VS::get_singleton()->gi_probe_get_dynamic_range(probe); @@ -154,15 +177,42 @@ Vector3 GIProbe::get_extents() const { return extents; } -void GIProbe::set_dynamic_range(float p_dynamic_range) { +void GIProbe::set_dynamic_range(int p_dynamic_range) { dynamic_range=p_dynamic_range; } -float GIProbe::get_dynamic_range() const { +int GIProbe::get_dynamic_range() const { return dynamic_range; } +void GIProbe::set_energy(float p_energy) { + + energy=p_energy; + if (probe_data.is_valid()) { + probe_data->set_energy(energy); + } +} +float GIProbe::get_energy() const { + + return energy; +} + +void GIProbe::set_interior(bool p_enable) { + + interior=p_enable; + if (probe_data.is_valid()) { + probe_data->set_interior(p_enable); + } +} + +bool GIProbe::is_interior() const { + + return interior; +} + + + #include "math.h" #define FINDMINMAX(x0,x1,x2,min,max) \ @@ -384,6 +434,8 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V Color albedo_accum; Color emission_accum; + Vector3 normal_accum; + float alpha=0.0; //map to a grid average in the best axis for this face @@ -441,6 +493,9 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V emission_accum.r+=p_material.emission[ofs].r; emission_accum.g+=p_material.emission[ofs].g; emission_accum.b+=p_material.emission[ofs].b; + + normal_accum+=normal; + alpha+=1.0; } @@ -471,6 +526,7 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V emission_accum.g=p_material.emission[ofs].g*alpha; emission_accum.b=p_material.emission[ofs].b*alpha; + normal_accum*=alpha; } else { @@ -486,6 +542,9 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V emission_accum.r*=accdiv; emission_accum.g*=accdiv; emission_accum.b*=accdiv; + + normal_accum*=accdiv; + } //put this temporarily here, corrected in a later step @@ -495,6 +554,9 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V p_baker->bake_cells[p_idx].emission[0]+=emission_accum.r; p_baker->bake_cells[p_idx].emission[1]+=emission_accum.g; p_baker->bake_cells[p_idx].emission[2]+=emission_accum.b; + p_baker->bake_cells[p_idx].normal[0]+=normal_accum.x; + p_baker->bake_cells[p_idx].normal[1]+=normal_accum.y; + p_baker->bake_cells[p_idx].normal[2]+=normal_accum.z; p_baker->bake_cells[p_idx].alpha+=alpha; static const Vector3 side_normals[6]={ @@ -506,11 +568,12 @@ void GIProbe::_plot_face(int p_idx, int p_level,int p_x,int p_y,int p_z, const V Vector3( 0, 0, 1), }; + /* for(int i=0;i<6;i++) { if (normal.dot(side_normals[i])>CMP_EPSILON) { p_baker->bake_cells[p_idx].used_sides|=(1<<i); } - } + }*/ } else { @@ -589,8 +652,27 @@ void GIProbe::_fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker p_baker->bake_cells[p_idx].emission[1]/=alpha; p_baker->bake_cells[p_idx].emission[2]/=alpha; + p_baker->bake_cells[p_idx].normal[0]/=alpha; + p_baker->bake_cells[p_idx].normal[1]/=alpha; + p_baker->bake_cells[p_idx].normal[2]/=alpha; + + Vector3 n(p_baker->bake_cells[p_idx].normal[0],p_baker->bake_cells[p_idx].normal[1],p_baker->bake_cells[p_idx].normal[2]); + if (n.length()<0.01) { + //too much fight over normal, zero it + p_baker->bake_cells[p_idx].normal[0]=0; + p_baker->bake_cells[p_idx].normal[1]=0; + p_baker->bake_cells[p_idx].normal[2]=0; + } else { + n.normalize(); + p_baker->bake_cells[p_idx].normal[0]=n.x; + p_baker->bake_cells[p_idx].normal[1]=n.y; + p_baker->bake_cells[p_idx].normal[2]=n.z; + } + + p_baker->bake_cells[p_idx].alpha=1.0; + /* //remove neighbours from used sides for(int n=0;n<6;n++) { @@ -653,6 +735,7 @@ void GIProbe::_fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker p_baker->bake_cells[p_idx].used_sides&=~(1<<uint32_t(n)); } } + */ } else { @@ -687,6 +770,9 @@ void GIProbe::_fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker p_baker->bake_cells[p_idx].emission[0]=0; p_baker->bake_cells[p_idx].emission[1]=0; p_baker->bake_cells[p_idx].emission[2]=0; + p_baker->bake_cells[p_idx].normal[0]=0; + p_baker->bake_cells[p_idx].normal[1]=0; + p_baker->bake_cells[p_idx].normal[2]=0; p_baker->bake_cells[p_idx].albedo[0]=0; p_baker->bake_cells[p_idx].albedo[1]=0; p_baker->bake_cells[p_idx].albedo[2]=0; @@ -1024,7 +1110,21 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug){ w32[ofs++]=em; } - w32[ofs++]=baker.bake_cells[i].used_sides; + //w32[ofs++]=baker.bake_cells[i].used_sides; + { //normal + + Vector3 n(baker.bake_cells[i].normal[0],baker.bake_cells[i].normal[1],baker.bake_cells[i].normal[2]); + n=n*Vector3(0.5,0.5,0.5)+Vector3(0.5,0.5,0.5); + uint32_t norm=0; + + + norm|=uint32_t(CLAMP( n.x*255.0, 0, 255))<<16; + norm|=uint32_t(CLAMP( n.y*255.0, 0, 255))<<8; + norm|=uint32_t(CLAMP( n.z*255.0, 0, 255))<<0; + + w32[ofs++]=norm; + } + w32[ofs++]=uint32_t(baker.bake_cells[i].alpha*65535.0); } @@ -1036,6 +1136,9 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug){ probe_data->set_bounds(AABB(-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_to_cell_xform(baker.to_cell_space); set_probe_data(probe_data); @@ -1212,13 +1315,21 @@ void GIProbe::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_dynamic_range","max"),&GIProbe::set_dynamic_range); ObjectTypeDB::bind_method(_MD("get_dynamic_range"),&GIProbe::get_dynamic_range); + ObjectTypeDB::bind_method(_MD("set_energy","max"),&GIProbe::set_energy); + ObjectTypeDB::bind_method(_MD("get_energy"),&GIProbe::get_energy); + + ObjectTypeDB::bind_method(_MD("set_interior","enable"),&GIProbe::set_interior); + ObjectTypeDB::bind_method(_MD("is_interior"),&GIProbe::is_interior); + ObjectTypeDB::bind_method(_MD("bake","from_node","create_visual_debug"),&GIProbe::bake,DEFVAL(Variant()),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("debug_bake"),&GIProbe::_debug_bake); ObjectTypeDB::set_method_flags(get_type_static(),_SCS("debug_bake"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR); ADD_PROPERTY( PropertyInfo(Variant::INT,"subdiv",PROPERTY_HINT_ENUM,"64,128,256,512"),_SCS("set_subdiv"),_SCS("get_subdiv")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"extents"),_SCS("set_extents"),_SCS("get_extents")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"dynamic_range",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("set_dynamic_range"),_SCS("get_dynamic_range")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"dynamic_range",PROPERTY_HINT_RANGE,"1,16,1"),_SCS("set_dynamic_range"),_SCS("get_dynamic_range")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_energy"),_SCS("get_energy")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"interior"),_SCS("set_interior"),_SCS("is_interior")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"data",PROPERTY_HINT_RESOURCE_TYPE,"GIProbeData"),_SCS("set_probe_data"),_SCS("get_probe_data")); @@ -1232,10 +1343,12 @@ void GIProbe::_bind_methods() { GIProbe::GIProbe() { subdiv=SUBDIV_128; - dynamic_range=1.0; + dynamic_range=4; + energy=1.0; extents=Vector3(10,10,10); color_scan_cell_width=4; bake_texture_size=128; + interior=false; gi_probe = VS::get_singleton()->gi_probe_create(); diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index e2017acfc3..297672198c 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -31,8 +31,14 @@ public: void set_dynamic_data(const DVector<int>& p_data); DVector<int> get_dynamic_data() const; - void set_dynamic_range(float p_range); - float get_dynamic_range() const; + void set_dynamic_range(int p_range); + int get_dynamic_range() const; + + void set_energy(float p_range); + float get_energy() const; + + void set_interior(bool p_enable); + bool is_interior() const; void set_static_data(const DVector<uint8_t>& p_data,DataFormat p_format,int p_width,int p_height,int p_depth); DVector<uint8_t> get_static_data() const; @@ -73,6 +79,7 @@ private: uint32_t childs[8]; float albedo[3]; //albedo in RGB24 float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast) + float normal[3]; uint32_t used_sides; float alpha; //used for upsampling @@ -84,6 +91,7 @@ private: for(int i=0;i<3;i++) { emission[i]=0; albedo[i]=0; + normal[i]=0; } alpha=0; used_sides=0; @@ -126,7 +134,9 @@ private: Subdiv subdiv; Vector3 extents; - float dynamic_range; + int dynamic_range; + float energy; + bool interior; int color_scan_cell_width; int bake_texture_size; @@ -157,8 +167,15 @@ public: void set_extents(const Vector3& p_extents); Vector3 get_extents() const; - void set_dynamic_range(float p_dynamic_range); - float get_dynamic_range() const; + void set_dynamic_range(int p_dynamic_range); + int get_dynamic_range() const; + + void set_energy(float p_energy); + float get_energy() const; + + void set_interior(bool p_enable); + bool is_interior() const; + void bake(Node *p_from_node=NULL,bool p_create_visual_debug=false); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index bd5eb0a4e6..728997e794 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1283,6 +1283,9 @@ bool Viewport::get_clear_on_new_frame() const{ void Viewport::set_shadow_atlas_size(int p_size) { + if (shadow_atlas_size==p_size) + return; + shadow_atlas_size=p_size; VS::get_singleton()->viewport_set_shadow_atlas_size(viewport,p_size); } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 79560f3486..f22b7e04f6 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -149,7 +149,7 @@ public: virtual bool reflection_probe_instance_postprocess_step(RID p_instance)=0; virtual RID gi_probe_instance_create()=0; - virtual void gi_probe_instance_set_light_data(RID p_probe,RID p_data)=0; + virtual void gi_probe_instance_set_light_data(RID p_probe,RID p_base,RID p_data)=0; virtual void gi_probe_instance_set_transform_to_data(RID p_probe,const Transform& p_xform)=0; virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds)=0; @@ -418,9 +418,14 @@ public: virtual void gi_probe_set_dynamic_data(RID p_probe,const DVector<int>& p_data)=0; virtual DVector<int> gi_probe_get_dynamic_data(RID p_probe) const=0; - virtual void gi_probe_set_dynamic_range(RID p_probe,float p_range)=0; - virtual float gi_probe_get_dynamic_range(RID p_probe) const=0; + virtual void gi_probe_set_dynamic_range(RID p_probe,int p_range)=0; + virtual int gi_probe_get_dynamic_range(RID p_probe) const=0; + 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_interior(RID p_probe,bool p_enable)=0; + virtual bool gi_probe_is_interior(RID p_probe) const=0; virtual void gi_probe_set_static_data(RID p_gi_probe,const DVector<uint8_t>& p_data,VS::GIProbeDataFormat p_format,int p_width,int p_height,int p_depth)=0; virtual DVector<uint8_t> gi_probe_get_static_data(RID p_gi_probe) const=0; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 191330c66c..9dec587d1e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -816,8 +816,14 @@ public: BIND2(gi_probe_set_to_cell_xform,RID,const Transform&) BIND1RC(Transform,gi_probe_get_to_cell_xform,RID) - BIND2(gi_probe_set_dynamic_range,RID,float) - BIND1RC(float,gi_probe_get_dynamic_range,RID) + BIND2(gi_probe_set_dynamic_range,RID,int) + BIND1RC(int,gi_probe_get_dynamic_range,RID) + + BIND2(gi_probe_set_energy,RID,float) + BIND1RC(float,gi_probe_get_energy,RID) + + BIND2(gi_probe_set_interior,RID,bool) + BIND1RC(bool,gi_probe_is_interior,RID) BIND2(gi_probe_set_dynamic_data,RID,const DVector<int>& ) BIND1RC( DVector<int>,gi_probe_get_dynamic_data,RID) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 162647e420..d74f5265e4 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -1641,6 +1641,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance,const } } + VSG::scene_render->light_instance_set_shadow_transform(light->instance,cm,xform,radius,0,i); VSG::scene_render->render_shadow(light->instance,p_shadow_atlas,i,(RasterizerScene::InstanceBase**)instance_shadow_cull_result,cull_count); } @@ -2203,10 +2204,10 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform,const Came } - bool redraw = VSG::scene_render->shadow_atlas_update_light(p_shadow_atlas,light->instance,coverage,light->last_version); if (redraw) { + print_line("redraw shadow"); //must redraw! _light_instance_update_shadow(ins,p_cam_transform,p_cam_projection,p_cam_orthogonal,p_shadow_atlas,scenario); } @@ -2407,6 +2408,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { probe->dynamic.probe_data=VSG::storage->gi_probe_dynamic_data_create(header->width,header->height,header->depth); + probe->dynamic.bake_dynamic_range=VSG::storage->gi_probe_get_dynamic_range(p_instance->base); probe->dynamic.mipmaps_3d.clear(); @@ -2443,7 +2445,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { probe->dynamic.light_to_cell_xform=cell_to_xform * p_instance->transform.affine_inverse(); - VSG::scene_render->gi_probe_instance_set_light_data(probe->probe_instance,probe->dynamic.probe_data); + VSG::scene_render->gi_probe_instance_set_light_data(probe->probe_instance,p_instance->base,probe->dynamic.probe_data); VSG::scene_render->gi_probe_instance_set_transform_to_data(probe->probe_instance,probe->dynamic.light_to_cell_xform); @@ -2457,7 +2459,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { probe->dynamic.enabled=false; probe->invalid=!data.is_valid(); if (data.is_valid()) { - VSG::scene_render->gi_probe_instance_set_light_data(probe->probe_instance,data); + VSG::scene_render->gi_probe_instance_set_light_data(probe->probe_instance,p_instance->base,data); } } @@ -2541,6 +2543,30 @@ uint32_t VisualServerScene::_gi_bake_find_cell(const GIProbeDataCell *cells,int } +static float _get_normal_advance(const Vector3& p_normal ) { + + Vector3 normal = p_normal; + Vector3 unorm = normal.abs(); + + if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) { + // x code + unorm = normal.x > 0.0 ? Vector3( 1.0, 0.0, 0.0 ) : Vector3( -1.0, 0.0, 0.0 ) ; + } else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) { + // y code + unorm = normal.y > 0.0 ? Vector3( 0.0, 1.0, 0.0 ) : Vector3( 0.0, -1.0, 0.0 ) ; + } else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) { + // z code + unorm = normal.z > 0.0 ? Vector3( 0.0, 0.0, 1.0 ) : Vector3( 0.0, 0.0, -1.0 ) ; + } else { + // oh-no we messed up code + // has to be + unorm = Vector3( 1.0, 0.0, 0.0 ); + } + + return 1.0/normal.dot(unorm); + +} + void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,const GIProbeDataCell *cells,InstanceGIProbeData::LocalData *local_data,const uint32_t *leaves,int leaf_count, const InstanceGIProbeData::LightCache& light_cache,int sign) { @@ -2548,20 +2574,20 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con int light_g = int(light_cache.color.g * light_cache.energy * 1024.0)*sign; int light_b = int(light_cache.color.b * light_cache.energy * 1024.0)*sign; + float limits[3]={float(header->width),float(header->height),float(header->depth)}; + Plane clip[3]; + int clip_planes=0; + + + switch(light_cache.type) { case VS::LIGHT_DIRECTIONAL: { - float limits[3]={float(header->width),float(header->height),float(header->depth)}; - Plane clip[3]; - int clip_planes=0; float max_len = Vector3(limits[0],limits[1],limits[2]).length()*1.1; Vector3 light_axis = -light_cache.transform.basis.get_axis(2).normalized(); - print_line("transform directional, axis: "+light_axis); - print_line("limits: "+Vector3(limits[0],limits[1],limits[2])); - for(int i=0;i<3;i++) { if (ABS(light_axis[i])<CMP_EPSILON) @@ -2578,29 +2604,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con clip_planes++; } - float distance_adv; - { - Vector3 normal = light_axis; - Vector3 unorm = normal.abs(); - - if ( (unorm.x >= unorm.y) && (unorm.x >= unorm.z) ) { - // x code - unorm = normal.x > 0.0 ? Vector3( 1.0, 0.0, 0.0 ) : Vector3( -1.0, 0.0, 0.0 ) ; - } else if ( (unorm.y > unorm.x) && (unorm.y >= unorm.z) ) { - // y code - unorm = normal.y > 0.0 ? Vector3( 0.0, 1.0, 0.0 ) : Vector3( 0.0, -1.0, 0.0 ) ; - } else if ( (unorm.z > unorm.x) && (unorm.z > unorm.y) ) { - // z code - unorm = normal.z > 0.0 ? Vector3( 0.0, 0.0, 1.0 ) : Vector3( 0.0, 0.0, -1.0 ) ; - } else { - // oh-no we messed up code - // has to be - unorm = Vector3( 1.0, 0.0, 0.0 ); - } - - distance_adv = 1.0/normal.dot(unorm); - - } + float distance_adv = _get_normal_advance(light_axis); int success_count=0; @@ -2614,7 +2618,18 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con InstanceGIProbeData::LocalData *light = &local_data[idx]; Vector3 to(light->pos[0]+0.5,light->pos[1]+0.5,light->pos[2]+0.5); + Vector3 norm ( + (((cells[idx].normal>>16)&0xFF)/255.0)*2.0-1.0, + (((cells[idx].normal>>8)&0xFF)/255.0)*2.0-1.0, + (((cells[idx].normal>>0)&0xFF)/255.0)*2.0-1.0 + ); + + float att = norm.dot(-light_axis); + if (att<0.001) { + //not lighting towards this + continue; + } Vector3 from = to - max_len * light_axis; @@ -2642,10 +2657,10 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con if (result==idx) { //cell hit itself! hooray! - light->energy[0]+=(uint32_t(light_r)*((cell->albedo>>16)&0xFF))>>8; - light->energy[1]+=(uint32_t(light_g)*((cell->albedo>>8)&0xFF))>>8; - light->energy[2]+=(uint32_t(light_b)*((cell->albedo)&0xFF))>>8; - success_count++; + light->energy[0]+=int32_t(light_r*att*((cell->albedo>>16)&0xFF)/255.0); + light->energy[1]+=int32_t(light_g*att*((cell->albedo>>8)&0xFF)/255.0); + light->energy[2]+=int32_t(light_b*att*((cell->albedo)&0xFF)/255.0); + success_count++; } } print_line("BAKE TIME: "+rtos((OS::get_singleton()->get_ticks_usec()-us)/1000000.0)); @@ -2653,6 +2668,120 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con } break; + case VS::LIGHT_OMNI: + case VS::LIGHT_SPOT: { + + + uint64_t us = OS::get_singleton()->get_ticks_usec(); + + Vector3 light_pos = light_cache.transform.origin; + Vector3 spot_axis = -light_cache.transform.basis.get_axis(2).normalized(); + + + float local_radius = light_cache.radius * light_cache.transform.basis.get_axis(2).length(); + + for(int i=0;i<leaf_count;i++) { + + uint32_t idx = leaves[i]; + + const GIProbeDataCell *cell = &cells[idx]; + InstanceGIProbeData::LocalData *light = &local_data[idx]; + + Vector3 to(light->pos[0]+0.5,light->pos[1]+0.5,light->pos[2]+0.5); + Vector3 norm ( + (((cells[idx].normal>>16)&0xFF)/255.0)*2.0-1.0, + (((cells[idx].normal>>8)&0xFF)/255.0)*2.0-1.0, + (((cells[idx].normal>>0)&0xFF)/255.0)*2.0-1.0 + ); + + Vector3 light_axis = (to - light_pos).normalized(); + float distance_adv = _get_normal_advance(light_axis); + + float att = norm.dot(-light_axis); + if (att<0.001) { + //not lighting towards this + continue; + } + + { + float d = light_pos.distance_to(to); + if (d+distance_adv > local_radius) + continue; // too far away + + float dt = CLAMP((d+distance_adv)/local_radius,0,1); + att*= pow(1.0-dt,light_cache.attenuation); + } + + + if (light_cache.type==VS::LIGHT_SPOT) { + + float angle = Math::rad2deg(acos(light_axis.dot(spot_axis))); + if (angle > light_cache.spot_angle) + continue; + + float d = CLAMP(angle/light_cache.spot_angle,1,0); + att*= pow(1.0-d,light_cache.spot_attenuation); + + } + + clip_planes=0; + + for(int c=0;c<3;c++) { + + if (ABS(light_axis[c])<CMP_EPSILON) + continue; + clip[clip_planes].normal[c]=1.0; + + if (light_axis[c]<0) { + + clip[clip_planes].d=limits[c]+1; + } else { + clip[clip_planes].d-=1.0; + } + + clip_planes++; + } + + Vector3 from = light_pos; + + for(int j=0;j<clip_planes;j++) { + + clip[j].intersects_segment(from,to,&from); + } + + float distance = (to - from).length(); + + + + distance-=Math::fmod(distance,distance_adv); //make it reach the center of the box always, but this tame make it closer + from = to - light_axis * distance; + + uint32_t result=0xFFFFFFFF; + + while(distance>-distance_adv) { //use this to avoid precision errors + + result = _gi_bake_find_cell(cells,int(floor(from.x)),int(floor(from.y)),int(floor(from.z)),header->cell_subdiv); + if (result!=0xFFFFFFFF) { + break; + } + + from+=light_axis*distance_adv; + distance-=distance_adv; + } + + if (result==idx) { + //cell hit itself! hooray! + + light->energy[0]+=int32_t(light_r*att*((cell->albedo>>16)&0xFF)/255.0); + light->energy[1]+=int32_t(light_g*att*((cell->albedo>>8)&0xFF)/255.0); + light->energy[2]+=int32_t(light_b*att*((cell->albedo)&0xFF)/255.0); + + } + } + print_line("BAKE TIME: "+rtos((OS::get_singleton()->get_ticks_usec()-us)/1000000.0)); + + + } break; } } @@ -2760,9 +2889,9 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) { uint32_t idx = level_cells[j]; - uint32_t r = local_data[idx].energy[0]>>2; - uint32_t g = local_data[idx].energy[1]>>2; - uint32_t b = local_data[idx].energy[2]>>2; + uint32_t r = (uint32_t(local_data[idx].energy[0])/probe_data->dynamic.bake_dynamic_range)>>2; + uint32_t g = (uint32_t(local_data[idx].energy[1])/probe_data->dynamic.bake_dynamic_range)>>2; + uint32_t b = (uint32_t(local_data[idx].energy[2])/probe_data->dynamic.bake_dynamic_range)>>2; uint32_t a = cells[idx].alpha>>8; uint32_t mm_ofs = sizes[0]*sizes[1]*(local_data[idx].pos[2]) + sizes[0]*(local_data[idx].pos[1]) + (local_data[idx].pos[0]); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 894d3529af..418e8387bf 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -432,6 +432,7 @@ public: Vector<Vector<uint32_t> > level_cell_lists; RID probe_data; bool enabled; + int bake_dynamic_range; Vector< DVector<uint8_t> > mipmaps_3d; @@ -536,7 +537,7 @@ public: uint32_t children[8]; uint32_t albedo; uint32_t emission; - uint32_t sides_used; + uint32_t normal; uint32_t alpha; }; @@ -560,7 +561,6 @@ public: _FORCE_INLINE_ uint32_t _gi_bake_find_cell(const GIProbeDataCell *cells,int x,int y, int z,int p_cell_subdiv); void _bake_gi_downscale_light(int p_idx, int p_level, const GIProbeDataCell* p_cells, const GIProbeDataHeader *p_header, InstanceGIProbeData::LocalData *p_local_data); - void _bake_gi_probe_light(const GIProbeDataHeader *header,const GIProbeDataCell *cells,InstanceGIProbeData::LocalData *local_data,const uint32_t *leaves,int p_leaf_count, const InstanceGIProbeData::LightCache& light_cache,int p_sign); void _bake_gi_probe(Instance *p_probe); bool _check_gi_probe(Instance *p_gi_probe); diff --git a/servers/visual_server.h b/servers/visual_server.h index 6f2aa73952..20fe8e7d76 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -461,8 +461,14 @@ public: virtual void gi_probe_set_dynamic_data(RID p_probe,const DVector<int>& p_data)=0; virtual DVector<int> gi_probe_get_dynamic_data(RID p_probe) const=0; - virtual void gi_probe_set_dynamic_range(RID p_probe,float p_range)=0; - virtual float gi_probe_get_dynamic_range(RID p_probe) const=0; + virtual void gi_probe_set_dynamic_range(RID p_probe,int p_range)=0; + virtual int gi_probe_get_dynamic_range(RID p_probe) const=0; + + 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_interior(RID p_probe,bool p_enable)=0; + virtual bool gi_probe_is_interior(RID p_probe) const=0; enum GIProbeDataFormat { GI_PROBE_DATA_RGBA8, |