[Bf-blender-cvs] [f17e7a34744] blender2.8-workbench: Workbench: Shadows
Jeroen Bakker
noreply at git.blender.org
Wed May 2 15:13:41 CEST 2018
Commit: f17e7a3474483315edb186d753deb1d7d6216ab7
Author: Jeroen Bakker
Date: Wed May 2 15:12:42 2018 +0200
Branches: blender2.8-workbench
https://developer.blender.org/rBf17e7a3474483315edb186d753deb1d7d6216ab7
Workbench: Shadows
Use a depth fail shadow volume algoritmh. TODO: optimize for speed. Fix
fireflies
===================================================================
M release/scripts/startup/bl_ui/properties_render.py
M source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
M source/blender/draw/engines/workbench/workbench_engine.c
M source/blender/draw/engines/workbench/workbench_materials.c
M source/blender/draw/intern/DRW_render.h
M source/blender/draw/intern/draw_manager_exec.c
M source/blender/editors/space_view3d/space_view3d.c
M source/blender/makesrna/intern/rna_layer.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 5e5a55a3dab..3de97789691 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -768,6 +768,7 @@ class RENDER_PT_workbench_environment_light(RenderButtonsPanel, Panel):
col.prop(props, "diffuse_light_z_neg", text="")
layout.prop(props, "light_direction", text="")
+ layout.prop(props, "ambient_light_intensity")
classes = (
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
index 9d6da35c314..15834cd4d45 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -1,37 +1,64 @@
#define EPSILON 0.0000001
-#define INFINITE 1000.0
-layout(lines) in;
-layout(triangle_strip, max_vertices=4) out;
+#define INFINITE 100.0
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=14) out;
uniform mat4 ModelMatrix;
uniform mat4 ModelViewProjectionMatrix;
uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
-flat in vec3 faceNormal1[];
-flat in vec3 faceNormal2[];
-
-void emit_quad(vec4 start_vertex, vec4 end_vertex, vec4 light_direction) {
- gl_Position = ModelViewProjectionMatrix * (start_vertex + light_direction * EPSILON);
+vec3 face_normal(vec3 v1, vec3 v2, vec3 v3) {
+ return normalize(cross(v2 - v1, v3 - v1));
+}
+void emit_side_quad(vec4 v1, vec4 v2, vec4 light_direction) {
+ gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * EPSILON);
EmitVertex();
- gl_Position = ModelViewProjectionMatrix * (start_vertex + light_direction * INFINITE);
+ gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * INFINITE);
EmitVertex();
- gl_Position = ModelViewProjectionMatrix * (end_vertex + light_direction * EPSILON);
+ gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * EPSILON);
EmitVertex();
- gl_Position = ModelViewProjectionMatrix * (end_vertex + light_direction * INFINITE);
+ gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * INFINITE);
EmitVertex();
EndPrimitive();
}
+void emit_front_cap(vec4 v1, vec4 v2, vec4 v3, vec4 light_direction) {
+ gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * EPSILON);
+ EmitVertex();
+ gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * EPSILON);
+ EmitVertex();
+ gl_Position = ModelViewProjectionMatrix * (v3 + light_direction * EPSILON);
+ EmitVertex();
+ EndPrimitive();
+}
+
+void emit_back_cap(vec4 v1, vec4 v2, vec4 v3, vec4 light_direction) {
+ gl_Position = ModelViewProjectionMatrix * (v3 + light_direction * INFINITE);
+ EmitVertex();
+ gl_Position = ModelViewProjectionMatrix * (v2 + light_direction * INFINITE);
+ EmitVertex();
+ gl_Position = ModelViewProjectionMatrix * (v1 + light_direction * INFINITE);
+ EmitVertex();
+ EndPrimitive();
+}
+
void main()
{
- /* light_direction: Light direction in object space TODO: Move to CPU */
+ /* light_direction: Light direction in object space TODO: Move to world space */
vec3 light_direction = normalize((vec4(lightDirection, 0.0) * ModelMatrix).xyz);
- bool front1 = dot(faceNormal1[0], light_direction) >= 0;
- bool front2 = dot(faceNormal2[0], light_direction) >= 0;
+ vec4 v1 = gl_in[0].gl_Position;
+ vec4 v2 = gl_in[1].gl_Position;
+ vec4 v3 = gl_in[2].gl_Position;
+ bool backface = dot(face_normal(v1.xyz, v2.xyz, v3.xyz), light_direction) > 0.0;
- if (!front1 && front2) {
- emit_quad(gl_in[0].gl_Position, gl_in[1].gl_Position, vec4(light_direction, 0.0));
+ if (backface) {
+ vec4 light_direction4 = vec4(light_direction, 0.0);
+ /* emit side faces */
+ emit_side_quad(v2, v1, light_direction4);
+ emit_side_quad(v3, v2, light_direction4);
+ emit_side_quad(v1, v3, light_direction4);
+ /* emit front and back cap */
+ emit_front_cap(v3, v2, v1, light_direction4);
+ emit_back_cap(v3, v2, v1, light_direction4);
}
- else if (front1 && !front2) {
- emit_quad(gl_in[1].gl_Position, gl_in[0].gl_Position, vec4(light_direction, 0.0));
- }
-}
\ No newline at end of file
+}
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 32c8479393e..844513372c9 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -74,7 +74,9 @@ static void workbench_view_layer_settings_create(RenderEngine *UNUSED(engine), I
BKE_collection_engine_property_add_float_array(props, "diffuse_light_z_neg", diffuse_z_neg, 3);
const float light_direction[3] = {0.577350269, 0.577350269, 0.577350269};
+ const float ambient_light_intensity = 0.8;
BKE_collection_engine_property_add_float_array(props, "light_direction", light_direction, 3);
+ BKE_collection_engine_property_add_float(props, "ambient_light_intensity", ambient_light_intensity);
}
/* Note: currently unused, we may want to register so we can see this when debugging the view. */
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 0187f3d1581..98397403edb 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -38,8 +38,9 @@
/* *********** STATIC *********** */
-// #define SHOW_SHADOW_VOLUME
+//#define DEBUG_SHADOW_VOLUME
#define MAX_SHADERS 255
+
static struct {
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
struct GPUShader *composite_sh_cache[MAX_SHADERS];
@@ -74,7 +75,6 @@ extern DrawEngineType draw_engine_workbench_solid;
#define OBJECT_ID_PASS_ENABLED(wpd) (wpd->drawtype_options & V3D_DRAWOPTION_OBJECT_OVERLAP)
#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (wpd->drawtype_lighting & V3D_LIGHTING_STUDIO)
#define SHADOW_ENABLED(wpd) (wpd->drawtype_options & V3D_DRAWOPTION_SHADOW)
-
static char *workbench_build_defines(WORKBENCH_PrivateData *wpd)
{
char *str = NULL;
@@ -220,8 +220,6 @@ 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.light_multiplier = 1.0;
- e_data.shadow_multiplier = 0.8;
e_data.shadow_sh = DRW_shader_create(datatoc_workbench_shadow_vert_glsl, datatoc_workbench_shadow_geom_glsl, NULL, NULL);
}
@@ -320,6 +318,8 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL);
DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data);
+ e_data.light_multiplier = 1.0;
+ e_data.shadow_multiplier = BKE_collection_engine_property_value_get_float(props, "ambient_light_intensity");
copy_v3_v3(e_data.light_direction, BKE_collection_engine_property_value_get_float_array(props, "light_direction"));
negate_v3(e_data.light_direction);
@@ -331,14 +331,14 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
if (SHADOW_ENABLED(wpd)) {
-#ifdef SHOW_SHADOW_VOLUME
- psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR );
+#ifdef DEBUG_SHADOW_VOLUME
+ psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
DRW_shgroup_stencil_mask(grp, 0xFF);
wpd->shadow_shgrp = grp;
#else
- psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_INCR_DECR_WRAP);
+ psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP);
grp = DRW_shgroup_create(e_data.shadow_sh, psl->shadow_pass);
DRW_shgroup_uniform_vec3(grp, "lightDirection", e_data.light_direction, 1);
DRW_shgroup_stencil_mask(grp, 0xFF);
@@ -468,7 +468,7 @@ void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob
}
if (SHADOW_ENABLED(wpd)) {
- struct Gwn_Batch *geom_shadow = DRW_cache_mesh_wire_outline_get(ob);
+ struct Gwn_Batch *geom_shadow = DRW_cache_object_surface_get(ob);
if (geom_shadow) {
DRW_shgroup_call_object_add(wpd->shadow_shgrp, geom_shadow, ob);
}
@@ -508,7 +508,7 @@ void workbench_materials_draw_scene(WORKBENCH_Data *vedata)
GPU_framebuffer_bind(fbl->prepass_fb);
DRW_draw_pass(psl->prepass_pass);
if (SHADOW_ENABLED(wpd)) {
-#ifdef SHOW_SHADOW_VOLUME
+#ifdef DEBUG_SHADOW_VOLUME
GPU_framebuffer_bind(dfbl->default_fb);
DRW_draw_pass(psl->composite_pass);
DRW_draw_pass(psl->shadow_pass);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ba7a5f3e75a..7fd9030bc25 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -272,7 +272,7 @@ typedef enum {
DRW_STATE_WRITE_STENCIL = (1 << 27),
DRW_STATE_STENCIL_EQUAL = (1 << 28),
DRW_STATE_STENCIL_NEQUAL = (1 << 29),
- DRW_STATE_STENCIL_INCR_DECR_WRAP = (1 << 30),
+ DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP = (1 << 30),
} DRWState;
#define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS)
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 4d063aedf7e..77b83ab4e99 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -275,7 +275,7 @@ void drw_state_set(DRWState state)
DRWState test;
if (CHANGED_ANY_STORE_VAR(
DRW_STATE_WRITE_STENCIL |
- DRW_STATE_STENCIL_INCR_DECR_WRAP |
+ DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP |
DRW_STATE_STENCIL_EQUAL |
DRW_STATE_STENCIL_NEQUAL,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list