Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/kernel/svm/svm_closure.h')
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h176
1 files changed, 145 insertions, 31 deletions
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 935504026ef..f378d24463d 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -20,19 +20,34 @@ CCL_NAMESPACE_BEGIN
/* Closure Nodes */
-__device void svm_node_glossy_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract)
+__device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract)
{
- if(type == CLOSURE_BSDF_REFRACTION_ID) {
+ if(type == CLOSURE_BSDF_SHARP_GLASS_ID) {
+ if(refract) {
+ sc->data0 = eta;
+ sd->flag |= bsdf_refraction_setup(sc);
+ }
+ else
+ sd->flag |= bsdf_reflection_setup(sc);
+ }
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
+ sc->data0 = roughness;
+ sc->data1 = eta;
+
if(refract)
- bsdf_refraction_setup(sd, sc, eta);
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
else
- bsdf_reflection_setup(sd, sc);
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
}
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
- bsdf_microfacet_beckmann_setup(sd, sc, roughness, eta, refract);
+ else {
+ sc->data0 = roughness;
+ sc->data1 = eta;
+
+ if(refract)
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
}
- else
- bsdf_microfacet_ggx_setup(sd, sc, roughness, eta, refract);
}
__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd)
@@ -57,7 +72,7 @@ __device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mi
#endif
}
-__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag)
+__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset)
{
uint type, param1_offset, param2_offset;
@@ -66,11 +81,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
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);
+ /* note we read this extra node before weight check, so offset is added */
+ uint4 data_node = read_node(kg, offset);
+
if(mix_weight == 0.0f)
return;
+
+ float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): 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.y)? stack_load_float3(stack, data_node.y): sd->N;
#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __int_as_float(node.z);
@@ -79,25 +102,32 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
switch(type) {
case CLOSURE_BSDF_DIFFUSE_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
float roughness = param1;
- if(roughness == 0.0f)
- bsdf_diffuse_setup(sd, sc);
- else
- bsdf_oren_nayar_setup(sd, sc, roughness);
+
+ if(roughness == 0.0f) {
+ sd->flag |= bsdf_diffuse_setup(sc);
+ }
+ else {
+ sc->data0 = roughness;
+ sd->flag |= bsdf_oren_nayar_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
- bsdf_translucent_setup(sd, sc);
+ sd->flag |= bsdf_translucent_setup(sc);
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
- bsdf_transparent_setup(sd, sc);
+ sd->flag |= bsdf_transparent_setup(sc);
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@@ -108,17 +138,17 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->data0 = param1;
svm_node_closure_set_mix_weight(sc, mix_weight);
- float roughness = param1;
-
/* setup bsdf */
if(type == CLOSURE_BSDF_REFLECTION_ID)
- bsdf_reflection_setup(sd, sc);
+ sd->flag |= bsdf_reflection_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
- bsdf_microfacet_beckmann_setup(sd, sc, roughness, 1.0f, false);
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
else
- bsdf_microfacet_ggx_setup(sd, sc, roughness, 1.0f, false);
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
break;
}
@@ -129,40 +159,68 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->data0 = param1;
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+
+ float eta = fmaxf(param2, 1.0f + 1e-5f);
+ sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFRACTION_ID)
+ sd->flag |= bsdf_refraction_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+
+ break;
+ }
+ case CLOSURE_BSDF_SHARP_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
+ case CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID: {
+#ifdef __CAUSTICS_TRICKS__
+ if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+#endif
/* index of refraction */
float eta = fmaxf(param2, 1.0f + 1e-5f);
eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
/* fresnel */
- float cosNO = dot(sd->N, sd->I);
+ float cosNO = dot(N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float roughness = param1;
#ifdef __MULTI_CLOSURE__
/* reflection */
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
float3 weight = sc->weight;
float sample_weight = sc->sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
- svm_node_glossy_setup(sd, sc, type, eta, roughness, false);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, false);
/* refraction */
sc = svm_node_closure_get(sd);
+ sc->N = N;
sc->weight = weight;
sc->sample_weight = sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
- svm_node_glossy_setup(sd, sc, type, eta, roughness, true);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, true);
#else
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
bool refract = (randb > fresnel);
svm_node_closure_set_mix_weight(sc, mix_weight);
- svm_node_glossy_setup(sd, sc, type, eta, roughness, refract);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
#endif
break;
@@ -174,22 +232,41 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->T = stack_load_float3(stack, data_node.z);
svm_node_closure_set_mix_weight(sc, mix_weight);
- float roughness_u = param1;
- float roughness_v = param2;
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.w);
- bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v);
+ if(rotation != 0.0f)
+ sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+
+ /* compute roughness */
+ float roughness = param1;
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
+
+ if(anisotropy < 0.0f) {
+ sc->data0 = roughness/(1.0f + anisotropy);
+ sc->data1 = roughness*(1.0f + anisotropy);
+ }
+ else {
+ sc->data0 = roughness*(1.0f - anisotropy);
+ sc->data1 = roughness/(1.0f - anisotropy);
+ }
+
+ sd->flag |= bsdf_ward_setup(sc);
break;
}
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
/* sigma */
- float sigma = clamp(param1, 0.0f, 1.0f);
- bsdf_ashikhmin_velvet_setup(sd, sc, sigma);
+ sc->data0 = clamp(param1, 0.0f, 1.0f);
+ sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
break;
}
default:
@@ -222,7 +299,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
svm_node_closure_set_mix_weight(sc, mix_weight);
float density = param1;
- volume_transparent_setup(sd, sc, density);
+ sd->flag |= volume_transparent_setup(sc, density);
break;
}
case CLOSURE_VOLUME_ISOTROPIC_ID: {
@@ -230,7 +307,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
svm_node_closure_set_mix_weight(sc, mix_weight);
float density = param1;
- volume_isotropic_setup(sd, sc, density);
+ sd->flag |= volume_isotropic_setup(sc, density);
break;
}
default:
@@ -320,6 +397,34 @@ __device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
sd->flag |= SD_HOLDOUT;
}
+__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)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
+
+ if(mix_weight == 0.0f)
+ return;
+
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->weight *= mix_weight;
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ }
+ else {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ }
+
+#else
+ ShaderClosure *sc = &sd->closure;
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+#endif
+
+ sd->flag |= SD_AO;
+}
+
/* Closure Nodes */
__device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
@@ -425,5 +530,14 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
#endif
}
+/* (Bump) normal */
+
+__device void svm_node_set_normal(KernelGlobals *kg, ShaderData *sd, float *stack, uint in_direction, uint out_normal)
+{
+ float3 normal = stack_load_float3(stack, in_direction);
+ sd->N = normal;
+ stack_store_float3(stack, out_normal, normal);
+}
+
CCL_NAMESPACE_END