diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 1 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 84 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 6 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 88 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 21 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 131 | ||||
-rw-r--r-- | drivers/unix/os_unix.cpp | 8 | ||||
-rw-r--r-- | drivers/unix/os_unix.h | 2 |
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 ); |