Merge branch 'master' into blender2.8
This commit is contained in:
@@ -445,8 +445,15 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Setup and evaluate shader. */
|
||||
/* Setup shader data. */
|
||||
shader_setup_from_ray(kg, sd, &isect, ray);
|
||||
|
||||
/* Skip most work for volume bounding surface. */
|
||||
#ifdef __VOLUME__
|
||||
if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
|
||||
#endif
|
||||
|
||||
/* Evaluate shader. */
|
||||
shader_eval_surface(kg, sd, state, state->flag);
|
||||
shader_prepare_closures(sd, state);
|
||||
|
||||
@@ -523,6 +530,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
||||
}
|
||||
#endif /* defined(__EMISSION__) */
|
||||
|
||||
#ifdef __VOLUME__
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!kernel_path_surface_bounce(kg, sd, &throughput, state, &L->state, ray))
|
||||
break;
|
||||
}
|
||||
@@ -605,8 +616,15 @@ ccl_device_forceinline void kernel_path_integrate(
|
||||
break;
|
||||
}
|
||||
|
||||
/* Setup and evaluate shader. */
|
||||
/* Setup shader data. */
|
||||
shader_setup_from_ray(kg, &sd, &isect, ray);
|
||||
|
||||
/* Skip most work for volume bounding surface. */
|
||||
#ifdef __VOLUME__
|
||||
if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
|
||||
#endif
|
||||
|
||||
/* Evaluate shader. */
|
||||
shader_eval_surface(kg, &sd, state, state->flag);
|
||||
shader_prepare_closures(&sd, state);
|
||||
|
||||
@@ -669,6 +687,10 @@ ccl_device_forceinline void kernel_path_integrate(
|
||||
/* direct lighting */
|
||||
kernel_path_surface_connect_light(kg, &sd, emission_sd, throughput, state, L);
|
||||
|
||||
#ifdef __VOLUME__
|
||||
}
|
||||
#endif
|
||||
|
||||
/* compute direct lighting and next bounce */
|
||||
if(!kernel_path_surface_bounce(kg, &sd, &throughput, state, &L->state, ray))
|
||||
break;
|
||||
|
||||
@@ -480,6 +480,12 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
|
||||
|
||||
/* Setup and evaluate shader. */
|
||||
shader_setup_from_ray(kg, &sd, &isect, &ray);
|
||||
|
||||
/* Skip most work for volume bounding surface. */
|
||||
#ifdef __VOLUME__
|
||||
if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
|
||||
#endif
|
||||
|
||||
shader_eval_surface(kg, &sd, &state, state.flag);
|
||||
shader_merge_closures(&sd);
|
||||
|
||||
@@ -533,37 +539,46 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
|
||||
}
|
||||
#endif /* __SUBSURFACE__ */
|
||||
|
||||
if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {
|
||||
PathState hit_state = state;
|
||||
PathState hit_state = state;
|
||||
|
||||
#ifdef __EMISSION__
|
||||
/* direct light */
|
||||
if(kernel_data.integrator.use_direct_light) {
|
||||
int all = (kernel_data.integrator.sample_all_lights_direct) ||
|
||||
(state.flag & PATH_RAY_SHADOW_CATCHER);
|
||||
kernel_branched_path_surface_connect_light(kg,
|
||||
&sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
|
||||
}
|
||||
/* direct light */
|
||||
if(kernel_data.integrator.use_direct_light) {
|
||||
int all = (kernel_data.integrator.sample_all_lights_direct) ||
|
||||
(state.flag & PATH_RAY_SHADOW_CATCHER);
|
||||
kernel_branched_path_surface_connect_light(kg,
|
||||
&sd, emission_sd, &hit_state, throughput, 1.0f, L, all);
|
||||
}
|
||||
#endif /* __EMISSION__ */
|
||||
|
||||
/* indirect light */
|
||||
kernel_branched_path_surface_indirect_light(kg,
|
||||
&sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
|
||||
/* indirect light */
|
||||
kernel_branched_path_surface_indirect_light(kg,
|
||||
&sd, &indirect_sd, emission_sd, throughput, 1.0f, &hit_state, L);
|
||||
|
||||
/* continue in case of transparency */
|
||||
throughput *= shader_bsdf_transparency(kg, &sd);
|
||||
/* continue in case of transparency */
|
||||
throughput *= shader_bsdf_transparency(kg, &sd);
|
||||
|
||||
if(is_zero(throughput))
|
||||
break;
|
||||
}
|
||||
if(is_zero(throughput))
|
||||
break;
|
||||
|
||||
/* Update Path State */
|
||||
path_state_next(kg, &state, LABEL_TRANSPARENT);
|
||||
|
||||
#ifdef __VOLUME__
|
||||
}
|
||||
else {
|
||||
/* 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) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ray.P = ray_offset(sd.P, -sd.Ng);
|
||||
ray.t -= sd.ray_length; /* clipping works through transparent */
|
||||
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
ray.dP = sd.dP;
|
||||
ray.dD.dx = -sd.dI.dx;
|
||||
|
||||
@@ -55,6 +55,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
|
||||
|
||||
#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. */
|
||||
|
||||
@@ -329,10 +329,12 @@ ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg,
|
||||
}
|
||||
#ifdef __VOLUME__
|
||||
else if(sd->flag & SD_HAS_ONLY_VOLUME) {
|
||||
/* no surface shader but have a volume shader? act transparent */
|
||||
|
||||
/* update path state, count as transparent */
|
||||
path_state_next(kg, state, LABEL_TRANSPARENT);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if(state->bounce == 0)
|
||||
ray->t -= sd->ray_length; /* clipping works through transparent */
|
||||
|
||||
@@ -49,6 +49,8 @@ CCL_NAMESPACE_BEGIN
|
||||
#define BSSRDF_MAX_BOUNCES 256
|
||||
#define LOCAL_MAX_HITS 4
|
||||
|
||||
#define VOLUME_BOUNDS_MAX 1024
|
||||
|
||||
#define BECKMANN_TABLE_SIZE 256
|
||||
|
||||
#define SHADER_NONE (~0)
|
||||
@@ -1107,6 +1109,7 @@ typedef struct PathState {
|
||||
/* volume rendering */
|
||||
#ifdef __VOLUME__
|
||||
int volume_bounce;
|
||||
int volume_bounds_bounce;
|
||||
uint rng_congruential;
|
||||
VolumeStack volume_stack[VOLUME_STACK_SIZE];
|
||||
#endif
|
||||
@@ -1497,8 +1500,10 @@ enum RayState {
|
||||
RAY_ACTIVE,
|
||||
/* Denotes ray has completed processing all samples and is inactive. */
|
||||
RAY_INACTIVE,
|
||||
/* Denoted ray has exited path-iteration and needs to update output buffer. */
|
||||
/* Denotes ray has exited path-iteration and needs to update output buffer. */
|
||||
RAY_UPDATE_BUFFER,
|
||||
/* Denotes ray needs to skip most surface shader work. */
|
||||
RAY_HAS_ONLY_VOLUME,
|
||||
/* Donotes ray has hit background */
|
||||
RAY_HIT_BACKGROUND,
|
||||
/* Denotes ray has to be regenerated */
|
||||
|
||||
@@ -53,39 +53,52 @@ ccl_device_inline void kernel_split_branched_indirect_light_init(KernelGlobals *
|
||||
ADD_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_LIGHT_INDIRECT);
|
||||
}
|
||||
|
||||
ccl_device void kernel_split_branched_indirect_light_end(KernelGlobals *kg, int ray_index)
|
||||
ccl_device void kernel_split_branched_transparent_bounce(KernelGlobals *kg, int ray_index)
|
||||
{
|
||||
kernel_split_branched_path_indirect_loop_end(kg, ray_index);
|
||||
|
||||
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
|
||||
ShaderData *sd = kernel_split_sd(sd, ray_index);
|
||||
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
|
||||
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
|
||||
|
||||
/* continue in case of transparency */
|
||||
*throughput *= shader_bsdf_transparency(kg, sd);
|
||||
# ifdef __VOLUME__
|
||||
if(!(sd->flag & SD_HAS_ONLY_VOLUME)) {
|
||||
# endif
|
||||
/* continue in case of transparency */
|
||||
*throughput *= shader_bsdf_transparency(kg, sd);
|
||||
|
||||
if(is_zero(*throughput)) {
|
||||
kernel_split_path_end(kg, ray_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if(is_zero(*throughput)) {
|
||||
kernel_split_path_end(kg, ray_index);
|
||||
}
|
||||
else {
|
||||
/* Update Path State */
|
||||
path_state_next(kg, state, LABEL_TRANSPARENT);
|
||||
# ifdef __VOLUME__
|
||||
}
|
||||
else {
|
||||
/* 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) {
|
||||
kernel_split_path_end(kg, ray_index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
ray->P = ray_offset(sd->P, -sd->Ng);
|
||||
ray->t -= sd->ray_length; /* clipping works through transparent */
|
||||
ray->P = ray_offset(sd->P, -sd->Ng);
|
||||
ray->t -= sd->ray_length; /* clipping works through transparent */
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
ray->dP = sd->dP;
|
||||
ray->dD.dx = -sd->dI.dx;
|
||||
ray->dD.dy = -sd->dI.dy;
|
||||
ray->dP = sd->dP;
|
||||
ray->dD.dx = -sd->dI.dx;
|
||||
ray->dD.dy = -sd->dI.dy;
|
||||
# endif /* __RAY_DIFFERENTIALS__ */
|
||||
|
||||
# ifdef __VOLUME__
|
||||
/* enter/exit volume */
|
||||
kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
|
||||
/* enter/exit volume */
|
||||
kernel_volume_stack_enter_exit(kg, sd, state->volume_stack);
|
||||
# endif /* __VOLUME__ */
|
||||
}
|
||||
}
|
||||
#endif /* __BRANCHED_PATH__ */
|
||||
|
||||
@@ -121,6 +134,13 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
|
||||
ccl_global char *ray_state = kernel_split_state.ray_state;
|
||||
|
||||
# ifdef __VOLUME__
|
||||
/* Reactivate only volume rays here, most surface work was skipped. */
|
||||
if(IS_STATE(ray_state, ray_index, RAY_HAS_ONLY_VOLUME)) {
|
||||
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_ACTIVE);
|
||||
}
|
||||
# endif
|
||||
|
||||
bool active = IS_STATE(ray_state, ray_index, RAY_ACTIVE);
|
||||
if(active) {
|
||||
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
|
||||
@@ -138,6 +158,9 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
}
|
||||
#ifdef __BRANCHED_PATH__
|
||||
}
|
||||
else if(sd->flag & SD_HAS_ONLY_VOLUME) {
|
||||
kernel_split_branched_transparent_bounce(kg, ray_index);
|
||||
}
|
||||
else {
|
||||
kernel_split_branched_indirect_light_init(kg, ray_index);
|
||||
|
||||
@@ -151,7 +174,8 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
|
||||
}
|
||||
else {
|
||||
kernel_split_branched_indirect_light_end(kg, ray_index);
|
||||
kernel_split_branched_path_indirect_loop_end(kg, ray_index);
|
||||
kernel_split_branched_transparent_bounce(kg, ray_index);
|
||||
}
|
||||
}
|
||||
#endif /* __BRANCHED_PATH__ */
|
||||
@@ -196,7 +220,8 @@ ccl_device void kernel_next_iteration_setup(KernelGlobals *kg,
|
||||
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
|
||||
}
|
||||
else {
|
||||
kernel_split_branched_indirect_light_end(kg, ray_index);
|
||||
kernel_split_branched_path_indirect_loop_end(kg, ray_index);
|
||||
kernel_split_branched_transparent_bounce(kg, ray_index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ ccl_device void kernel_queue_enqueue(KernelGlobals *kg,
|
||||
queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
|
||||
}
|
||||
else if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
|
||||
IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME) ||
|
||||
IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
|
||||
queue_number = QUEUE_ACTIVE_AND_REGENERATED_RAYS;
|
||||
}
|
||||
|
||||
@@ -59,12 +59,20 @@ ccl_device void kernel_shader_setup(KernelGlobals *kg,
|
||||
if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE)) {
|
||||
Intersection isect = kernel_split_state.isect[ray_index];
|
||||
Ray ray = kernel_split_state.ray[ray_index];
|
||||
ShaderData *sd = kernel_split_sd(sd, ray_index);
|
||||
|
||||
shader_setup_from_ray(kg,
|
||||
kernel_split_sd(sd, ray_index),
|
||||
sd,
|
||||
&isect,
|
||||
&ray);
|
||||
|
||||
#ifdef __VOLUME__
|
||||
if(sd->flag & SD_HAS_ONLY_VOLUME) {
|
||||
ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_HAS_ONLY_VOLUME);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -149,29 +149,6 @@ bool GPU_select_load_id(uint id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed when GL context of #GPU_select_end
|
||||
* can't be used to finalize selection operations
|
||||
* (because of context changes).
|
||||
*/
|
||||
void GPU_select_finalize(void)
|
||||
{
|
||||
if (!g_select_state.select_is_active)
|
||||
return;
|
||||
|
||||
switch (g_select_state.algorithm) {
|
||||
case ALGO_GL_LEGACY:
|
||||
case ALGO_GL_QUERY:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default: /* ALGO_GL_PICK */
|
||||
{
|
||||
gpu_select_pick_finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup and flush selection results to buffer.
|
||||
* Return number of hits and hits in buffer.
|
||||
|
||||
@@ -257,7 +257,6 @@ typedef struct GPUPickState {
|
||||
|
||||
/* Set after first draw */
|
||||
bool is_init;
|
||||
bool is_finalized;
|
||||
uint prev_id;
|
||||
} gl;
|
||||
|
||||
@@ -368,7 +367,6 @@ void gpu_select_pick_begin(
|
||||
#endif
|
||||
|
||||
ps->gl.is_init = false;
|
||||
ps->gl.is_finalized = false;
|
||||
ps->gl.prev_id = 0;
|
||||
}
|
||||
else {
|
||||
@@ -529,20 +527,6 @@ bool gpu_select_pick_load_id(uint id)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Optional), call before 'gpu_select_pick_end' if GL context is not kept.
|
||||
* is not compatible with regular select case.
|
||||
* */
|
||||
void gpu_select_pick_finalize(void)
|
||||
{
|
||||
GPUPickState *ps = &g_pick_state;
|
||||
if (ps->gl.is_init) {
|
||||
/* force finishing last pass */
|
||||
gpu_select_pick_load_id(ps->gl.prev_id);
|
||||
}
|
||||
ps->gl.is_finalized = true;
|
||||
}
|
||||
|
||||
uint gpu_select_pick_end(void)
|
||||
{
|
||||
GPUPickState *ps = &g_pick_state;
|
||||
@@ -552,10 +536,10 @@ uint gpu_select_pick_end(void)
|
||||
#endif
|
||||
|
||||
if (ps->is_cached == false) {
|
||||
if (ps->gl.is_finalized == false) {
|
||||
gpu_select_pick_finalize();
|
||||
if (ps->gl.is_init) {
|
||||
/* force finishing last pass */
|
||||
gpu_select_pick_load_id(ps->gl.prev_id);
|
||||
}
|
||||
|
||||
gpuPopAttrib();
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
/* gpu_select_pick */
|
||||
void gpu_select_pick_begin(unsigned int (*buffer)[4], unsigned int bufsize, const rcti *input, char mode);
|
||||
bool gpu_select_pick_load_id(unsigned int id);
|
||||
void gpu_select_pick_finalize(void);
|
||||
unsigned int gpu_select_pick_end(void);
|
||||
|
||||
void gpu_select_pick_cache_begin(void);
|
||||
|
||||
Reference in New Issue
Block a user