2011-04-27 11:58:34 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2011, Blender Foundation.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ShaderData, used in four steps:
|
|
|
|
*
|
|
|
|
* Setup from incoming ray, sampled position and background.
|
|
|
|
* Execute for surface, volume or displacement.
|
|
|
|
* Evaluate one or more closures.
|
|
|
|
* Release.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
#include "closure/bsdf_util.h"
|
2012-10-20 12:18:00 +00:00
|
|
|
#include "closure/bsdf.h"
|
|
|
|
#include "closure/emissive.h"
|
|
|
|
#include "closure/volume.h"
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#include "svm/svm.h"
|
|
|
|
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
/* ShaderData setup from incoming ray */
|
|
|
|
|
2012-10-17 22:48:29 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
|
|
|
__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
|
|
|
|
{
|
|
|
|
/* note that this is a separate non-inlined function to work around crash
|
|
|
|
* on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */
|
|
|
|
if(sd->flag & SD_OBJECT_MOTION) {
|
|
|
|
sd->ob_tfm = object_fetch_transform_motion(kg, sd->object, time);
|
|
|
|
sd->ob_itfm= transform_quick_inverse(sd->ob_tfm);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sd->ob_tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
|
|
|
|
sd->ob_itfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2013-02-11 22:41:11 +00:00
|
|
|
__device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
|
2011-04-27 11:58:34 +00:00
|
|
|
const Intersection *isect, const Ray *ray)
|
|
|
|
{
|
|
|
|
#ifdef __INSTANCING__
|
2012-04-30 12:49:26 +00:00
|
|
|
sd->object = (isect->object == ~0)? kernel_tex_fetch(__prim_object, isect->prim): isect->object;
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
2012-10-15 21:12:58 +00:00
|
|
|
|
2012-12-31 13:07:06 +00:00
|
|
|
sd->flag = kernel_tex_fetch(__object_flag, sd->object);
|
|
|
|
|
2012-04-30 12:49:26 +00:00
|
|
|
/* matrices and time */
|
2012-10-09 18:37:14 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
2012-10-17 22:48:29 +00:00
|
|
|
shader_setup_object_transforms(kg, sd, ray->time);
|
2012-04-30 12:49:26 +00:00
|
|
|
sd->time = ray->time;
|
|
|
|
#endif
|
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
|
2012-05-02 17:03:46 +00:00
|
|
|
sd->ray_length = isect->t;
|
2012-04-30 12:49:26 +00:00
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
|
2012-12-28 14:21:30 +00:00
|
|
|
/* Strand Shader setting*/
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
2012-12-28 14:21:30 +00:00
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
sd->shader = __float_as_int(curvedata.z);
|
|
|
|
sd->segment = isect->segment;
|
2012-12-28 14:21:30 +00:00
|
|
|
|
|
|
|
float tcorr = isect->t;
|
|
|
|
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION) {
|
|
|
|
tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
|
|
|
|
sd->ray_length = tcorr;
|
|
|
|
}
|
2013-01-03 12:09:09 +00:00
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#endif
|
|
|
|
/* fetch triangle data */
|
|
|
|
float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
|
|
|
|
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
|
|
|
|
sd->shader = __float_as_int(Ns.w);
|
|
|
|
|
2013-01-03 12:09:09 +00:00
|
|
|
#ifdef __HAIR__
|
|
|
|
sd->segment = ~0;
|
2013-04-15 21:38:31 +00:00
|
|
|
/*elements for minimum hair width using transparency bsdf*/
|
|
|
|
/*sd->curve_transparency = 0.0f;*/
|
|
|
|
/*sd->curve_radius = 0.0f;*/
|
2013-01-03 12:09:09 +00:00
|
|
|
#endif
|
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __UV__
|
|
|
|
sd->u = isect->u;
|
|
|
|
sd->v = isect->v;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* vectors */
|
|
|
|
sd->P = bvh_triangle_refine(kg, sd, isect, ray);
|
|
|
|
sd->Ng = Ng;
|
|
|
|
sd->N = Ng;
|
|
|
|
|
|
|
|
/* smooth normal */
|
|
|
|
if(sd->shader & SHADER_SMOOTH_NORMAL)
|
|
|
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
2011-09-27 20:37:24 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef __DPDU__
|
2012-12-28 14:21:30 +00:00
|
|
|
/* dPdu/dPdv */
|
|
|
|
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
sd->I = -ray->D;
|
|
|
|
|
2012-12-31 13:07:06 +00:00
|
|
|
sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
|
2012-12-28 14:21:30 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef __INSTANCING__
|
2012-04-30 12:49:26 +00:00
|
|
|
if(isect->object != ~0) {
|
2011-04-27 11:58:34 +00:00
|
|
|
/* instance transform */
|
2012-04-30 12:49:26 +00:00
|
|
|
object_normal_transform(kg, sd, &sd->N);
|
|
|
|
object_normal_transform(kg, sd, &sd->Ng);
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef __DPDU__
|
2012-04-30 12:49:26 +00:00
|
|
|
object_dir_transform(kg, sd, &sd->dPdu);
|
|
|
|
object_dir_transform(kg, sd, &sd->dPdv);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* backfacing test */
|
|
|
|
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
|
|
|
|
|
|
|
|
if(backfacing) {
|
2011-09-27 20:37:24 +00:00
|
|
|
sd->flag |= SD_BACKFACING;
|
2011-04-27 11:58:34 +00:00
|
|
|
sd->Ng = -sd->Ng;
|
|
|
|
sd->N = -sd->N;
|
|
|
|
#ifdef __DPDU__
|
|
|
|
sd->dPdu = -sd->dPdu;
|
|
|
|
sd->dPdv = -sd->dPdv;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
/* differentials */
|
|
|
|
differential_transfer(&sd->dP, ray->dP, ray->D, ray->dD, sd->Ng, isect->t);
|
|
|
|
differential_incoming(&sd->dI, ray->dD);
|
|
|
|
differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2013-04-01 20:26:52 +00:00
|
|
|
/* ShaderData setup from BSSRDF scatter */
|
|
|
|
|
|
|
|
#ifdef __SUBSURFACE__
|
|
|
|
__device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData *sd,
|
|
|
|
const Intersection *isect, const Ray *ray)
|
|
|
|
{
|
|
|
|
bool backfacing = sd->flag & SD_BACKFACING;
|
|
|
|
|
|
|
|
/* object, matrices, time, ray_length stay the same */
|
|
|
|
sd->flag = kernel_tex_fetch(__object_flag, sd->object);
|
|
|
|
sd->prim = kernel_tex_fetch(__prim_index, isect->prim);
|
|
|
|
|
|
|
|
#ifdef __HAIR__
|
|
|
|
if(kernel_tex_fetch(__prim_segment, isect->prim) != ~0) {
|
|
|
|
/* Strand Shader setting*/
|
|
|
|
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
|
|
|
|
|
|
|
sd->shader = __float_as_int(curvedata.z);
|
|
|
|
sd->segment = isect->segment;
|
|
|
|
|
|
|
|
float tcorr = isect->t;
|
|
|
|
if(kernel_data.curve_kernel_data.curveflags & CURVE_KN_POSTINTERSECTCORRECTION)
|
|
|
|
tcorr = (isect->u < 0)? tcorr + sqrtf(isect->v) : tcorr - sqrtf(isect->v);
|
|
|
|
|
|
|
|
sd->P = bvh_curve_refine(kg, sd, isect, ray, tcorr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
#endif
|
|
|
|
/* fetch triangle data */
|
|
|
|
float4 Ns = kernel_tex_fetch(__tri_normal, sd->prim);
|
|
|
|
float3 Ng = make_float3(Ns.x, Ns.y, Ns.z);
|
|
|
|
sd->shader = __float_as_int(Ns.w);
|
|
|
|
|
|
|
|
#ifdef __HAIR__
|
|
|
|
sd->segment = ~0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __UV__
|
|
|
|
sd->u = isect->u;
|
|
|
|
sd->v = isect->v;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* vectors */
|
|
|
|
sd->P = bvh_triangle_refine(kg, sd, isect, ray);
|
|
|
|
sd->Ng = Ng;
|
|
|
|
sd->N = Ng;
|
|
|
|
|
|
|
|
/* smooth normal */
|
|
|
|
if(sd->shader & SHADER_SMOOTH_NORMAL)
|
|
|
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
|
|
|
|
|
|
|
#ifdef __DPDU__
|
|
|
|
/* dPdu/dPdv */
|
|
|
|
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __HAIR__
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
sd->flag |= kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
|
|
|
|
|
|
|
|
#ifdef __INSTANCING__
|
|
|
|
if(isect->object != ~0) {
|
|
|
|
/* instance transform */
|
|
|
|
object_normal_transform(kg, sd, &sd->N);
|
|
|
|
object_normal_transform(kg, sd, &sd->Ng);
|
|
|
|
#ifdef __DPDU__
|
|
|
|
object_dir_transform(kg, sd, &sd->dPdu);
|
|
|
|
object_dir_transform(kg, sd, &sd->dPdv);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* backfacing test */
|
|
|
|
if(backfacing) {
|
|
|
|
sd->flag |= SD_BACKFACING;
|
|
|
|
sd->Ng = -sd->Ng;
|
|
|
|
sd->N = -sd->N;
|
|
|
|
#ifdef __DPDU__
|
|
|
|
sd->dPdu = -sd->dPdu;
|
|
|
|
sd->dPdv = -sd->dPdv;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* should not get used in principle as the shading will only use a diffuse
|
|
|
|
* BSDF, but the shader might still access it */
|
|
|
|
sd->I = sd->N;
|
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
/* differentials */
|
|
|
|
differential_dudv(&sd->du, &sd->dv, sd->dPdu, sd->dPdv, sd->dP, sd->Ng);
|
|
|
|
/* don't modify dP and dI */
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* ShaderData setup from position sampled on mesh */
|
|
|
|
|
2013-02-11 22:41:11 +00:00
|
|
|
__device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
|
2011-04-27 11:58:34 +00:00
|
|
|
const float3 P, const float3 Ng, const float3 I,
|
2013-05-09 14:05:40 +00:00
|
|
|
int shader, int object, int prim, float u, float v, float t, float time, int segment)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* vectors */
|
|
|
|
sd->P = P;
|
|
|
|
sd->N = Ng;
|
|
|
|
sd->Ng = Ng;
|
|
|
|
sd->I = I;
|
|
|
|
sd->shader = shader;
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
sd->segment = segment;
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
/* primitive */
|
|
|
|
#ifdef __INSTANCING__
|
|
|
|
sd->object = object;
|
|
|
|
#endif
|
2012-12-28 14:21:30 +00:00
|
|
|
/* currently no access to bvh prim index for strand sd->prim - this will cause errors with needs fixing*/
|
2011-04-27 11:58:34 +00:00
|
|
|
sd->prim = prim;
|
|
|
|
#ifdef __UV__
|
|
|
|
sd->u = u;
|
|
|
|
sd->v = v;
|
|
|
|
#endif
|
2012-05-02 17:03:46 +00:00
|
|
|
sd->ray_length = t;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
/* detect instancing, for non-instanced the object index is -object-1 */
|
2011-08-10 14:26:51 +00:00
|
|
|
#ifdef __INSTANCING__
|
2011-04-27 11:58:34 +00:00
|
|
|
bool instanced = false;
|
|
|
|
|
|
|
|
if(sd->prim != ~0) {
|
|
|
|
if(sd->object >= 0)
|
|
|
|
instanced = true;
|
|
|
|
else
|
2011-08-10 14:26:51 +00:00
|
|
|
#endif
|
2012-01-18 22:36:12 +00:00
|
|
|
sd->object = ~sd->object;
|
2011-08-10 14:26:51 +00:00
|
|
|
#ifdef __INSTANCING__
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-08-10 14:26:51 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2012-10-15 21:12:58 +00:00
|
|
|
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
|
2012-10-16 13:20:57 +00:00
|
|
|
if(sd->object != -1) {
|
2012-10-15 21:12:58 +00:00
|
|
|
sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
|
|
|
|
|
2012-10-09 18:37:14 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
2012-10-17 22:48:29 +00:00
|
|
|
shader_setup_object_transforms(kg, sd, time);
|
2012-10-15 21:12:58 +00:00
|
|
|
}
|
2012-04-30 12:49:26 +00:00
|
|
|
|
2012-10-15 21:12:58 +00:00
|
|
|
sd->time = time;
|
2012-10-16 13:20:57 +00:00
|
|
|
#else
|
|
|
|
}
|
2012-04-30 12:49:26 +00:00
|
|
|
#endif
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* smooth normal */
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
if(sd->shader & SHADER_SMOOTH_NORMAL && sd->segment == ~0) {
|
2012-12-28 14:21:30 +00:00
|
|
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
|
|
|
#else
|
2011-09-27 20:37:24 +00:00
|
|
|
if(sd->shader & SHADER_SMOOTH_NORMAL) {
|
2011-04-27 11:58:34 +00:00
|
|
|
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
#ifdef __INSTANCING__
|
|
|
|
if(instanced)
|
2012-04-30 12:49:26 +00:00
|
|
|
object_normal_transform(kg, sd, &sd->N);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __DPDU__
|
|
|
|
/* dPdu/dPdv */
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
if(sd->prim == ~0 || sd->segment != ~0) {
|
2012-12-28 14:21:30 +00:00
|
|
|
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
|
|
|
#else
|
2011-04-27 11:58:34 +00:00
|
|
|
if(sd->prim == ~0) {
|
|
|
|
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
}
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
else {
|
|
|
|
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
|
|
|
|
|
|
|
|
#ifdef __INSTANCING__
|
|
|
|
if(instanced) {
|
2012-04-30 12:49:26 +00:00
|
|
|
object_dir_transform(kg, sd, &sd->dPdu);
|
|
|
|
object_dir_transform(kg, sd, &sd->dPdv);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* backfacing test */
|
|
|
|
if(sd->prim != ~0) {
|
|
|
|
bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);
|
|
|
|
|
|
|
|
if(backfacing) {
|
2011-09-27 20:37:24 +00:00
|
|
|
sd->flag |= SD_BACKFACING;
|
2011-04-27 11:58:34 +00:00
|
|
|
sd->Ng = -sd->Ng;
|
|
|
|
sd->N = -sd->N;
|
|
|
|
#ifdef __DPDU__
|
|
|
|
sd->dPdu = -sd->dPdu;
|
|
|
|
sd->dPdv = -sd->dPdv;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
/* no ray differentials here yet */
|
2013-05-03 21:34:51 +00:00
|
|
|
sd->dP = differential3_zero();
|
|
|
|
sd->dI = differential3_zero();
|
|
|
|
sd->du = differential_zero();
|
|
|
|
sd->dv = differential_zero();
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ShaderData setup for displacement */
|
|
|
|
|
2013-04-01 20:26:52 +00:00
|
|
|
__device void shader_setup_from_displace(KernelGlobals *kg, ShaderData *sd,
|
2011-04-27 11:58:34 +00:00
|
|
|
int object, int prim, float u, float v)
|
|
|
|
{
|
|
|
|
float3 P, Ng, I = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
int shader;
|
|
|
|
|
|
|
|
P = triangle_point_MT(kg, prim, u, v);
|
|
|
|
Ng = triangle_normal_MT(kg, prim, &shader);
|
|
|
|
|
|
|
|
/* force smooth shading for displacement */
|
2011-11-22 13:15:19 +00:00
|
|
|
shader |= SHADER_SMOOTH_NORMAL;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
/* watch out: no instance transform currently */
|
|
|
|
|
2013-05-09 14:05:40 +00:00
|
|
|
shader_setup_from_sample(kg, sd, P, Ng, I, shader, object, prim, u, v, 0.0f, TIME_INVALID, ~0);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ShaderData setup from ray into background */
|
|
|
|
|
|
|
|
__device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData *sd, const Ray *ray)
|
|
|
|
{
|
|
|
|
/* vectors */
|
|
|
|
sd->P = ray->D;
|
|
|
|
sd->N = -sd->P;
|
|
|
|
sd->Ng = -sd->P;
|
|
|
|
sd->I = -sd->P;
|
|
|
|
sd->shader = kernel_data.background.shader;
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
|
2012-10-09 18:37:14 +00:00
|
|
|
#ifdef __OBJECT_MOTION__
|
2012-04-30 12:49:26 +00:00
|
|
|
sd->time = ray->time;
|
|
|
|
#endif
|
2012-05-02 17:03:46 +00:00
|
|
|
sd->ray_length = 0.0f;
|
2011-04-27 11:58:34 +00:00
|
|
|
|
|
|
|
#ifdef __INSTANCING__
|
|
|
|
sd->object = ~0;
|
|
|
|
#endif
|
|
|
|
sd->prim = ~0;
|
2012-12-28 14:21:30 +00:00
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
sd->segment = ~0;
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef __UV__
|
|
|
|
sd->u = 0.0f;
|
|
|
|
sd->v = 0.0f;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __DPDU__
|
|
|
|
/* dPdu/dPdv */
|
|
|
|
sd->dPdu = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
sd->dPdv = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef __RAY_DIFFERENTIALS__
|
|
|
|
/* differentials */
|
|
|
|
sd->dP = ray->dD;
|
|
|
|
differential_incoming(&sd->dI, sd->dP);
|
2013-05-03 21:34:51 +00:00
|
|
|
sd->du = differential_zero();
|
|
|
|
sd->dv = differential_zero();
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BSDF */
|
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
__device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, const ShaderData *sd, const float3 omega_in, float *pdf,
|
|
|
|
int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
|
2012-09-03 13:56:40 +00:00
|
|
|
{
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
if(i == skip_bsdf)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF(sc->type)) {
|
|
|
|
float bsdf_pdf = 0.0f;
|
2012-12-15 10:18:42 +00:00
|
|
|
float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
|
2012-09-03 13:56:40 +00:00
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
if(bsdf_pdf != 0.0f) {
|
2012-12-15 10:18:42 +00:00
|
|
|
bsdf_eval_accum(result_eval, sc->type, eval*sc->weight);
|
2011-09-12 13:13:56 +00:00
|
|
|
sum_pdf += bsdf_pdf*sc->sample_weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
sum_sample_weight += sc->sample_weight;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-31 15:59:30 +00:00
|
|
|
*pdf = (sum_sample_weight > 0.0f)? sum_pdf/sum_sample_weight: 0.0f;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
|
|
|
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
__device void shader_bsdf_eval(KernelGlobals *kg, const ShaderData *sd,
|
|
|
|
const float3 omega_in, BsdfEval *eval, float *pdf)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
bsdf_eval_init(eval, NBUILTIN_CLOSURES, make_float3(0.0f, 0.0f, 0.0f), kernel_data.film.use_light_pass);
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
return _shader_bsdf_multi_eval(kg, sd, omega_in, pdf, -1, eval, 0.0f, 0.0f);
|
2011-09-12 13:13:56 +00:00
|
|
|
#else
|
|
|
|
const ShaderClosure *sc = &sd->closure;
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
*pdf = 0.0f;
|
2012-12-15 10:18:42 +00:00
|
|
|
*eval = bsdf_eval(kg, sd, sc, omega_in, pdf)*sc->weight;
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
__device int shader_bsdf_sample(KernelGlobals *kg, const ShaderData *sd,
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
float randu, float randv, BsdfEval *bsdf_eval,
|
2011-09-12 13:13:56 +00:00
|
|
|
float3 *omega_in, differential3 *domega_in, float *pdf)
|
|
|
|
{
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
int sampled = 0;
|
|
|
|
|
|
|
|
if(sd->num_closure > 1) {
|
|
|
|
/* pick a BSDF closure based on sample weights */
|
|
|
|
float sum = 0.0f;
|
|
|
|
|
|
|
|
for(sampled = 0; sampled < sd->num_closure; sampled++) {
|
|
|
|
const ShaderClosure *sc = &sd->closure[sampled];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF(sc->type))
|
|
|
|
sum += sc->sample_weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
float r = sd->randb_closure*sum;
|
|
|
|
sum = 0.0f;
|
|
|
|
|
|
|
|
for(sampled = 0; sampled < sd->num_closure; sampled++) {
|
|
|
|
const ShaderClosure *sc = &sd->closure[sampled];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF(sc->type)) {
|
2013-04-01 20:26:52 +00:00
|
|
|
sum += sc->sample_weight;
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
if(r <= sum)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(sampled == sd->num_closure) {
|
|
|
|
*pdf = 0.0f;
|
|
|
|
return LABEL_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const ShaderClosure *sc = &sd->closure[sampled];
|
|
|
|
int label;
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
float3 eval;
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
*pdf = 0.0f;
|
2012-12-15 10:18:42 +00:00
|
|
|
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
2012-09-03 13:56:40 +00:00
|
|
|
|
2012-02-07 17:32:01 +00:00
|
|
|
if(*pdf != 0.0f) {
|
|
|
|
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
|
2011-04-27 11:58:34 +00:00
|
|
|
|
2012-02-07 17:32:01 +00:00
|
|
|
if(sd->num_closure > 1) {
|
|
|
|
float sweight = sc->sample_weight;
|
2012-12-15 10:18:42 +00:00
|
|
|
_shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
|
2012-02-07 17:32:01 +00:00
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return label;
|
|
|
|
#else
|
|
|
|
/* sample the single closure that we picked */
|
|
|
|
*pdf = 0.0f;
|
2012-12-15 10:18:42 +00:00
|
|
|
int label = bsdf_sample(kg, sd, &sd->closure, randu, randv, bsdf_eval, omega_in, domega_in, pdf);
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
*bsdf_eval *= sd->closure.weight;
|
2011-09-12 13:13:56 +00:00
|
|
|
return label;
|
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2012-06-13 11:44:48 +00:00
|
|
|
__device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
|
|
|
|
const ShaderClosure *sc, float randu, float randv, BsdfEval *bsdf_eval,
|
|
|
|
float3 *omega_in, differential3 *domega_in, float *pdf)
|
|
|
|
{
|
|
|
|
int label;
|
|
|
|
float3 eval;
|
|
|
|
|
|
|
|
*pdf = 0.0f;
|
2012-12-15 10:18:42 +00:00
|
|
|
label = bsdf_sample(kg, sd, sc, randu, randv, &eval, omega_in, domega_in, pdf);
|
2012-09-03 13:56:40 +00:00
|
|
|
|
2012-06-13 11:44:48 +00:00
|
|
|
if(*pdf != 0.0f)
|
|
|
|
bsdf_eval_init(bsdf_eval, sc->type, eval*sc->weight, kernel_data.film.use_light_pass);
|
|
|
|
|
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
__device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
|
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
if(CLOSURE_IS_BSDF(sc->type))
|
|
|
|
bsdf_blur(kg, sc, roughness);
|
2011-09-12 13:13:56 +00:00
|
|
|
}
|
|
|
|
#else
|
2012-12-15 10:18:42 +00:00
|
|
|
bsdf_blur(kg, &sd->closure, roughness);
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
__device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
|
2011-09-12 13:13:56 +00:00
|
|
|
eval += sc->weight;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
return eval;
|
|
|
|
#else
|
|
|
|
if(sd->closure.type == CLOSURE_BSDF_TRANSPARENT_ID)
|
|
|
|
return sd->closure.weight;
|
2011-04-27 11:58:34 +00:00
|
|
|
else
|
2011-09-12 13:13:56 +00:00
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
__device float3 shader_bsdf_diffuse(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
|
|
|
|
eval += sc->weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eval;
|
|
|
|
#else
|
|
|
|
if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
|
|
|
|
return sd->closure.weight;
|
|
|
|
else
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
__device float3 shader_bsdf_glossy(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
|
|
|
|
eval += sc->weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eval;
|
|
|
|
#else
|
|
|
|
if(CLOSURE_IS_BSDF_GLOSSY(sd->closure.type))
|
|
|
|
return sd->closure.weight;
|
|
|
|
else
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
__device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_BSDF_TRANSMISSION(sc->type))
|
|
|
|
eval += sc->weight;
|
|
|
|
}
|
|
|
|
|
|
|
|
return eval;
|
|
|
|
#else
|
|
|
|
if(CLOSURE_IS_BSDF_TRANSMISSION(sd->closure.type))
|
|
|
|
return sd->closure.weight;
|
|
|
|
else
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2012-11-15 15:37:58 +00:00
|
|
|
__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd, float ao_factor, float3 *N)
|
2012-11-06 19:59:02 +00:00
|
|
|
{
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
2012-11-15 15:37:58 +00:00
|
|
|
*N = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
2012-11-06 19:59:02 +00:00
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
2012-11-15 15:37:58 +00:00
|
|
|
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
|
|
|
|
eval += sc->weight*ao_factor;
|
|
|
|
*N += sc->N*average(sc->weight);
|
|
|
|
}
|
|
|
|
if(CLOSURE_IS_AMBIENT_OCCLUSION(sc->type)) {
|
2012-11-06 19:59:02 +00:00
|
|
|
eval += sc->weight;
|
2012-11-15 15:37:58 +00:00
|
|
|
*N += sd->N*average(sc->weight);
|
|
|
|
}
|
2012-11-06 19:59:02 +00:00
|
|
|
}
|
|
|
|
|
2012-11-23 13:41:25 +00:00
|
|
|
if(is_zero(*N))
|
|
|
|
*N = sd->N;
|
|
|
|
else
|
|
|
|
*N = normalize(*N);
|
2012-11-15 15:37:58 +00:00
|
|
|
|
2012-11-06 19:59:02 +00:00
|
|
|
return eval;
|
|
|
|
#else
|
2012-11-15 15:37:58 +00:00
|
|
|
*N = sd->N;
|
|
|
|
|
2012-11-15 15:59:58 +00:00
|
|
|
if(CLOSURE_IS_BSDF_DIFFUSE(sd->closure.type))
|
2012-11-15 15:37:58 +00:00
|
|
|
return sd->closure.weight*ao_factor;
|
|
|
|
else if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
|
2012-11-06 19:59:02 +00:00
|
|
|
return sd->closure.weight;
|
|
|
|
else
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
/* Emission */
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
__device float3 emissive_eval(KernelGlobals *kg, ShaderData *sd, ShaderClosure *sc)
|
|
|
|
{
|
|
|
|
#ifdef __OSL__
|
|
|
|
if(kg->osl && sc->prim)
|
|
|
|
return OSLShader::emissive_eval(sd, sc);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return emissive_simple_eval(sd->Ng, sd->I);
|
|
|
|
}
|
|
|
|
|
2011-09-12 13:13:56 +00:00
|
|
|
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2011-09-27 20:37:24 +00:00
|
|
|
float3 eval;
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
2011-09-27 20:37:24 +00:00
|
|
|
eval = make_float3(0.0f, 0.0f, 0.0f);
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
for(int i = 0; i < sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
if(CLOSURE_IS_EMISSION(sc->type))
|
|
|
|
eval += emissive_eval(kg, sd, sc)*sc->weight;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
#else
|
2012-12-15 10:18:42 +00:00
|
|
|
eval = emissive_eval(kg, sd, &sd->closure)*sd->closure.weight;
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2011-09-27 20:37:24 +00:00
|
|
|
|
|
|
|
return eval;
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
2011-08-28 13:55:59 +00:00
|
|
|
/* Holdout */
|
|
|
|
|
|
|
|
__device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 weight = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i < sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
|
|
|
if(CLOSURE_IS_HOLDOUT(sc->type))
|
|
|
|
weight += sc->weight;
|
2011-08-28 13:55:59 +00:00
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
return weight;
|
|
|
|
#else
|
|
|
|
if(sd->closure.type == CLOSURE_HOLDOUT_ID)
|
|
|
|
return make_float3(1.0f, 1.0f, 1.0f);
|
|
|
|
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
2011-08-28 13:55:59 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
/* Surface Evaluation */
|
|
|
|
|
|
|
|
__device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
|
2012-12-15 10:18:42 +00:00
|
|
|
float randb, int path_flag, ShaderContext ctx)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __OSL__
|
2012-12-01 19:15:05 +00:00
|
|
|
if (kg->osl)
|
2012-12-15 10:18:42 +00:00
|
|
|
OSLShader::eval_surface(kg, sd, randb, path_flag, ctx);
|
2012-09-03 13:56:40 +00:00
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
2011-04-27 11:58:34 +00:00
|
|
|
#ifdef __SVM__
|
2012-09-03 13:56:40 +00:00
|
|
|
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, randb, path_flag);
|
2011-04-27 11:58:34 +00:00
|
|
|
#else
|
2012-09-03 13:56:40 +00:00
|
|
|
sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
|
2013-05-09 14:05:40 +00:00
|
|
|
sd->closure.N = sd->N;
|
|
|
|
sd->flag |= bsdf_diffuse_setup(&sd->closure);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
2012-09-03 13:56:40 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Background Evaluation */
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
__device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd, int path_flag, ShaderContext ctx)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __OSL__
|
2012-12-01 19:15:05 +00:00
|
|
|
if (kg->osl)
|
2012-12-15 10:18:42 +00:00
|
|
|
return OSLShader::eval_background(kg, sd, path_flag, ctx);
|
2012-09-03 13:56:40 +00:00
|
|
|
else
|
|
|
|
#endif
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2012-09-03 13:56:40 +00:00
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __SVM__
|
2012-09-03 13:56:40 +00:00
|
|
|
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, 0.0f, path_flag);
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
#ifdef __MULTI_CLOSURE__
|
2012-09-03 13:56:40 +00:00
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2012-09-03 13:56:40 +00:00
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
const ShaderClosure *sc = &sd->closure[i];
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2012-09-03 13:56:40 +00:00
|
|
|
if(CLOSURE_IS_BACKGROUND(sc->type))
|
|
|
|
eval += sc->weight;
|
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2012-09-03 13:56:40 +00:00
|
|
|
return eval;
|
2011-09-12 13:13:56 +00:00
|
|
|
#else
|
2012-09-03 13:56:40 +00:00
|
|
|
if(sd->closure.type == CLOSURE_BACKGROUND_ID)
|
|
|
|
return sd->closure.weight;
|
|
|
|
else
|
|
|
|
return make_float3(0.0f, 0.0f, 0.0f);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
2011-09-12 13:13:56 +00:00
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
#else
|
2012-09-03 13:56:40 +00:00
|
|
|
return make_float3(0.8f, 0.8f, 0.8f);
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2012-09-03 13:56:40 +00:00
|
|
|
}
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Volume */
|
|
|
|
|
|
|
|
__device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
|
|
|
|
float3 omega_in, float3 omega_out)
|
|
|
|
{
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __MULTI_CLOSURE__
|
|
|
|
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
for(int i = 0; i< sd->num_closure; i++) {
|
|
|
|
const ShaderClosure *sc = &sd->closure[i];
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
if(CLOSURE_IS_VOLUME(sc->type))
|
|
|
|
eval += volume_eval_phase(kg, sc, omega_in, omega_out);
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
2011-09-12 13:13:56 +00:00
|
|
|
|
|
|
|
return eval;
|
|
|
|
#else
|
2012-12-15 10:18:42 +00:00
|
|
|
return volume_eval_phase(kg, &sd->closure, omega_in, omega_out);
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2011-04-27 11:58:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Volume Evaluation */
|
|
|
|
|
|
|
|
__device void shader_eval_volume(KernelGlobals *kg, ShaderData *sd,
|
2012-12-15 10:18:42 +00:00
|
|
|
float randb, int path_flag, ShaderContext ctx)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
#ifdef __SVM__
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __OSL__
|
2012-12-01 19:15:05 +00:00
|
|
|
if (kg->osl)
|
2012-12-15 10:18:42 +00:00
|
|
|
OSLShader::eval_volume(kg, sd, randb, path_flag, ctx);
|
2012-09-03 13:56:40 +00:00
|
|
|
else
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2012-09-03 13:56:40 +00:00
|
|
|
svm_eval_nodes(kg, sd, SHADER_TYPE_VOLUME, randb, path_flag);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Displacement Evaluation */
|
|
|
|
|
2012-12-15 10:18:42 +00:00
|
|
|
__device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ShaderContext ctx)
|
2011-04-27 11:58:34 +00:00
|
|
|
{
|
|
|
|
/* this will modify sd->P */
|
|
|
|
#ifdef __SVM__
|
2011-09-12 13:13:56 +00:00
|
|
|
#ifdef __OSL__
|
2012-12-01 19:15:05 +00:00
|
|
|
if (kg->osl)
|
2012-12-15 10:18:42 +00:00
|
|
|
OSLShader::eval_displacement(kg, sd, ctx);
|
2012-09-03 13:56:40 +00:00
|
|
|
else
|
2011-09-12 13:13:56 +00:00
|
|
|
#endif
|
2012-09-03 13:56:40 +00:00
|
|
|
svm_eval_nodes(kg, sd, SHADER_TYPE_DISPLACEMENT, 0.0f, 0);
|
2011-04-27 11:58:34 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-09-27 20:37:24 +00:00
|
|
|
/* Transparent Shadows */
|
|
|
|
|
|
|
|
#ifdef __TRANSPARENT_SHADOWS__
|
|
|
|
__device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect)
|
|
|
|
{
|
|
|
|
int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
2012-12-28 14:21:30 +00:00
|
|
|
int shader = 0;
|
|
|
|
|
|
|
|
#ifdef __HAIR__
|
2013-01-03 12:09:09 +00:00
|
|
|
if(kernel_tex_fetch(__prim_segment, isect->prim) == ~0) {
|
2012-12-28 14:21:30 +00:00
|
|
|
#endif
|
|
|
|
float4 Ns = kernel_tex_fetch(__tri_normal, prim);
|
|
|
|
shader = __float_as_int(Ns.w);
|
|
|
|
#ifdef __HAIR__
|
|
|
|
}
|
|
|
|
else {
|
2013-01-03 12:09:09 +00:00
|
|
|
float4 str = kernel_tex_fetch(__curves, prim);
|
2012-12-28 14:21:30 +00:00
|
|
|
shader = __float_as_int(str.z);
|
|
|
|
}
|
|
|
|
#endif
|
Cycles: Render Passes
Currently supported passes:
* Combined, Z, Normal, Object Index, Material Index, Emission, Environment,
Diffuse/Glossy/Transmission x Direct/Indirect/Color
Not supported yet:
* UV, Vector, Mist
Only enabled for CPU devices at the moment, will do GPU tweaks tommorrow,
also for environment importance sampling.
Documentation:
http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Passes
2012-01-25 17:23:52 +00:00
|
|
|
int flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
|
2011-09-27 20:37:24 +00:00
|
|
|
|
|
|
|
return (flag & SD_HAS_SURFACE_TRANSPARENT) != 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2012-06-13 11:44:48 +00:00
|
|
|
/* Merging */
|
|
|
|
|
|
|
|
#ifdef __NON_PROGRESSIVE__
|
|
|
|
__device void shader_merge_closures(KernelGlobals *kg, ShaderData *sd)
|
|
|
|
{
|
|
|
|
/* merge identical closures, better when we sample a single closure at a time */
|
|
|
|
for(int i = 0; i < sd->num_closure; i++) {
|
|
|
|
ShaderClosure *sci = &sd->closure[i];
|
|
|
|
|
|
|
|
for(int j = i + 1; j < sd->num_closure; j++) {
|
|
|
|
ShaderClosure *scj = &sd->closure[j];
|
|
|
|
|
2012-12-15 20:43:25 +00:00
|
|
|
#ifdef __OSL__
|
2013-04-02 15:53:24 +00:00
|
|
|
if(!sci->prim && !scj->prim && sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
|
2012-12-15 20:43:25 +00:00
|
|
|
#else
|
|
|
|
if(sci->type == scj->type && sci->data0 == scj->data0 && sci->data1 == scj->data1) {
|
|
|
|
#endif
|
2012-06-13 11:44:48 +00:00
|
|
|
sci->weight += scj->weight;
|
|
|
|
sci->sample_weight += scj->sample_weight;
|
|
|
|
|
|
|
|
int size = sd->num_closure - (j+1);
|
|
|
|
if(size > 0)
|
|
|
|
memmove(scj, scj+1, size*sizeof(ShaderClosure));
|
|
|
|
|
|
|
|
sd->num_closure--;
|
2013-04-02 15:53:24 +00:00
|
|
|
j--;
|
2012-06-13 11:44:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-04-27 11:58:34 +00:00
|
|
|
CCL_NAMESPACE_END
|
|
|
|
|