Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Fukhaut <turjuque@gmail.com>2016-06-04 22:38:03 +0300
committerClément Fukhaut <turjuque@gmail.com>2016-06-04 22:38:03 +0300
commitfbf7e5acfb5085bcec2fc49c2cd673b741c40ffd (patch)
treed78306fad4222ff5dec35bf3a9f791db750cc413 /source
parentd7d0166386b323756d7751816cdbc6e26224a7cc (diff)
-Finished SSR Integration
-Added HiZ bufffer generation for future HiZ raytracing -Rewritten probe choosing code -Fixed glossy aniso mistakes
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c10
-rw-r--r--source/blender/gpu/CMakeLists.txt4
-rw-r--r--source/blender/gpu/GPU_framebuffer.h2
-rw-r--r--source/blender/gpu/GPU_pbr.h2
-rw-r--r--source/blender/gpu/GPU_shader.h6
-rw-r--r--source/blender/gpu/intern/gpu_draw.c62
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c66
-rw-r--r--source/blender/gpu/intern/gpu_material.c16
-rw-r--r--source/blender/gpu/intern/gpu_pbr.c59
-rw-r--r--source/blender/gpu/intern/gpu_probe.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader.c26
-rw-r--r--source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl65
-rw-r--r--source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_ambient_occlusion.glsl4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl27
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl3
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material_utils.glsl147
-rw-r--r--source/blender/makesrna/intern/rna_space.c2
18 files changed, 381 insertions, 128 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 187772a305a..716f5362313 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2901,12 +2901,13 @@ static void gpu_update_scene_buffer(Scene *scene, View3D *v3d, ARegion *basear)
false, (bool)scene->world, true, true,
NULL, NULL, NULL, NULL);
- GPU_scenebuf_unbind(scene_buffer);
-
v3d->drawtype = drawtype;
v3d->flag2 = flag2;
v3d->flag3 = flag3;
v3d->pbr_settings.pbr_flag = pbr_flag;
+
+ GPU_scenebuf_unbind(scene_buffer);
+ GPU_scenebuf_filter_texture(scene_buffer);
}
static void gpu_update_backface_buffer(Scene *scene, View3D *v3d, ARegion *basear)
@@ -2948,12 +2949,13 @@ static void gpu_update_backface_buffer(Scene *scene, View3D *v3d, ARegion *basea
false, (bool)scene->world, true, true,
NULL, NULL, NULL, NULL);
- GPU_scenebuf_unbind(backface_buffer);
-
v3d->drawtype = drawtype;
v3d->flag2 = flag2;
v3d->flag3 = flag3;
v3d->pbr_settings.pbr_flag = pbr_flag;
+
+ GPU_scenebuf_unbind(backface_buffer);
+ GPU_scenebuf_filter_texture(backface_buffer);
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index f043b770870..6bb94b334b5 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -99,6 +99,8 @@ set(SRC
shaders/gpu_shader_probe_sh_compute_vert.glsl
shaders/gpu_shader_display_sh_frag.glsl
shaders/gpu_shader_display_sh_vert.glsl
+ shaders/gpu_shader_downsample_maxz_frag.glsl
+ shaders/gpu_shader_downsample_maxz_vert.glsl
GPU_basic_shader.h
GPU_buffers.h
@@ -159,6 +161,8 @@ data_to_c_simple(shaders/gpu_shader_probe_sh_compute_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_probe_sh_compute_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_display_sh_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_display_sh_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_downsample_maxz_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_downsample_maxz_vert.glsl SRC)
if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index f81b35c4dde..f7ffecf9511 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -67,6 +67,8 @@ void GPU_framebuffer_blur(
GPUFrameBuffer *fb, struct GPUTexture *tex,
GPUFrameBuffer *blurfb, struct GPUTexture *blurtex);
+void GPU_framebuffer_hiz_construction(GPUFrameBuffer *fb, struct GPUTexture *tex, const bool max);
+
/* GPU OffScreen
* - wrapper around framebuffer and texture for simple offscreen drawing
* - changes size if graphics card can't support it */
diff --git a/source/blender/gpu/GPU_pbr.h b/source/blender/gpu/GPU_pbr.h
index 6670987acef..1efca5ca68b 100644
--- a/source/blender/gpu/GPU_pbr.h
+++ b/source/blender/gpu/GPU_pbr.h
@@ -47,6 +47,7 @@ typedef struct GPUScreenBuffer {
struct GPUTexture *tex;
struct GPUTexture *depth;
struct GPUFrameBuffer *fb;
+ struct GPUFrameBuffer *downsamplingfb;
} GPUScreenBuffer;
typedef struct GPUPBR {
@@ -73,6 +74,7 @@ GPUScreenBuffer *GPU_pbr_scene_buffer(GPUPBR *pbr, int width, int height);
GPUScreenBuffer *GPU_pbr_backface_buffer(GPUPBR *pbr, int width, int height);
void GPU_scenebuf_bind(GPUScreenBuffer* buf, float winmat[4][4], int winsize[2], float clipsta, float clipend);
void GPU_scenebuf_unbind(GPUScreenBuffer* buf);
+void GPU_scenebuf_filter_texture(GPUScreenBuffer* buf);
void GPU_pbr_settings_validate(struct GPUPBRSettings *pbr_settings);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index cc7ec4e95e9..6911a8022ff 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -96,9 +96,11 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_SEP_GAUSSIAN_BLUR = 1,
GPU_SHADER_SMOKE = 2,
GPU_SHADER_SMOKE_FIRE = 3,
- GPU_SHADER_DISPLAY_SH = 4,
+ GPU_SHADER_MINZ_DOWNSAMPLE = 4,
+ GPU_SHADER_MAXZ_DOWNSAMPLE = 5,
+ GPU_SHADER_DISPLAY_SH = 6,
- GPU_SHADER_COMPUTE_SH = 5, /* This reserves the MAX_SH_SAMPLES following values */
+ GPU_SHADER_COMPUTE_SH = 7, /* This reserves the MAX_SH_SAMPLES following values */
} GPUBuiltinShader;
#define MAX_SH_SAMPLES 10
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 79f0bbc6d6d..337f573b394 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -1851,47 +1851,45 @@ void GPU_begin_object_materials(
}
if (v3d->flag3 & V3D_PROBE_CAPTURE) {
+ Object *pro = (ob->probetype == OB_PROBE_OBJECT && ob->probe)
+ ? ob->probe /* probe attached */
+ : ob; /* object itself */
+
GMS.use_ssr = false;
GMS.use_ssao = false;
GMS.use_backface_depth = false;
- }
-
- /* Picking the right probe */
- /* XXX need to be done clearer */
- if (ob->probetype == OB_PROBE_CUBEMAP || ob->probetype == OB_PROBE_PLANAR) {
-
- GMS.is_planar_probe = (ob->probetype == OB_PROBE_PLANAR);
- if (GMS.is_planar_probe && (v3d->flag3 & V3D_PROBE_CAPTURE)) {
- /* Disable planar reflection in probe capture */
- GMS.is_planar_probe = false;
-
- if (ob->probe && ob->probe->probetype == OB_PROBE_CUBEMAP) {
- GMS.gprobe = GPU_probe_object(scene, ob->probe);
- GMS.parallax_correc = ob->probe->probeparallax;
+ /* check if we are not rendering this particular probe to avoid feedback loop */
+ if (pro != v3d->probe_source) {
+ if (pro->probetype == OB_PROBE_CUBEMAP) {
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ GMS.parallax_correc = pro->probeparallax;
}
- else {
- /* it will later get the world probe eventualy */
+ else if (pro->probetype == OB_PROBE_PLANAR) {
+ /* fallback to attached probe or world probe */
+ if (pro->probe && pro->probe->probetype == OB_PROBE_CUBEMAP
+ && pro->probe != v3d->probe_source) {
+ GMS.gprobe = GPU_probe_object(scene, pro->probe);
+ GMS.parallax_correc = pro->probe->probeparallax;
+ }
}
}
- else {
- GMS.gprobe = GPU_probe_object(scene, ob);
-
- if (ob->probetype == OB_PROBE_CUBEMAP)
- GMS.parallax_correc = ob->probeparallax;
- else if (ob->probe && ob->probe->probetype == OB_PROBE_CUBEMAP)
- GMS.parallax_correc = ob->probe->probeparallax;
- }
}
- else if (ob->probetype == OB_PROBE_OBJECT && ob->probe) {
- /* check if we are not rendering this particular probe to avoid feedback loop */
- if (!((v3d->flag3 & V3D_PROBE_CAPTURE) && (ob->probe == v3d->probe_source))) {
- if (ob->probe->probetype == OB_PROBE_CUBEMAP || ob->probe->probetype == OB_PROBE_PLANAR) {
- GMS.is_planar_probe = (ob->probe->probetype == OB_PROBE_PLANAR);
- GMS.gprobe = GPU_probe_object(scene, ob->probe);
+ else {
+ Object *pro = (ob->probetype == OB_PROBE_OBJECT && ob->probe)
+ ? ob->probe /* probe attached */
+ : ob; /* object itself */
- if (ob->probe->probetype == OB_PROBE_CUBEMAP)
- GMS.parallax_correc = ob->probe->probeparallax;
+ if (pro->probetype == OB_PROBE_CUBEMAP) {
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ GMS.parallax_correc = pro->probeparallax;
+ }
+ else if (pro->probetype == OB_PROBE_PLANAR) {
+ GMS.is_planar_probe = true;
+ GMS.gprobe = GPU_probe_object(scene, pro);
+ /* Pass the parallax info of the fallback cubemap*/
+ if (pro->probe && pro->probe->probetype == OB_PROBE_CUBEMAP) {
+ GMS.parallax_correc = pro->probe->probeparallax;
}
}
}
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 1d6fb613769..3736d3f673f 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -460,6 +460,72 @@ void GPU_framebuffer_blur(
GPU_shader_unbind();
}
+void GPU_framebuffer_hiz_construction(GPUFrameBuffer* fb, GPUTexture *tex, const bool max)
+{
+ int current_dim[2] = {GPU_texture_width(tex), GPU_texture_height(tex)};
+ int levels, bindcode;
+ int lowermip_uniform, lowermipsize_uniform;
+ GPUShader *shader = GPU_shader_get_builtin_shader((max) ? GPU_SHADER_MAXZ_DOWNSAMPLE : GPU_SHADER_MINZ_DOWNSAMPLE);
+
+ if (!shader)
+ return;
+
+ GPU_shader_bind(shader);
+ lowermip_uniform = GPU_shader_get_uniform(shader, "lowermip");
+ lowermipsize_uniform = GPU_shader_get_uniform(shader, "lowermipsize");
+
+ GPU_framebuffer_texture_attach(fb, tex, 0, NULL);
+ GPU_texture_bind_as_framebuffer(tex);
+
+ bindcode = GPU_texture_opengl_bindcode(tex);
+
+ levels = 1 + (int)floorf(log2f(fmaxf(current_dim[0], current_dim[1])));
+
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
+ /* Avoid warning from GPU_texture_bind */
+ glBindTexture(GL_TEXTURE_2D, bindcode);
+ GPU_shader_uniform_texture(shader, lowermip_uniform, tex);
+
+ for (int i=1; i < levels; i++) {
+ /* Send previous mip size to the shader */
+ GPU_shader_uniform_vector_int(shader, lowermipsize_uniform, 2, 1, current_dim);
+
+ /* calculate next viewport size */
+ current_dim[0] /= 2;
+ current_dim[1] /= 2;
+
+ /* ensure that the viewport size is always at least 1x1 */
+ CLAMP_MIN(current_dim[0], 1);
+ CLAMP_MIN(current_dim[1], 1);
+ glViewport(0, 0, current_dim[0], current_dim[1]);
+
+ /* bind next level for rendering but first restrict fetches only to previous level */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, i-1);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i-1);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, bindcode, i);
+
+ /* Drawing quad */
+ glBegin(GL_TRIANGLE_STRIP);
+ glTexCoord2d(1.0, 1.0); glVertex3f( 1.0, 1.0, 1.0);
+ glTexCoord2d(0.0, 1.0); glVertex3f(-1.0, 1.0, 1.0);
+ glTexCoord2d(1.0, 0.0); glVertex3f( 1.0, -1.0, 1.0);
+ glTexCoord2d(0.0, 0.0); glVertex3f(-1.0, -1.0, 1.0);
+ glEnd();
+ }
+
+ GPU_framebuffer_texture_detach(tex);
+ GPU_framebuffer_texture_unbind(fb, tex);
+
+ /* reset mipmap level range for the depth image */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels - 1);
+
+ GPU_shader_unbind();
+ GPU_texture_unbind(tex);
+}
+
/* GPUOffScreen */
struct GPUOffScreen {
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 6d330681c17..009044a65c9 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -2391,9 +2391,9 @@ static const char *brdf_light_function(GPUBrdfType brdftype, int lamptype)
else if (brdftype == GPU_BRDF_ANISO_BECKMANN) {
switch (lamptype) {
case LA_SUN :
- case LA_HEMI : return "bsdf_anisotropic_ggx_sun_light";
- case LA_AREA : return "bsdf_anisotropic_ggx_area_light";
- default : return "bsdf_anisotropic_ggx_sphere_light";
+ case LA_HEMI : return "bsdf_anisotropic_beckmann_sun_light";
+ case LA_AREA : return "bsdf_anisotropic_beckmann_area_light";
+ default : return "bsdf_anisotropic_beckmann_sphere_light";
}
}
else if (brdftype == GPU_BRDF_ANISO_ASHIKHMIN_SHIRLEY) {
@@ -2540,8 +2540,14 @@ static void shade_one_brdf_light(GPUBrdfInput *brdf, GPULamp *lamp)
visifac = lamp_get_visibility(mat, lamp, &lv, &dist);
/* View Position */
- if (((brdf->type == GPU_BRDF_TRANSLUCENT || brdf->type == GPU_BRDF_DIFFUSE || brdf->type == GPU_BRDF_GLOSSY_GGX || brdf->type == GPU_BRDF_GLOSSY_BECKMANN) && (lamp->type == LA_AREA)) ||
- ((brdf->type == GPU_BRDF_GLOSSY_GGX || brdf->type == GPU_BRDF_REFRACT_GGX || brdf->type == GPU_BRDF_GLASS_GGX) && (lamp->type == LA_LOCAL || lamp->type == LA_SPOT)))
+ if (((brdf->type == GPU_BRDF_TRANSLUCENT ||
+ brdf->type == GPU_BRDF_DIFFUSE ||
+ brdf->type == GPU_BRDF_GLOSSY_GGX ||
+ brdf->type == GPU_BRDF_GLOSSY_ASHIKHMIN_SHIRLEY ||
+ brdf->type == GPU_BRDF_GLOSSY_BECKMANN) && (lamp->type == LA_AREA)) ||
+ ((brdf->type == GPU_BRDF_GLOSSY_GGX ||
+ brdf->type == GPU_BRDF_REFRACT_GGX ||
+ brdf->type == GPU_BRDF_GLASS_GGX) && (lamp->type == LA_LOCAL || lamp->type == LA_SPOT)))
GPU_link(mat, "set_rgb", GPU_builtin(GPU_VIEW_POSITION), &view);
else
GPU_link(mat, "shade_view", GPU_builtin(GPU_VIEW_POSITION), &view);
diff --git a/source/blender/gpu/intern/gpu_pbr.c b/source/blender/gpu/intern/gpu_pbr.c
index bc244941bd8..17d2d4da99b 100644
--- a/source/blender/gpu/intern/gpu_pbr.c
+++ b/source/blender/gpu/intern/gpu_pbr.c
@@ -43,6 +43,7 @@
#include "GPU_texture.h"
#include "GPU_framebuffer.h"
#include "GPU_pbr.h"
+#include "GPU_draw.h"
#include "gpu_codegen.h"
@@ -54,6 +55,10 @@
void GPU_scenebuf_free(GPUScreenBuffer *buf)
{
+ if (buf->fb) {
+ GPU_framebuffer_free(buf->fb);
+ buf->fb = NULL;
+ }
if (buf->tex) {
GPU_texture_free(buf->tex);
buf->tex = NULL;
@@ -62,9 +67,9 @@ void GPU_scenebuf_free(GPUScreenBuffer *buf)
GPU_texture_free(buf->depth);
buf->depth = NULL;
}
- if (buf->fb) {
- GPU_framebuffer_free(buf->fb);
- buf->fb = NULL;
+ if (buf->downsamplingfb) {
+ GPU_framebuffer_free(buf->downsamplingfb);
+ buf->downsamplingfb = NULL;
}
MEM_freeN(buf);
@@ -76,7 +81,7 @@ static GPUScreenBuffer *gpu_scenebuf_create(int width, int height, bool depth_on
buf->w = width;
buf->h = height;
- buf->tex = NULL;
+ buf->depth = NULL;
buf->fb = GPU_framebuffer_create();
if (!buf->fb) {
@@ -84,6 +89,13 @@ static GPUScreenBuffer *gpu_scenebuf_create(int width, int height, bool depth_on
return NULL;
}
+ /* DOWNSAMPLING FB */
+ buf->downsamplingfb = GPU_framebuffer_create();
+ if (!buf->downsamplingfb) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
+
if (depth_only) {
buf->tex = GPU_texture_create_depth(width, height, NULL);
if (!buf->tex) {
@@ -95,6 +107,12 @@ static GPUScreenBuffer *gpu_scenebuf_create(int width, int height, bool depth_on
GPU_scenebuf_free(buf);
return NULL;
}
+
+ /* check validity at the very end! */
+ if (!GPU_framebuffer_check_valid(buf->fb, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
}
else {
buf->depth = GPU_texture_create_depth(width, height, NULL);
@@ -118,13 +136,14 @@ static GPUScreenBuffer *gpu_scenebuf_create(int width, int height, bool depth_on
GPU_scenebuf_free(buf);
return NULL;
}
+
+ /* check validity at the very end! */
+ if (!GPU_framebuffer_check_valid(buf->fb, NULL)) {
+ GPU_scenebuf_free(buf);
+ return NULL;
+ }
}
- /* check validity at the very end! */
- if (!GPU_framebuffer_check_valid(buf->fb, NULL)) {
- GPU_scenebuf_free(buf);
- return NULL;
- }
GPU_framebuffer_restore();
@@ -195,6 +214,28 @@ void GPU_scenebuf_unbind(GPUScreenBuffer* buf)
glEnable(GL_SCISSOR_TEST);
}
+void GPU_scenebuf_filter_texture(GPUScreenBuffer* buf)
+{
+ return;
+ /* MinZ Pyramid for depth */
+ if (buf->depth) {
+ GPU_texture_bind(buf->depth, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(buf->depth);
+ GPU_framebuffer_hiz_construction(buf->downsamplingfb, buf->depth, false);
+ GPU_framebuffer_texture_attach(buf->fb, buf->depth, 0, NULL);
+ }
+ else {
+ GPU_texture_bind(buf->tex, 0);
+ GPU_generate_mipmap(GL_TEXTURE_2D);
+ GPU_texture_unbind(buf->tex);
+ GPU_framebuffer_hiz_construction(buf->downsamplingfb, buf->tex, true);
+ GPU_framebuffer_texture_attach(buf->fb, buf->tex, 0, NULL);
+ }
+
+ GPU_framebuffer_restore();
+}
+
/* PBR core */
GPUPBR *GPU_pbr_create(void)
diff --git a/source/blender/gpu/intern/gpu_probe.c b/source/blender/gpu/intern/gpu_probe.c
index cc3d24188eb..e1f5583bccb 100644
--- a/source/blender/gpu/intern/gpu_probe.c
+++ b/source/blender/gpu/intern/gpu_probe.c
@@ -491,7 +491,7 @@ void GPU_probe_rebuild_mipmaps(GPUProbe *probe)
GPU_generate_mipmap(GL_TEXTURE_CUBE_MAP);
GPU_texture_unbind(probe->tex);
}
- if (probe->type == GPU_PROBE_PLANAR) {
+ else if (probe->type == GPU_PROBE_PLANAR) {
GPU_texture_bind(probe->texreflect, 0);
GPU_generate_mipmap(GL_TEXTURE_2D);
GPU_texture_unbind(probe->texreflect);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index d58d34b868b..6371259d32c 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -66,6 +66,8 @@ extern char datatoc_gpu_shader_probe_sh_compute_frag_glsl[];
extern char datatoc_gpu_shader_probe_sh_compute_vert_glsl[];
extern char datatoc_gpu_shader_display_sh_frag_glsl[];
extern char datatoc_gpu_shader_display_sh_vert_glsl[];
+extern char datatoc_gpu_shader_downsample_maxz_frag_glsl[];
+extern char datatoc_gpu_shader_downsample_maxz_vert_glsl[];
static struct GPUShadersGlobal {
struct {
@@ -75,6 +77,8 @@ static struct GPUShadersGlobal {
GPUShader *smoke_fire;
GPUShader *compute_sh[MAX_SH_SAMPLES];
GPUShader *display_sh;
+ GPUShader *maxz_downsample;
+ GPUShader *minz_downsample;
/* cache for shader fx. Those can exist in combinations so store them here */
GPUShader *fx_shaders[MAX_FX_SHADERS * 2];
} shaders;
@@ -694,6 +698,18 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
NULL, NULL, NULL, 0, 0, 0);
retval = GG.shaders.display_sh;
break;
+ case GPU_SHADER_MAXZ_DOWNSAMPLE:
+ if (!GG.shaders.maxz_downsample)
+ GG.shaders.maxz_downsample = GPU_shader_create(
+ datatoc_gpu_shader_downsample_maxz_vert_glsl, datatoc_gpu_shader_downsample_maxz_frag_glsl,
+ NULL, NULL, NULL, 0, 0, 0);
+ case GPU_SHADER_MINZ_DOWNSAMPLE:
+ if (!GG.shaders.minz_downsample)
+ GG.shaders.minz_downsample = GPU_shader_create(
+ datatoc_gpu_shader_downsample_maxz_vert_glsl, datatoc_gpu_shader_downsample_maxz_frag_glsl,
+ NULL, NULL, "#define MIN;\n", 0, 0, 0);
+ retval = GG.shaders.minz_downsample;
+ break;
}
}
@@ -822,6 +838,16 @@ void GPU_shader_free_builtin_shaders(void)
GG.shaders.display_sh = NULL;
}
+ if (GG.shaders.maxz_downsample) {
+ GPU_shader_free(GG.shaders.maxz_downsample);
+ GG.shaders.maxz_downsample = NULL;
+ }
+
+ if (GG.shaders.minz_downsample) {
+ GPU_shader_free(GG.shaders.minz_downsample);
+ GG.shaders.minz_downsample = NULL;
+ }
+
for (i = 0; i < 2 * MAX_FX_SHADERS; ++i) {
if (GG.shaders.fx_shaders[i]) {
GPU_shader_free(GG.shaders.fx_shaders[i]);
diff --git a/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl
new file mode 100644
index 00000000000..3229b41ffdb
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_frag.glsl
@@ -0,0 +1,65 @@
+/* From http://rastergrid.com/blog/2010/10/hierarchical-z-map-based-occlusion-culling/ */
+#extension GL_EXT_gpu_shader4 : enable
+
+uniform sampler2D lowermip;
+uniform ivec2 lowermipsize;
+
+float minmax(float a, float b, float c, float d)
+{
+#ifdef MIN
+ return min(min(a, b), min(c, d));
+#else
+ return max(max(a, b), max(c, d));
+#endif
+}
+
+float minmax(float a, float b, float c)
+{
+#ifdef MIN
+ return min(min(a, b), c);
+#else
+ return max(max(a, b), c);
+#endif
+}
+
+float minmax(float a, float b)
+{
+#ifdef MIN
+ return min(a, b);
+#else
+ return max(a, b);
+#endif
+}
+
+void main()
+{
+ vec4 texels;
+ ivec2 texelPos = ivec2(gl_FragCoord.xy) * 2;
+ texels.x = texelFetch(lowermip, texelPos, 0).r;
+ texels.y = texelFetch(lowermip, texelPos + ivec2(1, 0), 0).r;
+ texels.z = texelFetch(lowermip, texelPos + ivec2(1, 1), 0).r;
+ texels.w = texelFetch(lowermip, texelPos + ivec2(0, 1), 0).r;
+
+ float minmaxz = minmax(texels.x, texels.y, texels.z, texels.w);
+ vec3 extra;
+ /* if we are reducing an odd-width texture then fetch the edge texels */
+ if (((lowermipsize.x & 1) != 0) && (int(gl_FragCoord.x) == lowermipsize.x-3)) {
+ /* if both edges are odd, fetch the top-left corner texel */
+ if (((lowermipsize.y & 1) != 0) && (int(gl_FragCoord.y) == lowermipsize.y-3)) {
+ extra.z = texelFetch(lowermip, texelPos + ivec2(-1, -1), 0).r;
+ minmaxz = minmax(minmaxz, extra.z);
+ }
+ extra.x = texelFetch(lowermip, texelPos + ivec2(0, -1), 0).r;
+ extra.y = texelFetch(lowermip, texelPos + ivec2(1, -1), 0).r;
+ minmaxz = minmax(minmaxz, extra.x, extra.y);
+ }
+ /* if we are reducing an odd-height texture then fetch the edge texels */
+ else if (((lowermipsize.y & 1) != 0) && (int(gl_FragCoord.y) == lowermipsize.y-3)) {
+ extra.x = texelFetch(lowermip, texelPos + ivec2(0, -1), 0).r;
+ extra.y = texelFetch(lowermip, texelPos + ivec2(1, -1), 0).r;
+ minmaxz = minmax(minmaxz, extra.x, extra.y);
+ }
+
+ gl_FragDepth = minmaxz;
+ gl_FragColor = vec4(1.0);
+}
diff --git a/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl
new file mode 100644
index 00000000000..203d5322cee
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_downsample_maxz_vert.glsl
@@ -0,0 +1,6 @@
+
+void main()
+{
+ gl_Position = gl_Vertex;
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+}
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 8041bb14a6a..8d37e1523de 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
@@ -112,7 +112,7 @@ void ssao(vec3 viewpos, vec3 viewnor, out float result)
if (co.x > unfclip.z || co.x < 0.0 || co.y > unfclip.w || co.y < 0.0)
break;
- float sampledepth = frontface_depth(ivec2(co.xy));
+ float sampledepth = frontface_depth(ivec2(co.xy), 0);
/* Background Case */
if (sampledepth == 1.0)
@@ -121,7 +121,7 @@ void ssao(vec3 viewpos, vec3 viewnor, out float result)
/* We have a hit */
if (sampledepth > ray.z + viewpos.z + homcoord * 0.002
#ifdef USE_BACKFACE
- && backface_depth(ivec2(co.xy)) < ray.z + viewpos.z
+ && backface_depth(ivec2(co.xy), 0) < ray.z + viewpos.z
#endif
)
{
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl
index 437f1b6d64b..cad9e28037a 100644
--- a/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_anisotropic.glsl
@@ -85,15 +85,14 @@ float D_ggx_aniso_opti(float NH, float XH2, float YH2, float a2, float ax2, floa
return M_PI * a2 * tmp*tmp; /* Doing RCP at the end */
}
-float D_beckmann_aniso(float NH, float XH2, float YH2, float a2, float ax, float ay)
+float D_beckmann_aniso(float NH, float XH, float YH, float a2, float ax, float ay)
{
- /* Ht is tangent space microfacet normal (global variable) */
- float sx = -Ht.x / (Ht.z * ax);
- float sy = -Ht.y / (Ht.z * ay);
+ float sx = -XH / (NH * ax);
+ float sy = -YH / (NH * ay);
- float costheta4 = Ht.z * Ht.z * Ht.z * Ht.z;
+ float NH2 = NH * NH;
- return exp(-sx*sx - sy*sy) / (M_PI * a2 * costheta4);
+ return exp(-sx*sx - sy*sy) / (M_PI * a2 * NH2 * NH2);
}
float pdf_ggx_aniso(float NH, float XH2, float YH2, float a2, float ax2, float ay2)
@@ -102,9 +101,9 @@ float pdf_ggx_aniso(float NH, float XH2, float YH2, float a2, float ax2, float a
return NH / D;
}
-float pdf_beckmann_aniso(float NH, float XH2, float YH2, float a2, float ax2, float ay2)
+float pdf_beckmann_aniso(float NH, float XH, float YH, float a2, float ax, float ay)
{
- float D = D_beckmann_aniso(NH, XH2, YH2, a2, ax2, ay2);
+ float D = D_beckmann_aniso(NH, XH, YH, a2, ax, ay);
return NH / D;
}
@@ -208,14 +207,14 @@ float bsdf_beckmann_aniso(vec3 N, vec3 T, vec3 L, vec3 V, float roughness_x, flo
float VY2 = pow(dot(V, Y), 2); /* sinPhiO² */
float LX2 = pow(dot(L, X), 2); /* cosPhiI² */
float LY2 = pow(dot(L, Y), 2); /* sinPhiI² */
- float XH2 = pow(dot(X, H), 2);
- float YH2 = pow(dot(Y, H), 2);
+ float XH = dot(X, H);
+ float YH = dot(Y, H);
float alphaV2 = (VX2 * ax2 + VY2 * ay2) / (VX2 + VY2);
float alphaL2 = (LX2 * ax2 + LY2 * ay2) / (LX2 + LY2);
float G = G1_Smith_beckmann(NV, alphaV2) * G1_Smith_beckmann(NL, alphaL2);
- float D = D_beckmann_aniso(NH, XH2, YH2, a2, ax2, ay2);
+ float D = D_beckmann_aniso(NH, XH, YH, a2, ax, ay);
return NL * D * G * 0.25 / (NL * NV);
}
@@ -698,10 +697,10 @@ void env_sampling_aniso_beckmann(
if (NL > 0.0) {
/* Step 1 : Sampling Environment */
float NH = Ht.z;
- float XH2 = Ht.x * Ht.x;
- float YH2 = Ht.y * Ht.y;
+ float XH = Ht.x;
+ float YH = Ht.y;
- float pdf = pdf_beckmann_aniso(NH, XH2, YH2, a2, ax, ay);
+ float pdf = pdf_beckmann_aniso(NH, XH, YH, a2, ax, ay);
vec4 sample = sample_reflect_pdf(L, roughness, pdf);
diff --git a/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl
index 839ce99326e..c1c10c38d5c 100644
--- a/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material_bsdf_glossy.glsl
@@ -575,7 +575,8 @@ void env_sampling_glossy_sharp(
srgb_to_linearrgb(sample_ssr, sample_ssr);
result = mix(sample_probe.rgb, sample_ssr.rgb, contrib);
- result = -texelFetch(unfscenebuf, ivec2(gl_FragCoord.xy), 0).aaa / 100;
+ //result = mix(vec3(0.0), sample_ssr.rgb, contrib);
+ //result = vec3(texelFetch(unfdepthbuf, ivec2(gl_FragCoord.xy) / int(pow(2,unfssrparam.x-1)), int(unfssrparam.x-1)).r);
#else
result = sample_probe.rgb;
#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_material_utils.glsl b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl
index ea1dc03d467..b7868a77434 100644
--- a/source/blender/gpu/shaders/gpu_shader_material_utils.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material_utils.glsl
@@ -174,9 +174,9 @@ float linear_depth(float z)
}
}
-float backface_depth(ivec2 texelpos)
+float backface_depth(ivec2 texelpos, int lod)
{
- float depth = linear_depth(texelFetch(unfbackfacebuf, texelpos, 0).r);
+ float depth = linear_depth(texelFetch(unfbackfacebuf, texelpos, lod).r);
/* background case */
if (depth == 1.0)
@@ -185,9 +185,9 @@ float backface_depth(ivec2 texelpos)
return -depth;
}
-float frontface_depth(ivec2 texelpos)
+float frontface_depth(ivec2 texelpos, int lod)
{
- float depth = linear_depth(texelFetch(unfdepthbuf, texelpos, 0).r);
+ float depth = linear_depth(texelFetch(unfdepthbuf, texelpos, lod).r);
/* background case */
if (depth == 1.0)
@@ -907,93 +907,126 @@ bool raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out
P0 = P0.yx;
}
- /* Track the derivatives */
- float step_sign = sign(delta.x);
- float invdx = step_sign / delta.x;
- vec2 dP = vec2(step_sign, invdx * delta.y);
- vec3 dQ = (Q1 - Q0) * invdx;
- float dk = (k1 - k0) * invdx;
+ /* Track the derivatives */
+ float step_sign = sign(delta.x);
+ float invdx = step_sign / delta.x;
+ vec2 dP = vec2(step_sign, invdx * delta.y);
+ vec3 dQ = (Q1 - Q0) * invdx;
+ float dk = (k1 - k0) * invdx;
- /* Stride */
- float stride = 1.0;
-
- /* Calculate pixel stride based on distance of ray origin from camera. */
- //float stride_scale = 1.0 - min( 1.0, -ray_origin.z);
- //stride = 1.0 + stride_scale * stride;
+ /* Slide each value from the start of the ray to the end */
+ vec4 pqk = vec4(P0, Q0.z, k0);
- /* Scale derivatives by the desired pixel stride */
- dP *= stride; dQ *= stride; dk *= stride;
+ /* Scale derivatives by the desired pixel stride */
+ vec4 dPQK = vec4(dP, dQ.z, dk) * 1.0;
- /* Offset the starting values by the jitter fraction */
- //P0 += dP * jitter; Q0 += dQ * jitter; k0 += dk * jitter;
+ bool hit = false;
- /* Slide each value from the start of the ray to the end */
- vec3 Q = Q0; vec2 P = P0; float k = k0;
+#if 1 /* Linear 2D raymarching */
/* We track the ray depth at +/- 1/2 pixel to treat pixels as clip-space solid
* voxels. Because the depth at -1/2 for a given pixel will be the same as at
* +1/2 for the previous iteration, we actually only have to compute one value
* per iteration. */
float prev_zmax = ray_origin.z;
- float zmax, zmin;
+ 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;
+ /* 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;
+ if ((pqk.x * step_sign) > end) break;
- P += dP; Q.z += dQ.z; k += dk;
+ /* step through current cell */
+ pqk += dPQK;
- hitpixel = permute ? P.yx : P;
+ hitpixel = permute ? pqk.yx : pqk.xy;
zmin = prev_zmax;
- zmax = (dQ.z * 0.5 + Q.z) / (dk * 0.5 + k);
+ zmax = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);
prev_zmax = zmax;
swapIfBigger(zmin, zmax);
- float frontface = frontface_depth(ivec2(hitpixel));
+ float frontface = frontface_depth(ivec2(hitpixel), 0);
if (zmax < frontface) {
+ /* Below surface */
#ifdef USE_BACKFACE
- float backface = backface_depth(ivec2(hitpixel));
+ float backface = backface_depth(ivec2(hitpixel), 0);
#else
- float backface = frontface - 1.0; /* Todo find a good thickness */
+ float backface = frontface - 0.2; /* Todo find a good thickness */
#endif
- hit = (zmin > backface);
+ hit = (zmax > backface);
}
}
- hitco = (Q0 + dQ * hitstep) / k;
- return hit;
-}
+ /* Hit coordinate in 3D */
+ hitco = (Q0 + dQ * hitstep) / pqk.w;
+
+#else /* Hierarchical raymarching */
+
+ float z, mip, mippow, s;
+ float level = 1.0;
+ float steps = 0.0;
+ float dir = 1.0;
+ float lastdir = 1.0;
+ for (hitstep = 0.0; hitstep < unfssrparam.x && level > 0.0; hitstep++) {
+ mip = level - 1.0;
+ mippow = pow(2, mip);
-#if 0
-/* 3D raycast */
-bool hierarchical_raycast(vec3 ray_origin, vec3 ray_dir, float jitter, out float hitstep, out vec2 hitpixel, out vec3 hitco)
-{
- /* ssr_parameters */
- ray_dir *= unfssrparam.y; /* step between samples */
-
- hitco = ray_origin;
- hitco += ray_dir * jitter;
-
- hitpixel = vec2(0.0);
- float mip = 0.0;
- for (hitstep = 0.0; hitstep < unfssrparam.x; hitstep++) {
/* step through current cell */
- if (above) mip++;
- if (below) mip--;
+ //s = dir * max(1.0, mippow / 2);
+ s = dir * mippow;
+ //s = dir * level;
+ P += dP * s; Q.z += dQ.z * s; k += dk * s; steps += s;
+
+ hitpixel = permute ? P.yx : P;
+ z = dQ.z / k;
+
+ float frontface = frontface_depth(ivec2(hitpixel / mippow), int(mip));
+
+ if (z < frontface) {
+ /* Below surface */
+#ifdef USE_BACKFACE
+ float backface = backface_depth(ivec2(hitpixel), 0);
+#else
+ float backface = -1e16; /* Todo find a good thickness */
+#endif
+ if (z > backface) {
+ /* Hit */
+ /* This will step back the current step */
+ //s = -1.0 * level;
+ //P += dP * s; Q.z += dQ.z * s; k += dk * s; steps += s;
+ dir = -1.0;
+ level--;
+ continue;
+ }
+ }
+
+ /* Above surface */
+ if (dir != -1.0 && lastdir != -1.0) {
+ /* Only step up in mip if the last iteration was positive
+ * This way we don't skip potential occluders */
+ level++;
+ level = min(level, 5.0);
+ }
+ lastdir = dir;
+ dir = 1.0;
}
- /* No hit */
- return false;
-}
+ hitstep = 1.0;
+
+ hit = (level == 0.0);
+
+ /* Hit coordinate in 3D */
+ hitco = (Q0 + dQ * steps) / k;
#endif
+ return hit;
+}
+
float ssr_contribution(vec3 ray_origin, float hitstep, bool hit, inout vec3 hitco)
{
/* ssr_parameters */
@@ -1010,5 +1043,5 @@ float ssr_contribution(vec3 ray_origin, float hitstep, bool hit, inout vec3 hitc
float maxdimension = saturate(max(abs(co.x), abs(co.y)));
float screenfade = saturate((0.999999 - maxdimension) * attenuation);
- return sqrt(stepfade * screenfade) * float(hit);
+ return smoothstep(0.0, 1.0, stepfade * screenfade) * float(hit);
}
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 272d027d490..4f2c3463c09 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2366,7 +2366,7 @@ static void rna_def_gpu_pbr_ssr(BlenderRNA *brna)
prop = RNA_def_property(srna, "steps", PROP_INT, PROP_NONE);
RNA_def_property_ui_text(prop, "Steps", "Number of samples");
- RNA_def_property_range(prop, 1, 128);
+ RNA_def_property_range(prop, 1, 256);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}