Screen space reflection effect
This commit is contained in:
parent
3f40701002
commit
a47c78aed1
@ -71,6 +71,11 @@ uniform sampler2D source;
|
||||
#endif
|
||||
varying vec2 uv2_interp;
|
||||
|
||||
|
||||
#ifdef USE_DEPTH
|
||||
uniform highp sampler2D source_depth; //texunit:1
|
||||
#endif
|
||||
|
||||
#ifdef USE_GLOW
|
||||
|
||||
uniform sampler2D glow_source;
|
||||
@ -547,5 +552,10 @@ void main() {
|
||||
|
||||
|
||||
gl_FragColor = color;
|
||||
|
||||
#ifdef USE_DEPTH
|
||||
gl_FragDepth = texture(source_depth,uv_interp).r;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
@ -1349,7 +1349,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
|
||||
|
||||
|
||||
if (storage->frame.current_rt) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
|
||||
glColorMask(1,1,1,1); //don't touch alpha
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ void RasterizerGLES3::set_current_render_target(RID p_render_target){
|
||||
|
||||
if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
|
||||
//handle pending clear request, if the framebuffer was not cleared
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
|
||||
print_line("unbind clear of: "+storage->frame.clear_request_color);
|
||||
glClearColor(
|
||||
storage->frame.clear_request_color.r,
|
||||
@ -213,7 +213,7 @@ void RasterizerGLES3::restore_render_target() {
|
||||
|
||||
ERR_FAIL_COND(storage->frame.current_rt==NULL);
|
||||
RasterizerStorageGLES3::RenderTarget * rt = storage->frame.current_rt;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,rt->fbo);
|
||||
glViewport(0,0,rt->width,rt->height);
|
||||
|
||||
}
|
||||
@ -238,7 +238,7 @@ void RasterizerGLES3::blit_render_target_to_screen(RID p_render_target,const Rec
|
||||
glDisable(GL_BLEND);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->config.system_fbo);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D,rt->front.color);
|
||||
glBindTexture(GL_TEXTURE_2D,rt->color);
|
||||
canvas->draw_generic_textured_rect(p_screen_rect,Rect2(0,0,1,-1));
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
canvas->canvas_end();
|
||||
|
@ -857,6 +857,21 @@ void RasterizerSceneGLES3::environment_set_fog(RID p_env,bool p_enable,float p_b
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::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) {
|
||||
|
||||
Environment *env=environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND(!env);
|
||||
|
||||
env->ssr_enabled=p_enable;
|
||||
env->ssr_max_steps=p_max_steps;
|
||||
env->ssr_accel=p_accel;
|
||||
env->ssr_fade=p_fade;
|
||||
env->ssr_depth_tolerance=p_depth_tolerance;
|
||||
env->ssr_smooth=p_smooth;
|
||||
env->ssr_roughness=p_roughness;
|
||||
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, bool p_enable, float p_exposure, float p_white, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale, VS::EnvironmentToneMapper p_tone_mapper){
|
||||
|
||||
}
|
||||
@ -2538,7 +2553,7 @@ void RasterizerSceneGLES3::_copy_screen() {
|
||||
void RasterizerSceneGLES3::_copy_to_front_buffer(Environment *env) {
|
||||
|
||||
//copy to front buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@ -2575,7 +2590,7 @@ void RasterizerSceneGLES3::_copy_to_front_buffer(Environment *env) {
|
||||
void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) {
|
||||
|
||||
//copy to front buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->fbo);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@ -2660,6 +2675,127 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase** p_cull_result,int p_
|
||||
}
|
||||
|
||||
|
||||
void RasterizerSceneGLES3::_render_mrts(Environment *env,const CameraMatrix &p_cam_projection) {
|
||||
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (env->ssr_enabled) {
|
||||
//blur diffuse into effect mipmaps using separatable convolution
|
||||
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
|
||||
for(int i=0;i<storage->frame.current_rt->effects.mip_maps[1].sizes.size();i++) {
|
||||
|
||||
|
||||
int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
|
||||
int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
|
||||
glViewport(0,0,vp_w,vp_h);
|
||||
//horizontal pass
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL,true);
|
||||
state.effect_blur_shader.bind();
|
||||
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));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (i==0) {
|
||||
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);
|
||||
_copy_screen();
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL,false);
|
||||
|
||||
//vertical pass
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL,true);
|
||||
state.effect_blur_shader.bind();
|
||||
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));
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
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[i+1].fbo); //next level, since mipmaps[0] starts one level bigger
|
||||
_copy_screen();
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL,false);
|
||||
}
|
||||
|
||||
|
||||
//perform SSR
|
||||
|
||||
state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::SMOOTH_ACCEL,env->ssr_accel>0 && env->ssr_smooth);
|
||||
state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS,env->ssr_accel>0 && env->ssr_roughness);
|
||||
|
||||
state.ssr_shader.bind();
|
||||
|
||||
int ssr_w = storage->frame.current_rt->effects.mip_maps[1].sizes[0].width;
|
||||
int ssr_h = storage->frame.current_rt->effects.mip_maps[1].sizes[0].height;
|
||||
|
||||
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::PIXEL_SIZE,Vector2(1.0/(ssr_w*0.5),1.0/(ssr_h*0.5)));
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::CAMERA_Z_NEAR,p_cam_projection.get_z_near());
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::CAMERA_Z_FAR,p_cam_projection.get_z_far());
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::PROJECTION,p_cam_projection);
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::INVERSE_PROJECTION,p_cam_projection.inverse());
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::VIEWPORT_SIZE,Size2(ssr_w,ssr_h));
|
||||
//state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FRAME_INDEX,int(render_pass));
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FILTER_MIPMAP_LEVELS,float(storage->frame.current_rt->effects.mip_maps[0].sizes.size()));
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::NUM_STEPS,env->ssr_max_steps);
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::ACCELERATION,env->ssr_accel);
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DEPTH_TOLERANCE,env->ssr_depth_tolerance);
|
||||
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DISTANCE_FADE,env->ssr_fade);
|
||||
|
||||
|
||||
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.normal_sr);
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->depth);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->effects.mip_maps[1].sizes[0].fbo);
|
||||
glViewport(0,0,ssr_w,ssr_h);
|
||||
|
||||
_copy_screen();
|
||||
glViewport(0,0,storage->frame.current_rt->width,storage->frame.current_rt->height);
|
||||
|
||||
}
|
||||
|
||||
|
||||
state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR,env->ssr_enabled);
|
||||
state.resolve_shader.bind();
|
||||
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);
|
||||
if (env->ssr_enabled) {
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
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->fbo);
|
||||
_copy_screen();
|
||||
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY,true);
|
||||
state.effect_blur_shader.bind();
|
||||
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD,float(0));
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D,storage->frame.current_rt->effects.mip_maps[0].color);
|
||||
|
||||
_copy_screen();
|
||||
|
||||
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY,false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_reflection_probe_cull_result,int p_reflection_probe_cull_count,RID p_environment,RID p_shadow_atlas,RID p_reflection_atlas,RID p_reflection_probe,int p_reflection_probe_pass){
|
||||
|
||||
//first of all, make a new render pass
|
||||
@ -2700,7 +2836,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
render_list.clear();
|
||||
|
||||
|
||||
bool use_mrt=false;
|
||||
bool use_mrt=true;
|
||||
|
||||
|
||||
_fill_render_list(p_cull_result,p_cull_count,false);
|
||||
@ -2712,10 +2848,11 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
|
||||
//rendering to a probe cubemap side
|
||||
ReflectionProbeInstance *probe = reflection_probe_instance_owner.getornull(p_reflection_probe);
|
||||
GLuint current_fbo;
|
||||
|
||||
|
||||
if (probe) {
|
||||
|
||||
ReflectionAtlas *ref_atlas = reflection_atlas_owner.getptr(probe->atlas);
|
||||
@ -2739,6 +2876,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
|
||||
glViewport(0,0,reflection_cubemaps[cubemap_index].size,reflection_cubemaps[cubemap_index].size);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,current_fbo);
|
||||
|
||||
} else {
|
||||
|
||||
glViewport(0,0,storage->frame.current_rt->width,storage->frame.current_rt->height);
|
||||
@ -2750,6 +2888,13 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,true);
|
||||
|
||||
|
||||
Vector<GLenum> draw_buffers;
|
||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT0);
|
||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT1);
|
||||
draw_buffers.push_back(GL_COLOR_ATTACHMENT2);
|
||||
glDrawBuffers(draw_buffers.size(),draw_buffers.ptr());
|
||||
|
||||
Color black(0,0,0,0);
|
||||
glClearBufferfv(GL_COLOR,1,black.components); // specular
|
||||
glClearBufferfv(GL_COLOR,2,black.components); // normal metal rough
|
||||
@ -2760,6 +2905,7 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -2841,6 +2987,11 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES3::USE_MULTIPLE_RENDER_TARGETS,false);
|
||||
|
||||
if (use_mrt) {
|
||||
GLenum gldb = GL_COLOR_ATTACHMENT0;
|
||||
glDrawBuffers(1,&gldb);
|
||||
}
|
||||
|
||||
if (env && env->bg_mode==VS::ENV_BG_SKYBOX) {
|
||||
|
||||
if (use_mrt) {
|
||||
@ -2859,16 +3010,17 @@ void RasterizerSceneGLES3::render_scene(const Transform& p_cam_transform,const C
|
||||
|
||||
// state.scene_shader.set_conditional( SceneShaderGLES3::USE_FOG,false);
|
||||
|
||||
|
||||
if (use_mrt) {
|
||||
_render_mrts(env,p_cam_projection);
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
|
||||
glEnable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
if (use_mrt) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.alpha_fbo);
|
||||
}
|
||||
|
||||
render_list.sort_by_depth(true);
|
||||
|
||||
if (state.directional_light_count==0) {
|
||||
@ -3812,6 +3964,10 @@ void RasterizerSceneGLES3::initialize() {
|
||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||
|
||||
#endif
|
||||
|
||||
state.resolve_shader.init();
|
||||
state.ssr_shader.init();
|
||||
state.effect_blur_shader.init();
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::iteration() {
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "rasterizer_storage_gles3.h"
|
||||
#include "drivers/gles3/shaders/scene.glsl.h"
|
||||
#include "drivers/gles3/shaders/cube_to_dp.glsl.h"
|
||||
#include "drivers/gles3/shaders/resolve.glsl.h"
|
||||
#include "drivers/gles3/shaders/screen_space_reflection.glsl.h"
|
||||
#include "drivers/gles3/shaders/effect_blur.glsl.h"
|
||||
|
||||
class RasterizerSceneGLES3 : public RasterizerScene {
|
||||
public:
|
||||
@ -45,6 +48,9 @@ public:
|
||||
|
||||
SceneShaderGLES3 scene_shader;
|
||||
CubeToDpShaderGLES3 cube_to_dp_shader;
|
||||
ResolveShaderGLES3 resolve_shader;
|
||||
ScreenSpaceReflectionShaderGLES3 ssr_shader;
|
||||
EffectBlurShaderGLES3 effect_blur_shader;
|
||||
|
||||
|
||||
struct SceneDataUBO {
|
||||
@ -289,6 +295,15 @@ public:
|
||||
|
||||
int canvas_max_layer;
|
||||
|
||||
bool ssr_enabled;
|
||||
int ssr_max_steps;
|
||||
float ssr_accel;
|
||||
float ssr_fade;
|
||||
float ssr_depth_tolerance;
|
||||
bool ssr_smooth;
|
||||
bool ssr_roughness;
|
||||
|
||||
|
||||
|
||||
Environment() {
|
||||
bg_mode=VS::ENV_BG_CLEAR_COLOR;
|
||||
@ -298,6 +313,15 @@ public:
|
||||
ambient_energy=1.0;
|
||||
ambient_skybox_contribution=0.0;
|
||||
canvas_max_layer=0;
|
||||
|
||||
ssr_enabled=false;
|
||||
ssr_max_steps=64;
|
||||
ssr_accel=0.04;
|
||||
ssr_fade=2.0;
|
||||
ssr_depth_tolerance=0.2;
|
||||
ssr_smooth=true;
|
||||
ssr_roughness=true;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@ -316,6 +340,8 @@ public:
|
||||
virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode);
|
||||
virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture);
|
||||
|
||||
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);
|
||||
|
||||
virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale,VS::EnvironmentToneMapper p_tone_mapper);
|
||||
virtual void environment_set_adjustment(RID p_env,bool p_enable,float p_brightness,float p_contrast,float p_saturation,RID p_ramp);
|
||||
|
||||
@ -551,6 +577,7 @@ public:
|
||||
|
||||
void _fill_render_list(InstanceBase** p_cull_result,int p_cull_count,bool p_shadow);
|
||||
|
||||
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
|
||||
virtual void render_scene(const Transform& p_cam_transform,const CameraMatrix& p_cam_projection,bool p_cam_ortogonal,InstanceBase** p_cull_result,int p_cull_count,RID* p_light_cull_result,int p_light_cull_count,RID* p_reflection_probe_cull_result,int p_reflection_probe_cull_count,RID p_environment,RID p_shadow_atlas,RID p_reflection_atlas,RID p_reflection_probe,int p_reflection_probe_pass);
|
||||
virtual void render_shadow(RID p_light,RID p_shadow_atlas,int p_pass,InstanceBase** p_cull_result,int p_cull_count);
|
||||
virtual bool free(RID p_rid);
|
||||
|
@ -4760,16 +4760,10 @@ void RasterizerStorageGLES3::instance_remove_dependency(RID p_base,RasterizerSce
|
||||
|
||||
void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
|
||||
|
||||
if (rt->front.fbo) {
|
||||
glDeleteFramebuffers(1,&rt->front.fbo);
|
||||
glDeleteTextures(1,&rt->front.color);
|
||||
rt->front.fbo=0;
|
||||
}
|
||||
|
||||
if (rt->back.fbo) {
|
||||
glDeleteFramebuffers(1,&rt->back.fbo);
|
||||
glDeleteTextures(1,&rt->back.color);
|
||||
rt->back.fbo=0;
|
||||
if (rt->fbo) {
|
||||
glDeleteFramebuffers(1,&rt->fbo);
|
||||
glDeleteTextures(1,&rt->color);
|
||||
rt->fbo=0;
|
||||
}
|
||||
|
||||
if (rt->buffers.fbo) {
|
||||
@ -4783,7 +4777,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
|
||||
}
|
||||
|
||||
if (rt->depth) {
|
||||
glDeleteRenderbuffers(1,&rt->depth);
|
||||
glDeleteTextures(1,&rt->depth);
|
||||
rt->depth=0;
|
||||
}
|
||||
|
||||
@ -4793,6 +4787,22 @@ 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);
|
||||
}
|
||||
|
||||
glDeleteTextures(1,&rt->effects.mip_maps[i].color);
|
||||
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);
|
||||
rt->effects.screen_space_depth=0;
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
@ -4833,21 +4843,24 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glGenFramebuffers(1, &rt->front.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->front.fbo);
|
||||
glGenFramebuffers(1, &rt->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
||||
|
||||
|
||||
glGenRenderbuffers(1, &rt->depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
|
||||
glGenTextures(1, &rt->depth);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->depth);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, rt->width, rt->height, 0,
|
||||
GL_DEPTH_COMPONENT, 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_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D, rt->depth, 0);
|
||||
|
||||
glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH24_STENCIL8, rt->width, rt->height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0 );
|
||||
|
||||
|
||||
glGenTextures(1, &rt->front.color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->front.color);
|
||||
glGenTextures(1, &rt->color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
|
||||
|
||||
@ -4855,7 +4868,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
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_ATTACHMENT0, GL_TEXTURE_2D, rt->front.color, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
|
||||
@ -4867,7 +4880,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
tex->gl_format_cache=color_format;
|
||||
tex->gl_type_cache=color_type;
|
||||
tex->gl_internal_format_cache=color_internal_format;
|
||||
tex->tex_id=rt->front.color;
|
||||
tex->tex_id=rt->color;
|
||||
tex->width=rt->width;
|
||||
tex->alloc_width=rt->width;
|
||||
tex->height=rt->height;
|
||||
@ -4881,32 +4894,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
|
||||
/* BACK FBO */
|
||||
|
||||
if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) {
|
||||
|
||||
glGenFramebuffers(1, &rt->back.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->back.fbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth );
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
|
||||
glGenTextures(1, &rt->back.color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->back.color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, 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_ATTACHMENT0, GL_TEXTURE_2D, rt->back.color, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
_render_target_clear(rt);
|
||||
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
|
||||
}
|
||||
}
|
||||
|
||||
if (config.render_arch==RENDER_ARCH_DESKTOP && !rt->flags[RENDER_TARGET_NO_3D]) {
|
||||
|
||||
|
||||
@ -4915,11 +4902,12 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
glGenFramebuffers(1, &rt->buffers.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.fbo);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D, rt->depth, 0);
|
||||
|
||||
glGenTextures(1, &rt->buffers.diffuse);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->buffers.diffuse);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, rt->width, rt->height, 0, GL_RGBA, GL_HALF_FLOAT, 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);
|
||||
@ -4958,7 +4946,9 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
glGenFramebuffers(1, &rt->buffers.alpha_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.alpha_fbo);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_TEXTURE_2D, rt->depth, 0);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->buffers.diffuse, 0);
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
@ -4969,9 +4959,80 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt){
|
||||
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
|
||||
}
|
||||
|
||||
for(int i=0;i<2;i++) {
|
||||
|
||||
ERR_FAIL_COND( rt->effects.mip_maps[i].sizes.size() );
|
||||
int w=rt->width;
|
||||
int h=rt->height;
|
||||
|
||||
|
||||
if (i>0) {
|
||||
w>>=1;
|
||||
h>>=1;
|
||||
}
|
||||
|
||||
|
||||
glGenTextures(1, &rt->effects.mip_maps[i].color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->effects.mip_maps[i].color);
|
||||
|
||||
int level=0;
|
||||
|
||||
while(true) {
|
||||
|
||||
RenderTarget::Effects::MipMaps::Size mm;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA16F, w, h, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
|
||||
mm.width=w;
|
||||
mm.height=h;
|
||||
rt->effects.mip_maps[i].sizes.push_back(mm);
|
||||
|
||||
w>>=1;
|
||||
h>>=1;
|
||||
|
||||
if (w<32 || h<32)
|
||||
break; //going less than 32 is pointless
|
||||
|
||||
level++;
|
||||
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
|
||||
|
||||
|
||||
for(int j=0;j<rt->effects.mip_maps[i].sizes.size();j++) {
|
||||
|
||||
RenderTarget::Effects::MipMaps::Size &mm=rt->effects.mip_maps[i].sizes[j];
|
||||
|
||||
glGenFramebuffers(1, &mm.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,rt->effects.mip_maps[i].color ,j);
|
||||
|
||||
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
_render_target_clear(rt);
|
||||
ERR_FAIL_COND( status != GL_FRAMEBUFFER_COMPLETE );
|
||||
}
|
||||
|
||||
|
||||
float zero[4]={1,0,1,0};
|
||||
glClearBufferfv(GL_COLOR,0,zero);
|
||||
|
||||
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, config.system_fbo);
|
||||
rt->effects.mip_maps[i].levels=level;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
//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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -877,11 +877,8 @@ public:
|
||||
|
||||
struct RenderTarget : public RID_Data {
|
||||
|
||||
struct Color {
|
||||
GLuint fbo;
|
||||
GLuint color;
|
||||
} front,back;
|
||||
|
||||
GLuint fbo;
|
||||
GLuint color;
|
||||
GLuint depth;
|
||||
|
||||
struct Buffers {
|
||||
@ -890,8 +887,35 @@ public:
|
||||
GLuint specular;
|
||||
GLuint diffuse;
|
||||
GLuint normal_sr;
|
||||
GLuint temporal;
|
||||
} buffers;
|
||||
|
||||
struct Effects {
|
||||
|
||||
struct MipMaps {
|
||||
|
||||
struct Size {
|
||||
GLuint fbo;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
Vector<Size> sizes;
|
||||
GLuint color;
|
||||
int levels;
|
||||
|
||||
MipMaps() { color=0; levels=0;}
|
||||
};
|
||||
|
||||
MipMaps mip_maps[2]; //first mipmap chain starts from full-screen
|
||||
//GLuint depth2; //depth for the second mipmap chain, in case of desiring upsampling
|
||||
|
||||
Effects() {
|
||||
|
||||
}
|
||||
|
||||
} effects;
|
||||
|
||||
int width,height;
|
||||
|
||||
bool flags[RENDER_TARGET_FLAG_MAX];
|
||||
@ -905,8 +929,7 @@ public:
|
||||
width=0;
|
||||
height=0;
|
||||
depth=0;
|
||||
front.fbo=0;
|
||||
back.fbo=0;
|
||||
fbo=0;
|
||||
buffers.fbo=0;
|
||||
buffers.alpha_fbo=0;
|
||||
used_in_frame=false;
|
||||
|
@ -393,8 +393,8 @@ ShaderGLES3::Version* ShaderGLES3::get_current_version() {
|
||||
|
||||
strings.resize(strings_base_size);
|
||||
//fragment precision is medium
|
||||
strings.push_back("precision mediump float;\n");
|
||||
strings.push_back("precision mediump int;\n");
|
||||
strings.push_back("precision highp float;\n");
|
||||
strings.push_back("precision highp int;\n");
|
||||
|
||||
#if 0
|
||||
if (cc) {
|
||||
|
@ -2,10 +2,13 @@ Import('env')
|
||||
|
||||
if env['BUILDERS'].has_key('GLES3_GLSL'):
|
||||
env.GLES3_GLSL('copy.glsl');
|
||||
env.GLES3_GLSL('resolve.glsl');
|
||||
env.GLES3_GLSL('canvas.glsl');
|
||||
env.GLES3_GLSL('canvas_shadow.glsl');
|
||||
env.GLES3_GLSL('scene.glsl');
|
||||
env.GLES3_GLSL('cubemap_filter.glsl');
|
||||
env.GLES3_GLSL('cube_to_dp.glsl');
|
||||
env.GLES3_GLSL('blend_shape.glsl');
|
||||
env.GLES3_GLSL('screen_space_reflection.glsl');
|
||||
env.GLES3_GLSL('effect_blur.glsl');
|
||||
|
||||
|
@ -50,6 +50,7 @@ float sRGB_gamma_correct(float c){
|
||||
|
||||
|
||||
uniform float stuff;
|
||||
uniform vec2 pixel_size;
|
||||
|
||||
in vec2 uv2_interp;
|
||||
|
||||
@ -81,6 +82,24 @@ void main() {
|
||||
color.a=1.0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef GAUSSIAN_HORIZONTAL
|
||||
color*=0.38774;
|
||||
color+=texture( source, uv_interp+vec2( 1.0, 0.0)*pixel_size )*0.24477;
|
||||
color+=texture( source, uv_interp+vec2( 2.0, 0.0)*pixel_size )*0.06136;
|
||||
color+=texture( source, uv_interp+vec2(-1.0, 0.0)*pixel_size )*0.24477;
|
||||
color+=texture( source, uv_interp+vec2(-2.0, 0.0)*pixel_size )*0.06136;
|
||||
#endif
|
||||
|
||||
#ifdef GAUSSIAN_VERTICAL
|
||||
color*=0.38774;
|
||||
color+=texture( source, uv_interp+vec2( 0.0, 1.0)*pixel_size )*0.24477;
|
||||
color+=texture( source, uv_interp+vec2( 0.0, 2.0)*pixel_size )*0.06136;
|
||||
color+=texture( source, uv_interp+vec2( 0.0,-1.0)*pixel_size )*0.24477;
|
||||
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136;
|
||||
#endif
|
||||
|
||||
|
||||
frag_color = color;
|
||||
}
|
||||
|
||||
|
45
drivers/gles3/shaders/resolve.glsl
Normal file
45
drivers/gles3/shaders/resolve.glsl
Normal file
@ -0,0 +1,45 @@
|
||||
[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]
|
||||
|
||||
|
||||
in vec2 uv_interp;
|
||||
uniform sampler2D source_diffuse; //texunit:0
|
||||
uniform sampler2D source_specular; //texunit:1
|
||||
|
||||
|
||||
uniform sampler2D source_ssr_ssao; //texunit:2
|
||||
|
||||
uniform float stuff;
|
||||
|
||||
in vec2 uv2_interp;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 diffuse = texture( source_diffuse, uv_interp );
|
||||
vec4 specular = texture( source_specular, uv_interp );
|
||||
|
||||
#ifdef USE_SSR
|
||||
|
||||
vec4 ssr = textureLod(source_ssr_ssao,uv_interp,0.0);
|
||||
specular.rgb = mix(specular.rgb,ssr.rgb*specular.a,ssr.a);
|
||||
#endif
|
||||
|
||||
frag_color = vec4(diffuse.rgb,1.0)+vec4(specular.rgb,1.0);
|
||||
}
|
||||
|
166
drivers/gles3/shaders/resolve.glsl.h
Normal file
166
drivers/gles3/shaders/resolve.glsl.h
Normal file
@ -0,0 +1,166 @@
|
||||
/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */
|
||||
#ifndef RESOLVE_GLSL_HGLES3_120
|
||||
#define RESOLVE_GLSL_HGLES3_120
|
||||
|
||||
|
||||
#include "drivers/gles3/shader_gles3.h"
|
||||
|
||||
|
||||
class ResolveShaderGLES3 : public ShaderGLES3 {
|
||||
|
||||
virtual String get_shader_name() const { return "ResolveShaderGLES3"; }
|
||||
public:
|
||||
|
||||
enum Conditionals {
|
||||
USE_SSR,
|
||||
};
|
||||
|
||||
enum Uniforms {
|
||||
STUFF,
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ int get_uniform(Uniforms p_uniform) const { return _get_uniform(p_uniform); }
|
||||
|
||||
_FORCE_INLINE_ void set_conditional(Conditionals p_conditional,bool p_enable) { _set_conditional(p_conditional,p_enable); }
|
||||
|
||||
#define _FU if (get_uniform(p_uniform)<0) return; ERR_FAIL_COND( get_active()!=this );
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, double p_value) { _FU glUniform1f(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int8_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int16_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, uint32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, int32_t p_value) { _FU glUniform1i(get_uniform(p_uniform),p_value); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Color& p_color) { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(get_uniform(p_uniform),1,col); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector2& p_vec2) { _FU GLfloat vec2[2]={p_vec2.x,p_vec2.y}; glUniform2fv(get_uniform(p_uniform),1,vec2); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Vector3& p_vec3) { _FU GLfloat vec3[3]={p_vec3.x,p_vec3.y,p_vec3.z}; glUniform3fv(get_uniform(p_uniform),1,vec3); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b) { _FU glUniform2f(get_uniform(p_uniform),p_a,p_b); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c) { _FU glUniform3f(get_uniform(p_uniform),p_a,p_b,p_c); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d) { _FU glUniform4f(get_uniform(p_uniform),p_a,p_b,p_c,p_d); }
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Transform& p_transform) { _FU
|
||||
|
||||
const Transform &tr = p_transform;
|
||||
|
||||
GLfloat matrix[16]={ /* build a 16x16 matrix */
|
||||
tr.basis.elements[0][0],
|
||||
tr.basis.elements[1][0],
|
||||
tr.basis.elements[2][0],
|
||||
0,
|
||||
tr.basis.elements[0][1],
|
||||
tr.basis.elements[1][1],
|
||||
tr.basis.elements[2][1],
|
||||
0,
|
||||
tr.basis.elements[0][2],
|
||||
tr.basis.elements[1][2],
|
||||
tr.basis.elements[2][2],
|
||||
0,
|
||||
tr.origin.x,
|
||||
tr.origin.y,
|
||||
tr.origin.z,
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
||||
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const Matrix32& p_transform) { _FU
|
||||
|
||||
const Matrix32 &tr = p_transform;
|
||||
|
||||
GLfloat matrix[16]={ /* build a 16x16 matrix */
|
||||
tr.elements[0][0],
|
||||
tr.elements[0][1],
|
||||
0,
|
||||
0,
|
||||
tr.elements[1][0],
|
||||
tr.elements[1][1],
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
tr.elements[2][0],
|
||||
tr.elements[2][1],
|
||||
0,
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
||||
|
||||
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix) { _FU
|
||||
|
||||
GLfloat matrix[16];
|
||||
|
||||
for (int i=0;i<4;i++) {
|
||||
for (int j=0;j<4;j++) {
|
||||
|
||||
matrix[i*4+j]=p_matrix.matrix[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
glUniformMatrix4fv(get_uniform(p_uniform),1,false,matrix);
|
||||
};
|
||||
|
||||
#undef _FU
|
||||
|
||||
|
||||
virtual void init() {
|
||||
|
||||
static const Enum *_enums=NULL;
|
||||
static const EnumValue *_enum_values=NULL;
|
||||
static const char* _conditional_strings[]={
|
||||
"#define USE_SSR\n",
|
||||
};
|
||||
|
||||
static const char* _uniform_strings[]={
|
||||
"stuff",
|
||||
};
|
||||
|
||||
static AttributePair *_attribute_pairs=NULL;
|
||||
static const Feedback* _feedbacks=NULL;
|
||||
static TexUnitPair _texunit_pairs[]={
|
||||
{"source_diffuse",0},
|
||||
{"source_specular",1},
|
||||
{"source_ssr_ssao",2},
|
||||
};
|
||||
|
||||
static UBOPair *_ubo_pairs=NULL;
|
||||
static const char _vertex_code[]={
|
||||
10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,61,48,41,32,105,110,32,104,105,103,104,112,32,118,101,99,52,32,118,101,114,116,101,120,95,97,116,116,114,105,98,59,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,61,52,41,32,105,110,32,118,101,99,50,32,117,118,95,105,110,59,10,10,111,117,116,32,118,101,99,50,32,117,118,95,105,110,116,101,114,112,59,10,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,10,9,117,118,95,105,110,116,101,114,112,32,61,32,117,118,95,105,110,59,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,114,116,101,120,95,97,116,116,114,105,98,59,10,125,10,10, 0};
|
||||
|
||||
static const int _vertex_code_start=1;
|
||||
static const char _fragment_code[]={
|
||||
10,10,105,110,32,118,101,99,50,32,117,118,95,105,110,116,101,114,112,59,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,115,111,117,114,99,101,95,100,105,102,102,117,115,101,59,32,47,47,116,101,120,117,110,105,116,58,48,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,115,111,117,114,99,101,95,115,112,101,99,117,108,97,114,59,32,47,47,116,101,120,117,110,105,116,58,49,10,10,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,115,111,117,114,99,101,95,115,115,114,95,115,115,97,111,59,32,47,47,116,101,120,117,110,105,116,58,50,10,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,115,116,117,102,102,59,10,10,105,110,32,118,101,99,50,32,117,118,50,95,105,110,116,101,114,112,59,10,10,108,97,121,111,117,116,40,108,111,99,97,116,105,111,110,32,61,32,48,41,32,111,117,116,32,118,101,99,52,32,102,114,97,103,95,99,111,108,111,114,59,10,10,118,111,105,100,32,109,97,105,110,40,41,32,123,10,10,9,118,101,99,52,32,100,105,102,102,117,115,101,32,61,32,116,101,120,116,117,114,101,40,32,115,111,117,114,99,101,95,100,105,102,102,117,115,101,44,32,32,117,118,95,105,110,116,101,114,112,32,41,59,10,9,118,101,99,52,32,115,112,101,99,117,108,97,114,32,61,32,116,101,120,116,117,114,101,40,32,115,111,117,114,99,101,95,115,112,101,99,117,108,97,114,44,32,32,117,118,95,105,110,116,101,114,112,32,41,59,10,10,35,105,102,100,101,102,32,85,83,69,95,83,83,82,10,10,9,118,101,99,52,32,115,115,114,32,61,32,116,101,120,116,117,114,101,76,111,100,40,115,111,117,114,99,101,95,115,115,114,95,115,115,97,111,44,117,118,95,105,110,116,101,114,112,44,48,46,48,41,59,10,9,115,112,101,99,117,108,97,114,46,114,103,98,32,61,32,109,105,120,40,115,112,101,99,117,108,97,114,46,114,103,98,44,115,115,114,46,114,103,98,42,115,112,101,99,117,108,97,114,46,97,44,115,115,114,46,97,41,59,10,35,101,110,100,105,102,10,10,9,102,114,97,103,95,99,111,108,111,114,32,61,32,118,101,99,52,40,100,105,102,102,117,115,101,46,114,103,98,44,49,46,48,41,43,118,101,99,52,40,115,112,101,99,117,108,97,114,46,114,103,98,44,49,46,48,41,59,10,125,10,10, 0};
|
||||
|
||||
static const int _fragment_code_start=16;
|
||||
setup(_conditional_strings,1,_uniform_strings,1,_attribute_pairs,0, _texunit_pairs,3,_ubo_pairs,0,_feedbacks,0,_vertex_code,_fragment_code,_vertex_code_start,_fragment_code_start);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1189,8 +1189,10 @@ LIGHT_SHADER_CODE
|
||||
#endif //ENABLE_AO
|
||||
|
||||
diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale);
|
||||
specular_buffer=vec4(specular_light,0.0);
|
||||
normal_mr_buffer=vec4(normal.x,normal.y,max(specular.r,max(specular.g,specular.b)),roughness);
|
||||
specular_buffer=vec4(specular_light,max(specular.r,max(specular.g,specular.b)));
|
||||
|
||||
|
||||
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
|
||||
|
||||
#else
|
||||
|
||||
|
183
drivers/gles3/shaders/screen_space.glsl.h
Normal file
183
drivers/gles3/shaders/screen_space.glsl.h
Normal file
File diff suppressed because one or more lines are too long
350
drivers/gles3/shaders/screen_space_reflection.glsl
Normal file
350
drivers/gles3/shaders/screen_space_reflection.glsl
Normal file
@ -0,0 +1,350 @@
|
||||
[vertex]
|
||||
|
||||
|
||||
layout(location=0) in highp vec4 vertex_attrib;
|
||||
layout(location=4) in vec2 uv_in;
|
||||
|
||||
out vec2 uv_interp;
|
||||
out vec2 pos_interp;
|
||||
|
||||
void main() {
|
||||
|
||||
uv_interp = uv_in;
|
||||
gl_Position = vertex_attrib;
|
||||
pos_interp.xy=gl_Position.xy;
|
||||
}
|
||||
|
||||
[fragment]
|
||||
|
||||
|
||||
in vec2 uv_interp;
|
||||
in vec2 pos_interp;
|
||||
|
||||
uniform sampler2D source_diffuse; //texunit:0
|
||||
uniform sampler2D source_normal_roughness; //texunit:1
|
||||
uniform sampler2D source_depth; //texunit:2
|
||||
uniform sampler2D source_diffuse_mipmaps; //texunit:3
|
||||
|
||||
uniform float camera_z_near;
|
||||
uniform float camera_z_far;
|
||||
|
||||
uniform vec2 viewport_size;
|
||||
uniform vec2 pixel_size;
|
||||
|
||||
uniform float filter_mipmap_levels;
|
||||
|
||||
uniform mat4 inverse_projection;
|
||||
uniform mat4 projection;
|
||||
|
||||
uniform int num_steps;
|
||||
uniform float depth_tolerance;
|
||||
uniform float distance_fade;
|
||||
uniform float acceleration;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
|
||||
|
||||
vec2 view_to_screen(vec3 view_pos,out float w) {
|
||||
vec4 projected = projection * vec4(view_pos, 1.0);
|
||||
projected.xyz /= projected.w;
|
||||
projected.xy = projected.xy * 0.5 + 0.5;
|
||||
w=projected.w;
|
||||
return projected.xy;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define M_PI 3.14159265359
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
////
|
||||
|
||||
vec4 diffuse = texture( source_diffuse, uv_interp );
|
||||
vec4 normal_roughness = texture( source_normal_roughness, uv_interp);
|
||||
|
||||
vec3 normal;
|
||||
|
||||
normal = normal_roughness.xyz*2.0-1.0;
|
||||
|
||||
float roughness = normal_roughness.w;
|
||||
|
||||
float depth_tex = texture(source_depth,uv_interp).r;
|
||||
|
||||
vec4 world_pos = inverse_projection * vec4( uv_interp*2.0-1.0, depth_tex*2.0-1.0, 1.0 );
|
||||
vec3 vertex = world_pos.xyz/world_pos.w;
|
||||
|
||||
vec3 view_dir = normalize(vertex);
|
||||
vec3 ray_dir = normalize(reflect(view_dir, normal));
|
||||
|
||||
if (dot(ray_dir,normal)<0.001) {
|
||||
frag_color=vec4(0.0);
|
||||
return;
|
||||
}
|
||||
//ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
|
||||
|
||||
//ray_dir = normalize(vec3(1,1,-1));
|
||||
|
||||
|
||||
////////////////
|
||||
|
||||
|
||||
//make ray length and clip it against the near plane (don't want to trace beyond visible)
|
||||
float ray_len = (vertex.z + ray_dir.z * camera_z_far) > -camera_z_near ? (-camera_z_near - vertex.z) / ray_dir.z : camera_z_far;
|
||||
vec3 ray_end = vertex + ray_dir*ray_len;
|
||||
|
||||
float w_begin;
|
||||
vec2 vp_line_begin = view_to_screen(vertex,w_begin);
|
||||
float w_end;
|
||||
vec2 vp_line_end = view_to_screen( ray_end, w_end);
|
||||
vec2 vp_line_dir = vp_line_end-vp_line_begin;
|
||||
|
||||
//we need to interpolate w along the ray, to generate perspective correct reflections
|
||||
|
||||
w_begin = 1.0/w_begin;
|
||||
w_end = 1.0/w_end;
|
||||
|
||||
|
||||
float z_begin = vertex.z*w_begin;
|
||||
float z_end = ray_end.z*w_end;
|
||||
|
||||
vec2 line_begin = vp_line_begin/pixel_size;
|
||||
vec2 line_dir = vp_line_dir/pixel_size;
|
||||
float z_dir = z_end - z_begin;
|
||||
float w_dir = w_end - w_begin;
|
||||
|
||||
|
||||
// clip the line to the viewport edges
|
||||
|
||||
float scale_max_x = min(1, 0.99 * (1.0 - vp_line_begin.x) / max(1e-5, vp_line_dir.x));
|
||||
float scale_max_y = min(1, 0.99 * (1.0 - vp_line_begin.y) / max(1e-5, vp_line_dir.y));
|
||||
float scale_min_x = min(1, 0.99 * vp_line_begin.x / max(1e-5, -vp_line_dir.x));
|
||||
float scale_min_y = min(1, 0.99 * vp_line_begin.y / max(1e-5, -vp_line_dir.y));
|
||||
float line_clip = min(scale_max_x, scale_max_y) * min(scale_min_x, scale_min_y);
|
||||
line_dir *= line_clip;
|
||||
z_dir *= line_clip;
|
||||
w_dir *=line_clip;
|
||||
|
||||
//clip z and w advance to line advance
|
||||
vec2 line_advance = normalize(line_dir); //down to pixel
|
||||
float step_size = length(line_advance)/length(line_dir);
|
||||
float z_advance = z_dir*step_size; // adapt z advance to line advance
|
||||
float w_advance = w_dir*step_size; // adapt w advance to line advance
|
||||
|
||||
//make line advance faster if direction is closer to pixel edges (this avoids sampling the same pixel twice)
|
||||
float advance_angle_adj = 1.0/max(abs(line_advance.x),abs(line_advance.y));
|
||||
line_advance*=advance_angle_adj; // adapt z advance to line advance
|
||||
z_advance*=advance_angle_adj;
|
||||
w_advance*=advance_angle_adj;
|
||||
|
||||
vec2 pos = line_begin;
|
||||
float z = z_begin;
|
||||
float w = w_begin;
|
||||
float z_from=z/w;
|
||||
float z_to=z_from;
|
||||
float depth;
|
||||
vec2 prev_pos=pos;
|
||||
|
||||
bool found=false;
|
||||
|
||||
//if acceleration > 0, distance between pixels gets larger each step. This allows covering a larger area
|
||||
float accel=1.0+acceleration;
|
||||
float steps_taken=0;
|
||||
|
||||
for(float i=0;i<num_steps;i++) {
|
||||
|
||||
pos+=line_advance;
|
||||
z+=z_advance;
|
||||
w+=w_advance;
|
||||
|
||||
//convert to linear depth
|
||||
depth = texture(source_depth, pos*pixel_size).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;
|
||||
|
||||
z_from = z_to;
|
||||
z_to = z/w;
|
||||
|
||||
if (depth>z_to) {
|
||||
//if depth was surpassed
|
||||
if (depth<=max(z_to,z_from)+depth_tolerance) {
|
||||
//check the depth tolerance
|
||||
found=true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
steps_taken+=1.0;
|
||||
prev_pos=pos;
|
||||
z_advance*=accel;
|
||||
w_advance*=accel;
|
||||
line_advance*=accel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (found) {
|
||||
|
||||
float margin_blend=1.0;
|
||||
|
||||
|
||||
vec2 margin = vec2((viewport_size.x+viewport_size.y)*0.5*0.05); //make a uniform margin
|
||||
if (any(bvec4(lessThan(pos,-margin),greaterThan(pos,viewport_size+margin)))) {
|
||||
//clip outside screen + margin
|
||||
frag_color=vec4(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
//blend fading out towards external margin
|
||||
vec2 margin_grad = mix(pos-viewport_size,-pos,lessThan(pos,vec2(0.0)));
|
||||
margin_blend = 1.0-smoothstep(0.0,margin.x,max(margin_grad.x,margin_grad.y));
|
||||
//margin_blend=1.0;
|
||||
|
||||
}
|
||||
|
||||
vec2 final_pos;
|
||||
float grad;
|
||||
|
||||
#ifdef SMOOTH_ACCEL
|
||||
//if the distance between point and prev point is >1, then take some samples in the middle for smoothing out the image
|
||||
vec2 blend_dir = pos - prev_pos;
|
||||
float steps = min(8.0,length(blend_dir));
|
||||
if (steps>2.0) {
|
||||
vec2 blend_step = blend_dir/steps;
|
||||
float blend_z = (z_to-z_from)/steps;
|
||||
vec2 new_pos;
|
||||
float subgrad=0.0;
|
||||
for(float i=0.0;i<steps;i++) {
|
||||
|
||||
new_pos = (prev_pos+blend_step*i);
|
||||
float z = z_from+blend_z*i;
|
||||
|
||||
depth = texture(source_depth, new_pos*pixel_size).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;
|
||||
|
||||
subgrad=i/steps;
|
||||
if (depth>z)
|
||||
break;
|
||||
}
|
||||
|
||||
final_pos = new_pos;
|
||||
grad=(steps_taken+subgrad)/num_steps;
|
||||
|
||||
} else {
|
||||
#endif
|
||||
grad=steps_taken/num_steps;
|
||||
final_pos=pos;
|
||||
#ifdef SMOOTH_ACCEL
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef REFLECT_ROUGHNESS
|
||||
|
||||
|
||||
vec4 final_color;
|
||||
//if roughness is enabled, do screen space cone tracing
|
||||
if (roughness > 0.001) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//use a blurred version (in consecutive mipmaps) of the screen to simulate roughness
|
||||
|
||||
float gloss = 1.0-roughness;
|
||||
float cone_angle = roughness * M_PI * 0.5;
|
||||
vec2 cone_dir = final_pos - line_begin;
|
||||
float cone_len = length(cone_dir);
|
||||
cone_dir = normalize(cone_dir); //will be used normalized from now on
|
||||
float max_mipmap = filter_mipmap_levels -1;
|
||||
float gloss_mult=gloss;
|
||||
|
||||
float rem_alpha=1.0;
|
||||
final_color = vec4(0.0);
|
||||
|
||||
for(int i=0;i<7;i++) {
|
||||
|
||||
float op_len = 2.0 * tan(cone_angle) * cone_len; //oposite side of iso triangle
|
||||
float radius;
|
||||
{
|
||||
//fit to sphere inside cone (sphere ends at end of cone), something like this:
|
||||
// ___
|
||||
// \O/
|
||||
// V
|
||||
//
|
||||
// as it avoids bleeding from beyond the reflection as much as possible. As a plus
|
||||
// it also makes the rough reflection more elongated.
|
||||
float a = op_len;
|
||||
float h = cone_len;
|
||||
float a2 = a * a;
|
||||
float fh2 = 4.0f * h * h;
|
||||
radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
|
||||
}
|
||||
|
||||
//find the place where screen must be sampled
|
||||
vec2 sample_pos = ( line_begin + cone_dir * (cone_len - radius) ) * pixel_size;
|
||||
//radius is in pixels, so it's natural that log2(radius) maps to the right mipmap for the amount of pixels
|
||||
float mipmap = clamp( log2( radius ), 0.0, max_mipmap );
|
||||
|
||||
//mipmap = max(mipmap-1.0,0.0);
|
||||
//do sampling
|
||||
|
||||
vec4 sample_color;
|
||||
{
|
||||
sample_color = textureLod(source_diffuse_mipmaps,sample_pos,max(1.0,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
|
||||
sample_color.rgb*=gloss_mult;
|
||||
sample_color.a=gloss_mult;
|
||||
|
||||
rem_alpha -= sample_color.a;
|
||||
if(rem_alpha < 0.0) {
|
||||
sample_color.rgb *= (1.0 - abs(rem_alpha));
|
||||
}
|
||||
|
||||
final_color+=sample_color;
|
||||
|
||||
if (final_color.a>=0.95) {
|
||||
// This code of accumulating gloss and aborting on near one
|
||||
// makes sense when you think of cone tracing.
|
||||
// Think of it as if roughness was 0, then we could abort on the first
|
||||
// iteration. For lesser roughness values, we need more iterations, but
|
||||
// each needs to have less influence given the sphere is smaller
|
||||
break;
|
||||
}
|
||||
|
||||
cone_len-=radius*2.0; //go to next (smaller) circle.
|
||||
|
||||
gloss_mult*=gloss;
|
||||
|
||||
|
||||
}
|
||||
} else {
|
||||
final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0);
|
||||
}
|
||||
|
||||
frag_color = vec4(final_color.rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
|
||||
|
||||
#else
|
||||
frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
frag_color = vec4(0.0,0.0,0.0,0.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -300,6 +300,84 @@ void Environment::_validate_property(PropertyInfo& property) const {
|
||||
|
||||
}
|
||||
|
||||
void Environment::set_ssr_enabled(bool p_enable) {
|
||||
|
||||
ssr_enabled=p_enable;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
}
|
||||
|
||||
bool Environment::is_ssr_enabled() const{
|
||||
|
||||
return ssr_enabled;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_max_steps(int p_steps){
|
||||
|
||||
ssr_max_steps=p_steps;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
int Environment::get_ssr_max_steps() const {
|
||||
|
||||
return ssr_max_steps;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_accel(float p_accel) {
|
||||
|
||||
ssr_accel=p_accel;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
float Environment::get_ssr_accel() const {
|
||||
|
||||
return ssr_accel;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_fade(float p_fade) {
|
||||
|
||||
ssr_fade=p_fade;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
float Environment::get_ssr_fade() const {
|
||||
|
||||
return ssr_fade;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) {
|
||||
|
||||
ssr_depth_tolerance=p_depth_tolerance;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
float Environment::get_ssr_depth_tolerance() const {
|
||||
|
||||
return ssr_depth_tolerance;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_smooth(bool p_enable) {
|
||||
|
||||
ssr_smooth=p_enable;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
bool Environment::is_ssr_smooth() const {
|
||||
|
||||
return ssr_smooth;
|
||||
}
|
||||
|
||||
void Environment::set_ssr_rough(bool p_enable) {
|
||||
|
||||
ssr_roughness=p_enable;
|
||||
VS::get_singleton()->environment_set_ssr(environment,ssr_enabled,ssr_max_steps,ssr_accel,ssr_fade,ssr_depth_tolerance,ssr_smooth,ssr_roughness);
|
||||
|
||||
}
|
||||
bool Environment::is_ssr_rough() const {
|
||||
|
||||
return ssr_roughness;
|
||||
}
|
||||
|
||||
|
||||
void Environment::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_background","mode"),&Environment::set_background);
|
||||
@ -334,6 +412,37 @@ void Environment::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/energy",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_ambient_light_energy"),_SCS("get_ambient_light_energy") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ambient_light/skybox_contribution",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_ambient_light_skybox_contribution"),_SCS("get_ambient_light_skybox_contribution") );
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_enabled","enabled"),&Environment::set_ssr_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_ssr_enabled"),&Environment::is_ssr_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_max_steps","max_steps"),&Environment::set_ssr_max_steps);
|
||||
ObjectTypeDB::bind_method(_MD("get_ssr_max_steps"),&Environment::get_ssr_max_steps);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_accel","accel"),&Environment::set_ssr_accel);
|
||||
ObjectTypeDB::bind_method(_MD("get_ssr_accel"),&Environment::get_ssr_accel);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_fade","fade"),&Environment::set_ssr_fade);
|
||||
ObjectTypeDB::bind_method(_MD("get_ssr_fade"),&Environment::get_ssr_fade);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_depth_tolerance","depth_tolerance"),&Environment::set_ssr_depth_tolerance);
|
||||
ObjectTypeDB::bind_method(_MD("get_ssr_depth_tolerance"),&Environment::get_ssr_depth_tolerance);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_smooth","smooth"),&Environment::set_ssr_smooth);
|
||||
ObjectTypeDB::bind_method(_MD("is_ssr_smooth"),&Environment::is_ssr_smooth);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_ssr_rough","rough"),&Environment::set_ssr_rough);
|
||||
ObjectTypeDB::bind_method(_MD("is_ssr_rough"),&Environment::is_ssr_rough);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/enable"),_SCS("set_ssr_enabled"),_SCS("is_ssr_enabled") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"ss_reflections/max_steps",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_ssr_max_steps"),_SCS("get_ssr_max_steps") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/accel",PROPERTY_HINT_RANGE,"0,4,0.01"),_SCS("set_ssr_accel"),_SCS("get_ssr_accel") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/fade",PROPERTY_HINT_EXP_EASING),_SCS("set_ssr_fade"),_SCS("get_ssr_fade") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"ss_reflections/depth_tolerance",PROPERTY_HINT_RANGE,"0.1,128,0.1"),_SCS("set_ssr_depth_tolerance"),_SCS("get_ssr_depth_tolerance") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/accel_smooth"),_SCS("set_ssr_smooth"),_SCS("is_ssr_smooth") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"ss_reflections/roughness"),_SCS("set_ssr_rough"),_SCS("is_ssr_rough") );
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_tonemapper","mode"),&Environment::set_tonemapper);
|
||||
ObjectTypeDB::bind_method(_MD("get_tonemapper"),&Environment::get_tonemapper);
|
||||
|
||||
@ -358,6 +467,9 @@ void Environment::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_tonemap_auto_exposure_scale","exposure_scale"),&Environment::set_tonemap_auto_exposure_scale);
|
||||
ObjectTypeDB::bind_method(_MD("get_tonemap_auto_exposure_scale"),&Environment::get_tonemap_auto_exposure_scale);
|
||||
|
||||
|
||||
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT,"tonemap/mode",PROPERTY_HINT_ENUM,"Linear,Log,Reindhart,Filmic,Aces"),_SCS("set_tonemapper"),_SCS("get_tonemapper") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/exposure",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_exposure"),_SCS("get_tonemap_exposure") );
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL,"tonemap/white",PROPERTY_HINT_RANGE,"0,16,0.01"),_SCS("set_tonemap_white"),_SCS("get_tonemap_white") );
|
||||
@ -441,6 +553,14 @@ Environment::Environment() {
|
||||
|
||||
environment = VS::get_singleton()->environment_create();
|
||||
|
||||
ssr_enabled=false;
|
||||
ssr_max_steps=64;
|
||||
ssr_accel=0.04;
|
||||
ssr_fade=2.0;
|
||||
ssr_depth_tolerance=0.2;
|
||||
ssr_smooth=true;
|
||||
ssr_roughness=true;
|
||||
|
||||
}
|
||||
|
||||
Environment::~Environment() {
|
||||
|
@ -94,6 +94,14 @@ private:
|
||||
float adjustment_brightness;
|
||||
Ref<Texture> adjustment_color_correction;
|
||||
|
||||
bool ssr_enabled;
|
||||
int ssr_max_steps;
|
||||
float ssr_accel;
|
||||
float ssr_fade;
|
||||
float ssr_depth_tolerance;
|
||||
bool ssr_smooth;
|
||||
bool ssr_roughness;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
@ -162,6 +170,27 @@ public:
|
||||
void set_adjustment_color_correction(const Ref<Texture>& p_ramp);
|
||||
Ref<Texture> get_adjustment_color_correction() const;
|
||||
|
||||
void set_ssr_enabled(bool p_enable);
|
||||
bool is_ssr_enabled() const;
|
||||
|
||||
void set_ssr_max_steps(int p_steps);
|
||||
int get_ssr_max_steps() const;
|
||||
|
||||
void set_ssr_accel(float p_accel);
|
||||
float get_ssr_accel() const;
|
||||
|
||||
void set_ssr_fade(float p_fade);
|
||||
float get_ssr_fade() const;
|
||||
|
||||
void set_ssr_depth_tolerance(float p_depth_tolerance);
|
||||
float get_ssr_depth_tolerance() const;
|
||||
|
||||
void set_ssr_smooth(bool p_enable);
|
||||
bool is_ssr_smooth() const;
|
||||
|
||||
void set_ssr_rough(bool p_enable);
|
||||
bool is_ssr_rough() const;
|
||||
|
||||
|
||||
virtual RID get_rid() const;
|
||||
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
virtual void environment_set_glow(RID p_env,bool p_enable,int p_radius,float p_intensity,float p_strength,float p_bloom_treshold,VS::EnvironmentGlowBlendMode p_blend_mode)=0;
|
||||
virtual void environment_set_fog(RID p_env,bool p_enable,float p_begin,float p_end,RID p_gradient_texture)=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_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale,VS::EnvironmentToneMapper p_tone_mapper)=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;
|
||||
|
||||
|
@ -875,6 +875,7 @@ public:
|
||||
BIND2(environment_set_bg_energy,RID,float )
|
||||
BIND2(environment_set_canvas_max_layer,RID,int )
|
||||
BIND4(environment_set_ambient_light,RID,const Color& ,float,float )
|
||||
BIND8(environment_set_ssr,RID,bool,int,float,float,float,bool,bool )
|
||||
|
||||
BIND7(environment_set_glow,RID,bool ,int ,float ,float ,float ,EnvironmentGlowBlendMode )
|
||||
BIND5(environment_set_fog,RID,bool ,float ,float ,RID )
|
||||
|
@ -555,7 +555,7 @@ public:
|
||||
virtual void environment_set_tonemap(RID p_env,bool p_enable,float p_exposure,float p_white,float p_min_luminance,float p_max_luminance,float p_auto_exp_speed,float p_auto_exp_scale,EnvironmentToneMapper p_tone_mapper)=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;
|
||||
/* SCENARIO API */
|
||||
|
||||
|
||||
|
@ -463,7 +463,7 @@ Transform Collada::_read_transform(XMLParser& parser) {
|
||||
if (parser.is_empty())
|
||||
return Transform();
|
||||
|
||||
Vector<float> array;
|
||||
Vector<String> array;
|
||||
while(parser.read()==OK) {
|
||||
// TODO: check for comments inside the element
|
||||
// and ignore them.
|
||||
@ -471,7 +471,7 @@ Transform Collada::_read_transform(XMLParser& parser) {
|
||||
if (parser.get_node_type() == XMLParser::NODE_TEXT) {
|
||||
// parse float data
|
||||
String str = parser.get_node_data();
|
||||
array=str.split_floats(" ",false);
|
||||
array=str.split_spaces();
|
||||
}
|
||||
else
|
||||
if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
|
||||
@ -479,7 +479,13 @@ Transform Collada::_read_transform(XMLParser& parser) {
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(array.size()!=16,Transform());
|
||||
return _read_transform_from_array(array);
|
||||
Vector<float> farr;
|
||||
farr.resize(16);
|
||||
for(int i=0;i<16;i++) {
|
||||
farr[i]=array[i].to_double();
|
||||
}
|
||||
|
||||
return _read_transform_from_array(farr);
|
||||
}
|
||||
|
||||
String Collada::_read_empty_draw_type(XMLParser& parser) {
|
||||
|
Loading…
Reference in New Issue
Block a user