forked from bartvdbraak/blender
Fix T36979: wrong render of textured mesh lights with multiple importance sampling.
This commit is contained in:
parent
52bae9691b
commit
9c83ed774b
@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
|
||||
/* Direction Emission */
|
||||
|
||||
ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
LightSample *ls, float u, float v, float3 I, differential3 dI, float t, float time, int bounce)
|
||||
LightSample *ls, float3 I, differential3 dI, float t, float time, int bounce)
|
||||
{
|
||||
/* setup shading at emitter */
|
||||
ShaderData sd;
|
||||
@ -47,10 +47,10 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg, float rando,
|
||||
{
|
||||
#ifdef __HAIR__
|
||||
if(ls->type == LIGHT_STRAND)
|
||||
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ls->prim);
|
||||
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ls->prim);
|
||||
else
|
||||
#endif
|
||||
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, u, v, t, time, bounce+1, ~0);
|
||||
shader_setup_from_sample(kg, &sd, ls->P, ls->Ng, I, ls->shader, ls->object, ls->prim, ls->u, ls->v, t, time, bounce+1, ~0);
|
||||
|
||||
ls->Ng = sd.Ng;
|
||||
|
||||
@ -95,7 +95,7 @@ ccl_device_noinline bool direct_emission(KernelGlobals *kg, ShaderData *sd, int
|
||||
differential3 dD = differential3_zero();
|
||||
|
||||
/* evaluate closure */
|
||||
float3 light_eval = direct_emissive_eval(kg, rando, &ls, randu, randv, -ls.D, dD, ls.t, sd->time, bounce);
|
||||
float3 light_eval = direct_emissive_eval(kg, rando, &ls, -ls.D, dD, ls.t, sd->time, bounce);
|
||||
|
||||
if(is_zero(light_eval))
|
||||
return false;
|
||||
@ -211,10 +211,7 @@ ccl_device_noinline bool indirect_lamp_emission(KernelGlobals *kg, Ray *ray, int
|
||||
}
|
||||
#endif
|
||||
|
||||
/* todo: missing texture coordinates */
|
||||
float u = 0.0f;
|
||||
float v = 0.0f;
|
||||
float3 L = direct_emissive_eval(kg, 0.0f, &ls, u, v, -ray->D, ray->dD, ls.t, ray->time, bounce);
|
||||
float3 L = direct_emissive_eval(kg, 0.0f, &ls, -ray->D, ray->dD, ls.t, ray->time, bounce);
|
||||
|
||||
if(!(path_flag & PATH_RAY_MIS_SKIP)) {
|
||||
/* multiple importance sampling, get regular light pdf,
|
||||
|
@ -23,6 +23,7 @@ typedef struct LightSample {
|
||||
float3 Ng; /* normal on light */
|
||||
float3 D; /* direction from shading point to light */
|
||||
float t; /* distance to light (FLT_MAX for distant light) */
|
||||
float u, v; /* parametric coordinate on primitive */
|
||||
float pdf; /* light sampling probability density function */
|
||||
float eval_fac; /* intensity multiplier */
|
||||
int object; /* object id for triangle/curve lights */
|
||||
@ -219,6 +220,8 @@ ccl_device void lamp_light_sample(KernelGlobals *kg, int lamp,
|
||||
ls->object = ~0;
|
||||
ls->prim = ~0;
|
||||
ls->lamp = lamp;
|
||||
ls->u = randu;
|
||||
ls->v = randv;
|
||||
|
||||
if(type == LIGHT_DISTANT) {
|
||||
/* distant light */
|
||||
@ -309,6 +312,9 @@ ccl_device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D,
|
||||
ls->object = ~0;
|
||||
ls->prim = ~0;
|
||||
ls->lamp = lamp;
|
||||
/* todo: missing texture coordinates */
|
||||
ls->u = 0.0f;
|
||||
ls->v = 0.0f;
|
||||
|
||||
if(!(ls->shader & SHADER_USE_MIS))
|
||||
return false;
|
||||
@ -443,14 +449,24 @@ ccl_device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls
|
||||
ccl_device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
|
||||
float randu, float randv, float time, LightSample *ls)
|
||||
{
|
||||
float u, v;
|
||||
|
||||
/* compute random point in triangle */
|
||||
randu = sqrtf(randu);
|
||||
|
||||
u = 1.0f - randu;
|
||||
v = randv*randu;
|
||||
|
||||
/* triangle, so get position, normal, shader */
|
||||
ls->P = triangle_sample_MT(kg, prim, randu, randv);
|
||||
ls->P = triangle_point_MT(kg, prim, u, v);
|
||||
ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
|
||||
ls->object = object;
|
||||
ls->prim = prim;
|
||||
ls->lamp = ~0;
|
||||
ls->shader |= SHADER_USE_MIS;
|
||||
ls->t = 0.0f;
|
||||
ls->u = u;
|
||||
ls->v = v;
|
||||
ls->type = LIGHT_TRIANGLE;
|
||||
ls->eval_fac = 1.0f;
|
||||
|
||||
@ -504,6 +520,8 @@ ccl_device void curve_segment_light_sample(KernelGlobals *kg, int prim, int obje
|
||||
ls->prim = prim;
|
||||
ls->lamp = ~0;
|
||||
ls->t = 0.0f;
|
||||
ls->u = randu;
|
||||
ls->v = randv;
|
||||
ls->type = LIGHT_STRAND;
|
||||
ls->eval_fac = 1.0f;
|
||||
ls->shader = __float_as_int(v00.z) | SHADER_USE_MIS;
|
||||
|
@ -31,18 +31,6 @@ ccl_device_inline float3 triangle_point_MT(KernelGlobals *kg, int tri_index, flo
|
||||
return (u*v0 + v*v1 + t*v2);
|
||||
}
|
||||
|
||||
/* Sample point on triangle */
|
||||
ccl_device_inline float3 triangle_sample_MT(KernelGlobals *kg, int tri_index, float randu, float randv)
|
||||
{
|
||||
/* compute point */
|
||||
randu = sqrtf(randu);
|
||||
|
||||
float u = 1.0f - randu;
|
||||
float v = randv*randu;
|
||||
|
||||
return triangle_point_MT(kg, tri_index, u, v);
|
||||
}
|
||||
|
||||
/* Normal for Moller-Trumbore triangles */
|
||||
ccl_device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int *shader)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user