Workbench: Cleanups & Simplifications

* Move the curvature computation to the cavity pass: One can argue it's not
  the best performance wise (it gets a tiny perf pernalty if it is done
  alone without the ssao), but it make the code cleaner and reduce
  considerably the number of shader variation possible.
* Lower shader variation to 2^8 instead of 2^12
This commit is contained in:
Clément Foucault 2018-11-30 01:53:50 +01:00
parent e1023014f4
commit 6a4f5f6eb4
8 changed files with 127 additions and 112 deletions

View File

@ -3,6 +3,7 @@ out vec4 fragColor;
uniform sampler2D depthBuffer;
uniform sampler2D colorBuffer;
uniform sampler2D normalBuffer;
uniform usampler2D objectId;
uniform vec2 invertedViewportSize;
uniform mat4 WinMatrix; /* inverse WinMatrix */
@ -10,6 +11,7 @@ uniform mat4 WinMatrix; /* inverse WinMatrix */
uniform vec4 viewvecs[3];
uniform vec4 ssao_params;
uniform vec4 ssao_settings;
uniform vec2 curvature_settings;
uniform sampler2D ssao_jitter;
layout(std140) uniform samples_block {
@ -23,7 +25,7 @@ layout(std140) uniform samples_block {
#define ssao_distance ssao_settings.x
#define ssao_factor_cavity ssao_settings.y
#define ssao_factor_edge ssao_settings.z
#define ssao_attenuation ssao_settings.a
#define ssao_attenuation ssao_settings.w
vec3 get_view_space_from_depth(in vec2 uvcoords, in float depth)
{
@ -54,6 +56,9 @@ void main()
vec2 screenco = vec2(gl_FragCoord.xy) * invertedViewportSize;
ivec2 texel = ivec2(gl_FragCoord.xy);
float cavity = 0.0, edges = 0.0, curvature = 0.0;
#ifdef USE_CAVITY
float depth = texelFetch(depthBuffer, texel, 0).x;
vec3 position = get_view_space_from_depth(screenco, depth);
@ -63,8 +68,16 @@ void main()
normal_viewport = -normal_viewport;
}
float cavity = 0.0, edges = 0.0;
ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
fragColor = vec4(cavity, edges, 0.0, 1.0);
ssao_factors(depth, normal_viewport, position, screenco, cavity, edges);
#endif
#ifdef USE_CURVATURE
curvature = calculate_curvature(objectId, normalBuffer, texel, curvature_settings.x, curvature_settings.y);
#endif
float final_cavity_factor = clamp((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0);
/* Using UNORM render target so compress the range. */
fragColor = vec4(final_cavity_factor / CAVITY_BUFFER_RANGE);
}

View File

@ -2,6 +2,8 @@
#define EPSILON 0.00001
#define M_PI 3.14159265358979323846
#define CAVITY_BUFFER_RANGE 4.0
/* 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](

View File

@ -4,37 +4,40 @@
float curvature_soft_clamp(float curvature, float control)
{
if (curvature < 0.5 / control)
return curvature * (1.0 - curvature * control);
return 0.25 / control;
if (curvature < 0.5 / control) {
return curvature * (1.0 - curvature * control);
}
return 0.25 / control;
}
float calculate_curvature(usampler2D objectId, sampler2D normalBuffer, ivec2 texel, float ridge, float valley)
{
uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r;
uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r;
uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r;
uint object_right = texelFetchOffset(objectId, texel, 0, ivec2( CURVATURE_OFFSET, 0)).r;
uint object_up = texelFetchOffset(objectId, texel, 0, ivec2(0, CURVATURE_OFFSET)).r;
uint object_down = texelFetchOffset(objectId, texel, 0, ivec2(0, -CURVATURE_OFFSET)).r;
uint object_left = texelFetchOffset(objectId, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).r;
uint object_right = texelFetchOffset(objectId, texel, 0, ivec2( CURVATURE_OFFSET, 0)).r;
if((object_up != object_down) || (object_right != object_left)) {
return 0.0;
}
if((object_up != object_down) || (object_right != object_left)) {
return 0.0;
}
vec2 normal_up = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, CURVATURE_OFFSET)).rg;
vec2 normal_down = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, -CURVATURE_OFFSET)).rg;
vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg;
vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg;
vec2 normal_up = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, CURVATURE_OFFSET)).rg;
vec2 normal_down = texelFetchOffset(normalBuffer, texel, 0, ivec2(0, -CURVATURE_OFFSET)).rg;
vec2 normal_left = texelFetchOffset(normalBuffer, texel, 0, ivec2(-CURVATURE_OFFSET, 0)).rg;
vec2 normal_right = texelFetchOffset(normalBuffer, texel, 0, ivec2( CURVATURE_OFFSET, 0)).rg;
#ifdef WORKBENCH_ENCODE_NORMALS
normal_up = normal_decode(normal_up ).rg;
normal_down = normal_decode(normal_down ).rg;
normal_left = normal_decode(normal_left ).rg;
normal_right = normal_decode(normal_right).rg;
normal_up = normal_decode(normal_up ).rg;
normal_down = normal_decode(normal_down ).rg;
normal_left = normal_decode(normal_left ).rg;
normal_right = normal_decode(normal_right).rg;
#endif
float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r));
float normal_diff = ((normal_up.g - normal_down.g) + (normal_right.r - normal_left.r));
if (normal_diff < 0)
return -2.0 * curvature_soft_clamp(-normal_diff, valley);
return 2.0 * curvature_soft_clamp(normal_diff, ridge);
if (normal_diff < 0) {
return -2.0 * curvature_soft_clamp(-normal_diff, valley);
}
return 2.0 * curvature_soft_clamp(normal_diff, ridge);
}

View File

@ -74,9 +74,8 @@ void main()
#elif defined(V3D_LIGHTING_MATCAP)
bool flipped = world_data.matcap_orientation != 0;
vec2 matcap_uv = matcap_uv_compute(I_vs, normal_viewport, flipped);
vec3 object_color = texelFetch(specularBuffer, texel, 0).rgb;
vec3 matcap = textureLod(matcapImage, matcap_uv, 0.0).rgb;
vec3 shaded_color = matcap * object_color;
vec3 shaded_color = matcap * diffuse_color.rgb;
#elif defined(V3D_LIGHTING_STUDIO)
@ -91,15 +90,9 @@ void main()
#endif
/* -------- POST EFFECTS --------- */
#ifdef V3D_SHADING_SSAO
vec2 cavity = texelFetch(cavityBuffer, texel, 0).rg;
shaded_color *= 1.0 - cavity.x;
shaded_color *= 1.0 + cavity.y;
#endif
#ifdef V3D_SHADING_CURVATURE
float curvature = calculate_curvature(objectId, normalBuffer, texel, world_data.curvature_ridge, world_data.curvature_valley);
shaded_color *= curvature + 1.0;
#ifdef WB_CAVITY
/* Using UNORM texture so decompress the range */
shaded_color *= texelFetch(cavityBuffer, texel, 0).r * CAVITY_BUFFER_RANGE;
#endif
#ifdef V3D_SHADING_SHADOW

View File

@ -24,7 +24,9 @@ flat in float hair_rand;
layout(location=0) out uint objectId;
layout(location=1) out vec4 diffuseColor;
#ifdef V3D_SHADING_SPECULAR_HIGHLIGHT
layout(location=2) out vec4 specularColor;
#endif
#ifdef NORMAL_VIEWPORT_PASS_ENABLED
# ifdef WORKBENCH_ENCODE_NORMALS
layout(location=3) out vec2 normalViewport;
@ -49,10 +51,6 @@ void main()
}
#else
diffuseColor = vec4(materialDiffuseColor.rgb, 0.0);
# ifdef STUDIOLIGHT_TYPE_MATCAP
specularColor = vec4(materialDiffuseColor.rgb, 0.0);
# endif
#endif /* V3D_SHADING_TEXTURE_COLOR */
#ifdef HAIR_SHADER

View File

@ -59,7 +59,7 @@
static struct {
struct GPUShader *prepass_sh_cache[MAX_SHADERS];
struct GPUShader *composite_sh_cache[MAX_SHADERS];
struct GPUShader *cavity_sh;
struct GPUShader *cavity_sh[MAX_CAVITY_SHADERS];
struct GPUShader *ghost_resolve_sh;
struct GPUShader *shadow_fail_sh;
struct GPUShader *shadow_fail_manifold_sh;
@ -167,13 +167,23 @@ static char *workbench_build_prepass_vert(bool is_hair)
return str;
}
static char *workbench_build_cavity_frag(void)
static char *workbench_build_cavity_frag(bool cavity, bool curvature, bool high_dpi)
{
char *str = NULL;
DynStr *ds = BLI_dynstr_new();
if (cavity) {
BLI_dynstr_append(ds, "#define USE_CAVITY\n");
}
if (curvature) {
BLI_dynstr_append(ds, "#define USE_CURVATURE\n");
}
if (high_dpi) {
BLI_dynstr_append(ds, "#define CURVATURE_OFFSET 2\n");
}
BLI_dynstr_append(ds, datatoc_workbench_common_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_curvature_lib_glsl);
BLI_dynstr_append(ds, datatoc_workbench_cavity_frag_glsl);
BLI_dynstr_append(ds, datatoc_workbench_cavity_lib_glsl);
@ -182,6 +192,23 @@ static char *workbench_build_cavity_frag(void)
return str;
}
static GPUShader *workbench_cavity_shader_get(bool cavity, bool curvature)
{
const bool high_dpi = (U.pixelsize > 1.5f);
int index = 0;
SET_FLAG_FROM_TEST(index, cavity, 1 << 0);
SET_FLAG_FROM_TEST(index, curvature, 1 << 1);
SET_FLAG_FROM_TEST(index, high_dpi, 1 << 2);
GPUShader **sh = &e_data.cavity_sh[index];
if (*sh == NULL) {
char *cavity_frag = workbench_build_cavity_frag(cavity, curvature, high_dpi);
*sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
MEM_freeN(cavity_frag);
}
return *sh;
}
static void ensure_deferred_shaders(WORKBENCH_PrivateData *wpd, int index, bool use_textures, bool is_hair)
{
if (e_data.prepass_sh_cache[index] == NULL) {
@ -303,6 +330,7 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
#else
const char *shadow_frag = datatoc_gpu_shader_depth_only_frag_glsl;
#endif
/* TODO only compile on demand */
e_data.shadow_pass_sh = DRW_shader_create(
datatoc_workbench_shadow_vert_glsl,
datatoc_workbench_shadow_geom_glsl,
@ -337,10 +365,6 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
shadow_frag,
"#define SHADOW_FAIL\n");
char *cavity_frag = workbench_build_cavity_frag();
e_data.cavity_sh = DRW_shader_create_fullscreen(cavity_frag, NULL);
MEM_freeN(cavity_frag);
e_data.ghost_resolve_sh = DRW_shader_create_fullscreen(datatoc_workbench_ghost_resolve_frag_glsl, NULL);
}
workbench_volume_engine_init();
@ -353,21 +377,13 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
{
const float *viewport_size = DRW_viewport_size_get();
const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
const GPUTextureFormat nor_tex_format = NORMAL_ENCODING_ENABLED() ? GPU_RG16 : GPU_RGBA32F;
e_data.object_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R32UI, &draw_engine_workbench_solid);
e_data.color_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], nor_tex_format, &draw_engine_workbench_solid);
e_data.cavity_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16, &draw_engine_workbench_solid);
e_data.specular_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8, &draw_engine_workbench_solid);
e_data.composite_buffer_tx = DRW_texture_pool_query_2D(
size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
if (NORMAL_ENCODING_ENABLED()) {
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(
size[0], size[1], GPU_RG16, &draw_engine_workbench_solid);
}
else {
e_data.normal_buffer_tx = DRW_texture_pool_query_2D(
size[0], size[1], GPU_RGBA32F, &draw_engine_workbench_solid);
}
e_data.composite_buffer_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA16F, &draw_engine_workbench_solid);
GPU_framebuffer_ensure_config(&fbl->prepass_fb, {
GPU_ATTACHMENT_TEXTURE(dtxl->depth),
@ -438,21 +454,30 @@ void workbench_deferred_engine_init(WORKBENCH_Data *vedata)
workbench_aa_create_pass(vedata, &e_data.color_buffer_tx);
}
{
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
int state = DRW_STATE_WRITE_COLOR;
GPUShader *shader = workbench_cavity_shader_get(SSAO_ENABLED(wpd), CURVATURE_ENABLED(wpd));
psl->cavity_pass = DRW_pass_create("Cavity", state);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.cavity_sh, psl->cavity_pass);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
DRWShadingGroup *grp = DRW_shgroup_create(shader, psl->cavity_pass);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
DRW_shgroup_uniform_block(grp, "samples_block", e_data.sampling_ubo);
if (SSAO_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &e_data.color_buffer_tx);
DRW_shgroup_uniform_vec2(grp, "invertedViewportSize", DRW_viewport_invert_size_get(), 1);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
DRW_shgroup_uniform_vec4(grp, "ssao_params", wpd->ssao_params, 1);
DRW_shgroup_uniform_vec4(grp, "ssao_settings", wpd->ssao_settings, 1);
DRW_shgroup_uniform_mat4(grp, "WinMatrix", wpd->winmat);
DRW_shgroup_uniform_texture(grp, "ssao_jitter", e_data.jitter_tx);
}
if (CURVATURE_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "objectId", &e_data.object_id_tx);
DRW_shgroup_uniform_vec2(grp, "curvature_settings", &wpd->world_data.curvature_ridge, 1);
}
DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@ -478,7 +503,9 @@ void workbench_deferred_engine_free(void)
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.cavity_sh);
for (int index = 0; index < MAX_CAVITY_SHADERS; ++index) {
DRW_SHADER_FREE_SAFE(e_data.cavity_sh[index]);
}
DRW_SHADER_FREE_SAFE(e_data.ghost_resolve_sh);
DRW_UBO_FREE_SAFE(e_data.sampling_ubo);
DRW_TEXTURE_FREE_SAFE(e_data.jitter_tx);
@ -502,11 +529,13 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
if (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &e_data.normal_buffer_tx);
}
if (SSAO_ENABLED(wpd)) {
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "cavityBuffer", &e_data.cavity_buffer_tx);
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || MATCAP_ENABLED(wpd)) {
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
DRW_shgroup_uniform_texture_ref(grp, "specularBuffer", &e_data.specular_buffer_tx);
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd) || STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)wpd->viewvecs, 3);
}
DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
@ -514,7 +543,7 @@ static void workbench_composite_uniforms(WORKBENCH_PrivateData *wpd, DRWShadingG
if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
BKE_studiolight_ensure_flag(wpd->studio_light, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture );
DRW_shgroup_uniform_texture(grp, "matcapImage", wpd->studio_light->equirect_radiance_gputexture);
}
}
@ -902,7 +931,7 @@ void workbench_deferred_draw_scene(WORKBENCH_Data *vedata)
DRW_draw_pass(psl->ghost_resolve_pass);
}
if (SSAO_ENABLED(wpd)) {
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
GPU_framebuffer_bind(fbl->cavity_fb);
DRW_draw_pass(psl->cavity_pass);
}

