Workbench: Shadow: Add Depth Fail method
Also add new debug visualisation. Depth fail method is not used for the moment but has nice benefits. It will be used efficiently in the future.
This commit is contained in:
@@ -213,6 +213,8 @@ data_to_c_simple(engines/workbench/shaders/workbench_prepass_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_composite_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_vert.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_geom.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_caps_geom.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_shadow_debug_frag.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_background_lib.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_common_lib.glsl SRC)
|
||||
data_to_c_simple(engines/workbench/shaders/workbench_data_lib.glsl SRC)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#extension GL_ARB_gpu_shader5 : enable
|
||||
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
#define USE_INVOC_EXT
|
||||
#endif
|
||||
|
||||
#define DOUBLE_MANIFOLD
|
||||
|
||||
#ifdef DOUBLE_MANIFOLD
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 4
|
||||
# else
|
||||
# define vert_ct 12
|
||||
# endif
|
||||
#else
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 2
|
||||
# else
|
||||
# define vert_ct 6
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_INVOC_EXT
|
||||
layout(triangles, invocations = invoc_ct) in;
|
||||
layout(triangle_strip, max_vertices = 3) out;
|
||||
#else
|
||||
layout(triangles) in;
|
||||
layout(triangle_strip, max_vertices = vert_ct) out;
|
||||
#endif
|
||||
|
||||
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
|
||||
|
||||
in VertexData {
|
||||
vec3 pos; /* local position */
|
||||
vec4 frontPosition; /* final ndc position */
|
||||
vec4 backPosition;
|
||||
} vData[];
|
||||
|
||||
vec4 get_pos(int v, bool backface)
|
||||
{
|
||||
return (backface) ? vData[v].backPosition : vData[v].frontPosition;
|
||||
}
|
||||
|
||||
void emit_cap(const bool front)
|
||||
{
|
||||
if (front) {
|
||||
gl_Position = vData[0].frontPosition; EmitVertex();
|
||||
gl_Position = vData[1].frontPosition; EmitVertex();
|
||||
gl_Position = vData[2].frontPosition; EmitVertex();
|
||||
}
|
||||
else {
|
||||
gl_Position = vData[0].backPosition; EmitVertex();
|
||||
gl_Position = vData[2].backPosition; EmitVertex();
|
||||
gl_Position = vData[1].backPosition; EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 v10 = vData[0].pos - vData[1].pos;
|
||||
vec3 v12 = vData[2].pos - vData[1].pos;
|
||||
|
||||
vec3 n = cross(v12, v10);
|
||||
float facing = dot(n, lightDirection);
|
||||
|
||||
bool backface = facing > 0.0;
|
||||
|
||||
if (!backface) {
|
||||
#ifdef USE_INVOC_EXT
|
||||
bool do_front = (gl_InvocationID & 1) == 0;
|
||||
emit_cap(do_front);
|
||||
#else
|
||||
emit_cap(true);
|
||||
emit_cap(false);
|
||||
# ifdef DOUBLE_MANIFOLD
|
||||
emit_cap(true);
|
||||
emit_cap(false);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float intensity = 0.25;
|
||||
#ifdef SHADOW_PASS
|
||||
fragColor = vec4((gl_FrontFacing) ? vec3(intensity, -intensity, 0.0)
|
||||
: vec3(-intensity, intensity, 0.0), 1.0);
|
||||
#else
|
||||
fragColor = vec4((gl_FrontFacing) ? vec3(intensity, intensity, -intensity)
|
||||
: vec3(-intensity, -intensity, intensity), 1.0);
|
||||
#endif
|
||||
}
|
||||
@@ -1,11 +1,31 @@
|
||||
#extension GL_ARB_gpu_shader5 : enable
|
||||
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
layout(lines_adjacency, invocations = 2) in;
|
||||
#define USE_INVOC_EXT
|
||||
#endif
|
||||
|
||||
#define DOUBLE_MANIFOLD
|
||||
|
||||
#ifdef DOUBLE_MANIFOLD
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 2
|
||||
# else
|
||||
# define vert_ct 8
|
||||
# endif
|
||||
#else
|
||||
# ifdef USE_INVOC_EXT
|
||||
# define invoc_ct 1
|
||||
# else
|
||||
# define vert_ct 4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_INVOC_EXT
|
||||
layout(lines_adjacency, invocations = invoc_ct) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
#else
|
||||
layout(lines_adjacency) in;
|
||||
layout(triangle_strip, max_vertices = 8) out;
|
||||
layout(triangle_strip, max_vertices = vert_ct) out;
|
||||
#endif
|
||||
|
||||
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
|
||||
@@ -22,7 +42,8 @@ in VertexData {
|
||||
|
||||
void extrude_edge(bool invert)
|
||||
{
|
||||
ivec2 idx = (invert) ? ivec2(2, 1) : ivec2(1, 2);
|
||||
/* Reverse order if backfacing the light. */
|
||||
ivec2 idx = (invert) ? ivec2(1, 2) : ivec2(2, 1);
|
||||
gl_Position = vData[idx.x].frontPosition; EmitVertex();
|
||||
gl_Position = vData[idx.y].frontPosition; EmitVertex();
|
||||
gl_Position = vData[idx.x].backPosition; EmitVertex();
|
||||
@@ -69,23 +90,23 @@ void main()
|
||||
if (backface.x == backface.y)
|
||||
return;
|
||||
|
||||
/* Reverse order if backfacing the light. */
|
||||
ivec2 idx = ivec2(1, 2);
|
||||
idx = (backface.x) ? idx.yx : idx.xy;
|
||||
|
||||
#ifdef GL_ARB_gpu_shader5
|
||||
#ifdef USE_INVOC_EXT
|
||||
if (gl_InvocationID == 0) {
|
||||
extrude_edge(backface.x);
|
||||
}
|
||||
else if (is_manifold) {
|
||||
# ifdef DOUBLE_MANIFOLD
|
||||
/* Increment/Decrement twice for manifold edges. */
|
||||
extrude_edge(backface.x);
|
||||
# endif
|
||||
}
|
||||
#else
|
||||
extrude_edge(backface.x);
|
||||
/* Increment/Decrement twice for manifold edges. */
|
||||
if (is_manifold) {
|
||||
# ifdef DOUBLE_MANIFOLD
|
||||
/* Increment/Decrement twice for manifold edges. */
|
||||
extrude_edge(backface.x);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#define EPSILON 0.0001
|
||||
#define INFINITE 1000000.0
|
||||
#define INFINITE 1000.0
|
||||
|
||||
uniform mat4 ModelViewProjectionMatrix;
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
|
||||
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
|
||||
|
||||
in vec3 pos;
|
||||
|
||||
@@ -54,7 +54,9 @@
|
||||
static struct {
|
||||
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
|
||||
struct GPUShader *composite_sh_cache[MAX_SHADERS];
|
||||
struct GPUShader *shadow_sh;
|
||||
struct GPUShader *shadow_fail_sh;
|
||||
struct GPUShader *shadow_pass_sh;
|
||||
struct GPUShader *shadow_caps_sh;
|
||||
|
||||
struct GPUTexture *object_id_tx; /* ref only, not alloced */
|
||||
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
|
||||
@@ -74,6 +76,8 @@ extern char datatoc_workbench_composite_frag_glsl[];
|
||||
|
||||
extern char datatoc_workbench_shadow_vert_glsl[];
|
||||
extern char datatoc_workbench_shadow_geom_glsl[];
|
||||
extern char datatoc_workbench_shadow_caps_geom_glsl[];
|
||||
extern char datatoc_workbench_shadow_debug_frag_glsl[];
|
||||
|
||||
extern char datatoc_workbench_background_lib_glsl[];
|
||||
extern char datatoc_workbench_common_lib_glsl[];
|
||||
@@ -320,7 +324,26 @@ void workbench_materials_engine_init(WORKBENCH_Data *vedata)
|
||||
memset(e_data.prepass_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
|
||||
memset(e_data.composite_sh_cache, 0x00, sizeof(struct GPUShader *) * MAX_SHADERS);
|
||||
e_data.next_object_id = 1;
|
||||
e_data.shadow_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl, datatoc_workbench_shadow_geom_glsl, NULL, NULL);
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
const char *shadow_frag = datatoc_workbench_shadow_debug_frag_glsl;
|
||||
#else
|
||||
const char *shadow_frag = NULL;
|
||||
#endif
|
||||
e_data.shadow_pass_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_PASS\n");
|
||||
e_data.shadow_fail_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_geom_glsl,
|
||||
shadow_frag,
|
||||
"#define SHADOW_FAIL\n");
|
||||
e_data.shadow_caps_sh = DRW_shader_create(
|
||||
datatoc_workbench_shadow_vert_glsl,
|
||||
datatoc_workbench_shadow_caps_geom_glsl,
|
||||
shadow_frag,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (!stl->g_data) {
|
||||
@@ -369,7 +392,9 @@ void workbench_materials_engine_free()
|
||||
DRW_SHADER_FREE_SAFE(e_data.prepass_sh_cache[index]);
|
||||
DRW_SHADER_FREE_SAFE(e_data.composite_sh_cache[index]);
|
||||
}
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_pass_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_fail_sh);
|
||||
DRW_SHADER_FREE_SAFE(e_data.shadow_caps_sh);
|
||||
}
|
||||
|
||||
static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
|
||||
@@ -442,13 +467,22 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
|
||||
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
||||
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK | DRW_STATE_WRITE_COLOR);
|
||||
grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.display.light_direction, 1);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
wpd->shadow_shgrp = grp;
|
||||
psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Debug Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Debug Fail", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Depth Fail Caps", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
#else
|
||||
psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL_SHADOW);
|
||||
psl->shadow_depth_pass_pass = DRW_pass_create("Shadow Depth Pass", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL_SHADOW);
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
psl->shadow_depth_fail_pass = DRW_pass_create("Shadow Depth Fail", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL_SHADOW);
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
psl->shadow_depth_fail_caps_pass = DRW_pass_create("Shadow Depth Fail Caps", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL_SHADOW);
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
|
||||
psl->composite_shadow_pass = DRW_pass_create("Composite Shadow", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_NEQUAL);
|
||||
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_shadow_pass);
|
||||
@@ -632,10 +666,24 @@ void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
mul_v3_mat3_m4v3(engine_object_data->shadow_dir, ob->imat, e_data.display.light_direction);
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_stencil_mask(grp, 0xFF);
|
||||
DRW_shgroup_call_object_add(grp, geom_shadow, ob);
|
||||
DRWShadingGroup *grp;
|
||||
if (true) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_pass_sh, psl->shadow_depth_pass_pass);
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_shadow, ob);
|
||||
}
|
||||
else {
|
||||
struct Gwn_Batch *geom_caps = DRW_cache_object_surface_get(ob);
|
||||
if (geom_caps) {
|
||||
grp = DRW_shgroup_create(e_data.shadow_caps_sh, psl->shadow_depth_fail_caps_pass);
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_caps, ob);
|
||||
}
|
||||
|
||||
grp = DRW_shgroup_create(e_data.shadow_fail_sh, psl->shadow_depth_fail_pass);
|
||||
DRW_shgroup_uniform_vec3(grp, "lightDirection", engine_object_data->shadow_dir, 1);
|
||||
DRW_shgroup_call_object_add(grp, geom_shadow, ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -676,12 +724,16 @@ void workbench_materials_draw_scene(WORKBENCH_Data *vedata)
|
||||
DRW_draw_pass(psl->prepass_pass);
|
||||
if (SHADOW_ENABLED(wpd)) {
|
||||
#ifdef DEBUG_SHADOW_VOLUME
|
||||
GPU_framebuffer_bind(dfbl->default_fb);
|
||||
GPU_framebuffer_bind(fbl->composite_fb);
|
||||
DRW_draw_pass(psl->composite_pass);
|
||||
DRW_draw_pass(psl->shadow_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_pass_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
|
||||
#else
|
||||
GPU_framebuffer_bind(dfbl->depth_only_fb);
|
||||
DRW_draw_pass(psl->shadow_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_pass_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_pass);
|
||||
DRW_draw_pass(psl->shadow_depth_fail_caps_pass);
|
||||
GPU_framebuffer_bind(fbl->composite_fb);
|
||||
DRW_draw_pass(psl->composite_pass);
|
||||
DRW_draw_pass(psl->composite_shadow_pass);
|
||||
|
||||
@@ -50,7 +50,9 @@ typedef struct WORKBENCH_StorageList {
|
||||
|
||||
typedef struct WORKBENCH_PassList {
|
||||
struct DRWPass *prepass_pass;
|
||||
struct DRWPass *shadow_pass;
|
||||
struct DRWPass *shadow_depth_pass_pass;
|
||||
struct DRWPass *shadow_depth_fail_pass;
|
||||
struct DRWPass *shadow_depth_fail_caps_pass;
|
||||
struct DRWPass *composite_pass;
|
||||
struct DRWPass *composite_shadow_pass;
|
||||
struct DRWPass *composite_light_pass;
|
||||
|
||||
@@ -161,7 +161,7 @@ void drw_state_set(DRWState state)
|
||||
glDepthFunc(GL_EQUAL);
|
||||
}
|
||||
else if (state & DRW_STATE_DEPTH_GREATER) {
|
||||
glDepthFunc(GL_GREATER);
|
||||
glDepthFunc(GL_GEQUAL);
|
||||
}
|
||||
else if (state & DRW_STATE_DEPTH_ALWAYS) {
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
@@ -313,8 +313,8 @@ void drw_state_set(DRWState state)
|
||||
}
|
||||
else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW) != 0) {
|
||||
glStencilMask(0xFF);
|
||||
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
|
||||
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
|
||||
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
|
||||
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
|
||||
}
|
||||
/* Stencil Test */
|
||||
else if ((state & (DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)) != 0) {
|
||||
|
||||
Reference in New Issue
Block a user