Ver Fonte

can bake for omni and spotlight
store normal when baking

Juan Linietsky há 8 anos atrás
pai
commit
f9603d8236

+ 3 - 3
drivers/gles3/rasterizer_gles3.cpp

@@ -130,9 +130,9 @@ void RasterizerGLES3::initialize() {
 		ERR_PRINT("Error initializing GLAD");
 		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
 #endif
 
 

+ 23 - 16
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->depth=0;
 		shadow_atlas->fbo=0;
 		shadow_atlas->fbo=0;
+
+		print_line("erasing atlas");
 	}
 	}
 	for(int i=0;i<4;i++) {
 	for(int i=0;i<4;i++) {
 		//clear subdivisions
 		//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,
 		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_atlas->size, shadow_atlas->size, 0,
 			     GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
 			     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_MIN_FILTER, GL_LINEAR);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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_S, GL_CLAMP_TO_EDGE);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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,
 		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
 				       GL_TEXTURE_2D, shadow_atlas->depth, 0);
 				       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_S, GL_CLAMP_TO_EDGE);
 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, 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;
 		mmsize=reflection_atlas->size;
 
 
 		for(int i=0;i<6;i++) {
 		for(int i=0;i<6;i++) {
 			glGenFramebuffers(1, &reflection_atlas->fbo[i]);
 			glGenFramebuffers(1, &reflection_atlas->fbo[i]);
 			glBindFramebuffer(GL_FRAMEBUFFER, reflection_atlas->fbo[i]);
 			glBindFramebuffer(GL_FRAMEBUFFER, reflection_atlas->fbo[i]);
 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,  reflection_atlas->color, 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);
 			glDisable(GL_SCISSOR_TEST);
 			glViewport(0,0,mmsize,mmsize);
 			glViewport(0,0,mmsize,mmsize);
 			glClearColor(0,0,0,0);
 			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);
 	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);
 	GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_probe);
 	ERR_FAIL_COND(!gipi);
 	ERR_FAIL_COND(!gipi);
 	gipi->data=p_data;
 	gipi->data=p_data;
+	gipi->probe=storage->gi_probe_owner.getornull(p_base);
 	if (p_data.is_valid()) {
 	if (p_data.is_valid()) {
 		RasterizerStorageGLES3::GIProbeData *gipd = storage->gi_probe_data_owner.getornull(p_data);
 		RasterizerStorageGLES3::GIProbeData *gipd = storage->gi_probe_data_owner.getornull(p_data);
 		ERR_FAIL_COND(!gipd);
 		ERR_FAIL_COND(!gipd);
@@ -1571,6 +1578,8 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform&
 		glBindTexture(GL_TEXTURE_3D,gipi->tex_cache);
 		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_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_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);
 		state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE1, gipi->cell_size_cache);
 		if (gi_probe_count>1) {
 		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_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_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_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 );
 			state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, true );
 		} else {
 		} else {
 
 
@@ -4209,7 +4219,6 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa
 		fbo=shadow_atlas->fbo;
 		fbo=shadow_atlas->fbo;
 		vp_height=shadow_atlas->size;
 		vp_height=shadow_atlas->size;
 
 
-
 		uint32_t key = shadow_atlas->shadow_owners[p_light];
 		uint32_t key = shadow_atlas->shadow_owners[p_light];
 
 
 		uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT)&0x3;
 		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
 	render_list.sort_by_depth(false); //shadow is front to back for performance
 
 
 	glDepthMask(true);
 	glDepthMask(true);
-	glColorMask(0,0,0,0);
+	glColorMask(1,1,1,1);
 	glDisable(GL_BLEND);
 	glDisable(GL_BLEND);
 	glDisable(GL_DITHER);
 	glDisable(GL_DITHER);
 	glEnable(GL_DEPTH_TEST);
 	glEnable(GL_DEPTH_TEST);