View File

@ -59,17 +59,8 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
if (wpd->shading.flag & V3D_SHADING_SHADOW) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SHADOW\n");
}
if (SSAO_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SSAO\n");
}
if (CURVATURE_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_CURVATURE\n");
if (U.pixelsize > 1.5f) {
BLI_dynstr_appendf(ds, "#define CURVATURE_OFFSET 2\n");
}
else {
BLI_dynstr_appendf(ds, "#define CURVATURE_OFFSET 1\n");
}
if (SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define WB_CAVITY\n");
}
if (SPECULAR_HIGHLIGHT_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_SHADING_SPECULAR_HIGHLIGHT\n");
@ -83,15 +74,6 @@ char *workbench_material_build_defines(WORKBENCH_PrivateData *wpd, bool use_text
if (MATCAP_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define V3D_LIGHTING_MATCAP\n");
}
if (STUDIOLIGHT_TYPE_WORLD_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_TYPE_WORLD\n");
}
if (STUDIOLIGHT_TYPE_STUDIO_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_TYPE_STUDIO\n");
}
if (STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define STUDIOLIGHT_TYPE_MATCAP\n");
}
if (NORMAL_VIEWPORT_PASS_ENABLED(wpd)) {
BLI_dynstr_appendf(ds, "#define NORMAL_VIEWPORT_PASS_ENABLED\n");
}
@ -147,21 +129,15 @@ int workbench_material_get_shader_index(WORKBENCH_PrivateData *wpd, bool use_tex
int index = 0;
/* 1 bit V3D_SHADING_TEXTURE_COLOR */
SET_FLAG_FROM_TEST(index, use_textures, 1 << 0);
/* 2 bits FLAT/STUDIO/MATCAP/SCENE */
SET_FLAG_FROM_TEST(index, wpd->shading.light, wpd->shading.light << 1);
/* 1 bit V3D_SHADING_SPECULAR_HIGHLIGHT */
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT, 1 << 3);
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 4);
SET_FLAG_FROM_TEST(index, SSAO_ENABLED(wpd), 1 << 5);
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 6);
bool uses_curvature = CURVATURE_ENABLED(wpd);
SET_FLAG_FROM_TEST(index, uses_curvature, 1 << 7);
SET_FLAG_FROM_TEST(index, uses_curvature && (U.pixelsize > 1.5f), 1 << 8);
/* 2 bits STUDIOLIGHT_ORIENTATION */
SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_TYPE_WORLD, 1 << 9);
SET_FLAG_FROM_TEST(index, wpd->studio_light->flag & STUDIOLIGHT_TYPE_MATCAP, 1 << 10);
/* 2 bits FLAT/STUDIO/MATCAP + Specular highlight */
int ligh_flag = SPECULAR_HIGHLIGHT_ENABLED(wpd) ? 3 : wpd->shading.light;
SET_FLAG_FROM_TEST(index, wpd->shading.light, ligh_flag << 1);
/* 3 bits for flags */
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_SHADOW, 1 << 3);
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_CAVITY, 1 << 4);
SET_FLAG_FROM_TEST(index, wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE, 1 << 5);
/* 1 bit for hair */
SET_FLAG_FROM_TEST(index, is_hair, 1 << 11);
SET_FLAG_FROM_TEST(index, is_hair, 1 << 6);
return index;
}

