Fix: Cycles: reuse random number for sampling color channel in volume
The same random number was used for sampling color channel at each step, which leads to bias. Fixed by rescaling the random number. Another possibility would be to scramble `rng_offset` and use a new random number each time, similar as in subsurface scattering, but rescaling random number should be faster than computing a new one, and is favorable here since the precision here is not very important Pull Request: https://projects.blender.org/blender/blender/pulls/127454
This commit is contained in:
committed by
Weizhen Huang
parent
2ca5a65add
commit
ee2fe7fa6c
@@ -153,7 +153,7 @@ ccl_device float volume_channel_get(Spectrum value, int channel)
|
||||
|
||||
ccl_device int volume_sample_channel(Spectrum albedo,
|
||||
Spectrum throughput,
|
||||
float rand,
|
||||
ccl_private float *rand,
|
||||
ccl_private Spectrum *pdf)
|
||||
{
|
||||
/* Sample color channel proportional to throughput and single scattering
|
||||
@@ -173,10 +173,13 @@ ccl_device int volume_sample_channel(Spectrum albedo,
|
||||
|
||||
float pdf_sum = 0.0f;
|
||||
FOREACH_SPECTRUM_CHANNEL (i) {
|
||||
pdf_sum += GET_SPECTRUM_CHANNEL(*pdf, i);
|
||||
if (rand < pdf_sum) {
|
||||
const float channel_pdf = GET_SPECTRUM_CHANNEL(*pdf, i);
|
||||
if (*rand < pdf_sum + channel_pdf) {
|
||||
/* Rescale to reuse. */
|
||||
*rand = (*rand - pdf_sum) / channel_pdf;
|
||||
return i;
|
||||
}
|
||||
pdf_sum += channel_pdf;
|
||||
}
|
||||
return SPECTRUM_CHANNELS - 1;
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ ccl_device_forceinline void volume_integrate_step_scattering(
|
||||
const Spectrum albedo = safe_divide_color(coeff.sigma_s, coeff.sigma_t);
|
||||
Spectrum channel_pdf;
|
||||
const int channel = volume_sample_channel(
|
||||
albedo, result.indirect_throughput, vstate.rchannel, &channel_pdf);
|
||||
albedo, result.indirect_throughput, &vstate.rchannel, &channel_pdf);
|
||||
|
||||
/* Equiangular sampling for direct lighting. */
|
||||
if (vstate.direct_sample_method == VOLUME_SAMPLE_EQUIANGULAR && !result.direct_scatter) {
|
||||
|
||||
@@ -269,7 +269,7 @@ ccl_device_inline bool subsurface_random_walk(KernelGlobals kg,
|
||||
/* Sample color channel, use MIS with balance heuristic. */
|
||||
float rchannel = path_state_rng_1D(kg, &rng_state, PRNG_SUBSURFACE_COLOR_CHANNEL);
|
||||
Spectrum channel_pdf;
|
||||
int channel = volume_sample_channel(alpha, throughput, rchannel, &channel_pdf);
|
||||
int channel = volume_sample_channel(alpha, throughput, &rchannel, &channel_pdf);
|
||||
float sample_sigma_t = volume_channel_get(sigma_t, channel);
|
||||
float randt = path_state_rng_1D(kg, &rng_state, PRNG_SUBSURFACE_SCATTER_DISTANCE);
|
||||
|
||||
|
||||
Submodule tests/data updated: bbe5fbe084...ee017c3e97
Reference in New Issue
Block a user