Eevee: SSR: Add fullscreen raytrace.
This commit is contained in:
@@ -86,7 +86,9 @@ static struct {
|
||||
|
||||
/* Screen Space Reflection */
|
||||
struct GPUShader *ssr_raytrace_sh;
|
||||
struct GPUShader *ssr_raytrace_full_sh;
|
||||
struct GPUShader *ssr_resolve_sh;
|
||||
struct GPUShader *ssr_resolve_full_sh;
|
||||
|
||||
/* Simple Downsample */
|
||||
struct GPUShader *downsample_sh;
|
||||
@@ -197,7 +199,11 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
BLI_dynstr_free(ds_frag);
|
||||
|
||||
e_data.ssr_raytrace_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RAYTRACE\n");
|
||||
e_data.ssr_raytrace_full_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RAYTRACE\n"
|
||||
"#define FULLRES\n");
|
||||
e_data.ssr_resolve_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RESOLVE\n");
|
||||
e_data.ssr_resolve_full_sh = DRW_shader_create_fullscreen(ssr_shader_str, SHADER_DEFINES "#define STEP_RESOLVE\n"
|
||||
"#define FULLRES\n");
|
||||
|
||||
MEM_freeN(ssr_shader_str);
|
||||
|
||||
@@ -542,7 +548,10 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
/* Enable double buffering to be able to read previous frame color */
|
||||
effects->enabled_effects |= EFFECT_DOUBLE_BUFFER;
|
||||
|
||||
int tracing_res[2] = {(int)viewport_size[0] / 2, (int)viewport_size[1] / 2};
|
||||
effects->reflection_trace_full = true;
|
||||
|
||||
const int divisor = (effects->reflection_trace_full) ? 1 : 2;
|
||||
int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
|
||||
const bool record_two_hit = false;
|
||||
const bool high_qual_input = true; /* TODO dither low quality input */
|
||||
|
||||
@@ -704,8 +713,11 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
}
|
||||
|
||||
if ((effects->enabled_effects & EFFECT_SSR) != 0) {
|
||||
struct GPUShader *trace_shader = (effects->reflection_trace_full) ? e_data.ssr_raytrace_full_sh : e_data.ssr_raytrace_sh;
|
||||
struct GPUShader *resolve_shader = (effects->reflection_trace_full) ? e_data.ssr_resolve_full_sh : e_data.ssr_resolve_sh;
|
||||
|
||||
psl->ssr_raytrace = DRW_pass_create("SSR Raytrace", DRW_STATE_WRITE_COLOR);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.ssr_raytrace_sh, psl->ssr_raytrace);
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace);
|
||||
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
|
||||
@@ -715,7 +727,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
|
||||
DRW_shgroup_call_add(grp, quad, NULL);
|
||||
|
||||
psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.ssr_resolve_sh, psl->ssr_resolve);
|
||||
grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve);
|
||||
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
|
||||
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
|
||||
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
|
||||
@@ -1193,7 +1205,9 @@ void EEVEE_effects_free(void)
|
||||
{
|
||||
DRW_SHADER_FREE_SAFE(e_data.downsample_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_raytrace_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_raytrace_full_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_resolve_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.ssr_resolve_full_sh);
|
||||
|
||||
DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh);
|
||||
|
||||
|
||||
@@ -320,6 +320,7 @@ typedef struct EEVEE_EffectsInfo {
|
||||
|
||||
/* SSR */
|
||||
bool use_ssr;
|
||||
bool reflection_trace_full;
|
||||
|
||||
/* Ambient Occlusion */
|
||||
bool use_ao, use_bent_normals;
|
||||
|
||||
@@ -34,15 +34,24 @@ layout(location = 1) out vec4 pdfData;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef FULLRES
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy);
|
||||
ivec2 halfres_texel = fullres_texel;
|
||||
#else
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy) * 2;
|
||||
ivec2 halfres_texel = ivec2(gl_FragCoord.xy);
|
||||
#endif
|
||||
|
||||
float depth = texelFetch(depthBuffer, fullres_texel, 0).r;
|
||||
|
||||
/* Early out */
|
||||
if (depth == 1.0)
|
||||
discard;
|
||||
|
||||
vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(depthBuffer, 0));
|
||||
vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0));
|
||||
#ifndef FULLRES
|
||||
uvs *= 2.0;
|
||||
#endif
|
||||
|
||||
/* Using view space */
|
||||
vec3 viewPosition = get_view_space_from_depth(uvs, depth);
|
||||
@@ -75,8 +84,10 @@ void main()
|
||||
|
||||
/* Raycast over screen */
|
||||
float hit_dist = -1.0;
|
||||
/* Only raytrace if ray is above the surface normal */
|
||||
/* Note : this still fails in some cases like with normal map.
|
||||
* We should check against the geometric normal but we don't have it at this stage. */
|
||||
if (dot(R, N) > 0.0001) {
|
||||
/* Only raytrace if ray is above the surface normal */
|
||||
hit_dist = raycast(depthBuffer, viewPosition, R);
|
||||
}
|
||||
|
||||
@@ -195,8 +206,12 @@ float screen_border_mask(vec2 past_hit_co, vec3 hit)
|
||||
|
||||
void main()
|
||||
{
|
||||
ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0);
|
||||
ivec2 fullres_texel = ivec2(gl_FragCoord.xy);
|
||||
#ifdef FULLRES
|
||||
ivec2 halfres_texel = fullres_texel;
|
||||
#else
|
||||
ivec2 halfres_texel = ivec2(gl_FragCoord.xy / 2.0);
|
||||
#endif
|
||||
vec2 texture_size = vec2(textureSize(depthBuffer, 0));
|
||||
vec2 uvs = gl_FragCoord.xy / texture_size;
|
||||
vec3 rand = texelFetch(utilTex, ivec3(fullres_texel % LUT_SIZE, 2), 0).rba;
|
||||
|
||||
Reference in New Issue
Block a user