Merge branch 'master' into blender2.8

This commit is contained in:
2018-03-01 16:48:13 +11:00
11 changed files with 127 additions and 88 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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);
}

View File

@@ -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);