22 data_.sample_len = 16;
24 if (!(inst_.pipelines.deferred.closure_bits_get() &
CLOSURE_SSS)) {
34 pass.
bind_texture(
"depth_tx", &inst_.render_buffers.depth_tx);
35 pass.
bind_image(
"direct_light_img", &direct_light_tx_);
36 pass.
bind_image(
"indirect_light_img", &indirect_light_tx_);
37 pass.
bind_image(
"object_id_img", &object_id_tx_);
38 pass.
bind_image(
"radiance_img", &radiance_tx_);
39 pass.
bind_ssbo(
"convolve_tile_buf", &convolve_tile_buf_);
40 pass.
bind_ssbo(
"convolve_dispatch_buf", &convolve_dispatch_buf_);
42 pass.
dispatch(&setup_dispatch_size_);
60 pass.
bind_texture(
"radiance_tx", &radiance_tx_, sampler);
61 pass.
bind_texture(
"depth_tx", &inst_.render_buffers.depth_tx, sampler);
62 pass.
bind_texture(
"object_id_tx", &object_id_tx_, sampler);
63 pass.
bind_image(
"out_direct_light_img", &direct_light_tx_);
64 pass.
bind_image(
"out_indirect_light_img", &indirect_light_tx_);
65 pass.
bind_ssbo(
"tiles_coord_buf", &convolve_tile_buf_);
67 pass.
dispatch(convolve_dispatch_buf_);
80 precompute_samples_location();
82 int2 render_extent = inst_.film.render_extent_get();
85 const int convolve_tile_count = setup_dispatch_size_.x * setup_dispatch_size_.y;
88 direct_light_tx_ = direct_diffuse_light_tx;
89 indirect_light_tx_ = indirect_diffuse_light_tx;
92 object_id_tx_.acquire(render_extent, gpu::TextureFormat::SUBSURFACE_OBJECT_ID_FORMAT, usage);
93 radiance_tx_.acquire(render_extent, gpu::TextureFormat::SUBSURFACE_RADIANCE_FORMAT, usage);
95 convolve_dispatch_buf_.clear_to_zero();
97 inst_.manager->submit(setup_ps_,
view);
98 inst_.manager->submit(convolve_ps_,
view);
100 object_id_tx_.release();
101 radiance_tx_.release();
104void SubsurfaceModule::precompute_samples_location()
115 double golden_angle =
M_PI * (3.0 -
sqrt(5.0));
117 float theta = golden_angle *
i +
M_PI * 2.0f * rand_u;
119 float r = SubsurfaceModule::burley_sample(d,
x);
123 data_.
samples[
i].z = 1.0f / burley_pdf(d, r);
141float SubsurfaceModule::burley_sample(
float d,
float x_rand)
145 const float tolerance = 1
e-6;
146 const int max_iteration_count = 10;
154 r =
exp(x_rand * x_rand * 2.4) - 1.0;
161 for (
int i = 0;
i < max_iteration_count;
i++) {
162 float exp_r_3 =
exp(-r / 3.0);
163 float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
164 float f = 1.0 - 0.25 * exp_r - 0.75 * exp_r_3 - x_rand;
165 float f_ = 0.25 * exp_r + 0.25 * exp_r_3;
167 if (
abs(f) < tolerance || f_ == 0.0) {
172 r = std::max<double>(r, 0.0);
178float SubsurfaceModule::burley_eval(
float d,
float r)
184 float exp_r_3_d =
expf(-r / (3.0f * d));
185 float exp_r_d = exp_r_3_d * exp_r_3_d * exp_r_3_d;
186 return (exp_r_d + exp_r_3_d) / (8.0f *
float(
M_PI) * d);
189float SubsurfaceModule::burley_pdf(
float d,
float r)
MINLINE uint ceil_to_multiple_u(uint a, uint b)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
@ GPU_BARRIER_SHADER_STORAGE
@ GPU_BARRIER_TEXTURE_FETCH
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
@ GPU_SAMPLER_CUSTOM_COMPARE
@ GPU_SAMPLER_STATE_TYPE_PARAMETERS
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER
@ GPU_SAMPLER_FILTERING_DEFAULT
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
void bind_resources(U &resources)
void shader_set(gpu::Shader *shader)
void bind_texture(const char *name, gpu::Texture *texture, GPUSamplerState state=sampler_auto)
void bind_image(const char *name, gpu::Texture *image)
void dispatch(int group_len)
void state_set(DRWState state, int clip_plane_count=0)
void barrier(GPUBarrier type)
void bind_ssbo(const char *name, gpu::StorageBuf *buffer)
UniformDataModule uniform_data
float rng_get(eSamplingDimension dimension) const
#define SUBSURFACE_GROUP_SIZE
#define SSS_BURLEY_TRUNCATE
#define SSS_BURLEY_TRUNCATE_CDF
detail::Pass< command::DrawCommandBuf > PassSimple
static float3 burley_setup(float3 radius, float3 albedo)
VecBase< T, Size > divide_ceil(const VecBase< T, Size > &a, const VecBase< T, Size > &b)
VecBase< int32_t, 2 > int2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
float4 samples[SSS_SAMPLE_MAX]
void render(gpu::Texture *direct_diffuse_light_tx, gpu::Texture *indirect_diffuse_light_tx, eClosureBits active_closures, View &view)