Code cleanup: remove old closure sampling code Cycles.

This was the original code to get things working on old GPUs, but now it is no
longer in use and various features in fact depend on this to work correctly to
the point that enabling this code is too buggy to be useful.
This commit is contained in:
Brecht Van Lommel 2014-04-21 15:53:20 +02:00
parent 7765b73f6d
commit 04a10907dc
Notes: blender-bot 2023-02-14 11:21:43 +01:00
Referenced by commit f6abc96b6b, Cleanup: Remove OpenCL __MULTI_CLOSURE__ sanity check, not needed anymore after 04a10907dc.
12 changed files with 45 additions and 398 deletions

View File

@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN
/* Direction Emission */
ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce, int transparent_bounce)
{
/* setup shading at emitter */
@ -49,7 +49,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
/* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */
shader_eval_surface(kg, &sd, rando, 0, SHADER_CONTEXT_EMISSION);
shader_eval_surface(kg, &sd, 0.0f, 0, SHADER_CONTEXT_EMISSION);
/* evaluate emissive closure */
if(sd.flag & SD_EMISSION)
@ -64,7 +64,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
}
ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float randt, float rando, float randu, float randv, Ray *ray, BsdfEval *eval,
float randt, float randu, float randv, Ray *ray, BsdfEval *eval,
bool *is_lamp, int bounce, int transparent_bounce)
{
LightSample ls;
@ -88,7 +88,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
differential3 dD = differential3_zero();
/* evaluate closure */
float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce, transparent_bounce);
float3 light_eval = direct_emissive_eval(kg, &ls, -ls.D, dD, ls.t, sd->time, bounce, transparent_bounce);
if(is_zero(light_eval))
return false;
@ -204,7 +204,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
}
#endif
float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce, transparent_bounce);
float3 L = direct_emissive_eval(kg, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce, transparent_bounce);
if(!(path_flag & PATH_RAY_MIS_SKIP)) {
/* multiple importance sampling, get regular light pdf,

View File

@ -56,11 +56,6 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
/* sample illumination from lights to find path contribution */
if(sd->flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
#ifdef __MULTI_CLOSURE__
float light_o = 0.0f;
#else
float light_o = path_state_rng_1D(kg, rng, state, PRNG_LIGHT_F);
#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
@ -72,7 +67,7 @@ ccl_device_inline bool kernel_path_integrate_scatter_lighting(KernelGlobals *kg,
light_ray.time = sd->time;
#endif
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@ -157,7 +152,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
float light_u, light_v;
path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v);
if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
if(direct_emission(kg, sd, i, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@ -186,7 +181,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
if(kernel_data.integrator.num_all_lights)
light_t = 0.5f*light_t;
if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@ -204,7 +199,7 @@ ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
/* sample random light */
if(direct_emission(kg, sd, LAMP_NONE, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@ -474,11 +469,6 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
/* sample illumination from lights to find path contribution */
if(sd->flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT);
#ifdef __MULTI_CLOSURE__
float light_o = 0.0f;
#else
float light_o = path_state_rng_1D(kg, rng, state, PRNG_LIGHT_F);
#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v);
@ -490,7 +480,7 @@ ccl_device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rn
light_ray.time = sd->time;
#endif
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
if(direct_emission(kg, sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce, state->transparent_bounce)) {
/* trace shadow ray */
float3 shadow;
@ -835,11 +825,6 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT);
#ifdef __MULTI_CLOSURE__
float light_o = 0.0f;
#else
float light_o = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT_F);
#endif
float light_u, light_v;
path_state_rng_2D(kg, rng, &state, PRNG_LIGHT_U, &light_u, &light_v);
@ -851,7 +836,7 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
light_ray.time = sd.time;
#endif
if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce, state.transparent_bounce)) {
if(direct_emission(kg, &sd, LAMP_NONE, light_t, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce, state.transparent_bounce)) {
/* trace shadow ray */
float3 shadow;

View File

@ -490,8 +490,6 @@ ccl_device void shader_merge_closures(ShaderData *sd)
/* BSDF */
#ifdef __MULTI_CLOSURE__
ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
{
@ -519,28 +517,18 @@ ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderDa
*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
}
#endif
ccl_device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
const float3 omega_in, BsdfEval *eval, float *pdf)
{
#ifdef __MULTI_CLOSURE__
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
_shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
#else
const ShaderClosure *sc = &sd->closure;
*pdf = 0.0f;
*eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
#endif
}
ccl_device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
float randu, float randv, BsdfEval *bsdf_eval,
float3 *omega_in, differential3 *domega_in, float *pdf)
{
#ifdef __MULTI_CLOSURE__
int sampled = 0;
if(sd->num_closure > 1) {
@ -591,13 +579,6 @@ ccl_device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
}
return label;
#else
/* sample the single closure that we picked */
*pdf = 0.0f;
int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
*bsdf_eval *= sd->closure.weight;
return label;
#endif
}
ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
@ -618,21 +599,16 @@ ccl_device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *s
ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
#ifdef __MULTI_CLOSURE__
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type))
bsdf_blur(kg, sc, roughness);
}
#else
bsdf_blur(kg, &sd->closure, roughness);
#endif
}
ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -643,12 +619,6 @@ ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
}
return eval;
#else
if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
@ -663,7 +633,6 @@ ccl_device float3 shader_bsdf_alpha(KernelGlobals *kg, ShaderData *sd)
ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -674,17 +643,10 @@ ccl_device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
}
return eval;
#else
if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -695,17 +657,10 @@ ccl_device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
}
return eval;
#else
if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -716,17 +671,10 @@ ccl_device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
}
return eval;
#else
if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -737,17 +685,10 @@ ccl_device float3 shader_bsdf_subsurface(KernelGlobals *kg, ShaderData *sd)
}
return eval;
#else
if(CLOSURE_IS_BSSRDF(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N_)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
float3 N = make_float3(0.0f, 0.0f, 0.0f);
@ -771,21 +712,10 @@ ccl_device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_fac
*N_ = N;
return eval;
#else
*N_ = sd->N;
if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
return sd->closure.weight*ao_factor;
else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_blur_)
{
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
float3 N = make_float3(0.0f, 0.0f, 0.0f);
float texture_blur = 0.0f, weight_sum = 0.0f;
@ -810,20 +740,6 @@ ccl_device float3 shader_bssrdf_sum(ShaderData *sd, float3 *N_, float *texture_b
*texture_blur_ = texture_blur/weight_sum;
return eval;
#else
if(CLOSURE_IS_BSSRDF(sd->closure.type)) {
if(N_) *N_ = sd->closure.N;
if(texture_blur_) *texture_blur_ = sd->closure.data1;
return sd->closure.weight;
}
else {
if(N_) *N_ = sd->N;
if(texture_blur_) *texture_blur_ = 0.0f;
return make_float3(0.0f, 0.0f, 0.0f);
}
#endif
}
/* Emission */
@ -836,7 +752,6 @@ ccl_device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure
ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{
float3 eval;
#ifdef __MULTI_CLOSURE__
eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
@ -845,9 +760,6 @@ ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
if(CLOSURE_IS_EMISSION(sc->type))
eval += emissive_eval(kg, sd, sc)*sc->weight;
}
#else
eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
#endif
return eval;
}
@ -856,7 +768,6 @@ ccl_device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
{
#ifdef __MULTI_CLOSURE__
float3 weight = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
@ -867,12 +778,6 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
}
return weight;
#else
if(sd->closure.type == CLOSURE_HOLDOUT_ID)
return make_float3(1.0f, 1.0f, 1.0f);
return make_float3(0.0f, 0.0f, 0.0f);
#endif
}
/* Surface Evaluation */
@ -880,12 +785,8 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
float randb, int path_flag, ShaderContext ctx)
{
#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = randb;
#else
sd->closure.type = NBUILTIN_CLOSURES;
#endif
#ifdef __OSL__
if(kg->osl)
@ -894,7 +795,7 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
#endif
{
#ifdef __SVM__
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag);
#else
sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
sd->closure.N = sd->N;
@ -907,12 +808,8 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
{
#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = 0.0f;
#else
sd->closure.type = NBUILTIN_CLOSURES;
#endif
#ifdef __OSL__
if(kg->osl) {
@ -923,9 +820,8 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int
{
#ifdef __SVM__
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag);
#ifdef __MULTI_CLOSURE__
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i< sd->num_closure; i++) {
@ -936,13 +832,6 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int
}
return eval;
#else
if(sd->closure.type == CLOSURE_BACKGROUND_ID)
return sd->closure.weight;
else
return make_float3(0.0f, 0.0f, 0.0f);
#endif
#else
return make_float3(0.8f, 0.8f, 0.8f);
#endif
@ -1062,11 +951,7 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
{
/* reset closures once at the start, we will be accumulating the closures
* for all volumes in the stack into a single array of closures */
#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
#else
sd->closure.type = NBUILTIN_CLOSURES;
#endif
sd->flag = 0;
for(int i = 0; stack[i].shader != SHADER_NONE; i++) {
@ -1097,7 +982,7 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
else
#endif
{
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, 0.0f, path_flag);
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, path_flag);
}
#endif
@ -1113,12 +998,8 @@ ccl_device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
{
#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
sd->randb_closure = 0.0f;
#else
sd->closure.type = NBUILTIN_CLOSURES;
#endif
/* this will modify sd->P */
#ifdef __SVM__
@ -1128,7 +1009,7 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, Shad
else
#endif
{
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0);
}
#endif
}

View File

@ -36,10 +36,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
* in cases where we don't need them. after a regular shadow ray is
* cast we check if the hit primitive was potentially transparent, and
* only in that case start marching. this gives on extra ray cast for
* the cases were we do want transparency.
*
* also note that for this to work correct, multi close sampling must
* be used, since we don't pass a random number to shader_eval_surface */
* the cases were we do want transparency. */
if(shader_transparent_shadow(kg, &isect)) {
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
float3 Pend = ray->P + ray->D*ray->t;
@ -95,7 +92,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
/* setup shader data at surface */
ShaderData sd;
shader_setup_from_ray(kg, &sd, &isect, ray, ps.bounce+1, ps.transparent_bounce);
shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1, bounce);
/* attenuation from transparent surface */
if(!(sd.flag & SD_HAS_ONLY_VOLUME)) {

View File

@ -192,7 +192,7 @@ enum PathTraceDimension {
PRNG_LIGHT = 3,
PRNG_LIGHT_U = 4,
PRNG_LIGHT_V = 5,
PRNG_LIGHT_F = 6,
PRNG_UNUSED_3 = 6,
PRNG_TERMINATE = 7,
#ifdef __VOLUME__
@ -491,15 +491,17 @@ typedef enum AttributeStandard {
/* Closure data */
#ifdef __MULTI_CLOSURE__
#define MAX_CLOSURE 64
#else
#define MAX_CLOSURE 1
#endif
typedef struct ShaderClosure {
ClosureType type;
float3 weight;
#ifdef __MULTI_CLOSURE__
float sample_weight;
#endif
float data0;
float data1;
@ -634,15 +636,10 @@ typedef struct ShaderData {
Transform ob_itfm;
#endif
#ifdef __MULTI_CLOSURE__
/* Closure data, we store a fixed array of closures */
ShaderClosure closure[MAX_CLOSURE];
int num_closure;
float randb_closure;
#else
/* Closure data, with a single sampled closure for low memory usage */
ShaderClosure closure;
#endif
/* ray start position, only set for backgrounds */
float3 ray_P;

View File

@ -182,10 +182,9 @@ CCL_NAMESPACE_BEGIN
/* Main Interpreter Loop */
ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, float randb, int path_flag)
ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, int path_flag)
{
float stack[SVM_STACK_SIZE];
float closure_weight = 1.0f;
int offset = sd->shader & SHADER_MASK;
while(1) {
@ -200,7 +199,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
break;
}
case NODE_CLOSURE_BSDF:
svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag, &offset);
svm_node_closure_bsdf(kg, sd, stack, node, path_flag, &offset);
break;
case NODE_CLOSURE_EMISSION:
svm_node_closure_emission(sd, stack, node);
@ -227,10 +226,7 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
svm_node_emission_weight(kg, sd, stack, node);
break;
case NODE_MIX_CLOSURE:
svm_node_mix_closure(sd, stack, node, &offset, &randb);
break;
case NODE_ADD_CLOSURE:
svm_node_add_closure(sd, stack, node.y, node.z, &offset, &randb, &closure_weight);
svm_node_mix_closure(sd, stack, node);
break;
case NODE_JUMP_IF_ZERO:
if(stack_load_float(stack, node.z) == 0.0f)
@ -442,9 +438,6 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, Shade
#endif
case NODE_END:
default:
#ifndef __MULTI_CLOSURE__
sd->closure.weight *= closure_weight;
#endif
return;
}
}

View File

@ -51,7 +51,6 @@ ccl_device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type
ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, ClosureType type, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
if(sd->num_closure < MAX_CLOSURE) {
@ -65,14 +64,10 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_non_bsdf(ShaderData *sd, C
}
return NULL;
#else
return &sd->closure;
#endif
}
ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight * mix_weight;
float sample_weight = fabsf(average(weight));
@ -88,14 +83,10 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_bsdf(ShaderData *sd, float
}
return NULL;
#else
return &sd->closure;
#endif
}
ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd, float mix_weight)
{
#ifdef __MULTI_CLOSURE__
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = (make_float3(1.0f, 1.0f, 1.0f) - sc->weight) * mix_weight;
float sample_weight = fabsf(average(weight));
@ -111,16 +102,12 @@ ccl_device_inline ShaderClosure *svm_node_closure_get_absorption(ShaderData *sd,
}
return NULL;
#else
return &sd->closure;
#endif
}
ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset)
ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, int path_flag, int *offset)
{
uint type, param1_offset, param2_offset;
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset;
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
@ -132,13 +119,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
return;
float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
#else
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
float mix_weight = 1.0f;
uint4 data_node = read_node(kg, offset);
float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
@ -255,7 +235,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float roughness = param1;
#ifdef __MULTI_CLOSURE__
/* reflection */
ShaderClosure *sc = &sd->closure[sd->num_closure];
float3 weight = sc->weight;
@ -279,15 +258,6 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
sc->N = N;
svm_node_glass_setup(sd, sc, type, eta, roughness, true);
}
#else
ShaderClosure *sc = svm_node_closure_get_bsdf(sd, mix_weight);
if(sc) {
sc->N = N;
bool refract = (randb > fresnel);
svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
}
#endif
break;
}
@ -484,17 +454,12 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
#ifdef __VOLUME__
uint type, param1_offset, param2_offset;
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset;
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, &mix_weight_offset);
float mix_weight = (stack_valid(mix_weight_offset)? stack_load_float(stack, mix_weight_offset): 1.0f);
if(mix_weight == 0.0f)
return;
#else
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
float mix_weight = 1.0f;
#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
float param2 = (stack_valid(param2_offset))? stack_load_float(stack, param2_offset): __uint_as_float(node.w);
@ -527,7 +492,6 @@ ccl_device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float
ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 node)
{
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@ -540,17 +504,12 @@ ccl_device void svm_node_closure_emission(ShaderData *sd, float *stack, uint4 no
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_EMISSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_EMISSION_ID;
#endif
sd->flag |= SD_EMISSION;
}
ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4 node)
{
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@ -563,15 +522,10 @@ ccl_device void svm_node_closure_background(ShaderData *sd, float *stack, uint4
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_BACKGROUND_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_BACKGROUND_ID;
#endif
}
ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
{
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@ -584,17 +538,12 @@ ccl_device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 nod
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_HOLDOUT_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_HOLDOUT_ID;
#endif
sd->flag |= SD_HOLDOUT;
}
ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
{
#ifdef __MULTI_CLOSURE__
uint mix_weight_offset = node.y;
if(stack_valid(mix_weight_offset)) {
@ -607,10 +556,6 @@ ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack,
}
else
svm_node_closure_get_non_bsdf(sd, CLOSURE_AMBIENT_OCCLUSION_ID, 1.0f);
#else
ShaderClosure *sc = &sd->closure;
sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
#endif
sd->flag |= SD_AO;
}
@ -619,12 +564,8 @@ ccl_device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack,
ccl_device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
{
#ifdef __MULTI_CLOSURE__
if(sd->num_closure < MAX_CLOSURE)
sd->closure[sd->num_closure].weight = weight;
#else
sd->closure.weight = weight;
#endif
}
ccl_device void svm_node_closure_set_weight(ShaderData *sd, uint r, uint g, uint b)
@ -665,10 +606,8 @@ ccl_device void svm_node_emission_weight(KernelGlobals *kg, ShaderData *sd, floa
svm_node_closure_store_weight(sd, weight);
}
ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack,
uint4 node, int *offset, float *randb)
ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack, uint4 node)
{
#ifdef __MULTI_CLOSURE__
/* fetch weight from blend input, previous mix closures,
* and write to stack to be used by closure nodes later */
uint weight_offset, in_weight_offset, weight1_offset, weight2_offset;
@ -683,44 +622,6 @@ ccl_device void svm_node_mix_closure(ShaderData *sd, float *stack,
stack_store_float(stack, weight1_offset, in_weight*(1.0f - weight));
if(stack_valid(weight2_offset))
stack_store_float(stack, weight2_offset, in_weight*weight);
#else
/* pick a closure and make the random number uniform over 0..1 again.
* closure 1 starts on the next node, for closure 2 the start is at an
* offset from the current node, so we jump */
uint weight_offset = node.y;
uint node_jump = node.z;
float weight = stack_load_float(stack, weight_offset);
weight = clamp(weight, 0.0f, 1.0f);
if(*randb < weight) {
*offset += node_jump;
*randb = *randb/weight;
}
else
*randb = (*randb - weight)/(1.0f - weight);
#endif
}
ccl_device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
uint node_jump, int *offset, float *randb, float *closure_weight)
{
#ifdef __MULTI_CLOSURE__
/* nothing to do, handled in compiler */
#else
/* pick one of the two closures with probability 0.5. sampling quality
* is not going to be great, for that we'd need to evaluate the weights
* of the two closures being added */
float weight = 0.5f;
if(*randb < weight) {
*offset += node_jump;
*randb = *randb/weight;
}
else
*randb = (*randb - weight)/(1.0f - weight);
*closure_weight *= 2.0f;
#endif
}
/* (Bump) normal */

View File

@ -72,7 +72,6 @@ typedef enum NodeType {
NODE_TEX_COORD,
NODE_TEX_COORD_BUMP_DX,
NODE_TEX_COORD_BUMP_DY,
NODE_ADD_CLOSURE,
NODE_EMISSION_SET_WEIGHT_TOTAL,
NODE_ATTR_BUMP_DX,
NODE_ATTR_BUMP_DY,

View File

@ -227,7 +227,7 @@ void ShaderGraph::disconnect(ShaderInput *to)
from->links.erase(remove(from->links.begin(), from->links.end(), to), from->links.end());
}
void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
void ShaderGraph::finalize(bool do_bump, bool do_osl)
{
/* before compiling, the shader graph may undergo a number of modifications.
* currently we set default geometry shader inputs, and create automatic bump
@ -242,17 +242,15 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl, bool do_multi_transform)
if(do_bump)
bump_from_displacement();
if(do_multi_transform) {
ShaderInput *surface_in = output()->input("Surface");
ShaderInput *volume_in = output()->input("Volume");
ShaderInput *surface_in = output()->input("Surface");
ShaderInput *volume_in = output()->input("Volume");
/* todo: make this work when surface and volume closures are tangled up */
/* todo: make this work when surface and volume closures are tangled up */
if(surface_in->link)
transform_multi_closure(surface_in->link->parent, NULL, false);
if(volume_in->link)
transform_multi_closure(volume_in->link->parent, NULL, true);
}
if(surface_in->link)
transform_multi_closure(surface_in->link->parent, NULL, false);
if(volume_in->link)
transform_multi_closure(volume_in->link->parent, NULL, true);
finalized = true;
}

