Cycles / SSS:

* Render Passes are now available for Subsurface Scattering (Direct, Indirect and Color pass). 

This is part of my GSoC project, SVN merge of r58587, r58828 and r58835.
This commit is contained in:
Thomas Dinges 2013-08-03 13:12:09 +00:00
parent ea95a78b0b
commit 5fc6f04fc8
17 changed files with 282 additions and 100 deletions

View File

@ -373,7 +373,13 @@ class CyclesRender_PT_layer_passes(CyclesButtonsPanel, Panel):
row.prop(rl, "use_pass_transmission_direct", text="Direct", toggle=True)
row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True)
row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True)
col.label(text="Subsurface:")
row = col.row(align=True)
row.prop(rl, "use_pass_subsurface_direct", text="Direct", toggle=True)
row.prop(rl, "use_pass_subsurface_indirect", text="Indirect", toggle=True)
row.prop(rl, "use_pass_subsurface_color", text="Color", toggle=True)
col.separator()
col.prop(rl, "use_pass_emit", text="Emission")
col.prop(rl, "use_pass_environment")
col.prop(rl, "use_pass_ambient_occlusion")

View File

@ -216,6 +216,8 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_GLOSSY_DIRECT;
case BL::RenderPass::type_TRANSMISSION_DIRECT:
return PASS_TRANSMISSION_DIRECT;
case BL::RenderPass::type_SUBSURFACE_DIRECT:
return PASS_SUBSURFACE_DIRECT;
case BL::RenderPass::type_DIFFUSE_INDIRECT:
return PASS_DIFFUSE_INDIRECT;
@ -223,6 +225,8 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_GLOSSY_INDIRECT;
case BL::RenderPass::type_TRANSMISSION_INDIRECT:
return PASS_TRANSMISSION_INDIRECT;
case BL::RenderPass::type_SUBSURFACE_INDIRECT:
return PASS_SUBSURFACE_INDIRECT;
case BL::RenderPass::type_DIFFUSE_COLOR:
return PASS_DIFFUSE_COLOR;
@ -230,6 +234,8 @@ static PassType get_pass_type(BL::RenderPass b_pass)
return PASS_GLOSSY_COLOR;
case BL::RenderPass::type_TRANSMISSION_COLOR:
return PASS_TRANSMISSION_COLOR;
case BL::RenderPass::type_SUBSURFACE_COLOR:
return PASS_SUBSURFACE_COLOR;
case BL::RenderPass::type_EMIT:
return PASS_EMISSION;

View File

