diff options
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 1 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/geom_object.h | 15 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bake.h | 3 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_emission.h | 2 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_light.h | 21 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_shader.h | 21 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_services.cpp | 24 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 6 | ||||
-rw-r--r-- | intern/cycles/render/light.cpp | 12 | ||||
-rw-r--r-- | intern/cycles/render/light.h | 2 | ||||
-rw-r--r-- | intern/cycles/util/util_math.h | 12 |
12 files changed, 105 insertions, 18 deletions
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index f7f77dfb4cb..0d961c5bf88 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -153,6 +153,7 @@ void BlenderSync::sync_light(BL::Object& b_parent, /* location and (inverted!) direction */ light->co = transform_get_column(&tfm, 3); light->dir = -transform_get_column(&tfm, 2); + light->tfm = tfm; /* shader */ vector<Shader*> used_shaders; diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 32900f7f27a..6b42f66b0d5 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -55,6 +55,21 @@ ccl_device_inline Transform object_fetch_transform(KernelGlobals *kg, int object return tfm; } +/* Lamp to world space transformation */ + +ccl_device_inline Transform lamp_fetch_transform(KernelGlobals *kg, int lamp, bool inverse) +{ + int offset = lamp*LIGHT_SIZE + (inverse? 8 : 5); + + Transform tfm; + tfm.x = kernel_tex_fetch(__light_data, offset + 0); + tfm.y = kernel_tex_fetch(__light_data, offset + 1); + tfm.z = kernel_tex_fetch(__light_data, offset + 2); + tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f); + + return tfm; +} + /* Object to world space transformation for motion vectors */ ccl_device_inline Transform object_fetch_vector_transform(KernelGlobals *kg, int object, enum ObjectVectorTransform type) diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h index fd9207fd69f..84575d35d7f 100644 --- a/intern/cycles/kernel/kernel_bake.h +++ b/intern/cycles/kernel/kernel_bake.h @@ -320,7 +320,8 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input, P, Ng, Ng, shader, object, prim, u, v, 1.0f, 0.5f, - !(kernel_tex_fetch(__object_flag, object) & SD_TRANSFORM_APPLIED)); + !(kernel_tex_fetch(__object_flag, object) & SD_TRANSFORM_APPLIED), + LAMP_NONE); sd.I = sd.N; /* update differentials */ diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h index ac498ba3592..9e4a631b998 100644 --- a/intern/cycles/kernel/kernel_emission.h +++ b/intern/cycles/kernel/kernel_emission.h @@ -65,7 +65,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, shader_setup_from_sample(kg, emission_sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, - ls->u, ls->v, t, time, false); + ls->u, ls->v, t, time, false, ls->lamp); ls->Ng = ccl_fetch(emission_sd, Ng); diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h index fffa9afb342..d4cc36d1495 100644 --- a/intern/cycles/kernel/kernel_light.h +++ b/intern/cycles/kernel/kernel_light.h @@ -297,7 +297,7 @@ ccl_device_inline float background_portal_pdf(KernelGlobals *kg, float3 axisu = make_float3(data1.y, data1.z, data1.w); float3 axisv = make_float3(data2.y, data2.z, data2.w); - if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL)) + if(!ray_quad_intersect(P, direction, 1e-4f, FLT_MAX, lightpos, axisu, axisv, dir, NULL, NULL, NULL, NULL)) continue; portal_pdf += area_light_sample(P, &lightpos, axisu, axisv, 0.0f, 0.0f, false); @@ -585,6 +585,10 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg, return false; } } + float2 uv = map_to_sphere(ls->Ng); + ls->u = uv.x; + ls->v = uv.y; + ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t); } else { @@ -600,11 +604,16 @@ ccl_device_inline bool lamp_light_sample(KernelGlobals *kg, return false; } + float3 inplane = ls->P; ls->pdf = area_light_sample(P, &ls->P, axisu, axisv, randu, randv, true); + inplane = ls->P - inplane; + ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f; + ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f; + ls->Ng = D; ls->D = normalize_len(ls->P - P, &ls->t); @@ -706,6 +715,9 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, if(ls->eval_fac == 0.0f) return false; } + float2 uv = map_to_sphere(ls->Ng); + ls->u = uv.x; + ls->v = uv.y; /* compute pdf */ if(ls->t != FLT_MAX) @@ -730,8 +742,10 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float3 light_P = make_float3(data0.y, data0.z, data0.w); - if(!ray_quad_intersect(P, D, 0.0f, t, - light_P, axisu, axisv, Ng, &ls->P, &ls->t)) + if(!ray_quad_intersect(P, D, 0.0f, t, light_P, + axisu, axisv, Ng, + &ls->P, &ls->t, + &ls->u, &ls->v)) { return false; } @@ -887,4 +901,3 @@ ccl_device int light_select_num_samples(KernelGlobals *kg, int index) } CCL_NAMESPACE_END - diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 3e098c922dc..6480975a84d 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -242,7 +242,8 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, int shader, int object, int prim, float u, float v, float t, float time, - bool object_space) + bool object_space, + int lamp) { /* vectors */ ccl_fetch(sd, P) = P; @@ -250,7 +251,12 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, ccl_fetch(sd, Ng) = Ng; ccl_fetch(sd, I) = I; ccl_fetch(sd, shader) = shader; - ccl_fetch(sd, type) = (prim == PRIM_NONE)? PRIMITIVE_NONE: PRIMITIVE_TRIANGLE; + if(prim != PRIM_NONE) + ccl_fetch(sd, type) = PRIMITIVE_TRIANGLE; + else if(lamp != LAMP_NONE) + ccl_fetch(sd, type) = PRIMITIVE_LAMP; + else + ccl_fetch(sd, type) = PRIMITIVE_NONE; /* primitive */ #ifdef __INSTANCING__ @@ -270,11 +276,15 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, #ifdef __OBJECT_MOTION__ shader_setup_object_transforms(kg, sd, time); +#else + } + else if(lamp != LAMP_NONE) { + ccl_fetch(sd, ob_tfm) = lamp_fetch_transform(kg, lamp, false); + ccl_fetch(sd, ob_itfm) = lamp_fetch_transform(kg, lamp, true); } +#ifdef __OBJECT_MOTION__ ccl_fetch(sd, time) = time; -#else - } #endif /* transform into world space */ @@ -357,7 +367,8 @@ ccl_device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd, P, Ng, I, shader, object, prim, u, v, 0.0f, 0.5f, - !(kernel_tex_fetch(__object_flag, object) & SD_TRANSFORM_APPLIED)); + !(kernel_tex_fetch(__object_flag, object) & SD_TRANSFORM_APPLIED), + LAMP_NONE); } /* ShaderData setup from ray into background */ diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 734b4462a91..91b86618745 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -37,7 +37,7 @@ CCL_NAMESPACE_BEGIN /* constants */ #define OBJECT_SIZE 12 #define OBJECT_VECTOR_SIZE 6 -#define LIGHT_SIZE 5 +#define LIGHT_SIZE 11 #define FILTER_TABLE_SIZE 1024 #define RAMP_TABLE_SIZE 256 #define SHUTTER_TABLE_SIZE 256 @@ -552,6 +552,8 @@ typedef enum PrimitiveType { PRIMITIVE_MOTION_TRIANGLE = 2, PRIMITIVE_CURVE = 4, PRIMITIVE_MOTION_CURVE = 8, + /* Lamp primitive is not included below on purpose, since it is no real traceable primitive */ + PRIMITIVE_LAMP = 16, PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE|PRIMITIVE_MOTION_TRIANGLE), PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE|PRIMITIVE_MOTION_CURVE), diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 0f3edcb7eaa..26543862b80 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -168,6 +168,12 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result return true; } + else if(sd->type == PRIMITIVE_LAMP) { + Transform tfm = transform_transpose(sd->ob_tfm); + COPY_MATRIX44(&result, &tfm); + + return true; + } } return false; @@ -198,6 +204,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 return true; } + else if(sd->type == PRIMITIVE_LAMP) { + Transform tfm = transform_transpose(sd->ob_itfm); + COPY_MATRIX44(&result, &tfm); + + return true; + } } return false; @@ -287,6 +299,12 @@ bool OSLRenderServices::get_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 &result return true; } + else if(sd->type == PRIMITIVE_LAMP) { + Transform tfm = transform_transpose(sd->ob_tfm); + COPY_MATRIX44(&result, &tfm); + + return true; + } } return false; @@ -312,6 +330,12 @@ bool OSLRenderServices::get_inverse_matrix(OSL::ShaderGlobals *sg, OSL::Matrix44 return true; } + else if(sd->type == PRIMITIVE_LAMP) { + Transform tfm = transform_transpose(sd->ob_itfm); + COPY_MATRIX44(&result, &tfm); + + return true; + } } return false; diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 6ea2539c543..6c3394adbce 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -49,7 +49,7 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if(ccl_fetch(sd, object) != OBJECT_NONE) + if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) object_inverse_normal_transform(kg, sd, &data); break; } @@ -131,7 +131,7 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if(ccl_fetch(sd, object) != OBJECT_NONE) + if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) object_inverse_normal_transform(kg, sd, &data); break; } @@ -216,7 +216,7 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if(ccl_fetch(sd, object) != OBJECT_NONE) + if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) object_inverse_normal_transform(kg, sd, &data); break; } diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 93f6d7902f0..777f3229ce6 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -126,6 +126,8 @@ NODE_DEFINE(Light) SOCKET_FLOAT(spot_angle, "Spot Angle", M_PI_4_F); SOCKET_FLOAT(spot_smooth, "Spot Smooth", 0.0f); + SOCKET_TRANSFORM(tfm, "Transform", transform_identity()); + SOCKET_BOOLEAN(cast_shadow, "Cast Shadow", true); SOCKET_BOOLEAN(use_mis, "Use Mis", false); SOCKET_BOOLEAN(use_diffuse, "Use Diffuse", true); @@ -762,6 +764,11 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 4] = make_float4(max_bounces, 0.0f, 0.0f, 0.0f); + Transform tfm = light->tfm; + Transform itfm = transform_inverse(tfm); + memcpy(&light_data[light_index*LIGHT_SIZE + 5], &tfm, sizeof(float4)*3); + memcpy(&light_data[light_index*LIGHT_SIZE + 8], &itfm, sizeof(float4)*3); + light_index++; } @@ -788,6 +795,11 @@ void LightManager::device_update_points(Device *device, light_data[light_index*LIGHT_SIZE + 3] = make_float4(-1, dir.x, dir.y, dir.z); light_data[light_index*LIGHT_SIZE + 4] = make_float4(-1, 0.0f, 0.0f, 0.0f); + Transform tfm = light->tfm; + Transform itfm = transform_inverse(tfm); + memcpy(&light_data[light_index*LIGHT_SIZE + 5], &tfm, sizeof(float4)*3); + memcpy(&light_data[light_index*LIGHT_SIZE + 8], &itfm, sizeof(float4)*3); + light_index++; } diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index 040a672937d..f56530b6490 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -50,6 +50,8 @@ public: float3 axisv; float sizev; + Transform tfm; + int map_resolution; float spot_angle; diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h index bd376e80c64..e2abfcde702 100644 --- a/intern/cycles/util/util_math.h +++ b/intern/cycles/util/util_math.h @@ -1579,7 +1579,7 @@ ccl_device_inline bool ray_triangle_intersect_uv( ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, float ray_maxt, float3 quad_P, float3 quad_u, float3 quad_v, float3 quad_n, - float3 *isect_P, float *isect_t) + float3 *isect_P, float *isect_t, float *isect_u, float *isect_v) { float t = -(dot(ray_P, quad_n) - dot(quad_P, quad_n)) / dot(ray_D, quad_n); if(t < ray_mint || t > ray_maxt) @@ -1587,13 +1587,19 @@ ccl_device bool ray_quad_intersect(float3 ray_P, float3 ray_D, float ray_mint, f float3 hit = ray_P + t*ray_D; float3 inplane = hit - quad_P; - if(fabsf(dot(inplane, quad_u) / dot(quad_u, quad_u)) > 0.5f) + + float u = dot(inplane, quad_u) / dot(quad_u, quad_u) + 0.5f; + if(u < 0.0f || u > 1.0f) return false; - if(fabsf(dot(inplane, quad_v) / dot(quad_v, quad_v)) > 0.5f) + + float v = dot(inplane, quad_v) / dot(quad_v, quad_v) + 0.5f; + if(v < 0.0f || v > 1.0f) return false; if(isect_P) *isect_P = hit; if(isect_t) *isect_t = t; + if(isect_u) *isect_u = u; + if(isect_v) *isect_v = v; return true; } |