-
 	glBindFramebuffer(GL_FRAMEBUFFER,fbo);
 	glBindFramebuffer(GL_FRAMEBUFFER,fbo);
 
 
 	if (custom_vp_size) {
 	if (custom_vp_size) {
 		glViewport(0,0,custom_vp_size,custom_vp_size);
 		glViewport(0,0,custom_vp_size,custom_vp_size);
 		glScissor(0,0,custom_vp_size,custom_vp_size);
 		glScissor(0,0,custom_vp_size,custom_vp_size);
 
 
+
 	} else {
 	} else {
 		glViewport(x,y,width,height);
 		glViewport(x,y,width,height);
 		glScissor(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);
 	glEnable(GL_SCISSOR_TEST);
 	glClearDepth(1.0);
 	glClearDepth(1.0);
 	glClear(GL_DEPTH_BUFFER_BIT);
 	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);
 	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,false);
 	state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW_DUAL_PARABOLOID,false);
 	state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_SHADOW_DUAL_PARABOLOID,false);

+ 2 - 1
drivers/gles3/rasterizer_scene_gles3.h

@@ -531,6 +531,7 @@ public:
 
 
 	struct GIProbeInstance : public RID_Data {
 	struct GIProbeInstance : public RID_Data {
 		RID data;
 		RID data;
+		RasterizerStorageGLES3::GIProbe *probe;
 		GLuint tex_cache;
 		GLuint tex_cache;
 		Vector3 cell_size_cache;
 		Vector3 cell_size_cache;
 		Vector3 bounds;
 		Vector3 bounds;
@@ -542,7 +543,7 @@ public:
 	mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
 	mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
 
 
 	virtual RID gi_probe_instance_create();
 	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_transform_to_data(RID p_probe,const Transform& p_xform);
 	virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds);
 	virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds);
 
 

+ 39 - 2
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -4695,6 +4695,8 @@ RID RasterizerStorageGLES3::gi_probe_create() {
 	gip->data_depth=0;
 	gip->data_depth=0;
 	gip->bounds=AABB(Vector3(),Vector3(1,1,1));
 	gip->bounds=AABB(Vector3(),Vector3(1,1,1));
 	gip->dynamic_range=1.0;
 	gip->dynamic_range=1.0;
+	gip->energy=1.0;
+	gip->interior=false;
 	gip->version=1;
 	gip->version=1;
 	gip->cell_size=1.0;
 	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;
 	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);
 	GIProbe *gip = gi_probe_owner.getornull(p_probe);
 	ERR_FAIL_COND(!gip);
 	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;
 	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);
 	const GIProbe *gip = gi_probe_owner.getornull(p_probe);
 	ERR_FAIL_COND_V(!gip,0);
 	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;
 	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) {
 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) {
 
 

+ 10 - 3
drivers/gles3/rasterizer_storage_gles3.h

@@ -890,7 +890,9 @@ public:
 		Transform to_cell;
 		Transform to_cell;
 		float cell_size;
 		float cell_size;
 
 
-		float dynamic_range;
+		int dynamic_range;
+		float energy;
+		bool interior;
 
 
 		uint32_t version;
 		uint32_t version;
 
 
@@ -921,9 +923,14 @@ public:
 	virtual void gi_probe_set_dynamic_data(RID p_probe,const DVector<int>& p_data);
 	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 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 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;
 	virtual DVector<uint8_t> gi_probe_get_static_data(RID p_gi_probe) const;

+ 23 - 6
drivers/gles3/shaders/scene.glsl

@@ -845,14 +845,18 @@ uniform mediump sampler3D gi_probe1; //texunit:-6
 uniform highp mat4 gi_probe_xform1;
 uniform highp mat4 gi_probe_xform1;
 uniform highp vec3 gi_probe_bounds1;
 uniform highp vec3 gi_probe_bounds1;
 uniform highp vec3 gi_probe_cell_size1;
 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 mediump sampler3D gi_probe2; //texunit:-7
 uniform highp mat4 gi_probe_xform2;
 uniform highp mat4 gi_probe_xform2;
 uniform highp vec3 gi_probe_bounds2;
 uniform highp vec3 gi_probe_bounds2;
 uniform highp vec3 gi_probe_cell_size2;
 uniform highp vec3 gi_probe_cell_size2;
+uniform highp float gi_probe_multiplier2;
 uniform bool gi_probe2_enabled;
 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;
 	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;
 		dist += diameter * 0.5;
 	}
 	}
 
 
