diff options
author | Clément Fukhaut <turjuque@gmail.com> | 2016-05-31 19:08:18 +0300 |
---|---|---|
committer | Clément Fukhaut <turjuque@gmail.com> | 2016-05-31 19:08:18 +0300 |
commit | d7d0166386b323756d7751816cdbc6e26224a7cc (patch) | |
tree | 5a6236a986a26c2c49febd6ee99d10f7c973529b /source/blender/gpu | |
parent | 6ebbef4724dd7d6f09677d5cd871042a44f8008c (diff) |
-Fixed SSR : Using depth buffer for increased precision but using another slot
-Fixed some typos
Diffstat (limited to 'source/blender/gpu')
6 files changed, 54 insertions, 103 deletions
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index d4c296ebd2f..f8f78566ea2 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -448,9 +448,9 @@ static void codegen_set_unique_ids(ListBase *nodes, bool reserve_texid) GPUNode *node; GPUInput *input; GPUOutput *output; - /* XXX tex slot (texid) 0-9 are pbr textures */ + /* XXX tex slot (texid) 0-10 are pbr textures */ /* TODO : these should reserved on demand not in bulk */ - int id = 1, texid = (reserve_texid) ? 9 : 0; + int id = 1, texid = (reserve_texid) ? 10 : 0; bindhash = BLI_ghash_ptr_new("codegen_set_unique_ids1 gh"); definehash = BLI_ghash_ptr_new("codegen_set_unique_ids2 gh"); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9a30aafef41..6d330681c17 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -145,12 +145,14 @@ struct GPUMaterial { /* Screen space effects (SSR, SSAO...) */ int scenebufloc; + int depthbufloc; int backfacebufloc; int ssaoparamsloc; int clipinfoloc; int ssrparamsloc; int pixelprojmatloc; GPUTexture *bindedscenebuffer; + GPUTexture *bindeddepthbuffer; GPUTexture *bindedbackfacebuffer; ListBase lamps; @@ -361,6 +363,7 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam material->probecoloc = GPU_shader_get_uniform(shader, "unfprobepos"); material->planarvecloc = GPU_shader_get_uniform(shader, "unfplanarvec"); material->scenebufloc = GPU_shader_get_uniform(shader, "unfscenebuf"); + material->depthbufloc = GPU_shader_get_uniform(shader, "unfdepthbuf"); material->backfacebufloc = GPU_shader_get_uniform(shader, "unfbackfacebuf"); material->ssrparamsloc = GPU_shader_get_uniform(shader, "unfssrparam"); material->pixelprojmatloc = GPU_shader_get_uniform(shader, "unfpixelprojmat"); @@ -502,6 +505,7 @@ void GPU_material_bind( material->bindedrefrprobe = NULL; material->bindedhammersley = NULL; material->bindedscenebuffer = NULL; + material->bindeddepthbuffer = NULL; material->bindedbackfacebuffer = NULL; material->bindedjitter = NULL; material->bindedltcmat = NULL; @@ -661,6 +665,11 @@ void GPU_material_bind_uniforms_pbr(GPUMaterial *material, GPUProbe *probe, GPUP GPU_texture_bind(material->bindedscenebuffer, 7); GPU_shader_uniform_texture(shader, material->scenebufloc, material->bindedscenebuffer); + /* Depth Buffer */ + material->bindeddepthbuffer = pbr->scene->depth; + GPU_texture_bind(material->bindeddepthbuffer, 8); + GPU_shader_uniform_texture(shader, material->depthbufloc, material->bindeddepthbuffer); + /* Pixel proj matrix */ GPU_shader_uniform_vector(shader, material->pixelprojmatloc, 16, 1, (float *)pbr->scene->pixelprojmat); @@ -674,7 +683,7 @@ void GPU_material_bind_uniforms_pbr(GPUMaterial *material, GPUProbe *probe, GPUP if (pbr_settings->pbr_flag & GPU_PBR_FLAG_BACKFACE) { /* Backface Buffer */ material->bindedbackfacebuffer = pbr->backface->tex; - GPU_texture_bind(material->bindedbackfacebuffer, 8); + GPU_texture_bind(material->bindedbackfacebuffer, 9); GPU_shader_uniform_texture(shader, material->backfacebufloc, material->bindedbackfacebuffer); } } @@ -717,6 +726,8 @@ void GPU_material_unbind(GPUMaterial *material) GPU_texture_unbind(material->bindedrefrprobe); if (material->bindedscenebuffer) GPU_texture_unbind(material->bindedscenebuffer); + if (material->bindeddepthbuffer) + GPU_texture_unbind(material->bindeddepthbuffer); if (material->bindedbackfacebuffer) GPU_texture_unbind(material->bindedbackfacebuffer); if (material->bindedhammersley) @@ -2611,7 +2622,7 @@ static const char *brdf_env_sampling_function(GPUBrdfType brdftype) else if (brdftype == GPU_BRDF_TOON_DIFFUSE) return "env_sampling_toon_diffuse"; else if (brdftype == GPU_BRDF_TOON_GLOSSY) - return "env_sampling_toon_diffuse"; + return "env_sampling_toon_glossy"; else if (brdftype == GPU_BRDF_AMBIENT_OCCLUSION) return "env_sampling_ambient_occlusion"; else /* (brdftype == GPU_BRDF_DIFFUSE) */ diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl index 53add6ba829..8041bb14a6a 100644 --- a/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl @@ -23,23 +23,6 @@ vec3 sample_hemisphere(float nsample, float invsamplenbr, vec3 N, vec3 T, vec3 B return from_tangent_to_world(Ht, N, T, B); } - -vec3 position_from_depth(vec2 uv, float depth) -{ - vec3 pos; - float homcoord = gl_ProjectionMatrix[2][3] * depth + gl_ProjectionMatrix[3][3]; - pos.x = gl_ProjectionMatrixInverse[0][0] * (uv.x * 2.0 - 1.0) * homcoord; - pos.y = gl_ProjectionMatrixInverse[1][1] * (uv.y * 2.0 - 1.0) * homcoord; - pos.z = depth; - return pos; -} - -vec2 uv_from_position(vec3 position) -{ - vec4 projvec = gl_ProjectionMatrix * vec4(position, 1.0); - return (projvec.xy / projvec.w) * 0.5 + 0.5; -} - #ifdef USE_SSAO #if 0 /* Cheap */ @@ -68,7 +51,7 @@ float ssao(vec3 viewpos, vec3 viewnor, out float result) if (uvsample.x > 1.0 || uvsample.x < 0.0 || uvsample.y > 1.0 || uvsample.y < 0.0) continue; - float sampledepth = texture2D(unfscenebuf, uvsample).a; + float sampledepth = frontface_depth(ivec2(uvsample * unfclip.zw)); /* Background Case */ if (sampledepth == 1.0) diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl index 53c00e90ac0..7976429b3a4 100644 --- a/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_toon.glsl @@ -269,5 +269,5 @@ void env_sampling_toon_glossy( } } - result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, a2); + result = out_radiance.rgb * unfbsdfsamples.y * specular_occlusion(NV, ao_factor, roughness); } diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl index f4b47a2a297..a4f1725bbf7 100644 --- a/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_transparent.glsl @@ -20,10 +20,10 @@ vec3 sample_transparent() /* -------- Image Based Lighting --------- */ void env_sampling_transparent( - float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat, - vec3 N, vec3 T, float roughness, float ior, float sigma, - float toon_size, float toon_smooth, float anisotropy, float aniso_rotation, - out vec3 result) + float pbr, vec3 viewpos, mat4 invviewmat, mat4 viewmat, + vec3 N, vec3 T, float roughness, float ior, float sigma, + float toon_size, float toon_smooth, float anisotropy, float aniso_rotation, + float ao_factor, out vec3 result) { vector_prepass(viewpos, N, invviewmat, viewmat); result = sample_transparent(); diff --git a/source/blender/gpu/shaders/gpu_shader_material_utils.glsl b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl index d1037daa784..ea1dc03d467 100644 --- a/source/blender/gpu/shaders/gpu_shader_material_utils.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl @@ -23,6 +23,7 @@ uniform sampler2D unfrefract; uniform sampler2D unfltcmat; uniform sampler2D unfltcmag; uniform sampler2D unfscenebuf; +uniform sampler2D unfdepthbuf; uniform sampler2D unfbackfacebuf; uniform sampler2D unfjitter; uniform sampler1D unflutsamples; @@ -177,6 +178,7 @@ float backface_depth(ivec2 texelpos) { float depth = linear_depth(texelFetch(unfbackfacebuf, texelpos, 0).r); + /* background case */ if (depth == 1.0) return -1e16; else @@ -185,13 +187,29 @@ float backface_depth(ivec2 texelpos) float frontface_depth(ivec2 texelpos) { - float depth = texelFetch(unfscenebuf, texelpos, 0).a; + float depth = linear_depth(texelFetch(unfdepthbuf, texelpos, 0).r); /* background case */ if (depth == 1.0) return -1e16; else - return depth; + return -depth; +} + +vec3 position_from_depth(vec2 uv, float depth) +{ + vec3 pos; + float homcoord = gl_ProjectionMatrix[2][3] * depth + gl_ProjectionMatrix[3][3]; + pos.x = gl_ProjectionMatrixInverse[0][0] * (uv.x * 2.0 - 1.0) * homcoord; + pos.y = gl_ProjectionMatrixInverse[1][1] * (uv.y * 2.0 - 1.0) * homcoord; + pos.z = depth; + return pos; +} + +vec2 uv_from_position(vec3 position) +{ + vec4 projvec = gl_ProjectionMatrix * vec4(position, 1.0); + return (projvec.xy / projvec.w) * 0.5 + 0.5; } vec3 axis_angle_rotation(vec3 point, vec3 axis, float angle) @@ -821,14 +839,10 @@ vec3 hammersley_3d(float i) /* ------- Screen Space Raycasting ---------*/ -#if 0 /* 2D raymarch (More efficient) */ - /* By Morgan McGuire and Michael Mara at Williams College 2014 * Released as open source under the BSD 2-Clause License * http://opensource.org/licenses/BSD-2-Clause * http://casual-effects.blogspot.fr/2014/08/screen-space-ray-tracing.html */ - - void swapIfBigger(inout float a, inout float b) { if (a > b) { @@ -842,10 +856,11 @@ void swapIfBigger(inout float a, inout float b) bool raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out vec2 hitpixel, out vec3 hitco) { /* ssr_parameters */ - float nearz = -unfclip.x; /* Near plane distance (Negative number) */ + float nearz = -unfclip.x; /* Near plane distance (Negative number) */ + float farz = -unfclip.y; /* Far plane distance (Negative number) */ /* Clip ray to a near plane in 3D */ - float ray_length = 1e15; + float ray_length = 1e16; if ((ray_origin.z + ray_dir.z * ray_length) > nearz) ray_length = (nearz - ray_origin.z) / ray_dir.z; @@ -920,19 +935,17 @@ bool raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out * +1/2 for the previous iteration, we actually only have to compute one value * per iteration. */ float prev_zmax = ray_origin.z; - float zmax = prev_zmax, zmin = prev_zmax; - float scene_zmax = zmax + 1e4; + float zmax, zmin; /* P1.x is never modified after this point, so pre-scale it by * the step direction for a signed comparison */ float end = P1.x * step_sign; bool hit = false; - for (hitstep = 0.0; hitstep < unfssrparam.x && !hit; hitstep++) { - /* Ray finished & no hit*/ - //if ((P.x * step_sign) > end) break; + /* Ray finished & no hit*/ + if ((P.x * step_sign) > end) break; P += dP; Q.z += dQ.z; k += dk; @@ -942,79 +955,22 @@ bool raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out prev_zmax = zmax; swapIfBigger(zmin, zmax); - scene_zmax = texelFetch(unfscenebuf, ivec2(hitpixel), 0).a; - - /* background case */ - if (scene_zmax == 1.0) scene_zmax = -1e16; + float frontface = frontface_depth(ivec2(hitpixel)); + if (zmax < frontface) { #ifdef USE_BACKFACE - float backface = backface_depth(ivec2(hitpixel)); + float backface = backface_depth(ivec2(hitpixel)); #else - const float backface = -1e16; + float backface = frontface - 1.0; /* Todo find a good thickness */ #endif - hit = ((zmax > backface) && (zmin < scene_zmax)); + hit = (zmin > backface); + } } hitco = (Q0 + dQ * hitstep) / k; return hit; } -#else /* 3D raymarch */ - -void binary_search(vec3 ray_dir, inout vec3 hitco) -{ - for (int i = 0; i < MAX_SSR_REFINE_STEPS; i++) { - ray_dir *= 0.5; - hitco -= ray_dir; - vec4 co = unfpixelprojmat * vec4(hitco, 1.0); - float frontface = frontface_depth(ivec2(co.xy / co.w)) - hitco.z; - if (frontface - hitco.z < 0.0) hitco += ray_dir; - } -} - -/* 3D raycast */ -bool raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out vec2 hitpixel, out vec3 hitco) -{ - /* ssr_parameters */ - float slope = 1.0 - ray_dir.z; - ray_dir *= unfssrparam.y; /* step between samples */ - - float homcoord = gl_ProjectionMatrix[2][3] * ray_origin.z + gl_ProjectionMatrix[3][3]; - - hitco = ray_origin; - hitco += ray_dir * (jitter + homcoord * 0.005); - - hitpixel = vec2(0.0); - for (hitstep = 0.0; hitstep < unfssrparam.x; hitstep++) { - hitco += ray_dir; - vec4 co = unfpixelprojmat * vec4(hitco, 1.0); - co.xy /= co.w; - - /* Find a way to resolve inter penetration better */ - if (floor(co.xy) == gl_FragCoord.xy) continue; - - float frontface = frontface_depth(ivec2(co.xy)); -#ifdef USE_BACKFACE - float backface = backface_depth(ivec2(co.xy)); -#else - float backface = frontface - unfssrparam.y * 2.0; -#endif - if (frontface - hitco.z > 0.001 && backface - hitco.z < 0.0) { - /* Refine hit */ - //binary_search(ray_dir, hitco); - /* Find texel coord */ - vec4 pix = unfpixelprojmat * vec4(hitco, 1.0); - hitpixel = pix.xy / pix.w; - - return true; - } - } - - /* No hit */ - return false; -} - -#endif #if 0 /* 3D raycast */ bool hierarchical_raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out vec2 hitpixel, out vec3 hitco) @@ -1037,6 +993,7 @@ bool hierarchical_raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float return false; } #endif + float ssr_contribution(vec3 ray_origin, float hitstep, bool hit, inout vec3 hitco) { /* ssr_parameters */ |