@ -45,6 +45,7 @@ __device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const ShaderCl
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_BSSRDF_ID:
label = bsdf_diffuse_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
@ -134,6 +135,7 @@ __device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderC
if(dot(sd->Ng, omega_in) >= 0.0f) {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_BSSRDF_ID:
eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#ifdef __SVM__
@ -195,6 +197,7 @@ __device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const ShaderC
else {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_BSSRDF_ID:
eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#ifdef __SVM__
@ -262,6 +265,7 @@ __device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
case CLOSURE_BSDF_BSSRDF_ID:
bsdf_diffuse_blur(sc, roughness);
break;
#ifdef __SVM__

View File

@ -33,6 +33,7 @@ __device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 val
eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
eval->transparent = make_float3(0.0f, 0.0f, 0.0f);
eval->subsurface = make_float3(0.0f, 0.0f, 0.0f);
if(type == CLOSURE_BSDF_TRANSPARENT_ID)
eval->transparent = value;
@ -40,8 +41,10 @@ __device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 val
eval->diffuse = value;
else if(CLOSURE_IS_BSDF_GLOSSY(type))
eval->glossy = value;
else
else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
eval->transmission = value;
else if(CLOSURE_IS_BSDF_BSSRDF(type))
eval->subsurface = value;
}
else
eval->diffuse = value;
@ -58,8 +61,10 @@ __device_inline void bsdf_eval_accum(BsdfEval *eval, ClosureType type, float3 va
eval->diffuse += value;
else if(CLOSURE_IS_BSDF_GLOSSY(type))
eval->glossy += value;
else
else if(CLOSURE_IS_BSDF_TRANSMISSION(type))
eval->transmission += value;
else if(CLOSURE_IS_BSDF_BSSRDF(type))
eval->subsurface += value;
/* skipping transparent, this function is used by for eval(), will be zero then */
}
@ -77,7 +82,8 @@ __device_inline bool bsdf_eval_is_zero(BsdfEval *eval)
return is_zero(eval->diffuse)
&& is_zero(eval->glossy)
&& is_zero(eval->transmission)
&& is_zero(eval->transparent);
&& is_zero(eval->transparent)
&& is_zero(eval->subsurface);
}
else
return is_zero(eval->diffuse);
@ -93,6 +99,7 @@ __device_inline void bsdf_eval_mul(BsdfEval *eval, float3 value)
eval->diffuse *= value;
eval->glossy *= value;
eval->transmission *= value;
eval->subsurface *= value;
/* skipping transparent, this function is used by for eval(), will be zero then */
}
@ -124,18 +131,22 @@ __device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
L->color_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->color_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->color_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->color_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->emission = make_float3(0.0f, 0.0f, 0.0f);
L->background = make_float3(0.0f, 0.0f, 0.0f);
@ -164,14 +175,15 @@ __device_inline void path_radiance_bsdf_bounce(PathRadiance *L, float3 *throughp
L->path_diffuse = bsdf_eval->diffuse*value;
L->path_glossy = bsdf_eval->glossy*value;
L->path_transmission = bsdf_eval->transmission*value;
L->path_subsurface = bsdf_eval->subsurface*value;
*throughput = L->path_diffuse + L->path_glossy + L->path_transmission;
*throughput = L->path_diffuse + L->path_glossy + L->path_transmission + L->path_subsurface;
L->direct_throughput = *throughput;
}
else {
/* transparent bounce before first hit, or indirectly visible through BSDF */
float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent)*inverse_pdf;
float3 sum = (bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->transparent + bsdf_eval->subsurface)*inverse_pdf;
*throughput *= sum;
}
}
@ -230,6 +242,7 @@ __device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughpu
L->direct_diffuse += throughput*bsdf_eval->diffuse*shadow;
L->direct_glossy += throughput*bsdf_eval->glossy*shadow;
L->direct_transmission += throughput*bsdf_eval->transmission*shadow;
L->direct_subsurface += throughput*bsdf_eval->subsurface*shadow;
if(is_lamp) {
L->shadow.x += shadow.x*shadow_fac;
@ -239,7 +252,7 @@ __device_inline void path_radiance_accum_light(PathRadiance *L, float3 throughpu
}
else {
/* indirectly visible lighting after BSDF bounce */
float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission;
float3 sum = bsdf_eval->diffuse + bsdf_eval->glossy + bsdf_eval->transmission + bsdf_eval->subsurface;
L->indirect += throughput*sum*shadow;
}
}
@ -279,11 +292,13 @@ __device_inline void path_radiance_sum_indirect(PathRadiance *L)
L->direct_diffuse += L->path_diffuse*L->direct_emission;
L->direct_glossy += L->path_glossy*L->direct_emission;
L->direct_transmission += L->path_transmission*L->direct_emission;
L->direct_subsurface += L->path_subsurface*L->direct_emission;
L->indirect = safe_divide_color(L->indirect, L->direct_throughput);
L->indirect_diffuse += L->path_diffuse*L->indirect;
L->indirect_glossy += L->path_glossy*L->indirect;
L->indirect_transmission += L->path_transmission*L->indirect;
L->indirect_subsurface += L->path_subsurface*L->indirect;
}
#endif
}
@ -295,6 +310,7 @@ __device_inline void path_radiance_reset_indirect(PathRadiance *L)
L->path_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->path_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->path_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->direct_emission = make_float3(0.0f, 0.0f, 0.0f);
L->indirect = make_float3(0.0f, 0.0f, 0.0f);
@ -309,8 +325,8 @@ __device_inline float3 path_radiance_sum(KernelGlobals *kg, PathRadiance *L)
path_radiance_sum_indirect(L);
float3 L_sum = L->emission
+ L->direct_diffuse + L->direct_glossy + L->direct_transmission
+ L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission;
+ L->direct_diffuse + L->direct_glossy + L->direct_transmission + L->direct_subsurface
+ L->indirect_diffuse + L->indirect_glossy + L->indirect_transmission + L->indirect_subsurface;
if(!kernel_data.background.transparent)
L_sum += L->background;
@ -337,10 +353,12 @@ __device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float c
L->direct_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->direct_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->direct_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->direct_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_diffuse = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_glossy = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_transmission = make_float3(0.0f, 0.0f, 0.0f);
L->indirect_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->emission = make_float3(0.0f, 0.0f, 0.0f);
}
@ -357,10 +375,12 @@ __device_inline void path_radiance_clamp(PathRadiance *L, float3 *L_sum, float c
L->direct_diffuse *= scale;
L->direct_glossy *= scale;
L->direct_transmission *= scale;
L->direct_subsurface *= scale;
L->indirect_diffuse *= scale;
L->indirect_glossy *= scale;
L->indirect_transmission *= scale;
L->indirect_subsurface *= scale;
L->emission *= scale;
}

