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:
parent
7765b73f6d
commit
04a10907dc
Notes:
blender-bot
2023-02-14 11:21:43 +01:00
Referenced by commitf6abc96b6b
, Cleanup: Remove OpenCL __MULTI_CLOSURE__ sanity check, not needed anymore after04a10907dc
.
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, ¶m1_offset, ¶m2_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, ¶m1_offset, ¶m2_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, ¶m1_offset, ¶m2_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, ¶m1_offset, ¶m2_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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue