summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp84
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h6
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp88
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h21
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/scene.glsl131
-rw-r--r--drivers/unix/os_unix.cpp8
-rw-r--r--drivers/unix/os_unix.h2
9 files changed, 294 insertions, 48 deletions
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 5c6b9c5410..e1ddad0dc9 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -167,6 +167,7 @@ void RasterizerGLES3::initialize() {
void RasterizerGLES3::begin_frame(){
+
uint64_t tick = OS::get_singleton()->get_ticks_usec();
double time_total = double(tick)/1000000.0;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index c0af9b3bcf..b504ef819f 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -148,6 +148,9 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas,int p_size){
glClearDepth(0.0f);
glClear(GL_DEPTH_BUFFER_BIT);
+ glBindFramebuffer(GL_FRAMEBUFFER,0);
+
+
}
}
@@ -557,6 +560,8 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas,int p_size)
}
+
+
void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas,int p_subdiv) {
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas);
@@ -1081,6 +1086,18 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
state.current_line_width=p_material->line_width;
}
+ if (state.current_depth_test!=(!p_material->shader->spatial.ontop)) {
+ if (p_material->shader->spatial.ontop) {
+ glDisable(GL_DEPTH_TEST);
+
+ } else {
+ glEnable(GL_DEPTH_TEST);
+
+ }
+
+ state.current_depth_test=!p_material->shader->spatial.ontop;
+ }
+
if (state.current_depth_draw!=p_material->shader->spatial.depth_draw_mode) {
switch(p_material->shader->spatial.depth_draw_mode) {
case RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
@@ -1204,6 +1221,11 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
} else {
+#ifdef TOOLS_ENABLED
+ if (t->detect_3d) {
+ t->detect_3d(t->detect_3d_ud);
+ }
+#endif
if (storage->config.srgb_decode_supported) {
//if SRGB decode extension is present, simply switch the texture to whathever is needed
bool must_srgb=false;
@@ -1216,9 +1238,8 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material* p_m
if (must_srgb) {
glTexParameteri(t->target,_TEXTURE_SRGB_DECODE_EXT,_DECODE_EXT);
#ifdef TOOLS_ENABLED
- if (!(t->flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
- t->flags|=VS::TEXTURE_FLAG_CONVERT_TO_LINEAR;
- //notify that texture must be set to linear beforehand, so it works in other platforms when exported
+ if (t->detect_srgb) {
+ t->detect_srgb(t->detect_srgb_ud);
}
#endif
@@ -1714,6 +1735,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements,int p_e
state.cull_front=false;
glCullFace(GL_BACK);
+ state.current_depth_test=true;
+ glEnable(GL_DEPTH_TEST);
+
state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON,false);
state.current_blend_mode=-1;
@@ -2297,10 +2321,10 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index,const Transform&
ubo_data.light_params[3]=0;
Color shadow_color = li->light_ptr->shadow_color.to_linear();
- ubo_data.light_shadow_color[0]=shadow_color.r;
- ubo_data.light_shadow_color[1]=shadow_color.g;
- ubo_data.light_shadow_color[2]=shadow_color.b;
- ubo_data.light_shadow_color[3]=1.0;
+ ubo_data.light_shadow_color_contact[0]=shadow_color.r;
+ ubo_data.light_shadow_color_contact[1]=shadow_color.g;
+ ubo_data.light_shadow_color_contact[2]=shadow_color.b;
+ ubo_data.light_shadow_color_contact[3]=li->light_ptr->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE];
if (p_use_shadows && li->light_ptr->shadow) {
@@ -2456,10 +2480,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
ubo_data.light_params[3]=0;
Color shadow_color = li->light_ptr->shadow_color.to_linear();
- ubo_data.light_shadow_color[0]=shadow_color.r;
- ubo_data.light_shadow_color[1]=shadow_color.g;
- ubo_data.light_shadow_color[2]=shadow_color.b;
- ubo_data.light_shadow_color[3]=1.0;
+ ubo_data.light_shadow_color_contact[0]=shadow_color.r;
+ ubo_data.light_shadow_color_contact[1]=shadow_color.g;
+ ubo_data.light_shadow_color_contact[2]=shadow_color.b;
+ ubo_data.light_shadow_color_contact[3]=li->light_ptr->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE];
if (li->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) {
// fill in the shadow information
@@ -2549,10 +2573,10 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result,int p_light_cu
ubo_data.light_params[3]=0;
Color shadow_color = li->light_ptr->shadow_color.to_linear();
- ubo_data.light_shadow_color[0]=shadow_color.r;
- ubo_data.light_shadow_color[1]=shadow_color.g;
- ubo_data.light_shadow_color[2]=shadow_color.b;
- ubo_data.light_shadow_color[3]=1.0;
+ ubo_data.light_shadow_color_contact[0]=shadow_color.r;
+ ubo_data.light_shadow_color_contact[1]=shadow_color.g;
+ ubo_data.light_shadow_color_contact[2]=shadow_color.b;
+ ubo_data.light_shadow_color_contact[3]=li->light_ptr->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE];
if (li->light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) {
// fill in the shadow information
@@ -3736,14 +3760,20 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
state.ubo_data.shadow_dual_paraboloid_render_side=0;
state.ubo_data.shadow_dual_paraboloid_render_zfar=0;
+ if (storage->frame.current_rt) {
+ state.ubo_data.screen_pixel_size[0]=1.0/storage->frame.current_rt->width;
+ state.ubo_data.screen_pixel_size[1]=1.0/storage->frame.current_rt->height;
+ }
+
_setup_environment(env,p_cam_projection,p_cam_transform);
bool fb_cleared=false;
glDepthFunc(GL_LEQUAL);
+ state.used_contact_shadows=true;
- if (storage->frame.current_rt && true) {
+ if (storage->frame.current_rt && true) { //detect with state.used_contact_shadows too
//pre z pass
@@ -3770,6 +3800,19 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
glColorMask(1,1,1,1);
+ if (state.used_contact_shadows) {
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ //bind depth for read
+ glActiveTexture(GL_TEXTURE0+storage->config.max_texture_image_units-8);
+ glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
+ }
+
fb_cleared=true;
render_pass++;
}
@@ -4403,18 +4446,18 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa
render_list.sort_by_depth(false); //shadow is front to back for performance
- glDepthMask(true);
- glColorMask(1,1,1,1);
glDisable(GL_BLEND);
glDisable(GL_DITHER);
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER,fbo);
+ glDepthMask(true);
+ glColorMask(0,0,0,0);
+
if (custom_vp_size) {
glViewport(0,0,custom_vp_size,custom_vp_size);
glScissor(0,0,custom_vp_size,custom_vp_size);
-
} else {
glViewport(x,y,width,height);
glScissor(x,y,width,height);
@@ -4434,7 +4477,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light,RID p_shadow_atlas,int p_pa
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH,true);
- _render_list(render_list.elements,render_list.element_count,light_transform,light_projection,0,!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_DEPTH,false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH_DUAL_PARABOLOID,false);
@@ -5009,5 +5052,4 @@ void RasterizerSceneGLES3::finalize(){
RasterizerSceneGLES3::RasterizerSceneGLES3()
{
-
}
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 7838345e59..81dfa1bf46 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -61,6 +61,7 @@ public:
int current_blend_mode;
float current_line_width;
int current_depth_draw;
+ bool current_depth_test;
GLuint current_main_tex;
SceneShaderGLES3 scene_shader;
@@ -90,6 +91,7 @@ public:
float shadow_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
+ float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
float reflection_multiplier;
@@ -135,6 +137,7 @@ public:
int max_ubo_reflections;
int max_skeleton_bones;
+ bool used_contact_shadows;
int spot_light_count;
@@ -209,7 +212,6 @@ public:
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
bool shadow_atlas_update_light(RID p_atlas,RID p_light_intance,float p_coverage,uint64_t p_light_version);
-
struct DirectionalShadow {
GLuint fbo;
GLuint depth;
@@ -467,7 +469,7 @@ public:
float light_color_energy[4];
float light_params[4]; //spot attenuation, spot angle, specular, shadow enabled
float light_clamp[4];
- float light_shadow_color[4];
+ float light_shadow_color_contact[4];
float shadow_matrix1[16]; //up to here for spot and omni, rest is for directional
float shadow_matrix2[16];
float shadow_matrix3[16];
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index a96fd8dd41..06daebbf82 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -218,7 +218,7 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image& p_image, Ima
if (config.s3tc_supported) {
- r_gl_internal_format=(config.srgb_decode_supported || p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ r_gl_internal_format=(config.srgb_decode_supported || p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_S3TC_DXT1_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_gl_format=GL_RGBA;
r_gl_type=GL_UNSIGNED_BYTE;
r_compressed=true;
@@ -785,7 +785,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture,const Image& p_image
if (texture->compressed) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glCompressedTexImage2D( blit_target, i, format,w,h,0,size,&read[ofs] );
+ glCompressedTexImage2D( blit_target, i, internal_format,w,h,0,size,&read[ofs] );
} else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -814,6 +814,10 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture,const Image& p_image
if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && mipmaps==1 && !texture->ignore_mipmaps && (!(texture->flags&VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides==(1<<6)-1)) {
//generate mipmaps if they were requested and the image does not contain them
glGenerateMipmap(texture->target);
+ } else if (mipmaps>1) {
+ glTexParameteri(texture->target, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(texture->target, GL_TEXTURE_MAX_LEVEL, mipmaps-1);
+
}
texture->mipmaps=mipmaps;
@@ -1066,6 +1070,26 @@ void RasterizerStorageGLES3::textures_keep_original(bool p_enable) {
config.keep_original_textures=p_enable;
}
+void RasterizerStorageGLES3::texture_set_detect_3d_callback(RID p_texture,VisualServer::TextureDetectCallback p_callback,void* p_userdata) {
+
+ Texture * texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ texture->detect_3d=p_callback;
+ texture->detect_3d_ud=p_userdata;
+}
+
+void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture,VisualServer::TextureDetectCallback p_callback,void* p_userdata){
+ Texture * texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ texture->detect_srgb=p_callback;
+ texture->detect_srgb_ud=p_userdata;
+
+}
+
+
+
RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source,int p_resolution) const {
Texture * texture = texture_owner.get(p_source);
@@ -1515,12 +1539,12 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
actions->uniforms=&p_shader->uniforms;
- }
+ } break;
case VS::SHADER_PARTICLES: {
actions=&shaders.actions_particles;
actions->uniforms=&p_shader->uniforms;
- }
+ } break;
}
@@ -2471,6 +2495,7 @@ RID RasterizerStorageGLES3::mesh_create(){
void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::PrimitiveType p_primitive,const PoolVector<uint8_t>& p_array,int p_vertex_count,const PoolVector<uint8_t>& p_index_array,int p_index_count,const Rect3& p_aabb,const Vector<PoolVector<uint8_t> >& p_blend_shapes,const Vector<Rect3>& p_bone_aabbs){
+
PoolVector<uint8_t> array = p_array;
Mesh *mesh = mesh_owner.getornull(p_mesh);
@@ -2669,8 +2694,6 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh,uint32_t p_format,VS::P
int array_size = stride * p_vertex_count;
int index_array_size=0;
-
- print_line("desired size: "+itos(array_size)+" vcount "+itos(p_vertex_count)+" should be: "+itos(array.size()+p_vertex_count*2)+" but is "+itos(array.size()));
if (array.size()!=array_size && array.size()+p_vertex_count*2 == array_size) {
//old format, convert
array = PoolVector<uint8_t>();
@@ -4267,6 +4290,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type){
light->param[VS::LIGHT_PARAM_SPECULAR]=0.5;
light->param[VS::LIGHT_PARAM_RANGE]=1.0;
light->param[VS::LIGHT_PARAM_SPOT_ANGLE]=45;
+ light->param[VS::LIGHT_PARAM_CONTACT_SHADOW_SIZE]=45;
light->param[VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE]=0;
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET]=0.1;
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET]=0.3;
@@ -4753,6 +4777,7 @@ RID RasterizerStorageGLES3::gi_probe_create() {
gip->bounds=Rect3(Vector3(),Vector3(1,1,1));
gip->dynamic_range=1.0;
gip->energy=1.0;
+ gip->propagation=1.0;
gip->interior=false;
gip->compress=false;
gip->version=1;
@@ -4858,6 +4883,15 @@ void RasterizerStorageGLES3::gi_probe_set_energy(RID p_probe,float p_range){
}
+void RasterizerStorageGLES3::gi_probe_set_propagation(RID p_probe,float p_range){
+
+ GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND(!gip);
+
+ gip->propagation=p_range;
+
+}
+
void RasterizerStorageGLES3::gi_probe_set_interior(RID p_probe,bool p_enable) {
GIProbe *gip = gi_probe_owner.getornull(p_probe);
@@ -4902,6 +4936,16 @@ float RasterizerStorageGLES3::gi_probe_get_energy(RID p_probe) const{
return gip->energy;
}
+float RasterizerStorageGLES3::gi_probe_get_propagation(RID p_probe) const{
+
+ const GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND_V(!gip,0);
+
+ return gip->propagation;
+}
+
+
+
uint32_t RasterizerStorageGLES3::gi_probe_get_version(RID p_probe) {
@@ -5403,12 +5447,14 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
+
if (rt->fbo) {
glDeleteFramebuffers(1,&rt->fbo);
glDeleteTextures(1,&rt->color);
rt->fbo=0;
}
+
if (rt->buffers.fbo) {
glDeleteFramebuffers(1,&rt->buffers.fbo);
glDeleteRenderbuffers(1,&rt->buffers.depth);
@@ -5422,11 +5468,13 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
rt->buffers.fbo=0;
}
+
if (rt->depth) {
glDeleteTextures(1,&rt->depth);
rt->depth=0;
}
+
if (rt->effects.ssao.blur_fbo[0]) {
glDeleteFramebuffers(1,&rt->effects.ssao.blur_fbo[0]);
glDeleteTextures(1,&rt->effects.ssao.blur_red[0]);
@@ -5439,11 +5487,16 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
rt->effects.ssao.depth_mipmap_fbos.clear();
glDeleteTextures(1,&rt->effects.ssao.linear_depth);
+
+ rt->effects.ssao.blur_fbo[0]=0;
+ rt->effects.ssao.blur_fbo[1]=0;
}
+
if (rt->exposure.fbo) {
glDeleteFramebuffers(1,&rt->exposure.fbo);
glDeleteTextures(1,&rt->exposure.color);
+ rt->exposure.fbo=0;
}
Texture *tex = texture_owner.get(rt->texture);
tex->alloc_height=0;
@@ -5451,6 +5504,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
tex->width=0;
tex->height=0;
+
for(int i=0;i<2;i++) {
for(int j=0;j<rt->effects.mip_maps[i].sizes.size();j++) {
glDeleteFramebuffers(1,&rt->effects.mip_maps[i].sizes[j].fbo);
@@ -5460,6 +5514,8 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
rt->effects.mip_maps[i].sizes.clear();
rt->effects.mip_maps[i].levels=0;
}
+
+
/*
if (rt->effects.screen_space_depth) {
glDeleteTextures(1,&rt->effects.screen_space_depth);
@@ -5474,7 +5530,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
if (rt->width<=0 || rt->height<=0)
return;
-
GLuint color_internal_format;
GLuint color_format;
GLuint color_type;
@@ -6294,6 +6349,25 @@ bool RasterizerStorageGLES3::free(RID p_rid){
return true;
}
+
+bool RasterizerStorageGLES3::has_os_feature(const String& p_feature) const {
+
+ if (p_feature=="s3tc")
+ return config.s3tc_supported;
+
+ if (p_feature=="etc")
+ return config.etc_supported;
+
+ if (p_feature=="etc2")
+ return config.etc2_supported;
+
+ if (p_feature=="pvrtc")
+ return config.pvrtc_supported;
+
+ return false;
+
+}
+
////////////////////////////////////////////
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index c8f04f72c1..07998886a8 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -228,6 +228,12 @@ public:
Image images[6];
+ VisualServer::TextureDetectCallback detect_3d;
+ void *detect_3d_ud;
+
+ VisualServer::TextureDetectCallback detect_srgb;
+ void *detect_srgb_ud;
+
Texture() {
using_srgb=false;
@@ -243,6 +249,10 @@ public:
total_data_size=0;
target=GL_TEXTURE_2D;
mipmaps=0;
+ detect_3d=NULL;
+ detect_3d_ud=NULL;
+ detect_srgb=NULL;
+ detect_srgb_ud=NULL;
}
@@ -281,6 +291,10 @@ public:
virtual void textures_keep_original(bool p_enable);
+ virtual void texture_set_detect_3d_callback(RID p_texture,VisualServer::TextureDetectCallback p_callback,void* p_userdata);
+ virtual void texture_set_detect_srgb_callback(RID p_texture,VisualServer::TextureDetectCallback p_callback,void* p_userdata);
+
+
/* SKYBOX API */
struct SkyBox : public RID_Data {
@@ -907,6 +921,7 @@ public:
int dynamic_range;
float energy;
+ float propagation;
bool interior;
bool compress;
@@ -939,6 +954,9 @@ public:
virtual void gi_probe_set_energy(RID p_probe,float p_range);
virtual float gi_probe_get_energy(RID p_probe) const;
+ virtual void gi_probe_set_propagation(RID p_probe,float p_range);
+ virtual float gi_probe_get_propagation(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;
@@ -1160,9 +1178,11 @@ public:
height=0;
depth=0;
fbo=0;
+ exposure.fbo=0;
buffers.fbo=0;
used_in_frame=false;
+
flags[RENDER_TARGET_VFLIP]=false;
flags[RENDER_TARGET_TRANSPARENT]=false;
flags[RENDER_TARGET_NO_3D]=false;
@@ -1237,6 +1257,7 @@ public:
void initialize();
void finalize();
+ virtual bool has_os_feature(const String& p_feature) const;
RasterizerStorageGLES3();
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 97872226a4..12aac79912 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -582,6 +582,7 @@ Error ShaderCompilerGLES3::compile(VS::ShaderMode p_mode, const String& p_code,
used_name_defines.clear();
used_rmode_defines.clear();
+ used_flag_pointers.clear();
_dump_node_code(parser.get_shader(),1,r_gen_code,*p_actions,actions[p_mode]);
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 66123193e6..200c0c0cac 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -71,6 +71,7 @@ layout(std140) uniform SceneData { //ubo:0
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
+ highp vec2 screen_pixel_size;
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
@@ -91,7 +92,7 @@ layout(std140) uniform DirectionalLightData { //ubo:3
mediump vec4 light_color_energy;
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
mediump vec4 light_clamp;
- mediump vec4 shadow_color;
+ mediump vec4 shadow_color_contact;
highp mat4 shadow_matrix1;
highp mat4 shadow_matrix2;
highp mat4 shadow_matrix3;
@@ -126,13 +127,6 @@ out vec3 binormal_interp;
#endif
-#if !defined(USE_DEPTH_SHADOWS) && defined(USE_SHADOW_PASS)
-
-varying vec4 position_interp;
-
-#endif
-
-
VERTEX_SHADER_GLOBALS
@@ -161,6 +155,8 @@ layout(std140) uniform SkeletonData { //ubo:7
#endif
+out highp vec4 position_interp;
+
void main() {
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
@@ -293,7 +289,7 @@ VERTEX_SHADER_CODE
gl_Position = vertex;
#endif
-
+ position_interp=gl_Position;
}
@@ -375,6 +371,8 @@ layout(std140) uniform SceneData {
highp vec4 ambient_light_color;
highp vec4 bg_color;
+
+
float ambient_energy;
float bg_energy;
@@ -383,6 +381,7 @@ layout(std140) uniform SceneData {
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
+ highp vec2 screen_pixel_size;
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
@@ -403,7 +402,7 @@ layout(std140) uniform DirectionalLightData {
mediump vec4 light_color_energy;
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
mediump vec4 light_clamp;
- mediump vec4 shadow_color;
+ mediump vec4 shadow_color_contact;
highp mat4 shadow_matrix1;
highp mat4 shadow_matrix2;
highp mat4 shadow_matrix3;
@@ -425,7 +424,7 @@ struct LightData {
mediump vec4 light_color_energy;
mediump vec4 light_params; //cone attenuation, angle, specular, shadow enabled,
mediump vec4 light_clamp;
- mediump vec4 shadow_color;
+ mediump vec4 shadow_color_contact;
highp mat4 shadow_matrix;
};
@@ -493,6 +492,69 @@ layout(location=0) out vec4 frag_color;
#endif
+in highp vec4 position_interp;
+uniform highp sampler2D depth_buffer; //texunit:-8
+
+float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
+
+ if (abs(dir.z)>0.99)
+ return 1.0;
+
+ vec3 endpoint = pos+dir*max_distance;
+ vec4 source = position_interp;
+ vec4 dest = projection_matrix * vec4(endpoint, 1.0);
+
+ vec2 from_screen = (source.xy / source.w) * 0.5 + 0.5;
+ vec2 to_screen = (dest.xy / dest.w) * 0.5 + 0.5;
+
+ vec2 screen_rel = to_screen - from_screen;
+
+ /*float pixel_size; //approximate pixel size
+
+ if (screen_rel.x > screen_rel.y) {
+
+ pixel_size = abs((pos.x-endpoint.x)/(screen_rel.x/screen_pixel_size.x));
+ } else {
+ pixel_size = abs((pos.y-endpoint.y)/(screen_rel.y/screen_pixel_size.y));
+
+ }*/
+ vec4 bias = projection_matrix * vec4(pos+vec3(0.0,0.0,0.04), 1.0); //todo un-harcode the 0.04
+
+
+
+ vec2 pixel_incr = normalize(screen_rel)*screen_pixel_size;
+
+ float steps = length(screen_rel) / length(pixel_incr);
+
+ //steps=10.0;
+
+ vec4 incr = (dest - source)/steps;
+ float ratio=0.0;
+ float ratio_incr = 1.0/steps;
+
+ do {
+ source += incr*2;
+ bias+=incr*2;
+
+ vec3 uv_depth = (source.xyz / source.w) * 0.5 + 0.5;
+ float depth = texture(depth_buffer,uv_depth.xy).r;
+
+ if (depth < uv_depth.z) {
+ if (depth > (bias.z/bias.w) * 0.5 + 0.5) {
+ return min(pow(ratio,4.0),1.0);
+ } else {
+ return 1.0;
+ }
+ }
+
+
+ ratio+=ratio_incr;
+ steps-=1.0;
+ } while (steps>0.0);
+
+ return 1.0;
+}
+
// GGX Specular
// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
@@ -517,6 +579,8 @@ float GTR1(float NdotH, float a)
return (a2-1.0) / (M_PI*log(a2)*t);
}
+
+
void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 specular_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) {
float dotNL = max(dot(N,L), 0.0 );
@@ -660,7 +724,8 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 specular, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
- float normalized_distance = length( light_rel_vec )*omni_lights[idx].light_pos_inv_radius.w;
+ float light_length = length( light_rel_vec );
+ float normalized_distance = light_length*omni_lights[idx].light_pos_inv_radius.w;
vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), omni_lights[idx].light_direction_attenuation.w ));
if (omni_lights[idx].light_params.w>0.5) {
@@ -696,8 +761,15 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
splane.z = shadow_len * omni_lights[idx].light_pos_inv_radius.w;
splane.xy = clamp_rect.xy+splane.xy*clamp_rect.zw;
+ float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect);
+ if (shadow>0.01 && omni_lights[idx].shadow_color_contact.a>0.0) {
+
+ float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,omni_lights[idx].shadow_color_contact.a));
+ shadow=min(shadow,contact_shadow);
- light_attenuation*=mix(omni_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,clamp_rect));
+
+ }
+ light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
@@ -707,7 +779,8 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 specular, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
- float normalized_distance = length( light_rel_vec )*spot_lights[idx].light_pos_inv_radius.w;
+ float light_length = length( light_rel_vec );
+ float normalized_distance = light_length*spot_lights[idx].light_pos_inv_radius.w;
vec3 light_attenuation = vec3(pow( max(1.0 - normalized_distance, 0.0), spot_lights[idx].light_direction_attenuation.w ));
vec3 spot_dir = spot_lights[idx].light_direction_attenuation.xyz;
float spot_cutoff=spot_lights[idx].light_params.y;
@@ -719,7 +792,17 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
//there is a shadowmap
highp vec4 splane=(spot_lights[idx].shadow_matrix * vec4(vertex,1.0));
splane.xyz/=splane.w;
- light_attenuation*=mix(spot_lights[idx].shadow_color.rgb,vec3(1.0),sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp));
+
+ float shadow = sample_shadow(shadow_atlas,shadow_atlas_pixel_size,splane.xy,splane.z,spot_lights[idx].light_clamp);
+
+ if (shadow>0.01 && spot_lights[idx].shadow_color_contact.a>0.0) {
+
+ float contact_shadow = contact_shadow_compute(vertex,normalize(light_rel_vec),min(light_length,spot_lights[idx].shadow_color_contact.a));
+ shadow=min(shadow,contact_shadow);
+
+ }
+
+ light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,specular,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
@@ -1268,6 +1351,8 @@ FRAGMENT_SHADER_CODE
}
}
+
+
#endif //LIGHT_USE_PSSM4
#ifdef LIGHT_USE_PSSM2
@@ -1306,16 +1391,26 @@ FRAGMENT_SHADER_CODE
//one one sample
- light_attenuation=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp));
+ float shadow = sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord.xy,pssm_coord.z,light_clamp);
#if defined(LIGHT_USE_PSSM_BLEND)
+
if (use_blend) {
- vec3 light_attenuation2=mix(shadow_color.rgb,vec3(1.0),sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp));
- light_attenuation=mix(light_attenuation,light_attenuation2,pssm_blend);
+ shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp));
}
#endif
+ if (shadow>0.01 && shadow_color_contact.a>0.0) {
+
+ float contact_shadow = contact_shadow_compute(vertex,-light_direction_attenuation.xyz,shadow_color_contact.a);
+ shadow=min(shadow,contact_shadow);
+
+ }
+
+ light_attenuation=mix(shadow_color_contact.rgb,vec3(1.0),shadow);
+
+
}
#endif //LIGHT_DIRECTIONAL_SHADOW
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 283cff0486..cc69283f97 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -30,6 +30,7 @@
#ifdef UNIX_ENABLED
+#include "servers/visual_server.h"
#include "thread_posix.h"
#include "semaphore_posix.h"
@@ -478,6 +479,13 @@ String OS_Unix::get_data_dir() const {
}
+bool OS_Unix::check_feature_support(const String& p_feature) {
+
+ return VisualServer::get_singleton()->has_os_feature(p_feature);
+
+}
+
+
String OS_Unix::get_installed_templates_path() const {
String p=get_global_settings_path();
if (p!="")
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index b28adc2ee0..220f818ff6 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -117,6 +117,8 @@ public:
virtual String get_executable_path() const;
virtual String get_data_dir() const;
+ virtual bool check_feature_support(const String& p_feature);
+
//virtual void run( MainLoop * p_main_loop );