Subsurface scattering material param is now working!
This commit is contained in:
parent
8c6a586b75
commit
27a46d78ec
17 changed files with 378 additions and 49 deletions
|
@ -1809,6 +1809,10 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
||||||
mirror=!mirror;
|
mirror=!mirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m->shader->spatial.uses_sss) {
|
||||||
|
state.used_sss=true;
|
||||||
|
}
|
||||||
|
|
||||||
if (p_shadow) {
|
if (p_shadow) {
|
||||||
|
|
||||||
if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode!=RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
|
if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode!=RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
|
||||||
|
@ -1827,6 +1831,7 @@ void RasterizerSceneGLES3::_add_geometry( RasterizerStorageGLES3::Geometry* p_g
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
|
RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
|
@ -2620,6 +2625,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase** p_cull_result,int p_
|
||||||
|
|
||||||
current_geometry_index=0;
|
current_geometry_index=0;
|
||||||
current_material_index=0;
|
current_material_index=0;
|
||||||
|
state.used_sss=false;
|
||||||
|
|
||||||
//fill list
|
//fill list
|
||||||
|
|
||||||
|
@ -2683,6 +2689,50 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
if (state.used_sss) {//sss enabled
|
||||||
|
//copy diffuse while performing sss
|
||||||
|
|
||||||
|
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_LOW);
|
||||||
|
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_MEDIUM);
|
||||||
|
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_25_SAMPLES,subsurface_scatter_quality==SSS_QUALITY_HIGH);
|
||||||
|
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::ENABLE_FOLLOW_SURFACE,subsurface_scatter_follow_surface);
|
||||||
|
state.sss_shader.bind();
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::MAX_RADIUS,subsurface_scatter_size);
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::FOVY,p_cam_projection.get_fov());
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::CAMERA_Z_NEAR,p_cam_projection.get_z_near());
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::CAMERA_Z_FAR,p_cam_projection.get_z_far());
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR,Vector2(1,0));
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.motion_sss);
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo); //copy to front first
|
||||||
|
|
||||||
|
_copy_screen();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->color);
|
||||||
|
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR,Vector2(0,1));
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
|
||||||
|
_copy_screen();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// just copy diffuse
|
||||||
|
storage->shaders.copy.bind();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
|
||||||
|
_copy_screen();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (env->ssr_enabled) {
|
if (env->ssr_enabled) {
|
||||||
//blur diffuse into effect mipmaps using separatable convolution
|
//blur diffuse into effect mipmaps using separatable convolution
|
||||||
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
|
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
|
||||||
|
@ -2698,11 +2748,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
|
||||||
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE,Vector2(1.0/vp_w,1.0/vp_h));
|
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE,Vector2(1.0/vp_w,1.0/vp_h));
|
||||||
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(i));
|
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(i));
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
if (i==0) {
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
|
|
||||||
}
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
|
||||||
_copy_screen();
|
_copy_screen();
|
||||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL,false);
|
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL,false);
|
||||||
|
@ -2748,7 +2794,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.normal_sr);
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.normal_rough);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
@ -2764,22 +2810,26 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//copy reflection over diffuse, resolving SSR if needed
|
||||||
state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR,env->ssr_enabled);
|
state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR,env->ssr_enabled);
|
||||||
state.resolve_shader.bind();
|
state.resolve_shader.bind();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.diffuse);
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.specular);
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->buffers.specular);
|
||||||
if (env->ssr_enabled) {
|
if (env->ssr_enabled) {
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[1].color);
|
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[1].color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
|
||||||
//glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
|
glEnable(GL_BLEND);
|
||||||
|
glBlendEquation(GL_FUNC_ADD);
|
||||||
|
glBlendFunc(GL_ONE,GL_ONE); //use additive to accumulate one over the other
|
||||||
|
|
||||||
_copy_screen();
|
_copy_screen();
|
||||||
|
|
||||||
|
glDisable(GL_BLEND); //end additive
|
||||||
|
|
||||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY,true);
|
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY,true);
|
||||||
state.effect_blur_shader.bind();
|
state.effect_blur_shader.bind();
|
||||||
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(0));
|
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(0));
|
||||||
|
@ -2839,6 +2889,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||||
bool use_mrt=true;
|
bool use_mrt=true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_fill_render_list(p_cull_result,p_cull_count,false);
|
_fill_render_list(p_cull_result,p_cull_count,false);
|
||||||
//
|
//
|
||||||
|
|
||||||
|
@ -2893,11 +2944,17 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT0);
|
draw_buffers.push_back(GL_COLOR_ATTACHMENT0);
|
||||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT1);
|
draw_buffers.push_back(GL_COLOR_ATTACHMENT1);
|
||||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT2);
|
draw_buffers.push_back(GL_COLOR_ATTACHMENT2);
|
||||||
|
if (state.used_sss) {
|
||||||
|
draw_buffers.push_back(GL_COLOR_ATTACHMENT3);
|
||||||
|
}
|
||||||
glDrawBuffers(draw_buffers.size(),draw_buffers.ptr());
|
glDrawBuffers(draw_buffers.size(),draw_buffers.ptr());
|
||||||
|
|
||||||
Color black(0,0,0,0);
|
Color black(0,0,0,0);
|
||||||
glClearBufferfv(GL_COLOR,1,black.components); // specular
|
glClearBufferfv(GL_COLOR,1,black.components); // specular
|
||||||
glClearBufferfv(GL_COLOR,2,black.components); // normal metal rough
|
glClearBufferfv(GL_COLOR,2,black.components); // normal metal rough
|
||||||
|
if (state.used_sss) {
|
||||||
|
glClearBufferfv(GL_COLOR,3,black.components); // normal metal rough
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -3968,11 +4025,25 @@ void RasterizerSceneGLES3::initialize() {
|
||||||
state.resolve_shader.init();
|
state.resolve_shader.init();
|
||||||
state.ssr_shader.init();
|
state.ssr_shader.init();
|
||||||
state.effect_blur_shader.init();
|
state.effect_blur_shader.init();
|
||||||
|
state.sss_shader.init();
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
GLOBAL_DEF("rendering/gles3/subsurface_scattering/quality",1);
|
||||||
|
Globals::get_singleton()->set_custom_property_info("rendering/gles3/subsurface_scattering/quality",PropertyInfo(Variant::INT,"rendering/gles3/subsurface_scattering/quality",PROPERTY_HINT_ENUM,"Low,Medium,High"));
|
||||||
|
GLOBAL_DEF("rendering/gles3/subsurface_scattering/max_size",1.0);
|
||||||
|
Globals::get_singleton()->set_custom_property_info("rendering/gles3/subsurface_scattering/max_size",PropertyInfo(Variant::INT,"rendering/gles3/subsurface_scattering/max_size",PROPERTY_HINT_RANGE,"0.01,8,0.01"));
|
||||||
|
GLOBAL_DEF("rendering/gles3/subsurface_scattering/follow_surface",false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerSceneGLES3::iteration() {
|
void RasterizerSceneGLES3::iteration() {
|
||||||
|
|
||||||
shadow_filter_mode=ShadowFilterMode(int(Globals::get_singleton()->get("rendering/gles3/shadow_filter_mode")));
|
shadow_filter_mode=ShadowFilterMode(int(Globals::get_singleton()->get("rendering/gles3/shadow_filter_mode")));
|
||||||
|
subsurface_scatter_follow_surface=Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/follow_surface");
|
||||||
|
subsurface_scatter_quality=SubSurfaceScatterQuality(int(Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/quality")));
|
||||||
|
subsurface_scatter_size=Globals::get_singleton()->get("rendering/gles3/subsurface_scattering/max_size");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerSceneGLES3::finalize(){
|
void RasterizerSceneGLES3::finalize(){
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "drivers/gles3/shaders/resolve.glsl.h"
|
#include "drivers/gles3/shaders/resolve.glsl.h"
|
||||||
#include "drivers/gles3/shaders/screen_space_reflection.glsl.h"
|
#include "drivers/gles3/shaders/screen_space_reflection.glsl.h"
|
||||||
#include "drivers/gles3/shaders/effect_blur.glsl.h"
|
#include "drivers/gles3/shaders/effect_blur.glsl.h"
|
||||||
|
#include "drivers/gles3/shaders/subsurf_scattering.glsl.h"
|
||||||
|
|
||||||
class RasterizerSceneGLES3 : public RasterizerScene {
|
class RasterizerSceneGLES3 : public RasterizerScene {
|
||||||
public:
|
public:
|
||||||
|
@ -22,6 +23,15 @@ public:
|
||||||
|
|
||||||
uint64_t shadow_atlas_realloc_tolerance_msec;
|
uint64_t shadow_atlas_realloc_tolerance_msec;
|
||||||
|
|
||||||
|
enum SubSurfaceScatterQuality {
|
||||||
|
SSS_QUALITY_LOW,
|
||||||
|
SSS_QUALITY_MEDIUM,
|
||||||
|
SSS_QUALITY_HIGH,
|
||||||
|
};
|
||||||
|
|
||||||
|
SubSurfaceScatterQuality subsurface_scatter_quality;
|
||||||
|
float subsurface_scatter_size;
|
||||||
|
bool subsurface_scatter_follow_surface;
|
||||||
|
|
||||||
uint64_t render_pass;
|
uint64_t render_pass;
|
||||||
uint64_t scene_pass;
|
uint64_t scene_pass;
|
||||||
|
@ -51,6 +61,7 @@ public:
|
||||||
ResolveShaderGLES3 resolve_shader;
|
ResolveShaderGLES3 resolve_shader;
|
||||||
ScreenSpaceReflectionShaderGLES3 ssr_shader;
|
ScreenSpaceReflectionShaderGLES3 ssr_shader;
|
||||||
EffectBlurShaderGLES3 effect_blur_shader;
|
EffectBlurShaderGLES3 effect_blur_shader;
|
||||||
|
SubsurfScatteringShaderGLES3 sss_shader;
|
||||||
|
|
||||||
|
|
||||||
struct SceneDataUBO {
|
struct SceneDataUBO {
|
||||||
|
@ -118,6 +129,7 @@ public:
|
||||||
int reflection_probe_count;
|
int reflection_probe_count;
|
||||||
|
|
||||||
bool cull_front;
|
bool cull_front;
|
||||||
|
bool used_sss;
|
||||||
|
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
|
|
|
@ -1456,6 +1456,7 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
|
||||||
p_shader->spatial.uses_alpha=false;
|
p_shader->spatial.uses_alpha=false;
|
||||||
p_shader->spatial.unshaded=false;
|
p_shader->spatial.unshaded=false;
|
||||||
p_shader->spatial.ontop=false;
|
p_shader->spatial.ontop=false;
|
||||||
|
p_shader->spatial.uses_sss=false;
|
||||||
|
|
||||||
shaders.actions_scene.render_mode_values["blend_add"]=Pair<int*,int>(&p_shader->spatial.blend_mode,Shader::Spatial::BLEND_MODE_ADD);
|
shaders.actions_scene.render_mode_values["blend_add"]=Pair<int*,int>(&p_shader->spatial.blend_mode,Shader::Spatial::BLEND_MODE_ADD);
|
||||||
shaders.actions_scene.render_mode_values["blend_mix"]=Pair<int*,int>(&p_shader->spatial.blend_mode,Shader::Spatial::BLEND_MODE_MIX);
|
shaders.actions_scene.render_mode_values["blend_mix"]=Pair<int*,int>(&p_shader->spatial.blend_mode,Shader::Spatial::BLEND_MODE_MIX);
|
||||||
|
@ -1477,6 +1478,8 @@ void RasterizerStorageGLES3::_update_shader(Shader* p_shader) const {
|
||||||
shaders.actions_scene.usage_flag_pointers["ALPHA"]=&p_shader->spatial.uses_alpha;
|
shaders.actions_scene.usage_flag_pointers["ALPHA"]=&p_shader->spatial.uses_alpha;
|
||||||
shaders.actions_scene.usage_flag_pointers["VERTEX"]=&p_shader->spatial.uses_vertex;
|
shaders.actions_scene.usage_flag_pointers["VERTEX"]=&p_shader->spatial.uses_vertex;
|
||||||
|
|
||||||
|
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"]=&p_shader->spatial.uses_sss;
|
||||||
|
|
||||||
actions=&shaders.actions_scene;
|
actions=&shaders.actions_scene;
|
||||||
actions->uniforms=&p_shader->uniforms;
|
actions->uniforms=&p_shader->uniforms;
|
||||||
|
|
||||||
|
@ -4771,7 +4774,8 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
|
||||||
glDeleteFramebuffers(1,&rt->buffers.alpha_fbo);
|
glDeleteFramebuffers(1,&rt->buffers.alpha_fbo);
|
||||||
glDeleteTextures(1,&rt->buffers.diffuse);
|
glDeleteTextures(1,&rt->buffers.diffuse);
|
||||||
glDeleteTextures(1,&rt->buffers.specular);
|
glDeleteTextures(1,&rt->buffers.specular);
|
||||||
glDeleteTextures(1,&rt->buffers.normal_sr);
|
glDeleteTextures(1,&rt->buffers.normal_rough);
|
||||||
|
glDeleteTextures(1,&rt->buffers.motion_sss);
|
||||||
rt->buffers.fbo=0;
|
rt->buffers.fbo=0;
|
||||||
rt->buffers.alpha_fbo=0;
|
rt->buffers.alpha_fbo=0;
|
||||||
}
|
}
|
||||||
|
@ -4923,14 +4927,23 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->buffers.specular, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rt->buffers.specular, 0);
|
||||||
|
|
||||||
glGenTextures(1, &rt->buffers.normal_sr);
|
glGenTextures(1, &rt->buffers.normal_rough);
|
||||||
glBindTexture(GL_TEXTURE_2D, rt->buffers.normal_sr);
|
glBindTexture(GL_TEXTURE_2D, rt->buffers.normal_rough);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->buffers.normal_sr, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, rt->buffers.normal_rough, 0);
|
||||||
|
|
||||||
|
glGenTextures(1, &rt->buffers.motion_sss);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, rt->buffers.motion_sss);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, rt->width, rt->height, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, rt->buffers.motion_sss, 0);
|
||||||
|
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
|
|
@ -369,6 +369,7 @@ public:
|
||||||
bool ontop;
|
bool ontop;
|
||||||
bool uses_vertex;
|
bool uses_vertex;
|
||||||
bool uses_discard;
|
bool uses_discard;
|
||||||
|
bool uses_sss;
|
||||||
|
|
||||||
} spatial;
|
} spatial;
|
||||||
|
|
||||||
|
@ -886,8 +887,8 @@ public:
|
||||||
GLuint alpha_fbo; //single buffer, just diffuse (for alpha pass)
|
GLuint alpha_fbo; //single buffer, just diffuse (for alpha pass)
|
||||||
GLuint specular;
|
GLuint specular;
|
||||||
GLuint diffuse;
|
GLuint diffuse;
|
||||||
GLuint normal_sr;
|
GLuint normal_rough;
|
||||||
GLuint temporal;
|
GLuint motion_sss;
|
||||||
} buffers;
|
} buffers;
|
||||||
|
|
||||||
struct Effects {
|
struct Effects {
|
||||||
|
|
|
@ -422,9 +422,9 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
|
||||||
used_name_defines.insert(vnode->name);
|
used_name_defines.insert(vnode->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_actions.usage_flag_pointers.has(vnode->name) && !used_name_defines.has(vnode->name)) {
|
if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) {
|
||||||
*p_actions.usage_flag_pointers[vnode->name]=true;
|
*p_actions.usage_flag_pointers[vnode->name]=true;
|
||||||
used_name_defines.insert(vnode->name);
|
used_flag_pointers.insert(vnode->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_default_actions.renames.has(vnode->name))
|
if (p_default_actions.renames.has(vnode->name))
|
||||||
|
@ -670,6 +670,8 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
||||||
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"]="clearcoat_gloss";
|
actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"]="clearcoat_gloss";
|
||||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"]="anisotropy";
|
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"]="anisotropy";
|
||||||
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"]="anisotropy_flow";
|
actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"]="anisotropy_flow";
|
||||||
|
actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"]="sss_spread";
|
||||||
|
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"]="sss_strength";
|
||||||
actions[VS::SHADER_SPATIAL].renames["AO"]="ao";
|
actions[VS::SHADER_SPATIAL].renames["AO"]="ao";
|
||||||
actions[VS::SHADER_SPATIAL].renames["EMISSION"]="emission";
|
actions[VS::SHADER_SPATIAL].renames["EMISSION"]="emission";
|
||||||
actions[VS::SHADER_SPATIAL].renames["DISCARD"]="_discard";
|
actions[VS::SHADER_SPATIAL].renames["DISCARD"]="_discard";
|
||||||
|
@ -692,6 +694,11 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
|
||||||
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"]="@NORMALMAP";
|
actions[VS::SHADER_SPATIAL].usage_defines["NORMALMAP_DEPTH"]="@NORMALMAP";
|
||||||
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"]="#define ENABLE_COLOR_INTERP\n";
|
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"]="#define ENABLE_COLOR_INTERP\n";
|
||||||
|
|
||||||
|
actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"]="#define ENABLE_SSS_MOTION\n";
|
||||||
|
|
||||||
|
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"]="sss_strength";
|
||||||
|
|
||||||
|
|
||||||
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
|
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_transform"]="#define SKIP_TRANSFORM_USED\n";
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ private:
|
||||||
StringName time_name;
|
StringName time_name;
|
||||||
|
|
||||||
Set<StringName> used_name_defines;
|
Set<StringName> used_name_defines;
|
||||||
|
Set<StringName> used_flag_pointers;
|
||||||
Set<StringName> used_rmode_defines;
|
Set<StringName> used_rmode_defines;
|
||||||
Set<StringName> internal_functions;
|
Set<StringName> internal_functions;
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,6 @@ if env['BUILDERS'].has_key('GLES3_GLSL'):
|
||||||
env.GLES3_GLSL('blend_shape.glsl');
|
env.GLES3_GLSL('blend_shape.glsl');
|
||||||
env.GLES3_GLSL('screen_space_reflection.glsl');
|
env.GLES3_GLSL('screen_space_reflection.glsl');
|
||||||
env.GLES3_GLSL('effect_blur.glsl');
|
env.GLES3_GLSL('effect_blur.glsl');
|
||||||
|
env.GLES3_GLSL('subsurf_scattering.glsl');
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,8 @@ void main() {
|
||||||
|
|
||||||
|
|
||||||
in vec2 uv_interp;
|
in vec2 uv_interp;
|
||||||
uniform sampler2D source_diffuse; //texunit:0
|
uniform sampler2D source_specular; //texunit:0
|
||||||
uniform sampler2D source_specular; //texunit:1
|
uniform sampler2D source_ssr; //texunit:1
|
||||||
|
|
||||||
|
|
||||||
uniform sampler2D source_ssr_ssao; //texunit:2
|
|
||||||
|
|
||||||
uniform float stuff;
|
uniform float stuff;
|
||||||
|
|
||||||
|
@ -31,15 +28,14 @@ layout(location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
||||||
vec4 diffuse = texture( source_diffuse, uv_interp );
|
|
||||||
vec4 specular = texture( source_specular, uv_interp );
|
vec4 specular = texture( source_specular, uv_interp );
|
||||||
|
|
||||||
#ifdef USE_SSR
|
#ifdef USE_SSR
|
||||||
|
|
||||||
vec4 ssr = textureLod(source_ssr_ssao,uv_interp,0.0);
|
vec4 ssr = textureLod(source_ssr,uv_interp,0.0);
|
||||||
specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a);
|
specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
frag_color = vec4(diffuse.rgb,1.0)+vec4(specular.rgb,1.0);
|
frag_color = vec4(specular.rgb,1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ layout(std140) uniform SceneData { //ubo:0
|
||||||
vec2 directional_shadow_pixel_size;
|
vec2 directional_shadow_pixel_size;
|
||||||
|
|
||||||
float reflection_multiplier;
|
float reflection_multiplier;
|
||||||
|
float subsurface_scatter_width;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -385,6 +386,7 @@ layout(std140) uniform SceneData {
|
||||||
vec2 directional_shadow_pixel_size;
|
vec2 directional_shadow_pixel_size;
|
||||||
|
|
||||||
float reflection_multiplier;
|
float reflection_multiplier;
|
||||||
|
float subsurface_scatter_width;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -479,6 +481,9 @@ uniform int reflection_count;
|
||||||
layout(location=0) out vec4 diffuse_buffer;
|
layout(location=0) out vec4 diffuse_buffer;
|
||||||
layout(location=1) out vec4 specular_buffer;
|
layout(location=1) out vec4 specular_buffer;
|
||||||
layout(location=2) out vec4 normal_mr_buffer;
|
layout(location=2) out vec4 normal_mr_buffer;
|
||||||
|
#if defined (ENABLE_SSS_MOTION)
|
||||||
|
layout(location=3) out uint motion_ssr_buffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -621,6 +626,35 @@ in highp float dp_clip;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
//need to save texture depth for this
|
||||||
|
|
||||||
|
vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 pos, float distance) {
|
||||||
|
|
||||||
|
float scale = 8.25 * (1.0 - translucency) / subsurface_scatter_width;
|
||||||
|
float d = scale * distance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Armed with the thickness, we can now calculate the color by means of the
|
||||||
|
* precalculated transmittance profile.
|
||||||
|
* (It can be precomputed into a texture, for maximum performance):
|
||||||
|
*/
|
||||||
|
float dd = -d * d;
|
||||||
|
vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
|
||||||
|
vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
|
||||||
|
vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
|
||||||
|
vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
|
||||||
|
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
|
||||||
|
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using the profile, we finally approximate the transmitted lighting from
|
||||||
|
* the back of the object:
|
||||||
|
*/
|
||||||
|
return profile * clamp(0.3 + dot(light_vec, normal),0.0,1.0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
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) {
|
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;
|
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
|
||||||
|
@ -870,6 +904,10 @@ void main() {
|
||||||
bool discard_=false;
|
bool discard_=false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined (ENABLE_SSS_MOTION)
|
||||||
|
float sss_strength=0.0;
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
@ -1194,6 +1232,10 @@ LIGHT_SHADER_CODE
|
||||||
|
|
||||||
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
|
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
|
||||||
|
|
||||||
|
#if defined (ENABLE_SSS_MOTION)
|
||||||
|
motion_ssr_buffer = uint(clamp(sqrt(sss_strength)*255.0,0.0,255))<<24;
|
||||||
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ in vec2 pos_interp;
|
||||||
uniform sampler2D source_diffuse; //texunit:0
|
uniform sampler2D source_diffuse; //texunit:0
|
||||||
uniform sampler2D source_normal_roughness; //texunit:1
|
uniform sampler2D source_normal_roughness; //texunit:1
|
||||||
uniform sampler2D source_depth; //texunit:2
|
uniform sampler2D source_depth; //texunit:2
|
||||||
uniform sampler2D source_diffuse_mipmaps; //texunit:3
|
|
||||||
|
|
||||||
uniform float camera_z_near;
|
uniform float camera_z_near;
|
||||||
uniform float camera_z_far;
|
uniform float camera_z_far;
|
||||||
|
@ -295,11 +294,7 @@ void main() {
|
||||||
|
|
||||||
vec4 sample_color;
|
vec4 sample_color;
|
||||||
{
|
{
|
||||||
sample_color = textureLod(source_diffuse_mipmaps,sample_pos,max(1.0,mipmap));
|
sample_color = textureLod(source_diffuse,sample_pos,mipmap);
|
||||||
if (mipmap<1.0) { //we use another image as base to avoid copying all the screen unnecesarily
|
|
||||||
vec4 base_sample_color = textureLod(source_diffuse,sample_pos,0.0);
|
|
||||||
sample_color = mix(base_sample_color,sample_color,mipmap);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//multiply by gloss
|
//multiply by gloss
|
||||||
|
|
172
drivers/gles3/shaders/subsurf_scattering.glsl
Normal file
172
drivers/gles3/shaders/subsurf_scattering.glsl
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
[vertex]
|
||||||
|
|
||||||
|
|
||||||
|
layout(location=0) in highp vec4 vertex_attrib;
|
||||||
|
layout(location=4) in vec2 uv_in;
|
||||||
|
|
||||||
|
out vec2 uv_interp;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
uv_interp = uv_in;
|
||||||
|
gl_Position = vertex_attrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
[fragment]
|
||||||
|
|
||||||
|
//#define QUALIFIER uniform // some guy on the interweb says it may be faster with this
|
||||||
|
#define QUALIFIER const
|
||||||
|
|
||||||
|
#ifdef USE_25_SAMPLES
|
||||||
|
|
||||||
|
const int kernel_size=25;
|
||||||
|
QUALIFIER vec4 kernel[25] = vec4[] (
|
||||||
|
vec4(0.530605, 0.613514, 0.739601, 0.0),
|
||||||
|
vec4(0.000973794, 1.11862e-005, 9.43437e-007, -3.0),
|
||||||
|
vec4(0.00333804, 7.85443e-005, 1.2945e-005, -2.52083),
|
||||||
|
vec4(0.00500364, 0.00020094, 5.28848e-005, -2.08333),
|
||||||
|
vec4(0.00700976, 0.00049366, 0.000151938, -1.6875),
|
||||||
|
vec4(0.0094389, 0.00139119, 0.000416598, -1.33333),
|
||||||
|
vec4(0.0128496, 0.00356329, 0.00132016, -1.02083),
|
||||||
|
vec4(0.017924, 0.00711691, 0.00347194, -0.75),
|
||||||
|
vec4(0.0263642, 0.0119715, 0.00684598, -0.520833),
|
||||||
|
vec4(0.0410172, 0.0199899, 0.0118481, -0.333333),
|
||||||
|
vec4(0.0493588, 0.0367726, 0.0219485, -0.1875),
|
||||||
|
vec4(0.0402784, 0.0657244, 0.04631, -0.0833333),
|
||||||
|
vec4(0.0211412, 0.0459286, 0.0378196, -0.0208333),
|
||||||
|
vec4(0.0211412, 0.0459286, 0.0378196, 0.0208333),
|
||||||
|
vec4(0.0402784, 0.0657244, 0.04631, 0.0833333),
|
||||||
|
vec4(0.0493588, 0.0367726, 0.0219485, 0.1875),
|
||||||
|
vec4(0.0410172, 0.0199899, 0.0118481, 0.333333),
|
||||||
|
vec4(0.0263642, 0.0119715, 0.00684598, 0.520833),
|
||||||
|
vec4(0.017924, 0.00711691, 0.00347194, 0.75),
|
||||||
|
vec4(0.0128496, 0.00356329, 0.00132016, 1.02083),
|
||||||
|
vec4(0.0094389, 0.00139119, 0.000416598, 1.33333),
|
||||||
|
vec4(0.00700976, 0.00049366, 0.000151938, 1.6875),
|
||||||
|
vec4(0.00500364, 0.00020094, 5.28848e-005, 2.08333),
|
||||||
|
vec4(0.00333804, 7.85443e-005, 1.2945e-005, 2.52083),
|
||||||
|
vec4(0.000973794, 1.11862e-005, 9.43437e-007, 3.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif //USE_25_SAMPLES
|
||||||
|
|
||||||
|
#ifdef USE_17_SAMPLES
|
||||||
|
|
||||||
|
const int kernel_size=17;
|
||||||
|
|
||||||
|
QUALIFIER vec4 kernel[17] = vec4[](
|
||||||
|
vec4(0.536343, 0.624624, 0.748867, 0.0),
|
||||||
|
vec4(0.00317394, 0.000134823, 3.77269e-005, -2.0),
|
||||||
|
vec4(0.0100386, 0.000914679, 0.000275702, -1.53125),
|
||||||
|
vec4(0.0144609, 0.00317269, 0.00106399, -1.125),
|
||||||
|
vec4(0.0216301, 0.00794618, 0.00376991, -0.78125),
|
||||||
|
vec4(0.0347317, 0.0151085, 0.00871983, -0.5),
|
||||||
|
vec4(0.0571056, 0.0287432, 0.0172844, -0.28125),
|
||||||
|
vec4(0.0582416, 0.0659959, 0.0411329, -0.125),
|
||||||
|
vec4(0.0324462, 0.0656718, 0.0532821, -0.03125),
|
||||||
|
vec4(0.0324462, 0.0656718, 0.0532821, 0.03125),
|
||||||
|
vec4(0.0582416, 0.0659959, 0.0411329, 0.125),
|
||||||
|
vec4(0.0571056, 0.0287432, 0.0172844, 0.28125),
|
||||||
|
vec4(0.0347317, 0.0151085, 0.00871983, 0.5),
|
||||||
|
vec4(0.0216301, 0.00794618, 0.00376991, 0.78125),
|
||||||
|
vec4(0.0144609, 0.00317269, 0.00106399, 1.125),
|
||||||
|
vec4(0.0100386, 0.000914679, 0.000275702, 1.53125),
|
||||||
|
vec4(0.00317394, 0.000134823, 3.77269e-005, 2.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif //USE_17_SAMPLES
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_11_SAMPLES
|
||||||
|
|
||||||
|
const int kernel_size=11;
|
||||||
|
|
||||||
|
QUALIFIER vec4 kernel[11] = vec4[](
|
||||||
|
vec4(0.560479, 0.669086, 0.784728, 0.0),
|
||||||
|
vec4(0.00471691, 0.000184771, 5.07566e-005, -2.0),
|
||||||
|
vec4(0.0192831, 0.00282018, 0.00084214, -1.28),
|
||||||
|
vec4(0.03639, 0.0130999, 0.00643685, -0.72),
|
||||||
|
vec4(0.0821904, 0.0358608, 0.0209261, -0.32),
|
||||||
|
vec4(0.0771802, 0.113491, 0.0793803, -0.08),
|
||||||
|
vec4(0.0771802, 0.113491, 0.0793803, 0.08),
|
||||||
|
vec4(0.0821904, 0.0358608, 0.0209261, 0.32),
|
||||||
|
vec4(0.03639, 0.0130999, 0.00643685, 0.72),
|
||||||
|
vec4(0.0192831, 0.00282018, 0.00084214, 1.28),
|
||||||
|
vec4(0.00471691, 0.000184771, 5.07565e-005, 2.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif //USE_11_SAMPLES
|
||||||
|
|
||||||
|
|
||||||
|
uniform float max_radius;
|
||||||
|
uniform float fovy;
|
||||||
|
uniform float camera_z_far;
|
||||||
|
uniform float camera_z_near;
|
||||||
|
uniform vec2 dir;
|
||||||
|
in vec2 uv_interp;
|
||||||
|
|
||||||
|
uniform sampler2D source_diffuse; //texunit:0
|
||||||
|
uniform highp usampler2D source_motion_ss; //texunit:1
|
||||||
|
uniform sampler2D source_depth; //texunit:2
|
||||||
|
|
||||||
|
layout(location = 0) out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
float strength = float(texture(source_motion_ss,uv_interp).r>>24)*(1.0/255.0);
|
||||||
|
strength*=strength; //stored as sqrt
|
||||||
|
|
||||||
|
// Fetch color of current pixel:
|
||||||
|
vec4 base_color = texture(source_diffuse, uv_interp);
|
||||||
|
|
||||||
|
if (strength>0.0) {
|
||||||
|
|
||||||
|
|
||||||
|
// Fetch linear depth of current pixel:
|
||||||
|
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
|
||||||
|
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
||||||
|
depth=-depth;
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate the radius scale (1.0 for a unit plane sitting on the
|
||||||
|
// projection window):
|
||||||
|
float distance = 1.0 / tan(0.5 * fovy);
|
||||||
|
float scale = distance / -depth; //remember depth is negative by default in OpenGL
|
||||||
|
|
||||||
|
// Calculate the final step to fetch the surrounding pixels:
|
||||||
|
vec2 step = max_radius * scale * dir;
|
||||||
|
step *= strength; // Modulate it using the alpha channel.
|
||||||
|
step *= 1.0 / 3.0; // Divide by 3 as the kernels range from -3 to 3.
|
||||||
|
|
||||||
|
// Accumulate the center sample:
|
||||||
|
vec3 color_accum = base_color.rgb;
|
||||||
|
color_accum *= kernel[0].rgb;
|
||||||
|
|
||||||
|
// Accumulate the other samples:
|
||||||
|
for (int i = 1; i < kernel_size; i++) {
|
||||||
|
// Fetch color and depth for current sample:
|
||||||
|
vec2 offset = uv_interp + kernel[i].a * step;
|
||||||
|
vec3 color = texture(source_diffuse, offset).rgb;
|
||||||
|
|
||||||
|
#ifdef ENABLE_FOLLOW_SURFACE
|
||||||
|
// If the difference in depth is huge, we lerp color back to "colorM":
|
||||||
|
float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0;
|
||||||
|
depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near));
|
||||||
|
depth_cmp=-depth_cmp;
|
||||||
|
|
||||||
|
float s = clamp(300.0f * distance *
|
||||||
|
max_radius * abs(depth - depth_cmp),0.0,1.0);
|
||||||
|
color = mix(color, base_color.rgb, s);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Accumulate:
|
||||||
|
color_accum += kernel[i].rgb * color;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_color = vec4(color_accum,base_color.a); //keep alpha (used for SSAO)
|
||||||
|
} else {
|
||||||
|
frag_color = base_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ void Light::_bind_methods() {
|
||||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
|
ADD_PROPERTY( PropertyInfo( Variant::INT, "light/cull_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_cull_mask"), _SCS("get_cull_mask"));
|
||||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
|
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "shadow/enabled"), _SCS("set_shadow"), _SCS("has_shadow"));
|
||||||
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "shadow/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_shadow_color"), _SCS("get_shadow_color"));
|
ADD_PROPERTY( PropertyInfo( Variant::COLOR, "shadow/color",PROPERTY_HINT_COLOR_NO_ALPHA), _SCS("set_shadow_color"), _SCS("get_shadow_color"));
|
||||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias",PROPERTY_HINT_RANGE,"0,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
|
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/bias",PROPERTY_HINT_RANGE,"-16,16,0.01"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_BIAS);
|
||||||
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
|
ADD_PROPERTYI( PropertyInfo( Variant::REAL, "shadow/max_distance",PROPERTY_HINT_RANGE,"0,65536,0.1"), _SCS("set_param"), _SCS("get_param"), PARAM_SHADOW_MAX_DISTANCE);
|
||||||
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
|
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "editor/editor_only"), _SCS("set_editor_only"), _SCS("is_editor_only"));
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ void FixedSpatialMaterial::init_shaders() {
|
||||||
shader_names->clearcoat_gloss="clearcoat_gloss";
|
shader_names->clearcoat_gloss="clearcoat_gloss";
|
||||||
shader_names->anisotropy="anisotropy_ratio";
|
shader_names->anisotropy="anisotropy_ratio";
|
||||||
shader_names->height_scale="height_scale";
|
shader_names->height_scale="height_scale";
|
||||||
shader_names->subsurface_scattering="subsurface_scattering";
|
shader_names->subsurface_scattering_strength="subsurface_scattering_strength";
|
||||||
shader_names->refraction="refraction";
|
shader_names->refraction="refraction";
|
||||||
shader_names->refraction_roughness="refraction_roughness";
|
shader_names->refraction_roughness="refraction_roughness";
|
||||||
shader_names->point_size="point_size";
|
shader_names->point_size="point_size";
|
||||||
|
@ -217,6 +217,14 @@ void FixedSpatialMaterial::_update_shader() {
|
||||||
code+="uniform sampler2D texture_detail_mask : hint_white;\n";
|
code+="uniform sampler2D texture_detail_mask : hint_white;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (features[FEATURE_SUBSURACE_SCATTERING]) {
|
||||||
|
|
||||||
|
code+="uniform float subsurface_scattering_strength : hint_range(0,1);\n";
|
||||||
|
code+="uniform sampler2D texture_subsurface_scattering : hint_white;\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
code+="\n\n";
|
code+="\n\n";
|
||||||
|
|
||||||
code+="void vertex() {\n";
|
code+="void vertex() {\n";
|
||||||
|
@ -230,7 +238,7 @@ void FixedSpatialMaterial::_update_shader() {
|
||||||
code+="\tPOINT_SIZE=point_size;\n";
|
code+="\tPOINT_SIZE=point_size;\n";
|
||||||
}
|
}
|
||||||
code+="\tUV=UV*uv1_scale+uv1_offset;\n";
|
code+="\tUV=UV*uv1_scale+uv1_offset;\n";
|
||||||
if (detail_blend_mode==DETAIL_UV_2) {
|
if (detail_uv==DETAIL_UV_2) {
|
||||||
code+="\tUV2=UV2*uv2_scale+uv2_offset;\n";
|
code+="\tUV2=UV2*uv2_scale+uv2_offset;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +292,12 @@ void FixedSpatialMaterial::_update_shader() {
|
||||||
code+="\tAO = texture(texture_ambient_occlusion,UV).r;\n";
|
code+="\tAO = texture(texture_ambient_occlusion,UV).r;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (features[FEATURE_SUBSURACE_SCATTERING]) {
|
||||||
|
|
||||||
|
code+="\tfloat sss_tex = texture(texture_subsurface_scattering,UV).r;\n";
|
||||||
|
code+="\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (features[FEATURE_DETAIL]) {
|
if (features[FEATURE_DETAIL]) {
|
||||||
String det_uv=detail_uv==DETAIL_UV_1?"UV":"UV2";
|
String det_uv=detail_uv==DETAIL_UV_1?"UV":"UV2";
|
||||||
code+="\tvec4 detail_tex = texture(texture_detail_albedo,"+det_uv+");\n";
|
code+="\tvec4 detail_tex = texture(texture_detail_albedo,"+det_uv+");\n";
|
||||||
|
@ -512,17 +526,18 @@ float FixedSpatialMaterial::get_height_scale() const{
|
||||||
return height_scale;
|
return height_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedSpatialMaterial::set_subsurface_scattering(float p_subsurface_scattering){
|
|
||||||
|
|
||||||
subsurface_scattering=p_subsurface_scattering;
|
void FixedSpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength){
|
||||||
VS::get_singleton()->material_set_param(_get_material(),shader_names->subsurface_scattering,subsurface_scattering);
|
|
||||||
|
subsurface_scattering_strength=p_subsurface_scattering_strength;
|
||||||
|
VS::get_singleton()->material_set_param(_get_material(),shader_names->subsurface_scattering_strength,subsurface_scattering_strength);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float FixedSpatialMaterial::get_subsurface_scattering() const{
|
float FixedSpatialMaterial::get_subsurface_scattering_strength() const{
|
||||||
|
|
||||||
return subsurface_scattering;
|
return subsurface_scattering_strength;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedSpatialMaterial::set_refraction(float p_refraction){
|
void FixedSpatialMaterial::set_refraction(float p_refraction){
|
||||||
|
@ -806,8 +821,8 @@ void FixedSpatialMaterial::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("set_height_scale","height_scale"),&FixedSpatialMaterial::set_height_scale);
|
ObjectTypeDB::bind_method(_MD("set_height_scale","height_scale"),&FixedSpatialMaterial::set_height_scale);
|
||||||
ObjectTypeDB::bind_method(_MD("get_height_scale"),&FixedSpatialMaterial::get_height_scale);
|
ObjectTypeDB::bind_method(_MD("get_height_scale"),&FixedSpatialMaterial::get_height_scale);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("set_subsurface_scattering","subsurface_scattering"),&FixedSpatialMaterial::set_subsurface_scattering);
|
ObjectTypeDB::bind_method(_MD("set_subsurface_scattering_strength","strength"),&FixedSpatialMaterial::set_subsurface_scattering_strength);
|
||||||
ObjectTypeDB::bind_method(_MD("get_subsurface_scattering"),&FixedSpatialMaterial::get_subsurface_scattering);
|
ObjectTypeDB::bind_method(_MD("get_subsurface_scattering_strength"),&FixedSpatialMaterial::get_subsurface_scattering_strength);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("set_refraction","refraction"),&FixedSpatialMaterial::set_refraction);
|
ObjectTypeDB::bind_method(_MD("set_refraction","refraction"),&FixedSpatialMaterial::set_refraction);
|
||||||
ObjectTypeDB::bind_method(_MD("get_refraction"),&FixedSpatialMaterial::get_refraction);
|
ObjectTypeDB::bind_method(_MD("get_refraction"),&FixedSpatialMaterial::get_refraction);
|
||||||
|
@ -912,7 +927,7 @@ void FixedSpatialMaterial::_bind_methods() {
|
||||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"height/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_HEIGHT);
|
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"height/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_HEIGHT);
|
||||||
|
|
||||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"subsurf_scatter/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SUBSURACE_SCATTERING);
|
ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"subsurf_scatter/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_SUBSURACE_SCATTERING);
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"subsurf_scatter/amount",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_subsurface_scattering"),_SCS("get_subsurface_scattering"));
|
ADD_PROPERTY(PropertyInfo(Variant::REAL,"subsurf_scatter/strength",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_subsurface_scattering_strength"),_SCS("get_subsurface_scattering_strength"));
|
||||||
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"subsurf_scatter/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SUBSURFACE_SCATTERING);
|
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT,"subsurf_scatter/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"),TEXTURE_SUBSURFACE_SCATTERING);
|
||||||
|
|
||||||
ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"refraction/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_REFRACTION);
|
ADD_PROPERTYI(PropertyInfo(Variant::BOOL,"refraction/enabled"),_SCS("set_feature"),_SCS("get_feature"),FEATURE_REFRACTION);
|
||||||
|
@ -1011,7 +1026,7 @@ FixedSpatialMaterial::FixedSpatialMaterial() : element(this) {
|
||||||
set_clearcoat_gloss(0.5);
|
set_clearcoat_gloss(0.5);
|
||||||
set_anisotropy(0);
|
set_anisotropy(0);
|
||||||
set_height_scale(1);
|
set_height_scale(1);
|
||||||
set_subsurface_scattering(0);
|
set_subsurface_scattering_strength(0);
|
||||||
set_refraction(0);
|
set_refraction(0);
|
||||||
set_refraction_roughness(0);
|
set_refraction_roughness(0);
|
||||||
set_line_width(1);
|
set_line_width(1);
|
||||||
|
|
|
@ -213,7 +213,7 @@ private:
|
||||||
StringName clearcoat_gloss;
|
StringName clearcoat_gloss;
|
||||||
StringName anisotropy;
|
StringName anisotropy;
|
||||||
StringName height_scale;
|
StringName height_scale;
|
||||||
StringName subsurface_scattering;
|
StringName subsurface_scattering_strength;
|
||||||
StringName refraction;
|
StringName refraction;
|
||||||
StringName refraction_roughness;
|
StringName refraction_roughness;
|
||||||
StringName point_size;
|
StringName point_size;
|
||||||
|
@ -247,7 +247,7 @@ private:
|
||||||
float clearcoat_gloss;
|
float clearcoat_gloss;
|
||||||
float anisotropy;
|
float anisotropy;
|
||||||
float height_scale;
|
float height_scale;
|
||||||
float subsurface_scattering;
|
float subsurface_scattering_strength;
|
||||||
float refraction;
|
float refraction;
|
||||||
float refraction_roughness;
|
float refraction_roughness;
|
||||||
float line_width;
|
float line_width;
|
||||||
|
@ -318,8 +318,8 @@ public:
|
||||||
void set_height_scale(float p_height_scale);
|
void set_height_scale(float p_height_scale);
|
||||||
float get_height_scale() const;
|
float get_height_scale() const;
|
||||||
|
|
||||||
void set_subsurface_scattering(float p_subsurface_scattering);
|
void set_subsurface_scattering_strength(float p_strength);
|
||||||
float get_subsurface_scattering() const;
|
float get_subsurface_scattering_strength() const;
|
||||||
|
|
||||||
void set_refraction(float p_refraction);
|
void set_refraction(float p_refraction);
|
||||||
float get_refraction() const;
|
float get_refraction() const;
|
||||||
|
|
|
@ -66,6 +66,7 @@ ShaderTypes::ShaderTypes()
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT_GLOSS"]=ShaderLanguage::TYPE_FLOAT;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["CLEARCOAT_GLOSS"]=ShaderLanguage::TYPE_FLOAT;
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY"]=ShaderLanguage::TYPE_FLOAT;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY"]=ShaderLanguage::TYPE_FLOAT;
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY_FLOW"]=ShaderLanguage::TYPE_VEC2;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ANISOTROPY_FLOW"]=ShaderLanguage::TYPE_VEC2;
|
||||||
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SSS_STRENGTH"]=ShaderLanguage::TYPE_FLOAT;
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["AO"]=ShaderLanguage::TYPE_FLOAT;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["AO"]=ShaderLanguage::TYPE_FLOAT;
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"]=ShaderLanguage::TYPE_VEC3;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"]=ShaderLanguage::TYPE_VEC3;
|
||||||
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"]=ShaderLanguage::TYPE_FLOAT;
|
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"]=ShaderLanguage::TYPE_FLOAT;
|
||||||
|
|
|
@ -1555,7 +1555,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance,const
|
||||||
float angle = VSG::storage->light_get_param( p_instance->base, VS::LIGHT_PARAM_SPOT_ANGLE);
|
float angle = VSG::storage->light_get_param( p_instance->base, VS::LIGHT_PARAM_SPOT_ANGLE);
|
||||||
|
|
||||||
CameraMatrix cm;
|
CameraMatrix cm;
|
||||||
cm.set_perspective( angle, 1.0, 0.01, radius );
|
cm.set_perspective( angle*2.0, 1.0, 0.01, radius );
|
||||||
|
|
||||||
|
|
||||||
Vector<Plane> planes = cm.get_projection_planes(p_instance->transform);
|
Vector<Plane> planes = cm.get_projection_planes(p_instance->transform);
|
||||||
|
|
|
@ -556,6 +556,7 @@ public:
|
||||||
virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp)=0;
|
virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp)=0;
|
||||||
|
|
||||||
virtual void environment_set_ssr(RID p_env,bool p_enable, int p_max_steps,float p_accel,float p_fade,float p_depth_tolerance,bool p_smooth,bool p_roughness)=0;
|
virtual void environment_set_ssr(RID p_env,bool p_enable, int p_max_steps,float p_accel,float p_fade,float p_depth_tolerance,bool p_smooth,bool p_roughness)=0;
|
||||||
|
|
||||||
/* SCENARIO API */
|
/* SCENARIO API */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue