forked from bartvdbraak/blender
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!
This commit is contained in:
parent
a0d7db503d
commit
ff7220349d
@ -765,6 +765,7 @@ if B.targets != ['cudakernels']:
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_frag.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_dof_vert.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_lib.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl")
|
||||
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fx_vert.glsl")
|
||||
data_to_c_simple("intern/opencolorio/gpu_shader_display_transform.glsl")
|
||||
|
||||
|
@ -2666,7 +2666,7 @@ static void view3d_draw_objects(
|
||||
const bContext *C,
|
||||
Scene *scene, View3D *v3d, ARegion *ar,
|
||||
const char **grid_unit,
|
||||
const bool do_bgpic, const bool draw_offscreen)
|
||||
const bool do_bgpic, const bool draw_offscreen, bool do_compositing)
|
||||
{
|
||||
RegionView3D *rv3d = ar->regiondata;
|
||||
Base *base;
|
||||
@ -2675,6 +2675,7 @@ static void view3d_draw_objects(
|
||||
const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
|
||||
/* only draw grids after in solid modes, else it hovers over mesh wires */
|
||||
const bool draw_grids_after = draw_grids && draw_floor && (v3d->drawtype > OB_WIRE);
|
||||
bool do_composite_xray = false;
|
||||
bool xrayclear = true;
|
||||
|
||||
if (!draw_offscreen) {
|
||||
@ -2814,9 +2815,20 @@ static void view3d_draw_objects(
|
||||
|
||||
/* transp and X-ray afterdraw stuff */
|
||||
if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d);
|
||||
|
||||
/* always do that here to cleanup depth buffers if none needed */
|
||||
if (do_compositing) {
|
||||
do_composite_xray = v3d->zbuf && (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first);
|
||||
GPU_fx_compositor_setup_XRay_pass(rv3d->compositor, do_composite_xray);
|
||||
}
|
||||
|
||||
if (v3d->afterdraw_xray.first) view3d_draw_xray(scene, ar, v3d, &xrayclear);
|
||||
if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, xrayclear);
|
||||
|
||||
if (do_compositing && do_composite_xray) {
|
||||
GPU_fx_compositor_XRay_resolve(rv3d->compositor);
|
||||
}
|
||||
|
||||
if (!draw_offscreen) {
|
||||
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
|
||||
}
|
||||
@ -3117,11 +3129,11 @@ void ED_view3d_draw_offscreen(
|
||||
}
|
||||
else {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
/* main drawing call */
|
||||
view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true);
|
||||
view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing);
|
||||
|
||||
/* post process */
|
||||
if (do_compositing) {
|
||||
@ -3551,7 +3563,7 @@ static void view3d_main_area_draw_objects(const bContext *C, Scene *scene, View3
|
||||
}
|
||||
|
||||
/* main drawing call */
|
||||
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false);
|
||||
view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing);
|
||||
|
||||
/* post process */
|
||||
if (do_compositing) {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
Normal file
14
source/blender/gpu/shaders/gpu_shader_fx_depth_resolve.glsl
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user