Merge branch 'blender-v4.4-release'

This commit is contained in:
Weizhen Huang
2025-02-05 13:41:44 +01:00
23 changed files with 439 additions and 420 deletions

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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]]

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;