work in progress global illumination

This commit is contained in:
Juan Linietsky 2016-12-20 00:21:07 -03:00
parent 22a90e8f2a
commit 075fde7f26
29 changed files with 5222 additions and 964 deletions

View file

@ -390,16 +390,16 @@ void Image::convert( Format p_new_format ){
case FORMAT_R8|(FORMAT_RG8<<8): _convert<1,false,2,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_R8|(FORMAT_RGB8<<8): _convert<1,false,3,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_R8|(FORMAT_RGBA8<<8): _convert<1,false,3,true,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_L8<<8): _convert<1,false,1,false,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_LA8<<8): _convert<1,false,1,true,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_R8<<8): _convert<1,false,1,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_RGB8<<8): _convert<1,false,3,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_RGBA8<<8): _convert<1,false,3,true,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_L8<<8): _convert<2,false,1,false,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_LA8<<8): _convert<2,false,1,true,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_R8<<8): _convert<2,false,1,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_RG8<<8): _convert<2,false,2,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_RGBA8<<8): _convert<2,false,3,true,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_L8<<8): _convert<2,false,1,false,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_LA8<<8): _convert<2,false,1,true,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_R8<<8): _convert<2,false,1,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_RGB8<<8): _convert<2,false,3,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RG8|(FORMAT_RGBA8<<8): _convert<2,false,3,true,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_L8<<8): _convert<3,false,1,false,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_LA8<<8): _convert<3,false,1,true,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_R8<<8): _convert<3,false,1,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_RG8<<8): _convert<3,false,2,false,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGB8|(FORMAT_RGBA8<<8): _convert<3,false,3,true,false,false>( width, height,rptr, wptr ); break;
case FORMAT_RGBA8|(FORMAT_L8<<8): _convert<3,true,1,false,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGBA8|(FORMAT_LA8<<8): _convert<3,true,1,true,false,true>( width, height,rptr, wptr ); break;
case FORMAT_RGBA8|(FORMAT_R8<<8): _convert<3,true,1,false,false,false>( width, height,rptr, wptr ); break;
@ -414,7 +414,7 @@ void Image::convert( Format p_new_format ){
bool gen_mipmaps=mipmaps;
mipmaps=false;
// mipmaps=false;
*this=new_img;

View file

@ -1010,6 +1010,48 @@ void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) {
light_instance->last_scene_pass=scene_pass;
}
//////////////////////
RID RasterizerSceneGLES3::gi_probe_instance_create() {
GIProbeInstance *gipi = memnew(GIProbeInstance);
return gi_probe_instance_owner.make_rid(gipi);
}
void RasterizerSceneGLES3::gi_probe_instance_set_light_data(RID p_probe,RID p_data) {
GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gipi);
gipi->data=p_data;
if (p_data.is_valid()) {
RasterizerStorageGLES3::GIProbeData *gipd = storage->gi_probe_data_owner.getornull(p_data);
ERR_FAIL_COND(!gipd);
if (gipd) {
gipi->tex_cache=gipd->tex_id;
gipi->cell_size_cache.x=1.0/gipd->width;
gipi->cell_size_cache.y=1.0/gipd->height;
gipi->cell_size_cache.z=1.0/gipd->depth;
}
}
}
void RasterizerSceneGLES3::gi_probe_instance_set_transform_to_data(RID p_probe,const Transform& p_xform) {
GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gipi);
gipi->transform_to_data=p_xform;
}
void RasterizerSceneGLES3::gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds) {
GIProbeInstance *gipi = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gipi);
gipi->bounds=p_bounds;
}
////////////////////////////
////////////////////////////
////////////////////////////
@ -1438,7 +1480,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
}
void RasterizerSceneGLES3::_setup_light(RenderList::Element *e) {
void RasterizerSceneGLES3::_setup_light(RenderList::Element *e,const Transform& p_view_transform) {
int omni_indices[16];
int omni_count=0;
@ -1509,7 +1551,33 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e) {
glUniform1iv(state.scene_shader.get_uniform(SceneShaderGLES3::REFLECTION_INDICES),reflection_count,reflection_indices);
}
int gi_probe_count = e->instance->gi_probe_instances.size();
if (gi_probe_count) {
const RID * ridp = e->instance->gi_probe_instances.ptr();
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-6);
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_CELL_SIZE1, gipi->cell_size_cache);
if (gi_probe_count>1) {
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-7);
glBindTexture(GL_TEXTURE_3D,gipi2->tex_cache);
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_PROBE2_ENABLED, true );
} else {
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, false );
}
}
}
@ -1672,11 +1740,15 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND,false);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5,false);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13,false);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES,false);
//state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true);
} else {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES,e->instance->gi_probe_instances.size()>0);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,false);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING,!p_directional_add);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL,false);
@ -1711,9 +1783,12 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
}
rebind=true;
}
if (p_alpha_pass || p_directional_add) {
int desired_blend_mode;
if (p_directional_add) {
@ -1794,7 +1869,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
}
if (!(e->sort_key&RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
_setup_light(e);
_setup_light(e,p_view_transform);
}
@ -1837,6 +1913,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,false);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5,false);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13,false);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES,false);
}
@ -1950,6 +2027,10 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
copymem(oe,e,sizeof(RenderList::Element));
}
if (e->instance->gi_probe_instances.size()) {
e->sort_key|=RenderList::SORT_KEY_GI_PROBES_FLAG;
}
}
//if (e->geometry->type==RasterizerStorageGLES3::Geometry::GEOMETRY_MULTISURFACE)

View file

@ -526,6 +526,25 @@ public:
virtual void light_instance_set_shadow_transform(RID p_light_instance,const CameraMatrix& p_projection,const Transform& p_transform,float p_far,float p_split,int p_pass);
virtual void light_instance_mark_visible(RID p_light_instance);
/* REFLECTION INSTANCE */
struct GIProbeInstance : public RID_Data {
RID data;
GLuint tex_cache;
Vector3 cell_size_cache;
Vector3 bounds;
Transform transform_to_data;
};
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_transform_to_data(RID p_probe,const Transform& p_xform);
virtual void gi_probe_instance_set_bounds(RID p_probe,const Vector3& p_bounds);
/* RENDER LIST */
struct RenderList {
@ -541,8 +560,9 @@ public:
SORT_KEY_DEPTH_LAYER_SHIFT=60,
SORT_KEY_UNSHADED_FLAG=uint64_t(1)<<59,
SORT_KEY_NO_DIRECTIONAL_FLAG=uint64_t(1)<<58,
SORT_KEY_SHADING_SHIFT=58,
SORT_KEY_SHADING_MASK=3,
SORT_KEY_GI_PROBES_FLAG=uint64_t(1)<<57,
SORT_KEY_SHADING_SHIFT=57,
SORT_KEY_SHADING_MASK=7,
SORT_KEY_MATERIAL_INDEX_SHIFT=40,
SORT_KEY_GEOMETRY_INDEX_SHIFT=20,
SORT_KEY_GEOMETRY_TYPE_SHIFT=15,
@ -669,7 +689,7 @@ public:
_FORCE_INLINE_ void _setup_transform(InstanceBase *p_instance,const Transform& p_view_transform,const CameraMatrix& p_projection);
_FORCE_INLINE_ void _setup_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e,const Transform& p_view_transform);
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform& p_view_transform, const CameraMatrix& p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);

View file

