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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-28 00:37:24 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2011-09-28 00:37:24 +0400
commitcdee3435c67abebb633cb09410c4a87d42ff61e3 (patch)
tree9647e36a3661caab918e7726a5971b58b444d403 /intern/cycles/kernel
parent136d27b350355232ebe4d0a13427777445334b05 (diff)
Cycles: internal changes that should have no effect on user level yet, added
shader flags for various purposes, and some code for light types other than points.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/kernel.cpp83
-rw-r--r--intern/cycles/kernel/kernel_emission.h43
-rw-r--r--intern/cycles/kernel/kernel_light.h114
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h11
-rw-r--r--intern/cycles/kernel/kernel_path.h25
-rw-r--r--intern/cycles/kernel/kernel_shader.h44
-rw-r--r--intern/cycles/kernel/kernel_textures.h3
-rw-r--r--intern/cycles/kernel/kernel_types.h66
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp16
-rw-r--r--intern/cycles/kernel/svm/svm.h2
-rw-r--r--intern/cycles/kernel/svm/svm_bsdf.h6
11 files changed, 215 insertions, 198 deletions
diff --git a/intern/cycles/kernel/kernel.cpp b/intern/cycles/kernel/kernel.cpp
index 7e5fa25c662..52a3852aa01 100644
--- a/intern/cycles/kernel/kernel.cpp
+++ b/intern/cycles/kernel/kernel.cpp
@@ -73,82 +73,17 @@ void kernel_const_copy(KernelGlobals *kg, const char *name, void *host, size_t s
void kernel_tex_copy(KernelGlobals *kg, const char *name, device_ptr mem, size_t width, size_t height)
{
- if(strcmp(name, "__bvh_nodes") == 0) {
- kg->__bvh_nodes.data = (float4*)mem;
- kg->__bvh_nodes.width = width;
+ if(0) {
}
- else if(strcmp(name, "__objects") == 0) {
- kg->__objects.data = (float4*)mem;
- kg->__objects.width = width;
- }
- else if(strcmp(name, "__tri_normal") == 0) {
- kg->__tri_normal.data = (float4*)mem;
- kg->__tri_normal.width = width;
- }
- else if(strcmp(name, "__tri_woop") == 0) {
- kg->__tri_woop.data = (float4*)mem;
- kg->__tri_woop.width = width;
- }
- else if(strcmp(name, "__prim_visibility") == 0) {
- kg->__prim_visibility.data = (uint*)mem;
- kg->__prim_visibility.width = width;
- }
- else if(strcmp(name, "__prim_index") == 0) {
- kg->__prim_index.data = (uint*)mem;
- kg->__prim_index.width = width;
- }
- else if(strcmp(name, "__prim_object") == 0) {
- kg->__prim_object.data = (uint*)mem;
- kg->__prim_object.width = width;
- }
- else if(strcmp(name, "__object_node") == 0) {
- kg->__object_node.data = (uint*)mem;
- kg->__object_node.width = width;
- }
- else if(strcmp(name, "__tri_vnormal") == 0) {
- kg->__tri_vnormal.data = (float4*)mem;
- kg->__tri_vnormal.width = width;
- }
- else if(strcmp(name, "__tri_vindex") == 0) {
- kg->__tri_vindex.data = (float4*)mem;
- kg->__tri_vindex.width = width;
- }
- else if(strcmp(name, "__tri_verts") == 0) {
- kg->__tri_verts.data = (float4*)mem;
- kg->__tri_verts.width = width;
- }
- else if(strcmp(name, "__light_distribution") == 0) {
- kg->__light_distribution.data = (float4*)mem;
- kg->__light_distribution.width = width;
- }
- else if(strcmp(name, "__light_point") == 0) {
- kg->__light_point.data = (float4*)mem;
- kg->__light_point.width = width;
- }
- else if(strcmp(name, "__svm_nodes") == 0) {
- kg->__svm_nodes.data = (uint4*)mem;
- kg->__svm_nodes.width = width;
- }
- else if(strcmp(name, "__filter_table") == 0) {
- kg->__filter_table.data = (float*)mem;
- kg->__filter_table.width = width;
- }
- else if(strcmp(name, "__sobol_directions") == 0) {
- kg->__sobol_directions.data = (uint*)mem;
- kg->__sobol_directions.width = width;
- }
- else if(strcmp(name, "__attributes_map") == 0) {
- kg->__attributes_map.data = (uint4*)mem;
- kg->__attributes_map.width = width;
- }
- else if(strcmp(name, "__attributes_float") == 0) {
- kg->__attributes_float.data = (float*)mem;
- kg->__attributes_float.width = width;
- }
- else if(strcmp(name, "__attributes_float3") == 0) {
- kg->__attributes_float3.data = (float4*)mem;
- kg->__attributes_float3.width = width;
+
+#define KERNEL_TEX(type, ttype, tname) \
+ else if(strcmp(name, #tname) == 0) { \
+ kg->tname.data = (type*)mem; \
+ kg->tname.width = width; \
}
+#define KERNEL_IMAGE_TEX(type, ttype, tname)
+#include "kernel_textures.h"
+
else if(strstr(name, "__tex_image")) {
texture_image_uchar4 *tex = NULL;
int id = atoi(name + strlen("__tex_image_"));
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 58c9183e58a..13c48464088 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -63,15 +63,11 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
light_sample(kg, randt, randu, randv, sd->P, &ls);
}
- /* compute incoming direction and distance */
- float t;
- float3 omega_in = normalize_len(ls.P - sd->P, &t);
-
/* compute pdf */
- float pdf = light_sample_pdf(kg, &ls, -omega_in, t);
+ float pdf = light_sample_pdf(kg, &ls, -ls.D, ls.t);
/* evaluate closure */
- *eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -omega_in);
+ *eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D);
if(is_zero(*eval) || pdf == 0.0f)
return false;
@@ -80,7 +76,7 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
/* evaluate BSDF at shading point */
float bsdf_pdf;
- float3 bsdf_eval = shader_bsdf_eval(kg, sd, omega_in, &bsdf_pdf);
+ float3 bsdf_eval = shader_bsdf_eval(kg, sd, ls.D, &bsdf_pdf);
*eval *= bsdf_eval/pdf;
@@ -92,29 +88,34 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
float mis_weight = power_heuristic(pdf, bsdf_pdf);
*eval *= mis_weight;
}
- else {
+ else if(!(ls.shader & SHADER_AREA_LIGHT)) {
/* ensure point light works in Watts, this should be handled
* elsewhere but for now together with the diffuse emission
* closure it works out to the right value */
*eval *= 0.25f;
+
+ /* XXX verify with other light types */
}
-#if 0
- /* todo: implement this in light */
- bool no_shadow = true;
+ if(ls.shader & SHADER_CAST_SHADOW) {
+ /* setup ray */
+ ray->P = ray_offset(sd->P, sd->Ng);
- if(no_shadow) {
- ray->t = 0.0f;
+ if(ls.t == FLT_MAX) {
+ /* distant light */
+ ray->D = ls.D;
+ ray->t = ls.t;
+ }
+ else {
+ /* other lights, avoid self-intersection */
+ ray->D = ray_offset(ls.P, ls.Ng) - ray->P;
+ ray->D = normalize_len(ray->D, &ray->t);
+ }
}
else {
-#endif
- /* setup ray */
- ray->P = ray_offset(sd->P, sd->Ng);
- ray->D = ray_offset(ls.P, ls.Ng) - ray->P;
- ray->D = normalize_len(ray->D, &ray->t);
-#if 0
+ /* signal to not cast shadow ray */
+ ray->t = 0.0f;
}
-#endif
return true;
}
@@ -126,7 +127,7 @@ __device float3 indirect_emission(KernelGlobals *kg, ShaderData *sd, float t, in
/* evaluate emissive closure */
float3 L = shader_emissive_eval(kg, sd);
- if(!(path_flag & PATH_RAY_SINGULAR)) {
+ if(!(path_flag & PATH_RAY_SINGULAR) && (sd->flag & SD_SAMPLE_AS_LIGHT)) {
/* multiple importance sampling */
float pdf = triangle_light_pdf(kg, sd->Ng, sd->I, t);
float mis_weight = power_heuristic(bsdf_pdf, pdf);
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 77e73e932ef..68d08a2655f 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -20,30 +20,112 @@ CCL_NAMESPACE_BEGIN
typedef struct LightSample {
float3 P;
+ float3 D;
float3 Ng;
+ float t;
int object;
int prim;
int shader;
- float weight;
} LightSample;
-/* Point Light */
+/* Regular Light */
-__device void point_light_sample(KernelGlobals *kg, int point,
+__device float3 disk_light_sample(float3 v, float randu, float randv)
+{
+ float3 ru, rv;
+
+ make_orthonormals(v, &ru, &rv);
+ to_unit_disk(&randu, &randv);
+
+ return ru*randu + rv*randv;
+}
+
+__device float3 distant_light_sample(float3 D, float size, float randu, float randv)
+{
+ return normalize(D + disk_light_sample(D, randu, randv)*size);
+}
+
+__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv)
+{
+ return disk_light_sample(normalize(P - center), randu, randv)*size;
+}
+
+__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
+{
+ randu = randu - 0.5f;
+ randv = randv - 0.5f;
+
+ return axisu*randu + axisv*randv;
+}
+
+__device void regular_light_sample(KernelGlobals *kg, int point,
float randu, float randv, float3 P, LightSample *ls)
{
- float4 f = kernel_tex_fetch(__light_point, point);
+ float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
+ float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
+
+ LightType type = (LightType)__float_as_int(data0.x);
+
+ if(type == LIGHT_DISTANT) {
+ /* distant light */
+ float3 D = make_float3(data0.y, data0.z, data0.w);
+ float size = data1.y;
+
+ if(size > 0.0f)
+ D = distant_light_sample(D, size, randu, randv);
+
+ ls->P = D;
+ ls->Ng = -D;
+ ls->D = D;
+ ls->t = FLT_MAX;
+ }
+ else {
+ ls->P = make_float3(data0.y, data0.z, data0.w);
+
+ if(type == LIGHT_POINT) {
+ float size = data1.y;
+
+ /* sphere light */
+ if(size > 0.0f)
+ ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
+
+ ls->Ng = normalize(P - ls->P);
+ }
+ else {
+ /* area light */
+ float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
+ float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3);
+
+ float3 axisu = make_float3(data1.y, data1.z, data2.w);
+ float3 axisv = make_float3(data2.y, data2.z, data2.w);
+ float3 D = make_float3(data3.y, data3.z, data3.w);
+
+ ls->P += area_light_sample(axisu, axisv, randu, randv);
+ ls->Ng = D;
+ }
+
+ ls->t = 0.0f;
+ }
- ls->P = make_float3(f.x, f.y, f.z);
- ls->Ng = normalize(ls->P - P);
- ls->shader = __float_as_int(f.w);
+ ls->shader = __float_as_int(data1.x);
ls->object = ~0;
ls->prim = ~0;
}
-__device float point_light_pdf(KernelGlobals *kg, float t)
+__device float regular_light_pdf(KernelGlobals *kg,
+ const float3 Ng, const float3 I, float t)
{
- return t*t*kernel_data.integrator.pdf_lights;
+ float pdf = kernel_data.integrator.pdf_lights;
+
+ if(t == FLT_MAX)
+ return pdf;
+
+ float cos_pi = fabsf(dot(Ng, I));
+
+ if(cos_pi == 0.0f)
+ return 0.0f;
+
+ return t*t*pdf/cos_pi;
}
/* Triangle Light */
@@ -56,6 +138,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
ls->object = object;
ls->prim = prim;
+ ls->t = 0.0f;
#ifdef __INSTANCING__
/* instance transform */
@@ -117,7 +200,6 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
/* fetch light data */
float4 l = kernel_tex_fetch(__light_distribution, index);
int prim = __float_as_int(l.y);
- ls->weight = l.z;
if(prim >= 0) {
int object = __float_as_int(l.w);
@@ -125,8 +207,12 @@ __device void light_sample(KernelGlobals *kg, float randt, float randu, float ra
}
else {
int point = -prim-1;
- point_light_sample(kg, point, randu, randv, P, ls);
+ regular_light_sample(kg, point, randu, randv, P, ls);
}
+
+ /* compute incoming direction and distance */
+ if(ls->t != FLT_MAX)
+ ls->D = normalize_len(ls->P - P, &ls->t);
}
__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
@@ -136,19 +222,19 @@ __device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, fl
if(ls->prim != ~0)
pdf = triangle_light_pdf(kg, ls->Ng, I, t);
else
- pdf = point_light_pdf(kg, t);
+ pdf = regular_light_pdf(kg, ls->Ng, I, t);
return pdf;
}
__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
{
- point_light_sample(kg, index, randu, randv, P, ls);
+ regular_light_sample(kg, index, randu, randv, P, ls);
}
__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
{
- return point_light_pdf(kg, t);
+ return regular_light_pdf(kg, ls->Ng, I, t);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index 5d9afb6418f..df291b66b23 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -67,17 +67,6 @@ __device void to_unit_disk(float *x, float *y)
*y = r * sinf(phi);
}
-__device_inline void make_orthonormals(const float3 N, float3 *a, float3 *b)
-{
- if(N.x != N.y || N.x != N.z)
- *a = make_float3(N.z-N.y, N.x-N.z, N.y-N.x); //(1,1,1)x N
- else
- *a = make_float3(N.z-N.y, N.x+N.z, -N.y-N.x); //(-1,1,1)x N
-
- *a = normalize(*a);
- *b = cross(N, *a);
-}
-
__device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b)
{
*b = cross(N, T);
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index d6977c24c53..e438780b1c8 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -162,19 +162,6 @@ __device_inline float path_state_terminate_probability(KernelGlobals *kg, PathSt
return average(throughput);
}
-#ifdef __TRANSPARENT_SHADOWS__
-__device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
-{
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 Ns = kernel_tex_fetch(__tri_normal, prim);
- int shader = __float_as_int(Ns.w);
-
- /* todo: add shader flag to check this */
-
- return true;
-}
-#endif
-
__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, Intersection *isect, float3 *light_L)
{
if(ray->t == 0.0f)
@@ -229,12 +216,10 @@ __device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ra
throughput *= shader_bsdf_transparency(kg, &sd);
ray->P = ray_offset(sd.P, -sd.Ng);
- ray->t = len(Pend - ray->P);
+ ray->t = (ray->t == FLT_MAX)? FLT_MAX: len(Pend - ray->P);
bounce++;
}
-
- return true;
}
}
#endif
@@ -298,10 +283,8 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
#ifdef __EMISSION__
/* emission */
- if(kernel_data.integrator.use_emission) {
- if(sd.flag & SD_EMISSION)
- L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
- }
+ if(sd.flag & SD_EMISSION)
+ L += throughput*indirect_emission(kg, &sd, isect.t, state.flag, ray_pdf);
#endif
/* path termination. this is a strange place to put the termination, it's
@@ -316,7 +299,7 @@ __device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, R
throughput /= probability;
#ifdef __EMISSION__
- if(kernel_data.integrator.use_emission) {
+ if(kernel_data.integrator.use_direct_light) {
/* sample illumination from lights to find path contribution */
if(sd.flag & SD_BSDF_HAS_EVAL) {
float light_t = path_rng(kg, rng, sample, rng_offset + PRNG_LIGHT);
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index 0cf2091590c..c1bcbb067b5 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -60,7 +60,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->N = Ng;
sd->I = -ray->D;
sd->shader = shader;
- sd->flag = 0;
/* triangle */
#ifdef __INSTANCING__
@@ -73,10 +72,10 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#endif
/* smooth normal */
- if(sd->shader < 0) {
+ if(sd->shader & SHADER_SMOOTH_NORMAL)
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
- sd->shader = -sd->shader;
- }
+
+ sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
#ifdef __DPDU__
/* dPdu/dPdv */
@@ -103,7 +102,7 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
if(backfacing) {
- sd->flag = SD_BACKFACING;
+ sd->flag |= SD_BACKFACING;
sd->Ng = -sd->Ng;
sd->N = -sd->N;
#ifdef __DPDU__
@@ -132,7 +131,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
sd->Ng = Ng;
sd->I = I;
sd->shader = shader;
- sd->flag = 0;
/* primitive */
#ifdef __INSTANCING__
@@ -159,9 +157,8 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
/* smooth normal */
- if(sd->shader < 0) {
+ if(sd->shader & SHADER_SMOOTH_NORMAL) {
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
- sd->shader = -sd->shader;
#ifdef __INSTANCING__
if(instanced)
@@ -169,6 +166,8 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
}
+ sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
+
#ifdef __DPDU__
/* dPdu/dPdv */
if(sd->prim == ~0) {
@@ -192,7 +191,7 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
if(backfacing) {
- sd->flag = SD_BACKFACING;
+ sd->flag |= SD_BACKFACING;
sd->Ng = -sd->Ng;
sd->N = -sd->N;
#ifdef __DPDU__
@@ -245,7 +244,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
sd->Ng = -sd->P;
sd->I = -sd->P;
sd->shader = kernel_data.background.shader;
- sd->flag = 0;
+ sd->flag = kernel_tex_fetch(__shader_flag, sd->shader & SHADER_MASK);
#ifdef __INSTANCING__
sd->object = ~0;
@@ -410,7 +409,7 @@ __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // XXX osl
+ if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
eval += sc->weight;
}
@@ -428,8 +427,9 @@ __device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
{
+ float3 eval;
#ifdef __MULTI_CLOSURE__
- float3 eval = make_float3(0.0f, 0.0f, 0.0f);
+ eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
@@ -442,11 +442,11 @@ __device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
#endif
}
}
-
- return eval;
#else
- return svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
+ eval = svm_emissive_eval(sd, &sd->closure)*sd->closure.weight;
#endif
+
+ return eval;
}
/* Holdout */
@@ -581,6 +581,20 @@ __device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd)
#endif
}
+/* Transparent Shadows */
+
+#ifdef __TRANSPARENT_SHADOWS__
+__device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
+{
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 Ns = kernel_tex_fetch(__tri_normal, prim);
+ int shader = __float_as_int(Ns.w);
+ int flag = kernel_tex_fetch(__shader_flag, shader & SHADER_MASK);
+
+ return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
+}
+#endif
+
/* Free ShaderData */
__device void shader_release(KernelGlobals *kg, ShaderData *sd)
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 19635b2664c..2bfb1b3b88e 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -32,10 +32,11 @@ KERNEL_TEX(float4, texture_float4, __attributes_float3)
/* lights */
KERNEL_TEX(float4, texture_float4, __light_distribution)
-KERNEL_TEX(float4, texture_float4, __light_point)
+KERNEL_TEX(float4, texture_float4, __light_data)
/* shaders */
KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
+KERNEL_TEX(uint, texture_uint, __shader_flag)
/* camera/film */
KERNEL_TEX(float, texture_float, __filter_table)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index e09eaa8284c..bda037e88cc 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -26,6 +26,7 @@
CCL_NAMESPACE_BEGIN
#define OBJECT_SIZE 16
+#define LIGHT_SIZE 4
#define __SOBOL__
#define __INSTANCING__
@@ -43,12 +44,12 @@ CCL_NAMESPACE_BEGIN
#define __EMISSION__
#define __TEXTURES__
#define __HOLDOUT__
+//#define __MULTI_CLOSURE__
+//#define __TRANSPARENT_SHADOWS__
+//#define __MULTI_LIGHT__
#endif
#ifdef __KERNEL_CPU__
-//#define __MULTI_CLOSURE__
-//#define __MULTI_LIGHT__
-//#define __TRANSPARENT_SHADOWS__
//#define __OSL__
#endif
@@ -79,6 +80,7 @@ enum PathTraceDimension {
/* these flag values correspond exactly to OSL defaults, so be careful not to
* change this, or if you do, set the "raytypes" shading system attribute with
* your own new ray types and bitflag values */
+
enum PathRayFlag {
PATH_RAY_CAMERA = 1,
PATH_RAY_SHADOW = 2,
@@ -92,28 +94,6 @@ enum PathRayFlag {
PATH_RAY_ALL = (1|2|4|8|16|32|64|128)
};
-/* Bidirectional Path Tracing */
-
-enum BidirTraceDimension {
- BRNG_FILTER_U = 0,
- BRNG_FILTER_V = 1,
- BRNG_LENS_U = 2,
- BRNG_LENS_V = 3,
- BRNG_LIGHT_U = 4,
- BRNG_LIGHT_V = 5,
- BRNG_LIGHT = 6,
- BRNG_LIGHT_F = 7,
- BRNG_EMISSIVE_U = 8,
- BRNG_EMISSIVE_V = 9,
- BRNG_BASE_NUM = 10,
-
- BRNG_BSDF_U = 0,
- BRNG_BSDF_V = 1,
- BRNG_BSDF = 2,
- BRNG_TERMINATE = 3,
- BRNG_BOUNCE_NUM = 4
-};
-
/* Closure Label */
typedef enum ClosureLabel {
@@ -132,16 +112,23 @@ typedef enum ClosureLabel {
LABEL_STOP = 2048
} ClosureLabel;
-/* Ray Type */
+/* Shader Flag */
+
+typedef enum ShaderFlag {
+ SHADER_SMOOTH_NORMAL = (1 << 31),
+ SHADER_CAST_SHADOW = (1 << 30),
+ SHADER_AREA_LIGHT = (1 << 29),
-typedef enum RayType {
- RayTypeCamera = 1,
- RayTypeShadow = 2,
- RayTypeReflection = 4,
- RayTypeRefraction = 8,
- RayTypeDiffuse = 16,
- RayTypeGlossy = 32
-} RayType;
+ SHADER_MASK = ~(SHADER_SMOOTH_NORMAL|SHADER_CAST_SHADOW|SHADER_AREA_LIGHT)
+} ShaderFlag;
+
+/* Light Type */
+
+typedef enum LightType {
+ LIGHT_POINT,
+ LIGHT_DISTANT,
+ LIGHT_AREA
+} LightType;
/* Differential */
@@ -213,13 +200,20 @@ typedef struct ShaderClosure {
* are in world space. */
enum ShaderDataFlag {
+ /* runtime flags */
SD_BACKFACING = 1, /* backside of surface? */
SD_EMISSION = 2, /* have emissive closure? */
SD_BSDF = 4, /* have bsdf closure? */
SD_BSDF_HAS_EVAL = 8, /* have non-singular bsdf closure? */
SD_BSDF_GLOSSY = 16, /* have glossy bsdf */
SD_HOLDOUT = 32, /* have holdout closure? */
- SD_VOLUME = 64 /* have volume closure? */
+ SD_VOLUME = 64, /* have volume closure? */
+
+ /* shader flags */
+ SD_SAMPLE_AS_LIGHT = 128, /* direct light sample */
+ SD_HAS_SURFACE_TRANSPARENT = 256, /* has surface transparency */
+ SD_HAS_VOLUME = 512, /* has volume shader */
+ SD_HOMOGENEOUS_VOLUME = 1024 /* has homogeneous volume */
};
typedef struct ShaderData {
@@ -351,7 +345,7 @@ typedef struct KernelSunSky {
typedef struct KernelIntegrator {
/* emission */
- int use_emission;
+ int use_direct_light;
int num_distribution;
int num_all_lights;
float pdf_triangles;
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 3f0b1610181..18a8e974492 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -216,8 +216,10 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
/* execute shader for this point */
- if(kg->osl.surface_state[sd->shader])
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[sd->shader]), *globals);
+ int shader = sd->shader & SHADER_MASK;
+
+ if(kg->osl.surface_state[shader])
+ ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.surface_state[shader]), *globals);
/* flatten closure tree */
sd->num_closure = 0;
@@ -351,7 +353,10 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
shaderdata_to_shaderglobals(kg, sd, path_flag, globals);
/* execute shader */
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[sd->shader]), *globals);
+ int shader = sd->shader & SHADER_MASK;
+
+ if(kg->osl.volume_state[shader])
+ ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.volume_state[shader]), *globals);
/* retrieve resulting closures */
sd->osl_closure.volume_sample_sum = 0.0f;
@@ -377,7 +382,10 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
shaderdata_to_shaderglobals(kg, sd, 0, globals);
/* execute shader */
- ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[sd->shader]), *globals);
+ int shader = sd->shader & SHADER_MASK;
+
+ if(kg->osl.displacement_state[shader])
+ ctx->execute(OSL::pvt::ShadUseSurface, *(kg->osl.displacement_state[shader]), *globals);
/* get back position */
sd->P = TO_FLOAT3(globals->P);
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index bd5c07753ad..62e02f1a01a 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -152,7 +152,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
{
float stack[SVM_STACK_SIZE];
float closure_weight = 1.0f;
- int offset = sd->shader;
+ int offset = sd->shader & SHADER_MASK;
#ifdef __MULTI_CLOSURE__
sd->num_closure = 0;
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
index a1b39c6ca1e..411efc8be8f 100644
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ b/intern/cycles/kernel/svm/svm_bsdf.h
@@ -90,6 +90,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_DIFFUSE_ID:
eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
+#ifdef __SVM__
case CLOSURE_BSDF_TRANSLUCENT_ID:
eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
@@ -124,6 +125,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf);
break;
+#endif
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
break;
@@ -134,6 +136,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_DIFFUSE_ID:
eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
+#ifdef __SVM__
case CLOSURE_BSDF_TRANSLUCENT_ID:
eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
@@ -168,6 +171,7 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf);
break;
+#endif
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
break;
@@ -183,6 +187,7 @@ __device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_DIFFUSE_ID:
bsdf_diffuse_blur(sc, roughness);
break;
+#ifdef __SVM__
case CLOSURE_BSDF_TRANSLUCENT_ID:
bsdf_translucent_blur(sc, roughness);
break;
@@ -217,6 +222,7 @@ __device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
bsdf_westin_sheen_blur(sc, roughness);
break;
+#endif
default:
break;
}