diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-05-23 17:35:34 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-05-24 10:28:29 +0300 |
commit | e561eef3ff0b40c0abeb785d779f0c6ef73d5aa8 (patch) | |
tree | f3072a3a3e00e5862048f43f0413d8f64900ccd6 /source/blender/draw | |
parent | a709e8d6bb4aa56468fefac43f21f4b9a1b3a057 (diff) |
Workbench: Revealage buffer
Diffstat (limited to 'source/blender/draw')
10 files changed, 78 insertions, 11 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 96dcac5b2d2..c93035e5c6d 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -220,6 +220,7 @@ data_to_c_simple(engines/workbench/shaders/workbench_deferred_composite_frag.gls data_to_c_simple(engines/workbench/shaders/workbench_forward_composite_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_forward_depth_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl SRC) +data_to_c_simple(engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_object_outline_lib.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_prepass_vert.glsl SRC) data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl index 2550f44271b..88b715f55a8 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl @@ -1,5 +1,5 @@ #define NO_OBJECT_ID uint(0) - +#define EPSILON 0.00001 /* 4x4 bayer matrix prepared for 8bit UNORM precision error. */ #define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0)) const vec4 dither_mat4x4[4] = vec4[4]( @@ -62,3 +62,10 @@ void fresnel(vec3 I, vec3 N, float ior, out float kr) // As a consequence of the conservation of energy, transmittance is given by: // kt = 1 - kr; } + +vec4 calculate_transparent_accum(vec4 premultiplied) { + float a = min(1.0, premultiplied.a) * 8.0 + 0.01; + float b = -gl_FragCoord.z * 0.95 + 1.0; + float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2); + return premultiplied * w; +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl index 2d6f78082e3..02acc0aa00e 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_composite_frag.glsl @@ -15,6 +15,7 @@ void main() vec2 uv_viewport = gl_FragCoord.xy * invertedViewportSize; uint object_id = texelFetch(objectId, texel, 0).r; vec4 transparent_accum = texelFetch(transparentAccum, texel, 0); + float transparent_revealage = texelFetch(transparentRevealage, texel, 0).r; float revealage = texelFetch(transparentRevealage, texel, 0).r; vec4 color; @@ -27,7 +28,8 @@ void main() if (object_id == NO_OBJECT_ID) { color = vec4(background_color(world_data, uv_viewport.y), 0.0); } else { - color = transparent_accum / transparent_accum.a; + color = vec4((transparent_accum.xyz / max(transparent_accum.a, EPSILON)) * (1.0 - transparent_revealage), 1.0); + // color = vec4(transparent_revealage); } fragColor = vec4(mix(world_data.object_outline_color.rgb, color.xyz, outline), 1.0); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl index 6428ed44f6b..66445048996 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_accum_frag.glsl @@ -17,12 +17,7 @@ layout(std140) uniform world_block { layout(location=0) out vec4 transparentAccum; -vec4 calculate_transparent_accum(vec4 premultiplied) { - float a = min(1.0, premultiplied.a) * 8.0 + 0.01; - float b = -gl_FragCoord.z * 0.95 + 1.0; - float w = clamp(a * a * a * 1e8 * b * b * b, 1e-2, 3e2); - return vec4(premultiplied.rgb, premultiplied.a); -} + void main() { vec4 diffuse_color; @@ -47,7 +42,7 @@ void main() vec3 shaded_color = diffuse_color.rgb; #endif /* V3D_LIGHTING_STUDIO */ - float alpha = 0.1; + float alpha = 1.0; vec4 premultiplied = vec4(shaded_color.rgb * alpha, alpha); transparentAccum = calculate_transparent_accum(premultiplied); } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl new file mode 100644 index 00000000000..22f1cbc8a66 --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_forward_transparent_revealage_frag.glsl @@ -0,0 +1,7 @@ +layout(location=0) out float transparentRevealage; + +void main() +{ + transparentRevealage = 1.0; +} + diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 823ca904415..f2c8f3f0aef 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -50,12 +50,14 @@ static struct { struct GPUShader *composite_sh_cache[MAX_SHADERS]; struct GPUShader *transparent_accum_sh_cache[MAX_SHADERS]; + struct GPUShader *transparent_revealage_sh; struct GPUShader *object_outline_sh; struct GPUShader *depth_sh; struct GPUShader *checker_depth_sh; struct GPUTexture *object_id_tx; /* ref only, not alloced */ struct GPUTexture *transparent_accum_tx; /* ref only, not alloced */ + struct GPUTexture *transparent_revealage_tx; /* ref only, not alloced */ struct GPUTexture *composite_buffer_tx; /* ref only, not alloced */ int next_object_id; float normal_world_matrix[3][3]; @@ -65,6 +67,7 @@ static struct { extern char datatoc_workbench_forward_composite_frag_glsl[]; extern char datatoc_workbench_forward_depth_frag_glsl[]; extern char datatoc_workbench_forward_transparent_accum_frag_glsl[]; +extern char datatoc_workbench_forward_transparent_revealage_frag_glsl[]; extern char datatoc_workbench_data_lib_glsl[]; extern char datatoc_workbench_background_lib_glsl[]; extern char datatoc_workbench_checkerboard_depth_frag_glsl[]; @@ -104,6 +107,20 @@ static char *workbench_build_forward_transparent_accum_frag(void) return str; } +static char *workbench_build_forward_transparent_revealage_frag(void) +{ + char *str = NULL; + + DynStr *ds = BLI_dynstr_new(); + + BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl); + BLI_dynstr_append(ds, datatoc_workbench_forward_transparent_revealage_frag_glsl); + + str = BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return str; +} + static char *workbench_build_forward_composite_frag(void) { char *str = NULL; @@ -234,9 +251,12 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) /* XXX: forward depth does not use any defines ATM. */ char *defines = workbench_material_build_defines(wpd, OB_SOLID); char *forward_depth_frag = workbench_build_forward_depth_frag(); + char *forward_transparent_revealage_frag = workbench_build_forward_transparent_revealage_frag(); e_data.object_outline_sh = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, forward_depth_frag, defines); + e_data.transparent_revealage_sh = DRW_shader_create(datatoc_workbench_prepass_vert_glsl, NULL, forward_transparent_revealage_frag, defines); e_data.depth_sh = DRW_shader_create_3D_depth_only(); e_data.checker_depth_sh = DRW_shader_create_fullscreen(datatoc_workbench_checkerboard_depth_frag_glsl, NULL); + MEM_freeN(forward_transparent_revealage_frag); MEM_freeN(forward_depth_frag); MEM_freeN(defines); } @@ -247,6 +267,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_transparent); e_data.transparent_accum_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent); + e_data.transparent_revealage_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16F, &draw_engine_workbench_transparent); e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_transparent); GPU_framebuffer_ensure_config(&fbl->object_outline_fb, { GPU_ATTACHMENT_TEXTURE(dtxl->depth), @@ -256,6 +277,10 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(e_data.transparent_accum_tx), }); + GPU_framebuffer_ensure_config(&fbl->transparent_revealage_fb, { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(e_data.transparent_revealage_tx), + }); GPU_framebuffer_ensure_config(&fbl->composite_fb, { GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(e_data.composite_buffer_tx), @@ -264,6 +289,9 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) DRW_stats_group_start("Clear Buffers"); GPU_framebuffer_bind(fbl->transparent_accum_fb); GPU_framebuffer_clear_color(fbl->transparent_accum_fb, clear_color); + const float clear_color1[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + GPU_framebuffer_bind(fbl->transparent_revealage_fb); + GPU_framebuffer_clear_color(fbl->transparent_revealage_fb, clear_color1); GPU_framebuffer_bind(fbl->object_outline_fb); GPU_framebuffer_clear_color_depth(fbl->object_outline_fb, clear_color, 1.0f); DRW_stats_group_end(); @@ -273,6 +301,14 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) int state = DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE_FULL; psl->transparent_accum_pass = DRW_pass_create("Transparent Accum", state); } + /* Treansparecy Revealage */ + { + int state = DRW_STATE_WRITE_COLOR | DRW_STATE_TRANSPARENT_REVEALAGE; + psl->transparent_revealage_pass = DRW_pass_create("Transparent Revealage", state); + grp = DRW_shgroup_create(e_data.transparent_revealage_sh, psl->transparent_revealage_pass); + wpd->transparent_revealage_shgrp = grp; + + } /* Depth */ { int state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS; @@ -286,6 +322,7 @@ void workbench_forward_engine_init(WORKBENCH_Data *vedata) grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass); DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx); DRW_shgroup_uniform_texture_ref(grp, "transparentAccum", &e_data.transparent_accum_tx); + DRW_shgroup_uniform_texture_ref(grp, "transparentRevealage", &e_data.transparent_revealage_tx); DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo); DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1); DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL); @@ -305,6 +342,7 @@ void workbench_forward_engine_free() DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]); DRW_SHADER_FREE_SAFE(e_data.transparent_accum_sh_cache[index]); } + DRW_SHADER_FREE_SAFE(e_data.transparent_revealage_sh); DRW_SHADER_FREE_SAFE(e_data.object_outline_sh); DRW_SHADER_FREE_SAFE(e_data.checker_depth_sh); } @@ -315,6 +353,8 @@ void workbench_forward_cache_init(WORKBENCH_Data *UNUSED(vedata)) static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, Object *ob) { + WORKBENCH_StorageList *stl = vedata->stl; + WORKBENCH_PrivateData *wpd = stl->g_data; const DRWContextState *draw_ctx = DRW_context_state_get(); if (ob == draw_ctx->object_edit) { return; @@ -335,6 +375,7 @@ static void workbench_forward_cache_populate_particles(WORKBENCH_Data *vedata, O if (draw_as == PART_DRAW_PATH) { struct Gwn_Batch *geom = DRW_cache_particles_get_hair(ob, psys, NULL); WORKBENCH_MaterialData *material = get_or_create_material_data(vedata, ob, NULL, NULL, OB_SOLID); + DRW_shgroup_call_add(wpd->transparent_revealage_shgrp, geom, mat); DRW_shgroup_call_add(material->shgrp_object_outline, geom, mat); DRW_shgroup_call_add(material->shgrp, geom, mat); } @@ -376,6 +417,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) mat_drawtype = OB_TEXTURE; } material = get_or_create_material_data(vedata, ob, mat, image, mat_drawtype); + DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, geom_array[i], ob); DRW_shgroup_call_object_add(material->shgrp_object_outline, geom_array[i], ob); DRW_shgroup_call_object_add(material->shgrp, geom_array[i], ob); } @@ -391,10 +433,12 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) struct Gwn_Batch *geom = DRW_cache_object_surface_get(ob); if (geom) { if (is_sculpt_mode) { + DRW_shgroup_call_sculpt_add(wpd->transparent_revealage_shgrp, ob, ob->obmat); DRW_shgroup_call_sculpt_add(material->shgrp_object_outline, ob, ob->obmat); DRW_shgroup_call_sculpt_add(material->shgrp, ob, ob->obmat); } else { + DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, geom, ob); DRW_shgroup_call_object_add(material->shgrp_object_outline, geom, ob); DRW_shgroup_call_object_add(material->shgrp, geom, ob); } @@ -412,6 +456,7 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob) for (int i = 0; i < materials_len; ++i) { Material *mat = give_current_material(ob, i + 1); material = get_or_create_material_data(vedata, ob, mat, NULL, OB_SOLID); + DRW_shgroup_call_object_add(wpd->transparent_revealage_shgrp, mat_geom[i], ob); DRW_shgroup_call_object_add(material->shgrp_object_outline, mat_geom[i], ob); DRW_shgroup_call_object_add(material->shgrp, mat_geom[i], ob); } @@ -450,6 +495,8 @@ void workbench_forward_draw_scene(WORKBENCH_Data *vedata) /* Shade */ GPU_framebuffer_bind(fbl->transparent_accum_fb); DRW_draw_pass(psl->transparent_accum_pass); + GPU_framebuffer_bind(fbl->transparent_revealage_fb); + DRW_draw_pass(psl->transparent_revealage_pass); /* Composite */ GPU_framebuffer_bind(fbl->composite_fb); diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 087ed5100d9..b54d46dd55c 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -55,6 +55,7 @@ typedef struct WORKBENCH_FramebufferList { /* Forward render buffers */ struct GPUFrameBuffer *object_outline_fb; struct GPUFrameBuffer *transparent_accum_fb; + struct GPUFrameBuffer *transparent_revealage_fb; } WORKBENCH_FramebufferList; typedef struct WORKBENCH_StorageList { @@ -72,6 +73,7 @@ typedef struct WORKBENCH_PassList { /* forward rendering */ struct DRWPass *transparent_accum_pass; + struct DRWPass *transparent_revealage_pass; struct DRWPass *object_outline_pass; struct DRWPass *depth_pass; struct DRWPass *checker_depth_pass; @@ -111,6 +113,7 @@ typedef struct WORKBENCH_PrivateData { struct GPUUniformBuffer *world_ubo; struct DRWShadingGroup *shadow_shgrp; struct DRWShadingGroup *depth_shgrp; + struct DRWShadingGroup *transparent_revealage_shgrp; WORKBENCH_UBO_World world_data; float shadow_multiplier; } WORKBENCH_PrivateData; /* Transient data */ diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 8af3e6c7859..78e421d6a29 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -280,6 +280,7 @@ typedef enum { DRW_STATE_BLEND_PREMUL = (1 << 21), /* Use that if color is already premult by alpha. */ DRW_STATE_WIRE_SMOOTH = (1 << 22), DRW_STATE_TRANS_FEEDBACK = (1 << 23), + DRW_STATE_TRANSPARENT_REVEALAGE = (1 << 24), DRW_STATE_WRITE_STENCIL = (1 << 27), DRW_STATE_WRITE_STENCIL_SHADOW_PASS = (1 << 28), diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 29adb6b47f4..e28278d0b67 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1023,7 +1023,7 @@ static void drw_engines_enable_from_engine(RenderEngineType *engine_type, int dr case OB_SOLID: case OB_TEXTURE: - if (shading_flags & V3D_SHADING_SEE_THROUGH) { + if (shading_flags & V3D_SHADING_XRAY) { use_drw_engine(&draw_engine_workbench_transparent); } else { diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 9f4adac0106..14994e72169 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -221,7 +221,8 @@ void drw_state_set(DRWState state) int test; if (CHANGED_ANY_STORE_VAR( DRW_STATE_BLEND | DRW_STATE_BLEND_PREMUL | DRW_STATE_ADDITIVE | - DRW_STATE_MULTIPLY | DRW_STATE_TRANSMISSION | DRW_STATE_ADDITIVE_FULL, + DRW_STATE_MULTIPLY | DRW_STATE_TRANSMISSION | DRW_STATE_ADDITIVE_FULL | + DRW_STATE_TRANSPARENT_REVEALAGE, test)) { if (test) { @@ -240,6 +241,9 @@ void drw_state_set(DRWState state) else if ((state & DRW_STATE_TRANSMISSION) != 0) { glBlendFunc(GL_ONE, GL_SRC_ALPHA); } + else if ((state & DRW_STATE_TRANSPARENT_REVEALAGE) != 0) { + glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); + } else if ((state & DRW_STATE_ADDITIVE) != 0) { /* Do not let alpha accumulate but premult the source RGB by it. */ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, /* RGB */ |