Cycles: Added Float2 attribute type.
Float2 are now a new type for attributes in Cycles. Before, the choices for attribute storage were float and float3, the latter padded to float4. This meant that UV maps were inflated to twice the size necessary. Reviewers: brecht, sergey Reviewed By: brecht Subscribers: #cycles Tags: #cycles Differential Revision: https://developer.blender.org/D4409
This commit is contained in:

committed by
Stefan Werner

parent
a325bc6bf3
commit
db7f9a70b0
@@ -106,7 +106,7 @@ struct MikkUserData {
|
||||
else {
|
||||
Attribute *attr_uv = attributes.find(ustring(layer_name));
|
||||
if(attr_uv != NULL) {
|
||||
texface = attr_uv->data_float3();
|
||||
texface = attr_uv->data_float2();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,7 @@ struct MikkUserData {
|
||||
int num_faces;
|
||||
|
||||
float3 *vertex_normal;
|
||||
float3 *texface;
|
||||
float2 *texface;
|
||||
float3 *orco;
|
||||
float3 orco_loc, orco_size;
|
||||
|
||||
@@ -190,7 +190,7 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
if(userdata->texface != NULL) {
|
||||
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
|
||||
float3 tfuv = userdata->texface[corner_index];
|
||||
float2 tfuv = userdata->texface[corner_index];
|
||||
uv[0] = tfuv.x;
|
||||
uv[1] = tfuv.y;
|
||||
}
|
||||
@@ -494,19 +494,19 @@ static void attr_create_uv_map(Scene *scene,
|
||||
}
|
||||
|
||||
BL::MeshTextureFaceLayer::data_iterator t;
|
||||
float3 *fdata = uv_attr->data_float3();
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
size_t i = 0;
|
||||
|
||||
for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
|
||||
int tri_a[3], tri_b[3];
|
||||
face_split_tri_indices(face_flags[i], tri_a, tri_b);
|
||||
|
||||
float3 uvs[4];
|
||||
uvs[0] = get_float3(t->uv1());
|
||||
uvs[1] = get_float3(t->uv2());
|
||||
uvs[2] = get_float3(t->uv3());
|
||||
float2 uvs[4];
|
||||
uvs[0] = get_float2(t->uv1());
|
||||
uvs[1] = get_float2(t->uv2());
|
||||
uvs[2] = get_float2(t->uv3());
|
||||
if(nverts[i] == 4) {
|
||||
uvs[3] = get_float3(t->uv4());
|
||||
uvs[3] = get_float2(t->uv4());
|
||||
}
|
||||
|
||||
fdata[0] = uvs[tri_a[0]];
|
||||
@@ -593,12 +593,12 @@ static void attr_create_subd_uv_map(Scene *scene,
|
||||
}
|
||||
|
||||
BL::Mesh::polygons_iterator p;
|
||||
float3 *fdata = uv_attr->data_float3();
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
|
||||
for(b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
|
||||
int n = p->loop_total();
|
||||
for(int j = 0; j < n; j++) {
|
||||
*(fdata++) = get_float3(l->data[p->loop_start() + j].uv());
|
||||
*(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -87,6 +87,45 @@ ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd,
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float2 curve_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_CURVE) {
|
||||
/* idea: we can't derive any useful differentials here, but for tiled
|
||||
* mipmap image caching it would be useful to avoid reading the highest
|
||||
* 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(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CURVE_KEY || desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) {
|
||||
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
|
||||
int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
|
||||
int k1 = k0 + 1;
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + k0);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + k1);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*(f1 - f0);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return (1.0f - sd->u)*f0 + sd->u*f1;
|
||||
}
|
||||
else {
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
#endif
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 curve_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_CURVE) {
|
||||
|
@@ -284,6 +284,33 @@ ccl_device float patch_eval_float(KernelGlobals *kg, const ShaderData *sd, int o
|
||||
return val;
|
||||
}
|
||||
|
||||
ccl_device float2 patch_eval_float2(KernelGlobals *kg, const ShaderData *sd, int offset,
|
||||
int patch, float u, float v, int channel,
|
||||
float2 *du, float2 *dv)
|
||||
{
|
||||
int indices[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights_du[PATCH_MAX_CONTROL_VERTS];
|
||||
float weights_dv[PATCH_MAX_CONTROL_VERTS];
|
||||
|
||||
int num_control = patch_eval_control_verts(kg, sd->object, patch, u, v, channel,
|
||||
indices, weights, weights_du, weights_dv);
|
||||
|
||||
float2 val = make_float2(0.0f, 0.0f);
|
||||
if(du) *du = make_float2(0.0f, 0.0f);
|
||||
if(dv) *dv = make_float2(0.0f, 0.0f);
|
||||
|
||||
for(int i = 0; i < num_control; i++) {
|
||||
float2 v = kernel_tex_fetch(__attributes_float2, offset + indices[i]);
|
||||
|
||||
val += v * weights[i];
|
||||
if(du) *du += v * weights_du[i];
|
||||
if(dv) *dv += v * weights_dv[i];
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
ccl_device float3 patch_eval_float3(KernelGlobals *kg, const ShaderData *sd, int offset,
|
||||
int patch, float u, float v, int channel,
|
||||
float3 *du, float3 *dv)
|
||||
|
@@ -89,6 +89,37 @@ ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg,
|
||||
}
|
||||
#endif
|
||||
|
||||
ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
float2 *dx, float2 *dy)
|
||||
{
|
||||
if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if(subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if(sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
#ifdef __VOLUME__
|
||||
else if(sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) {
|
||||
kernel_assert(0);
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
@@ -119,6 +150,29 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg,
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
float2 *dx, float2 *dy)
|
||||
{
|
||||
if(sd->type & PRIMITIVE_ALL_TRIANGLE) {
|
||||
if(subd_triangle_patch(kg, sd) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
else if(sd->type & PRIMITIVE_ALL_CURVE) {
|
||||
return curve_attribute_float2(kg, sd, desc, dx, dy);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg,
|
||||
const ShaderData *sd,
|
||||
const AttributeDescriptor desc,
|
||||
|
@@ -216,6 +216,128 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals *kg, const
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if(desc.flags & ATTR_SUBDIVIDED) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
float2 dpdu = uv[0] - uv[2];
|
||||
float2 dpdv = uv[1] - uv[2];
|
||||
|
||||
/* p is [s, t] */
|
||||
float2 p = dpdu * sd->u + dpdv * sd->v + uv[2];
|
||||
|
||||
float2 a, dads, dadt;
|
||||
|
||||
a = patch_eval_float2(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx || dy) {
|
||||
float dsdu = dpdu.x;
|
||||
float dtdu = dpdu.y;
|
||||
float dsdv = dpdv.x;
|
||||
float dtdv = dpdv.y;
|
||||
|
||||
if(dx) {
|
||||
float dudx = sd->du.dx;
|
||||
float dvdx = sd->dv.dx;
|
||||
|
||||
float dsdx = dsdu*dudx + dsdv*dvdx;
|
||||
float dtdx = dtdu*dudx + dtdv*dvdx;
|
||||
|
||||
*dx = dads*dsdx + dadt*dtdx;
|
||||
}
|
||||
if(dy) {
|
||||
float dudy = sd->du.dy;
|
||||
float dvdy = sd->dv.dy;
|
||||
|
||||
float dsdy = dsdu*dudy + dsdv*dvdy;
|
||||
float dtdy = dtdu*dudy + dtdv*dvdy;
|
||||
|
||||
*dy = dads*dsdy + dadt*dtdy;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return a;
|
||||
}
|
||||
else
|
||||
#endif /* __PATCH_EVAL__ */
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + subd_triangle_patch_face(kg, patch));
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
uint4 v = subd_triangle_patch_indices(kg, patch);
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + v.x);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + v.y);
|
||||
float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + v.z);
|
||||
float2 f3 = kernel_tex_fetch(__attributes_float2, desc.offset + v.w);
|
||||
|
||||
if(subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1+f0)*0.5f;
|
||||
f3 = (f3+f0)*0.5f;
|
||||
}
|
||||
|
||||
float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
|
||||
float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
|
||||
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*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
|
||||
if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
|
||||
#endif
|
||||
|
||||
return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
float2 uv[3];
|
||||
subd_triangle_patch_uv(kg, sd, uv);
|
||||
|
||||
int corners[4];
|
||||
subd_triangle_patch_corners(kg, patch, corners);
|
||||
|
||||
float2 f0, f1, f2, f3;
|
||||
|
||||
f0 = kernel_tex_fetch(__attributes_float2, corners[0] + desc.offset);
|
||||
f1 = kernel_tex_fetch(__attributes_float2, corners[1] + desc.offset);
|
||||
f2 = kernel_tex_fetch(__attributes_float2, corners[2] + desc.offset);
|
||||
f3 = kernel_tex_fetch(__attributes_float2, corners[3] + desc.offset);
|
||||
|
||||
if(subd_triangle_patch_num_corners(kg, patch) != 4) {
|
||||
f1 = (f1+f0)*0.5f;
|
||||
f3 = (f3+f0)*0.5f;
|
||||
}
|
||||
|
||||
float2 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y);
|
||||
float2 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y);
|
||||
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*a + sd->dv.dx*b - (sd->du.dx + sd->dv.dx)*c;
|
||||
if(dy) *dy = sd->du.dy*a + sd->dv.dy*b - (sd->du.dy + sd->dv.dy)*c;
|
||||
#endif
|
||||
|
||||
return sd->u*a + sd->v*b + (1.0f - sd->u - sd->v)*c;
|
||||
}
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
|
@@ -149,6 +149,53 @@ ccl_device float triangle_attribute_float(KernelGlobals *kg, const ShaderData *s
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float2 triangle_attribute_float2(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float2 *dx, float2 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim);
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) {
|
||||
uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim);
|
||||
|
||||
float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x);
|
||||
float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y);
|
||||
float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z);
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
|
||||
if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
|
||||
#endif
|
||||
|
||||
return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
|
||||
}
|
||||
else if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
int tri = desc.offset + sd->prim*3;
|
||||
float2 f0, f1, f2;
|
||||
|
||||
if(desc.element == ATTR_ELEMENT_CORNER) {
|
||||
f0 = kernel_tex_fetch(__attributes_float2, tri + 0);
|
||||
f1 = kernel_tex_fetch(__attributes_float2, tri + 1);
|
||||
f2 = kernel_tex_fetch(__attributes_float2, tri + 2);
|
||||
}
|
||||
|
||||
#ifdef __RAY_DIFFERENTIALS__
|
||||
if(dx) *dx = sd->du.dx*f0 + sd->dv.dx*f1 - (sd->du.dx + sd->dv.dx)*f2;
|
||||
if(dy) *dy = sd->du.dy*f0 + sd->dv.dy*f1 - (sd->du.dy + sd->dv.dy)*f2;
|
||||
#endif
|
||||
|
||||
return sd->u*f0 + sd->v*f1 + (1.0f - sd->u - sd->v)*f2;
|
||||
}
|
||||
else {
|
||||
if(dx) *dx = make_float2(0.0f, 0.0f);
|
||||
if(dy) *dy = make_float2(0.0f, 0.0f);
|
||||
|
||||
return make_float2(0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float3 *dx, float3 *dy)
|
||||
{
|
||||
if(desc.element == ATTR_ELEMENT_FACE) {
|
||||
|
@@ -56,6 +56,7 @@ KERNEL_TEX(uint, __patches)
|
||||
/* attributes */
|
||||
KERNEL_TEX(uint4, __attributes_map)
|
||||
KERNEL_TEX(float, __attributes_float)
|
||||
KERNEL_TEX(float2, __attributes_float2)
|
||||
KERNEL_TEX(float4, __attributes_float3)
|
||||
KERNEL_TEX(uchar4, __attributes_uchar4)
|
||||
|
||||
|
@@ -392,6 +392,44 @@ bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg, bool derivat
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor)
|
||||
{
|
||||
float *fval = (float *)val;
|
||||
|
||||
fval[0] = f[0].x;
|
||||
fval[1] = f[0].y;
|
||||
fval[2] = 0.0f;
|
||||
|
||||
if(derivatives) {
|
||||
fval[3] = f[1].x;
|
||||
fval[4] = f[1].y;
|
||||
fval[5] = 0.0f;
|
||||
|
||||
fval[6] = f[2].x;
|
||||
fval[7] = f[2].y;
|
||||
fval[8] = 0.0f;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else if(type == TypeDesc::TypeFloat) {
|
||||
float *fval = (float *)val;
|
||||
fval[0] = average(f[0]);
|
||||
|
||||
if(derivatives) {
|
||||
fval[1] = average(f[1]);
|
||||
fval[2] = average(f[2]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
if(type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
@@ -572,6 +610,12 @@ static bool get_primitive_attribute(KernelGlobals *kg, const ShaderData *sd, con
|
||||
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if(attr.type == TypeFloat2) {
|
||||
float2 fval[2];
|
||||
fval[0] = primitive_attribute_float2(kg, sd, attr.desc,
|
||||
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
else if(attr.type == TypeDesc::TypeFloat) {
|
||||
float fval[3];
|
||||
fval[0] = primitive_attribute_float(kg, sd, attr.desc,
|
||||
|
@@ -52,18 +52,27 @@ ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, u
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
float f = primitive_attribute_float(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f, f, f));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f));
|
||||
}
|
||||
else {
|
||||
@@ -84,20 +93,30 @@ void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
float dx;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f+dx);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f+dx, f+dx, f+dx));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dx;
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dx.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x+dx.x, f.y+dx.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dx;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f+dx));
|
||||
}
|
||||
else {
|
||||
@@ -121,20 +140,30 @@ void svm_node_attr_bump_dy(KernelGlobals *kg,
|
||||
AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset);
|
||||
|
||||
/* fetch and store attribute */
|
||||
if (desc.type == NODE_ATTR_FLOAT) {
|
||||
if(desc.type == NODE_ATTR_FLOAT) {
|
||||
float dy;
|
||||
float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f+dy);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f+dy, f+dy, f+dy));
|
||||
}
|
||||
}
|
||||
else if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 dy;
|
||||
float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy);
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, f.x + dy.x);
|
||||
}
|
||||
else {
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x+dy.x, f.y+dy.y, 0.0f));
|
||||
}
|
||||
}
|
||||
else {
|
||||
float3 dy;
|
||||
float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy);
|
||||
if (type == NODE_ATTR_FLOAT) {
|
||||
if(type == NODE_ATTR_FLOAT) {
|
||||
stack_store_float(stack, out_offset, average(f+dy));
|
||||
}
|
||||
else {
|
||||
|
@@ -363,8 +363,16 @@ ccl_device void svm_node_tangent(KernelGlobals *kg, ShaderData *sd, float *stack
|
||||
float3 attribute_value;
|
||||
const AttributeDescriptor desc = find_attribute(kg, sd, node.z);
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
if(desc.type == NODE_ATTR_FLOAT2) {
|
||||
float2 value = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL);
|
||||
attribute_value.x = value.x;
|
||||
attribute_value.y = value.y;
|
||||
attribute_value.z = 0.0f;
|
||||
}
|
||||
else {
|
||||
attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(direction_type == NODE_TANGENT_UVMAP) {
|
||||
|
@@ -141,6 +141,7 @@ typedef enum ShaderNodeType {
|
||||
|
||||
typedef enum NodeAttributeType {
|
||||
NODE_ATTR_FLOAT = 0,
|
||||
NODE_ATTR_FLOAT2,
|
||||
NODE_ATTR_FLOAT3,
|
||||
NODE_ATTR_MATRIX
|
||||
} NodeAttributeType;
|
||||
|
@@ -48,7 +48,8 @@ void Attribute::set(ustring name_, TypeDesc type_, AttributeElement element_)
|
||||
/* string and matrix not supported! */
|
||||
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
|
||||
type == TypeDesc::TypePoint || type == TypeDesc::TypeVector ||
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix);
|
||||
type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix ||
|
||||
type == TypeFloat2);
|
||||
}
|
||||
|
||||
void Attribute::resize(Mesh *mesh, AttributePrimitive prim, bool reserve_only)
|
||||
@@ -400,7 +401,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
||||
attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_FACE);
|
||||
break;
|
||||
case ATTR_STD_UV:
|
||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_CORNER);
|
||||
attr = add(name, TypeFloat2, ATTR_ELEMENT_CORNER);
|
||||
break;
|
||||
case ATTR_STD_UV_TANGENT:
|
||||
attr = add(name, TypeDesc::TypeVector, ATTR_ELEMENT_CORNER);
|
||||
|
@@ -67,6 +67,7 @@ public:
|
||||
size_t buffer_size(Mesh *mesh, AttributePrimitive prim) const;
|
||||
|
||||
char *data() { return (buffer.size())? &buffer[0]: NULL; };
|
||||
float2 *data_float2() { return (float2*)data(); }
|
||||
float3 *data_float3() { return (float3*)data(); }
|
||||
float4 *data_float4() { return (float4*)data(); }
|
||||
float *data_float() { return (float*)data(); }
|
||||
@@ -75,6 +76,7 @@ public:
|
||||
VoxelAttribute *data_voxel() { return ( VoxelAttribute*)data(); }
|
||||
|
||||
const char *data() const { return (buffer.size())? &buffer[0]: NULL; }
|
||||
const float2 *data_float2() const { return (const float2*)data(); }
|
||||
const float3 *data_float3() const { return (const float3*)data(); }
|
||||
const float4 *data_float4() const { return (const float4*)data(); }
|
||||
const float *data_float() const { return (const float*)data(); }
|
||||
@@ -85,6 +87,7 @@ public:
|
||||
void add_with_weight(void* dst, void* src, float weight);
|
||||
|
||||
void add(const float& f);
|
||||
void add(const float2& f);
|
||||
void add(const float3& f);
|
||||
void add(const uchar4& f);
|
||||
void add(const Transform& f);
|
||||
|
@@ -1233,6 +1233,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
|
||||
osl_attr.type = TypeDesc::TypeFloat;
|
||||
else if(req.triangle_type == TypeDesc::TypeMatrix)
|
||||
osl_attr.type = TypeDesc::TypeMatrix;
|
||||
else if(req.triangle_type == TypeFloat2)
|
||||
osl_attr.type = TypeFloat2;
|
||||
else
|
||||
osl_attr.type = TypeDesc::TypeColor;
|
||||
|
||||
@@ -1342,6 +1344,8 @@ void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *sc
|
||||
attr_map[index].w = NODE_ATTR_FLOAT;
|
||||
else if(req.triangle_type == TypeDesc::TypeMatrix)
|
||||
attr_map[index].w = NODE_ATTR_MATRIX;
|
||||
else if(req.triangle_type == TypeFloat2)
|
||||
attr_map[index].w = NODE_ATTR_FLOAT2;
|
||||
else
|
||||
attr_map[index].w = NODE_ATTR_FLOAT3;
|
||||
|
||||
@@ -1359,6 +1363,8 @@ void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *sc
|
||||
attr_map[index].w = NODE_ATTR_FLOAT;
|
||||
else if(req.curve_type == TypeDesc::TypeMatrix)
|
||||
attr_map[index].w = NODE_ATTR_MATRIX;
|
||||
else if(req.curve_type == TypeFloat2)
|
||||
attr_map[index].w = NODE_ATTR_FLOAT2;
|
||||
else
|
||||
attr_map[index].w = NODE_ATTR_FLOAT3;
|
||||
|
||||
@@ -1376,6 +1382,8 @@ void MeshManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *sc
|
||||
attr_map[index].w = NODE_ATTR_FLOAT;
|
||||
else if(req.subd_type == TypeDesc::TypeMatrix)
|
||||
attr_map[index].w = NODE_ATTR_MATRIX;
|
||||
else if(req.subd_type == TypeFloat2)
|
||||
attr_map[index].w = NODE_ATTR_FLOAT2;
|
||||
else
|
||||
attr_map[index].w = NODE_ATTR_FLOAT3;
|
||||
|
||||
@@ -1404,6 +1412,7 @@ static void update_attribute_element_size(Mesh *mesh,
|
||||
Attribute *mattr,
|
||||
AttributePrimitive prim,
|
||||
size_t *attr_float_size,
|
||||
size_t *attr_float2_size,
|
||||
size_t *attr_float3_size,
|
||||
size_t *attr_uchar4_size)
|
||||
{
|
||||
@@ -1419,6 +1428,9 @@ static void update_attribute_element_size(Mesh *mesh,
|
||||
else if(mattr->type == TypeDesc::TypeFloat) {
|
||||
*attr_float_size += size;
|
||||
}
|
||||
else if(mattr->type == TypeFloat2) {
|
||||
*attr_float2_size += size;
|
||||
}
|
||||
else if(mattr->type == TypeDesc::TypeMatrix) {
|
||||
*attr_float3_size += size * 4;
|
||||
}
|
||||
@@ -1431,6 +1443,8 @@ static void update_attribute_element_size(Mesh *mesh,
|
||||
static void update_attribute_element_offset(Mesh *mesh,
|
||||
device_vector<float>& attr_float,
|
||||
size_t& attr_float_offset,
|
||||
device_vector<float2>& attr_float2,
|
||||
size_t& attr_float2_offset,
|
||||
device_vector<float4>& attr_float3,
|
||||
size_t& attr_float3_offset,
|
||||
device_vector<uchar4>& attr_uchar4,
|
||||
@@ -1477,6 +1491,16 @@ static void update_attribute_element_offset(Mesh *mesh,
|
||||
}
|
||||
attr_float_offset += size;
|
||||
}
|
||||
else if(mattr->type == TypeFloat2) {
|
||||
float2 *data = mattr->data_float2();
|
||||
offset = attr_float2_offset;
|
||||
|
||||
assert(attr_float2.size() >= offset + size);
|
||||
for(size_t k = 0; k < size; k++) {
|
||||
attr_float2[offset+k] = data[k];
|
||||
}
|
||||
attr_float2_offset += size;
|
||||
}
|
||||
else if(mattr->type == TypeDesc::TypeMatrix) {
|
||||
Transform *tfm = mattr->data_transform();
|
||||
offset = attr_float3_offset;
|
||||
@@ -1561,6 +1585,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
* take 2x of overall attribute memory usage.
|
||||
*/
|
||||
size_t attr_float_size = 0;
|
||||
size_t attr_float2_size = 0;
|
||||
size_t attr_float3_size = 0;
|
||||
size_t attr_uchar4_size = 0;
|
||||
for(size_t i = 0; i < scene->meshes.size(); i++) {
|
||||
@@ -1575,28 +1600,33 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
triangle_mattr,
|
||||
ATTR_PRIM_TRIANGLE,
|
||||
&attr_float_size,
|
||||
&attr_float2_size,
|
||||
&attr_float3_size,
|
||||
&attr_uchar4_size);
|
||||
update_attribute_element_size(mesh,
|
||||
curve_mattr,
|
||||
ATTR_PRIM_CURVE,
|
||||
&attr_float_size,
|
||||
&attr_float2_size,
|
||||
&attr_float3_size,
|
||||
&attr_uchar4_size);
|
||||
update_attribute_element_size(mesh,
|
||||
subd_mattr,
|
||||
ATTR_PRIM_SUBD,
|
||||
&attr_float_size,
|
||||
&attr_float2_size,
|
||||
&attr_float3_size,
|
||||
&attr_uchar4_size);
|
||||
}
|
||||
}
|
||||
|
||||
dscene->attributes_float.alloc(attr_float_size);
|
||||
dscene->attributes_float2.alloc(attr_float2_size);
|
||||
dscene->attributes_float3.alloc(attr_float3_size);
|
||||
dscene->attributes_uchar4.alloc(attr_uchar4_size);
|
||||
|
||||
size_t attr_float_offset = 0;
|
||||
size_t attr_float2_offset = 0;
|
||||
size_t attr_float3_offset = 0;
|
||||
size_t attr_uchar4_offset = 0;
|
||||
|
||||
@@ -1614,6 +1644,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
|
||||
update_attribute_element_offset(mesh,
|
||||
dscene->attributes_float, attr_float_offset,
|
||||
dscene->attributes_float2, attr_float2_offset,
|
||||
dscene->attributes_float3, attr_float3_offset,
|
||||
dscene->attributes_uchar4, attr_uchar4_offset,
|
||||
triangle_mattr,
|
||||
@@ -1623,6 +1654,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
|
||||
update_attribute_element_offset(mesh,
|
||||
dscene->attributes_float, attr_float_offset,
|
||||
dscene->attributes_float2, attr_float2_offset,
|
||||
dscene->attributes_float3, attr_float3_offset,
|
||||
dscene->attributes_uchar4, attr_uchar4_offset,
|
||||
curve_mattr,
|
||||
@@ -1632,6 +1664,7 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
|
||||
update_attribute_element_offset(mesh,
|
||||
dscene->attributes_float, attr_float_offset,
|
||||
dscene->attributes_float2, attr_float2_offset,
|
||||
dscene->attributes_float3, attr_float3_offset,
|
||||
dscene->attributes_uchar4, attr_uchar4_offset,
|
||||
subd_mattr,
|
||||
@@ -1657,6 +1690,9 @@ void MeshManager::device_update_attributes(Device *device, DeviceScene *dscene,
|
||||
if(dscene->attributes_float.size()) {
|
||||
dscene->attributes_float.copy_to_device();
|
||||
}
|
||||
if(dscene->attributes_float2.size()) {
|
||||
dscene->attributes_float2.copy_to_device();
|
||||
}
|
||||
if(dscene->attributes_float3.size()) {
|
||||
dscene->attributes_float3.copy_to_device();
|
||||
}
|
||||
@@ -2289,6 +2325,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
|
||||
dscene->patches.free();
|
||||
dscene->attributes_map.free();
|
||||
dscene->attributes_float.free();
|
||||
dscene->attributes_float2.free();
|
||||
dscene->attributes_float3.free();
|
||||
dscene->attributes_uchar4.free();
|
||||
|
||||
|
@@ -231,6 +231,9 @@ public:
|
||||
if(attr.same_storage(attr.type, TypeDesc::TypeFloat)) {
|
||||
primvar_refiner.Interpolate(i+1, (OsdValue<float>*)src, (OsdValue<float>*&)dest);
|
||||
}
|
||||
else if(attr.same_storage(attr.type, TypeFloat2)) {
|
||||
primvar_refiner.Interpolate(i+1, (OsdValue<float2>*)src, (OsdValue<float2>*&)dest);
|
||||
}
|
||||
else {
|
||||
primvar_refiner.Interpolate(i+1, (OsdValue<float4>*)src, (OsdValue<float4>*&)dest);
|
||||
}
|
||||
@@ -243,6 +246,10 @@ public:
|
||||
patch_table->ComputeLocalPointValues((OsdValue<float>*)&attr.buffer[0],
|
||||
(OsdValue<float>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
|
||||
}
|
||||
else if(attr.same_storage(attr.type, TypeFloat2)) {
|
||||
patch_table->ComputeLocalPointValues((OsdValue<float2>*)&attr.buffer[0],
|
||||
(OsdValue<float2>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
|
||||
}
|
||||
else {
|
||||
patch_table->ComputeLocalPointValues((OsdValue<float4>*)&attr.buffer[0],
|
||||
(OsdValue<float4>*)&attr.buffer[num_refiner_verts * attr.data_sizeof()]);
|
||||
|
@@ -3483,7 +3483,7 @@ void TextureCoordinateNode::compile(SVMCompiler& compiler)
|
||||
}
|
||||
else {
|
||||
int attr = compiler.attribute(ATTR_STD_UV);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3);
|
||||
compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -66,6 +66,7 @@ DeviceScene::DeviceScene(Device *device)
|
||||
camera_motion(device, "__camera_motion", MEM_TEXTURE),
|
||||
attributes_map(device, "__attributes_map", MEM_TEXTURE),
|
||||
attributes_float(device, "__attributes_float", MEM_TEXTURE),
|
||||
attributes_float2(device, "__attributes_float2", MEM_TEXTURE),
|
||||
attributes_float3(device, "__attributes_float3", MEM_TEXTURE),
|
||||
attributes_uchar4(device, "__attributes_uchar4", MEM_TEXTURE),
|
||||
light_distribution(device, "__light_distribution", MEM_TEXTURE),
|
||||
|
@@ -98,6 +98,7 @@ public:
|
||||
/* attributes */
|
||||
device_vector<uint4> attributes_map;
|
||||
device_vector<float> attributes_float;
|
||||
device_vector<float2> attributes_float2;
|
||||
device_vector<float4> attributes_float3;
|
||||
device_vector<uchar4> attributes_uchar4;
|
||||
|
||||
|
@@ -220,6 +220,12 @@ ccl_device_inline float2 interp(const float2& a, const float2& b, float t)
|
||||
{
|
||||
return a + t*(b - a);
|
||||
}
|
||||
|
||||
ccl_device_inline float2 mix(const float2& a, const float2& b, float t)
|
||||
{
|
||||
return a + t*(b - a);
|
||||
}
|
||||
|
||||
#endif /* !__KERNEL_OPENCL__ */
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -28,6 +28,8 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
OIIO_NAMESPACE_USING
|
||||
|
||||
static constexpr TypeDesc TypeFloat2(TypeDesc::FLOAT, TypeDesc::VEC2);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __UTIL_PARAM_H__ */
|
||||
|
Reference in New Issue
Block a user