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:
authorJeroen Bakker <j.bakker@atmind.nl>2018-05-04 15:07:00 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2018-05-04 15:08:40 +0300
commit3f95daa31fa98b1bd67fc71835f0011287c1d136 (patch)
tree6b171179a5da5ca9b6326bfa5cb56ae7979aeda5 /source/blender
parentd8a03c77d796db4ae2546fbcbe230dbf4846b0ea (diff)
Workbench: Shadows
Initial review of the shard shadows in the workbench engine. Speed optimizations like transform feedback are not implemented yet. I first want this part to be reviewed and merged. @fclem please check the note in drw_stencil_set it was holding back nequal == 0 as by default DST.stencil_mask was set to 0. questioin is should we remove the whole check or not. Also I am still looking for a better name (or split the enum) for DRW_STATE_STENCIL_DEPTH_FAIL_INCR_DECR_WRAP Reviewers: fclem Reviewed By: fclem Tags: #code_quest Differential Revision: https://developer.blender.org/D3198
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenloader/intern/versioning_280.c5
-rw-r--r--source/blender/draw/CMakeLists.txt2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl6
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl51
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl23
-rw-r--r--source/blender/draw/engines/workbench/solid_mode.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c149
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h7
-rw-r--r--source/blender/draw/intern/DRW_render.h7
-rw-r--r--source/blender/draw/intern/draw_manager.h2
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c20
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_layer.c57
-rw-r--r--source/blender/makesrna/intern/rna_space.c15
16 files changed, 261 insertions, 96 deletions
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 07f51dfbc2f..b0cfadacb2c 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1068,6 +1068,11 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+ if (sl->spacetype == SPACE_VIEW3D) {
+ View3D *v3d = (View3D *)sl;
+ v3d->drawtype_ambient_intensity = 0.5;
+ v3d->overlays |= V3D_OVERLAY_HIDE_CURSOR;
+ }
}
}
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index e3b6e6fb1f9..3c4d7da29fb 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -212,6 +212,8 @@ data_to_c_simple(engines/eevee/shaders/volumetric_integration_frag.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)
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_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)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
index 38211239d01..b032bb6a7b5 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
@@ -6,8 +6,8 @@ uniform sampler2D colorBuffer;
uniform sampler2D normalBuffer;
/* normalBuffer contains viewport normals */
uniform vec2 invertedViewportSize;
-
uniform vec3 objectOverlapColor = vec3(0.0);
+uniform float lightMultiplier;
layout(std140) uniform world_block {
WorldData world_data;
@@ -52,11 +52,11 @@ void main()
vec3 normal_viewport = texelFetch(normalBuffer, texel, 0).rgb;
#endif /* WORKBENCH_ENCODE_NORMALS */
vec3 diffuse_light = get_world_diffuse_light(world_data, normal_viewport);
- vec3 shaded_color = diffuse_light * diffuse_color.rgb;
+ vec3 shaded_color = diffuse_light * diffuse_color.rgb * lightMultiplier;
#else /* V3D_LIGHTING_STUDIO */
vec3 diffuse_color = texelFetch(colorBuffer, texel, 0).rgb;
- vec3 shaded_color = diffuse_color;
+ vec3 shaded_color = diffuse_color * lightMultiplier;
#endif /* V3D_LIGHTING_STUDIO */
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
new file mode 100644
index 00000000000..a1abfb3fe1c
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_geom.glsl
@@ -0,0 +1,51 @@
+layout(triangles) in;
+layout(triangle_strip, max_vertices=9) out;
+
+uniform mat4 ModelMatrix;
+uniform mat4 ModelViewProjectionMatrix;
+
+uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
+
+in VertexData {
+ flat vec4 lightDirectionMS;
+ vec4 frontPosition;
+ vec4 backPosition;
+} vertexData[];
+
+vec3 face_normal(vec3 v1, vec3 v2, vec3 v3) {
+ return normalize(cross(v2 - v1, v3 - v1));
+}
+void main()
+{
+ vec4 light_direction = vertexData[0].lightDirectionMS;
+ 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.xyz) > 0.0;
+
+ int index0 = backface?0:2;
+ int index2 = backface?2:0;
+
+ /* back cap */
+ gl_Position = vertexData[index0].backPosition;
+ EmitVertex();
+ gl_Position = vertexData[1].backPosition;
+ EmitVertex();
+ gl_Position = vertexData[index2].backPosition;
+ EmitVertex();
+
+ /* sides */
+ gl_Position = vertexData[index2].frontPosition;
+ EmitVertex();
+ gl_Position = vertexData[index0].backPosition;
+ EmitVertex();
+ gl_Position = vertexData[index0].frontPosition;
+ EmitVertex();
+ gl_Position = vertexData[1].backPosition;
+ EmitVertex();
+ gl_Position = vertexData[1].frontPosition;
+ EmitVertex();
+ gl_Position = vertexData[index2].frontPosition;
+ EmitVertex();
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
new file mode 100644
index 00000000000..7322266a956
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl
@@ -0,0 +1,23 @@
+#define EPSILON 0.000001
+#define INFINITE 100.0
+
+uniform mat4 ModelMatrixInverse;
+uniform mat4 ModelViewProjectionMatrix;
+uniform vec3 lightDirection = vec3(0.57, 0.57, -0.57);
+
+in vec4 pos;
+
+out VertexData {
+ flat vec4 lightDirectionMS;
+ vec4 frontPosition;
+ vec4 backPosition;
+} vertexData;
+
+void main()
+{
+ gl_Position = pos;
+ vertexData.lightDirectionMS = normalize(ModelMatrixInverse * vec4(lightDirection, 0.0));
+ vertexData.lightDirectionMS.w = 0.0;
+ vertexData.frontPosition = ModelViewProjectionMatrix * (pos + vertexData.lightDirectionMS * EPSILON);
+ vertexData.backPosition = ModelViewProjectionMatrix * (pos + vertexData.lightDirectionMS * INFINITE);
+}
diff --git a/source/blender/draw/engines/workbench/solid_mode.c b/source/blender/draw/engines/workbench/solid_mode.c
index 2a1b5eecc27..c001cd13bb8 100644
--- a/source/blender/draw/engines/workbench/solid_mode.c
+++ b/source/blender/draw/engines/workbench/solid_mode.c
@@ -59,8 +59,10 @@ static void workbench_solid_cache_finish(void *vedata)
workbench_materials_cache_finish(data);
}
-static void workbench_solid_draw_background(void *UNUSED(vedata))
+static void workbench_solid_draw_background(void *vedata)
{
+ WORKBENCH_Data * data = (WORKBENCH_Data *)vedata;
+ workbench_materials_draw_background(data);
}
static void workbench_solid_draw_scene(void *vedata)
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index f758918d577..40d5c2b12f9 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -58,7 +58,9 @@ static void workbench_view_layer_settings_create(RenderEngine *UNUSED(engine), I
BLI_assert(props &&
props->type == IDP_GROUP &&
props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
- UNUSED_VARS_NDEBUG(props);
+
+ const float light_direction[3] = {-0.577350269, -0.577350269, 0.577350269};
+ BKE_collection_engine_property_add_float_array(props, "light_direction", light_direction, 3); UNUSED_VARS_NDEBUG(props);
}
/* 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 69d983b96c7..04a12d992b3 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -25,8 +25,9 @@
#include "workbench_private.h"
-#include "BLI_dynstr.h"
#include "BLI_alloca.h"
+#include "BLI_dynstr.h"
+#include "BLI_utildefines.h"
#include "BKE_particle.h"
@@ -37,23 +38,31 @@
#include "UI_resources.h"
/* *********** STATIC *********** */
+
+// #define DEBUG_SHADOW_VOLUME
#define MAX_SHADERS 255
+
static struct {
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
struct GPUShader *composite_sh_cache[MAX_SHADERS];
+ struct GPUShader *shadow_sh;
struct GPUTexture *object_id_tx; /* ref only, not alloced */
struct GPUTexture *color_buffer_tx; /* ref only, not alloced */
struct GPUTexture *normal_buffer_tx; /* ref only, not alloced */
+ float light_direction[3]; /* world light direction for shadows */
int next_object_id;
-} e_data = {{NULL}};
+} e_data = {NULL};
/* Shaders */
extern char datatoc_workbench_prepass_vert_glsl[];
extern char datatoc_workbench_prepass_frag_glsl[];
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_background_lib_glsl[];
extern char datatoc_workbench_common_lib_glsl[];
extern char datatoc_workbench_data_lib_glsl[];
@@ -64,7 +73,7 @@ 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;
@@ -127,7 +136,8 @@ static char *workbench_build_prepass_frag(void)
static int get_shader_index(WORKBENCH_PrivateData *wpd)
{
- return (wpd->drawtype_options << 2) + wpd->drawtype_lighting;
+ const int DRAWOPTIONS_MASK = V3D_DRAWOPTION_OBJECT_OVERLAP;
+ return ((wpd->drawtype_options & DRAWOPTIONS_MASK) << 2) + wpd->drawtype_lighting;
}
static void select_deferred_shaders(WORKBENCH_PrivateData *wpd)
@@ -209,6 +219,7 @@ 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);
}
if (!stl->g_data) {
@@ -248,6 +259,22 @@ 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);
+}
+
+static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingGroup *grp)
+{
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
+ if (OBJECT_ID_PASS_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
+ }
+ if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
+ DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
+ }
+ DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
+ DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
}
void workbench_materials_cache_init(WORKBENCH_Data *vedata)
@@ -255,8 +282,12 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
WORKBENCH_StorageList *stl = vedata->stl;
WORKBENCH_PassList *psl = vedata->psl;
WORKBENCH_PrivateData *wpd = stl->g_data;
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DRWShadingGroup *grp;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_WORKBENCH);
+ static float light_multiplier = 1.0f;
+
const DRWContextState *DCS = DRW_context_state_get();
wpd->material_hash = BLI_ghash_ptr_new(__func__);
@@ -266,11 +297,13 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
wpd->drawtype_lighting = v3d->drawtype_lighting;
wpd->drawtype_options = v3d->drawtype_options;
wpd->drawtype_studiolight = v3d->drawtype_studiolight;
+ wpd->drawtype_ambient_intensity = v3d->drawtype_ambient_intensity;
}
else {
wpd->drawtype_lighting = V3D_LIGHTING_STUDIO;
wpd->drawtype_options = 0;
wpd->drawtype_studiolight = 0;
+ wpd->drawtype_ambient_intensity = 0.5;
}
select_deferred_shaders(wpd);
@@ -281,25 +314,49 @@ void workbench_materials_cache_init(WORKBENCH_Data *vedata)
UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
studiolight_update_world(wpd->drawtype_studiolight, wd);
- psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
- DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
- }
- if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
- DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
- }
wpd->world_ubo = DRW_uniformbuffer_create(sizeof(WORKBENCH_UBO_World), NULL);
- DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
DRW_uniformbuffer_update(wpd->world_ubo, &wpd->world_data);
- DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
- DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ copy_v3_v3(e_data.light_direction, BKE_collection_engine_property_value_get_float_array(props, "light_direction"));
+ negate_v3(e_data.light_direction);
+
+ if (SHADOW_ENABLED(wpd)) {
+ psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL);
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_stencil_mask(grp, 0x00);
+ DRW_shgroup_uniform_float(grp, "lightMultiplier", &light_multiplier, 1);
+ 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.light_direction, 1);
+ DRW_shgroup_stencil_mask(grp, 0xFF);
+ wpd->shadow_shgrp = grp;
+#else
+ psl->shadow_pass = DRW_pass_create("Shadow", DRW_STATE_DEPTH_GREATER | DRW_STATE_WRITE_STENCIL_SHADOW);
+ 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;
+
+ 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);
+ DRW_shgroup_stencil_mask(grp, 0x00);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_uniform_float(grp, "lightMultiplier", &wpd->drawtype_ambient_intensity, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+#endif
+ }
+ else {
+ psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
+ grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
+ workbench_composite_uniforms(wpd, grp);
+ DRW_shgroup_uniform_float(grp, "lightMultiplier", &light_multiplier, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
}
-
-
}
static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedata, IDProperty *props, Object *ob, Material *mat)
{
@@ -324,6 +381,7 @@ static WORKBENCH_MaterialData *get_or_create_material_data(WORKBENCH_Data *vedat
if (material == NULL) {
material = MEM_mallocN(sizeof(WORKBENCH_MaterialData), __func__);
material->shgrp = DRW_shgroup_create(wpd->prepass_sh, psl->prepass_pass);
+ DRW_shgroup_stencil_mask(material->shgrp, 0xFF);
material->object_id = engine_object_data->object_id;
copy_v3_v3(material->color, material_template.color);
DRW_shgroup_uniform_vec3(material->shgrp, "object_color", material->color, 1);
@@ -366,6 +424,9 @@ static void workbench_cache_populate_particles(WORKBENCH_Data *vedata, IDPropert
void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
{
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+
if (!DRW_object_is_renderable(ob))
return;
@@ -409,6 +470,13 @@ void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob
}
}
}
+
+ if (SHADOW_ENABLED(wpd)) {
+ 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);
+ }
+ }
}
}
@@ -416,6 +484,22 @@ void workbench_materials_cache_finish(WORKBENCH_Data *UNUSED(vedata))
{
}
+void workbench_materials_draw_background(WORKBENCH_Data *vedata)
+{
+ WORKBENCH_StorageList *stl = vedata->stl;
+ WORKBENCH_FramebufferList *fbl = vedata->fbl;
+ WORKBENCH_PrivateData *wpd = stl->g_data;
+ const float clear_depth = 1.0f;
+ const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ unsigned int clear_stencil = 0xFF;
+
+ GPU_framebuffer_bind(fbl->prepass_fb);
+ int clear_bits = GPU_DEPTH_BIT;
+ SET_FLAG_FROM_TEST(clear_bits, OBJECT_ID_PASS_ENABLED(wpd), GPU_COLOR_BIT);
+ SET_FLAG_FROM_TEST(clear_bits, SHADOW_ENABLED(wpd), GPU_STENCIL_BIT);
+ GPU_framebuffer_clear(fbl->prepass_fb, clear_bits, clear_color, clear_depth, clear_stencil);
+}
+
void workbench_materials_draw_scene(WORKBENCH_Data *vedata)
{
WORKBENCH_PassList *psl = vedata->psl;
@@ -423,20 +507,27 @@ void workbench_materials_draw_scene(WORKBENCH_Data *vedata)
WORKBENCH_FramebufferList *fbl = vedata->fbl;
WORKBENCH_PrivateData *wpd = stl->g_data;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- const float clear_depth = 1.0f;
+ /* clear in background */
GPU_framebuffer_bind(fbl->prepass_fb);
- if (OBJECT_ID_PASS_ENABLED(wpd)) {
- const float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_clear_color_depth(fbl->prepass_fb, clear_color, clear_depth);
+ DRW_draw_pass(psl->prepass_pass);
+ if (SHADOW_ENABLED(wpd)) {
+#ifdef DEBUG_SHADOW_VOLUME
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_draw_pass(psl->composite_pass);
+ DRW_draw_pass(psl->shadow_pass);
+#else
+ GPU_framebuffer_bind(dfbl->depth_only_fb);
+ DRW_draw_pass(psl->shadow_pass);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_draw_pass(psl->composite_pass);
+ DRW_draw_pass(psl->composite_shadow_pass);
+#endif
}
else {
- GPU_framebuffer_clear_depth(fbl->prepass_fb, clear_depth);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_draw_pass(psl->composite_pass);
}
- DRW_draw_pass(psl->prepass_pass);
-
- GPU_framebuffer_bind(dfbl->color_only_fb);
- DRW_draw_pass(psl->composite_pass);
BLI_ghash_free(wpd->material_hash, NULL, MEM_freeN);
DRW_UBO_FREE_SAFE(wpd->world_ubo);
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 1f66fb31095..6b8acaebc82 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -44,7 +44,10 @@ typedef struct WORKBENCH_StorageList {
typedef struct WORKBENCH_PassList {
struct DRWPass *prepass_pass;
+ struct DRWPass *shadow_pass;
struct DRWPass *composite_pass;
+ struct DRWPass *composite_shadow_pass;
+ struct DRWPass *composite_light_pass;
} WORKBENCH_PassList;
typedef struct WORKBENCH_Data {
@@ -74,7 +77,10 @@ typedef struct WORKBENCH_PrivateData {
short drawtype_lighting;
short drawtype_options;
short drawtype_studiolight;
+ short pad;
+ float drawtype_ambient_intensity;
struct GPUUniformBuffer *world_ubo;
+ struct DRWShadingGroup *shadow_shgrp;
WORKBENCH_UBO_World world_data;
} WORKBENCH_PrivateData; /* Transient data */
@@ -109,6 +115,7 @@ void workbench_solid_materials_free(void);
/* workbench_materials.c */
void workbench_materials_engine_init(WORKBENCH_Data *vedata);
void workbench_materials_engine_free(void);
+void workbench_materials_draw_background(WORKBENCH_Data *vedata);
void workbench_materials_draw_scene(WORKBENCH_Data *vedata);
void workbench_materials_cache_init(WORKBENCH_Data *vedata);
void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob);
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 51fba1500f7..0912e5dde29 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -273,10 +273,11 @@ typedef enum {
DRW_STATE_ADDITIVE_FULL = (1 << 19), /* Same as DRW_STATE_ADDITIVE but let alpha accumulate without premult. */
DRW_STATE_BLEND_PREMUL = (1 << 20), /* Use that if color is already premult by alpha. */
- DRW_STATE_WRITE_STENCIL = (1 << 27),
- DRW_STATE_STENCIL_EQUAL = (1 << 28),
+ DRW_STATE_WRITE_STENCIL = (1 << 27),
+ DRW_STATE_WRITE_STENCIL_SHADOW = (1 << 28),
+ DRW_STATE_STENCIL_EQUAL = (1 << 29),
+ DRW_STATE_STENCIL_NEQUAL = (1 << 30),
} DRWState;
-
#define DRW_STATE_DEFAULT (DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS)
typedef enum {
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 00d7c7233a5..7a45b808651 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -262,7 +262,7 @@ typedef struct ViewUboStorage {
/* ------------- DRAW MANAGER ------------ */
#define MAX_CLIP_PLANES 6 /* GL_MAX_CLIP_PLANES is at least 6 */
-
+#define STENCIL_UNDEFINED 256
typedef struct DRWManager {
/* TODO clean up this struct a bit */
/* Cache generation */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index 232ae36438e..434c021775a 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -278,21 +278,27 @@ void drw_state_set(DRWState state)
DRWState test;
if (CHANGED_ANY_STORE_VAR(
DRW_STATE_WRITE_STENCIL |
- DRW_STATE_STENCIL_EQUAL,
+ DRW_STATE_WRITE_STENCIL_SHADOW |
+ DRW_STATE_STENCIL_EQUAL |
+ DRW_STATE_STENCIL_NEQUAL,
test))
{
if (test) {
glEnable(GL_STENCIL_TEST);
-
/* Stencil Write */
if ((state & DRW_STATE_WRITE_STENCIL) != 0) {
glStencilMask(0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
}
+ 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);
+ }
/* Stencil Test */
- else if ((state & DRW_STATE_STENCIL_EQUAL) != 0) {
+ else if ((state & (DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)) != 0) {
glStencilMask(0x00); /* disable write */
- DST.stencil_mask = 0;
+ DST.stencil_mask = STENCIL_UNDEFINED;
}
else {
BLI_assert(0);
@@ -318,15 +324,17 @@ void drw_state_set(DRWState state)
static void drw_stencil_set(unsigned int mask)
{
if (DST.stencil_mask != mask) {
+ DST.stencil_mask = mask;
/* Stencil Write */
if ((DST.state & DRW_STATE_WRITE_STENCIL) != 0) {
glStencilFunc(GL_ALWAYS, mask, 0xFF);
- DST.stencil_mask = mask;
}
/* Stencil Test */
else if ((DST.state & DRW_STATE_STENCIL_EQUAL) != 0) {
glStencilFunc(GL_EQUAL, mask, 0xFF);
- DST.stencil_mask = mask;
+ }
+ else if ((DST.state & DRW_STATE_STENCIL_NEQUAL) != 0) {
+ glStencilFunc(GL_NOTEQUAL, mask, 0xFF);
}
}
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index ceff9fb2851..6071b8d8e94 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -323,7 +323,7 @@ static SpaceLink *view3d_new(const ScrArea *UNUSED(sa), const Scene *scene)
v3d->gridsubdiv = 10;
v3d->drawtype = OB_SOLID;
v3d->drawtype_lighting = V3D_LIGHTING_STUDIO;
- v3d->overlays = 0;
+ v3d->drawtype_ambient_intensity = 0.5;
v3d->gridflag = V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_FLOOR;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 8b5c6f84f78..8021ed12e45 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -90,6 +90,7 @@ enum {
V3D_DRAWOPTION_OBJECT_OVERLAP = (1 << 1),
V3D_DRAWOPTION_SINGLE_COLOR = (1 << 2),
V3D_DRAWOPTION_OBJECT_COLOR = (1 << 4),
+ V3D_DRAWOPTION_SHADOW = (1 << 5),
};
#define V3D_DRAWOPTION_SOLID_COLOR_MASK (V3D_DRAWOPTION_SINGLE_COLOR | V3D_DRAWOPTION_RANDOMIZE | V3D_DRAWOPTION_OBJECT_COLOR | V3D_DRAWOPTION_MATERIAL_COLOR)
@@ -259,9 +260,9 @@ typedef struct View3D {
short drawtype_lighting;
short drawtype_options;
short drawtype_studiolight;
+ float drawtype_ambient_intensity;
int overlays;
- int pad6;
View3DDebug debug;
} View3D;
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 93df67306e3..e394680cddd 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -319,6 +319,9 @@ static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr,
#define RNA_LAYER_ENGINE_WORKBENCH_GET_SET_INT(_NAME_) \
RNA_LAYER_ENGINE_GET_SET(int, Workbench, COLLECTION_MODE_NONE, _NAME_)
+#define RNA_LAYER_ENGINE_WORKBENCH_GET_SET_BOOL(_NAME_) \
+ RNA_LAYER_ENGINE_GET_SET(bool, Workbench, COLLECTION_MODE_NONE, _NAME_)
+
/* mode engines */
#define RNA_LAYER_MODE_OBJECT_GET_SET_FLOAT(_NAME_) \
@@ -368,12 +371,7 @@ RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(hair_brightness_randomness)
RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT(random_object_color_saturation)
RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT(random_object_color_value)
/* View Layer settings */
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_x_pos, 3)
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_x_neg, 3)
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_y_pos, 3)
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_y_neg, 3)
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_z_pos, 3)
-RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(diffuse_light_z_neg, 3)
+RNA_LAYER_ENGINE_WORKBENCH_GET_SET_FLOAT_ARRAY(light_direction, 3)
/* eevee engine */
/* ViewLayer settings. */
@@ -1709,51 +1707,10 @@ static void rna_def_view_layer_engine_settings_workbench(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Workbench Scene Layer Settings", "Workbench Engine settings");
RNA_define_verify_sdna(0); /* not in sdna */
-
- prop = RNA_def_property(srna, "diffuse_light_x_pos", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_x_pos_get", "rna_LayerEngineSettings_Workbench_diffuse_light_x_pos_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse +X Light", "Diffuse light color in positive X direction");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
- RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
-
- prop = RNA_def_property(srna, "diffuse_light_x_neg", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_x_neg_get", "rna_LayerEngineSettings_Workbench_diffuse_light_x_neg_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse -X Light", "Diffuse light color in negative X direction");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
- RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
-
- prop = RNA_def_property(srna, "diffuse_light_y_pos", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_y_pos_get", "rna_LayerEngineSettings_Workbench_diffuse_light_y_pos_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse +Y Light", "Diffuse light color in positive Y direction");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
- RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
-
- prop = RNA_def_property(srna, "diffuse_light_y_neg", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_y_neg_get", "rna_LayerEngineSettings_Workbench_diffuse_light_y_neg_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse -Y Light", "Diffuse light color in negative Y direction");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
- RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
-
- prop = RNA_def_property(srna, "diffuse_light_z_pos", PROP_FLOAT, PROP_COLOR);
- RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_z_pos_get", "rna_LayerEngineSettings_Workbench_diffuse_light_z_pos_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse +Z Light", "Diffuse light color in positive Z direction");
- RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
- RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
-
- prop = RNA_def_property(srna, "diffuse_light_z_neg", PROP_FLOAT, PROP_COLOR);
+ prop = RNA_def_property(srna, "light_direction", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_array(prop, 3);
- RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_diffuse_light_z_neg_get", "rna_LayerEngineSettings_Workbench_diffuse_light_z_neg_set", NULL);
- RNA_def_property_ui_text(prop, "Diffuse -Z Light", "Diffuse light color in negative Z direction");
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Workbench_light_direction_get", "rna_LayerEngineSettings_Workbench_light_direction_set", NULL);
+ RNA_def_property_ui_text(prop, "Light Direction", "Direction of the light for shadow calculation");
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_ViewLayerEngineSettings_update");
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 60c4fc20f77..bb9c711838a 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -2249,6 +2249,21 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
NULL);
RNA_def_property_ui_text(prop, "Color", "Single Color Mode");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update");
+
+ prop = RNA_def_property(srna, "show_shadows", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "drawtype_options", V3D_DRAWOPTION_SHADOW);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Shadow", "Show Shadow");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update");
+
+ prop = RNA_def_property(srna, "ambient_light_intensity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "drawtype_ambient_intensity");
+ RNA_def_property_float_default(prop, 0.5);
+ RNA_def_property_ui_text(prop, "Ambient Light", "Intensity of ambient light for shadows");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_range(prop, 0.00f, 1.0f, 1, 3);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update");
}
static void rna_def_space_view3d_overlay(BlenderRNA *brna)