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
diff options
context:
space:
mode:
authorAntony Riakiotakis <kalast@gmail.com>2015-02-17 20:08:28 +0300
committerAntony Riakiotakis <kalast@gmail.com>2015-02-17 20:11:22 +0300
commitff7220349d32e747c7559809d68de7d835c0c1cd (patch)
treec6955f0b86bcf12ab6dc5d87b4a48300375d3da3 /source/blender/gpu
parenta0d7db503d82c1a5b56a5723da90364f11569b37 (diff)
Compositing works with X-Ray.
Basically, before drawing X-Rays, we now bind a second depth buffer. After drawing XRays, we do an extra resolve pass where we overwrite the non-XRay depth buffer in pixels where the depth is not maximum (which means background pixel, since depth is cleared before drawing X-Ray objects). This ensures both scene and X-Rays keep their depth values and are ready for compositing. Well, the odd effect due to depth discontinuities can be expected, and X-Rays are a bit more expensive (extra buffer + resolve pass) but at least X-Rays won't invalidate depth values anymore. Whee!
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_compositing.h10
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c89
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl14
5 files changed, 118 insertions, 1 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 7e32105a916..12b7f864469 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -69,6 +69,7 @@ set(SRC
shaders/gpu_shader_vertex.glsl
shaders/gpu_shader_vsm_store_frag.glsl
shaders/gpu_shader_vsm_store_vert.glsl
+ shaders/gpu_shader_fx_depth_resolve.glsl
GPU_buffers.h
GPU_draw.h
@@ -96,6 +97,7 @@ data_to_c_simple(shaders/gpu_shader_fx_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_ssao_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_dof_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_fx_depth_resolve.glsl SRC)
data_to_c_simple(shaders/gpu_shader_fx_lib.glsl SRC)
if(WITH_GAMEENGINE)
diff --git a/source/blender/gpu/GPU_compositing.h b/source/blender/gpu/GPU_compositing.h
index 796341d4830..93f1bc64922 100644
--- a/source/blender/gpu/GPU_compositing.h
+++ b/source/blender/gpu/GPU_compositing.h
@@ -60,10 +60,12 @@ typedef enum GPUFXShaderEffect {
GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE = 4,
GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR = 5,
GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE = 6,
+
+ GPU_SHADER_FX_DEPTH_RESOLVE = 7,
} GPUFXShaderEffect;
/* keep in synch with enum above! */
-#define MAX_FX_SHADERS 11
+#define MAX_FX_SHADERS 8
/* generate a new FX compositor */
GPUFX *GPU_fx_compositor_create(void);
@@ -79,6 +81,12 @@ bool GPU_fx_compositor_initialize_passes(
/* do compositing on the fx passes that have been initialized */
bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, struct Scene *scene, struct GPUOffScreen *ofs);
+/* bind new depth buffer for XRay pass */
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray);
+
+/* resolve a final depth buffer by compositing the XRay and normal depth buffers */
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx);
+
void GPU_fx_compositor_init_dof_settings(struct GPUDOFSettings *dof);
void GPU_fx_compositor_init_ssao_settings(struct GPUSSAOSettings *ssao);
#ifdef __cplusplus
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index cf288070126..32d805035d4 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -89,6 +89,7 @@ struct GPUFX {
/* texture bound to the depth attachment of the gbuffer */
GPUTexture *depth_buffer;
+ GPUTexture *depth_buffer_xray;
/* texture used for jittering for various effects */
GPUTexture *jitter_buffer;
@@ -213,6 +214,12 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
fx->depth_buffer = NULL;
}
+ if (fx->depth_buffer_xray) {
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+ GPU_texture_free(fx->depth_buffer_xray);
+ fx->depth_buffer_xray = NULL;
+ }
+
cleanup_fx_dof_buffers(fx);
if (fx->ssao_concentric_samples_tex) {
@@ -452,6 +459,88 @@ static void gpu_fx_bind_render_target(int *passes_left, GPUFX *fx, struct GPUOff
}
}
+void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray)
+{
+ char err_out[256];
+
+ if (do_xray) {
+ if (!fx->depth_buffer_xray && !(fx->depth_buffer_xray = GPU_texture_create_depth(fx->gbuffer_dim[0], fx->gbuffer_dim[1], err_out))) {
+ printf("%.256s\n", err_out);
+ cleanup_fx_gl_data(fx, true);
+ return;
+ }
+ }
+ else {
+ if (fx->depth_buffer_xray) {
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+ GPU_texture_free(fx->depth_buffer_xray);
+ fx->depth_buffer_xray = NULL;
+ }
+ return;
+ }
+
+ GPU_framebuffer_texture_detach(fx->depth_buffer);
+
+ /* first depth buffer, because system assumes read/write buffers */
+ if(!GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0, err_out))
+ printf("%.256s\n", err_out);
+}
+
+
+void GPU_fx_compositor_XRay_resolve(GPUFX *fx)
+{
+ GPUShader *depth_resolve_shader;
+ GPU_framebuffer_texture_detach(fx->depth_buffer_xray);
+
+ /* attach regular framebuffer */
+ GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0, NULL);
+
+ /* full screen quad where we will always write to depth buffer */
+ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_SCISSOR_BIT);
+ glDepthFunc(GL_ALWAYS);
+ /* disable scissor from sculpt if any */
+ glDisable(GL_SCISSOR_TEST);
+ /* disable writing to color buffer, it's depth only pass */
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ /* set up quad buffer */
+ glVertexPointer(2, GL_FLOAT, 0, fullscreencos);
+ glTexCoordPointer(2, GL_FLOAT, 0, fullscreenuvs);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false);
+
+ if (depth_resolve_shader) {
+ int depth_uniform;
+
+ depth_uniform = GPU_shader_get_uniform(depth_resolve_shader, "depthbuffer");
+
+ GPU_shader_bind(depth_resolve_shader);
+
+ GPU_texture_bind(fx->depth_buffer_xray, 0);
+ GPU_depth_texture_mode(fx->depth_buffer_xray, false, true);
+ GPU_shader_uniform_texture(depth_resolve_shader, depth_uniform, fx->depth_buffer_xray);
+
+ /* draw */
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ /* disable bindings */
+ GPU_depth_texture_mode(fx->depth_buffer_xray, true, false);
+ GPU_texture_unbind(fx->depth_buffer_xray);
+
+ GPU_shader_unbind();
+ }
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glPopAttrib();
+}
+
+
bool GPU_fx_do_composite_pass(GPUFX *fx, float projmat[4][4], bool is_persp, struct Scene *scene, struct GPUOffScreen *ofs)
{
GPUTexture *src, *target;
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 4d1a9770c78..1d081875c9b 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -83,6 +83,7 @@ extern char datatoc_gpu_shader_fx_vert_glsl[];
extern char datatoc_gpu_shader_fx_ssao_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_frag_glsl[];
extern char datatoc_gpu_shader_fx_dof_vert_glsl[];
+extern char datatoc_gpu_shader_fx_depth_resolve_glsl[];
extern char datatoc_gpu_shader_fx_lib_glsl[];
typedef struct GPUShaders {
@@ -1776,6 +1777,9 @@ GPUShader *GPU_shader_get_builtin_fx_shader(int effects, bool persp)
strcat(defines, "#define FIFTH_PASS\n");
GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_dof_vert_glsl, datatoc_gpu_shader_fx_dof_frag_glsl, datatoc_gpu_shader_fx_lib_glsl, defines);
break;
+
+ case GPU_SHADER_FX_DEPTH_RESOLVE:
+ GG.shaders.fx_shaders[offset] = GPU_shader_create(datatoc_gpu_shader_fx_vert_glsl, datatoc_gpu_shader_fx_depth_resolve_glsl, NULL, defines);
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
new file mode 100644
index 00000000000..e04cd7d3306
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
@@ -0,0 +1,14 @@
+uniform sampler2D depthbuffer;
+varying vec4 uvcoordsvar;
+
+void main(void)
+{
+ float depth = texture2D(depthbuffer, uvcoordsvar.xy).r;
+
+ /* XRay background, discard */
+ if (depth >= 1.0) {
+ discard;
+ }
+
+ gl_FragDepth = depth;
+}