+	color.rgb = mix(color.rgb,mix(ambient,color.rgb,alpha),blend_ambient);
+
 	return color.rgb;
 	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++) {
 	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);
 		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);
 	out_diff = vec4(light*blend,blend);
 
 
 	//irradiance
 	//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);
 	//irr_light=vec3(0.0);
 
 
 	out_spec = vec4(irr_light*blend,blend);
 	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 diff_accum = vec4(0.0);
 	vec4 spec_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) {
 	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) {
 	if (diff_accum.a>0.0) {

+ 121 - 8
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);
 	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);
 	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);
 	return VS::get_singleton()->gi_probe_get_dynamic_range(probe);
@@ -154,15 +177,42 @@ Vector3 GIProbe::get_extents() const {
 	return extents;
 	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;
 	dynamic_range=p_dynamic_range;
 }
 }
-float GIProbe::get_dynamic_range() const {
+int GIProbe::get_dynamic_range() const {
 
 
 	return dynamic_range;
 	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"
 #include "math.h"
 
 
 #define FINDMINMAX(x0,x1,x2,min,max) \
 #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 albedo_accum;
 		Color emission_accum;
 		Color emission_accum;
+		Vector3 normal_accum;
+
 		float alpha=0.0;
 		float alpha=0.0;
 
 
 		//map to a grid average in the best axis for this face
 		//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.r+=p_material.emission[ofs].r;
 				emission_accum.g+=p_material.emission[ofs].g;
 				emission_accum.g+=p_material.emission[ofs].g;
 				emission_accum.b+=p_material.emission[ofs].b;
 				emission_accum.b+=p_material.emission[ofs].b;
+
+				normal_accum+=normal;
+
 				alpha+=1.0;
 				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.g=p_material.emission[ofs].g*alpha;
 			emission_accum.b=p_material.emission[ofs].b*alpha;
 			emission_accum.b=p_material.emission[ofs].b*alpha;
 
 
+			normal_accum*=alpha;
 
 
 
 
 		} else {
 		} 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.r*=accdiv;
 			emission_accum.g*=accdiv;
 			emission_accum.g*=accdiv;
 			emission_accum.b*=accdiv;
 			emission_accum.b*=accdiv;
+
+			normal_accum*=accdiv;
+
 		}
 		}
 
 
 		//put this temporarily here, corrected in a later step
 		//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[0]+=emission_accum.r;
 		p_baker->bake_cells[p_idx].emission[1]+=emission_accum.g;
 		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].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;
 		p_baker->bake_cells[p_idx].alpha+=alpha;
 
 
 		static const Vector3 side_normals[6]={
 		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),
 			Vector3( 0, 0, 1),
 		};
 		};
 
 
+		/*
 		for(int i=0;i<6;i++) {
 		for(int i=0;i<6;i++) {
 			if (normal.dot(side_normals[i])>CMP_EPSILON) {
 			if (normal.dot(side_normals[i])>CMP_EPSILON) {
 				p_baker->bake_cells[p_idx].used_sides|=(1<<i);
 				p_baker->bake_cells[p_idx].used_sides|=(1<<i);
 			}
 			}
-		}
+		}*/
 
 
 
 
 	} else {
 	} 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[1]/=alpha;
 		p_baker->bake_cells[p_idx].emission[2]/=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;
 		p_baker->bake_cells[p_idx].alpha=1.0;
 
 
