123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- * Copyright 2011-2013 Blender Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- CCL_NAMESPACE_BEGIN
- ccl_device_inline void path_state_init(KernelGlobals *kg,
- ShaderData *stack_sd,
- ccl_addr_space PathState *state,
- uint rng_hash,
- int sample,
- ccl_addr_space Ray *ray)
- {
- state->flag = PATH_RAY_CAMERA | PATH_RAY_MIS_SKIP | PATH_RAY_TRANSPARENT_BACKGROUND;
- state->rng_hash = rng_hash;
- state->rng_offset = PRNG_BASE_NUM;
- state->sample = sample;
- state->num_samples = kernel_data.integrator.aa_samples;
- state->branch_factor = 1.0f;
- state->bounce = 0;
- state->diffuse_bounce = 0;
- state->glossy_bounce = 0;
- state->transmission_bounce = 0;
- state->transparent_bounce = 0;
- #ifdef __DENOISING_FEATURES__
- if (kernel_data.film.pass_denoising_data) {
- state->flag |= PATH_RAY_STORE_SHADOW_INFO;
- state->denoising_feature_weight = 1.0f;
- }
- else {
- state->denoising_feature_weight = 0.0f;
- }
- #endif /* __DENOISING_FEATURES__ */
- state->min_ray_pdf = FLT_MAX;
- state->ray_pdf = 0.0f;
- #ifdef __LAMP_MIS__
- state->ray_t = 0.0f;
- #endif
- #ifdef __VOLUME__
- state->volume_bounce = 0;
- state->volume_bounds_bounce = 0;
- if (kernel_data.integrator.use_volumes) {
- /* Initialize volume stack with volume we are inside of. */
- kernel_volume_stack_init(kg, stack_sd, state, ray, state->volume_stack);
- }
- else {
- state->volume_stack[0].shader = SHADER_NONE;
- }
- #endif
- }
- ccl_device_inline void path_state_next(KernelGlobals *kg,
- ccl_addr_space PathState *state,
- int label)
- {
- /* ray through transparent keeps same flags from previous ray and is
- * not counted as a regular bounce, transparent has separate max */
- if (label & LABEL_TRANSPARENT) {
- state->flag |= PATH_RAY_TRANSPARENT;
- state->transparent_bounce++;
- if (state->transparent_bounce >= kernel_data.integrator.transparent_max_bounce) {
- state->flag |= PATH_RAY_TERMINATE_IMMEDIATE;
- }
- if (!kernel_data.integrator.transparent_shadows)
- state->flag |= PATH_RAY_MIS_SKIP;
- /* random number generator next bounce */
- state->rng_offset += PRNG_BOUNCE_NUM;
- return;
- }
- state->bounce++;
- if (state->bounce >= kernel_data.integrator.max_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- state->flag &= ~(PATH_RAY_ALL_VISIBILITY | PATH_RAY_MIS_SKIP);
- #ifdef __VOLUME__
- if (label & LABEL_VOLUME_SCATTER) {
- /* volume scatter */
- state->flag |= PATH_RAY_VOLUME_SCATTER;
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
- state->volume_bounce++;
- if (state->volume_bounce >= kernel_data.integrator.max_volume_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- else
- #endif
- {
- /* surface reflection/transmission */
- if (label & LABEL_REFLECT) {
- state->flag |= PATH_RAY_REFLECT;
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
- if (label & LABEL_DIFFUSE) {
- state->diffuse_bounce++;
- if (state->diffuse_bounce >= kernel_data.integrator.max_diffuse_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- else {
- state->glossy_bounce++;
- if (state->glossy_bounce >= kernel_data.integrator.max_glossy_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- }
- else {
- kernel_assert(label & LABEL_TRANSMIT);
- state->flag |= PATH_RAY_TRANSMIT;
- if (!(label & LABEL_TRANSMIT_TRANSPARENT)) {
- state->flag &= ~PATH_RAY_TRANSPARENT_BACKGROUND;
- }
- state->transmission_bounce++;
- if (state->transmission_bounce >= kernel_data.integrator.max_transmission_bounce) {
- state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
- }
- }
- /* diffuse/glossy/singular */
- if (label & LABEL_DIFFUSE) {
- state->flag |= PATH_RAY_DIFFUSE | PATH_RAY_DIFFUSE_ANCESTOR;
- }
- else if (label & LABEL_GLOSSY) {
- state->flag |= PATH_RAY_GLOSSY;
- }
- else {
- kernel_assert(label & LABEL_SINGULAR);
- state->flag |= PATH_RAY_GLOSSY | PATH_RAY_SINGULAR | PATH_RAY_MIS_SKIP;
- }
- }
- /* random number generator next bounce */
- state->rng_offset += PRNG_BOUNCE_NUM;
- #ifdef __DENOISING_FEATURES__
- if ((state->denoising_feature_weight == 0.0f) && !(state->flag & PATH_RAY_SHADOW_CATCHER)) {
- state->flag &= ~PATH_RAY_STORE_SHADOW_INFO;
- }
- #endif
- }
- #ifdef __VOLUME__
- ccl_device_inline bool path_state_volume_next(KernelGlobals *kg, ccl_addr_space PathState *state)
- {
- /* For volume bounding meshes we pass through without counting transparent
- * bounces, only sanity check in case self intersection gets us stuck. */
- state->volume_bounds_bounce++;
- if (state->volume_bounds_bounce > VOLUME_BOUNDS_MAX) {
- return false;
- }
- /* Random number generator next bounce. */
- if (state->volume_bounds_bounce > 1) {
- state->rng_offset += PRNG_BOUNCE_NUM;
- }
- return true;
- }
- #endif
- ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg,
- ccl_addr_space PathState *state)
- {
- uint flag = state->flag & PATH_RAY_ALL_VISIBILITY;
- /* for visibility, diffuse/glossy are for reflection only */
- if (flag & PATH_RAY_TRANSMIT)
- flag &= ~(PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY);
- /* todo: this is not supported as its own ray visibility yet */
- if (state->flag & PATH_RAY_VOLUME_SCATTER)
- flag |= PATH_RAY_DIFFUSE;
- return flag;
- }
- ccl_device_inline float path_state_continuation_probability(KernelGlobals *kg,
- ccl_addr_space PathState *state,
- const float3 throughput)
- {
- if (state->flag & PATH_RAY_TERMINATE_IMMEDIATE) {
- /* Ray is to be terminated immediately. */
- return 0.0f;
- }
- else if (state->flag & PATH_RAY_TRANSPARENT) {
- /* Do at least specified number of bounces without RR. */
- if (state->transparent_bounce <= kernel_data.integrator.transparent_min_bounce) {
- return 1.0f;
- }
- #ifdef __SHADOW_TRICKS__
- /* Exception for shadow catcher not working correctly with RR. */
- else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
- return 1.0f;
- }
- #endif
- }
- else {
- /* Do at least specified number of bounces without RR. */
- if (state->bounce <= kernel_data.integrator.min_bounce) {
- return 1.0f;
- }
- #ifdef __SHADOW_TRICKS__
- /* Exception for shadow catcher not working correctly with RR. */
- else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
- return 1.0f;
- }
- #endif
- }
- /* Probabilistic termination: use sqrt() to roughly match typical view
- * transform and do path termination a bit later on average. */
- return min(sqrtf(max3(fabs(throughput)) * state->branch_factor), 1.0f);
- }
- /* TODO(DingTo): Find more meaningful name for this */
- ccl_device_inline void path_state_modify_bounce(ccl_addr_space PathState *state, bool increase)
- {
- /* Modify bounce temporarily for shader eval */
- if (increase)
- state->bounce += 1;
- else
- state->bounce -= 1;
- }
- ccl_device_inline bool path_state_ao_bounce(KernelGlobals *kg, ccl_addr_space PathState *state)
- {
- if (state->bounce <= kernel_data.integrator.ao_bounces) {
- return false;
- }
- int bounce = state->bounce - state->transmission_bounce - (state->glossy_bounce > 0);
- return (bounce > kernel_data.integrator.ao_bounces);
- }
- ccl_device_inline void path_state_branch(ccl_addr_space PathState *state,
- int branch,
- int num_branches)
- {
- if (num_branches > 1) {
- /* Path is splitting into a branch, adjust so that each branch
- * still gets a unique sample from the same sequence. */
- state->sample = state->sample * num_branches + branch;
- state->num_samples = state->num_samples * num_branches;
- state->branch_factor *= num_branches;
- }
- }
- CCL_NAMESPACE_END
|