Workbench: Fix: Performance Regressions
Optimize Workbench performance so it's on par with the previous implementation. Most of these changes are barely noticeable on powerful GPUs, but can cause a notable performance improvement on old or low-end hardware. * Avoid unnecessary texture copies and draw directly to the viewport textures. * Optimize-out depth/stencil reads, using stencil testing instead. * Avoid using `Texture::clear` and use framebuffer clears instead. * Avoid framebuffer state changes (always use the same attachments). * Avoid constant variation of acquired `TextureFromPool`s. Fix #113010 Pull Request: https://projects.blender.org/blender/blender/pulls/113251
This commit is contained in:
parent
1a30e0597b
commit
fe39456ba5
|
@ -10,10 +10,9 @@
|
|||
* \{ */
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_composite)
|
||||
.sampler(3, ImageType::FLOAT_2D, "normal_tx")
|
||||
.sampler(4, ImageType::FLOAT_2D, "material_tx")
|
||||
.sampler(5, ImageType::DEPTH_2D, "depth_tx")
|
||||
.sampler(6, ImageType::UINT_2D, "stencil_tx")
|
||||
.sampler(3, ImageType::DEPTH_2D, "depth_tx")
|
||||
.sampler(4, ImageType::FLOAT_2D, "normal_tx")
|
||||
.sampler(5, ImageType::FLOAT_2D, "material_tx")
|
||||
.uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data")
|
||||
.typedef_source("workbench_shader_shared.h")
|
||||
.push_constant(Type::BOOL, "forceShadowing")
|
||||
|
@ -35,23 +34,32 @@ GPU_SHADER_CREATE_INFO(workbench_resolve_opaque_flat).define("WORKBENCH_LIGHTING
|
|||
|
||||
GPU_SHADER_CREATE_INFO(workbench_resolve_curvature)
|
||||
.define("WORKBENCH_CURVATURE")
|
||||
.sampler(7, ImageType::UINT_2D, "object_id_tx");
|
||||
.sampler(6, ImageType::UINT_2D, "object_id_tx");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_resolve_cavity)
|
||||
.define("WORKBENCH_CAVITY")
|
||||
/* TODO(@pragma37): GPU_SAMPLER_EXTEND_MODE_REPEAT is set in CavityEffect,
|
||||
* it doesn't work here? */
|
||||
.sampler(8, ImageType::FLOAT_2D, "jitter_tx")
|
||||
.sampler(7, ImageType::FLOAT_2D, "jitter_tx")
|
||||
.uniform_buf(5, "vec4", "cavity_samples[512]");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_resolve_shadow)
|
||||
.define("WORKBENCH_SHADOW")
|
||||
.sampler(8, ImageType::UINT_2D, "stencil_tx");
|
||||
|
||||
/* Variations */
|
||||
|
||||
#define WORKBENCH_FINAL_VARIATION(name, ...) \
|
||||
GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true);
|
||||
|
||||
#define WORKBENCH_RESOLVE_SHADOW_VARIATION(prefix, ...) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_shadow, "workbench_resolve_shadow", __VA_ARGS__) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_no_shadow, __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_CURVATURE_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_curvature, "workbench_resolve_curvature", __VA_ARGS__) \
|
||||
WORKBENCH_FINAL_VARIATION(prefix##_no_curvature, __VA_ARGS__)
|
||||
WORKBENCH_RESOLVE_SHADOW_VARIATION( \
|
||||
prefix##_curvature, "workbench_resolve_curvature", __VA_ARGS__) \
|
||||
WORKBENCH_RESOLVE_SHADOW_VARIATION(prefix##_no_curvature, __VA_ARGS__)
|
||||
|
||||
#define WORKBENCH_CAVITY_VARIATIONS(prefix, ...) \
|
||||
WORKBENCH_CURVATURE_VARIATIONS(prefix##_cavity, "workbench_resolve_cavity", __VA_ARGS__) \
|
||||
|
|
|
@ -12,8 +12,6 @@ GPU_SHADER_CREATE_INFO(workbench_merge_depth)
|
|||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(workbench_overlay_depth)
|
||||
.sampler(0, ImageType::DEPTH_2D, "depth_tx")
|
||||
.sampler(1, ImageType::UINT_2D, "stencil_tx")
|
||||
.fragment_source("workbench_overlay_depth_frag.glsl")
|
||||
.additional_info("draw_fullscreen")
|
||||
.depth_write(DepthWrite::ANY)
|
||||
|
|
|
@ -12,73 +12,58 @@
|
|||
void main()
|
||||
{
|
||||
vec2 uv = uvcoordsvar.st;
|
||||
|
||||
float depth = texture(depth_tx, uv).r;
|
||||
if (depth == 1.0) {
|
||||
/* Skip the background. */
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Normal and Incident vector are in view-space. Lighting is evaluated in view-space. */
|
||||
vec3 V = get_view_vector_from_screen_uv(uv);
|
||||
vec3 N = workbench_normal_decode(texture(normal_tx, uv));
|
||||
vec4 mat_data = texture(material_tx, uv);
|
||||
float depth = texture(depth_tx, uv).r;
|
||||
|
||||
vec3 base_color = mat_data.rgb;
|
||||
vec4 color = world_data.background_color;
|
||||
vec4 color = vec4(1.0);
|
||||
|
||||
/* Background pixels. */
|
||||
if (depth != 1.0) {
|
||||
#ifdef WORKBENCH_LIGHTING_MATCAP
|
||||
/* When using matcaps, mat_data.a is the back-face sign. */
|
||||
N = (mat_data.a > 0.0) ? N : -N;
|
||||
color.rgb = get_matcap_lighting(matcap_tx, base_color, N, V);
|
||||
/* When using matcaps, mat_data.a is the back-face sign. */
|
||||
N = (mat_data.a > 0.0) ? N : -N;
|
||||
color.rgb = get_matcap_lighting(matcap_tx, base_color, N, V);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_STUDIO
|
||||
float roughness, metallic;
|
||||
workbench_float_pair_decode(mat_data.a, roughness, metallic);
|
||||
color.rgb = get_world_lighting(base_color, roughness, metallic, N, V);
|
||||
float roughness, metallic;
|
||||
workbench_float_pair_decode(mat_data.a, roughness, metallic);
|
||||
color.rgb = get_world_lighting(base_color, roughness, metallic, N, V);
|
||||
#endif
|
||||
|
||||
#ifdef WORKBENCH_LIGHTING_FLAT
|
||||
color.rgb = base_color;
|
||||
color.rgb = base_color;
|
||||
#endif
|
||||
|
||||
#if defined(WORKBENCH_CAVITY) || defined(WORKBENCH_CURVATURE)
|
||||
float cavity = 0.0, edges = 0.0, curvature = 0.0;
|
||||
float cavity = 0.0, edges = 0.0, curvature = 0.0;
|
||||
|
||||
# ifdef WORKBENCH_CAVITY
|
||||
cavity_compute(uv, depth_tx, normal_tx, cavity, edges);
|
||||
cavity_compute(uv, depth_tx, normal_tx, cavity, edges);
|
||||
# endif
|
||||
|
||||
# ifdef WORKBENCH_CURVATURE
|
||||
curvature_compute(uv, object_id_tx, normal_tx, curvature);
|
||||
curvature_compute(uv, object_id_tx, normal_tx, curvature);
|
||||
# endif
|
||||
|
||||
float final_cavity_factor = clamp(
|
||||
(1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0);
|
||||
float final_cavity_factor = clamp((1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0);
|
||||
|
||||
color.rgb *= final_cavity_factor;
|
||||
color.rgb *= final_cavity_factor;
|
||||
#endif
|
||||
|
||||
bool shadow = texture(stencil_tx, uv).r != 0;
|
||||
color.rgb *= get_shadow(N, shadow);
|
||||
|
||||
color.a = 1.0f;
|
||||
}
|
||||
|
||||
#ifdef WORKBENCH_OUTLINE
|
||||
vec3 offset = vec3(world_data.viewport_size_inv, 0.0) * world_data.ui_scale;
|
||||
|
||||
uint center_id = texture(object_id_tx, uv).r;
|
||||
uvec4 adjacent_ids = uvec4(texture(object_id_tx, uv + offset.zy).r,
|
||||
texture(object_id_tx, uv - offset.zy).r,
|
||||
texture(object_id_tx, uv + offset.xz).r,
|
||||
texture(object_id_tx, uv - offset.xz).r);
|
||||
|
||||
float outline_opacity = 1.0 - dot(vec4(equal(uvec4(center_id), adjacent_ids)), vec4(0.25));
|
||||
color = mix(color, world_data.object_outline_color, outline_opacity);
|
||||
#ifdef WORKBENCH_SHADOW
|
||||
bool shadow = texture(stencil_tx, uv).r != 0;
|
||||
color.rgb *= get_shadow(N, shadow);
|
||||
#endif
|
||||
|
||||
if (all(equal(color, world_data.background_color))) {
|
||||
discard;
|
||||
}
|
||||
else {
|
||||
fragColor = color;
|
||||
}
|
||||
fragColor = color;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,5 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
float depth = texture(depth_tx, uvcoordsvar.xy).r;
|
||||
if (depth != 1.0) {
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
else {
|
||||
discard;
|
||||
}
|
||||
gl_FragDepth = texture(depth_tx, uvcoordsvar.xy).r;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,7 @@
|
|||
|
||||
void main()
|
||||
{
|
||||
uint stencil = texelFetch(stencil_tx, ivec2(gl_FragCoord.xy), 0).r;
|
||||
if (stencil != 0) {
|
||||
/* Set the depth to 0 for "In Front" objects,
|
||||
* so the Overlay engine doesn't draw on top of them. */
|
||||
gl_FragDepth = 0.0;
|
||||
}
|
||||
else {
|
||||
float depth = texelFetch(depth_tx, ivec2(gl_FragCoord.xy), 0).r;
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
/* Set the depth to 0 for "In Front" objects,
|
||||
* so the Overlay engine doesn't draw on top of them. */
|
||||
gl_FragDepth = 0.0;
|
||||
}
|
||||
|
|
|
@ -139,17 +139,15 @@ AntiAliasingPass::~AntiAliasingPass()
|
|||
void AntiAliasingPass::init(const SceneState &scene_state)
|
||||
{
|
||||
enabled_ = scene_state.draw_aa;
|
||||
sample_ = scene_state.sample;
|
||||
samples_len_ = scene_state.samples_len;
|
||||
}
|
||||
|
||||
void AntiAliasingPass::sync(SceneResources &resources, int2 resolution)
|
||||
void AntiAliasingPass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
overlay_depth_ps_.init();
|
||||
overlay_depth_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
|
||||
overlay_depth_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS |
|
||||
DRW_STATE_STENCIL_EQUAL);
|
||||
overlay_depth_ps_.state_stencil(0x00, 0xFF, uint8_t(StencilBits::OBJECT_IN_FRONT));
|
||||
overlay_depth_ps_.shader_set(overlay_depth_sh_);
|
||||
overlay_depth_ps_.bind_texture("depth_tx", &resources.depth_tx);
|
||||
overlay_depth_ps_.bind_texture("stencil_tx", &stencil_tx_);
|
||||
overlay_depth_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
if (!enabled_) {
|
||||
|
@ -158,17 +156,23 @@ void AntiAliasingPass::sync(SceneResources &resources, int2 resolution)
|
|||
return;
|
||||
}
|
||||
|
||||
taa_accumulation_tx_.ensure_2d(
|
||||
GPU_RGBA16F, resolution, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_viewport_metrics_ = float4(float2(1.0f / float2(scene_state.resolution)),
|
||||
scene_state.resolution);
|
||||
smaa_mix_factor_ = 1.0f - clamp_f(scene_state.sample / 4.0f, 0.0f, 1.0f);
|
||||
|
||||
taa_accumulation_tx_.ensure_2d(GPU_RGBA16F,
|
||||
scene_state.resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
sample0_depth_tx_.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
scene_state.resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
sample0_depth_in_front_tx_.ensure_2d(
|
||||
GPU_DEPTH24_STENCIL8, resolution, GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
GPU_DEPTH24_STENCIL8, scene_state.resolution, GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
taa_accumulation_ps_.init();
|
||||
taa_accumulation_ps_.state_set(sample_ == 0 ? DRW_STATE_WRITE_COLOR :
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
|
||||
taa_accumulation_ps_.state_set(scene_state.sample == 0 ?
|
||||
DRW_STATE_WRITE_COLOR :
|
||||
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
|
||||
taa_accumulation_ps_.shader_set(taa_accumulation_sh_);
|
||||
taa_accumulation_ps_.bind_texture("colorBuffer", &resources.color_tx);
|
||||
taa_accumulation_ps_.push_constant("samplesWeights", weights_, 9);
|
||||
|
@ -204,7 +208,7 @@ void AntiAliasingPass::sync(SceneResources &resources, int2 resolution)
|
|||
smaa_resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
}
|
||||
|
||||
void AntiAliasingPass::setup_view(View &view, int2 resolution)
|
||||
void AntiAliasingPass::setup_view(View &view, const SceneState &scene_state)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
|
@ -213,22 +217,22 @@ void AntiAliasingPass::setup_view(View &view, int2 resolution)
|
|||
const TaaSamples &taa_samples = get_taa_samples();
|
||||
|
||||
float2 sample_offset;
|
||||
switch (samples_len_) {
|
||||
switch (scene_state.samples_len) {
|
||||
default:
|
||||
case 5:
|
||||
sample_offset = taa_samples.x5[sample_];
|
||||
sample_offset = taa_samples.x5[scene_state.sample];
|
||||
break;
|
||||
case 8:
|
||||
sample_offset = taa_samples.x8[sample_];
|
||||
sample_offset = taa_samples.x8[scene_state.sample];
|
||||
break;
|
||||
case 11:
|
||||
sample_offset = taa_samples.x11[sample_];
|
||||
sample_offset = taa_samples.x11[scene_state.sample];
|
||||
break;
|
||||
case 16:
|
||||
sample_offset = taa_samples.x16[sample_];
|
||||
sample_offset = taa_samples.x16[scene_state.sample];
|
||||
break;
|
||||
case 32:
|
||||
sample_offset = taa_samples.x32[sample_];
|
||||
sample_offset = taa_samples.x32[scene_state.sample];
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -242,43 +246,58 @@ void AntiAliasingPass::setup_view(View &view, int2 resolution)
|
|||
DRW_view_viewmat_get(default_view, viewmat.ptr(), false);
|
||||
DRW_view_persmat_get(default_view, persmat.ptr(), false);
|
||||
|
||||
window_translate_m4(
|
||||
winmat.ptr(), persmat.ptr(), sample_offset.x / resolution.x, sample_offset.y / resolution.y);
|
||||
window_translate_m4(winmat.ptr(),
|
||||
persmat.ptr(),
|
||||
sample_offset.x / scene_state.resolution.x,
|
||||
sample_offset.y / scene_state.resolution.y);
|
||||
|
||||
view.sync(viewmat, winmat);
|
||||
}
|
||||
|
||||
void AntiAliasingPass::draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture *depth_tx,
|
||||
GPUTexture *depth_in_front_tx,
|
||||
GPUTexture *color_tx)
|
||||
const SceneState &scene_state,
|
||||
SceneResources &resources)
|
||||
{
|
||||
auto draw_overlay_depth = [&](GPUTexture *target) {
|
||||
stencil_tx_ = resources.stencil_view.extract(manager, resources.depth_tx);
|
||||
overlay_depth_fb_.ensure(GPU_ATTACHMENT_TEXTURE(target));
|
||||
if (resources.depth_in_front_tx.is_valid() && scene_state.sample == 0 &&
|
||||
scene_state.overlays_enabled)
|
||||
{
|
||||
overlay_depth_fb_.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
overlay_depth_fb_.bind();
|
||||
manager.submit(overlay_depth_ps_);
|
||||
};
|
||||
}
|
||||
|
||||
if (!enabled_) {
|
||||
GPU_texture_copy(color_tx, resources.color_tx);
|
||||
draw_overlay_depth(depth_tx);
|
||||
return;
|
||||
}
|
||||
|
||||
const bool last_sample = scene_state.sample + 1 == scene_state.samples_len;
|
||||
|
||||
if (scene_state.samples_len > 1 && (scene_state.overlays_enabled || DRW_state_is_scene_render()))
|
||||
{
|
||||
if (scene_state.sample == 0) {
|
||||
GPU_texture_copy(sample0_depth_tx_, resources.depth_tx);
|
||||
if (resources.depth_in_front_tx.is_valid()) {
|
||||
GPU_texture_copy(sample0_depth_in_front_tx_, resources.depth_in_front_tx);
|
||||
}
|
||||
}
|
||||
else if (!DRW_state_is_scene_render() || last_sample) {
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(resources.depth_tx, sample0_depth_tx_);
|
||||
if (resources.depth_in_front_tx.is_valid()) {
|
||||
GPU_texture_copy(resources.depth_in_front_tx, sample0_depth_in_front_tx_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We always do SMAA on top of TAA accumulation, unless the number of samples of TAA is already
|
||||
* high. This ensure a smoother transition.
|
||||
* If TAA accumulation is finished, we only blit the result.
|
||||
*/
|
||||
const bool last_sample = sample_ + 1 == samples_len_;
|
||||
const bool taa_finished = sample_ >= samples_len_;
|
||||
|
||||
const bool taa_finished = scene_state.sample >= scene_state.samples_len;
|
||||
if (!taa_finished) {
|
||||
if (sample_ == 0) {
|
||||
if (scene_state.sample == 0) {
|
||||
weight_accum_ = 0;
|
||||
}
|
||||
/* Accumulate result to the TAA buffer. */
|
||||
|
@ -288,30 +307,17 @@ void AntiAliasingPass::draw(Manager &manager,
|
|||
weight_accum_ += weights_sum_;
|
||||
}
|
||||
|
||||
if (sample_ == 0) {
|
||||
draw_overlay_depth(sample0_depth_tx_);
|
||||
GPU_texture_copy(sample0_depth_in_front_tx_, resources.depth_in_front_tx);
|
||||
}
|
||||
if (!DRW_state_is_scene_render()) {
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
GPU_texture_copy(depth_in_front_tx, sample0_depth_in_front_tx_);
|
||||
}
|
||||
else if (last_sample) {
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
/* There's no depth_in_front_tx in scene image renders. */
|
||||
}
|
||||
/** Always acquire to avoid constant allocation/deallocation. */
|
||||
smaa_weight_tx_.acquire(scene_state.resolution,
|
||||
GPU_RGBA8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_edge_tx_.acquire(scene_state.resolution,
|
||||
GPU_RG8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
if (!DRW_state_is_image_render() || last_sample) {
|
||||
smaa_weight_tx_.acquire(
|
||||
resolution, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_mix_factor_ = 1.0f - clamp_f(sample_ / 4.0f, 0.0f, 1.0f);
|
||||
smaa_viewport_metrics_ = float4(float2(1.0f / float2(resolution)), resolution);
|
||||
|
||||
/* After a certain point SMAA is no longer necessary. */
|
||||
if (smaa_mix_factor_ > 0.0f) {
|
||||
smaa_edge_tx_.acquire(
|
||||
resolution, GPU_RG8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
smaa_edge_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_edge_tx_));
|
||||
smaa_edge_fb_.bind();
|
||||
manager.submit(smaa_edge_detect_ps_, view);
|
||||
|
@ -319,13 +325,14 @@ void AntiAliasingPass::draw(Manager &manager,
|
|||
smaa_weight_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_weight_tx_));
|
||||
smaa_weight_fb_.bind();
|
||||
manager.submit(smaa_aa_weight_ps_, view);
|
||||
smaa_edge_tx_.release();
|
||||
}
|
||||
smaa_resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_tx));
|
||||
smaa_resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
smaa_resolve_fb_.bind();
|
||||
manager.submit(smaa_resolve_ps_, view);
|
||||
smaa_weight_tx_.release();
|
||||
}
|
||||
|
||||
smaa_edge_tx_.release();
|
||||
smaa_weight_tx_.release();
|
||||
}
|
||||
|
||||
} // namespace blender::workbench
|
||||
|
|
|
@ -69,12 +69,6 @@ class Instance {
|
|||
|
||||
void begin_sync()
|
||||
{
|
||||
const float2 viewport_size = DRW_viewport_size_get();
|
||||
const int2 resolution = {int(viewport_size.x), int(viewport_size.y)};
|
||||
resources.depth_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
|
||||
resources.material_buf.clear();
|
||||
|
||||
opaque_ps.sync(scene_state, resources);
|
||||
|
@ -85,7 +79,7 @@ class Instance {
|
|||
volume_ps.sync(resources);
|
||||
outline_ps.sync(resources);
|
||||
dof_ps.sync(resources);
|
||||
anti_aliasing_ps.sync(resources, scene_state.resolution);
|
||||
anti_aliasing_ps.sync(scene_state, resources);
|
||||
}
|
||||
|
||||
void end_sync()
|
||||
|
@ -438,38 +432,38 @@ class Instance {
|
|||
|
||||
if (scene_state.render_finished) {
|
||||
/* Just copy back the already rendered result */
|
||||
anti_aliasing_ps.draw(
|
||||
manager, view, resources, resolution, depth_tx, depth_in_front_tx, color_tx);
|
||||
anti_aliasing_ps.draw(manager, view, scene_state, resources);
|
||||
return;
|
||||
}
|
||||
|
||||
anti_aliasing_ps.setup_view(view, resolution);
|
||||
anti_aliasing_ps.setup_view(view, scene_state);
|
||||
|
||||
resources.color_tx.acquire(
|
||||
resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
resources.color_tx.clear(resources.world_buf.background_color);
|
||||
resources.depth_tx.wrap(depth_tx);
|
||||
resources.color_tx.wrap(color_tx);
|
||||
GPUAttachment id_attachment = GPU_ATTACHMENT_NONE;
|
||||
if (scene_state.draw_object_id) {
|
||||
resources.object_id_tx.acquire(
|
||||
resolution, GPU_R16UI, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
resources.object_id_tx.clear(uint4(0));
|
||||
id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx);
|
||||
}
|
||||
|
||||
Framebuffer fb = Framebuffer("Workbench.Clear");
|
||||
fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
fb.bind();
|
||||
GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00);
|
||||
resources.clear_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(resources.color_tx),
|
||||
id_attachment);
|
||||
resources.clear_fb.bind();
|
||||
float4 clear_colors[2] = {scene_state.background_color, float4(0.0f)};
|
||||
GPU_framebuffer_multi_clear(resources.clear_fb, reinterpret_cast<float(*)[4]>(clear_colors));
|
||||
GPU_framebuffer_clear_depth_stencil(resources.clear_fb, 1.0f, 0x00);
|
||||
|
||||
bool needs_depth_in_front = !transparent_ps.accumulation_in_front_ps_.is_empty() ||
|
||||
scene_state.sample == 0;
|
||||
if (needs_depth_in_front) {
|
||||
resources.depth_in_front_tx.acquire(resolution,
|
||||
GPU_DEPTH24_STENCIL8,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ |
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT);
|
||||
|
||||
fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx));
|
||||
fb.bind();
|
||||
GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00);
|
||||
(!opaque_ps.gbuffer_in_front_ps_.is_empty() &&
|
||||
scene_state.overlays_enabled && scene_state.sample == 0);
|
||||
resources.depth_in_front_tx.wrap(needs_depth_in_front ? depth_in_front_tx : nullptr);
|
||||
if ((!needs_depth_in_front && scene_state.overlays_enabled) ||
|
||||
(needs_depth_in_front && opaque_ps.gbuffer_in_front_ps_.is_empty()))
|
||||
{
|
||||
resources.clear_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(depth_in_front_tx));
|
||||
resources.clear_in_front_fb.bind();
|
||||
GPU_framebuffer_clear_depth_stencil(resources.clear_in_front_fb, 1.0f, 0x00);
|
||||
}
|
||||
|
||||
opaque_ps.draw(
|
||||
|
@ -480,12 +474,9 @@ class Instance {
|
|||
volume_ps.draw(manager, view, resources);
|
||||
outline_ps.draw(manager, resources);
|
||||
dof_ps.draw(manager, view, resources, resolution);
|
||||
anti_aliasing_ps.draw(
|
||||
manager, view, resources, resolution, depth_tx, depth_in_front_tx, color_tx);
|
||||
anti_aliasing_ps.draw(manager, view, scene_state, resources);
|
||||
|
||||
resources.color_tx.release();
|
||||
resources.object_id_tx.release();
|
||||
resources.depth_in_front_tx.release();
|
||||
}
|
||||
|
||||
void draw_viewport(Manager &manager,
|
||||
|
@ -512,8 +503,7 @@ class Instance {
|
|||
/* Re-sync anything dependent on scene_state.sample. */
|
||||
resources.init(scene_state);
|
||||
dof_ps.init(scene_state);
|
||||
anti_aliasing_ps.init(scene_state);
|
||||
anti_aliasing_ps.sync(resources, scene_state.resolution);
|
||||
anti_aliasing_ps.sync(scene_state, resources);
|
||||
}
|
||||
this->draw(manager, depth_tx, depth_in_front_tx, color_tx);
|
||||
}
|
||||
|
@ -622,9 +612,11 @@ static bool workbench_render_framebuffers_init()
|
|||
"txl.color", size.x, size.y, 1, GPU_RGBA16F, usage, nullptr);
|
||||
dtxl->depth = GPU_texture_create_2d(
|
||||
"txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
|
||||
dtxl->depth_in_front = GPU_texture_create_2d(
|
||||
"txl.depth_in_front", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, usage, nullptr);
|
||||
}
|
||||
|
||||
if (!(dtxl->depth && dtxl->color)) {
|
||||
if (!(dtxl->depth && dtxl->color && dtxl->depth_in_front)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,19 +112,20 @@ PassMain::Sub &MeshPass::get_subpass(
|
|||
void OpaquePass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
scene_state.cull_state;
|
||||
DRW_STATE_WRITE_STENCIL | scene_state.cull_state;
|
||||
|
||||
bool clip = scene_state.clip_planes.size() > 0;
|
||||
|
||||
DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
|
||||
DRWState in_front_state = state | DRW_STATE_STENCIL_ALWAYS;
|
||||
gbuffer_in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size());
|
||||
gbuffer_in_front_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
gbuffer_in_front_ps_.state_stencil(uint8_t(StencilBits::OBJECT_IN_FRONT), 0xFF, 0x00);
|
||||
gbuffer_in_front_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
state |= DRW_STATE_STENCIL_NEQUAL;
|
||||
gbuffer_ps_.init_pass(resources, state, scene_state.clip_planes.size());
|
||||
gbuffer_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
gbuffer_ps_.state_stencil(
|
||||
uint8_t(StencilBits::OBJECT), 0xFF, uint8_t(StencilBits::OBJECT_IN_FRONT));
|
||||
gbuffer_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
||||
|
@ -133,7 +134,8 @@ void OpaquePass::sync(const SceneState &scene_state, SceneResources &resources)
|
|||
deferred_ps_.shader_set(resources.shader_cache.resolve_shader_get(ePipelineType::OPAQUE,
|
||||
scene_state.lighting_type,
|
||||
scene_state.draw_cavity,
|
||||
scene_state.draw_curvature));
|
||||
scene_state.draw_curvature,
|
||||
scene_state.draw_shadows));
|
||||
deferred_ps_.push_constant("forceShadowing", false);
|
||||
deferred_ps_.bind_ubo(WB_WORLD_SLOT, resources.world_buf);
|
||||
deferred_ps_.bind_texture(WB_MATCAP_SLOT, resources.matcap_tx);
|
||||
|
@ -165,11 +167,11 @@ void OpaquePass::draw(Manager &manager,
|
|||
}
|
||||
|
||||
if (!gbuffer_in_front_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
opaque_fb.bind();
|
||||
gbuffer_in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
gbuffer_in_front_fb.bind();
|
||||
|
||||
manager.submit(gbuffer_in_front_ps_, view);
|
||||
|
||||
|
@ -179,55 +181,40 @@ void OpaquePass::draw(Manager &manager,
|
|||
}
|
||||
|
||||
if (!gbuffer_ps_.is_empty()) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
opaque_fb.bind();
|
||||
gbuffer_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx),
|
||||
GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx),
|
||||
object_id_attachment);
|
||||
gbuffer_fb.bind();
|
||||
|
||||
manager.submit(gbuffer_ps_, view);
|
||||
}
|
||||
|
||||
bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty();
|
||||
|
||||
Texture *depth_stencil_tx = nullptr;
|
||||
|
||||
if (needs_stencil_copy) {
|
||||
if (shadow_pass) {
|
||||
shadow_depth_stencil_tx.ensure_2d(GPU_DEPTH24_STENCIL8,
|
||||
resolution,
|
||||
GPU_TEXTURE_USAGE_SHADER_READ |
|
||||
GPU_TEXTURE_USAGE_ATTACHMENT |
|
||||
GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW);
|
||||
|
||||
GPU_texture_copy(shadow_depth_stencil_tx, resources.depth_tx);
|
||||
clear_fb.ensure(GPU_ATTACHMENT_TEXTURE(shadow_depth_stencil_tx));
|
||||
clear_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(clear_fb, 0);
|
||||
|
||||
depth_stencil_tx = shadow_depth_stencil_tx.ptr();
|
||||
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(*depth_stencil_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
shadow_pass->draw(
|
||||
manager, view, resources, **&shadow_depth_stencil_tx, !gbuffer_in_front_ps_.is_empty());
|
||||
deferred_ps_stencil_tx = resources.stencil_view.extract(manager, shadow_depth_stencil_tx);
|
||||
}
|
||||
else {
|
||||
shadow_depth_stencil_tx.free();
|
||||
depth_stencil_tx = resources.depth_tx.ptr();
|
||||
deferred_ps_stencil_tx = nullptr;
|
||||
}
|
||||
|
||||
if (shadow_pass) {
|
||||
shadow_pass->draw(
|
||||
manager, view, resources, **depth_stencil_tx, !gbuffer_in_front_ps_.is_empty());
|
||||
}
|
||||
|
||||
deferred_ps_stencil_tx = resources.stencil_view.extract(manager, *depth_stencil_tx);
|
||||
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
opaque_fb.bind();
|
||||
deferred_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx));
|
||||
deferred_fb.bind();
|
||||
manager.submit(deferred_ps_, view);
|
||||
|
||||
if (shadow_pass && !needs_stencil_copy) {
|
||||
opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx));
|
||||
opaque_fb.bind();
|
||||
GPU_framebuffer_clear_stencil(opaque_fb, 0);
|
||||
}
|
||||
|
||||
gbuffer_normal_tx.release();
|
||||
gbuffer_material_tx.release();
|
||||
}
|
||||
|
@ -257,7 +244,8 @@ void TransparentPass::sync(const SceneState &scene_state, SceneResources &resour
|
|||
|
||||
accumulation_ps_.init_pass(
|
||||
resources, state | DRW_STATE_STENCIL_NEQUAL, scene_state.clip_planes.size());
|
||||
accumulation_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
accumulation_ps_.state_stencil(
|
||||
uint8_t(StencilBits::OBJECT), 0xFF, uint8_t(StencilBits::OBJECT_IN_FRONT));
|
||||
accumulation_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
accumulation_ps_.init_subpasses(
|
||||
ePipelineType::TRANSPARENT, scene_state.lighting_type, clip, resources.shader_cache);
|
||||
|
@ -335,13 +323,13 @@ TransparentDepthPass::~TransparentDepthPass()
|
|||
void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &resources)
|
||||
{
|
||||
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
|
||||
scene_state.cull_state;
|
||||
DRW_STATE_WRITE_STENCIL | scene_state.cull_state;
|
||||
|
||||
bool clip = scene_state.clip_planes.size() > 0;
|
||||
|
||||
DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
|
||||
DRWState in_front_state = state | DRW_STATE_STENCIL_ALWAYS;
|
||||
in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size());
|
||||
in_front_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
in_front_ps_.state_stencil(uint8_t(StencilBits::OBJECT_IN_FRONT), 0xFF, 0x00);
|
||||
in_front_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache);
|
||||
|
||||
|
@ -350,15 +338,17 @@ void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &r
|
|||
}
|
||||
merge_ps_.init();
|
||||
merge_ps_.shader_set(merge_sh_);
|
||||
merge_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_WRITE_STENCIL |
|
||||
DRW_STATE_STENCIL_ALWAYS);
|
||||
merge_ps_.state_stencil(0xFF, 0xFF, 0x00);
|
||||
merge_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WRITE_STENCIL |
|
||||
DRW_STATE_STENCIL_EQUAL);
|
||||
merge_ps_.state_stencil(
|
||||
uint8_t(StencilBits::OBJECT_IN_FRONT), 0xFF, uint8_t(StencilBits::OBJECT_IN_FRONT));
|
||||
merge_ps_.bind_texture("depth_tx", &resources.depth_in_front_tx);
|
||||
merge_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3);
|
||||
|
||||
state |= DRW_STATE_STENCIL_NEQUAL;
|
||||
main_ps_.init_pass(resources, state, scene_state.clip_planes.size());
|
||||
main_ps_.state_stencil(0x00, 0xFF, 0xFF);
|
||||
main_ps_.state_stencil(
|
||||
uint8_t(StencilBits::OBJECT), 0xFF, uint8_t(StencilBits::OBJECT_IN_FRONT));
|
||||
main_ps_.init_subpasses(
|
||||
ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache);
|
||||
}
|
||||
|
|
|
@ -32,14 +32,15 @@ class ShaderCache {
|
|||
GPUShader *resolve_shader_get(ePipelineType pipeline_type,
|
||||
eLightingType lighting_type,
|
||||
bool cavity = false,
|
||||
bool curvature = false);
|
||||
bool curvature = false,
|
||||
bool shadow = false);
|
||||
|
||||
private:
|
||||
/* TODO(fclem): We might want to change to a Map since most shader will never be compiled. */
|
||||
GPUShader *prepass_shader_cache_[pipeline_type_len][geometry_type_len][shader_type_len]
|
||||
[lighting_type_len][2 /*clip*/] = {{{{{nullptr}}}}};
|
||||
GPUShader *resolve_shader_cache_[pipeline_type_len][lighting_type_len][2 /*cavity*/]
|
||||
[2 /*curvature*/] = {{{{nullptr}}}};
|
||||
[2 /*curvature*/][2 /*shadow*/] = {{{{nullptr}}}};
|
||||
};
|
||||
|
||||
struct Material {
|
||||
|
@ -96,6 +97,8 @@ struct SceneState {
|
|||
bool reset_taa_next_sample = false;
|
||||
bool render_finished = false;
|
||||
|
||||
bool overlays_enabled = false;
|
||||
|
||||
/* Used when material_type == eMaterialType::SINGLE */
|
||||
Material material_override = Material(float3(1.0f));
|
||||
/* When r == -1.0 the shader uses the vertex color */
|
||||
|
@ -196,10 +199,14 @@ struct SceneResources {
|
|||
StringRefNull current_matcap = {};
|
||||
Texture matcap_tx = "matcap_tx";
|
||||
|
||||
TextureFromPool color_tx = "wb_color_tx";
|
||||
TextureFromPool object_id_tx = "wb_object_id_tx";
|
||||
Texture depth_tx = "wb_depth_tx";
|
||||
TextureFromPool depth_in_front_tx = "wb_depth_in_front_tx";
|
||||
|
||||
TextureRef color_tx;
|
||||
TextureRef depth_tx;
|
||||
TextureRef depth_in_front_tx;
|
||||
|
||||
Framebuffer clear_fb = {"Clear Main"};
|
||||
Framebuffer clear_in_front_fb = {"Clear In Front"};
|
||||
|
||||
StorageVectorBuffer<Material> material_buf = {"material_buf"};
|
||||
UniformBuffer<WorldData> world_buf = {};
|
||||
|
@ -243,11 +250,16 @@ class MeshPass : public PassMain {
|
|||
ImageUser *iuser = nullptr);
|
||||
};
|
||||
|
||||
enum class StencilBits : uint8_t {
|
||||
BACKGROUND = 0,
|
||||
OBJECT = 1u << 0,
|
||||
OBJECT_IN_FRONT = 1u << 1,
|
||||
};
|
||||
|
||||
class OpaquePass {
|
||||
public:
|
||||
TextureFromPool gbuffer_normal_tx = {"gbuffer_normal_tx"};
|
||||
TextureFromPool gbuffer_material_tx = {"gbuffer_material_tx"};
|
||||
Framebuffer opaque_fb = {};
|
||||
|
||||
Texture shadow_depth_stencil_tx = {"shadow_depth_stencil_tx"};
|
||||
GPUTexture *deferred_ps_stencil_tx = nullptr;
|
||||
|
@ -256,6 +268,11 @@ class OpaquePass {
|
|||
MeshPass gbuffer_in_front_ps_ = {"Opaque.GbufferInFront"};
|
||||
PassSimple deferred_ps_ = {"Opaque.Deferred"};
|
||||
|
||||
Framebuffer gbuffer_fb = {"Opaque.Gbuffer"};
|
||||
Framebuffer gbuffer_in_front_fb = {"Opaque.GbufferInFront"};
|
||||
Framebuffer deferred_fb = {"Opaque.Deferred"};
|
||||
Framebuffer clear_fb = {"Opaque.Clear"};
|
||||
|
||||
void sync(const SceneState &scene_state, SceneResources &resources);
|
||||
void draw(Manager &manager,
|
||||
View &view,
|
||||
|
@ -511,7 +528,6 @@ class AntiAliasingPass {
|
|||
|
||||
Texture sample0_depth_tx_ = {"sample0_depth_tx"};
|
||||
Texture sample0_depth_in_front_tx_ = {"sample0_depth_in_front_tx"};
|
||||
GPUTexture *stencil_tx_ = nullptr;
|
||||
|
||||
Texture taa_accumulation_tx_ = {"taa_accumulation_tx"};
|
||||
Texture smaa_search_tx_ = {"smaa_search_tx"};
|
||||
|
@ -545,15 +561,12 @@ class AntiAliasingPass {
|
|||
~AntiAliasingPass();
|
||||
|
||||
void init(const SceneState &scene_state);
|
||||
void sync(SceneResources &resources, int2 resolution);
|
||||
void setup_view(View &view, int2 resolution);
|
||||
void sync(const SceneState &scene_state, SceneResources &resources);
|
||||
void setup_view(View &view, const SceneState &scene_state);
|
||||
void draw(Manager &manager,
|
||||
View &view,
|
||||
SceneResources &resources,
|
||||
int2 resolution,
|
||||
GPUTexture *depth_tx,
|
||||
GPUTexture *depth_in_front_tx,
|
||||
GPUTexture *color_tx);
|
||||
const SceneState &scene_state,
|
||||
SceneResources &resources);
|
||||
};
|
||||
|
||||
} // namespace blender::workbench
|
||||
|
|
|
@ -23,7 +23,9 @@ ShaderCache::~ShaderCache()
|
|||
for (auto j : IndexRange(lighting_type_len)) {
|
||||
for (auto k : IndexRange(2) /*cavity*/) {
|
||||
for (auto l : IndexRange(2) /*curvature*/) {
|
||||
DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l]);
|
||||
for (auto m : IndexRange(2) /*shadow*/) {
|
||||
DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l][m]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,10 +94,11 @@ GPUShader *ShaderCache::prepass_shader_get(ePipelineType pipeline_type,
|
|||
GPUShader *ShaderCache::resolve_shader_get(ePipelineType pipeline_type,
|
||||
eLightingType lighting_type,
|
||||
bool cavity,
|
||||
bool curvature)
|
||||
bool curvature,
|
||||
bool shadow)
|
||||
{
|
||||
GPUShader *&shader_ptr =
|
||||
resolve_shader_cache_[int(pipeline_type)][int(lighting_type)][cavity][curvature];
|
||||
resolve_shader_cache_[int(pipeline_type)][int(lighting_type)][cavity][curvature][shadow];
|
||||
|
||||
if (shader_ptr != nullptr) {
|
||||
return shader_ptr;
|
||||
|
@ -125,6 +128,7 @@ GPUShader *ShaderCache::resolve_shader_get(ePipelineType pipeline_type,
|
|||
}
|
||||
info_name += cavity ? "_cavity" : "_no_cavity";
|
||||
info_name += curvature ? "_curvature" : "_no_curvature";
|
||||
info_name += shadow ? "_shadow" : "_no_shadow";
|
||||
|
||||
shader_ptr = GPU_shader_create_from_info_name(info_name.c_str());
|
||||
return shader_ptr;
|
||||
|
|
|
@ -173,6 +173,8 @@ void SceneState::init(Object *camera_ob /*=nullptr*/)
|
|||
shading.flag & V3D_SHADING_DEPTH_OF_FIELD;
|
||||
|
||||
draw_object_id = draw_outline || draw_curvature;
|
||||
|
||||
overlays_enabled = v3d && !(v3d->flag2 & V3D_HIDE_OVERLAYS);
|
||||
};
|
||||
|
||||
static const CustomData *get_loop_custom_data(const Mesh *mesh)
|
||||
|
|
Loading…
Reference in New Issue