PixarAnimationStudios / OpenSubdiv

An Open-Source subdivision surface library.
graphics.pixar.com/opensubdiv
Other
2.86k stars 557 forks source link

Some Questions about Edge Crease #210

Open ghost opened 10 years ago

ghost commented 10 years ago
  1. 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.

  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.
  3. 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

cjones2244 commented 10 years ago

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

  1. 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 notifications@github.com wrote:

1.

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 .

ghost commented 10 years ago

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.

cjones2244 commented 10 years ago

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 notifications@github.comwrote:

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_cubecrease0.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 .

cjones2244 commented 10 years ago

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 cwjones2244@gmail.comwrote:

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 notifications@github.comwrote:

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_cubecrease0.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 .

ghost commented 10 years ago

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.

cjones2244 commented 10 years ago

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 notifications@github.comwrote:

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 .

cjones2244 commented 10 years ago

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 cwjones2244@gmail.comwrote:

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 notifications@github.comwrote:

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 .

manuelk commented 10 years ago

You are correct:

2/1/0 translates:

Most creases are not hierarchical, so a default "crease" flag is available for convenience and efficiency, that does not require a full h-path.

  1. 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...

  1. 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.

ghost commented 10 years ago

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!

manuelk commented 10 years ago

Actually we do have bugs in adaptive mode: hcrease_bug

# 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
ghost commented 10 years ago

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.

1 fig.1

manuelk commented 10 years ago

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.

ghost commented 10 years ago

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?

manuelk commented 10 years ago

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 ?

ghost commented 10 years ago

Yes, it is very helpful. I read glDrawRegistry.cpp. Now I realize that glslPatchBSpline.glsl and glslPatchTransition.glsl are combined to render transition patch.

ghost commented 10 years ago

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) gregoryshadervariables

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. screen shot 2013-08-22 at 10 08 39 am

screen shot 2013-08-22 at 10 08 39 am

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: codecogseqn-2 (j is the edge index, that is to say j = prev)

Substitue into it the expression of e0 and e1 used in vertex shader: codecogseqn-2 copy

codecogseqn-3

using formula: cos(α-β) = cosαcosβ+sinαsinβ then I get:

codecogseqn-2 copy 2

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:

codecogseqn copy 2

where codecogseqn copy

jtran56 commented 6 years ago

Filed as internal issue #151679.