can bake for omni and spotlight
store normal when baking
This commit is contained in:
parent
37f558cd7b
commit
f9603d8236
14 changed files with 440 additions and 92 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,8 +2618,19 @@ 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;
|
||||
|
||||
for(int j=0;j<clip_planes;j++) {
|
||||
|
@ -2642,16 +2657,130 @@ 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));
|
||||
print_line("valid cells: "+itos(success_count));
|
||||
|
||||
|
||||
} 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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue