Blender V4.3
workbench_effect_cavity.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
16#include "BLI_rand.h"
17#include "workbench_private.hh"
18
19namespace blender::workbench {
20
21void CavityEffect::init(const SceneState &scene_state, SceneResources &resources)
22{
23 cavity_enabled_ = scene_state.draw_cavity;
24 curvature_enabled_ = scene_state.draw_curvature;
25
26 const int ssao_samples = scene_state.scene->display.matcap_ssao_samples;
27 int sample_count = min_ii(scene_state.samples_len * ssao_samples, max_samples_);
28 const int max_iter_count = sample_count / ssao_samples;
29
30 sample_ = scene_state.sample % max_iter_count;
31
32 UniformBuffer<WorldData> &world_buf = resources.world_buf;
33
34 world_buf.cavity_sample_start = ssao_samples * sample_;
35 world_buf.cavity_sample_end = ssao_samples * (sample_ + 1);
36
37 world_buf.cavity_sample_count_inv = 1.0f / (world_buf.cavity_sample_end -
38 world_buf.cavity_sample_start);
39 world_buf.cavity_jitter_scale = 1.0f / 64.0f;
40
41 world_buf.cavity_valley_factor = scene_state.shading.cavity_valley_factor;
42 world_buf.cavity_ridge_factor = scene_state.shading.cavity_ridge_factor;
43 world_buf.cavity_attenuation = scene_state.scene->display.matcap_ssao_attenuation;
44 world_buf.cavity_distance = scene_state.scene->display.matcap_ssao_distance;
45
46 world_buf.curvature_ridge = 0.5f /
47 max_ff(square_f(scene_state.shading.curvature_ridge_factor), 1e-4f);
48 world_buf.curvature_valley = 0.7f / max_ff(square_f(scene_state.shading.curvature_valley_factor),
49 1e-4f);
50
51 if (cavity_enabled_ && sample_count_ != sample_count) {
52 sample_count_ = sample_count;
53 load_samples_buf(ssao_samples);
54 resources.load_jitter_tx(sample_count_);
55 }
56}
57
58void CavityEffect::load_samples_buf(int ssao_samples)
59{
60 const float iteration_samples_inv = 1.0f / ssao_samples;
61
62 /* Create disk samples using Hammersley distribution */
63 for (int i : IndexRange(sample_count_)) {
64 float it_add = (i / ssao_samples) * 0.499f;
65 float r = fmodf((i + 0.5f + it_add) * iteration_samples_inv, 1.0f);
66 double dphi;
67 BLI_hammersley_1d(i, &dphi);
68
69 float phi = float(dphi) * 2.0f * M_PI + it_add;
70 samples_buf[i].x = math::cos(phi);
71 samples_buf[i].y = math::sin(phi);
72 /* This deliberately distribute more samples
73 * at the center of the disk (and thus the shadow). */
74 samples_buf[i].z = r;
75 }
76
77 samples_buf.push_update();
78}
79
81{
82 if (cavity_enabled_) {
83 pass.bind_ubo("cavity_samples", samples_buf);
84 pass.bind_texture("jitter_tx",
85 &resources.jitter_tx,
86 {GPU_SAMPLER_FILTERING_DEFAULT,
87 GPU_SAMPLER_EXTEND_MODE_REPEAT,
88 GPU_SAMPLER_EXTEND_MODE_REPEAT});
89 }
90 if (curvature_enabled_) {
91 pass.bind_texture("object_id_tx", &resources.object_id_tx);
92 }
93}
94
95} // namespace blender::workbench
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float square_f(float a)
#define M_PI
Random number functions.
void BLI_hammersley_1d(unsigned int n, double *r)
Definition rand.cc:350
void setup_resolve_pass(PassSimple &pass, SceneResources &resources)
void init(const SceneState &scene_state, SceneResources &resources)
#define fmodf(x, y)
draw_view in_light_buf[] float
T cos(const AngleRadianBase< T > &a)
T sin(const AngleRadianBase< T > &a)
float matcap_ssao_attenuation
struct SceneDisplay display
float curvature_valley_factor
UniformBuffer< WorldData > world_buf