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:
-rw-r--r--intern/cycles/blender/blender_object.cpp1
-rw-r--r--intern/cycles/kernel/geom/geom_object.h15
-rw-r--r--intern/cycles/kernel/kernel_bake.h3
-rw-r--r--intern/cycles/kernel/kernel_emission.h2
-rw-r--r--intern/cycles/kernel/kernel_light.h21
-rw-r--r--intern/cycles/kernel/kernel_shader.h21
-rw-r--r--intern/cycles/kernel/kernel_types.h4
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp24
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h6
-rw-r--r--intern/cycles/render/light.cpp12
-rw-r--r--intern/cycles/render/light.h2
-rw-r--r--intern/cycles/util/util_math.h12
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;
}