OpenSubdiv
OpenSubdiv copied to clipboard
Some Questions about Edge Crease
-
Setting edge crease I have read the .obj like representation of coarse shapes and I cannot understand some parameters used to set edge creases. For example, in shape: catmark_cube_crease0.h:
"t crease 2/1/0 0 1 2.0\n"
, I am not sure what are the first three numbers (2/1/0) stands for. I know the following 0 1 stands for the ID of vertices (origin and end) and 2.0 stands for the strength of the crease. And"t interpolateboundary 1/0/0 2\n"
, I am not sure what the values stand for. I've checked the RenderMan's API for Subdivision Surface, but the grammar seems to be a little bit different. -
Support of general semi-sharp creases I read the paper "Subdivision Surface in Character Animation" by Pixar Animation Studio, 1998 (the paper can be found at: http://www.cs.rutgers.edu/~decarlo/readings/derose98.pdf) In the Appendix B of this paper, it mentioned that the crease sharpness can vary along the crease. I think that is a very useful feature for organic model representation (e.g., Figure 10 in this paper). Intuitively, I think this feature can be realised by dividing one single crease into pieces and assign varying crease values to each pieces. So I wonder is general semi-sharp crease representation supported in OpenSubdiv and if yes how to setting a varying sharpness edge in file.
-
The Course Note of Siggraph 2013 Course OpenSubdiv From Research to Industry Adoption I knew this course from Pixar's graphics portal. (http://s2013.siggraph.org/attendees/courses/events/opensubdiv-research-industry-adoption) However I didn't go to Siggraph 2013. I really want to read this course notes. Will the course note be freely published on the page of OpenSubdiv or provide purchasing from ACM's online Library later?
Thanks for your time. Tyler
Unless I'm mistaken the 2/1/0 is the subdivision path to the edge to change the crease on. So go to the facet number 2 in the course mesh, of the children of that facet go to the second face (index 1) for subdivision 1, then of that facet go to the first facet(index 0) of next level of subdivision. In this face find the edge that goes from vertex 0 to vertex
- Set the crease there to 2.0. Basically this is demonstrating that the crease sharpness of any arbitrary edge, at any level subdivision can be targeted and edited. There is a better explanation in the documentation on the Hierarchical Subdivision Mesh in the RenderMan or in OpenSubdiv docs themselves. I think this means that yes you can vary the sharpness of a course/base edge along its length.
On Sun, Aug 11, 2013 at 3:05 AM, Tyler Zhu [email protected] wrote:
Setting edge crease I have read the .obj like representation of coarse shapes and I cannot understand some parameters used to set edge creases. For example, in shape: catmark_cube_crease0.h:
"t crease 2/1/0 0 1 2.0\n", I am not sure what are the first three numbers (2/1/0) stands for. I know the following 1 3 stands for the ID of vertices (origin and end) and 5.0 stands for the strength of the crease. And "t interpolateboundary 1/0/0 2\n", I am not sure what the values stand for. I've checked the RenderMan's API for Subdivision Surface, but the grammar seems to be a little bit different. 2.
Support of general semi-sharp creases I read the paper "Subdivision Surface in Character Animation" by Pixar Animation Studio, 1998 (the paper can be found at: http://www.cs.rutgers.edu/~decarlo/readings/derose98.pdf) In the Appendix B of this paper, it mentioned that the crease sharpness can vary along the crease. I think that is a very useful feature for organic model representation (e.g., Figure 10 in this paper). Intuitively, I think this feature can be realised by dividing one single crease into pieces and assign varying crease values to each pieces. So I wonder is general semi-sharp crease representation supported in OpenSubdiv and if yes how to setting a varying sharpness edge in file.
— Reply to this email directly or view it on GitHubhttps://github.com/PixarAnimationStudios/OpenSubdiv/issues/210 .
Thank you!I never thought about it that way.
However, It seems that the crease strength is assigned to whole single coarse edge (one of the cube's edge) instead of the edge in certain subdiv level , because I tried the following experiment:
In catmark_cube_crease0.h, I set all 12 edge's strength to infinite with the same prefix 2/1/0
"t crease 2/1/0 0 1 5.0\n" "t crease 2/1/0 1 3 5.0\n" "t crease 2/1/0 3 2 5.0\n" "t crease 2/1/0 2 0 5.0\n" "t crease 2/1/0 4 5 5.0\n" "t crease 2/1/0 5 7 5.0\n" "t crease 2/1/0 7 6 5.0\n" "t crease 2/1/0 6 4 5.0\n" "t crease 2/1/0 0 6 5.0\n" "t crease 2/1/0 1 7 5.0\n" "t crease 2/1/0 2 4 5.0\n" "t crease 2/1/0 3 5 5.0\n"
The result is that all the edges are become infinite sharp, so I think the sharpness is applied to the whole original coarse edges instead of the edges in subdiv process.
I look forward to further discussing with you. I will check renderman's document again more carefully tomorrow.
I by no means an expert on this. The authors can probably explain it better. It seems to me your test has issues though, as vertex index at subdivision level 2 should be higher than 3.
Check out these docs: http://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html#hierarchical-edits
On Sun, Aug 11, 2013 at 10:18 AM, Tyler Zhu [email protected]:
Thank you!I never thought this way.
However, It seems that the crease strength is assigned to whole single coarse edge (one of the cube's edge) instead of the edge in certain subdiv level , because I tried the following experiment:
In catmark_cube_crease0.h, I set all 12 edge's strength to infinite with the same prefix 2/1/0 "t crease 2/1/0 0 1 5.0\n" "t crease 2/1/0 1 3 5.0\n" "t crease 2/1/0 3 2 5.0\n" "t crease 2/1/0 2 0 5.0\n" "t crease 2/1/0 4 5 5.0\n" "t crease 2/1/0 5 7 5.0\n" "t crease 2/1/0 7 6 5.0\n" "t crease 2/1/0 6 4 5.0\n" "t crease 2/1/0 0 6 5.0\n" "t crease 2/1/0 1 7 5.0\n" "t crease 2/1/0 2 4 5.0\n" "t crease 2/1/0 3 5 5.0\n"
The result is that all the edges are become infinite sharp, so I think the sharpness is applied to the whole coarse edge instead of the edges in subdiv process.
I look forward to further discussing with you. I will check renderman's document again more carefully tomorrow.
— Reply to this email directly or view it on GitHubhttps://github.com/PixarAnimationStudios/OpenSubdiv/issues/210#issuecomment-22460241 .
Sorry I realize I left out a not, the vertex indices for the edge should * not* be higher than 3.
On Sun, Aug 11, 2013 at 10:28 AM, Christopher Jones [email protected]:
I by no means an expert on this. The authors can probably explain it better. It seems to me your test has issues though, as vertex index at subdivision level 2 should be higher than 3.
Check out these docs: http://graphics.pixar.com/opensubdiv/docs/subdivision_surfaces.html#hierarchical-edits
On Sun, Aug 11, 2013 at 10:18 AM, Tyler Zhu [email protected]:
Thank you!I never thought this way.
However, It seems that the crease strength is assigned to whole single coarse edge (one of the cube's edge) instead of the edge in certain subdiv level , because I tried the following experiment:
In catmark_cube_crease0.h, I set all 12 edge's strength to infinite with the same prefix 2/1/0 "t crease 2/1/0 0 1 5.0\n" "t crease 2/1/0 1 3 5.0\n" "t crease 2/1/0 3 2 5.0\n" "t crease 2/1/0 2 0 5.0\n" "t crease 2/1/0 4 5 5.0\n" "t crease 2/1/0 5 7 5.0\n" "t crease 2/1/0 7 6 5.0\n" "t crease 2/1/0 6 4 5.0\n" "t crease 2/1/0 0 6 5.0\n" "t crease 2/1/0 1 7 5.0\n" "t crease 2/1/0 2 4 5.0\n" "t crease 2/1/0 3 5 5.0\n"
The result is that all the edges are become infinite sharp, so I think the sharpness is applied to the whole coarse edge instead of the edges in subdiv process.
I look forward to further discussing with you. I will check renderman's document again more carefully tomorrow.
— Reply to this email directly or view it on GitHubhttps://github.com/PixarAnimationStudios/OpenSubdiv/issues/210#issuecomment-22460241 .
I think this usage is justified by the shape file: catmark_cube_crease1.h https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/regression/shapes/catmark_cube_creases1.h
So I think the prefix 2/1/0
may not mean the path to a edge. It might have other unknown meanings.
Ok, now I'm confused. To write a vertex edit path the vertex is at the end and its 0-3 because all facets at the 2nd subdivision level have 4 indices. I'm not sure why an edge edit can be higher than 3. Can anyone else clarify?
On Sun, Aug 11, 2013 at 10:44 AM, Tyler Zhu [email protected]:
I think this usage is justified by the shape file: *catmark_cube_crease1.h *
https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/regression/shapes/catmark_cube_creases1.h
— Reply to this email directly or view it on GitHubhttps://github.com/PixarAnimationStudios/OpenSubdiv/issues/210#issuecomment-22460698 .
After looking at http://renderman.pixar.com/resources/current/rps/hierarchsubdiv.html and the regression code that parses the shapes ( https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/regression/common/shape_utils.h ) I realized I read it wrong.
The "crease" statement is not an edit but a set up of the coarse mesh. So the 2/1/0 is actually like the renderman spec being 2 int arguments, 1 float argument and 0 string arguments. The first int argument is the first vertex of the edge, the second is the next vertex of the edge. Finally the float is the sharpness.
To edit a later generated edge you need to specify a Hierarchical edge edit to change it. See https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/regression/shapes/catmark_square_hedit3.h for an example of an hierarchical edge edit.
On Sun, Aug 11, 2013 at 10:52 AM, Christopher Jones [email protected]:
Ok, now I'm confused. To write a vertex edit path the vertex is at the end and its 0-3 because all facets at the 2nd subdivision level have 4 indices. I'm not sure why an edge edit can be higher than 3. Can anyone else clarify?
On Sun, Aug 11, 2013 at 10:44 AM, Tyler Zhu [email protected]:
I think this usage is justified by the shape file: * catmark_cube_crease1.h*
https://github.com/PixarAnimationStudios/OpenSubdiv/blob/master/regression/shapes/catmark_cube_creases1.h
— Reply to this email directly or view it on GitHubhttps://github.com/PixarAnimationStudios/OpenSubdiv/issues/210#issuecomment-22460698 .
You are correct:
2/1/0 translates:
- 2 integer arguments (the vert indices)
- 1 float argument (the sharpness)
- 0 string arguments
Most creases are not hierarchical, so a default "crease" flag is available for convenience and efficiency, that does not require a full h-path.
- Support of general semi-sharp creases
Yes Hbr supports hierarchical edge sharpness edit tags, and they should carry to both uniform and adaptive modes (although we currently do not have a test shape for it - but since they are edits, it "should just work"(tm), right ?). The code in shape_utils may be able to edit edges with those kinds of tags, although keep in mind that the current parser is incomplete compared to PRman's (sorry, i never intended to "enrich" the OBJ file format, and i would rather this code be buried before anyone got too creative with it...). Also: hierarchical-anything tends to be quite expensive...
- The Course Note of Siggraph 2013 Course OpenSubdiv From Research to Industry Adoption
That's a good question actually - i will check what the status is wrt/ who owns what copyright and what our options are. This would require some work on our end too, as we would have to convert multi-media slide decks... No promises.
Thank you so much!
Yes, the hierarchical sharpness edit tag can be attached to edges and vertices in subdivision level.
e.g., In catmark_cube_crease0.h
"t vertexedit 20/16/6 4 4 1 1 0 4 4 1 1 1 4 4 1 1 2 4 4 1 1 3 0 0 1 10 0 0 1 10 0 0 1 10 0 0 1 10 add P value set P sharpness\n"
"t edgeedit 20/4/3 4 4 1 1 0 4 4 1 1 1 4 4 1 1 2 4 4 1 1 3 5 5 5 5 set P sharpness\n"
They are supported!
Actually we do have bugs in adaptive mode:
# This file uses centimeters as units for non-parametric coordinates.
v 0.000000 -1.414214 1.000000
v 1.414214 0.000000 1.000000
v -1.414214 0.000000 1.000000
v 0.000000 1.414214 1.000000
v -1.414214 0.000000 -1.000000
v 0.000000 1.414214 -1.000000
v 0.000000 -1.414214 -1.000000
v 1.414214 0.000000 -1.000000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.125000 0.000000
vt 0.125000 0.250000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn -0.707107 0.707107 0.000000
vn -0.707107 0.707107 0.000000
vn -0.707107 0.707107 0.000000
vn -0.707107 0.707107 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.707107 -0.707107 0.000000
vn 0.707107 -0.707107 0.000000
vn 0.707107 -0.707107 0.000000
vn 0.707107 -0.707107 0.000000
vn 0.707107 0.707107 0.000000
vn 0.707107 0.707107 0.000000
vn 0.707107 0.707107 0.000000
vn 0.707107 0.707107 0.000000
vn -0.707107 -0.707107 0.000000
vn -0.707107 -0.707107 0.000000
vn -0.707107 -0.707107 0.000000
vn -0.707107 -0.707107 0.000000
s off
f 1/1/1 2/2/2 4/4/3 3/3/4
f 3/3/5 4/4/6 6/6/7 5/5/8
f 5/5/9 6/6/10 8/8/11 7/7/12
f 7/7/13 8/8/14 2/10/15 1/9/16
f 2/2/17 8/11/18 6/12/19 4/4/20
f 7/13/21 1/1/22 3/3/23 5/14/24
t edgeedit 20/4/3 4 4 1 1 0 4 4 1 1 1 4 4 1 1 2 4 4 1 1 3 5 5 5 5 set P sharpness
By observing the image you upload, I notice that there is a crack around hierarchically edited creases and a narrow crack at the bottom. Is it possible that the crease strength which is added between certain subdivision levels may interfere with the feature detection process?
In order to explore this interesting bug, I have switched from OS X ( currently not support Feature Adaptive Subdivision) to Windows 8 with ATI driver. However, I have just encountered another problem: the approximation patches around the irregular point are not rendered (fig.1) Guess I will have to spend some time on this problem... I am now reading the shaders written in GLSL400.
fig.1
This looks like missing Gregory patches, which is not an entirely unusual problem as the shaders are significantly heavier than the other patches and we have had a number of problems getting them to work. In ATI's particular case, we have observed that the late HD generation of cards works well with adaptive, but Gregory patch shaders fail to compile properly on previous generations, which is a likely candidate for what you are seeing.
This is really a strange problem with ATI cards. I am reading the shaders (vertex, tessellation control, tessellation evaluation) of the B-spline patch, Transition patch and Gregory patch. I also read two papers: Approximation Subdivision Surfaces with Gregory Patches for Hardware Tessellation(http://faculty.cse.tamu.edu/schaefer/research/greg.pdf) and Feature Adaptive GPU Rendering of Catmull-Clark Subdivision Surfaces(http://research.microsoft.com/en-us/um/people/cloop/tog2012.pdf).
I have difficulty in understanding glslPatchTransition.glsl. I know it needs to deal with 5 possible constellations, but I cannot find codes to evaluate the actual gl_position of the transition patch. Instead only UV is returned. Is the UV need to be passed to other shaders in order to get the xyz position of Transition Patch?
Transition patches are broken down into 3 or 4 regular BSpline patch draw calls depending on pattern constellation. For all intents and purposes, they behave exactly like glslPatchBSpline, only with slightly altered local UV parameters.
If you look in glslPatchBSpline.glsl you will find the calls to SetTransitionTessLevels( ) and GetTransitionSubpatchUV( ) encased inside #ifdefs. The rest of the magic is hidden in the OsdDrawRegistry which activates these code paths for each shader type (look at glDrawRegistry.cpp around line 150).
Does this help ?
Yes, it is very helpful. I read glDrawRegistry.cpp. Now I realize that glslPatchBSpline.glsl and glslPatchTransition.glsl are combined to render transition patch.
I don't catch up with the method used to compute the edge points of Gregory Patch.
In vertex shader of glslPatchGregory.glsl, we need to calculate: vec3 position // the limit position a the vertex vec3 e0 // used later in tessellation control shader to calculate Ep and Em, which is Gregory Edge Control Points vec3 e1 // used later in tessellation control shader to calculate Ep and Em, which is Gregory Edge Control Points
Then Tessellation Control shader is launched. Suppose the Tessellation Control Shader of glslPatchGregory.glsl is launched on this gregory patch (gl_primitiveID = 4) with the gl_InvocationID = 3 (corresponding to the bottom vertex v3)
The following figure is a layout of Gregory Patch and suppose pi corresponds to vi above.
I am afraid that the notation used in this layout figure ( from the paper Approximation Subdivision Surfaces with Gregory Patches for Hardware Tessellation) is not consistent with that used in gregory patch shaders, which might cause some ambiguity in my statement below. So I add some notation to this figure.
In tessellation control shader Ep and Em is calculated by the following computing formula:
vec3 Ep = inpt[i].v.position + inpt[i].v.e0 * csf(n-3, 2*start) + inpt[i].v.e1*csf(n-3, 2*start + 1);
vec3 Em = inpt[i].v.position + inpt[i].v.e0 * csf(n-3, 2*prev ) + inpt[i].v.e1*csf(n-3, 2*prev + 1);
Since we suppose gl_InvocationID = 3, so i = gl_InvocationID = 3
start and prev are from a precomputed table OsdQuadOffsetBuffer which describes a mapping: vertex index of gregory quad --> the edge index around the vertex inpt[i].v.position is the limit position of v3 which is the p3 control vertex on Gregroy Patch layout figure inpt[i].v.e0 and inpt[i].v.e1 is computed in vertex shader by:
vec3 e;
outpt.v.e0 = vec3(0,0,0);
outpt.v.e1 = vec3(0,0,0);
for(uint i=0; i<valence; ++i) {
uint im = (i + valence -1) % valence;
e = 0.5f * (f[i] + f[im]);
outpt.v.e0 += csf(valence-3, 2*i) *e;
outpt.v.e1 += csf(valence-3, 2*i + 1)*e;
}
outpt.v.e0 *= ef[valence - 3];
outpt.v.e1 *= ef[valence - 3];
ef is a precomputed table for a function whose variable is the valence of a vertex. f[i] is computed by:
f[i] = (pos * float(valence) + (neighbor_p + neighbor)*2.0f + diagonal) / (float(valence)+5.0f);
Focus on Em's calculation (since Ep is very similar) and convert it to Mathematics Symbol:
(j is the edge index, that is to say j = prev)
Substitue into it the expression of e0 and e1 used in vertex shader:
using formula: cos(α-β) = cosαcosβ+sinαsinβ then I get:
As previously mentioned:
f[i] = (pos * float(valence) + (neighbor_p + neighbor)*2.0f + diagonal) / (float(valence)+5.0f);
However this formular to compute Em is quite different from the formula described in paper Approximation Subdivision Surfaces with Gregory Patches for Hardware Tessellation:
where
Filed as internal issue #151679.