Cycles: Add OpenCL support for shadow catcher feature
The title says it all actually.
This commit is contained in:
parent
8ada7f7397
commit
e07ffcbd1c
@ -16,11 +16,18 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#if (defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__)) && !defined(__SPLIT_KERNEL__)
|
||||
#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) || defined(__SHADOW_TRICKS__)
|
||||
/* branched path tracing: connect path directly to position on one or more lights and add it to L */
|
||||
ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobals *kg, RNG *rng,
|
||||
ShaderData *sd, ShaderData *emission_sd, PathState *state, float3 throughput,
|
||||
float num_samples_adjust, PathRadiance *L, int sample_all_lights)
|
||||
ccl_device_noinline void kernel_branched_path_surface_connect_light(
|
||||
KernelGlobals *kg,
|
||||
RNG *rng,
|
||||
ShaderData *sd,
|
||||
ShaderData *emission_sd,
|
||||
ccl_addr_space PathState *state,
|
||||
float3 throughput,
|
||||
float num_samples_adjust,
|
||||
PathRadiance *L,
|
||||
int sample_all_lights)
|
||||
{
|
||||
#ifdef __EMISSION__
|
||||
/* sample illumination from lights to find path contribution */
|
||||
@ -138,9 +145,17 @@ ccl_device_noinline void kernel_branched_path_surface_connect_light(KernelGlobal
|
||||
}
|
||||
|
||||
/* branched path tracing: bounce off or through surface to with new direction stored in ray */
|
||||
ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng,
|
||||
ShaderData *sd, const ShaderClosure *sc, int sample, int num_samples,
|
||||
float3 *throughput, PathState *state, PathRadiance *L, Ray *ray)
|
||||
ccl_device bool kernel_branched_path_surface_bounce(
|
||||
KernelGlobals *kg,
|
||||
RNG *rng,
|
||||
ShaderData *sd,
|
||||
const ShaderClosure *sc,
|
||||
int sample,
|
||||
int num_samples,
|
||||
ccl_addr_space float3 *throughput,
|
||||
ccl_addr_space PathState *state,
|
||||
PathRadiance *L,
|
||||
Ray *ray)
|
||||
{
|
||||
/* sample BSDF */
|
||||
float bsdf_pdf;
|
||||
|
@ -117,10 +117,18 @@ bool kernel_path_volume_bounce(
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef __BRANCHED_PATH__
|
||||
ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG *rng,
|
||||
ShaderData *sd, ShaderData *emission_sd, float3 throughput, PathState *state, PathRadiance *L,
|
||||
bool sample_all_lights, Ray *ray, const VolumeSegment *segment)
|
||||
#ifndef __SPLIT_KERNEL__
|
||||
ccl_device void kernel_branched_path_volume_connect_light(
|
||||
KernelGlobals *kg,
|
||||
RNG *rng,
|
||||
ShaderData *sd,
|
||||
ShaderData *emission_sd,
|
||||
float3 throughput,
|
||||
ccl_addr_space PathState *state,
|
||||
PathRadiance *L,
|
||||
bool sample_all_lights,
|
||||
Ray *ray,
|
||||
const VolumeSegment *segment)
|
||||
{
|
||||
#ifdef __EMISSION__
|
||||
if(!kernel_data.integrator.use_direct_light)
|
||||
@ -270,7 +278,7 @@ ccl_device void kernel_branched_path_volume_connect_light(KernelGlobals *kg, RNG
|
||||
}
|
||||
#endif /* __EMISSION__ */
|
||||
}
|
||||
#endif /* __BRANCHED_PATH__ */
|
||||
#endif /* __SPLIT_KERNEL__ */
|
||||
|
||||
#endif /* __VOLUME_SCATTER__ */
|
||||
|
||||
|
@ -282,18 +282,18 @@ ccl_device_inline void path_state_rng_2D(KernelGlobals *kg, RNG *rng, const ccl_
|
||||
path_rng_2D(kg, rng, state->sample, state->num_samples, state->rng_offset + dimension, fx, fy);
|
||||
}
|
||||
|
||||
ccl_device_inline float path_branched_rng_1D(KernelGlobals *kg, RNG *rng, const PathState *state, int branch, int num_branches, int dimension)
|
||||
ccl_device_inline float path_branched_rng_1D(KernelGlobals *kg, RNG *rng, const ccl_addr_space PathState *state, int branch, int num_branches, int dimension)
|
||||
{
|
||||
return path_rng_1D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, state->rng_offset + dimension);
|
||||
}
|
||||
|
||||
ccl_device_inline float path_branched_rng_1D_for_decision(KernelGlobals *kg, RNG *rng, const PathState *state, int branch, int num_branches, int dimension)
|
||||
ccl_device_inline float path_branched_rng_1D_for_decision(KernelGlobals *kg, RNG *rng, const ccl_addr_space PathState *state, int branch, int num_branches, int dimension)
|
||||
{
|
||||
int rng_offset = state->rng_offset + state->transparent_bounce*PRNG_BOUNCE_NUM;
|
||||
return path_rng_1D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, rng_offset + dimension);
|
||||
}
|
||||
|
||||
ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg, RNG *rng, const PathState *state, int branch, int num_branches, int dimension, float *fx, float *fy)
|
||||
ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg, RNG *rng, const ccl_addr_space PathState *state, int branch, int num_branches, int dimension, float *fx, float *fy)
|
||||
{
|
||||
path_rng_2D(kg, rng, state->sample*num_branches + branch, state->num_samples*num_branches, state->rng_offset + dimension, fx, fy);
|
||||
}
|
||||
@ -307,7 +307,7 @@ ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg, RNG
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg, RNG *rng, const PathState *state, int branch, int num_branches)
|
||||
ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg, RNG *rng, const ccl_addr_space PathState *state, int branch, int num_branches)
|
||||
{
|
||||
if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
|
||||
return path_branched_rng_1D_for_decision(kg, rng, state, branch, num_branches, PRNG_LIGHT_TERMINATE);
|
||||
@ -315,7 +315,7 @@ ccl_device_inline float path_branched_rng_light_termination(KernelGlobals *kg, R
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
ccl_device_inline void path_state_branch(PathState *state, int branch, int num_branches)
|
||||
ccl_device_inline void path_state_branch(ccl_addr_space PathState *state, int branch, int num_branches)
|
||||
{
|
||||
/* path is splitting into a branch, adjust so that each branch
|
||||
* still gets a unique sample from the same sequence */
|
||||
|
@ -157,10 +157,7 @@ CCL_NAMESPACE_BEGIN
|
||||
#define __INTERSECTION_REFINE__
|
||||
#define __CLAMP_SAMPLE__
|
||||
#define __PATCH_EVAL__
|
||||
|
||||
#ifndef __SPLIT_KERNEL__
|
||||
# define __SHADOW_TRICKS__
|
||||
#endif
|
||||
#define __SHADOW_TRICKS__
|
||||
|
||||
#ifdef __KERNEL_SHADING__
|
||||
# define __SVM__
|
||||
|
@ -111,7 +111,16 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
|
||||
buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride;
|
||||
|
||||
if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
|
||||
float3 L_sum = path_radiance_clamp_and_sum(kg, L);
|
||||
float3 L_sum;
|
||||
#ifdef __SHADOW_TRICKS__
|
||||
if(state->flag & PATH_RAY_SHADOW_CATCHER) {
|
||||
L_sum = path_radiance_sum_shadowcatcher(kg, L, L_transparent);
|
||||
}
|
||||
else
|
||||
#endif /* __SHADOW_TRICKS__ */
|
||||
{
|
||||
L_sum = path_radiance_clamp_and_sum(kg, L);
|
||||
}
|
||||
kernel_write_light_passes(kg, buffer, L, sample);
|
||||
#ifdef __KERNEL_DEBUG__
|
||||
kernel_write_debug_passes(kg, buffer, state, debug_data, sample);
|
||||
|
@ -79,16 +79,32 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
|
||||
|
||||
/* direct lighting */
|
||||
#ifdef __EMISSION__
|
||||
if((kernel_data.integrator.use_direct_light &&
|
||||
(sd->flag & SD_BSDF_HAS_EVAL)))
|
||||
{
|
||||
RNG rng = kernel_split_state.rng[ray_index];
|
||||
bool flag = (kernel_data.integrator.use_direct_light &&
|
||||
(sd->flag & SD_BSDF_HAS_EVAL));
|
||||
# ifdef __SHADOW_TRICKS__
|
||||
if(flag && state->flag & PATH_RAY_SHADOW_CATCHER) {
|
||||
flag = false;
|
||||
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
|
||||
float3 throughput = kernel_split_state.throughput[ray_index];
|
||||
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
|
||||
kernel_branched_path_surface_connect_light(kg,
|
||||
&rng,
|
||||
sd,
|
||||
emission_sd,
|
||||
state,
|
||||
throughput,
|
||||
1.0f,
|
||||
L,
|
||||
1);
|
||||
}
|
||||
# endif /* __SHADOW_TRICKS__ */
|
||||
if(flag) {
|
||||
/* Sample illumination from lights to find path contribution. */
|
||||
RNG rng = kernel_split_state.rng[ray_index];
|
||||
float light_t = path_state_rng_1D(kg, &rng, state, PRNG_LIGHT);
|
||||
float light_u, light_v;
|
||||
path_state_rng_2D(kg, &rng, state, PRNG_LIGHT_U, &light_u, &light_v);
|
||||
float terminate = path_state_rng_light_termination(kg, &rng, state);
|
||||
kernel_split_state.rng[ray_index] = rng;
|
||||
|
||||
LightSample ls;
|
||||
if(light_sample(kg,
|
||||
@ -99,9 +115,9 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
|
||||
&ls)) {
|
||||
|
||||
Ray light_ray;
|
||||
#ifdef __OBJECT_MOTION__
|
||||
# ifdef __OBJECT_MOTION__
|
||||
light_ray.time = sd->time;
|
||||
#endif
|
||||
# endif
|
||||
|
||||
BsdfEval L_light;
|
||||
bool is_lamp;
|
||||
@ -118,6 +134,7 @@ ccl_device void kernel_direct_lighting(KernelGlobals *kg,
|
||||
}
|
||||
}
|
||||
}
|
||||
kernel_split_state.rng[ray_index] = rng;
|
||||
#endif /* __EMISSION__ */
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,23 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
|
||||
|
||||
buffer += (kernel_split_params.offset + pixel_x + pixel_y * stride) * kernel_data.film.pass_stride;
|
||||
|
||||
#ifdef __SHADOW_TRICKS__
|
||||
if((sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
|
||||
if (state->flag & PATH_RAY_CAMERA) {
|
||||
state->flag |= (PATH_RAY_SHADOW_CATCHER | PATH_RAY_SHADOW_CATCHER_ONLY);
|
||||
state->catcher_object = sd->object;
|
||||
if(!kernel_data.background.transparent) {
|
||||
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
|
||||
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
|
||||
L->shadow_color = indirect_background(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, ray);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
state->flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
|
||||
}
|
||||
#endif /* __SHADOW_TRICKS__ */
|
||||
|
||||
/* holdout */
|
||||
#ifdef __HOLDOUT__
|
||||
if(((sd->flag & SD_HOLDOUT) ||
|
||||
|
@ -117,6 +117,9 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
shadow,
|
||||
state->bounce);
|
||||
}
|
||||
else {
|
||||
path_radiance_accum_total_ao(L, _throughput, kernel_split_state.ao_bsdf[ray_index]);
|
||||
}
|
||||
REMOVE_RAY_FLAG(ray_state, ray_index, RAY_SHADOW_RAY_CAST_AO);
|
||||
}
|
||||
|
||||
@ -124,8 +127,8 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
float3 shadow = kernel_split_state.light_ray[ray_index].P;
|
||||
// TODO(mai): investigate correctness here
|
||||
char update_path_radiance = (char)kernel_split_state.light_ray[ray_index].t;
|
||||
BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index];
|
||||
if(update_path_radiance) {
|
||||
BsdfEval L_light = kernel_split_state.bsdf_eval[ray_index];
|
||||
path_radiance_accum_light(L,
|
||||
_throughput,
|
||||
&L_light,
|
||||
@ -134,6 +137,9 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
state->bounce,
|
||||
kernel_split_state.is_lamp[ray_index]);
|
||||
}
|
||||
else {
|
||||
path_radiance_accum_total_light(L, _throughput, &L_light);
|
||||
}
|
||||
REMOVE_RAY_FLAG(ray_state, ray_index, RAY_SHADOW_RAY_CAST_DL);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user