Cycles: add ptex face ID and UV attributes.
Not the most memory efficient way to store these things but it's simple and implementing it better requires some work to natively support subd grids as a primitive in some way.
This commit is contained in:
@@ -393,11 +393,16 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, PointerR
|
|||||||
/* finalize subd mesh */
|
/* finalize subd mesh */
|
||||||
sdmesh.finish();
|
sdmesh.finish();
|
||||||
|
|
||||||
SubdParams sdparams(mesh, used_shaders[0], true);
|
/* parameters */
|
||||||
|
bool need_ptex = mesh->need_attribute(scene, ATTR_STD_PTEX_FACE_ID) ||
|
||||||
|
mesh->need_attribute(scene, ATTR_STD_PTEX_UV);
|
||||||
|
|
||||||
|
SubdParams sdparams(mesh, used_shaders[0], true, need_ptex);
|
||||||
sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate");
|
sdparams.dicing_rate = RNA_float_get(cmesh, "dicing_rate");
|
||||||
//scene->camera->update();
|
//scene->camera->update();
|
||||||
//sdparams.camera = scene->camera;
|
//sdparams.camera = scene->camera;
|
||||||
|
|
||||||
|
/* tesselate */
|
||||||
DiagSplit dsplit(sdparams);;
|
DiagSplit dsplit(sdparams);;
|
||||||
sdmesh.tessellate(&dsplit);
|
sdmesh.tessellate(&dsplit);
|
||||||
}
|
}
|
||||||
|
@@ -89,6 +89,25 @@ ccl_device float3 primitive_uv(KernelGlobals *kg, ShaderData *sd)
|
|||||||
return uv;
|
return uv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccl_device bool primitive_ptex(KernelGlobals *kg, ShaderData *sd, float2 *uv, int *face_id)
|
||||||
|
{
|
||||||
|
/* storing ptex data as attributes is not memory efficient but simple for tests */
|
||||||
|
AttributeElement elem_face_id, elem_uv;
|
||||||
|
int offset_face_id = find_attribute(kg, sd, ATTR_STD_PTEX_FACE_ID, &elem_face_id);
|
||||||
|
int offset_uv = find_attribute(kg, sd, ATTR_STD_PTEX_UV, &elem_uv);
|
||||||
|
|
||||||
|
if(offset_face_id == ATTR_STD_NOT_FOUND || offset_uv == ATTR_STD_NOT_FOUND)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float3 uv3 = primitive_attribute_float3(kg, sd, elem_uv, offset_uv, NULL, NULL);
|
||||||
|
float face_id_f = primitive_attribute_float(kg, sd, elem_face_id, offset_face_id, NULL, NULL);
|
||||||
|
|
||||||
|
*uv = make_float2(uv3.x, uv3.y);
|
||||||
|
*face_id = (int)face_id_f;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
|
ccl_device float3 primitive_tangent(KernelGlobals *kg, ShaderData *sd)
|
||||||
{
|
{
|
||||||
#ifdef __HAIR__
|
#ifdef __HAIR__
|
||||||
|
@@ -436,6 +436,8 @@ typedef enum AttributeStandard {
|
|||||||
ATTR_STD_MOTION_POST,
|
ATTR_STD_MOTION_POST,
|
||||||
ATTR_STD_PARTICLE,
|
ATTR_STD_PARTICLE,
|
||||||
ATTR_STD_CURVE_INTERCEPT,
|
ATTR_STD_CURVE_INTERCEPT,
|
||||||
|
ATTR_STD_PTEX_FACE_ID,
|
||||||
|
ATTR_STD_PTEX_UV,
|
||||||
ATTR_STD_NUM,
|
ATTR_STD_NUM,
|
||||||
|
|
||||||
ATTR_STD_NOT_FOUND = ~0
|
ATTR_STD_NOT_FOUND = ~0
|
||||||
|
@@ -147,6 +147,10 @@ const char *Attribute::standard_name(AttributeStandard std)
|
|||||||
return "particle";
|
return "particle";
|
||||||
else if(std == ATTR_STD_CURVE_INTERCEPT)
|
else if(std == ATTR_STD_CURVE_INTERCEPT)
|
||||||
return "curve_intercept";
|
return "curve_intercept";
|
||||||
|
else if(std == ATTR_STD_PTEX_FACE_ID)
|
||||||
|
return "ptex_face_id";
|
||||||
|
else if(std == ATTR_STD_PTEX_UV)
|
||||||
|
return "ptex_uv";
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -246,6 +250,12 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
|
|||||||
case ATTR_STD_MOTION_POST:
|
case ATTR_STD_MOTION_POST:
|
||||||
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
|
||||||
break;
|
break;
|
||||||
|
case ATTR_STD_PTEX_FACE_ID:
|
||||||
|
attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_FACE);
|
||||||
|
break;
|
||||||
|
case ATTR_STD_PTEX_UV:
|
||||||
|
attr = add(name, TypeDesc::TypePoint, ATTR_ELEMENT_VERTEX);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
@@ -34,6 +34,11 @@ EdgeDice::EdgeDice(const SubdParams& params_)
|
|||||||
vert_offset = 0;
|
vert_offset = 0;
|
||||||
|
|
||||||
params.mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
|
params.mesh->attributes.add(ATTR_STD_VERTEX_NORMAL);
|
||||||
|
|
||||||
|
if(params.ptex) {
|
||||||
|
params.mesh->attributes.add(ATTR_STD_PTEX_UV);
|
||||||
|
params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeDice::reserve(int num_verts, int num_tris)
|
void EdgeDice::reserve(int num_verts, int num_tris)
|
||||||
@@ -63,12 +68,29 @@ int EdgeDice::add_vert(Patch *patch, float2 uv)
|
|||||||
mesh_P[vert_offset] = P;
|
mesh_P[vert_offset] = P;
|
||||||
mesh_N[vert_offset] = N;
|
mesh_N[vert_offset] = N;
|
||||||
|
|
||||||
|
if(params.ptex) {
|
||||||
|
Attribute *attr_ptex_uv = params.mesh->attributes.add(ATTR_STD_PTEX_UV);
|
||||||
|
params.mesh->attributes.reserve();
|
||||||
|
|
||||||
|
float3 *ptex_uv = attr_ptex_uv->data_float3();
|
||||||
|
ptex_uv[vert_offset] = make_float3(uv.x, uv.y, 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
return vert_offset++;
|
return vert_offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
|
void EdgeDice::add_triangle(Patch *patch, int v0, int v1, int v2)
|
||||||
{
|
{
|
||||||
params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth);
|
params.mesh->add_triangle(v0, v1, v2, params.shader, params.smooth);
|
||||||
|
|
||||||
|
if(params.ptex) {
|
||||||
|
Attribute *attr_ptex_face_id = params.mesh->attributes.add(ATTR_STD_PTEX_FACE_ID);
|
||||||
|
params.mesh->attributes.reserve();
|
||||||
|
|
||||||
|
float *ptex_face_id = attr_ptex_face_id->data_float();
|
||||||
|
ptex_face_id[tri_offset] = (float)patch->ptex_face_id();
|
||||||
|
}
|
||||||
|
|
||||||
tri_offset++;
|
tri_offset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,17 +35,19 @@ struct SubdParams {
|
|||||||
Mesh *mesh;
|
Mesh *mesh;
|
||||||
int shader;
|
int shader;
|
||||||
bool smooth;
|
bool smooth;
|
||||||
|
bool ptex;
|
||||||
|
|
||||||
int test_steps;
|
int test_steps;
|
||||||
int split_threshold;
|
int split_threshold;
|
||||||
float dicing_rate;
|
float dicing_rate;
|
||||||
Camera *camera;
|
Camera *camera;
|
||||||
|
|
||||||
SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true)
|
SubdParams(Mesh *mesh_, int shader_, bool smooth_ = true, bool ptex_ = false)
|
||||||
{
|
{
|
||||||
mesh = mesh_;
|
mesh = mesh_;
|
||||||
shader = shader_;
|
shader = shader_;
|
||||||
smooth = smooth_;
|
smooth = smooth_;
|
||||||
|
ptex = ptex_;
|
||||||
|
|
||||||
test_steps = 3;
|
test_steps = 3;
|
||||||
split_threshold = 1;
|
split_threshold = 1;
|
||||||
|
@@ -28,6 +28,7 @@ public:
|
|||||||
virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) = 0;
|
virtual void eval(float3 *P, float3 *dPdu, float3 *dPdv, float u, float v) = 0;
|
||||||
virtual bool is_triangle() { return false; }
|
virtual bool is_triangle() { return false; }
|
||||||
virtual BoundBox bound() = 0;
|
virtual BoundBox bound() = 0;
|
||||||
|
virtual int ptex_face_id() { return -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Linear Quad Patch */
|
/* Linear Quad Patch */
|
||||||
|
Reference in New Issue
Block a user