View File

@ -86,6 +86,8 @@ __device_inline void kernel_write_data_passes(KernelGlobals *kg, __global float
L->color_glossy += shader_bsdf_glossy(kg, sd)*throughput;
if(flag & (PASS_TRANSMISSION_INDIRECT|PASS_TRANSMISSION_COLOR|PASS_TRANSMISSION_DIRECT))
L->color_transmission += shader_bsdf_transmission(kg, sd)*throughput;
if(flag & (PASS_SUBSURFACE_INDIRECT|PASS_SUBSURFACE_COLOR|PASS_SUBSURFACE_DIRECT))
L->color_subsurface += shader_bsdf_subsurface(kg, sd)*throughput;
if(flag & PASS_MIST) {
/* bring depth into 0..1 range */
@ -128,12 +130,16 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_indirect, sample, L->indirect_glossy);
if(flag & PASS_TRANSMISSION_INDIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_indirect, sample, L->indirect_transmission);
if(flag & PASS_SUBSURFACE_INDIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_indirect, sample, L->indirect_subsurface);
if(flag & PASS_DIFFUSE_DIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_diffuse_direct, sample, L->direct_diffuse);
if(flag & PASS_GLOSSY_DIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_direct, sample, L->direct_glossy);
if(flag & PASS_TRANSMISSION_DIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_direct, sample, L->direct_transmission);
if(flag & PASS_SUBSURFACE_DIRECT)
kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_direct, sample, L->direct_subsurface);
if(flag & PASS_EMISSION)
kernel_write_pass_float3(buffer + kernel_data.film.pass_emission, sample, L->emission);
@ -148,6 +154,8 @@ __device_inline void kernel_write_light_passes(KernelGlobals *kg, __global float
kernel_write_pass_float3(buffer + kernel_data.film.pass_glossy_color, sample, L->color_glossy);
if(flag & PASS_TRANSMISSION_COLOR)
kernel_write_pass_float3(buffer + kernel_data.film.pass_transmission_color, sample, L->color_transmission);
if(flag & PASS_SUBSURFACE_COLOR)
kernel_write_pass_float3(buffer + kernel_data.film.pass_subsurface_color, sample, L->color_subsurface);
if(flag & PASS_SHADOW) {
float4 shadow = L->shadow;
shadow.w = kernel_data.film.pass_shadow_scale;

View File

@ -892,7 +892,7 @@ __device_noinline void kernel_path_non_progressive_lighting(KernelGlobals *kg, R
int num_samples;
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type) || CLOSURE_IS_BSDF_BSSRDF(sc->type))
num_samples = kernel_data.integrator.diffuse_samples;
else if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
num_samples = kernel_data.integrator.glossy_samples;

View File

@ -685,6 +685,27 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
#endif
}
__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++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSSRDF(sc->type))
eval += sc->weight;
}
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
}
__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
{
#ifdef __MULTI_CLOSURE__

View File

@ -163,6 +163,10 @@ __device void subsurface_scatter_setup_diffuse_bsdf(ShaderData *sd, float3 weigh
sd->flag |= bsdf_diffuse_setup(sc);
sd->randb_closure = 0.0f;
/* replace CLOSURE_BSDF_DIFFUSE_ID with this special ID so render passes
* can recognize it as not being a regular diffuse closure */
sc->type = CLOSURE_BSDF_BSSRDF_ID;
/* todo: evaluate shading to get blurred textures and bump mapping */
/* shader_eval_surface(kg, sd, 0.0f, state_flag, SHADER_CONTEXT_SSS); */
}

View File

@ -268,7 +268,10 @@ typedef enum PassType {
PASS_SHADOW = 262144,
PASS_MOTION = 524288,
PASS_MOTION_WEIGHT = 1048576,
PASS_MIST = 2097152
PASS_MIST = 2097152,
PASS_SUBSURFACE_DIRECT = 4194304,
PASS_SUBSURFACE_INDIRECT = 8388608,
PASS_SUBSURFACE_COLOR = 16777216
} PassType;
#define PASS_ALL (~0)
@ -291,18 +294,22 @@ typedef struct PathRadiance {
float3 color_diffuse;
float3 color_glossy;
float3 color_transmission;
float3 color_subsurface;
float3 direct_diffuse;
float3 direct_glossy;
float3 direct_transmission;
float3 direct_subsurface;
float3 indirect_diffuse;
float3 indirect_glossy;
float3 indirect_transmission;
float3 indirect_subsurface;
float3 path_diffuse;
float3 path_glossy;
float3 path_transmission;
float3 path_subsurface;
float4 shadow;
float mist;
@ -315,6 +322,7 @@ typedef struct BsdfEval {
float3 glossy;
float3 transmission;
float3 transparent;
float3 subsurface;
} BsdfEval;
#else
@ -672,22 +680,27 @@ typedef struct KernelFilm {
int pass_diffuse_color;
int pass_glossy_color;
int pass_transmission_color;
int pass_subsurface_color;
int pass_diffuse_indirect;
int pass_glossy_indirect;
int pass_transmission_indirect;
int pass_subsurface_indirect;
int pass_diffuse_direct;
int pass_glossy_direct;
int pass_transmission_direct;
int pass_subsurface_direct;
int pass_emission;
int pass_background;
int pass_ao;
int pass_pad1;
int pass_shadow;
float pass_shadow_scale;
int filter_table_offset;
int pass_pad1;
int pass_pad2;
int pass_mist;
float mist_start;

View File

@ -371,7 +371,8 @@ typedef enum ClosureType {
CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
CLOSURE_BSDF_SHARP_GLASS_ID,
/* Transparent */
/* Special cases */
CLOSURE_BSDF_BSSRDF_ID,
CLOSURE_BSDF_TRANSPARENT_ID,
/* Other */
@ -395,6 +396,7 @@ typedef enum ClosureType {
#define CLOSURE_IS_BSDF_DIFFUSE(type) (type >= CLOSURE_BSDF_DIFFUSE_ID && type <= CLOSURE_BSDF_DIFFUSE_TOON_ID)
#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_GLOSSY_TOON_ID)
#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
#define CLOSURE_IS_BSDF_BSSRDF(type) (type == CLOSURE_BSDF_BSSRDF_ID)
#define CLOSURE_IS_BSSRDF(type) (type == CLOSURE_BSSRDF_ID)
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID)
#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)

View File

@ -98,6 +98,9 @@ void Pass::add(PassType type, vector<Pass>& passes)
case PASS_TRANSMISSION_COLOR:
pass.components = 4;
break;
case PASS_SUBSURFACE_COLOR:
pass.components = 4;
break;
case PASS_DIFFUSE_INDIRECT:
pass.components = 4;
pass.exposure = true;
@ -113,6 +116,11 @@ void Pass::add(PassType type, vector<Pass>& passes)
pass.exposure = true;
pass.divide_type = PASS_TRANSMISSION_COLOR;
break;
case PASS_SUBSURFACE_INDIRECT:
pass.components = 4;
pass.exposure = true;
pass.divide_type = PASS_SUBSURFACE_COLOR;
break;
case PASS_DIFFUSE_DIRECT:
pass.components = 4;
pass.exposure = true;
@ -128,6 +136,11 @@ void Pass::add(PassType type, vector<Pass>& passes)
pass.exposure = true;
pass.divide_type = PASS_TRANSMISSION_COLOR;
break;
case PASS_SUBSURFACE_DIRECT:
pass.components = 4;
pass.exposure = true;
pass.divide_type = PASS_SUBSURFACE_COLOR;
break;
case PASS_EMISSION:
pass.components = 4;
@ -327,6 +340,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_transmission_color = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_SUBSURFACE_COLOR:
kfilm->pass_subsurface_color = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_DIFFUSE_INDIRECT:
kfilm->pass_diffuse_indirect = kfilm->pass_stride;
kfilm->use_light_pass = 1;
@ -339,6 +356,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_transmission_indirect = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_SUBSURFACE_INDIRECT:
kfilm->pass_subsurface_indirect = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_DIFFUSE_DIRECT:
kfilm->pass_diffuse_direct = kfilm->pass_stride;
kfilm->use_light_pass = 1;
@ -351,6 +372,10 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_transmission_direct = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_SUBSURFACE_DIRECT:
kfilm->pass_subsurface_direct = kfilm->pass_stride;
kfilm->use_light_pass = 1;
break;
case PASS_EMISSION:
kfilm->pass_emission = kfilm->pass_stride;

View File

@ -778,34 +778,37 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMateria
/* ************** COMPOSITE NODES *************** */
/* output socket defines */
#define RRES_OUT_IMAGE 0
#define RRES_OUT_ALPHA 1
#define RRES_OUT_Z 2
#define RRES_OUT_NORMAL 3
#define RRES_OUT_UV 4
#define RRES_OUT_VEC 5
#define RRES_OUT_RGBA 6
#define RRES_OUT_DIFF 7
#define RRES_OUT_SPEC 8
#define RRES_OUT_SHADOW 9
#define RRES_OUT_AO 10
#define RRES_OUT_REFLECT 11
#define RRES_OUT_REFRACT 12
#define RRES_OUT_INDIRECT 13
#define RRES_OUT_INDEXOB 14
#define RRES_OUT_INDEXMA 15
#define RRES_OUT_MIST 16
#define RRES_OUT_EMIT 17
#define RRES_OUT_ENV 18
#define RRES_OUT_DIFF_DIRECT 19
#define RRES_OUT_DIFF_INDIRECT 20
#define RRES_OUT_DIFF_COLOR 21
#define RRES_OUT_GLOSSY_DIRECT 22
#define RRES_OUT_GLOSSY_INDIRECT 23
#define RRES_OUT_GLOSSY_COLOR 24
#define RRES_OUT_TRANSM_DIRECT 25
#define RRES_OUT_TRANSM_INDIRECT 26
#define RRES_OUT_TRANSM_COLOR 27
#define RRES_OUT_IMAGE 0
#define RRES_OUT_ALPHA 1
#define RRES_OUT_Z 2
#define RRES_OUT_NORMAL 3
#define RRES_OUT_UV 4
#define RRES_OUT_VEC 5
#define RRES_OUT_RGBA 6
#define RRES_OUT_DIFF 7
#define RRES_OUT_SPEC 8
#define RRES_OUT_SHADOW 9
#define RRES_OUT_AO 10
#define RRES_OUT_REFLECT 11
#define RRES_OUT_REFRACT 12
#define RRES_OUT_INDIRECT 13
#define RRES_OUT_INDEXOB 14
#define RRES_OUT_INDEXMA 15
#define RRES_OUT_MIST 16
#define RRES_OUT_EMIT 17
#define RRES_OUT_ENV 18
#define RRES_OUT_DIFF_DIRECT 19
#define RRES_OUT_DIFF_INDIRECT 20
#define RRES_OUT_DIFF_COLOR 21
#define RRES_OUT_GLOSSY_DIRECT 22
#define RRES_OUT_GLOSSY_INDIRECT 23
#define RRES_OUT_GLOSSY_COLOR 24
#define RRES_OUT_TRANSM_DIRECT 25
#define RRES_OUT_TRANSM_INDIRECT 26
#define RRES_OUT_TRANSM_COLOR 27
#define RRES_OUT_SUBSURFACE_DIRECT 28
#define RRES_OUT_SUBSURFACE_INDIRECT 29
#define RRES_OUT_SUBSURFACE_COLOR 30
/* note: types are needed to restore callbacks, don't change values */
#define CMP_NODE_VIEWER 201

View File

@ -209,34 +209,37 @@ typedef struct SceneRenderLayer {
#define SCE_LAY_NEG_ZMASK 0x80000
/* srl->passflag */
#define SCE_PASS_COMBINED (1<<0)
#define SCE_PASS_Z (1<<1)
#define SCE_PASS_RGBA (1<<2)
#define SCE_PASS_DIFFUSE (1<<3)
#define SCE_PASS_SPEC (1<<4)
#define SCE_PASS_SHADOW (1<<5)
#define SCE_PASS_AO (1<<6)
#define SCE_PASS_REFLECT (1<<7)
#define SCE_PASS_NORMAL (1<<8)
#define SCE_PASS_VECTOR (1<<9)
#define SCE_PASS_REFRACT (1<<10)
#define SCE_PASS_INDEXOB (1<<11)
#define SCE_PASS_UV (1<<12)
#define SCE_PASS_INDIRECT (1<<13)
#define SCE_PASS_MIST (1<<14)
#define SCE_PASS_RAYHITS (1<<15)
#define SCE_PASS_EMIT (1<<16)
#define SCE_PASS_ENVIRONMENT (1<<17)
#define SCE_PASS_INDEXMA (1<<18)
#define SCE_PASS_DIFFUSE_DIRECT (1<<19)
#define SCE_PASS_DIFFUSE_INDIRECT (1<<20)
#define SCE_PASS_DIFFUSE_COLOR (1<<21)
#define SCE_PASS_GLOSSY_DIRECT (1<<22)
#define SCE_PASS_GLOSSY_INDIRECT (1<<23)
#define SCE_PASS_GLOSSY_COLOR (1<<24)
#define SCE_PASS_TRANSM_DIRECT (1<<25)
#define SCE_PASS_TRANSM_INDIRECT (1<<26)
#define SCE_PASS_TRANSM_COLOR (1<<27)
#define SCE_PASS_COMBINED (1<<0)
#define SCE_PASS_Z (1<<1)
#define SCE_PASS_RGBA (1<<2)
#define SCE_PASS_DIFFUSE (1<<3)
#define SCE_PASS_SPEC (1<<4)
#define SCE_PASS_SHADOW (1<<5)
#define SCE_PASS_AO (1<<6)
#define SCE_PASS_REFLECT (1<<7)
#define SCE_PASS_NORMAL (1<<8)
#define SCE_PASS_VECTOR (1<<9)
#define SCE_PASS_REFRACT (1<<10)
#define SCE_PASS_INDEXOB (1<<11)
#define SCE_PASS_UV (1<<12)
#define SCE_PASS_INDIRECT (1<<13)
#define SCE_PASS_MIST (1<<14)
#define SCE_PASS_RAYHITS (1<<15)
#define SCE_PASS_EMIT (1<<16)
#define SCE_PASS_ENVIRONMENT (1<<17)
#define SCE_PASS_INDEXMA (1<<18)
#define SCE_PASS_DIFFUSE_DIRECT (1<<19)
#define SCE_PASS_DIFFUSE_INDIRECT (1<<20)
#define SCE_PASS_DIFFUSE_COLOR (1<<21)
#define SCE_PASS_GLOSSY_DIRECT (1<<22)
#define SCE_PASS_GLOSSY_INDIRECT (1<<23)
#define SCE_PASS_GLOSSY_COLOR (1<<24)
#define SCE_PASS_TRANSM_DIRECT (1<<25)
#define SCE_PASS_TRANSM_INDIRECT (1<<26)
#define SCE_PASS_TRANSM_COLOR (1<<27)
#define SCE_PASS_SUBSURFACE_DIRECT (1<<28)
#define SCE_PASS_SUBSURFACE_INDIRECT (1<<29)
#define SCE_PASS_SUBSURFACE_COLOR (1<<30)
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */

View File

@ -570,6 +570,9 @@ static void rna_def_render_pass(BlenderRNA *brna)
{SCE_PASS_TRANSM_DIRECT, "TRANSMISSION_DIRECT", 0, "Transmission Direct", ""},
{SCE_PASS_TRANSM_INDIRECT, "TRANSMISSION_INDIRECT", 0, "Transmission Indirect", ""},
{SCE_PASS_TRANSM_COLOR, "TRANSMISSION_COLOR", 0, "Transmission Color", ""},
{SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
{SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""},
{SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
{0, NULL, 0, NULL, NULL}
};

View File

@ -2555,6 +2555,24 @@ void rna_def_render_layer_common(StructRNA *srna, int scene)
RNA_def_property_ui_text(prop, "Transmission Color", "Deliver transmission color pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "use_pass_subsurface_direct", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_DIRECT);
RNA_def_property_ui_text(prop, "Subsurface Direct", "Deliver subsurface direct pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "use_pass_subsurface_indirect", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_INDIRECT);
RNA_def_property_ui_text(prop, "Subsurface Indirect", "Deliver subsurface indirect pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "use_pass_subsurface_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "passflag", SCE_PASS_SUBSURFACE_COLOR);
RNA_def_property_ui_text(prop, "Subsurface Color", "Deliver subsurface color pass");
if (scene) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderLayer_pass_update");
else RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
static void rna_def_freestyle_linesets(BlenderRNA *brna, PropertyRNA *cprop)

View File

@ -72,6 +72,9 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{ SOCK_RGBA, 0, N_("Transmission Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Transmission Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Transmission Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Subsurface Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Subsurface Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ SOCK_RGBA, 0, N_("Subsurface Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
@ -152,6 +155,13 @@ static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT);
if (passflag & SCE_PASS_TRANSM_COLOR)
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR);
if (passflag & SCE_PASS_SUBSURFACE_DIRECT)
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT);
if (passflag & SCE_PASS_SUBSURFACE_INDIRECT)
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT);
if (passflag & SCE_PASS_SUBSURFACE_COLOR)
cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR);
}
static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl)
@ -385,35 +395,38 @@ void node_cmp_rlayers_force_hidden_passes(bNode *node)
for (sock = node->outputs.first; sock; sock = sock->next)
sock->flag &= ~SOCK_UNAVAIL;
set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV);
set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA);
set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE);
set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC);
set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW);
set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO);
set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT);
set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT);
set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB);
set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA);
set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST);
set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT);
set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT);
set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT);
set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR);
set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT);
set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR);
set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV);
set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA);
set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE);
set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC);
set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW);
set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO);
set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT);
set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT);
set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB);
set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA);
set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST);
set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT);
set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT);
set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT);
set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR);
set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT);
set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR);
set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT, SCE_PASS_SUBSURFACE_DIRECT);
set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT, SCE_PASS_SUBSURFACE_INDIRECT);
set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR, SCE_PASS_SUBSURFACE_COLOR);
}
static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)