@ -1514,6 +1514,7 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
p_shader->valid=true;
p_shader->version++;
}
void RasterizerStorageGLES3::update_dirty_shaders() {
@ -3600,16 +3601,15 @@ void RasterizerStorageGLES3::multimesh_instance_set_color(RID p_multimesh,int p_
ERR_FAIL_COND(multimesh->color_format==VS::MULTIMESH_COLOR_NONE);
int stride = multimesh->color_floats+multimesh->xform_floats;
float *dataptr=&multimesh->data[stride*p_index+multimesh->color_floats];
float *dataptr=&multimesh->data[stride*p_index+multimesh->xform_floats];
if (multimesh->color_format==VS::MULTIMESH_COLOR_8BIT) {
union {
uint32_t colu;
float colf;
} cu;
cu.colu=p_color.to_32();
dataptr[ 0]=cu.colf;
uint8_t *data8=(uint8_t*)dataptr;
data8[0]=CLAMP(p_color.r*255.0,0,255);
data8[1]=CLAMP(p_color.g*255.0,0,255);
data8[2]=CLAMP(p_color.b*255.0,0,255);
data8[3]=CLAMP(p_color.a*255.0,0,255);
} else if (multimesh->color_format==VS::MULTIMESH_COLOR_FLOAT) {
dataptr[ 0]=p_color.r;
@ -3701,7 +3701,7 @@ Color RasterizerStorageGLES3::multimesh_instance_get_color(RID p_multimesh,int p
float colf;
} cu;
return Color::hex(cu.colu);
return Color::hex(BSWAP32(cu.colu));
} else if (multimesh->color_format==VS::MULTIMESH_COLOR_FLOAT) {
Color c;
@ -4385,6 +4385,15 @@ float RasterizerStorageGLES3::light_get_param(RID p_light,VS::LightParam p_param
return light->param[p_param];
}
Color RasterizerStorageGLES3::light_get_color(RID p_light) {
const Light * light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light,Color());
return light->color;
}
bool RasterizerStorageGLES3::light_has_shadow(RID p_light) const {
const Light * light = light_owner.getornull(p_light);
@ -4668,6 +4677,261 @@ void RasterizerStorageGLES3::portal_set_disabled_color(RID p_portal, const Color
}
RID RasterizerStorageGLES3::gi_probe_create() {
GIProbe *gip = memnew( GIProbe );
gip->data_width=0;
gip->data_height=0;
gip->data_depth=0;
gip->bounds=AABB(Vector3(),Vector3(1,1,1));
gip->dynamic_range=1.0;
gip->version=1;
gip->cell_size=1.0;
return gi_probe_owner.make_rid(gip);
}
void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe,const AABB& p_bounds){
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
gip->bounds=p_bounds;
gip->version++;
gip->instance_change_notify();
}
AABB RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const{
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,AABB());
return gip->bounds;
}
void RasterizerStorageGLES3::gi_probe_set_cell_size(RID p_probe,float p_size) {
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
gip->cell_size=p_size;
gip->version++;
gip->instance_change_notify();
}
float RasterizerStorageGLES3::gi_probe_get_cell_size(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,0);
return gip->cell_size;
}
void RasterizerStorageGLES3::gi_probe_set_to_cell_xform(RID p_probe,const Transform& p_xform) {
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
gip->to_cell=p_xform;
}
Transform RasterizerStorageGLES3::gi_probe_get_to_cell_xform(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,Transform());
return gip->to_cell;
}
void RasterizerStorageGLES3::gi_probe_set_dynamic_data(RID p_probe,const DVector<int>& p_data){
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
gip->dynamic_data=p_data;
gip->version++;
gip->instance_change_notify();
}
DVector<int> RasterizerStorageGLES3::gi_probe_get_dynamic_data(RID p_probe) const{
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,DVector<int>());
return gip->dynamic_data;
}
void RasterizerStorageGLES3::gi_probe_set_dynamic_range(RID p_probe,float p_range){
GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!gip);
gip->dynamic_range=p_range;
}
float 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);
return gip->dynamic_range;
}
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) {
GIProbe *gip = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gip);
if (gip->data.is_valid()) {
free(gip->data);
}
gip->data=RID();
//this is platform dependent
gip->version++;
gip->instance_change_notify();
}
DVector<uint8_t> RasterizerStorageGLES3::gi_probe_get_static_data(RID p_gi_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gip,DVector<uint8_t>());
//platform dependent
return DVector<uint8_t>();
}
VS::GIProbeDataFormat RasterizerStorageGLES3::gi_probe_get_static_data_format(RID p_gi_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gip,VS::GI_PROBE_DATA_RGBA8);
return gip->data_format;
}
int RasterizerStorageGLES3::gi_probe_get_static_data_width(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,0);
return gip->data_width;
}
int RasterizerStorageGLES3::gi_probe_get_static_data_height(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,0);
return gip->data_height;
}
int RasterizerStorageGLES3::gi_probe_get_static_data_depth(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,0);
return gip->data_depth;
}
RID RasterizerStorageGLES3::gi_probe_get_data(RID p_probe) {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,RID());
return gip->data;
}
uint32_t RasterizerStorageGLES3::gi_probe_get_version(RID p_probe) {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!gip,0);
return gip->version;
}
RID RasterizerStorageGLES3::gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth) {
GIProbeData *gipd = memnew( GIProbeData );
gipd->width=p_width;
gipd->height=p_height;
gipd->depth=p_depth;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1,&gipd->tex_id);
glBindTexture(GL_TEXTURE_3D,gipd->tex_id);
int level=0;
print_line("dyndata create");
while(true) {
Vector<uint8_t> data;
data.resize(p_width*p_height*p_depth*4);
for(int i=0;i<data.size();i+=4) {
data[i+0]=0xFF;
data[i+1]=0x00;
data[i+2]=0xFF;
data[i+3]=0xFF;
}
glTexImage3D(GL_TEXTURE_3D,level,GL_RGBA8,p_width,p_height,p_depth,0,GL_RGBA,GL_UNSIGNED_BYTE,data.ptr());
if (p_width<=1 || p_height<=1 || p_depth<=1)
break;
p_width>>=1;
p_height>>=1;
p_depth>>=1;
level++;
}
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, level);
gipd->levels=level+1;
return gi_probe_data_owner.make_rid(gipd);
}
void RasterizerStorageGLES3::gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_data, int p_depth_slice, int p_slice_count, int p_mipmap, const void *p_data) {
GIProbeData *gipd = gi_probe_data_owner.getornull(p_gi_probe_data);
ERR_FAIL_COND(!gipd);
/*
Vector<uint8_t> data;
data.resize((gipd->width>>p_mipmap)*(gipd->height>>p_mipmap)*(gipd->depth>>p_mipmap)*4);
for(int i=0;i<(gipd->width>>p_mipmap);i++) {
for(int j=0;j<(gipd->height>>p_mipmap);j++) {
for(int k=0;k<(gipd->depth>>p_mipmap);k++) {
int ofs = (k*(gipd->height>>p_mipmap)*(gipd->width>>p_mipmap)) + j *(gipd->width>>p_mipmap) + i;
ofs*=4;
data[ofs+0]=i*0xFF/(gipd->width>>p_mipmap);
data[ofs+1]=j*0xFF/(gipd->height>>p_mipmap);
data[ofs+2]=k*0xFF/(gipd->depth>>p_mipmap);
data[ofs+3]=0xFF;
}
}
}
*/
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D,gipd->tex_id);
glTexSubImage3D(GL_TEXTURE_3D,p_mipmap,0,0,p_depth_slice,gipd->width>>p_mipmap,gipd->height>>p_mipmap,p_slice_count,GL_RGBA,GL_UNSIGNED_BYTE,p_data);
//glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,p_data);
//glTexImage3D(GL_TEXTURE_3D,p_mipmap,GL_RGBA8,gipd->width>>p_mipmap,gipd->height>>p_mipmap,gipd->depth>>p_mipmap,0,GL_RGBA,GL_UNSIGNED_BYTE,data.ptr());
print_line("update rgba8 "+itos(p_mipmap));
}
void RasterizerStorageGLES3::instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
@ -4709,6 +4973,10 @@ void RasterizerStorageGLES3::instance_add_dependency(RID p_base,RasterizerScene:
inst = light_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
case VS::INSTANCE_GI_PROBE: {
inst = gi_probe_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
default: {
if (!inst) {
ERR_FAIL();
@ -4744,6 +5012,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
inst = light_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
case VS::INSTANCE_GI_PROBE: {
inst = gi_probe_owner.getornull(p_base);
ERR_FAIL_COND(!inst);
} break;
default: {
if (!inst) {
@ -5395,19 +5667,27 @@ VS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const {
if (mesh_owner.owns(p_rid)) {
return VS::INSTANCE_MESH;
}
if (multimesh_owner.owns(p_rid)) {
return VS::INSTANCE_MULTIMESH;
}
if (immediate_owner.owns(p_rid)) {
return VS::INSTANCE_IMMEDIATE;
}
if (light_owner.owns(p_rid)) {
return VS::INSTANCE_LIGHT;
}
if (reflection_probe_owner.owns(p_rid)) {
return VS::INSTANCE_REFLECTION_PROBE;
}
if (gi_probe_owner.owns(p_rid)) {
return VS::INSTANCE_GI_PROBE;
}
return VS::INSTANCE_NONE;
}
@ -5561,6 +5841,27 @@ bool RasterizerStorageGLES3::free(RID p_rid){
reflection_probe_owner.free(p_rid);
memdelete(reflection_probe);
} else if (gi_probe_owner.owns(p_rid)) {
// delete the texture
GIProbe *gi_probe = gi_probe_owner.get(p_rid);
if (gi_probe->data.is_valid()) {
free(gi_probe->data);
}
gi_probe_owner.free(p_rid);
memdelete(gi_probe);
} else if (gi_probe_data_owner.owns(p_rid)) {
// delete the texture
GIProbeData *gi_probe_data = gi_probe_data_owner.get(p_rid);
print_line("dyndata delete");
glDeleteTextures(1,&gi_probe_data->tex_id);
gi_probe_owner.free(p_rid);
memdelete(gi_probe_data);
} else if (canvas_occluder_owner.owns(p_rid)) {

View file

@ -799,6 +799,7 @@ public:
virtual VS::LightType light_get_type(RID p_light) const;
virtual float light_get_param(RID p_light,VS::LightParam p_param);
virtual Color light_get_color(RID p_light);
virtual AABB light_get_aabb(RID p_light) const;
virtual uint64_t light_get_version(RID p_light) const;
@ -868,6 +869,84 @@ public:
virtual void portal_set_disable_distance(RID p_portal, float p_distance);
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color);
/* GI PROBE API */
struct GIProbe : public Instantiable {
AABB bounds;
Transform to_cell;
float cell_size;
float dynamic_range;
uint32_t version;
DVector<int> dynamic_data;
RID data;
int data_width;
int data_height;
int data_depth;
VS::GIProbeDataFormat data_format;
};
mutable RID_Owner<GIProbe> gi_probe_owner;
virtual RID gi_probe_create();
virtual void gi_probe_set_bounds(RID p_probe,const AABB& p_bounds);
virtual AABB gi_probe_get_bounds(RID p_probe) const;
virtual void gi_probe_set_cell_size(RID p_probe, float p_size);
virtual float gi_probe_get_cell_size(RID p_probe) const;
virtual void gi_probe_set_to_cell_xform(RID p_probe,const Transform& p_xform);
virtual Transform gi_probe_get_to_cell_xform(RID p_probe) const;
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_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 VS::GIProbeDataFormat gi_probe_get_static_data_format(RID p_gi_probe) const;
virtual int gi_probe_get_static_data_width(RID p_probe) const;
virtual int gi_probe_get_static_data_height(RID p_probe) const;
virtual int gi_probe_get_static_data_depth(RID p_probe) const;
virtual RID gi_probe_get_data(RID p_probe); //get data in case this is static
virtual uint32_t gi_probe_get_version(RID p_probe);
struct GIProbeData : public RID_Data {
int width;
int height;
int depth;
int levels;
GLuint tex_id;
GIProbeData() {
}
};
mutable RID_Owner<GIProbeData> gi_probe_data_owner;
virtual RID gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth);
virtual void gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_data,int p_depth_slice,int p_slice_count,int p_mipmap,const void* p_data);
virtual void instance_add_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance);
virtual void instance_remove_skeleton(RID p_skeleton,RasterizerScene::InstanceBase *p_instance);

View file

@ -838,6 +838,131 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
}
}
#ifdef USE_GI_PROBES
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 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 bool gi_probe2_enabled;
vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, 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 alpha=0.0;
vec4 color = vec4(0.0);
while(dist < max_distance && alpha < 0.95) {
float diameter = max(1.0, 2.0 * tan_half_angle * dist);
vec4 scolor = textureLod(probe, (pos + dist * direction) * cell_size, log2(diameter) );
float a = (1.0 - alpha);
color.rgb += a * scolor.rgb;
alpha += a * scolor.a;
dist += diameter * 0.5;
}
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) {
vec3 probe_pos = (probe_xform * vec4(pos,1.0)).xyz;
vec3 ref_pos = (probe_xform * vec4(pos+ref_vec,1.0)).xyz;
ref_vec = normalize(ref_pos - probe_pos);
/* out_diff.rgb = voxel_cone_trace(probe,cell_size,probe_pos,normalize((probe_xform * vec4(ref_vec,0.0)).xyz),0.0 ,100.0);
out_diff.a = 1.0;
return;*/
//out_diff = vec4(textureLod(probe,probe_pos*cell_size,3.0).rgb,1.0);
//return;
if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds)))))
return;
vec3 blendv = probe_pos/bounds * 2.0 - 1.0;
float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z));
blend=1.0;
//radiance
#define MAX_CONE_DIRS 6
vec3 cone_dirs[MAX_CONE_DIRS] = vec3[] (
vec3(0, 0, 1),
vec3(0.866025, 0, 0.5),
vec3(0.267617, 0.823639, 0.5),
vec3(-0.700629, 0.509037, 0.5),
vec3(-0.700629, -0.509037, 0.5),
vec3(0.267617, -0.823639, 0.5)
);
float cone_weights[MAX_CONE_DIRS] = float[](0.25, 0.15, 0.15, 0.15, 0.15, 0.15);
float max_distance = length(bounds);
vec3 light=vec3(0.0);
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,0.577,max_distance);
}
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);
//irr_light=vec3(0.0);
out_spec = vec4(irr_light*blend,blend);
}
void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, inout vec3 out_specular, inout vec3 out_ambient) {
vec3 ref_vec = normalize(reflect(normalize(pos),normal));
//find arbitrary tangent and bitangent, then build a matrix
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0);
vec3 tangent = normalize(cross(v0, normal));
vec3 bitangent = normalize(cross(tangent, normal));
mat3 normal_mat = mat3(tangent,bitangent,normal);
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);
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);
}
if (diff_accum.a>0.0) {
diff_accum.rgb/=diff_accum.a;
}
if (spec_accum.a>0.0) {
spec_accum.rgb/=spec_accum.a;
}
out_specular+=spec_accum.rgb;
out_ambient+=diff_accum.rgb;
}
#endif
void main() {
#ifdef RENDER_SHADOW_DUAL_PARABOLOID
@ -1161,21 +1286,27 @@ FRAGMENT_SHADER_CODE
#endif //#USE_LIGHT_DIRECTIONAL
#ifdef USE_GI_PROBES
gi_probes_compute(vertex,normal,roughness,specular,specular_light,ambient_light);
#endif
#ifdef USE_FORWARD_LIGHTING
highp vec4 reflection_accum = vec4(0.0,0.0,0.0,0.0);
highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0);
for(int i=0;i<reflection_count;i++) {
reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,brdf,reflection_accum,ambient_accum);
}
if (reflection_accum.a>0.0) {
specular_light=reflection_accum.rgb/reflection_accum.a;
specular_light+=reflection_accum.rgb/reflection_accum.a;
}
if (ambient_accum.a>0.0) {
ambient_light=ambient_accum.rgb/ambient_accum.a;
ambient_light+=ambient_accum.rgb/ambient_accum.a;
}
for(int i=0;i<omni_light_count;i++) {

File diff suppressed because it is too large Load diff

View file

@ -31,38 +31,142 @@
#include "scene/3d/visual_instance.h"
#include "scene/resources/baked_light.h"
#include "scene/3d/multimesh_instance.h"
#if 0
class BakedLightBaker;
class Light;
class BakedLight : public VisualInstance {
OBJ_TYPE(BakedLight,VisualInstance);
public:
enum DebugMode {
DEBUG_ALBEDO,
DEBUG_LIGHT
};
private:
RID baked_light;
int cell_subdiv;
AABB bounds;
int cells_per_axis;
enum {
CHILD_EMPTY=0xFFFFFFFF,
};
class BakedLightInstance : public VisualInstance {
OBJ_TYPE(BakedLightInstance,VisualInstance);
/* BAKE DATA */
Ref<BakedLight> baked_light;
struct BakeCell {
uint32_t childs[8];
float albedo[3]; //albedo in RGB24
float light[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
float radiance[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
uint32_t used_sides;
float alpha; //used for upsampling
uint32_t light_pass; //used for baking light
BakeCell() {
for(int i=0;i<8;i++) {
childs[i]=0xFFFFFFFF;
}
for(int i=0;i<3;i++) {
light[i]=0;
albedo[i]=0;
radiance[i]=0;
}
alpha=0;
light_pass=0;
used_sides=0;
}
};
int bake_texture_size;
int color_scan_cell_width;
struct MaterialCache {
//128x128 textures
Vector<Color> albedo;
Vector<Color> emission;
};
Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
Map<Ref<Material>,MaterialCache> material_cache;
MaterialCache _get_material_cache(Ref<Material> p_material);
int bake_cells_alloc;
int bake_cells_used;
int zero_alphas;
Vector<int> bake_cells_level_used;
DVector<BakeCell> bake_cells;
DVector<BakeCell>::Write bake_cells_write;
void _plot_face(int p_idx,int p_level,const Vector3 *p_vtx,const Vector2* p_uv, const MaterialCache& p_material,const AABB& p_aabb);
void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z);
void _bake_add_mesh(const Transform& p_xform,Ref<Mesh>& p_mesh);
void _bake_add_to_aabb(const Transform& p_xform,Ref<Mesh>& p_mesh,bool &first);
void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb,DebugMode p_mode,Ref<MultiMesh> &p_multimesh,int &idx);
void _debug_mesh_albedo();
void _debug_mesh_light();
_FORCE_INLINE_ int _find_cell(int x,int y, int z);
int _plot_ray(const Vector3& p_from, const Vector3& p_to);
uint32_t light_pass;
void _bake_directional(int p_idx, int p_level, int p_x,int p_y,int p_z,const Vector3& p_dir,const Color& p_color,int p_sign);
void _upscale_light(int p_idx,int p_level);
void _bake_light(Light* p_light);
Color _cone_trace(const Vector3& p_from, const Vector3& p_dir, float p_half_angle);
void _bake_radiance(int p_idx, int p_level, int p_x,int p_y,int p_z);
friend class GeometryInstance;
Set<GeometryInstance*> geometries;
friend class Light;
Set<Light*> lights;
protected:
static void _bind_methods();
public:
void set_cell_subdiv(int p_subdiv);
int get_cell_subdiv() const;
RID get_baked_light_instance() const;
void bake();
void bake_lights();
void bake_radiance();
void set_baked_light(const Ref<BakedLight>& baked_light);
Ref<BakedLight> get_baked_light() const;
void create_debug_mesh(DebugMode p_mode);
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
String get_configuration_warning() const;
BakedLightInstance();
BakedLight();
~BakedLight();
};
#if 0
class BakedLightSampler : public VisualInstance {
OBJ_TYPE(BakedLightSampler,VisualInstance);

1248
scene/3d/gi_probe.cpp Normal file

File diff suppressed because it is too large Load diff

174
scene/3d/gi_probe.h Normal file
View file

@ -0,0 +1,174 @@
#ifndef GIPROBE_H
#define GIPROBE_H
#include "scene/3d/visual_instance.h"
#include "multimesh_instance.h"
class GIProbeData : public Resource {
OBJ_TYPE(GIProbeData,Resource);
RID probe;
public:
enum DataFormat {
DATA_RGBA8,
DATA_DXT5,
DATA_ETC2_EAC,
};
void set_bounds(const AABB& p_bounds);
AABB get_bounds() const;
void set_cell_size(float p_size);
float get_cell_size() const;
void set_to_cell_xform(const Transform& p_xform);
Transform get_to_cell_xform() const;
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_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;
DataFormat get_static_data_format() const;
int get_static_data_width() const;
int get_static_data_height() const;
int get_static_data_depth() const;
virtual RID get_rid() const;
GIProbeData();
~GIProbeData();
};
VARIANT_ENUM_CAST(GIProbeData::DataFormat);
class GIProbe : public VisualInstance {
OBJ_TYPE(GIProbe,VisualInstance);
public:
enum Subdiv{
SUBDIV_64,
SUBDIV_128,
SUBDIV_256,
SUBDIV_512,
SUBDIV_MAX
};
private:
//stuff used for bake
struct Baker {
enum {
CHILD_EMPTY=0xFFFFFFFF
};
struct Cell {
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)
uint32_t used_sides;
float alpha; //used for upsampling
Cell() {
for(int i=0;i<8;i++) {
childs[i]=CHILD_EMPTY;
}
for(int i=0;i<3;i++) {
emission[i]=0;
albedo[i]=0;
}
alpha=0;
used_sides=0;
}
};
Vector<Cell> bake_cells;
int cell_subdiv;
struct MaterialCache {
//128x128 textures
Vector<Color> albedo;
Vector<Color> emission;
};
Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
Map<Ref<Material>,MaterialCache> material_cache;
MaterialCache _get_material_cache(Ref<Material> p_material);
int leaf_voxel_count;
AABB po2_bounds;
int axis_cell_size[3];
struct PlotMesh {
Ref<Mesh> mesh;
Transform local_xform;
};
Transform to_cell_space;
List<PlotMesh> mesh_list;
};
Ref<GIProbeData> probe_data;
RID gi_probe;
Subdiv subdiv;
Vector3 extents;
float dynamic_range;
int color_scan_cell_width;
int bake_texture_size;
Vector<Color> _get_bake_texture(Image &p_image,const Color& p_color);
Baker::MaterialCache _get_material_cache(Ref<Material> p_material,Baker *p_baker);
void _plot_face(int p_idx, int p_level, int p_x,int p_y,int p_z,const Vector3 *p_vtx, const Vector2* p_uv, const Baker::MaterialCache& p_material, const AABB &p_aabb,Baker *p_baker);
void _plot_mesh(const Transform& p_xform, Ref<Mesh>& p_mesh, Baker *p_baker);
void _find_meshes(Node *p_at_node,Baker *p_baker);
void _fixup_plot(int p_idx, int p_level,int p_x,int p_y, int p_z,Baker *p_baker);
void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb,Ref<MultiMesh> &p_multimesh,int &idx,Baker *p_baker);
void _create_debug_mesh(Baker *p_baker);
void _debug_bake();
protected:
static void _bind_methods();
public:
void set_probe_data(const Ref<GIProbeData>& p_data);
Ref<GIProbeData> get_probe_data() const;
void set_subdiv(Subdiv p_subdiv);
Subdiv get_subdiv() const;
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 bake(Node *p_from_node=NULL,bool p_create_visual_debug=false);
virtual AABB get_aabb() const;
virtual DVector<Face3> get_faces(uint32_t p_usage_flags) const;
GIProbe();
~GIProbe();
};
VARIANT_ENUM_CAST(GIProbe::Subdiv)
#endif // GIPROBE_H

View file

@ -30,7 +30,7 @@
#include "globals.h"
#include "scene/resources/surface_tool.h"
#include "baked_light_instance.h"
bool Light::_can_gizmo_scale() const {
@ -168,9 +168,37 @@ void Light::_update_visibility() {
void Light::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE || p_what==NOTIFICATION_VISIBILITY_CHANGED) {
if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
_update_visibility();
}
if (p_what==NOTIFICATION_ENTER_TREE) {
_update_visibility();
Node *node = this;
while(node) {
baked_light=node->cast_to<BakedLight>();
if (baked_light) {
baked_light->lights.insert(this);
break;
}
node=node->get_parent();
}
}
if (p_what==NOTIFICATION_EXIT_TREE) {
if (baked_light) {
baked_light->lights.erase(this);
}
}
}
@ -247,6 +275,8 @@ Light::Light(VisualServer::LightType p_type) {
light=VisualServer::get_singleton()->light_create(p_type);
VS::get_singleton()->instance_set_base(get_instance(),light);
baked_light=NULL;
editor_only=false;
set_color(Color(1,1,1,1));
set_shadow(false);

View file

@ -37,6 +37,10 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class BakedLight;
class Light : public VisualInstance {
OBJ_TYPE( Light, VisualInstance );
@ -72,6 +76,8 @@ private:
VS::LightType type;
bool editor_only;
void _update_visibility();
BakedLight *baked_light;
// bind helpers
protected:

View file

@ -31,7 +31,6 @@
#include "servers/visual_server.h"
#include "room_instance.h"
#include "scene/scene_string_names.h"
#include "baked_light_instance.h"
#include "skeleton.h"
AABB VisualInstance::get_transformed_aabb() const {
@ -227,7 +226,6 @@ void GeometryInstance::_notification(int p_what) {
if (flags[FLAG_USE_BAKED_LIGHT]) {
_find_baked_light();
}
_update_visibility();
@ -236,11 +234,6 @@ void GeometryInstance::_notification(int p_what) {
if (flags[FLAG_USE_BAKED_LIGHT]) {
if (baked_light_instance) {
// baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
// baked_light_instance=NULL;
}
_baked_light_changed();
}
@ -252,37 +245,6 @@ void GeometryInstance::_notification(int p_what) {
}
void GeometryInstance::_baked_light_changed() {
//if (!baked_light_instance)
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),RID());
// else
// VS::get_singleton()->instance_geometry_set_baked_light(get_instance(),baked_light_instance->get_baked_light_instance());
}
void GeometryInstance::_find_baked_light() {
/*
Node *n=get_parent();
while(n) {
BakedLightInstance *bl=n->cast_to<BakedLightInstance>();
if (bl) {
baked_light_instance=bl;
baked_light_instance->connect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
_baked_light_changed();
return;
}
n=n->get_parent();
}
_baked_light_changed();
*/
}
void GeometryInstance::_update_visibility() {
if (!is_inside_tree())
@ -314,17 +276,6 @@ void GeometryInstance::set_flag(Flags p_flag,bool p_value) {
}
if (p_flag==FLAG_USE_BAKED_LIGHT) {
/* if (is_inside_world()) {
if (!p_value) {
if (baked_light_instance) {
baked_light_instance->disconnect(SceneStringNames::get_singleton()->baked_light_changed,this,SceneStringNames::get_singleton()->_baked_light_changed);
baked_light_instance=NULL;
}
_baked_light_changed();
} else {
_find_baked_light();
}
}*/
}
}
@ -357,17 +308,8 @@ GeometryInstance::ShadowCastingSetting GeometryInstance::get_cast_shadows_settin
return shadow_casting_setting;
}
void GeometryInstance::set_baked_light_texture_id(int p_id) {
// baked_light_texture_id=p_id;
// VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),baked_light_texture_id);
}
int GeometryInstance::get_baked_light_texture_id() const{
return baked_light_texture_id;
}
void GeometryInstance::set_extra_cull_margin(float p_margin) {
@ -405,15 +347,11 @@ void GeometryInstance::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_lod_min_distance"), &GeometryInstance::get_lod_min_distance);
ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id);
ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id);
ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin);
ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin);
ObjectTypeDB::bind_method(_MD("get_aabb"),&GeometryInstance::get_aabb);
ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "geometry/material_override",PROPERTY_HINT_RESOURCE_TYPE,"Material"), _SCS("set_material_override"), _SCS("get_material_override"));
@ -424,7 +362,6 @@ void GeometryInstance::_bind_methods() {
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible_in_all_rooms"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE_IN_ALL_ROOMS);
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/use_baked_light"), _SCS("set_flag"), _SCS("get_flag"),FLAG_USE_BAKED_LIGHT);
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/baked_light_tex_id"), _SCS("set_baked_light_texture_id"), _SCS("get_baked_light_texture_id"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_distance"), _SCS("get_lod_min_distance"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/min_hysteresis",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_min_hysteresis"), _SCS("get_lod_min_hysteresis"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "lod/max_distance",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_lod_max_distance"), _SCS("get_lod_max_distance"));
@ -461,8 +398,6 @@ GeometryInstance::GeometryInstance() {
flags[FLAG_CAST_SHADOW]=true;
shadow_casting_setting=SHADOW_CASTING_SETTING_ON;
baked_light_instance=NULL;
baked_light_texture_id=0;
extra_cull_margin=0;
// VS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);

View file

@ -79,7 +79,7 @@ public:
};
class BakedLightInstance;
class BakedLight;
class GeometryInstance : public VisualInstance {
@ -114,12 +114,9 @@ private:
float lod_max_distance;
float lod_min_hysteresis;
float lod_max_hysteresis;
void _find_baked_light();
BakedLightInstance *baked_light_instance;
int baked_light_texture_id;
float extra_cull_margin;
void _baked_light_changed();
void _update_visibility();
protected:
@ -148,9 +145,6 @@ public:
void set_material_override(const Ref<Material>& p_material);
Ref<Material> get_material_override() const;
void set_baked_light_texture_id(int p_id);
int get_baked_light_texture_id() const;
void set_extra_cull_margin(float p_margin);
float get_extra_cull_margin() const;

View file

@ -205,6 +205,7 @@
#include "scene/3d/quad.h"
#include "scene/3d/light.h"
#include "scene/3d/reflection_probe.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/particles.h"
#include "scene/3d/portal.h"
#include "scene/resources/environment.h"
@ -424,6 +425,8 @@ void register_scene_types() {
ObjectTypeDB::register_type<OmniLight>();
ObjectTypeDB::register_type<SpotLight>();
ObjectTypeDB::register_type<ReflectionProbe>();
ObjectTypeDB::register_type<GIProbe>();
ObjectTypeDB::register_type<GIProbeData>();
ObjectTypeDB::register_type<AnimationTreePlayer>();
ObjectTypeDB::register_type<Portal>();
//ObjectTypeDB::register_type<Particles>();
@ -455,7 +458,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PathFollow>();
ObjectTypeDB::register_type<VisibilityNotifier>();
ObjectTypeDB::register_type<VisibilityEnabler>();
//ObjectTypeDB::register_type<BakedLightInstance>();
ObjectTypeDB::register_type<BakedLight>();
//ObjectTypeDB::register_type<BakedLightSampler>();
ObjectTypeDB::register_type<WorldEnvironment>();
ObjectTypeDB::register_type<RemoteTransform>();

View file

@ -29,577 +29,3 @@
#include "baked_light.h"
#include "servers/visual_server.h"
#if 0
void BakedLight::set_mode(Mode p_mode) {
mode=p_mode;
VS::get_singleton()->baked_light_set_mode(baked_light,(VS::BakedLightMode(p_mode)));
}
BakedLight::Mode BakedLight::get_mode() const{
return mode;
}
void BakedLight::set_octree(const DVector<uint8_t>& p_octree) {
VS::get_singleton()->baked_light_set_octree(baked_light,p_octree);
}
DVector<uint8_t> BakedLight::get_octree() const {
return VS::get_singleton()->baked_light_get_octree(baked_light);
}
void BakedLight::set_light(const DVector<uint8_t>& p_light) {
VS::get_singleton()->baked_light_set_light(baked_light,p_light);
}
DVector<uint8_t> BakedLight::get_light() const {
return VS::get_singleton()->baked_light_get_light(baked_light);
}
void BakedLight::set_sampler_octree(const DVector<int>& p_sampler_octree) {
VS::get_singleton()->baked_light_set_sampler_octree(baked_light,p_sampler_octree);
}
DVector<int> BakedLight::get_sampler_octree() const {
return VS::get_singleton()->baked_light_get_sampler_octree(baked_light);
}
void BakedLight::add_lightmap(const Ref<Texture> &p_texture,Size2 p_gen_size) {
LightMap lm;
lm.texture=p_texture;
lm.gen_size=p_gen_size;
lightmaps.push_back(lm);
_update_lightmaps();
_change_notify();
}
void BakedLight::set_lightmap_gen_size(int p_idx,const Size2& p_size){
ERR_FAIL_INDEX(p_idx,lightmaps.size());
lightmaps[p_idx].gen_size=p_size;
_update_lightmaps();
}
Size2 BakedLight::get_lightmap_gen_size(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,lightmaps.size(),Size2());
return lightmaps[p_idx].gen_size;
}
void BakedLight::set_lightmap_texture(int p_idx,const Ref<Texture> &p_texture){
ERR_FAIL_INDEX(p_idx,lightmaps.size());
lightmaps[p_idx].texture=p_texture;
_update_lightmaps();
}
Ref<Texture> BakedLight::get_lightmap_texture(int p_idx) const{
ERR_FAIL_INDEX_V(p_idx,lightmaps.size(),Ref<Texture>());
return lightmaps[p_idx].texture;
}
void BakedLight::erase_lightmap(int p_idx){
ERR_FAIL_INDEX(p_idx,lightmaps.size());
lightmaps.remove(p_idx);
_update_lightmaps();
_change_notify();
}
int BakedLight::get_lightmaps_count() const{
return lightmaps.size();
}
void BakedLight::clear_lightmaps(){
lightmaps.clear();
_update_lightmaps();
_change_notify();
}
void BakedLight::_update_lightmaps() {
VS::get_singleton()->baked_light_clear_lightmaps(baked_light);
for(int i=0;i<lightmaps.size();i++) {
RID tid;
if (lightmaps[i].texture.is_valid())
tid=lightmaps[i].texture->get_rid();
VS::get_singleton()->baked_light_add_lightmap(baked_light,tid,i);
}
}
RID BakedLight::get_rid() const {
return baked_light;
}
Array BakedLight::_get_lightmap_data() const {
Array ret;
ret.resize(lightmaps.size()*2);
int idx=0;
for(int i=0;i<lightmaps.size();i++) {
ret[idx++]=Size2(lightmaps[i].gen_size);
ret[idx++]=lightmaps[i].texture;
}
return ret;
}
void BakedLight::_set_lightmap_data(Array p_array){
lightmaps.clear();
for(int i=0;i<p_array.size();i+=2) {
Size2 size = p_array[i];
Ref<Texture> tex = p_array[i+1];
// ERR_CONTINUE(tex.is_null());
LightMap lm;
lm.gen_size=size;
lm.texture=tex;
lightmaps.push_back(lm);
}
_update_lightmaps();
}
void BakedLight::set_cell_subdivision(int p_subdiv) {
cell_subdiv=p_subdiv;
}
int BakedLight::get_cell_subdivision() const{
return cell_subdiv;
}
void BakedLight::set_initial_lattice_subdiv(int p_size){
lattice_subdiv=p_size;
}
int BakedLight::get_initial_lattice_subdiv() const{
return lattice_subdiv;
}
void BakedLight::set_plot_size(float p_size){
plot_size=p_size;
}
float BakedLight::get_plot_size() const{
return plot_size;
}
void BakedLight::set_bounces(int p_size){
bounces=p_size;
}
int BakedLight::get_bounces() const{
return bounces;
}
void BakedLight::set_cell_extra_margin(float p_margin) {
cell_extra_margin=p_margin;
}
float BakedLight::get_cell_extra_margin() const {
return cell_extra_margin;
}
void BakedLight::set_edge_damp(float p_margin) {
edge_damp=p_margin;
}
float BakedLight::get_edge_damp() const {
return edge_damp;
}
void BakedLight::set_normal_damp(float p_margin) {
normal_damp=p_margin;
}
float BakedLight::get_normal_damp() const {
return normal_damp;
}
void BakedLight::set_tint(float p_margin) {
tint=p_margin;
}
float BakedLight::get_tint() const {
return tint;
}
void BakedLight::set_saturation(float p_margin) {
saturation=p_margin;
}
float BakedLight::get_saturation() const {
return saturation;
}
void BakedLight::set_ao_radius(float p_ao_radius) {
ao_radius=p_ao_radius;
}
float BakedLight::get_ao_radius() const {
return ao_radius;
}
void BakedLight::set_ao_strength(float p_ao_strength) {
ao_strength=p_ao_strength;
}
float BakedLight::get_ao_strength() const {
return ao_strength;
}
void BakedLight::set_realtime_color_enabled(const bool p_realtime_color_enabled) {
VS::get_singleton()->baked_light_set_realtime_color_enabled(baked_light, p_realtime_color_enabled);
}
bool BakedLight::get_realtime_color_enabled() const {
return VS::get_singleton()->baked_light_get_realtime_color_enabled(baked_light);
}
void BakedLight::set_realtime_color(const Color &p_realtime_color) {
VS::get_singleton()->baked_light_set_realtime_color(baked_light, p_realtime_color);
}
Color BakedLight::get_realtime_color() const {
return VS::get_singleton()->baked_light_get_realtime_color(baked_light);
}
void BakedLight::set_realtime_energy(const float p_realtime_energy) {
VS::get_singleton()->baked_light_set_realtime_energy(baked_light, p_realtime_energy);
}
float BakedLight::get_realtime_energy() const {
return VS::get_singleton()->baked_light_get_realtime_energy(baked_light);
}
void BakedLight::set_energy_multiplier(float p_multiplier){
energy_multiply=p_multiplier;
}
float BakedLight::get_energy_multiplier() const{
return energy_multiply;
}
void BakedLight::set_gamma_adjust(float p_adjust){
gamma_adjust=p_adjust;
}
float BakedLight::get_gamma_adjust() const{
return gamma_adjust;
}
void BakedLight::set_bake_flag(BakeFlags p_flags,bool p_enable){
flags[p_flags]=p_enable;
}
bool BakedLight::get_bake_flag(BakeFlags p_flags) const{
return flags[p_flags];
}
void BakedLight::set_format(Format p_format) {
format=p_format;
VS::get_singleton()->baked_light_set_lightmap_multiplier(baked_light,format==FORMAT_HDR8?8.0:1.0);
}
BakedLight::Format BakedLight::get_format() const{
return format;
}
void BakedLight::set_transfer_lightmaps_only_to_uv2(bool p_enable) {
transfer_only_uv2=p_enable;
}
bool BakedLight::get_transfer_lightmaps_only_to_uv2() const{
return transfer_only_uv2;
}
bool BakedLight::_set(const StringName& p_name, const Variant& p_value) {
String n = p_name;
if (!n.begins_with("lightmap"))
return false;
int idx = n.get_slicec('/',1).to_int();
ERR_FAIL_COND_V(idx<0,false);
ERR_FAIL_COND_V(idx>lightmaps.size(),false);
String what = n.get_slicec('/',2);
Ref<Texture> tex;
Size2 gens;
if (what=="texture")
tex=p_value;
else if (what=="gen_size")
gens=p_value;
if (idx==lightmaps.size()) {
if (tex.is_valid() || gens!=Size2())
add_lightmap(tex,gens);
} else {
if (tex.is_valid())
set_lightmap_texture(idx,tex);
else if (gens!=Size2())
set_lightmap_gen_size(idx,gens);
}
return true;
}
bool BakedLight::_get(const StringName& p_name,Variant &r_ret) const{
String n = p_name;
if (!n.begins_with("lightmap"))
return false;
int idx = n.get_slicec('/',1).to_int();
ERR_FAIL_COND_V(idx<0,false);
ERR_FAIL_COND_V(idx>lightmaps.size(),false);
String what = n.get_slicec('/',2);
if (what=="texture") {
if (idx==lightmaps.size())
r_ret=Ref<Texture>();
else
r_ret=lightmaps[idx].texture;
} else if (what=="gen_size") {
if (idx==lightmaps.size())
r_ret=Size2();
else
r_ret=Size2(lightmaps[idx].gen_size);
} else
return false;
return true;
}
void BakedLight::_get_property_list( List<PropertyInfo> *p_list) const{
for(int i=0;i<=lightmaps.size();i++) {
p_list->push_back(PropertyInfo(Variant::VECTOR2,"lightmaps/"+itos(i)+"/gen_size",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR));
p_list->push_back(PropertyInfo(Variant::OBJECT,"lightmaps/"+itos(i)+"/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture",PROPERTY_USAGE_EDITOR));
}
}
void BakedLight::_bind_methods(){
ObjectTypeDB::bind_method(_MD("set_mode","mode"),&BakedLight::set_mode);
ObjectTypeDB::bind_method(_MD("get_mode"),&BakedLight::get_mode);
ObjectTypeDB::bind_method(_MD("set_octree","octree"),&BakedLight::set_octree);
ObjectTypeDB::bind_method(_MD("get_octree"),&BakedLight::get_octree);
ObjectTypeDB::bind_method(_MD("set_light","light"),&BakedLight::set_light);
ObjectTypeDB::bind_method(_MD("get_light"),&BakedLight::get_light);
ObjectTypeDB::bind_method(_MD("set_sampler_octree","sampler_octree"),&BakedLight::set_sampler_octree);
ObjectTypeDB::bind_method(_MD("get_sampler_octree"),&BakedLight::get_sampler_octree);
ObjectTypeDB::bind_method(_MD("add_lightmap","texture:Texture","gen_size"),&BakedLight::add_lightmap);
ObjectTypeDB::bind_method(_MD("erase_lightmap","id"),&BakedLight::erase_lightmap);
ObjectTypeDB::bind_method(_MD("clear_lightmaps"),&BakedLight::clear_lightmaps);
ObjectTypeDB::bind_method(_MD("_set_lightmap_data","lightmap_data"),&BakedLight::_set_lightmap_data);
ObjectTypeDB::bind_method(_MD("_get_lightmap_data"),&BakedLight::_get_lightmap_data);
ObjectTypeDB::bind_method(_MD("set_cell_subdivision","cell_subdivision"),&BakedLight::set_cell_subdivision);
ObjectTypeDB::bind_method(_MD("get_cell_subdivision"),&BakedLight::get_cell_subdivision);
ObjectTypeDB::bind_method(_MD("set_initial_lattice_subdiv","cell_subdivision"),&BakedLight::set_initial_lattice_subdiv);
ObjectTypeDB::bind_method(_MD("get_initial_lattice_subdiv","cell_subdivision"),&BakedLight::get_initial_lattice_subdiv);
ObjectTypeDB::bind_method(_MD("set_plot_size","plot_size"),&BakedLight::set_plot_size);
ObjectTypeDB::bind_method(_MD("get_plot_size"),&BakedLight::get_plot_size);
ObjectTypeDB::bind_method(_MD("set_bounces","bounces"),&BakedLight::set_bounces);
ObjectTypeDB::bind_method(_MD("get_bounces"),&BakedLight::get_bounces);
ObjectTypeDB::bind_method(_MD("set_cell_extra_margin","cell_extra_margin"),&BakedLight::set_cell_extra_margin);
ObjectTypeDB::bind_method(_MD("get_cell_extra_margin"),&BakedLight::get_cell_extra_margin);
ObjectTypeDB::bind_method(_MD("set_edge_damp","edge_damp"),&BakedLight::set_edge_damp);
ObjectTypeDB::bind_method(_MD("get_edge_damp"),&BakedLight::get_edge_damp);
ObjectTypeDB::bind_method(_MD("set_normal_damp","normal_damp"),&BakedLight::set_normal_damp);
ObjectTypeDB::bind_method(_MD("get_normal_damp"),&BakedLight::get_normal_damp);
ObjectTypeDB::bind_method(_MD("set_tint","tint"),&BakedLight::set_tint);
ObjectTypeDB::bind_method(_MD("get_tint"),&BakedLight::get_tint);
ObjectTypeDB::bind_method(_MD("set_saturation","saturation"),&BakedLight::set_saturation);
ObjectTypeDB::bind_method(_MD("get_saturation"),&BakedLight::get_saturation);
ObjectTypeDB::bind_method(_MD("set_ao_radius","ao_radius"),&BakedLight::set_ao_radius);
ObjectTypeDB::bind_method(_MD("get_ao_radius"),&BakedLight::get_ao_radius);
ObjectTypeDB::bind_method(_MD("set_ao_strength","ao_strength"),&BakedLight::set_ao_strength);
ObjectTypeDB::bind_method(_MD("get_ao_strength"),&BakedLight::get_ao_strength);
ObjectTypeDB::bind_method(_MD("set_realtime_color_enabled", "enabled"), &BakedLight::set_realtime_color_enabled);
ObjectTypeDB::bind_method(_MD("get_realtime_color_enabled"), &BakedLight::get_realtime_color_enabled);
ObjectTypeDB::bind_method(_MD("set_realtime_color", "tint"), &BakedLight::set_realtime_color);
ObjectTypeDB::bind_method(_MD("get_realtime_color"), &BakedLight::get_realtime_color);
ObjectTypeDB::bind_method(_MD("set_realtime_energy", "energy"), &BakedLight::set_realtime_energy);
ObjectTypeDB::bind_method(_MD("get_realtime_energy"), &BakedLight::get_realtime_energy);
ObjectTypeDB::bind_method(_MD("set_format","format"),&BakedLight::set_format);
ObjectTypeDB::bind_method(_MD("get_format"),&BakedLight::get_format);
ObjectTypeDB::bind_method(_MD("set_transfer_lightmaps_only_to_uv2","enable"),&BakedLight::set_transfer_lightmaps_only_to_uv2);
ObjectTypeDB::bind_method(_MD("get_transfer_lightmaps_only_to_uv2"),&BakedLight::get_transfer_lightmaps_only_to_uv2);
ObjectTypeDB::bind_method(_MD("set_energy_multiplier","energy_multiplier"),&BakedLight::set_energy_multiplier);
ObjectTypeDB::bind_method(_MD("get_energy_multiplier"),&BakedLight::get_energy_multiplier);
ObjectTypeDB::bind_method(_MD("set_gamma_adjust","gamma_adjust"),&BakedLight::set_gamma_adjust);
ObjectTypeDB::bind_method(_MD("get_gamma_adjust"),&BakedLight::get_gamma_adjust);
ObjectTypeDB::bind_method(_MD("set_bake_flag","flag","enabled"),&BakedLight::set_bake_flag);
ObjectTypeDB::bind_method(_MD("get_bake_flag","flag"),&BakedLight::get_bake_flag);
ADD_PROPERTY( PropertyInfo(Variant::INT,"mode/mode",PROPERTY_HINT_ENUM,"Octree,Lightmaps"),_SCS("set_mode"),_SCS("get_mode"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/format",PROPERTY_HINT_ENUM,"RGB,HDR8,HDR16"),_SCS("set_format"),_SCS("get_format"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/cell_subdiv",PROPERTY_HINT_RANGE,"4,14,1"),_SCS("set_cell_subdivision"),_SCS("get_cell_subdivision"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/lattice_subdiv",PROPERTY_HINT_RANGE,"1,5,1"),_SCS("set_initial_lattice_subdiv"),_SCS("get_initial_lattice_subdiv"));
ADD_PROPERTY( PropertyInfo(Variant::INT,"baking/light_bounces",PROPERTY_HINT_RANGE,"0,3,1"),_SCS("set_bounces"),_SCS("get_bounces"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/plot_size",PROPERTY_HINT_RANGE,"1.0,16.0,0.01"),_SCS("set_plot_size"),_SCS("get_plot_size"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/energy_mult",PROPERTY_HINT_RANGE,"0.01,4096.0,0.01"),_SCS("set_energy_multiplier"),_SCS("get_energy_multiplier"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/gamma_adjust",PROPERTY_HINT_EXP_EASING),_SCS("set_gamma_adjust"),_SCS("get_gamma_adjust"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"baking/saturation",PROPERTY_HINT_RANGE,"0,8,0.01"),_SCS("set_saturation"),_SCS("get_saturation"));
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/diffuse"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_DIFFUSE);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/specular"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_SPECULAR);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/translucent"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_TRANSLUCENT);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/conserve_energy"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_CONSERVE_ENERGY);
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"baking_flags/linear_color"),_SCS("set_bake_flag"),_SCS("get_bake_flag"),BAKE_LINEAR_COLOR);
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"lightmap/use_only_uv2"),_SCS("set_transfer_lightmaps_only_to_uv2"),_SCS("get_transfer_lightmaps_only_to_uv2"));
ADD_PROPERTY( PropertyInfo(Variant::RAW_ARRAY,"octree",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_octree"),_SCS("get_octree"));
ADD_PROPERTY( PropertyInfo(Variant::RAW_ARRAY,"light",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_light"),_SCS("get_light"));
ADD_PROPERTY( PropertyInfo(Variant::INT_ARRAY,"sampler_octree",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_sampler_octree"),_SCS("get_sampler_octree"));
ADD_PROPERTY( PropertyInfo(Variant::ARRAY,"lightmaps",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_lightmap_data"),_SCS("_get_lightmap_data"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/cell_margin",PROPERTY_HINT_RANGE,"0.01,0.8,0.01"),_SCS("set_cell_extra_margin"),_SCS("get_cell_extra_margin"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/edge_damp",PROPERTY_HINT_RANGE,"0.0,8.0,0.1"),_SCS("set_edge_damp"),_SCS("get_edge_damp"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/normal_damp",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_normal_damp"),_SCS("get_normal_damp"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/light_tint",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_tint"),_SCS("get_tint"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/ao_radius",PROPERTY_HINT_RANGE,"0.0,16.0,0.01"),_SCS("set_ao_radius"),_SCS("get_ao_radius"));
ADD_PROPERTY( PropertyInfo(Variant::REAL,"advanced/ao_strength",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_ao_strength"),_SCS("get_ao_strength"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "realtime/enabled"), _SCS("set_realtime_color_enabled"), _SCS("get_realtime_color_enabled"));
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "realtime/color", PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_realtime_color"), _SCS("get_realtime_color"));
ADD_PROPERTY(PropertyInfo(Variant::REAL, "realtime/energy", PROPERTY_HINT_RANGE, "0.01,4096.0,0.01"), _SCS("set_realtime_energy"), _SCS("get_realtime_energy"));
BIND_CONSTANT( MODE_OCTREE );
BIND_CONSTANT( MODE_LIGHTMAPS );
BIND_CONSTANT( BAKE_DIFFUSE );
BIND_CONSTANT( BAKE_SPECULAR );
BIND_CONSTANT( BAKE_TRANSLUCENT );
BIND_CONSTANT( BAKE_CONSERVE_ENERGY );
BIND_CONSTANT( BAKE_MAX );
}
BakedLight::BakedLight() {
cell_subdiv=8;
lattice_subdiv=4;
plot_size=2.5;
bounces=1;
energy_multiply=2.0;
gamma_adjust=0.7;
cell_extra_margin=0.05;
edge_damp=0.0;
normal_damp=0.0;
saturation=1;
tint=0.0;
ao_radius=2.5;
ao_strength=0.7;
format=FORMAT_RGB8;
transfer_only_uv2=false;
flags[BAKE_DIFFUSE]=true;
flags[BAKE_SPECULAR]=false;
flags[BAKE_TRANSLUCENT]=true;
flags[BAKE_CONSERVE_ENERGY]=false;
flags[BAKE_LINEAR_COLOR]=false;
mode=MODE_OCTREE;
baked_light=VS::get_singleton()->baked_light_create();
}
BakedLight::~BakedLight() {
VS::get_singleton()->free(baked_light);
}
#endif

View file

@ -32,169 +32,6 @@
#include "resource.h"
#include "scene/resources/texture.h"
#if 0
class BakedLight : public Resource {
OBJ_TYPE( BakedLight, Resource);
public:
enum Mode {
MODE_OCTREE,
MODE_LIGHTMAPS
};
enum Format {
FORMAT_RGB8,
FORMAT_HDR8,
FORMAT_HDR16
};
enum BakeFlags {
BAKE_DIFFUSE,
BAKE_SPECULAR,
BAKE_TRANSLUCENT,
BAKE_CONSERVE_ENERGY,
BAKE_LINEAR_COLOR,
BAKE_MAX
};
private:
RID baked_light;
Mode mode;
struct LightMap {
Size2i gen_size;
Ref<Texture> texture;
};
Vector< LightMap> lightmaps;
//bake vars
int cell_subdiv;
int lattice_subdiv;
float plot_size;
float energy_multiply;
float gamma_adjust;
float cell_extra_margin;
float edge_damp;
float normal_damp;
float tint;
float ao_radius;
float ao_strength;
float saturation;
int bounces;
bool transfer_only_uv2;
Format format;
bool flags[BAKE_MAX];
void _update_lightmaps();
Array _get_lightmap_data() const;
void _set_lightmap_data(Array p_array);
protected:
bool _set(const StringName& p_name, const Variant& p_value);
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
static void _bind_methods();
public:
void set_cell_subdivision(int p_subdiv);
int get_cell_subdivision() const;
void set_initial_lattice_subdiv(int p_size);
int get_initial_lattice_subdiv() const;
void set_plot_size(float p_size);
float get_plot_size() const;
void set_bounces(int p_size);
int get_bounces() const;
void set_energy_multiplier(float p_multiplier);
float get_energy_multiplier() const;
void set_gamma_adjust(float p_adjust);
float get_gamma_adjust() const;
void set_cell_extra_margin(float p_margin);
float get_cell_extra_margin() const;
void set_edge_damp(float p_margin);
float get_edge_damp() const;
void set_normal_damp(float p_margin);
float get_normal_damp() const;
void set_tint(float p_margin);
float get_tint() const;
void set_saturation(float p_saturation);
float get_saturation() const;
void set_ao_radius(float p_ao_radius);
float get_ao_radius() const;
void set_ao_strength(float p_ao_strength);
float get_ao_strength() const;
void set_realtime_color_enabled(const bool p_enabled);
bool get_realtime_color_enabled() const;
void set_realtime_color(const Color& p_realtime_color);
Color get_realtime_color() const;
void set_realtime_energy(const float p_realtime_energy);
float get_realtime_energy() const;
void set_bake_flag(BakeFlags p_flags,bool p_enable);
bool get_bake_flag(BakeFlags p_flags) const;
void set_format(Format p_margin);
Format get_format() const;
void set_transfer_lightmaps_only_to_uv2(bool p_enable);
bool get_transfer_lightmaps_only_to_uv2() const;
void set_mode(Mode p_mode);
Mode get_mode() const;
void set_octree(const DVector<uint8_t>& p_octree);
DVector<uint8_t> get_octree() const;
void set_light(const DVector<uint8_t>& p_light);
DVector<uint8_t> get_light() const;
void set_sampler_octree(const DVector<int>& p_sampler_octree);
DVector<int> get_sampler_octree() const;
void add_lightmap(const Ref<Texture> &p_texture,Size2 p_gen_size=Size2(256,256));
void set_lightmap_gen_size(int p_idx,const Size2& p_size);
Size2 get_lightmap_gen_size(int p_idx) const;
void set_lightmap_texture(int p_idx,const Ref<Texture> &p_texture);
Ref<Texture> get_lightmap_texture(int p_idx) const;
void erase_lightmap(int p_idx);
int get_lightmaps_count() const;
void clear_lightmaps();
virtual RID get_rid() const;
BakedLight();
~BakedLight();
};
VARIANT_ENUM_CAST(BakedLight::Format);
VARIANT_ENUM_CAST(BakedLight::Mode);
VARIANT_ENUM_CAST(BakedLight::BakeFlags);
#endif
#endif // BAKED_LIGHT_H

View file

@ -91,6 +91,7 @@ public:
Vector<RID> materials;
Vector<RID> light_instances;
Vector<RID> reflection_probe_instances;
Vector<RID> gi_probe_instances;
Vector<float> morph_values;
@ -108,12 +109,14 @@ public:
float depth; //used for sorting
SelfList<InstanceBase> dependency_item;
InstanceBase *baked_light; //baked light to use
SelfList<InstanceBase> baked_light_item;
virtual void base_removed()=0;
virtual void base_changed()=0;
virtual void base_material_changed()=0;
InstanceBase() : dependency_item(this) {
InstanceBase() : dependency_item(this), baked_light_item(this) {
base_type=VS::INSTANCE_NONE;
cast_shadows=VS::SHADOW_CASTING_SETTING_ON;
@ -123,6 +126,7 @@ public:
billboard_y=false;
depth_layer=0;
layer_mask=1;
baked_light=NULL;
}
};
@ -144,6 +148,11 @@ public:
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas)=0;
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_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 render_scene(const Transform& p_cam_transform,const CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_reflection_probe_cull_result,int p_reflection_probe_cull_count,RID p_environment,RID p_shadow_atlas,RID p_reflection_atlas,RID p_reflection_probe,int p_reflection_probe_pass)=0;
virtual void render_shadow(RID p_light,RID p_shadow_atlas,int p_pass,InstanceBase** p_cull_result,int p_cull_count)=0;
@ -340,6 +349,7 @@ public:
virtual VS::LightType light_get_type(RID p_light) const=0;
virtual AABB light_get_aabb(RID p_light) const=0;
virtual float light_get_param(RID p_light,VS::LightParam p_param)=0;
virtual Color light_get_color(RID p_light)=0;
virtual uint64_t light_get_version(RID p_light) const=0;
@ -392,6 +402,39 @@ public:
virtual void instance_add_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance)=0;
virtual void instance_remove_dependency(RID p_base,RasterizerScene::InstanceBase *p_instance)=0;
/* GI PROBE API */
virtual RID gi_probe_create()=0;
virtual void gi_probe_set_bounds(RID p_probe,const AABB& p_bounds)=0;
virtual AABB gi_probe_get_bounds(RID p_probe) const=0;
virtual void gi_probe_set_cell_size(RID p_probe,float p_range)=0;
virtual float gi_probe_get_cell_size(RID p_probe) const=0;
virtual void gi_probe_set_to_cell_xform(RID p_probe,const Transform& p_xform)=0;
virtual Transform gi_probe_get_to_cell_xform(RID p_probe) const=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 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_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 VS::GIProbeDataFormat gi_probe_get_static_data_format(RID p_gi_probe) const=0;
virtual int gi_probe_get_static_data_width(RID p_probe) const=0;
virtual int gi_probe_get_static_data_height(RID p_probe) const=0;
virtual int gi_probe_get_static_data_depth(RID p_probe) const=0;
virtual RID gi_probe_get_data(RID p_probe)=0; //get data in case this is static
virtual uint32_t gi_probe_get_version(RID p_probe)=0;
virtual RID gi_probe_dynamic_data_create(int p_width,int p_height,int p_depth)=0;
virtual void gi_probe_dynamic_data_update_rgba8(RID p_gi_probe_data,int p_depth_slice,int p_slice_count,int p_mipmap,const void* p_data)=0;
/* RENDER TARGET */
enum RenderTargetFlags {

View file

@ -0,0 +1,6 @@
#include "visual_server_light_baker.h"
VisualServerLightBaker::VisualServerLightBaker()
{
}

View file

@ -0,0 +1,29 @@
#ifndef VISUALSERVERLIGHTBAKER_H
#define VISUALSERVERLIGHTBAKER_H
#include "servers/visual_server.h"
class VisualServerLightBaker {
public:
struct BakeCell {
uint32_t cells[8];
uint32_t neighbours[7]; //one unused
uint32_t albedo; //albedo in RGBE
uint32_t emission; //emissive light in RGBE
uint32_t light[4]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
float alpha; //used for upsampling
uint32_t directional_pass; //used for baking directional
};
VisualServerLightBaker();
};
#endif // VISUALSERVERLIGHTBAKER_H

View file

@ -90,9 +90,10 @@ void VisualServerRaster::draw(){
changes=0;
VSG::rasterizer->begin_frame();
VSG::scene->update_dirty_instances(); //update scene stuff
VSG::rasterizer->begin_frame();
VSG::viewport->draw_viewports();
VSG::scene->render_probes();
//_draw_cursors_and_margins();

View file

@ -803,12 +803,39 @@ public:
BIND2(portal_set_disable_distance,RID , float )
BIND2(portal_set_disabled_color,RID , const Color& )
/* CAMERA API */
/* BAKED LIGHT API */
BIND0R(RID, gi_probe_create)
BIND2(gi_probe_set_bounds,RID,const AABB&)
BIND1RC(AABB,gi_probe_get_bounds,RID)
BIND2(gi_probe_set_cell_size,RID,float)
BIND1RC(float,gi_probe_get_cell_size,RID)
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_data,RID,const DVector<int>& )
BIND1RC( DVector<int>,gi_probe_get_dynamic_data,RID)
BIND6(gi_probe_set_static_data,RID,const DVector<uint8_t>&,GIProbeDataFormat,int,int,int)
BIND1RC(DVector<uint8_t>,gi_probe_get_static_data,RID)
BIND1RC(GIProbeDataFormat,gi_probe_get_static_data_format,RID)
BIND1RC(int,gi_probe_get_static_data_width,RID)
BIND1RC(int,gi_probe_get_static_data_height,RID)
BIND1RC(int,gi_probe_get_static_data_depth,RID)
#undef BINDBASE
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::scene
/* CAMERA API */
BIND0R(RID, camera_create)
BIND4(camera_set_perspective,RID,float, float , float )
@ -936,7 +963,6 @@ public:
BIND5(instance_geometry_set_draw_range,RID,float ,float ,float ,float )
BIND2(instance_geometry_set_as_instance_lod,RID,RID )
#undef BINDBASE
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::canvas

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,9 @@
#include "allocators.h"
#include "octree.h"
#include "self_list.h"
#include "os/thread.h"
#include "os/semaphore.h"
#include "semaphore.h"
class VisualServerScene {
public:
@ -69,6 +72,8 @@ public:
#endif
/* CAMERA API */
struct Camera : public RID_Data {
enum Type {
@ -141,6 +146,7 @@ public:
*/
/* SCENARIO API */
struct Instance;
@ -296,11 +302,15 @@ public:
List<Instance*> reflection_probes;
bool reflection_dirty;
List<Instance*> gi_probes;
bool gi_probes_dirty;
InstanceGeometryData() {
lighting_dirty=false;
reflection_dirty=true;
can_cast_shadows=true;
gi_probes_dirty=true;
}
};
@ -310,7 +320,7 @@ public:
Instance *owner;
struct PairInfo {
List<Instance*>::Element *L; //light iterator in geometry
List<Instance*>::Element *L; //reflection iterator in geometry
Instance *geometry;
};
List<PairInfo> geometries;
@ -346,14 +356,112 @@ public:
List<PairInfo> geometries;
Instance *baked_light;
InstanceLightData() {
shadow_dirty=true;
D=NULL;
last_version=0;
baked_light=NULL;
}
};
struct InstanceGIProbeData : public InstanceBaseData {
Instance *owner;
struct PairInfo {
List<Instance*>::Element *L; //gi probe iterator in geometry
Instance *geometry;
};
List<PairInfo> geometries;
Set<Instance*> lights;
struct LightCache {
VS::LightType type;
Transform transform;
Color color;
float energy;
float radius;
float attenuation;
float spot_angle;
float spot_attenuation;
bool operator==(const LightCache& p_cache) {
return (type==p_cache.type &&
transform==p_cache.transform &&
color==p_cache.color &&
energy==p_cache.energy &&
radius==p_cache.radius &&
attenuation==p_cache.attenuation &&
spot_angle==p_cache.spot_angle &&
spot_attenuation==p_cache.spot_attenuation);
}
LightCache() {
type=VS::LIGHT_DIRECTIONAL;
energy=1.0;
radius=1.0;
attenuation=1.0;
spot_angle=1.0;
spot_attenuation=1.0;
}
};
struct LocalData {
uint16_t pos[3];
uint16_t energy[3]; //using 0..1024 for float range 0..1. integer is needed for deterministic add/remove of lights
};
struct Dynamic {
Map<RID,LightCache> light_cache;
Map<RID,LightCache> light_cache_changes;
DVector<int> light_data;
DVector<LocalData> local_data;
Vector<Vector<uint32_t> > level_cell_lists;
RID probe_data;
bool enabled;
Vector< DVector<uint8_t> > mipmaps_3d;
int updating_stage;
int grid_size[3];
Transform light_to_cell_xform;
} dynamic;
RID probe_instance;
bool invalid;
uint32_t base_version;
SelfList<InstanceGIProbeData> update_element;
InstanceGIProbeData() : update_element(this) {
invalid=true;
base_version=0;
}
};
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
Instance *instance_cull_result[MAX_INSTANCE_CULL];
Instance *instance_shadow_cull_result[MAX_INSTANCE_CULL]; //used for generating shadowmaps
@ -410,11 +518,61 @@ public:
void render_camera(RID p_camera, RID p_scenario, Size2 p_viewport_size, RID p_shadow_atlas);
void update_dirty_instances();
bool _render_probe_step(Instance* p_instance,int p_step);
//probes
struct GIProbeDataHeader {
uint32_t version;
uint32_t cell_subdiv;
uint32_t width;
uint32_t height;
uint32_t depth;
uint32_t cell_count;
uint32_t leaf_cell_count;
};
struct GIProbeDataCell {
uint32_t children[8];
uint32_t albedo;
uint32_t emission;
uint32_t sides_used;
uint32_t alpha;
};
enum {
GI_UPDATE_STAGE_CHECK,
GI_UPDATE_STAGE_LIGHTING,
GI_UPDATE_STAGE_UPLOADING,
};
void _gi_probe_bake_thread();
static void _gi_probe_bake_threads(void*);
volatile bool probe_bake_thread_exit;
Thread *probe_bake_thread;
Semaphore *probe_bake_sem;
Mutex *probe_bake_mutex;
List<Instance*> probe_bake_list;
bool _render_reflection_probe_step(Instance* p_instance,int p_step);
void _gi_probe_fill_local_data(int p_idx,int p_level,int p_x,int p_y,int p_z,const GIProbeDataCell* p_cell,const GIProbeDataHeader *p_header,InstanceGIProbeData::LocalData *p_local_data,Vector<uint32_t> *prev_cell);
_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);
void _setup_gi_probe(Instance *p_instance);
void render_probes();
bool free(RID p_rid);
VisualServerScene();
~VisualServerScene();
};
#endif // VISUALSERVERSCENE_H

View file

@ -445,7 +445,39 @@ public:
virtual void portal_set_disable_distance(RID p_portal, float p_distance)=0;
virtual void portal_set_disabled_color(RID p_portal, const Color& p_color)=0;
/* BAKED LIGHT API */
/* GI PROBE API */
virtual RID gi_probe_create()=0;
virtual void gi_probe_set_bounds(RID p_probe,const AABB& p_bounds)=0;
virtual AABB gi_probe_get_bounds(RID p_probe) const=0;
virtual void gi_probe_set_cell_size(RID p_probe,float p_range)=0;
virtual float gi_probe_get_cell_size(RID p_probe) const=0;
virtual void gi_probe_set_to_cell_xform(RID p_probe,const Transform& p_xform)=0;
virtual Transform gi_probe_get_to_cell_xform(RID p_probe) const=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 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;
enum GIProbeDataFormat {
GI_PROBE_DATA_RGBA8,
GI_PROBE_DATA_DXT5,
GI_PROBE_DATA_ETC2_EAC,
};
virtual void gi_probe_set_static_data(RID p_gi_probe,const DVector<uint8_t>& p_data,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 GIProbeDataFormat gi_probe_get_static_data_format(RID p_gi_probe) const=0;
virtual int gi_probe_get_static_data_width(RID p_probe) const=0;
virtual int gi_probe_get_static_data_height(RID p_probe) const=0;
virtual int gi_probe_get_static_data_depth(RID p_probe) const=0;
/* CAMERA API */
@ -600,9 +632,9 @@ public:
INSTANCE_REFLECTION_PROBE,
INSTANCE_ROOM,
INSTANCE_PORTAL,
INSTANCE_GI_PROBE,
INSTANCE_MAX,
/*INSTANCE_BAKED_LIGHT,
INSTANCE_BAKED_LIGHT_SAMPLER,*/
/*INSTANCE_BAKED_LIGHT_SAMPLER,*/
INSTANCE_GEOMETRY_MASK=(1<<INSTANCE_MESH)|(1<<INSTANCE_MULTIMESH)|(1<<INSTANCE_IMMEDIATE)
};

View file

@ -394,7 +394,8 @@ Error ColladaImport::_create_material(const String& p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
if (texture.is_valid()) {
// material->set_texture(FixedSpatialMaterial::PARAM_DIFFUSE,texture);
material->set_texture(FixedSpatialMaterial::TEXTURE_ALBEDO,texture);
material->set_albedo(Color(1,1,1,1));
// material->set_parameter(FixedSpatialMaterial::PARAM_DIFFUSE,Color(1,1,1,1));
} else {
missing_textures.push_back(texfile.get_file());
@ -413,6 +414,8 @@ Error ColladaImport::_create_material(const String& p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
if (texture.is_valid()) {
material->set_texture(FixedSpatialMaterial::TEXTURE_SPECULAR,texture);
material->set_specular(Color(1,1,1,1));
// material->set_texture(FixedSpatialMaterial::PARAM_SPECULAR,texture);
// material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
@ -435,7 +438,9 @@ Error ColladaImport::_create_material(const String& p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
if (texture.is_valid()) {
// material->set_texture(FixedSpatialMaterial::PARAM_EMISSION,texture);
material->set_texture(FixedSpatialMaterial::TEXTURE_EMISSION,texture);
material->set_emission(Color(1,1,1,1));
// material->set_parameter(FixedSpatialMaterial::PARAM_EMISSION,Color(1,1,1,1));
}else {
// missing_textures.push_back(texfile.get_file());
@ -455,6 +460,8 @@ Error ColladaImport::_create_material(const String& p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile,"Texture");
if (texture.is_valid()) {
material->set_texture(FixedSpatialMaterial::TEXTURE_NORMAL,texture);
// material->set_emission(Color(1,1,1,1));
// material->set_texture(FixedSpatialMaterial::PARAM_NORMAL,texture);
}else {
@ -466,8 +473,10 @@ Error ColladaImport::_create_material(const String& p_target) {
// material->set_parameter(FixedSpatialMaterial::PARAM_SPECULAR_EXP,effect.shininess);
// material->set_flag(Material::FLAG_DOUBLE_SIDED,effect.double_sided);
// material->set_flag(Material::FLAG_UNSHADED,effect.unshaded);
if (effect.double_sided) {
material->set_cull_mode(FixedSpatialMaterial::CULL_DISABLED);
}
material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED,effect.unshaded);

View file

@ -1692,7 +1692,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
String str=name;
int layer = str.substr(str.find("lm")+3,str.length()).to_int();
mi->set_baked_light_texture_id(layer);
//mi->set_baked_light_texture_id(layer);
}
if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly")) {

View file

@ -2397,6 +2397,163 @@ ReflectionProbeGizmo::ReflectionProbeGizmo(ReflectionProbe* p_probe){
///
String GIProbeGizmo::get_handle_name(int p_idx) const {
switch(p_idx) {
case 0: return "Extents X";
case 1: return "Extents Y";
case 2: return "Extents Z";
}
return "";
}
Variant GIProbeGizmo::get_handle_value(int p_idx) const{
return probe->get_extents();
}
void GIProbeGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){
Transform gt = probe->get_global_transform();
//gt.orthonormalize();
Transform gi = gt.affine_inverse();
Vector3 extents = probe->get_extents();
Vector3 ray_from = p_camera->project_ray_origin(p_point);
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
Vector3 sg[2]={gi.xform(ray_from),gi.xform(ray_from+ray_dir*16384)};
Vector3 axis;
axis[p_idx]=1.0;
Vector3 ra,rb;
Geometry::get_closest_points_between_segments(Vector3(),axis*16384,sg[0],sg[1],ra,rb);
float d = ra[p_idx];
if (d<0.001)
d=0.001;
extents[p_idx]=d;
probe->set_extents(extents);
}
void GIProbeGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){
Vector3 restore = p_restore;
if (p_cancel) {
probe->set_extents(restore);
return;
}
UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Probe Extents"));
ur->add_do_method(probe,"set_extents",probe->get_extents());
ur->add_undo_method(probe,"set_extents",restore);
ur->commit_action();
}
void GIProbeGizmo::redraw(){
clear();
Vector<Vector3> lines;
Vector3 extents = probe->get_extents();
static const int subdivs[GIProbe::SUBDIV_MAX]={64,128,256,512};
AABB aabb = AABB(-extents,extents*2);
int subdiv = subdivs[probe->get_subdiv()];
float cell_size = aabb.get_longest_axis_size()/subdiv;
for(int i=0;i<12;i++) {
Vector3 a,b;
aabb.get_edge(i,a,b);
lines.push_back(a);
lines.push_back(b);
}
add_lines(lines,SpatialEditorGizmos::singleton->gi_probe_material);
add_collision_segments(lines);
lines.clear();
for(int i=1;i<subdiv;i++) {
for(int j=0;j<3;j++) {
if (cell_size*i>aabb.size[j]) {
continue;
}
Vector2 dir;
dir[j]=1.0;
Vector2 ta,tb;
int j_n1=(j+1)%3;
int j_n2=(j+2)%3;
ta[j_n1]=1.0;
tb[j_n2]=1.0;
for(int k=0;k<4;k++) {
Vector3 from=aabb.pos,to=aabb.pos;
from[j]+= cell_size*i;
to[j]+=cell_size*i;
if (k&1) {
to[j_n1]+=aabb.size[j_n1];
} else {
to[j_n2]+=aabb.size[j_n2];
}
if (k&2) {
from[j_n1]+=aabb.size[j_n1];
from[j_n2]+=aabb.size[j_n2];
}
lines.push_back(from);
lines.push_back(to);
}
}
}
add_lines(lines,SpatialEditorGizmos::singleton->reflection_probe_material_internal);
Vector<Vector3> handles;
for(int i=0;i<3;i++) {
Vector3 ax;
ax[i]=aabb.pos[i]+aabb.size[i];
handles.push_back(ax);
}
add_handles(handles);
}
GIProbeGizmo::GIProbeGizmo(GIProbe* p_probe){
probe=p_probe;
set_spatial_node(p_probe);
}
////////
void NavigationMeshSpatialGizmo::redraw() {
@ -3093,6 +3250,11 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
Ref<ReflectionProbeGizmo> misg = memnew( ReflectionProbeGizmo(p_spatial->cast_to<ReflectionProbe>()) );
return misg;
}
if (p_spatial->cast_to<GIProbe>()) {
Ref<GIProbeGizmo> misg = memnew( GIProbeGizmo(p_spatial->cast_to<GIProbe>()) );
return misg;
}
if (p_spatial->cast_to<VehicleWheel>()) {
@ -3146,8 +3308,8 @@ Ref<FixedSpatialMaterial> SpatialEditorGizmos::create_line_material(const Color&
line_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
line_material->set_feature(FixedSpatialMaterial::FEATURE_TRANSPARENT, true);
line_material->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
line_material->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
//line_material->set_flag(FixedSpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
//->set_flag(FixedSpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
line_material->set_albedo(p_base_color);
return line_material;
@ -3298,7 +3460,9 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
car_wheel_material = create_line_material(Color(0.6,0.8,1.0));
visibility_notifier_material = create_line_material(Color(1.0,0.5,1.0));
reflection_probe_material = create_line_material(Color(0.5,1.0,0.7));
reflection_probe_material_internal = create_line_material(Color(0.3,0.8,0.5,0.4));
reflection_probe_material_internal = create_line_material(Color(0.3,0.8,0.5,0.15));
gi_probe_material = create_line_material(Color(0.7,1.0,0.5));
gi_probe_material_internal = create_line_material(Color(0.5,0.8,0.3,0.4));
joint_material = create_line_material(Color(0.6,0.8,1.0));
stream_player_icon = Ref<FixedSpatialMaterial>( memnew( FixedSpatialMaterial ));

View file

@ -46,6 +46,7 @@
#include "scene/3d/ray_cast.h"
#include "scene/3d/navigation_mesh.h"
#include "scene/3d/reflection_probe.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/vehicle_body.h"
#include "scene/3d/collision_polygon.h"
@ -327,6 +328,25 @@ public:
};
class GIProbeGizmo : public EditorSpatialGizmo {
OBJ_TYPE(GIProbeGizmo ,EditorSpatialGizmo);
GIProbe* probe;
public:
virtual String get_handle_name(int p_idx) const;
virtual Variant get_handle_value(int p_idx) const;
virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point);
virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false);
void redraw();
GIProbeGizmo(GIProbe* p_notifier=NULL);
};
class CollisionShapeSpatialGizmo : public EditorSpatialGizmo {
@ -496,6 +516,8 @@ public:
Ref<FixedSpatialMaterial> skeleton_material;
Ref<FixedSpatialMaterial> reflection_probe_material;
Ref<FixedSpatialMaterial> reflection_probe_material_internal;
Ref<FixedSpatialMaterial> gi_probe_material;
Ref<FixedSpatialMaterial> gi_probe_material_internal;
Ref<FixedSpatialMaterial> room_material;
Ref<FixedSpatialMaterial> portal_material;
Ref<FixedSpatialMaterial> raycast_material;