forked from bartvdbraak/blender
Merge branch 'blender2.7'
This commit is contained in:
commit
c891fb2fbe
@ -66,7 +66,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,7 @@ struct MikkUserData {
|
||||
int num_faces;
|
||||
|
||||
float3 *vertex_normal;
|
||||
float3 *texface;
|
||||
float2 *texface;
|
||||
float3 *orco;
|
||||
float3 orco_loc, orco_size;
|
||||
|
||||
@ -150,7 +150,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;
|
||||
}
|
||||
@ -435,13 +435,13 @@ static void attr_create_uv_map(Scene *scene,
|
||||
}
|
||||
|
||||
BL::Mesh::loop_triangles_iterator t;
|
||||
float3 *fdata = uv_attr->data_float3();
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
|
||||
for(b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
|
||||
int3 li = get_int3(t->loops());
|
||||
fdata[0] = get_float3(l->data[li[0]].uv());
|
||||
fdata[1] = get_float3(l->data[li[1]].uv());
|
||||
fdata[2] = get_float3(l->data[li[2]].uv());
|
||||
fdata[0] = get_float2(l->data[li[0]].uv());
|
||||
fdata[1] = get_float2(l->data[li[1]].uv());
|
||||
fdata[2] = get_float2(l->data[li[2]].uv());
|
||||
fdata += 3;
|
||||
}
|
||||
}
|
||||
@ -516,12 +516,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,7 +363,15 @@ 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) {
|
||||
attribute_value = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1209,6 +1209,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;
|
||||
|
||||
@ -1318,6 +1320,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;
|
||||
|
||||
@ -1335,6 +1339,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;
|
||||
|
||||
@ -1352,6 +1358,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;
|
||||
|
||||
@ -1380,6 +1388,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)
|
||||
{
|
||||
@ -1395,6 +1404,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;
|
||||
}
|
||||
@ -1407,6 +1419,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,
|
||||
@ -1453,6 +1467,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;
|
||||
@ -1537,6 +1561,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++) {
|
||||
@ -1551,28 +1576,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;
|
||||
|
||||
@ -1590,6 +1620,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,
|
||||
@ -1599,6 +1630,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,
|
||||
@ -1608,6 +1640,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,
|
||||
@ -1633,6 +1666,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();
|
||||
}
|
||||
@ -2265,6 +2301,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()]);
|
||||
|
@ -3480,7 +3480,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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user