View File

@ -40,7 +40,8 @@
#define WORKBENCH_ENGINE "BLENDER_WORKBENCH"
#define M_GOLDEN_RATION_CONJUGATE 0.618033988749895
#define MAX_SHADERS (1 << 12)
#define MAX_SHADERS (1 << 7)
#define MAX_CAVITY_SHADERS (1 << 3)
#define TEXTURE_DRAWING_ENABLED(wpd) (wpd->shading.color_type & V3D_SHADING_TEXTURE_COLOR)
#define FLAT_ENABLED(wpd) (wpd->shading.light == V3D_LIGHTING_FLAT)
@ -63,8 +64,8 @@
#define SPECULAR_HIGHLIGHT_ENABLED(wpd) (STUDIOLIGHT_ENABLED(wpd) && (wpd->shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT) && (!STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)))
#define OBJECT_OUTLINE_ENABLED(wpd) (wpd->shading.flag & V3D_SHADING_OBJECT_OUTLINE)
#define OBJECT_ID_PASS_ENABLED(wpd) (OBJECT_OUTLINE_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd) || SPECULAR_HIGHLIGHT_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || SSAO_ENABLED(wpd))
#define NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) (MATCAP_ENABLED(wpd) || STUDIOLIGHT_ENABLED(wpd) || SHADOW_ENABLED(wpd))
#define NORMAL_VIEWPORT_PASS_ENABLED(wpd) (NORMAL_VIEWPORT_COMP_PASS_ENABLED(wpd) || SSAO_ENABLED(wpd) || CURVATURE_ENABLED(wpd))
#define NORMAL_ENCODING_ENABLED() (true)