forked from bartvdbraak/blender
Cycles: spot lamp support.
This commit is contained in:
parent
0f1fd51c21
commit
6548f7efef
@ -488,9 +488,7 @@ class CyclesLamp_PT_lamp(CyclesButtonsPanel, Panel):
|
|||||||
col = split.column()
|
col = split.column()
|
||||||
col.prop(clamp, "cast_shadow")
|
col.prop(clamp, "cast_shadow")
|
||||||
|
|
||||||
if lamp.type == 'SPOT':
|
if lamp.type == 'HEMI':
|
||||||
layout.label(text="Not supported, interpreted as point lamp.")
|
|
||||||
elif lamp.type == 'HEMI':
|
|
||||||
layout.label(text="Not supported, interpreted as sun lamp.")
|
layout.label(text="Not supported, interpreted as sun lamp.")
|
||||||
|
|
||||||
|
|
||||||
@ -509,6 +507,29 @@ class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel):
|
|||||||
if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
|
if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
|
||||||
layout.prop(lamp, "color")
|
layout.prop(lamp, "color")
|
||||||
|
|
||||||
|
class CyclesLamp_PT_spot(CyclesButtonsPanel, Panel):
|
||||||
|
bl_label = "Spot Shape"
|
||||||
|
bl_context = "data"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
lamp = context.lamp
|
||||||
|
return (lamp and lamp.type == 'SPOT') and CyclesButtonsPanel.poll(context)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
lamp = context.lamp
|
||||||
|
|
||||||
|
split = layout.split()
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
sub = col.column()
|
||||||
|
sub.prop(lamp, "spot_size", text="Size")
|
||||||
|
sub.prop(lamp, "spot_blend", text="Blend", slider=True)
|
||||||
|
|
||||||
|
col = split.column()
|
||||||
|
col.prop(lamp, "show_cone")
|
||||||
|
|
||||||
class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
|
class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
|
||||||
bl_label = "Surface"
|
bl_label = "Surface"
|
||||||
|
@ -106,7 +106,9 @@ void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob,
|
|||||||
case BL::Lamp::type_SPOT: {
|
case BL::Lamp::type_SPOT: {
|
||||||
BL::SpotLamp b_spot_lamp(b_lamp);
|
BL::SpotLamp b_spot_lamp(b_lamp);
|
||||||
light->size = b_spot_lamp.shadow_soft_size();
|
light->size = b_spot_lamp.shadow_soft_size();
|
||||||
light->type = LIGHT_POINT;
|
light->type = LIGHT_SPOT;
|
||||||
|
light->spot_angle = b_spot_lamp.spot_size();
|
||||||
|
light->spot_smooth = b_spot_lamp.spot_blend();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BL::Lamp::type_HEMI: {
|
case BL::Lamp::type_HEMI: {
|
||||||
|
@ -104,13 +104,8 @@ __device bool direct_emission(KernelGlobals *kg, ShaderData *sd, int lindex,
|
|||||||
float mis_weight = power_heuristic(pdf, bsdf_pdf);
|
float mis_weight = power_heuristic(pdf, bsdf_pdf);
|
||||||
light_eval *= mis_weight;
|
light_eval *= mis_weight;
|
||||||
}
|
}
|
||||||
/* todo: clean up these weights */
|
|
||||||
else if(ls.shader & SHADER_AREA_LIGHT)
|
|
||||||
light_eval *= 0.25f; /* area lamp */
|
|
||||||
else if(ls.t != FLT_MAX)
|
|
||||||
light_eval *= 0.25f*M_1_PI_F; /* point lamp */
|
|
||||||
|
|
||||||
bsdf_eval_mul(eval, light_eval/pdf);
|
bsdf_eval_mul(eval, light_eval*(ls.eval_fac/pdf));
|
||||||
|
|
||||||
if(bsdf_eval_is_zero(eval))
|
if(bsdf_eval_is_zero(eval))
|
||||||
return false;
|
return false;
|
||||||
|
@ -23,6 +23,7 @@ typedef struct LightSample {
|
|||||||
float3 D;
|
float3 D;
|
||||||
float3 Ng;
|
float3 Ng;
|
||||||
float t;
|
float t;
|
||||||
|
float eval_fac;
|
||||||
int object;
|
int object;
|
||||||
int prim;
|
int prim;
|
||||||
int shader;
|
int shader;
|
||||||
@ -189,6 +190,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
|||||||
ls->Ng = D;
|
ls->Ng = D;
|
||||||
ls->D = -D;
|
ls->D = -D;
|
||||||
ls->t = FLT_MAX;
|
ls->t = FLT_MAX;
|
||||||
|
ls->eval_fac = 1.0f;
|
||||||
}
|
}
|
||||||
#ifdef __BACKGROUND_MIS__
|
#ifdef __BACKGROUND_MIS__
|
||||||
else if(type == LIGHT_BACKGROUND) {
|
else if(type == LIGHT_BACKGROUND) {
|
||||||
@ -199,6 +201,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
|||||||
ls->Ng = D;
|
ls->Ng = D;
|
||||||
ls->D = -D;
|
ls->D = -D;
|
||||||
ls->t = FLT_MAX;
|
ls->t = FLT_MAX;
|
||||||
|
ls->eval_fac = 1.0f;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
@ -212,6 +215,36 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
|||||||
ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
|
ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
|
||||||
|
|
||||||
ls->Ng = normalize(P - ls->P);
|
ls->Ng = normalize(P - ls->P);
|
||||||
|
ls->eval_fac = 0.25f*M_1_PI_F;
|
||||||
|
}
|
||||||
|
else if(type == LIGHT_SPOT) {
|
||||||
|
float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
|
||||||
|
float size = data1.y;
|
||||||
|
|
||||||
|
/* spot light */
|
||||||
|
if(size > 0.0f)
|
||||||
|
ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
|
||||||
|
|
||||||
|
float3 dir = make_float3(data1.z, data1.w, data2.x);
|
||||||
|
float3 I = normalize(P - ls->P);
|
||||||
|
|
||||||
|
float spot_angle = data2.y;
|
||||||
|
float spot_smooth = data2.z;
|
||||||
|
|
||||||
|
float eval_fac = fabsf(dot(dir, I));
|
||||||
|
|
||||||
|
if(eval_fac <= spot_angle) {
|
||||||
|
eval_fac = 0.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float t = eval_fac - spot_angle;
|
||||||
|
|
||||||
|
if(t < spot_smooth && spot_smooth != 0.0f)
|
||||||
|
eval_fac *= smoothstepf(t/spot_smooth);
|
||||||
|
}
|
||||||
|
|
||||||
|
ls->Ng = I;
|
||||||
|
ls->eval_fac = eval_fac*0.25f*M_1_PI_F;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* area light */
|
/* area light */
|
||||||
@ -224,6 +257,7 @@ __device void regular_light_sample(KernelGlobals *kg, int point,
|
|||||||
|
|
||||||
ls->P += area_light_sample(axisu, axisv, randu, randv);
|
ls->P += area_light_sample(axisu, axisv, randu, randv);
|
||||||
ls->Ng = D;
|
ls->Ng = D;
|
||||||
|
ls->eval_fac = 0.25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls->t = 0.0f;
|
ls->t = 0.0f;
|
||||||
@ -262,6 +296,7 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
|
|||||||
ls->prim = prim;
|
ls->prim = prim;
|
||||||
ls->t = 0.0f;
|
ls->t = 0.0f;
|
||||||
ls->type = LIGHT_AREA;
|
ls->type = LIGHT_AREA;
|
||||||
|
ls->eval_fac = 1.0f;
|
||||||
|
|
||||||
#ifdef __INSTANCING__
|
#ifdef __INSTANCING__
|
||||||
/* instance transform */
|
/* instance transform */
|
||||||
|
@ -283,7 +283,8 @@ typedef enum LightType {
|
|||||||
LIGHT_DISTANT,
|
LIGHT_DISTANT,
|
||||||
LIGHT_BACKGROUND,
|
LIGHT_BACKGROUND,
|
||||||
LIGHT_AREA,
|
LIGHT_AREA,
|
||||||
LIGHT_AO
|
LIGHT_AO,
|
||||||
|
LIGHT_SPOT
|
||||||
} LightType;
|
} LightType;
|
||||||
|
|
||||||
/* Camera Type */
|
/* Camera Type */
|
||||||
|
@ -34,14 +34,6 @@ CCL_NAMESPACE_BEGIN
|
|||||||
|
|
||||||
/* EMISSION CLOSURE */
|
/* EMISSION CLOSURE */
|
||||||
|
|
||||||
__device float3 emissive_eval(const float3 Ng, const float3 I)
|
|
||||||
{
|
|
||||||
float cosNO = fabsf(dot(Ng, I));
|
|
||||||
float res = (cosNO > 0.0f)? 1.0f: 0.0f;
|
|
||||||
|
|
||||||
return make_float3(res, res, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the probability distribution function in the direction I,
|
/// Return the probability distribution function in the direction I,
|
||||||
/// given the parameters and the light's surface normal. This MUST match
|
/// given the parameters and the light's surface normal. This MUST match
|
||||||
/// the PDF computed by sample().
|
/// the PDF computed by sample().
|
||||||
@ -51,6 +43,13 @@ __device float emissive_pdf(const float3 Ng, const float3 I)
|
|||||||
return (cosNO > 0.0f)? 1.0f: 0.0f;
|
return (cosNO > 0.0f)? 1.0f: 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__device float3 emissive_eval(const float3 Ng, const float3 I)
|
||||||
|
{
|
||||||
|
float res = emissive_pdf(Ng, I);
|
||||||
|
|
||||||
|
return make_float3(res, res, res);
|
||||||
|
}
|
||||||
|
|
||||||
__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
|
__device float3 svm_emissive_eval(ShaderData *sd, ShaderClosure *sc)
|
||||||
{
|
{
|
||||||
return emissive_eval(sd->Ng, sd->I);
|
return emissive_eval(sd->Ng, sd->I);
|
||||||
|
@ -109,6 +109,9 @@ Light::Light()
|
|||||||
|
|
||||||
map_resolution = 512;
|
map_resolution = 512;
|
||||||
|
|
||||||
|
spot_angle = M_PI_F/4.0f;
|
||||||
|
spot_smooth = 0.0f;
|
||||||
|
|
||||||
cast_shadow = true;
|
cast_shadow = true;
|
||||||
shader = 0;
|
shader = 0;
|
||||||
}
|
}
|
||||||
@ -451,6 +454,17 @@ void LightManager::device_update_points(Device *device, DeviceScene *dscene, Sce
|
|||||||
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
|
light_data[i*LIGHT_SIZE + 2] = make_float4(0.0f, axisv.x, axisv.y, axisv.z);
|
||||||
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
|
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, dir.x, dir.y, dir.z);
|
||||||
}
|
}
|
||||||
|
else if(light->type == LIGHT_SPOT) {
|
||||||
|
shader_id &= ~SHADER_AREA_LIGHT;
|
||||||
|
|
||||||
|
float spot_angle = cosf(light->spot_angle*0.5f);
|
||||||
|
float spot_smooth = (1.0f - spot_angle)*light->spot_smooth;
|
||||||
|
|
||||||
|
light_data[i*LIGHT_SIZE + 0] = make_float4(__int_as_float(light->type), co.x, co.y, co.z);
|
||||||
|
light_data[i*LIGHT_SIZE + 1] = make_float4(__int_as_float(shader_id), light->size, dir.x, dir.y);
|
||||||
|
light_data[i*LIGHT_SIZE + 2] = make_float4(dir.z, spot_angle, spot_smooth, 0.0f);
|
||||||
|
light_data[i*LIGHT_SIZE + 3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device->tex_alloc("__light_data", dscene->light_data);
|
device->tex_alloc("__light_data", dscene->light_data);
|
||||||
|
@ -48,6 +48,9 @@ public:
|
|||||||
|
|
||||||
int map_resolution;
|
int map_resolution;
|
||||||
|
|
||||||
|
float spot_angle;
|
||||||
|
float spot_smooth;
|
||||||
|
|
||||||
bool cast_shadow;
|
bool cast_shadow;
|
||||||
|
|
||||||
int shader;
|
int shader;
|
||||||
|
@ -162,6 +162,12 @@ __device_inline float nonzerof(float f, float eps)
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__device_inline float smoothstepf(float f)
|
||||||
|
{
|
||||||
|
float ff = f*f;
|
||||||
|
return (3.0f*ff - 2.0f*ff*f);
|
||||||
|
}
|
||||||
|
|
||||||
/* Float2 Vector */
|
/* Float2 Vector */
|
||||||
|
|
||||||
#ifndef __KERNEL_OPENCL__
|
#ifndef __KERNEL_OPENCL__
|
||||||
|
Loading…
Reference in New Issue
Block a user