Merge branch 'blender-v4.4-release'
This commit is contained in:
@@ -43,13 +43,13 @@ ccl_device_inline T curve_attribute_dfdy(const ccl_private differential &du,
|
||||
return du.dy * (f1 - f0);
|
||||
}
|
||||
|
||||
/* Reading attributes on various curve elements */
|
||||
/* Read attributes on various curve elements, and compute the partial derivatives if requested. */
|
||||
|
||||
ccl_device float curve_attribute_float(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
ccl_private float *dfdx,
|
||||
ccl_private float *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
|
||||
const KernelCurve curve = kernel_data_fetch(curves, sd->prim);
|
||||
@@ -60,22 +60,22 @@ ccl_device float curve_attribute_float(KernelGlobals kg,
|
||||
const float f1 = kernel_data_fetch(attributes_float, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
if (dfdx) {
|
||||
*dfdx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
if (dfdy) {
|
||||
*dfdy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
}
|
||||
# endif
|
||||
|
||||
return (1.0f - sd->u) * f0 + sd->u * f1;
|
||||
}
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -89,8 +89,8 @@ ccl_device float curve_attribute_float(KernelGlobals kg,
|
||||
ccl_device float2 curve_attribute_float2(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
ccl_private float2 *dfdx,
|
||||
ccl_private float2 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
|
||||
const KernelCurve curve = kernel_data_fetch(curves, sd->prim);
|
||||
@@ -101,11 +101,11 @@ ccl_device float2 curve_attribute_float2(KernelGlobals kg,
|
||||
const float2 f1 = kernel_data_fetch(attributes_float2, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
if (dfdx) {
|
||||
*dfdx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
if (dfdy) {
|
||||
*dfdy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -117,11 +117,11 @@ ccl_device float2 curve_attribute_float2(KernelGlobals kg,
|
||||
* detail level always. maybe a derivative based on the hair density
|
||||
* could be computed somehow? */
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float2();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float2();
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -129,14 +129,14 @@ ccl_device float2 curve_attribute_float2(KernelGlobals kg,
|
||||
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : desc.offset;
|
||||
return kernel_data_fetch(attributes_float2, offset);
|
||||
}
|
||||
return make_float2(0.0f, 0.0f);
|
||||
return zero_float2();
|
||||
}
|
||||
|
||||
ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
ccl_private float3 *dfdx,
|
||||
ccl_private float3 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
|
||||
const KernelCurve curve = kernel_data_fetch(curves, sd->prim);
|
||||
@@ -147,11 +147,11 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
const float3 f1 = kernel_data_fetch(attributes_float3, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
if (dfdx) {
|
||||
*dfdx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
if (dfdy) {
|
||||
*dfdy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -159,11 +159,11 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
}
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -171,14 +171,14 @@ ccl_device float3 curve_attribute_float3(KernelGlobals kg,
|
||||
const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : desc.offset;
|
||||
return kernel_data_fetch(attributes_float3, offset);
|
||||
}
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
return zero_float3();
|
||||
}
|
||||
|
||||
ccl_device float4 curve_attribute_float4(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
ccl_private float4 *dfdx,
|
||||
ccl_private float4 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) {
|
||||
const KernelCurve curve = kernel_data_fetch(curves, sd->prim);
|
||||
@@ -189,11 +189,11 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
|
||||
const float4 f1 = kernel_data_fetch(attributes_float4, desc.offset + k1);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
if (dfdx) {
|
||||
*dfdx = curve_attribute_dfdx(sd->du, f0, f1);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
if (dfdy) {
|
||||
*dfdy = curve_attribute_dfdy(sd->du, f0, f1);
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -201,11 +201,11 @@ ccl_device float4 curve_attribute_float4(KernelGlobals kg,
|
||||
}
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
@@ -32,31 +32,31 @@ CCL_NAMESPACE_BEGIN
|
||||
ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
ccl_private float *dfdx,
|
||||
ccl_private float *dfdy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
return triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
return triangle_attribute_float(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
return subd_triangle_attribute_float(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float(kg, sd, desc, dx, dy);
|
||||
return curve_attribute_float(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float(kg, sd, desc, dx, dy);
|
||||
return point_attribute_float(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
@@ -65,97 +65,97 @@ ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
|
||||
ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
ccl_private float2 *dfdx,
|
||||
ccl_private float2 *dfdy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
return triangle_attribute_float2(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
return curve_attribute_float2(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float2(kg, sd, desc, dx, dy);
|
||||
return point_attribute_float2(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float2();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float2();
|
||||
}
|
||||
return make_float2(0.0f, 0.0f);
|
||||
return zero_float2();
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
ccl_private float3 *dfdx,
|
||||
ccl_private float3 *dfdy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
return triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
return triangle_attribute_float3(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
return subd_triangle_attribute_float3(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float3(kg, sd, desc, dx, dy);
|
||||
return curve_attribute_float3(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float3(kg, sd, desc, dx, dy);
|
||||
return point_attribute_float3(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
return zero_float3();
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
ccl_private float4 *dfdx,
|
||||
ccl_private float4 *dfdy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
return triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
return triangle_attribute_float4(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
return subd_triangle_attribute_float4(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
if (sd->type & PRIMITIVE_CURVE) {
|
||||
return curve_attribute_float4(kg, sd, desc, dx, dy);
|
||||
return curve_attribute_float4(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
else if (sd->type & PRIMITIVE_POINT) {
|
||||
return point_attribute_float4(kg, sd, desc, dx, dy);
|
||||
return point_attribute_float4(kg, sd, desc, dfdx, dfdy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
return zero_float4();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "kernel/geom/attribute.h"
|
||||
#include "kernel/geom/patch.h"
|
||||
#include "kernel/geom/triangle.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -88,13 +89,52 @@ ccl_device_inline void subd_triangle_patch_corners(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
ccl_device_inline void subd_triangle_attribute_df(const ccl_private differential &du,
|
||||
const ccl_private differential &dv,
|
||||
const ccl_private T &dads,
|
||||
const ccl_private T &dadt,
|
||||
const float2 dpdu,
|
||||
const float2 dpdv,
|
||||
ccl_private T *dfdx,
|
||||
ccl_private T *dfdy)
|
||||
{
|
||||
if (!(dfdx || dfdy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float dsdu = dpdu.x;
|
||||
const float dtdu = dpdu.y;
|
||||
const float dsdv = dpdv.x;
|
||||
const float dtdv = dpdv.y;
|
||||
|
||||
if (dfdx) {
|
||||
const float dudx = du.dx;
|
||||
const float dvdx = dv.dx;
|
||||
|
||||
const float dsdx = dsdu * dudx + dsdv * dvdx;
|
||||
const float dtdx = dtdu * dudx + dtdv * dvdx;
|
||||
|
||||
*dfdx = dads * dsdx + dadt * dtdx;
|
||||
}
|
||||
if (dfdy) {
|
||||
const float dudy = du.dy;
|
||||
const float dvdy = dv.dy;
|
||||
|
||||
const float dsdy = dsdu * dudy + dsdv * dvdy;
|
||||
const float dtdy = dtdu * dudy + dtdv * dvdy;
|
||||
|
||||
*dfdy = dads * dsdy + dadt * dtdy;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reading attributes on various subdivision triangle elements */
|
||||
|
||||
ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
ccl_private float *dfdx,
|
||||
ccl_private float *dfdy)
|
||||
{
|
||||
const int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
@@ -115,42 +155,18 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
a = patch_eval_float(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx || dy) {
|
||||
const float dsdu = dpdu.x;
|
||||
const float dtdu = dpdu.y;
|
||||
const float dsdv = dpdv.x;
|
||||
const float dtdv = dpdv.y;
|
||||
|
||||
if (dx) {
|
||||
const float dudx = sd->du.dx;
|
||||
const float dvdx = sd->dv.dx;
|
||||
|
||||
const float dsdx = dsdu * dudx + dsdv * dvdx;
|
||||
const float dtdx = dtdu * dudx + dtdv * dvdx;
|
||||
|
||||
*dx = dads * dsdx + dadt * dtdx;
|
||||
}
|
||||
if (dy) {
|
||||
const float dudy = sd->du.dy;
|
||||
const float dvdy = sd->dv.dy;
|
||||
|
||||
const float dsdy = dsdu * dudy + dsdv * dvdy;
|
||||
const float dtdy = dtdu * dudy + dtdv * dvdy;
|
||||
|
||||
*dy = dads * dsdy + dadt * dtdy;
|
||||
}
|
||||
}
|
||||
subd_triangle_attribute_df(sd->du, sd->dv, dads, dadt, dpdu, dpdv, dfdx, dfdy);
|
||||
# endif
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if (desc.element == ATTR_ELEMENT_FACE) {
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
@@ -176,11 +192,11 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
const float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -208,32 +224,32 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
const float c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
|
||||
}
|
||||
if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float, desc.offset);
|
||||
}
|
||||
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
return 0.0f;
|
||||
}
|
||||
@@ -241,8 +257,8 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
ccl_private float2 *dfdx,
|
||||
ccl_private float2 *dfdy)
|
||||
{
|
||||
const int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
@@ -264,42 +280,18 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
||||
a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx || dy) {
|
||||
const float dsdu = dpdu.x;
|
||||
const float dtdu = dpdu.y;
|
||||
const float dsdv = dpdv.x;
|
||||
const float dtdv = dpdv.y;
|
||||
|
||||
if (dx) {
|
||||
const float dudx = sd->du.dx;
|
||||
const float dvdx = sd->dv.dx;
|
||||
|
||||
const float dsdx = dsdu * dudx + dsdv * dvdx;
|
||||
const float dtdx = dtdu * dudx + dtdv * dvdx;
|
||||
|
||||
*dx = dads * dsdx + dadt * dtdx;
|
||||
}
|
||||
if (dy) {
|
||||
const float dudy = sd->du.dy;
|
||||
const float dvdy = sd->dv.dy;
|
||||
|
||||
const float dsdy = dsdu * dudy + dsdv * dvdy;
|
||||
const float dtdy = dtdu * dudy + dtdv * dvdy;
|
||||
|
||||
*dy = dads * dsdy + dadt * dtdy;
|
||||
}
|
||||
}
|
||||
subd_triangle_attribute_df(sd->du, sd->dv, dads, dadt, dpdu, dpdv, dfdx, dfdy);
|
||||
# endif
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if (desc.element == ATTR_ELEMENT_FACE) {
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = make_float2(0.0f, 0.0f);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = make_float2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
@@ -325,11 +317,11 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
||||
const float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -362,42 +354,42 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
||||
const float2 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
|
||||
}
|
||||
if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float2();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float2();
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float2, desc.offset);
|
||||
}
|
||||
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float2();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float2();
|
||||
}
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
return zero_float2();
|
||||
}
|
||||
|
||||
ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
ccl_private float3 *dfdx,
|
||||
ccl_private float3 *dfdy)
|
||||
{
|
||||
const int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
@@ -418,42 +410,18 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
a = patch_eval_float3(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx || dy) {
|
||||
const float dsdu = dpdu.x;
|
||||
const float dtdu = dpdu.y;
|
||||
const float dsdv = dpdv.x;
|
||||
const float dtdv = dpdv.y;
|
||||
|
||||
if (dx) {
|
||||
const float dudx = sd->du.dx;
|
||||
const float dvdx = sd->dv.dx;
|
||||
|
||||
const float dsdx = dsdu * dudx + dsdv * dvdx;
|
||||
const float dtdx = dtdu * dudx + dtdv * dvdx;
|
||||
|
||||
*dx = dads * dsdx + dadt * dtdx;
|
||||
}
|
||||
if (dy) {
|
||||
const float dudy = sd->du.dy;
|
||||
const float dvdy = sd->dv.dy;
|
||||
|
||||
const float dsdy = dsdu * dudy + dsdv * dvdy;
|
||||
const float dtdy = dtdu * dudy + dtdv * dvdy;
|
||||
|
||||
*dy = dads * dsdy + dadt * dtdy;
|
||||
}
|
||||
}
|
||||
subd_triangle_attribute_df(sd->du, sd->dv, dads, dadt, dpdu, dpdv, dfdx, dfdy);
|
||||
# endif
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if (desc.element == ATTR_ELEMENT_FACE) {
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float3, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
@@ -479,11 +447,11 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
const float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -516,41 +484,41 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
const float3 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
|
||||
}
|
||||
if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float3, desc.offset);
|
||||
}
|
||||
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
return zero_float3();
|
||||
}
|
||||
|
||||
ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
ccl_private float4 *dfdx,
|
||||
ccl_private float4 *dfdy)
|
||||
{
|
||||
const int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
@@ -576,42 +544,18 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
}
|
||||
|
||||
# ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx || dy) {
|
||||
const float dsdu = dpdu.x;
|
||||
const float dtdu = dpdu.y;
|
||||
const float dsdv = dpdv.x;
|
||||
const float dtdv = dpdv.y;
|
||||
|
||||
if (dx) {
|
||||
const float dudx = sd->du.dx;
|
||||
const float dvdx = sd->dv.dx;
|
||||
|
||||
const float dsdx = dsdu * dudx + dsdv * dvdx;
|
||||
const float dtdx = dtdu * dudx + dtdv * dvdx;
|
||||
|
||||
*dx = dads * dsdx + dadt * dtdx;
|
||||
}
|
||||
if (dy) {
|
||||
const float dudy = sd->du.dy;
|
||||
const float dvdy = sd->dv.dy;
|
||||
|
||||
const float dsdy = dsdu * dudy + dsdv * dvdy;
|
||||
const float dtdy = dtdu * dudy + dtdv * dvdy;
|
||||
|
||||
*dy = dads * dsdy + dadt * dtdy;
|
||||
}
|
||||
}
|
||||
subd_triangle_attribute_df(sd->du, sd->dv, dads, dadt, dpdu, dpdv, dfdx, dfdy);
|
||||
# endif
|
||||
|
||||
return a;
|
||||
}
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if (desc.element == ATTR_ELEMENT_FACE) {
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float4, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
@@ -637,11 +581,11 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
const float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -686,32 +630,32 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
const float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * b + sd->dv.dx * c - (sd->du.dx + sd->dv.dx) * a;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * b + sd->dv.dy * c - (sd->du.dy + sd->dv.dy) * a;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, a, b, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * b + sd->v * c + (1.0f - sd->u - sd->v) * a;
|
||||
}
|
||||
if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) {
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
|
||||
return kernel_data_fetch(attributes_float4, desc.offset);
|
||||
}
|
||||
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
return zero_float4();
|
||||
}
|
||||
|
||||
@@ -154,13 +154,42 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals kg,
|
||||
*dPdv = (p2 - p0);
|
||||
}
|
||||
|
||||
/* Reading attributes on various triangle elements */
|
||||
/* Partial derivative of f w.r.t. x, namely ∂f/∂x.
|
||||
* f is a function of barycentric coordinates u, v, given by
|
||||
* f(u, v) = f1 * u + f2 * v + f0 * (1 - u - v),
|
||||
* the derivatives are
|
||||
* ∂f/∂u = (f1 - f0), ∂f/∂v = (f2 - f0).
|
||||
* The partial derivative in x is
|
||||
* ∂f/∂x = ∂f/∂u * ∂u/∂x + ∂f/∂v * ∂v/∂x
|
||||
* = (f1 - f0) * du.dx + (f2 - f0) * dv.dx. */
|
||||
template<typename T>
|
||||
ccl_device_inline T triangle_attribute_dfdx(const ccl_private differential &du,
|
||||
const ccl_private differential &dv,
|
||||
const ccl_private T &f0,
|
||||
const ccl_private T &f1,
|
||||
const ccl_private T &f2)
|
||||
{
|
||||
return du.dx * f1 + dv.dx * f2 - (du.dx + dv.dx) * f0;
|
||||
}
|
||||
|
||||
/* Partial derivative of f w.r.t. in x, namely ∂f/∂y, similarly computed as ∂f/∂x above. */
|
||||
template<typename T>
|
||||
ccl_device_inline T triangle_attribute_dfdy(const ccl_private differential &du,
|
||||
const ccl_private differential &dv,
|
||||
const ccl_private T &f0,
|
||||
const ccl_private T &f1,
|
||||
const ccl_private T &f2)
|
||||
{
|
||||
return du.dy * f1 + dv.dy * f2 - (du.dy + dv.dy) * f0;
|
||||
}
|
||||
|
||||
/* Read attributes on various triangle elements, and compute the partial derivatives if requested.
|
||||
*/
|
||||
ccl_device float triangle_attribute_float(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
ccl_private float *dfdx,
|
||||
ccl_private float *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) {
|
||||
float f0;
|
||||
@@ -182,22 +211,22 @@ ccl_device float triangle_attribute_float(KernelGlobals kg,
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
|
||||
}
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = 0.0f;
|
||||
if (dfdx) {
|
||||
*dfdx = 0.0f;
|
||||
}
|
||||
if (dy) {
|
||||
*dy = 0.0f;
|
||||
if (dfdy) {
|
||||
*dfdy = 0.0f;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -211,8 +240,8 @@ ccl_device float triangle_attribute_float(KernelGlobals kg,
|
||||
ccl_device float2 triangle_attribute_float2(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
ccl_private float2 *dfdx,
|
||||
ccl_private float2 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) {
|
||||
float2 f0;
|
||||
@@ -234,22 +263,22 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals kg,
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
|
||||
}
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = make_float2(0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float2();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float2(0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float2();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -257,14 +286,14 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals kg,
|
||||
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : desc.offset;
|
||||
return kernel_data_fetch(attributes_float2, offset);
|
||||
}
|
||||
return make_float2(0.0f, 0.0f);
|
||||
return zero_float2();
|
||||
}
|
||||
|
||||
ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
ccl_private float3 *dfdx,
|
||||
ccl_private float3 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) {
|
||||
float3 f0;
|
||||
@@ -286,22 +315,22 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
|
||||
}
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float3();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = make_float3(0.0f, 0.0f, 0.0f);
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float3();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -309,14 +338,14 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals kg,
|
||||
const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : desc.offset;
|
||||
return kernel_data_fetch(attributes_float3, offset);
|
||||
}
|
||||
return make_float3(0.0f, 0.0f, 0.0f);
|
||||
return zero_float3();
|
||||
}
|
||||
|
||||
ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
|
||||
const ccl_private ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
ccl_private float4 *dfdx,
|
||||
ccl_private float4 *dfdy)
|
||||
{
|
||||
if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER |
|
||||
ATTR_ELEMENT_CORNER_BYTE))
|
||||
@@ -350,22 +379,22 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals kg,
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = sd->du.dx * f1 + sd->dv.dx * f2 - (sd->du.dx + sd->dv.dx) * f0;
|
||||
if (dfdx) {
|
||||
*dfdx = triangle_attribute_dfdx(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
if (dy) {
|
||||
*dy = sd->du.dy * f1 + sd->dv.dy * f2 - (sd->du.dy + sd->dv.dy) * f0;
|
||||
if (dfdy) {
|
||||
*dfdy = triangle_attribute_dfdy(sd->du, sd->dv, f0, f1, f2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return sd->u * f1 + sd->v * f2 + (1.0f - sd->u - sd->v) * f0;
|
||||
}
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if (dx) {
|
||||
*dx = zero_float4();
|
||||
if (dfdx) {
|
||||
*dfdx = zero_float4();
|
||||
}
|
||||
if (dy) {
|
||||
*dy = zero_float4();
|
||||
if (dfdy) {
|
||||
*dfdy = zero_float4();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -19,15 +19,15 @@ shader node_attribute(string bump_offset = "center",
|
||||
Alpha = data[3];
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
Color += Dx(Color);
|
||||
Vector += Dx(Vector);
|
||||
Fac += Dx(Fac);
|
||||
Alpha += Dx(Alpha);
|
||||
Color += Dx(Color) * BUMP_DX;
|
||||
Vector += Dx(Vector) * BUMP_DX;
|
||||
Fac += Dx(Fac) * BUMP_DX;
|
||||
Alpha += Dx(Alpha) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
Color += Dy(Color);
|
||||
Vector += Dy(Vector);
|
||||
Fac += Dy(Fac);
|
||||
Alpha += Dy(Alpha);
|
||||
Color += Dy(Color) * BUMP_DY;
|
||||
Vector += Dy(Vector) * BUMP_DY;
|
||||
Fac += Dy(Fac) * BUMP_DY;
|
||||
Alpha += Dy(Alpha) * BUMP_DY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ surface node_bump(int invert = 0,
|
||||
dist *= -1.0;
|
||||
|
||||
/* compute and output perturbed normal */
|
||||
NormalOut = normalize(absdet * Normal - dist * sign(det) * surfgrad);
|
||||
NormalOut = normalize(BUMP_DX * absdet * Normal - dist * sign(det) * surfgrad);
|
||||
NormalOut = normalize(strength * NormalOut + (1.0 - strength) * Normal);
|
||||
|
||||
if (use_object_space) {
|
||||
|
||||
@@ -24,12 +24,12 @@ shader node_geometry(string bump_offset = "center",
|
||||
Backfacing = backfacing();
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
Position += Dx(Position);
|
||||
Parametric += Dx(Parametric);
|
||||
Position += Dx(Position) * BUMP_DX;
|
||||
Parametric += Dx(Parametric) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
Position += Dy(Position);
|
||||
Parametric += Dy(Parametric);
|
||||
Position += Dy(Position) * BUMP_DY;
|
||||
Parametric += Dy(Parametric) * BUMP_DY;
|
||||
}
|
||||
|
||||
point generated;
|
||||
@@ -52,10 +52,10 @@ shader node_geometry(string bump_offset = "center",
|
||||
|
||||
getattribute("geom:pointiness", Pointiness);
|
||||
if (bump_offset == "dx") {
|
||||
Pointiness += Dx(Pointiness);
|
||||
Pointiness += Dx(Pointiness) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
Pointiness += Dy(Pointiness);
|
||||
Pointiness += Dy(Pointiness) * BUMP_DY;
|
||||
}
|
||||
|
||||
getattribute("geom:random_per_island", RandomPerIsland);
|
||||
|
||||
@@ -74,21 +74,21 @@ shader node_texture_coordinate(
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
if (!from_dupli) {
|
||||
Generated += Dx(Generated);
|
||||
UV += Dx(UV);
|
||||
Generated += Dx(Generated) * BUMP_DX;
|
||||
UV += Dx(UV) * BUMP_DX;
|
||||
}
|
||||
Object += Dx(Object);
|
||||
Camera += Dx(Camera);
|
||||
Window += Dx(Window);
|
||||
Object += Dx(Object) * BUMP_DX;
|
||||
Camera += Dx(Camera) * BUMP_DX;
|
||||
Window += Dx(Window) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
if (!from_dupli) {
|
||||
Generated += Dy(Generated);
|
||||
UV += Dy(UV);
|
||||
Generated += Dy(Generated) * BUMP_DY;
|
||||
UV += Dy(UV) * BUMP_DY;
|
||||
}
|
||||
Object += Dy(Object);
|
||||
Camera += Dy(Camera);
|
||||
Window += Dy(Window);
|
||||
Object += Dy(Object) * BUMP_DY;
|
||||
Camera += Dy(Camera) * BUMP_DY;
|
||||
Window += Dy(Window) * BUMP_DY;
|
||||
}
|
||||
|
||||
Window[2] = 0.0;
|
||||
|
||||
@@ -21,12 +21,12 @@ shader node_uv_map(int from_dupli = 0,
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
if (!from_dupli) {
|
||||
UV += Dx(UV);
|
||||
UV += Dx(UV) * BUMP_DX;
|
||||
}
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
if (!from_dupli) {
|
||||
UV += Dy(UV);
|
||||
UV += Dy(UV) * BUMP_DY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,12 +24,12 @@ shader node_vertex_color(string bump_offset = "center",
|
||||
Alpha = vertex_color[3];
|
||||
|
||||
if (bump_offset == "dx") {
|
||||
Color += Dx(Color);
|
||||
Alpha += Dx(Alpha);
|
||||
Color += Dx(Color) * BUMP_DX;
|
||||
Alpha += Dx(Alpha) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
Color += Dy(Color);
|
||||
Alpha += Dy(Alpha);
|
||||
Color += Dy(Color) * BUMP_DY;
|
||||
Alpha += Dy(Alpha) * BUMP_DY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -11,10 +11,10 @@ shader node_wireframe(string bump_offset = "center",
|
||||
output float Fac = 0.0)
|
||||
{
|
||||
if (bump_offset == "dx") {
|
||||
P += Dx(P);
|
||||
P += Dx(P) * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == "dy") {
|
||||
P += Dy(P);
|
||||
P += Dy(P) * BUMP_DY;
|
||||
}
|
||||
|
||||
Fac = wireframe("triangles", Size, use_pixel_size);
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
// Constants
|
||||
#define FLT_MAX 3.402823466e+38 // max value
|
||||
|
||||
/* Offset of coordinates for evaluating bump node. Unit in pixel.
|
||||
* NOTE: keep the same as SVM. */
|
||||
#define BUMP_DX 0.1
|
||||
#define BUMP_DY BUMP_DX
|
||||
|
||||
// Declaration of built-in functions and closures, stdosl.h does not make
|
||||
// these available so we have to redefine them.
|
||||
#define BUILTIN [[int builtin = 1]]
|
||||
|
||||
@@ -157,16 +157,19 @@ ccl_device_noinline void svm_node_attr(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
/* Position offsetted in x direction. */
|
||||
ccl_device_forceinline float3 svm_node_bump_P_dx(const ccl_private ShaderData *sd)
|
||||
{
|
||||
return sd->P + differential_from_compact(sd->Ng, sd->dP).dx;
|
||||
return sd->P + differential_from_compact(sd->Ng, sd->dP).dx * BUMP_DX;
|
||||
}
|
||||
|
||||
/* Position offsetted in y direction. */
|
||||
ccl_device_forceinline float3 svm_node_bump_P_dy(const ccl_private ShaderData *sd)
|
||||
{
|
||||
return sd->P + differential_from_compact(sd->Ng, sd->dP).dy;
|
||||
return sd->P + differential_from_compact(sd->Ng, sd->dP).dy * BUMP_DY;
|
||||
}
|
||||
|
||||
/* Evaluate attributes at a position shifted in x direction. */
|
||||
ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
@@ -194,15 +197,15 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
||||
|
||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||
/* No generated attribute, fall back to object coordinates. */
|
||||
float3 f = svm_node_bump_P_dx(sd);
|
||||
float3 f_x = svm_node_bump_P_dx(sd);
|
||||
if (sd->object != OBJECT_NONE) {
|
||||
object_inverse_position_transform(kg, sd, &f);
|
||||
object_inverse_position_transform(kg, sd, &f_x);
|
||||
}
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(stack, out_offset, average(f_x));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(stack, out_offset, f_x);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
@@ -212,52 +215,56 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
||||
|
||||
/* Surface */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dx;
|
||||
const float f = primitive_surface_attribute_float(kg, sd, desc, &dx, nullptr);
|
||||
float dfdx;
|
||||
const float f = primitive_surface_attribute_float(kg, sd, desc, &dfdx, nullptr);
|
||||
const float f_x = f + dfdx * BUMP_DX;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dx);
|
||||
stack_store_float(stack, out_offset, f_x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_x));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dx;
|
||||
const float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, nullptr);
|
||||
float2 dfdx;
|
||||
const float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dfdx, nullptr);
|
||||
const float2 f_x = f + dfdx * BUMP_DX;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dx.x);
|
||||
stack_store_float(stack, out_offset, f_x.x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_x));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dx;
|
||||
const float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, nullptr);
|
||||
float4 dfdx;
|
||||
const float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dfdx, nullptr);
|
||||
const float4 f_x = f + dfdx * BUMP_DX;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(make_float3(f + dx)));
|
||||
stack_store_float(stack, out_offset, average(make_float3(f_x)));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dx));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_x));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dx.w);
|
||||
stack_store_float(stack, out_offset, f_x.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
const float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, nullptr);
|
||||
float3 dfdx;
|
||||
const float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dfdx, nullptr);
|
||||
const float3 f_x = f + dfdx * BUMP_DX;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dx));
|
||||
stack_store_float(stack, out_offset, average(f_x));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dx);
|
||||
stack_store_float3(stack, out_offset, f_x);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
@@ -265,6 +272,7 @@ ccl_device_noinline void svm_node_attr_bump_dx(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate attributes at a position shifted in y direction. */
|
||||
ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float *stack,
|
||||
@@ -292,15 +300,15 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
||||
|
||||
if (node.y == ATTR_STD_GENERATED && desc.element == ATTR_ELEMENT_NONE) {
|
||||
/* No generated attribute, fall back to object coordinates. */
|
||||
float3 f = svm_node_bump_P_dy(sd);
|
||||
float3 f_y = svm_node_bump_P_dy(sd);
|
||||
if (sd->object != OBJECT_NONE) {
|
||||
object_inverse_position_transform(kg, sd, &f);
|
||||
object_inverse_position_transform(kg, sd, &f_y);
|
||||
}
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
stack_store_float(stack, out_offset, average(f_y));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f);
|
||||
stack_store_float3(stack, out_offset, f_y);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
@@ -310,52 +318,56 @@ ccl_device_noinline void svm_node_attr_bump_dy(KernelGlobals kg,
|
||||
|
||||
/* Surface */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float dy;
|
||||
const float f = primitive_surface_attribute_float(kg, sd, desc, nullptr, &dy);
|
||||
float dfdy;
|
||||
const float f = primitive_surface_attribute_float(kg, sd, desc, nullptr, &dfdy);
|
||||
const float f_y = f + dfdy * BUMP_DY;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f + dy);
|
||||
stack_store_float(stack, out_offset, f_y);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_y));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dy;
|
||||
const float2 f = primitive_surface_attribute_float2(kg, sd, desc, nullptr, &dy);
|
||||
float2 dfdy;
|
||||
const float2 f = primitive_surface_attribute_float2(kg, sd, desc, nullptr, &dfdy);
|
||||
const float2 f_y = f + dfdy * BUMP_DY;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dy.x);
|
||||
stack_store_float(stack, out_offset, f_y.x);
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_y));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 dy;
|
||||
const float4 f = primitive_surface_attribute_float4(kg, sd, desc, nullptr, &dy);
|
||||
float4 dfdy;
|
||||
const float4 f = primitive_surface_attribute_float4(kg, sd, desc, nullptr, &dfdy);
|
||||
const float4 f_y = f + dfdy * BUMP_DY;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(make_float3(f + dy)));
|
||||
stack_store_float(stack, out_offset, average(make_float3(f_y)));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, make_float3(f + dy));
|
||||
stack_store_float3(stack, out_offset, make_float3(f_y));
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, f.w + dy.w);
|
||||
stack_store_float(stack, out_offset, f_y.w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
const float3 f = primitive_surface_attribute_float3(kg, sd, desc, nullptr, &dy);
|
||||
float3 dfdy;
|
||||
const float3 f = primitive_surface_attribute_float3(kg, sd, desc, nullptr, &dfdy);
|
||||
const float3 f_y = f + dfdy * BUMP_DY;
|
||||
if (type == NODE_ATTR_OUTPUT_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f + dy));
|
||||
stack_store_float(stack, out_offset, average(f_y));
|
||||
}
|
||||
else if (type == NODE_ATTR_OUTPUT_FLOAT3) {
|
||||
stack_store_float3(stack, out_offset, f + dy);
|
||||
stack_store_float3(stack, out_offset, f_y);
|
||||
}
|
||||
else {
|
||||
stack_store_float(stack, out_offset, 1.0f);
|
||||
|
||||
@@ -86,8 +86,16 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg,
|
||||
|
||||
strength = max(strength, 0.0f);
|
||||
|
||||
/* compute and output perturbed normal */
|
||||
float3 normal_out = safe_normalize(absdet * normal_in - scale * signf(det) * surfgrad);
|
||||
/* Compute and output perturbed normal.
|
||||
* dP'dx = dPdx + scale * (h_x - h_c) / BUMP_DX * normal
|
||||
* dP'dy = dPdy + scale * (h_y - h_c) / BUMP_DY * normal
|
||||
* N' = cross(dP'dx, dP'dy)
|
||||
* = cross(dPdx, dPdy) - scale * ((h_y - h_c) / BUMP_DY * Ry + (h_x - h_c) / BUMP_DX * Rx)
|
||||
* ≈ det * normal_in - scale * surfgrad / BUMP_DX
|
||||
*/
|
||||
kernel_assert(BUMP_DX == BUMP_DY);
|
||||
float3 normal_out = safe_normalize(BUMP_DX * absdet * normal_in -
|
||||
scale * signf(det) * surfgrad);
|
||||
if (is_zero(normal_out)) {
|
||||
normal_out = normal_in;
|
||||
}
|
||||
|
||||
@@ -65,9 +65,12 @@ ccl_device_noinline void svm_node_geometry_bump_dx(KernelGlobals kg,
|
||||
case NODE_GEOM_P:
|
||||
data = svm_node_bump_P_dx(sd);
|
||||
break;
|
||||
case NODE_GEOM_uv:
|
||||
data = make_float3(1.0f - sd->u - sd->du.dx - sd->v - sd->dv.dx, sd->u + sd->du.dx, 0.0f);
|
||||
case NODE_GEOM_uv: {
|
||||
const float u_x = sd->u + sd->du.dx * BUMP_DX;
|
||||
const float v_x = sd->v + sd->dv.dx * BUMP_DX;
|
||||
data = make_float3(1.0f - u_x - v_x, u_x, 0.0f);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
return;
|
||||
@@ -92,9 +95,12 @@ ccl_device_noinline void svm_node_geometry_bump_dy(KernelGlobals kg,
|
||||
case NODE_GEOM_P:
|
||||
data = svm_node_bump_P_dy(sd);
|
||||
break;
|
||||
case NODE_GEOM_uv:
|
||||
data = make_float3(1.0f - sd->u - sd->du.dy - sd->v - sd->dv.dy, sd->u + sd->du.dy, 0.0f);
|
||||
case NODE_GEOM_uv: {
|
||||
const float u_y = sd->u + sd->du.dy * BUMP_DY;
|
||||
const float v_y = sd->v + sd->dv.dy * BUMP_DY;
|
||||
data = make_float3(1.0f - u_y - v_y, u_y, 0.0f);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
svm_node_geometry(kg, sd, stack, type, out_offset);
|
||||
return;
|
||||
|
||||
@@ -135,6 +135,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg,
|
||||
break;
|
||||
}
|
||||
case NODE_TEXCO_NORMAL: {
|
||||
/* TODO(weizhen): implement. */
|
||||
data = sd->N;
|
||||
object_inverse_normal_transform(kg, sd, &data);
|
||||
break;
|
||||
@@ -228,6 +229,7 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg,
|
||||
break;
|
||||
}
|
||||
case NODE_TEXCO_NORMAL: {
|
||||
/* TODO(weizhen): implement. */
|
||||
data = sd->N;
|
||||
object_inverse_normal_transform(kg, sd, &data);
|
||||
break;
|
||||
|
||||
@@ -518,5 +518,8 @@ enum ClosureType {
|
||||
#define CLOSURE_WEIGHT_CUTOFF 1e-5f
|
||||
/* Treat closure as singular if the squared roughness is below this threshold. */
|
||||
#define BSDF_ROUGHNESS_SQ_THRESH 2e-10f
|
||||
/* Offset of coordinates for evaluating bump node. Unit in pixel. */
|
||||
#define BUMP_DX 0.1f
|
||||
#define BUMP_DY BUMP_DX
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -48,16 +48,16 @@ ccl_device_noinline void svm_node_vertex_color_bump_dx(KernelGlobals kg,
|
||||
const AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id);
|
||||
if (descriptor.offset != ATTR_STD_NOT_FOUND) {
|
||||
if (descriptor.type == NODE_ATTR_FLOAT4 || descriptor.type == NODE_ATTR_RGBA) {
|
||||
float4 dx;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, &dx, nullptr);
|
||||
vertex_color += dx;
|
||||
float4 dfdx;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, &dfdx, nullptr);
|
||||
vertex_color += dfdx * BUMP_DX;
|
||||
stack_store_float3(stack, color_offset, make_float3(vertex_color));
|
||||
stack_store_float(stack, alpha_offset, vertex_color.w);
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, &dx, nullptr);
|
||||
vertex_color += dx;
|
||||
float3 dfdx;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, &dfdx, nullptr);
|
||||
vertex_color += dfdx * BUMP_DX;
|
||||
stack_store_float3(stack, color_offset, vertex_color);
|
||||
stack_store_float(stack, alpha_offset, 1.0f);
|
||||
}
|
||||
@@ -78,16 +78,16 @@ ccl_device_noinline void svm_node_vertex_color_bump_dy(KernelGlobals kg,
|
||||
const AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id);
|
||||
if (descriptor.offset != ATTR_STD_NOT_FOUND) {
|
||||
if (descriptor.type == NODE_ATTR_FLOAT4 || descriptor.type == NODE_ATTR_RGBA) {
|
||||
float4 dy;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, nullptr, &dy);
|
||||
vertex_color += dy;
|
||||
float4 dfdy;
|
||||
float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, nullptr, &dfdy);
|
||||
vertex_color += dfdy * BUMP_DY;
|
||||
stack_store_float3(stack, color_offset, make_float3(vertex_color));
|
||||
stack_store_float(stack, alpha_offset, vertex_color.w);
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, nullptr, &dy);
|
||||
vertex_color += dy;
|
||||
float3 dfdy;
|
||||
float3 vertex_color = primitive_surface_attribute_float3(kg, sd, descriptor, nullptr, &dfdy);
|
||||
vertex_color += dfdy * BUMP_DY;
|
||||
stack_store_float3(stack, color_offset, vertex_color);
|
||||
stack_store_float(stack, alpha_offset, 1.0f);
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ ccl_device_noinline void svm_node_wireframe(KernelGlobals kg,
|
||||
|
||||
float3 P = sd->P;
|
||||
if (bump_offset == NODE_BUMP_OFFSET_DX) {
|
||||
P += dP.dx;
|
||||
P += dP.dx * BUMP_DX;
|
||||
}
|
||||
else if (bump_offset == NODE_BUMP_OFFSET_DY) {
|
||||
P += dP.dy;
|
||||
P += dP.dy * BUMP_DY;
|
||||
}
|
||||
|
||||
const float f = wireframe(kg, sd, dP, size, pixel_size, &P);
|
||||
|
||||
@@ -637,7 +637,9 @@ vec3 displacement_bump()
|
||||
vec3 surfgrad = dHd.x * Rx + dHd.y * Ry;
|
||||
|
||||
float facing = FrontFacing ? 1.0 : -1.0;
|
||||
return normalize(abs(det) * g_data.N - facing * sign(det) * surfgrad);
|
||||
/* NOTE: keep the same as defined `BUMP_DX`. */
|
||||
const float bump_dx = 0.1;
|
||||
return normalize(bump_dx * abs(det) * g_data.N - facing * sign(det) * surfgrad);
|
||||
# else
|
||||
return g_data.N;
|
||||
# endif
|
||||
|
||||
@@ -334,21 +334,27 @@ vec3 dF_impl(vec3 v)
|
||||
|
||||
void dF_branch(float fn, out vec2 result)
|
||||
{
|
||||
/* NOTE: this function is currently unused, once it is used we need to check if `BUMP_DX/BUMP_DY`
|
||||
* needs to be applied. */
|
||||
result.x = dFdx(fn);
|
||||
result.y = dFdy(fn);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Offset of coordinates for evaluating bump node. Unit in pixel. */
|
||||
# define BUMP_DX 0.1
|
||||
# define BUMP_DY BUMP_DX
|
||||
|
||||
/* Precise derivatives */
|
||||
int g_derivative_flag = 0;
|
||||
|
||||
vec3 dF_impl(vec3 v)
|
||||
{
|
||||
if (g_derivative_flag > 0) {
|
||||
return dFdx(v);
|
||||
return dFdx(v) * BUMP_DX;
|
||||
}
|
||||
else if (g_derivative_flag < 0) {
|
||||
return dFdy(v);
|
||||
return dFdy(v) * BUMP_DY;
|
||||
}
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,9 @@ void node_bump(float strength,
|
||||
|
||||
strength = max(strength, 0.0);
|
||||
|
||||
result = normalize(abs(det) * N - dist * sign(det) * surfgrad);
|
||||
/* NOTE: keep the same as defined `BUMP_DX`. */
|
||||
const float bump_dx = 0.1;
|
||||
result = normalize(bump_dx * abs(det) * N - dist * sign(det) * surfgrad);
|
||||
result = normalize(mix(N, result, strength));
|
||||
#else
|
||||
result = N;
|
||||
|
||||
Submodule tests/data updated: 442bbeece0...841659d63a
Reference in New Issue
Block a user