diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-09-28 00:37:24 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-09-28 00:37:24 +0400 |
commit | cdee3435c67abebb633cb09410c4a87d42ff61e3 (patch) | |
tree | 9647e36a3661caab918e7726a5971b58b444d403 /intern/cycles/kernel | |
parent | 136d27b350355232ebe4d0a13427777445334b05 (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.cpp | 83 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 43 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 114 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_montecarlo.h | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 44 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_textures.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 66 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_shader.cpp | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_bsdf.h | 6 |
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; } |