Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-09-14 23:56:32 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-09-20 20:38:08 +0300
commit095a01a73a35d3af57573fc724d381bcca019f54 (patch)
tree3f22c746d1e9ae75365ade400ca08e0ae255788e /intern/cycles/kernel/kernel_shader.h
parentb3afc8917cdeaa98ebfa3f2aa17e8c5a69fdb1e3 (diff)
Cycles: slightly improve BSDF sample stratification for path tracing.
Similar to what we did for area lights previously, this should help preserve stratification when using multiple BSDFs in theory. Improvements are not easily noticeable in practice though, because the number of BSDFs is usually low. Still nice to eliminate one sampling dimension.
Diffstat (limited to 'intern/cycles/kernel/kernel_shader.h')
-rw-r--r--intern/cycles/kernel/kernel_shader.h50
1 files changed, 33 insertions, 17 deletions
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 88aa1f712a4..5ef4475e259 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -575,7 +575,8 @@ void shader_bsdf_eval(KernelGlobals *kg,
}
}
-ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
+ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd,
+ float *randu)
{
int sampled = 0;
@@ -591,19 +592,25 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
}
}
- float r = sd->randb_closure*sum;
+ float r = (*randu)*sum;
float partial_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) {
- partial_sum += sc->sample_weight;
+ float next_sum = partial_sum + sc->sample_weight;
- if(r <= partial_sum) {
+ if(r < next_sum) {
sampled = i;
+
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
break;
}
+
+ partial_sum = next_sum;
}
}
}
@@ -612,7 +619,8 @@ ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd)
}
ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
- ccl_addr_space float3 *throughput)
+ ccl_addr_space float3 *throughput,
+ float *randu)
{
int sampled = 0;
@@ -632,16 +640,16 @@ ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
}
}
- float r = sd->randb_closure*(sum_bsdf + sum_bssrdf);
+ float r = (*randu)*(sum_bsdf + sum_bssrdf);
float partial_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
- partial_sum += sc->sample_weight;
+ float next_sum = partial_sum + sc->sample_weight;
- if(r <= partial_sum) {
+ if(r < next_sum) {
if(CLOSURE_IS_BSDF(sc->type)) {
*throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
return NULL;
@@ -649,9 +657,15 @@ ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
else {
*throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
sampled = i;
+
+ /* Rescale to reuse for direction sample, to better
+ * preserve stratifaction. */
+ *randu = (r - partial_sum) / sc->sample_weight;
break;
}
}
+
+ partial_sum = next_sum;
}
}
}
@@ -667,7 +681,7 @@ ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
differential3 *domega_in,
float *pdf)
{
- const ShaderClosure *sc = shader_bsdf_pick(sd);
+ const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
if(!sc) {
*pdf = 0.0f;
return LABEL_NONE;
@@ -923,11 +937,10 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */
ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
- ccl_addr_space PathState *state, float randb, int path_flag)
+ ccl_addr_space PathState *state, int path_flag)
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
- sd->randb_closure = randb;
#ifdef __OSL__
if(kg->osl)
@@ -958,7 +971,6 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd,
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
- sd->randb_closure = 0.0f;
#ifdef __SVM__
#ifdef __OSL__
@@ -1040,17 +1052,22 @@ ccl_device int shader_volume_phase_sample(KernelGlobals *kg, const ShaderData *s
sum += sc->sample_weight;
}
- float r = sd->randb_closure*sum;
- sum = 0.0f;
+ float r = randu*sum;
+ float partial_sum = 0.0f;
for(sampled = 0; sampled < sd->num_closure; sampled++) {
const ShaderClosure *sc = &sd->closure[sampled];
if(CLOSURE_IS_PHASE(sc->type)) {
- sum += sc->sample_weight;
+ float next_sum = partial_sum + sc->sample_weight;
- if(r <= sum)
+ if(r <= next_sum) {
+ /* Rescale to reuse for BSDF direction sample. */
+ randu = (r - partial_sum) / sc->sample_weight;
break;
+ }
+
+ partial_sum = next_sum;
}
}
@@ -1154,7 +1171,6 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
- sd->randb_closure = 0.0f;
/* this will modify sd->P */
#ifdef __SVM__