View File

@ -247,7 +247,7 @@ public:
void disconnect(ShaderInput *to);
void remove_unneeded_nodes();
void finalize(bool do_bump = false, bool do_osl = false, bool do_multi_closure = false);
void finalize(bool do_bump = false, bool do_osl = false);
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;

View File

@ -63,8 +63,6 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
}
bool use_multi_closure = device->info.advanced_shading;
for(i = 0; i < scene->shaders.size(); i++) {
Shader *shader = scene->shaders[i];
@ -75,8 +73,7 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(shader->use_mis && shader->has_surface_emission)
scene->light_manager->need_update = true;
SVMCompiler compiler(scene->shader_manager, scene->image_manager,
use_multi_closure);
SVMCompiler compiler(scene->shader_manager, scene->image_manager);
compiler.background = ((int)i == scene->default_background);
compiler.compile(shader, svm_nodes, i);
}
@ -104,7 +101,7 @@ void SVMShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s
/* Graph Compiler */
SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_, bool use_multi_closure_)
SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_)
{
shader_manager = shader_manager_;
image_manager = image_manager_;
@ -114,7 +111,6 @@ SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_man
current_graph = NULL;
background = false;
mix_weight_offset = SVM_STACK_INVALID;
use_multi_closure = use_multi_closure_;
compile_failed = false;
}
@ -422,97 +418,6 @@ void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNo
} while(!nodes_done);
}
void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
{
if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
ShaderInput *fin = node->input("Fac");
ShaderInput *cl1in = node->input("Closure1");
ShaderInput *cl2in = node->input("Closure2");
/* execute dependencies for mix weight */
if(fin) {
set<ShaderNode*> dependencies;
find_dependencies(dependencies, done, fin);
generate_svm_nodes(dependencies, done);
/* add mix node */
stack_assign(fin);
}
int mix_offset = svm_nodes.size();
if(fin)
add_node(NODE_MIX_CLOSURE, fin->stack_offset, 0, 0);
else
add_node(NODE_ADD_CLOSURE, 0, 0, 0);
/* generate code for closure 1
* note we backup all compiler state and restore it afterwards, so one
* closure choice doesn't influence the other*/
if(cl1in->link) {
StackBackup backup;
stack_backup(backup, done);
generate_closure(cl1in->link->parent, done);
add_node(NODE_END, 0, 0, 0);
stack_restore(backup, done);
}
else
add_node(NODE_END, 0, 0, 0);
/* generate code for closure 2 */
int cl2_offset = svm_nodes.size();
if(cl2in->link) {
StackBackup backup;
stack_backup(backup, done);
generate_closure(cl2in->link->parent, done);
add_node(NODE_END, 0, 0, 0);
stack_restore(backup, done);
}
else
add_node(NODE_END, 0, 0, 0);
/* set jump for mix node, -1 because offset is already
* incremented when this jump is added to it */
svm_nodes[mix_offset].z = cl2_offset - mix_offset - 1;
done.insert(node);
stack_clear_users(node, done);
stack_clear_temporary(node);
}
else {
/* execute dependencies for closure */
foreach(ShaderInput *in, node->inputs) {
if(!node_skip_input(node, in) && in->link) {
set<ShaderNode*> dependencies;
find_dependencies(dependencies, done, in);
generate_svm_nodes(dependencies, done);
}
}
/* compile closure itself */
generate_node(node, done);
if(current_type == SHADER_TYPE_SURFACE) {
if(node->has_surface_emission())
current_shader->has_surface_emission = true;
if(node->has_surface_transparent())
current_shader->has_surface_transparent = true;
if(node->has_surface_bssrdf()) {
current_shader->has_surface_bssrdf = true;
if(node->has_bssrdf_bump())
current_shader->has_bssrdf_bump = true;
}
}
/* end node is added outside of this */
}
}
void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done)
{
/* only generate once */
@ -537,7 +442,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
find_dependencies(dependencies, done, facin);
generate_svm_nodes(dependencies, done);
stack_assign(facin); /* XXX unassign? */
stack_assign(facin);
/* execute shared dependencies. this is needed to allow skipping
* of zero weight closures and their dependencies later, so we
@ -578,7 +483,7 @@ void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& don
}
/* unassign */
facin->stack_offset = SVM_STACK_INVALID; // XXX clear?
facin->stack_offset = SVM_STACK_INVALID;
}
else {
/* execute closures and their dependencies, no runtime checks
@ -706,14 +611,8 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
}
if(generate) {
set<ShaderNode*> done;
if(use_multi_closure) {
set<ShaderNode*> closure_done;
generate_multi_closure(clin->link->parent, done, closure_done);
}
else
generate_closure(clin->link->parent, done);
set<ShaderNode*> done, closure_done;
generate_multi_closure(clin->link->parent, done, closure_done);
}
}
@ -740,9 +639,9 @@ void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int in
shader->graph_bump = shader->graph->copy();
/* finalize */
shader->graph->finalize(false, false, use_multi_closure);
shader->graph->finalize(false, false);
if(shader->graph_bump)
shader->graph_bump->finalize(true, false, use_multi_closure);
shader->graph_bump->finalize(true, false);
current_shader = shader;

View File

@ -52,8 +52,7 @@ public:
class SVMCompiler {
public:
SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager,
bool use_multi_closure_);
SVMCompiler(ShaderManager *shader_manager, ImageManager *image_manager);
void compile(Shader *shader, vector<int4>& svm_nodes, int index);
void stack_assign(ShaderOutput *output);
@ -126,7 +125,6 @@ protected:
void find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input);
void generate_node(ShaderNode *node, set<ShaderNode*>& done);
void generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done);
void generate_closure(ShaderNode *node, set<ShaderNode*>& done);
/* multi closure */
void generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, set<ShaderNode*>& closure_done);
@ -141,7 +139,6 @@ protected:
Stack active_stack;
int max_stack_use;
uint mix_weight_offset;
bool use_multi_closure;
bool compile_failed;
};