View File

@ -279,6 +279,24 @@ static const char *get_pass_name(int passtype, int channel)
if (channel == 1) return "TransCol.G";
return "TransCol.B";
}
if (passtype == SCE_PASS_SUBSURFACE_DIRECT) {
if (channel == -1) return "SubsurfaceDir";
if (channel == 0) return "SubsurfaceDir.R";
if (channel == 1) return "SubsurfaceDir.G";
return "SubsDir.B";
}
if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) {
if (channel == -1) return "SubsurfaceInd";
if (channel == 0) return "SubsurfaceInd.R";
if (channel == 1) return "SubsurfaceInd.G";
return "SubsInd.B";
}
if (passtype == SCE_PASS_SUBSURFACE_COLOR) {
if (channel == -1) return "SubsurfaceCol";
if (channel == 0) return "SubsurfaceCol.R";
if (channel == 1) return "SubsurfaceCol.G";
return "SubsCol.B";
}
return "Unknown";
}
@ -368,6 +386,15 @@ static int passtype_from_name(const char *str)
if (strcmp(str, "TransCol") == 0)
return SCE_PASS_TRANSM_COLOR;
if (strcmp(str, "SubsurfaceDir") == 0)
return SCE_PASS_SUBSURFACE_DIRECT;
if (strcmp(str, "SubsurfaceInd") == 0)
return SCE_PASS_SUBSURFACE_INDIRECT;
if (strcmp(str, "SubsurfaceCol") == 0)
return SCE_PASS_SUBSURFACE_COLOR;
return 0;
}
@ -538,6 +565,12 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT);
if (srl->passflag & SCE_PASS_TRANSM_COLOR)
render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR);
if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT)
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT);
if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT)
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT);
if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR);
}
/* sss, previewrender and envmap don't do layers, so we make a default one */
if (rr->layers.first == NULL && !(layername && layername[0])) {