+		/*
 		//remove neighbours from used sides
 		//remove neighbours from used sides
 
 
 		for(int n=0;n<6;n++) {
 		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));
 				p_baker->bake_cells[p_idx].used_sides&=~(1<<uint32_t(n));
 			}
 			}
 		}
 		}
+		*/
 	} else {
 	} 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[0]=0;
 		p_baker->bake_cells[p_idx].emission[1]=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].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[0]=0;
 		p_baker->bake_cells[p_idx].albedo[1]=0;
 		p_baker->bake_cells[p_idx].albedo[1]=0;
 		p_baker->bake_cells[p_idx].albedo[2]=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++]=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);
 			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_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_cell_size(baker.po2_bounds.size[longest_axis]/baker.axis_cell_size[longest_axis]);
 	probe_data->set_dynamic_data(data);
 	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);
 	probe_data->set_to_cell_xform(baker.to_cell_space);
 
 
 	set_probe_data(probe_data);
 	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("set_dynamic_range","max"),&GIProbe::set_dynamic_range);
 	ObjectTypeDB::bind_method(_MD("get_dynamic_range"),&GIProbe::get_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("bake","from_node","create_visual_debug"),&GIProbe::bake,DEFVAL(Variant()),DEFVAL(false));
 	ObjectTypeDB::bind_method(_MD("debug_bake"),&GIProbe::_debug_bake);
 	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);
 	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::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::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"));
 	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() {
 GIProbe::GIProbe() {
 
 
 	subdiv=SUBDIV_128;
 	subdiv=SUBDIV_128;
-	dynamic_range=1.0;
+	dynamic_range=4;
+	energy=1.0;
 	extents=Vector3(10,10,10);
 	extents=Vector3(10,10,10);
 	color_scan_cell_width=4;
 	color_scan_cell_width=4;
 	bake_texture_size=128;
 	bake_texture_size=128;
+	interior=false;
 
 
 	gi_probe = VS::get_singleton()->gi_probe_create();
 	gi_probe = VS::get_singleton()->gi_probe_create();
 
 

+ 22 - 5
scene/3d/gi_probe.h

@@ -31,8 +31,14 @@ public:
 	void set_dynamic_data(const DVector<int>& p_data);
 	void set_dynamic_data(const DVector<int>& p_data);
 	DVector<int> get_dynamic_data() const;
 	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);
 	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;
 	DVector<uint8_t> get_static_data() const;
@@ -73,6 +79,7 @@ private:
 			uint32_t childs[8];
 			uint32_t childs[8];
 			float albedo[3]; //albedo in RGB24
 			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 emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
+			float normal[3];
 			uint32_t used_sides;
 			uint32_t used_sides;
 			float alpha; //used for upsampling
 			float alpha; //used for upsampling
 
 
@@ -84,6 +91,7 @@ private:
 				for(int i=0;i<3;i++) {
 				for(int i=0;i<3;i++) {
 					emission[i]=0;
 					emission[i]=0;
 					albedo[i]=0;
 					albedo[i]=0;
+					normal[i]=0;
 				}
 				}
 				alpha=0;
 				alpha=0;
 				used_sides=0;
 				used_sides=0;
@@ -126,7 +134,9 @@ private:
 
 
 	Subdiv subdiv;
 	Subdiv subdiv;
 	Vector3 extents;
 	Vector3 extents;
-	float dynamic_range;
+	int dynamic_range;
+	float energy;
+	bool interior;
 
 
 	int color_scan_cell_width;
 	int color_scan_cell_width;
 	int bake_texture_size;
 	int bake_texture_size;
@@ -157,8 +167,15 @@ public:
 	void set_extents(const Vector3& p_extents);
 	void set_extents(const Vector3& p_extents);
 	Vector3 get_extents() const;
 	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);
 	void bake(Node *p_from_node=NULL,bool p_create_visual_debug=false);
 
 

+ 3 - 0
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) {
 void Viewport::set_shadow_atlas_size(int p_size) {
 
 
+	if (shadow_atlas_size==p_size)
+		return;
+
 	shadow_atlas_size=p_size;
 	shadow_atlas_size=p_size;
 	VS::get_singleton()->viewport_set_shadow_atlas_size(viewport,p_size);
 	VS::get_singleton()->viewport_set_shadow_atlas_size(viewport,p_size);
 }
 }

+ 8 - 3
servers/visual/rasterizer.h

@@ -149,7 +149,7 @@ public:
 	virtual bool reflection_probe_instance_postprocess_step(RID p_instance)=0;
 	virtual bool reflection_probe_instance_postprocess_step(RID p_instance)=0;
 
 
 	virtual RID gi_probe_instance_create()=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_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;
 	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 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 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 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;
 	virtual DVector<uint8_t> gi_probe_get_static_data(RID p_gi_probe) const=0;

