24 data_.sample_len = 16;
32 pass.
bind_texture(
"depth_tx", &inst_.render_buffers.depth_tx);
33 pass.
bind_image(
"direct_light_img", &direct_light_tx_);
34 pass.
bind_image(
"indirect_light_img", &indirect_light_tx_);
35 pass.
bind_image(
"object_id_img", &object_id_tx_);
36 pass.
bind_image(
"radiance_img", &radiance_tx_);
37 pass.
bind_ssbo(
"convolve_tile_buf", &convolve_tile_buf_);
38 pass.
bind_ssbo(
"convolve_dispatch_buf", &convolve_dispatch_buf_);
40 pass.
dispatch(&setup_dispatch_size_);
61 pass.
bind_image(
"out_direct_light_img", &direct_light_tx_);
62 pass.
bind_image(
"out_indirect_light_img", &indirect_light_tx_);
63 pass.
bind_ssbo(
"tiles_coord_buf", &convolve_tile_buf_);
65 pass.
dispatch(convolve_dispatch_buf_);
70 GPUTexture *indirect_diffuse_light_tx,
78 precompute_samples_location();
80 int2 render_extent = inst_.film.render_extent_get();
83 const int convolve_tile_count = setup_dispatch_size_.x * setup_dispatch_size_.y;
86 direct_light_tx_ = direct_diffuse_light_tx;
87 indirect_light_tx_ = indirect_diffuse_light_tx;
93 convolve_dispatch_buf_.clear_to_zero();
95 inst_.manager->submit(setup_ps_,
view);
96 inst_.manager->submit(convolve_ps_,
view);
98 object_id_tx_.release();
99 radiance_tx_.release();
102void SubsurfaceModule::precompute_samples_location()
113 double golden_angle =
M_PI * (3.0 -
sqrt(5.0));
115 float theta = golden_angle * i +
M_PI * 2.0f * rand_u;
117 float r = SubsurfaceModule::burley_sample(d,
x);
121 data_.
samples[i].z = 1.0f / burley_pdf(d, r);
139float SubsurfaceModule::burley_sample(
float d,
float x_rand)
143 const float tolerance = 1
e-6;
144 const int max_iteration_count = 10;
152 r =
exp(x_rand * x_rand * 2.4) - 1.0;
159 for (
int i = 0; i < max_iteration_count; i++) {
160 float exp_r_3 =
exp(-r / 3.0);
161 float exp_r = exp_r_3 * exp_r_3 * exp_r_3;
162 float f = 1.0 - 0.25 * exp_r - 0.75 * exp_r_3 - x_rand;
163 float f_ = 0.25 * exp_r + 0.25 * exp_r_3;
165 if (
abs(f) < tolerance || f_ == 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_texture(const char *name, GPUTexture *texture, GPUSamplerState state=sampler_auto)
void bind_resources(U &resources)
void bind_image(const char *name, GPUTexture *image)
void dispatch(int group_len)
void barrier(eGPUBarrier type)
void state_set(DRWState state, int clip_plane_count=0)
void bind_ssbo(const char *name, GPUStorageBuf *buffer)
void shader_set(GPUShader *shader)
UniformDataModule uniform_data
float rng_get(eSamplingDimension dimension) const
local_group_size(16, 16) .push_constant(Type local_group_size(16, 16) .push_constant(Type input_tx sampler(1, ImageType::FLOAT_2D, "matte_tx") .image(0
#define SUBSURFACE_RADIANCE_FORMAT
#define SUBSURFACE_GROUP_SIZE
#define SUBSURFACE_OBJECT_ID_FORMAT
draw_view in_light_buf[] float
#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(GPUTexture *direct_diffuse_light_tx, GPUTexture *indirect_diffuse_light_tx, eClosureBits active_closures, View &view)