+ 8 - 2
servers/visual/visual_server_raster.h

@@ -816,8 +816,14 @@ public:
 	BIND2(gi_probe_set_to_cell_xform,RID,const Transform&)
 	BIND2(gi_probe_set_to_cell_xform,RID,const Transform&)
 	BIND1RC(Transform,gi_probe_get_to_cell_xform,RID)
 	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>& )
 	BIND2(gi_probe_set_dynamic_data,RID,const DVector<int>& )
 	BIND1RC( DVector<int>,gi_probe_get_dynamic_data,RID)
 	BIND1RC( DVector<int>,gi_probe_get_dynamic_data,RID)

+ 168 - 39
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->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);
 						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);
 			bool redraw = VSG::scene_render->shadow_atlas_update_light(p_shadow_atlas,light->instance,coverage,light->last_version);
 
 
 			if (redraw) {
 			if (redraw) {
+				print_line("redraw shadow");
 				//must redraw!
 				//must redraw!
 				_light_instance_update_shadow(ins,p_cam_transform,p_cam_projection,p_cam_orthogonal,p_shadow_atlas,scenario);
 				_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.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();
 		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();
 		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);
 		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->dynamic.enabled=false;
 		probe->invalid=!data.is_valid();
 		probe->invalid=!data.is_valid();
 		if (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) {
 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_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;
 	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) {
 	switch(light_cache.type) {
 
 
 		case VS::LIGHT_DIRECTIONAL: {
 		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;
 			float max_len = Vector3(limits[0],limits[1],limits[2]).length()*1.1;
 
 
 			Vector3 light_axis = -light_cache.transform.basis.get_axis(2).normalized();
 			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++) {
 			for(int i=0;i<3;i++) {
 
 
 				if (ABS(light_axis[i])<CMP_EPSILON)
 				if (ABS(light_axis[i])<CMP_EPSILON)
@@ -2578,29 +2604,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con
 				clip_planes++;
 				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;
 			int success_count=0;
 
 
@@ -2614,7 +2618,18 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con
 				InstanceGIProbeData::LocalData *light = &local_data[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 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;
 				Vector3 from = to - max_len * light_axis;
 
 
@@ -2642,16 +2657,130 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header,con
 
 
 				if (result==idx) {
 				if (result==idx) {
 					//cell hit itself! hooray!
 					//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("BAKE TIME: "+rtos((OS::get_singleton()->get_ticks_usec()-us)/1000000.0));
 			print_line("valid cells: "+itos(success_count));
 			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;
 		} break;
 	}
 	}
 }
 }
@@ -2760,9 +2889,9 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
 
 
 			uint32_t idx = level_cells[j];
 			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 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]);
 			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]);

+ 2 - 2
servers/visual/visual_server_scene.h

@@ -432,6 +432,7 @@ public:
 			Vector<Vector<uint32_t> > level_cell_lists;
 			Vector<Vector<uint32_t> > level_cell_lists;
 			RID probe_data;
 			RID probe_data;
 			bool enabled;
 			bool enabled;
+			int bake_dynamic_range;
 
 
 			Vector< DVector<uint8_t> > mipmaps_3d;
 			Vector< DVector<uint8_t> > mipmaps_3d;
 
 
@@ -536,7 +537,7 @@ public:
 		uint32_t children[8];
 		uint32_t children[8];
 		uint32_t albedo;
 		uint32_t albedo;
 		uint32_t emission;
 		uint32_t emission;
-		uint32_t sides_used;
+		uint32_t normal;
 		uint32_t alpha;
 		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);
 	_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_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_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);
 	void _bake_gi_probe(Instance *p_probe);
 	bool _check_gi_probe(Instance *p_gi_probe);
 	bool _check_gi_probe(Instance *p_gi_probe);

+ 8 - 2
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 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 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 {
 	enum GIProbeDataFormat {
 		GI_PROBE_DATA_RGBA8,
 		GI_PROBE_DATA_RGBA8,