mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-08 21:30:06 +00:00
Merge pull request #1113 from davidgyu/gregory_transitional_fix
Thanks, David
This commit is contained in:
commit
692949fc87
@ -1237,7 +1237,7 @@ PatchTableBuilder::populatePatches() {
|
||||
PatchParam patchParam =
|
||||
_patchBuilder->ComputePatchParam(patch.levelIndex, patch.faceIndex,
|
||||
_ptexIndices, patchInfo.isRegular, patchInfo.paramBoundaryMask,
|
||||
patchInfo.isRegular /* condition to compute transition mask */);
|
||||
true/* condition to compute transition mask */);
|
||||
*arrayBuilder->pptr++ = patchParam;
|
||||
|
||||
//
|
||||
|
@ -88,12 +88,6 @@ void main()
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier cpBezier[16];
|
||||
#if 0
|
||||
// XXX: this doesn't work on nvidia driver 34x.
|
||||
for (int i=0; i<16; ++i) {
|
||||
cpBezier[i] = outpt[i].v;
|
||||
}
|
||||
#else
|
||||
cpBezier[0] = outpt[0].v;
|
||||
cpBezier[1] = outpt[1].v;
|
||||
cpBezier[2] = outpt[2].v;
|
||||
@ -110,7 +104,7 @@ void main()
|
||||
cpBezier[13] = outpt[13].v;
|
||||
cpBezier[14] = outpt[14].v;
|
||||
cpBezier[15] = outpt[15].v;
|
||||
#endif
|
||||
|
||||
OsdEvalPatchBezierTessLevels(cpBezier, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
@ -143,7 +143,7 @@ void main()
|
||||
cv[i] = inpt[i].v;
|
||||
}
|
||||
|
||||
vec2 UV = OsdGetTessParameterizationTriangle(gl_TessCoord.xy,
|
||||
vec2 UV = OsdGetTessParameterizationTriangle(gl_TessCoord.xyz,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
|
@ -993,17 +993,17 @@ OsdEvalPatchGregory(ivec3 patchParam, vec2 UV, vec3 cv[20],
|
||||
// The equivalant quartic Bezier triangle (15 points):
|
||||
//
|
||||
// 14
|
||||
// . .
|
||||
// . .
|
||||
// . .
|
||||
// . .
|
||||
// 12 --- 13
|
||||
// . . . .
|
||||
// . . . .
|
||||
// . . . .
|
||||
// . . . .
|
||||
// 9 -- 10 --- 11
|
||||
// . . . . . .
|
||||
// . . . . . .
|
||||
// . . . . . .
|
||||
// . . . . . .
|
||||
// 5 --- 6 --- 7 --- 8
|
||||
// . . . . . . . .
|
||||
// . . . . . . . .
|
||||
// . . . . . . . .
|
||||
// . . . . . . . .
|
||||
// 0 --- 1 --- 2 --- 3 --- 4
|
||||
//
|
||||
// A hybrid cubic/quartic Bezier patch with cubic boundaries is a close
|
||||
|
@ -507,7 +507,6 @@ OsdGetTessLevelsUniform(ivec3 patchParam,
|
||||
out vec4 tessLevelOuter, out vec2 tessLevelInner,
|
||||
out vec4 tessOuterLo, out vec4 tessOuterHi)
|
||||
{
|
||||
// uniform tessellation
|
||||
OsdGetTessLevelsUniform(patchParam, tessOuterLo, tessOuterHi);
|
||||
|
||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
||||
@ -519,7 +518,6 @@ OsdGetTessLevelsUniformTriangle(ivec3 patchParam,
|
||||
out vec4 tessLevelOuter, out vec2 tessLevelInner,
|
||||
out vec4 tessOuterLo, out vec4 tessOuterHi)
|
||||
{
|
||||
// uniform tessellation
|
||||
OsdGetTessLevelsUniformTriangle(patchParam, tessOuterLo, tessOuterHi);
|
||||
|
||||
OsdComputeTessLevelsTriangle(tessOuterLo, tessOuterHi,
|
||||
@ -586,6 +584,7 @@ OsdGetTessLevelsAdaptiveLimitPoints(OsdPerPatchVertexBezier cpBezier[16],
|
||||
tessLevelOuter, tessLevelInner);
|
||||
}
|
||||
|
||||
// Deprecated -- prefer use of newer Bezier patch equivalent:
|
||||
void
|
||||
OsdGetTessLevels(vec3 cp0, vec3 cp1, vec3 cp2, vec3 cp3,
|
||||
ivec3 patchParam,
|
||||
@ -697,38 +696,37 @@ OsdGetTessTransitionSplit(float t, float lo, float hi)
|
||||
}
|
||||
|
||||
vec2
|
||||
OsdGetTessParameterization(vec2 uv, vec4 tessOuterLo, vec4 tessOuterHi)
|
||||
OsdGetTessParameterization(vec2 p, vec4 tessOuterLo, vec4 tessOuterHi)
|
||||
{
|
||||
vec2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
vec2 UV = p;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.x == 1 && tessOuterHi[2] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
||||
} else
|
||||
if (UV.y == 1 && tessOuterHi[3] > 0) {
|
||||
if (p.y == 1 && tessOuterHi[3] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
||||
vec2
|
||||
OsdGetTessParameterizationTriangle(vec2 uv, vec4 tessOuterLo, vec4 tessOuterHi)
|
||||
OsdGetTessParameterizationTriangle(vec3 p, vec4 tessOuterLo, vec4 tessOuterHi)
|
||||
{
|
||||
vec2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
vec2 UV = p.xy;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x+UV.y == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.z == 0 && tessOuterHi[2] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[2], tessOuterHi[2]);
|
||||
UV.y = 1.0 - UV.x;
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,8 @@ void main()
|
||||
//----------------------------------------------------------
|
||||
#ifdef OSD_PATCH_TESS_CONTROL_GREGORY_SHADER
|
||||
|
||||
patch out vec4 tessOuterLo, tessOuterHi;
|
||||
|
||||
in block {
|
||||
OsdPerVertexGregory v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
@ -73,14 +75,43 @@ void main()
|
||||
|
||||
OSD_USER_VARYING_PER_CONTROL_POINT(gl_InvocationID, gl_InvocationID);
|
||||
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Wait for all basis conversion to be finished
|
||||
barrier();
|
||||
#endif
|
||||
if (gl_InvocationID == 0) {
|
||||
vec4 tessLevelOuter = vec4(0);
|
||||
vec2 tessLevelInner = vec2(0);
|
||||
|
||||
OSD_PATCH_CULL(4);
|
||||
|
||||
OsdGetTessLevels(cv[0].P, cv[3].P, cv[2].P, cv[1].P,
|
||||
patchParam, tessLevelOuter, tessLevelInner);
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier bezcv[16];
|
||||
bezcv[ 0].P = outpt[0].v.P;
|
||||
bezcv[ 1].P = outpt[0].v.Ep;
|
||||
bezcv[ 2].P = outpt[1].v.Em;
|
||||
bezcv[ 3].P = outpt[1].v.P;
|
||||
bezcv[ 4].P = outpt[0].v.Em;
|
||||
bezcv[ 5].P = outpt[0].v.Fp;
|
||||
bezcv[ 6].P = outpt[1].v.Fm;
|
||||
bezcv[ 7].P = outpt[1].v.Ep;
|
||||
bezcv[ 8].P = outpt[3].v.Ep;
|
||||
bezcv[ 9].P = outpt[3].v.Fm;
|
||||
bezcv[10].P = outpt[2].v.Fp;
|
||||
bezcv[11].P = outpt[2].v.Em;
|
||||
bezcv[12].P = outpt[3].v.P;
|
||||
bezcv[13].P = outpt[3].v.Em;
|
||||
bezcv[14].P = outpt[2].v.Ep;
|
||||
bezcv[15].P = outpt[2].v.P;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(bezcv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(patchParam, tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
gl_TessLevelOuter[0] = tessLevelOuter[0];
|
||||
gl_TessLevelOuter[1] = tessLevelOuter[1];
|
||||
@ -102,6 +133,8 @@ void main()
|
||||
layout(quads) in;
|
||||
layout(OSD_SPACING) in;
|
||||
|
||||
patch in vec4 tessOuterLo, tessOuterHi;
|
||||
|
||||
in block {
|
||||
OsdPerPatchVertexGregory v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
@ -142,7 +175,10 @@ void main()
|
||||
cv[18] = inpt[3].v.Fp;
|
||||
cv[19] = inpt[3].v.Fm;
|
||||
|
||||
vec2 UV = gl_TessCoord.xy;
|
||||
vec2 UV = OsdGetTessParameterization(gl_TessCoord.xy,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
ivec3 patchParam = inpt[0].v.patchParam;
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -49,6 +49,8 @@ void main()
|
||||
//----------------------------------------------------------
|
||||
#ifdef OSD_PATCH_TESS_CONTROL_GREGORY_BASIS_SHADER
|
||||
|
||||
patch out vec4 tessOuterLo, tessOuterHi;
|
||||
|
||||
in block {
|
||||
ControlVertex v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
@ -66,7 +68,8 @@ void main()
|
||||
vec3 cv = inpt[gl_InvocationID].v.position.xyz;
|
||||
|
||||
ivec3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(gl_PrimitiveID));
|
||||
OsdComputePerPatchVertexGregoryBasis(patchParam, gl_InvocationID, cv, outpt[gl_InvocationID].v);
|
||||
OsdComputePerPatchVertexGregoryBasis(
|
||||
patchParam, gl_InvocationID, cv, outpt[gl_InvocationID].v);
|
||||
|
||||
OSD_USER_VARYING_PER_CONTROL_POINT(gl_InvocationID, gl_InvocationID);
|
||||
|
||||
@ -76,9 +79,36 @@ void main()
|
||||
|
||||
OSD_PATCH_CULL(20);
|
||||
|
||||
OsdGetTessLevels(inpt[0].v.position.xyz, inpt[15].v.position.xyz,
|
||||
inpt[10].v.position.xyz, inpt[5].v.position.xyz,
|
||||
patchParam, tessLevelOuter, tessLevelInner);
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier bezcv[16];
|
||||
bezcv[ 0].P = inpt[ 0].v.position.xyz;
|
||||
bezcv[ 1].P = inpt[ 1].v.position.xyz;
|
||||
bezcv[ 2].P = inpt[ 7].v.position.xyz;
|
||||
bezcv[ 3].P = inpt[ 5].v.position.xyz;
|
||||
bezcv[ 4].P = inpt[ 2].v.position.xyz;
|
||||
bezcv[ 5].P = inpt[ 3].v.position.xyz;
|
||||
bezcv[ 6].P = inpt[ 8].v.position.xyz;
|
||||
bezcv[ 7].P = inpt[ 6].v.position.xyz;
|
||||
bezcv[ 8].P = inpt[16].v.position.xyz;
|
||||
bezcv[ 9].P = inpt[18].v.position.xyz;
|
||||
bezcv[10].P = inpt[13].v.position.xyz;
|
||||
bezcv[11].P = inpt[12].v.position.xyz;
|
||||
bezcv[12].P = inpt[15].v.position.xyz;
|
||||
bezcv[13].P = inpt[17].v.position.xyz;
|
||||
bezcv[14].P = inpt[11].v.position.xyz;
|
||||
bezcv[15].P = inpt[10].v.position.xyz;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
bezcv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(
|
||||
patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
gl_TessLevelOuter[0] = tessLevelOuter[0];
|
||||
gl_TessLevelOuter[1] = tessLevelOuter[1];
|
||||
@ -100,6 +130,8 @@ void main()
|
||||
layout(quads) in;
|
||||
layout(OSD_SPACING) in;
|
||||
|
||||
patch in vec4 tessOuterLo, tessOuterHi;
|
||||
|
||||
in block {
|
||||
OsdPerPatchVertexGregoryBasis v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
@ -120,7 +152,10 @@ void main()
|
||||
cv[i] = inpt[i].v.P;
|
||||
}
|
||||
|
||||
vec2 UV = gl_TessCoord.xy;
|
||||
vec2 UV = OsdGetTessParameterization(gl_TessCoord.xy,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
ivec3 patchParam = inpt[0].v.patchParam;
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -57,7 +57,7 @@ in block {
|
||||
} inpt[];
|
||||
|
||||
out block {
|
||||
OsdPerPatchVertexBezier v;
|
||||
OsdPerPatchVertexGregoryBasis v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} outpt[18];
|
||||
|
||||
@ -68,54 +68,45 @@ void main()
|
||||
vec3 cv = inpt[gl_InvocationID].v.position.xyz;
|
||||
|
||||
ivec3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(gl_PrimitiveID));
|
||||
|
||||
outpt[gl_InvocationID].v.patchParam = patchParam;
|
||||
outpt[gl_InvocationID].v.P = cv;
|
||||
OsdComputePerPatchVertexGregoryBasis(
|
||||
patchParam, gl_InvocationID, cv, outpt[gl_InvocationID].v);
|
||||
|
||||
OSD_USER_VARYING_PER_CONTROL_POINT(gl_InvocationID, gl_InvocationID);
|
||||
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Wait for all basis conversion to be finished
|
||||
barrier();
|
||||
#endif
|
||||
if (gl_InvocationID == 0) {
|
||||
vec4 tessLevelOuter = vec4(0);
|
||||
vec2 tessLevelInner = vec2(0);
|
||||
|
||||
OSD_PATCH_CULL(18);
|
||||
|
||||
OsdGetTessLevelsUniformTriangle(patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
vec3 cv[15];
|
||||
cv[ 0] = outpt[ 0].v.P;
|
||||
cv[ 1] = outpt[ 1].v.P;
|
||||
cv[ 2] = outpt[15].v.P;
|
||||
cv[ 3] = outpt[ 7].v.P;
|
||||
cv[ 4] = outpt[ 5].v.P;
|
||||
cv[ 5] = outpt[ 2].v.P;
|
||||
cv[ 6] = outpt[ 3].v.P;
|
||||
cv[ 7] = outpt[ 8].v.P;
|
||||
cv[ 8] = outpt[ 6].v.P;
|
||||
cv[ 9] = outpt[17].v.P;
|
||||
cv[10] = outpt[13].v.P;
|
||||
cv[11] = outpt[16].v.P;
|
||||
cv[12] = outpt[11].v.P;
|
||||
cv[13] = outpt[12].v.P;
|
||||
cv[14] = outpt[10].v.P;
|
||||
cv[ 0] = inpt[ 0].v.position.xyz;
|
||||
cv[ 1] = inpt[ 1].v.position.xyz;
|
||||
cv[ 2] = inpt[15].v.position.xyz;
|
||||
cv[ 3] = inpt[ 7].v.position.xyz;
|
||||
cv[ 4] = inpt[ 5].v.position.xyz;
|
||||
cv[ 5] = inpt[ 2].v.position.xyz;
|
||||
cv[ 6] = inpt[ 3].v.position.xyz;
|
||||
cv[ 7] = inpt[ 8].v.position.xyz;
|
||||
cv[ 8] = inpt[ 6].v.position.xyz;
|
||||
cv[ 9] = inpt[17].v.position.xyz;
|
||||
cv[10] = inpt[13].v.position.xyz;
|
||||
cv[11] = inpt[16].v.position.xyz;
|
||||
cv[12] = inpt[11].v.position.xyz;
|
||||
cv[13] = inpt[12].v.position.xyz;
|
||||
cv[14] = inpt[10].v.position.xyz;
|
||||
|
||||
OsdEvalPatchBezierTriangleTessLevels(
|
||||
cv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
cv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniformTriangle(patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
||||
OsdGetTessLevelsUniformTriangle(
|
||||
patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
gl_TessLevelOuter[0] = tessLevelOuter[0];
|
||||
@ -139,7 +130,7 @@ layout(OSD_SPACING) in;
|
||||
patch in vec4 tessOuterLo, tessOuterHi;
|
||||
|
||||
in block {
|
||||
OsdPerPatchVertexBezier v;
|
||||
OsdPerPatchVertexGregoryBasis v;
|
||||
OSD_USER_VARYING_DECLARE
|
||||
} inpt[];
|
||||
|
||||
@ -150,10 +141,6 @@ out block {
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 UV = OsdGetTessParameterizationTriangle(gl_TessCoord.xy,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
vec3 P = vec3(0), dPu = vec3(0), dPv = vec3(0);
|
||||
vec3 N = vec3(0), dNu = vec3(0), dNv = vec3(0);
|
||||
|
||||
@ -162,6 +149,10 @@ void main()
|
||||
cv[i] = inpt[i].v.P;
|
||||
}
|
||||
|
||||
vec2 UV = OsdGetTessParameterizationTriangle(gl_TessCoord.xyz,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
ivec3 patchParam = inpt[0].v.patchParam;
|
||||
OsdEvalPatchGregoryTriangle(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -78,13 +78,7 @@ HSConstFunc(
|
||||
OSD_PATCH_CULL(16);
|
||||
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
#if 0
|
||||
// XXX: this doesn't work on nvidia driver 34x.
|
||||
OsdEvalPatchBezierTessLevels(bezierPatch, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
// This is needed to coerce correct behavior on nvidia driver 34x
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier cpBezier[16];
|
||||
for (int i=0; i<16; ++i) {
|
||||
cpBezier[i] = bezierPatch[i];
|
||||
@ -93,7 +87,6 @@ HSConstFunc(
|
||||
OsdEvalPatchBezierTessLevels(cpBezier, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
#else
|
||||
OsdGetTessLevelsUniform(patchParam, tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
@ -121,7 +121,7 @@ void ds_main_patches(
|
||||
cv[i] = patch[i];
|
||||
}
|
||||
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord.xy,
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord,
|
||||
input.tessOuterLo,
|
||||
input.tessOuterHi);
|
||||
|
||||
|
@ -458,7 +458,7 @@ OsdComputeBoxSplineTriangleBoundaryPoints(inout float3 cpt[12], int3 patchParam)
|
||||
if (boundaryMask == 0) return;
|
||||
|
||||
int upperBits = (boundaryMask >> 3) & 0x3;
|
||||
int lowerBits = boundaryMask & 0x7;
|
||||
int lowerBits = boundaryMask & 7;
|
||||
|
||||
int eBits = lowerBits;
|
||||
int vBits = 0;
|
||||
@ -881,7 +881,7 @@ OsdEvalPatchBezier(int3 patchParam, float2 UV,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// GregoryBasis
|
||||
// Gregory Basis
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct OsdPerPatchVertexGregoryBasis {
|
||||
|
@ -602,6 +602,7 @@ OsdGetTessLevelsAdaptiveLimitPoints(OsdPerPatchVertexBezier cpBezier[16],
|
||||
tessLevelOuter, tessLevelInner);
|
||||
}
|
||||
|
||||
// Deprecated -- prefer use of newer Bezier patch equivalent:
|
||||
void
|
||||
OsdGetTessLevels(float3 cp0, float3 cp1, float3 cp2, float3 cp3,
|
||||
int3 patchParam,
|
||||
@ -713,38 +714,37 @@ OsdGetTessTransitionSplit(float t, float lo, float hi)
|
||||
}
|
||||
|
||||
float2
|
||||
OsdGetTessParameterization(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
||||
OsdGetTessParameterization(float2 p, float4 tessOuterLo, float4 tessOuterHi)
|
||||
{
|
||||
float2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
float2 UV = p;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.x == 1 && tessOuterHi[2] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
||||
} else
|
||||
if (UV.y == 1 && tessOuterHi[3] > 0) {
|
||||
if (p.y == 1 && tessOuterHi[3] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
||||
float2
|
||||
OsdGetTessParameterizationTriangle(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
||||
OsdGetTessParameterizationTriangle(float3 p, float4 tessOuterLo, float4 tessOuterHi)
|
||||
{
|
||||
float2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
float2 UV = p.xy;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x+UV.y == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.z == 0 && tessOuterHi[2] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[2], tessOuterHi[2]);
|
||||
UV.y = 1.0 - UV.x;
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ OsdPerPatchVertexGregory hs_main_patches(
|
||||
|
||||
HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
InputPatch<OsdPerVertexGregory, 4> patch,
|
||||
OutputPatch<OsdPerPatchVertexGregory, 4> gregoryPatch,
|
||||
uint primitiveID : SV_PrimitiveID)
|
||||
{
|
||||
HS_CONSTANT_FUNC_OUT output;
|
||||
@ -71,11 +72,39 @@ HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
|
||||
float4 tessLevelOuter = float4(0,0,0,0);
|
||||
float2 tessLevelInner = float2(0,0);
|
||||
float4 tessOuterLo = float4(0,0,0,0);
|
||||
float4 tessOuterHi = float4(0,0,0,0);
|
||||
|
||||
OSD_PATCH_CULL(4);
|
||||
|
||||
OsdGetTessLevels(patch[0].P, patch[3].P, patch[2].P, patch[1].P,
|
||||
patchParam, tessLevelOuter, tessLevelInner);
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier bezcv[16];
|
||||
bezcv[ 0].P = gregoryPatch[0].P;
|
||||
bezcv[ 1].P = gregoryPatch[0].Ep;
|
||||
bezcv[ 2].P = gregoryPatch[1].Em;
|
||||
bezcv[ 3].P = gregoryPatch[1].P;
|
||||
bezcv[ 4].P = gregoryPatch[0].Em;
|
||||
bezcv[ 5].P = gregoryPatch[0].Fp;
|
||||
bezcv[ 6].P = gregoryPatch[1].Fm;
|
||||
bezcv[ 7].P = gregoryPatch[1].Ep;
|
||||
bezcv[ 8].P = gregoryPatch[3].Ep;
|
||||
bezcv[ 9].P = gregoryPatch[3].Fm;
|
||||
bezcv[10].P = gregoryPatch[2].Fp;
|
||||
bezcv[11].P = gregoryPatch[2].Em;
|
||||
bezcv[12].P = gregoryPatch[3].P;
|
||||
bezcv[13].P = gregoryPatch[3].Em;
|
||||
bezcv[14].P = gregoryPatch[2].Ep;
|
||||
bezcv[15].P = gregoryPatch[2].P;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(bezcv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(patchParam, tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
||||
#endif
|
||||
|
||||
output.tessLevelOuter[0] = tessLevelOuter[0];
|
||||
output.tessLevelOuter[1] = tessLevelOuter[1];
|
||||
@ -85,8 +114,9 @@ HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
output.tessLevelInner[0] = tessLevelInner[0];
|
||||
output.tessLevelInner[1] = tessLevelInner[1];
|
||||
|
||||
output.tessOuterLo = float4(0,0,0,0);
|
||||
output.tessOuterHi = float4(0,0,0,0);
|
||||
output.tessOuterLo = tessOuterLo;
|
||||
output.tessOuterHi = tessOuterHi;
|
||||
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -99,7 +129,7 @@ HS_CONSTANT_FUNC_OUT HSConstFunc(
|
||||
void ds_main_patches(
|
||||
in HS_CONSTANT_FUNC_OUT input,
|
||||
in OutputPatch<OsdPerPatchVertexGregory, 4> patch,
|
||||
in float2 UV : SV_DomainLocation,
|
||||
in float2 domainCoord : SV_DomainLocation,
|
||||
out OutputVertex output )
|
||||
{
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
@ -130,6 +160,10 @@ void ds_main_patches(
|
||||
cv[18] = patch[3].Fp;
|
||||
cv[19] = patch[3].Fm;
|
||||
|
||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||
input.tessOuterLo,
|
||||
input.tessOuterHi);
|
||||
|
||||
int3 patchParam = patch[0].patchParam;
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -73,9 +73,36 @@ HSConstFunc(
|
||||
|
||||
OSD_PATCH_CULL(20);
|
||||
|
||||
OsdGetTessLevels(patch[0].position.xyz, patch[15].position.xyz,
|
||||
patch[10].position.xyz, patch[5].position.xyz,
|
||||
patchParam, tessLevelOuter, tessLevelInner);
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
OsdPerPatchVertexBezier bezcv[16];
|
||||
bezcv[ 0].P = patch[ 0].position.xyz;
|
||||
bezcv[ 1].P = patch[ 1].position.xyz;
|
||||
bezcv[ 2].P = patch[ 7].position.xyz;
|
||||
bezcv[ 3].P = patch[ 5].position.xyz;
|
||||
bezcv[ 4].P = patch[ 2].position.xyz;
|
||||
bezcv[ 5].P = patch[ 3].position.xyz;
|
||||
bezcv[ 6].P = patch[ 8].position.xyz;
|
||||
bezcv[ 7].P = patch[ 6].position.xyz;
|
||||
bezcv[ 8].P = patch[16].position.xyz;
|
||||
bezcv[ 9].P = patch[18].position.xyz;
|
||||
bezcv[10].P = patch[13].position.xyz;
|
||||
bezcv[11].P = patch[12].position.xyz;
|
||||
bezcv[12].P = patch[15].position.xyz;
|
||||
bezcv[13].P = patch[17].position.xyz;
|
||||
bezcv[14].P = patch[11].position.xyz;
|
||||
bezcv[15].P = patch[10].position.xyz;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
bezcv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(
|
||||
patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
output.tessLevelOuter[0] = tessLevelOuter[0];
|
||||
output.tessLevelOuter[1] = tessLevelOuter[1];
|
||||
@ -85,6 +112,9 @@ HSConstFunc(
|
||||
output.tessLevelInner[0] = tessLevelInner[0];
|
||||
output.tessLevelInner[1] = tessLevelInner[1];
|
||||
|
||||
output.tessOuterLo = tessOuterLo;
|
||||
output.tessOuterHi = tessOuterHi;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -96,7 +126,7 @@ HSConstFunc(
|
||||
void ds_main_patches(
|
||||
in HS_CONSTANT_FUNC_OUT input,
|
||||
in OutputPatch<OsdPerPatchVertexGregoryBasis, 20> patch,
|
||||
in float2 UV : SV_DomainLocation,
|
||||
in float2 domainCoord : SV_DomainLocation,
|
||||
out OutputVertex output )
|
||||
{
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
@ -107,6 +137,10 @@ void ds_main_patches(
|
||||
cv[i] = patch[i].P;
|
||||
}
|
||||
|
||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||
input.tessOuterLo,
|
||||
input.tessOuterHi);
|
||||
|
||||
int3 patchParam = patch[0].patchParam;
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -42,19 +42,17 @@ void vs_main_patches( in InputVertex input,
|
||||
[outputtopology("triangle_cw")]
|
||||
[outputcontrolpoints(18)]
|
||||
[patchconstantfunc("HSConstFunc")]
|
||||
OsdPerPatchVertexBezier hs_main_patches(
|
||||
OsdPerPatchVertexGregoryBasis hs_main_patches(
|
||||
in InputPatch<HullVertex, 18> patch,
|
||||
uint primitiveID : SV_PrimitiveID,
|
||||
in uint ID : SV_OutputControlPointID )
|
||||
{
|
||||
OsdPerPatchVertexBezier output;
|
||||
OsdPerPatchVertexGregoryBasis output;
|
||||
|
||||
float3 cv = patch[ID].position.xyz;
|
||||
|
||||
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
|
||||
|
||||
output.patchParam = patchParam;
|
||||
output.P = cv;
|
||||
OsdComputePerPatchVertexGregoryBasis(patchParam, ID, cv, output);
|
||||
|
||||
return output;
|
||||
}
|
||||
@ -62,7 +60,6 @@ OsdPerPatchVertexBezier hs_main_patches(
|
||||
HS_CONSTANT_FUNC_TRIANGLE_OUT
|
||||
HSConstFunc(
|
||||
InputPatch<HullVertex, 18> patch,
|
||||
OutputPatch<OsdPerPatchVertexBezier, 18> bezierPatch,
|
||||
uint primitiveID : SV_PrimitiveID)
|
||||
{
|
||||
HS_CONSTANT_FUNC_TRIANGLE_OUT output;
|
||||
@ -77,28 +74,33 @@ HSConstFunc(
|
||||
OSD_PATCH_CULL_TRIANGLE(18);
|
||||
|
||||
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
float3 cv[15];
|
||||
cv[ 0] = bezierPatch[ 0].P;
|
||||
cv[ 1] = bezierPatch[ 1].P;
|
||||
cv[ 2] = bezierPatch[15].P;
|
||||
cv[ 3] = bezierPatch[ 7].P;
|
||||
cv[ 4] = bezierPatch[ 5].P;
|
||||
cv[ 5] = bezierPatch[ 2].P;
|
||||
cv[ 6] = bezierPatch[ 3].P;
|
||||
cv[ 7] = bezierPatch[ 8].P;
|
||||
cv[ 8] = bezierPatch[ 6].P;
|
||||
cv[ 9] = bezierPatch[17].P;
|
||||
cv[10] = bezierPatch[13].P;
|
||||
cv[11] = bezierPatch[16].P;
|
||||
cv[12] = bezierPatch[11].P;
|
||||
cv[13] = bezierPatch[12].P;
|
||||
cv[14] = bezierPatch[10].P;
|
||||
OsdEvalPatchBezierTriangleTessLevels(cv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
cv[ 0] = patch[ 0].position.xyz;
|
||||
cv[ 1] = patch[ 1].position.xyz;
|
||||
cv[ 2] = patch[15].position.xyz;
|
||||
cv[ 3] = patch[ 7].position.xyz;
|
||||
cv[ 4] = patch[ 5].position.xyz;
|
||||
cv[ 5] = patch[ 2].position.xyz;
|
||||
cv[ 6] = patch[ 3].position.xyz;
|
||||
cv[ 7] = patch[ 8].position.xyz;
|
||||
cv[ 8] = patch[ 6].position.xyz;
|
||||
cv[ 9] = patch[17].position.xyz;
|
||||
cv[10] = patch[13].position.xyz;
|
||||
cv[11] = patch[16].position.xyz;
|
||||
cv[12] = patch[11].position.xyz;
|
||||
cv[13] = patch[12].position.xyz;
|
||||
cv[14] = patch[10].position.xyz;
|
||||
|
||||
OsdEvalPatchBezierTriangleTessLevels(
|
||||
cv, patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#else
|
||||
OsdGetTessLevelsUniformTriangle(patchParam, tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
OsdGetTessLevelsUniformTriangle(
|
||||
patchParam,
|
||||
tessLevelOuter, tessLevelInner,
|
||||
tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
output.tessLevelOuter[0] = tessLevelOuter[0];
|
||||
@ -124,10 +126,6 @@ void ds_main_patches(
|
||||
in float3 domainCoord : SV_DomainLocation,
|
||||
out OutputVertex output )
|
||||
{
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord.xy,
|
||||
input.tessOuterLo,
|
||||
input.tessOuterHi);
|
||||
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||
|
||||
@ -136,6 +134,10 @@ void ds_main_patches(
|
||||
cv[i] = patch[i].P;
|
||||
}
|
||||
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord,
|
||||
input.tessOuterLo,
|
||||
input.tessOuterHi);
|
||||
|
||||
int3 patchParam = patch[0].patchParam;
|
||||
OsdEvalPatchGregoryTriangle(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
|
@ -65,10 +65,10 @@ void OsdComputePerPatchBSplineFactors(
|
||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0,0,0,0);
|
||||
float2 tessLevelInner = float2(0,0);
|
||||
float4 tessOuterLo = float4(0,0,0,0);
|
||||
float4 tessOuterHi = float4(0,0,0,0);
|
||||
float4 tessLevelOuter = float4(0);
|
||||
float2 tessLevelInner = float2(0);
|
||||
float4 tessOuterLo = float4(0);
|
||||
float4 tessOuterHi = float4(0);
|
||||
|
||||
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
@ -121,7 +121,7 @@ void OsdComputePerPatchFactors(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
osdBuffer.perPatchVertexBuffer + patchID * CONTROL_POINTS_PER_PATCH,
|
||||
osdBuffer.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
||||
#if !USE_PTVS_FACTORS
|
||||
osdBuffer.patchTessBuffer[patchID],
|
||||
#endif
|
||||
@ -167,15 +167,15 @@ OsdPatchVertex ds_regular_patches(
|
||||
OsdGetTessLevelsUniform(tessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
float2 UV = OsdGetTessParameterization(domainCoord.xy,
|
||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P, dPu, dPv;
|
||||
float3 N, dNu, dNv;
|
||||
float2 vSegments;
|
||||
float3 P = float3(0), dPu = float3(0), dPv = float3(0);
|
||||
float3 N = float3(0), dNu = float3(0), dNv = float3(0);
|
||||
float2 vSegments = float2(0);
|
||||
|
||||
OsdEvalPatchBezier(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv, vSegments);
|
||||
|
||||
|
@ -65,10 +65,10 @@ void OsdComputePerPatchBezierTriangleFactors(
|
||||
device MTLTriangleTessellationFactorsHalf& triFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0,0,0,0);
|
||||
float2 tessLevelInner = float2(0,0);
|
||||
float4 tessOuterLo = float4(0,0,0,0);
|
||||
float4 tessOuterHi = float4(0,0,0,0);
|
||||
float4 tessLevelOuter = float4(0);
|
||||
float2 tessLevelInner = float2(0);
|
||||
float4 tessOuterLo = float4(0);
|
||||
float4 tessOuterHi = float4(0);
|
||||
|
||||
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
@ -76,6 +76,7 @@ void OsdComputePerPatchBezierTriangleFactors(
|
||||
for (int i=0; i<15; ++i) {
|
||||
bezcv[i] = patch[i].P;
|
||||
}
|
||||
|
||||
OsdEvalPatchBezierTriangleTessLevels(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
@ -172,14 +173,15 @@ OsdPatchVertex ds_regular_patches(
|
||||
tessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord.xy,
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P, dPu, dPv;
|
||||
float3 N, dNu, dNv;
|
||||
float3 P = float3(0), dPu = float3(0), dPv = float3(0);
|
||||
float3 N = float3(0), dNu = float3(0), dNv = float3(0);
|
||||
|
||||
OsdEvalPatchBezierTriangle(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
output.normal = N;
|
||||
|
@ -860,7 +860,6 @@ OsdComputePerPatchVertexBSpline(
|
||||
P += Q[j][k]*Hi[k];
|
||||
}
|
||||
|
||||
|
||||
result.P = P;
|
||||
result.P1 = P;
|
||||
result.P2 = P;
|
||||
@ -875,7 +874,6 @@ OsdComputePerPatchVertexBSpline(
|
||||
H[l] += Q[i][k] * (cv + l*4 + k)->GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result.P = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k){
|
||||
|
@ -34,11 +34,6 @@
|
||||
#undef OSD_FRACTIONAL_ODD_SPACING
|
||||
#endif
|
||||
|
||||
//Adjustments to the UV reparameterization can be defined here.
|
||||
#ifndef OSD_UV_CORRECTION
|
||||
#define OSD_UV_CORRECTION
|
||||
#endif
|
||||
|
||||
//
|
||||
// Organization of B-spline and Bezier control points.
|
||||
//
|
||||
@ -132,9 +127,9 @@ OsdGetTessLevelsUniform(const float OsdTessLevel, int3 patchParam,
|
||||
// tessLevels of transition edge should be clamped to 2.
|
||||
int transitionMask = OsdGetPatchTransitionMask(patchParam);
|
||||
float4 tessLevelMin = float4(1) + float4(((transitionMask & 8) >> 3),
|
||||
((transitionMask & 1) >> 0),
|
||||
((transitionMask & 2) >> 1),
|
||||
((transitionMask & 4) >> 2));
|
||||
((transitionMask & 1) >> 0),
|
||||
((transitionMask & 2) >> 1),
|
||||
((transitionMask & 4) >> 2));
|
||||
|
||||
tessOuterLo = max(float4(tessLevel), tessLevelMin);
|
||||
tessOuterHi = float4(0);
|
||||
@ -439,12 +434,56 @@ OsdEvalPatchBezierTessLevels(
|
||||
corners, midpoints, patchParam, tessOuterLo, tessOuterHi);
|
||||
}
|
||||
|
||||
void
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
const float OsdTessLevel,
|
||||
const float4x4 OsdProjectionMatrix,
|
||||
const float4x4 OsdModelViewMatrix,
|
||||
float3 cv[16],
|
||||
int3 patchParam,
|
||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||
{
|
||||
// Each edge of a transition patch is adjacent to one or two patches
|
||||
// at the next refined level of subdivision. When the patch control
|
||||
// points have been converted to the Bezier basis, the control points
|
||||
// at the four corners are on the limit surface (since a Bezier patch
|
||||
// interpolates its corner control points). We can compute an adaptive
|
||||
// tessellation level for transition edges on the limit surface by
|
||||
// evaluating a limit position at the mid point of each transition edge.
|
||||
|
||||
tessOuterLo = float4(0);
|
||||
tessOuterHi = float4(0);
|
||||
|
||||
float3 corners[4];
|
||||
float3 midpoints[4];
|
||||
|
||||
int transitionMask = OsdGetPatchTransitionMask(patchParam);
|
||||
|
||||
corners[0] = cv[ 0];
|
||||
corners[1] = cv[ 3];
|
||||
corners[2] = cv[15];
|
||||
corners[3] = cv[12];
|
||||
|
||||
midpoints[0] = ((transitionMask & 8) == 0) ? float3(0) :
|
||||
Osd_EvalBezierCurveMidPoint(cv[0], cv[4], cv[8], cv[12]);
|
||||
midpoints[1] = ((transitionMask & 1) == 0) ? float3(0) :
|
||||
Osd_EvalBezierCurveMidPoint(cv[0], cv[1], cv[2], cv[3]);
|
||||
midpoints[2] = ((transitionMask & 2) == 0) ? float3(0) :
|
||||
Osd_EvalBezierCurveMidPoint(cv[3], cv[7], cv[11], cv[15]);
|
||||
midpoints[3] = ((transitionMask & 4) == 0) ? float3(0) :
|
||||
Osd_EvalBezierCurveMidPoint(cv[12], cv[13], cv[14], cv[15]);
|
||||
|
||||
Osd_GetTessLevelsFromPatchBoundaries4(
|
||||
OsdTessLevel, OsdProjectionMatrix, OsdModelViewMatrix,
|
||||
corners, midpoints, patchParam, tessOuterLo, tessOuterHi);
|
||||
}
|
||||
|
||||
void
|
||||
OsdEvalPatchBezierTriangleTessLevels(
|
||||
const float OsdTessLevel,
|
||||
const float4x4 OsdProjectionMatrix,
|
||||
const float4x4 OsdModelViewMatrix,
|
||||
thread float3* cv,
|
||||
float3 cv[15],
|
||||
int3 patchParam,
|
||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||
{
|
||||
@ -571,8 +610,9 @@ OsdComputeTessLevels(thread float4& tessOuterLo, thread float4& tessOuterHi,
|
||||
}
|
||||
|
||||
void
|
||||
OsdComputeTessLevelsTriangle(thread float4& tessOuterLo, thread float4& tessOuterHi,
|
||||
thread float4& tessLevelOuter, thread float2& tessLevelInner)
|
||||
OsdComputeTessLevelsTriangle(
|
||||
thread float4& tessOuterLo, thread float4& tessOuterHi,
|
||||
thread float4& tessLevelOuter, thread float2& tessLevelInner)
|
||||
{
|
||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
||||
tessLevelOuter, tessLevelInner);
|
||||
@ -623,12 +663,32 @@ OsdEvalPatchBezierTessLevels(
|
||||
tessLevelOuter, tessLevelInner);
|
||||
}
|
||||
|
||||
void
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
const float OsdTessLevels,
|
||||
const float4x4 OsdProjectionMatrix,
|
||||
const float4x4 OsdModelViewMatrix,
|
||||
float3 cv[16],
|
||||
int3 patchParam,
|
||||
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||
{
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
OsdTessLevels,
|
||||
OsdProjectionMatrix, OsdModelViewMatrix,
|
||||
cv, patchParam,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
||||
OsdComputeTessLevels(tessOuterLo, tessOuterHi,
|
||||
tessLevelOuter, tessLevelInner);
|
||||
}
|
||||
|
||||
void
|
||||
OsdEvalPatchBezierTriangleTessLevels(
|
||||
const float OsdTessLevels,
|
||||
const float4x4 OsdProjectionMatrix,
|
||||
const float4x4 OsdModelViewMatrix,
|
||||
thread float3* cv,
|
||||
float3 cv[15],
|
||||
int3 patchParam,
|
||||
thread float4& tessLevelOuter, thread float2& tessLevelInner,
|
||||
thread float4& tessOuterLo, thread float4& tessOuterHi)
|
||||
@ -696,6 +756,7 @@ OsdGetTessLevelsAdaptiveLimitPoints(
|
||||
tessLevelOuter, tessLevelInner);
|
||||
}
|
||||
|
||||
// Deprecated -- prefer use of newer Bezier patch equivalent:
|
||||
void
|
||||
OsdGetTessLevels(
|
||||
const float OsdTessLevel,
|
||||
@ -764,7 +825,7 @@ OsdGetTessFractionalSplit(float t, float level, float levelUp)
|
||||
#endif
|
||||
|
||||
float
|
||||
OsdGetTessTransitionSplit(float t, float lo, float hi )
|
||||
OsdGetTessTransitionSplit(float t, float lo, float hi)
|
||||
{
|
||||
#if defined OSD_FRACTIONAL_EVEN_SPACING
|
||||
float loRoundUp = OsdRoundUpEven(lo);
|
||||
@ -788,11 +849,8 @@ OsdGetTessTransitionSplit(float t, float lo, float hi )
|
||||
// The +1 below is to account for the extra segment produced by the
|
||||
// tessellator since the sum of two odd tess levels will be rounded
|
||||
// up by one to the next odd integer tess level.
|
||||
float ti = (t * (loRoundUp + hiRoundUp + 1));
|
||||
float ti = round(t * (loRoundUp + hiRoundUp + 1));
|
||||
|
||||
OSD_UV_CORRECTION
|
||||
|
||||
ti = round(ti);
|
||||
if (ti <= loRoundUp) {
|
||||
float t0 = ti / loRoundUp;
|
||||
return OsdGetTessFractionalSplit(t0, lo, loRoundUp) * 0.5;
|
||||
@ -815,35 +873,35 @@ OsdGetTessTransitionSplit(float t, float lo, float hi )
|
||||
}
|
||||
|
||||
float2
|
||||
OsdGetTessParameterization(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
||||
OsdGetTessParameterization(float2 p, float4 tessOuterLo, float4 tessOuterHi)
|
||||
{
|
||||
float2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
float2 UV = p;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.x == 1 && tessOuterHi[2] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[2], tessOuterHi[2]);
|
||||
} else
|
||||
if (UV.y == 1 && tessOuterHi[3] > 0) {
|
||||
if (p.y == 1 && tessOuterHi[3] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[3], tessOuterHi[3]);
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
||||
float2
|
||||
OsdGetTessParameterizationTriangle(float2 uv, float4 tessOuterLo, float4 tessOuterHi)
|
||||
OsdGetTessParameterizationTriangle(float3 p, float4 tessOuterLo, float4 tessOuterHi)
|
||||
{
|
||||
float2 UV = uv;
|
||||
if (UV.x == 0 && tessOuterHi[0] > 0) {
|
||||
float2 UV = p.xy;
|
||||
if (p.x == 0 && tessOuterHi[0] > 0) {
|
||||
UV.y = OsdGetTessTransitionSplit(UV.y, tessOuterLo[0], tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && tessOuterHi[1] > 0) {
|
||||
if (p.y == 0 && tessOuterHi[1] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[1], tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x+UV.y == 1 && tessOuterHi[2] > 0) {
|
||||
if (p.z == 0 && tessOuterHi[2] > 0) {
|
||||
UV.x = OsdGetTessTransitionSplit(UV.x, tessOuterLo[2], tessOuterHi[2]);
|
||||
UV.y = 1.0 - UV.x;
|
||||
}
|
||||
|
@ -54,6 +54,77 @@ void OsdComputePerVertex(
|
||||
// Patches.Gregory.Factors
|
||||
//----------------------------------------------------------
|
||||
|
||||
void OsdComputePerPatchGregoryFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
float4x4 projectionMatrix,
|
||||
float4x4 modelViewMatrix,
|
||||
device OsdPerPatchVertexGregory* patchVertices,
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors& patchFactors,
|
||||
#endif
|
||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0);
|
||||
float2 tessLevelInner = float2(0);
|
||||
float4 tessOuterLo = float4(0);
|
||||
float4 tessOuterHi = float4(0);
|
||||
|
||||
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
float3 bezcv[16];
|
||||
bezcv[ 0] = patchVertices[0].P;
|
||||
bezcv[ 1] = patchVertices[0].Ep;
|
||||
bezcv[ 2] = patchVertices[1].Em;
|
||||
bezcv[ 3] = patchVertices[1].P;
|
||||
bezcv[ 4] = patchVertices[0].Em;
|
||||
bezcv[ 5] = patchVertices[0].Fp;
|
||||
bezcv[ 6] = patchVertices[1].Fm;
|
||||
bezcv[ 7] = patchVertices[1].Ep;
|
||||
bezcv[ 8] = patchVertices[3].Ep;
|
||||
bezcv[ 9] = patchVertices[3].Fm;
|
||||
bezcv[10] = patchVertices[2].Fp;
|
||||
bezcv[11] = patchVertices[2].Em;
|
||||
bezcv[12] = patchVertices[3].P;
|
||||
bezcv[13] = patchVertices[3].Em;
|
||||
bezcv[14] = patchVertices[2].Ep;
|
||||
bezcv[15] = patchVertices[2].P;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
bezcv,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner,
|
||||
tessOuterLo,
|
||||
tessOuterHi
|
||||
);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(
|
||||
tessLevel,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner,
|
||||
tessOuterLo,
|
||||
tessOuterHi
|
||||
);
|
||||
#endif
|
||||
|
||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||
quadFactors.edgeTessellationFactor[2] = tessLevelOuter[2];
|
||||
quadFactors.edgeTessellationFactor[3] = tessLevelOuter[3];
|
||||
quadFactors.insideTessellationFactor[0] = tessLevelInner[0];
|
||||
quadFactors.insideTessellationFactor[1] = tessLevelInner[1];
|
||||
#if !USE_PTVS_FACTORS
|
||||
patchFactors.tessOuterLo = tessOuterLo;
|
||||
patchFactors.tessOuterHi = tessOuterHi;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsdComputePerPatchFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
@ -65,28 +136,17 @@ void OsdComputePerPatchFactors(
|
||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0,0,0,0);
|
||||
float2 tessLevelInner = float2(0,0);
|
||||
|
||||
OsdGetTessLevels(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
patchVertices[0].P,
|
||||
patchVertices[3].P,
|
||||
patchVertices[2].P,
|
||||
patchVertices[1].P,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner
|
||||
);
|
||||
|
||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||
quadFactors.edgeTessellationFactor[2] = tessLevelOuter[2];
|
||||
quadFactors.edgeTessellationFactor[3] = tessLevelOuter[3];
|
||||
quadFactors.insideTessellationFactor[0] = tessLevelInner[0];
|
||||
quadFactors.insideTessellationFactor[1] = tessLevelInner[1];
|
||||
OsdComputePerPatchGregoryFactors(
|
||||
patchParam,
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
osdBuffer.perPatchVertexBuffer + patchID * VERTEX_CONTROL_POINTS_PER_PATCH,
|
||||
#if !USE_PTVS_FACTORS
|
||||
osdBuffer.patchTessBuffer[patchID],
|
||||
#endif
|
||||
quadFactors
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -117,42 +177,52 @@ void OsdComputePerPatchVertex(
|
||||
|
||||
template<typename PerPatchVertexGregory>
|
||||
OsdPatchVertex ds_gregory_patches(
|
||||
const float tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
float4 tessOuterLo,
|
||||
float4 tessOuterHi,
|
||||
#endif
|
||||
PerPatchVertexGregory patch,
|
||||
int3 patchParam,
|
||||
float2 domainCoord
|
||||
)
|
||||
{
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||
|
||||
float3 cv[20];
|
||||
cv[0] = patch[0].P;
|
||||
cv[1] = patch[0].Ep;
|
||||
cv[2] = patch[0].Em;
|
||||
cv[3] = patch[0].Fp;
|
||||
cv[4] = patch[0].Fm;
|
||||
|
||||
cv[5] = patch[1].P;
|
||||
cv[6] = patch[1].Ep;
|
||||
cv[7] = patch[1].Em;
|
||||
cv[8] = patch[1].Fp;
|
||||
cv[9] = patch[1].Fm;
|
||||
|
||||
cv[10] = patch[2].P;
|
||||
cv[11] = patch[2].Ep;
|
||||
cv[12] = patch[2].Em;
|
||||
cv[13] = patch[2].Fp;
|
||||
cv[14] = patch[2].Fm;
|
||||
|
||||
cv[15] = patch[3].P;
|
||||
cv[16] = patch[3].Ep;
|
||||
cv[17] = patch[3].Em;
|
||||
cv[18] = patch[3].Fp;
|
||||
cv[19] = patch[3].Fm;
|
||||
|
||||
float2 UV = domainCoord.xy;
|
||||
#if USE_PTVS_FACTORS
|
||||
float4 tessOuterLo(0), tessOuterHi(0);
|
||||
OsdGetTessLevelsUniform(tessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P = float3(0), dPu = float3(0), dPv = float3(0);
|
||||
float3 N = float3(0), dNu = float3(0), dNv = float3(0);
|
||||
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
// all code below here is client code
|
||||
@ -186,6 +256,16 @@ OsdPatchVertex OsdComputePatch(
|
||||
)
|
||||
{
|
||||
return ds_gregory_patches(
|
||||
tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.tessOuterLo,
|
||||
osdPatch.tessOuterHi,
|
||||
#else
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
|
||||
#endif
|
||||
#endif
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.cv,
|
||||
osdPatch.patchParam,
|
||||
|
@ -53,6 +53,77 @@ void OsdComputePerVertex(
|
||||
// Patches.GregoryBasis.Factors
|
||||
//----------------------------------------------------------
|
||||
|
||||
void OsdComputePerPatchGregoryFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
float4x4 projectionMatrix,
|
||||
float4x4 modelViewMatrix,
|
||||
threadgroup PatchVertexType* patchVertices,
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors& patchFactors,
|
||||
#endif
|
||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0);
|
||||
float2 tessLevelInner = float2(0);
|
||||
float4 tessOuterLo = float4(0);
|
||||
float4 tessOuterHi = float4(0);
|
||||
|
||||
#if OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// Gather bezier control points to compute limit surface tess levels
|
||||
float3 bezcv[16];
|
||||
bezcv[ 0] = patchVertices[ 0].position.xyz;
|
||||
bezcv[ 1] = patchVertices[ 1].position.xyz;
|
||||
bezcv[ 2] = patchVertices[ 7].position.xyz;
|
||||
bezcv[ 3] = patchVertices[ 5].position.xyz;
|
||||
bezcv[ 4] = patchVertices[ 2].position.xyz;
|
||||
bezcv[ 5] = patchVertices[ 3].position.xyz;
|
||||
bezcv[ 6] = patchVertices[ 8].position.xyz;
|
||||
bezcv[ 7] = patchVertices[ 6].position.xyz;
|
||||
bezcv[ 8] = patchVertices[16].position.xyz;
|
||||
bezcv[ 9] = patchVertices[18].position.xyz;
|
||||
bezcv[10] = patchVertices[13].position.xyz;
|
||||
bezcv[11] = patchVertices[12].position.xyz;
|
||||
bezcv[12] = patchVertices[15].position.xyz;
|
||||
bezcv[13] = patchVertices[17].position.xyz;
|
||||
bezcv[14] = patchVertices[11].position.xyz;
|
||||
bezcv[15] = patchVertices[10].position.xyz;
|
||||
|
||||
OsdEvalPatchBezierTessLevels(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
bezcv,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner,
|
||||
tessOuterLo,
|
||||
tessOuterHi
|
||||
);
|
||||
#else
|
||||
OsdGetTessLevelsUniform(
|
||||
tessLevel,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner,
|
||||
tessOuterLo,
|
||||
tessOuterHi
|
||||
);
|
||||
#endif
|
||||
|
||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||
quadFactors.edgeTessellationFactor[2] = tessLevelOuter[2];
|
||||
quadFactors.edgeTessellationFactor[3] = tessLevelOuter[3];
|
||||
quadFactors.insideTessellationFactor[0] = tessLevelInner[0];
|
||||
quadFactors.insideTessellationFactor[1] = tessLevelInner[1];
|
||||
#if !USE_PTVS_FACTORS
|
||||
patchFactors.tessOuterLo = tessOuterLo;
|
||||
patchFactors.tessOuterHi = tessOuterHi;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsdComputePerPatchFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
@ -64,28 +135,17 @@ void OsdComputePerPatchFactors(
|
||||
device MTLQuadTessellationFactorsHalf& quadFactors
|
||||
)
|
||||
{
|
||||
float4 tessLevelOuter = float4(0);
|
||||
float2 tessLevelInner = float2(0);
|
||||
|
||||
OsdGetTessLevels(
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
patchVertices[ 0].position.xyz,
|
||||
patchVertices[15].position.xyz,
|
||||
patchVertices[10].position.xyz,
|
||||
patchVertices[ 5].position.xyz,
|
||||
patchParam,
|
||||
tessLevelOuter,
|
||||
tessLevelInner
|
||||
);
|
||||
|
||||
quadFactors.edgeTessellationFactor[0] = tessLevelOuter[0];
|
||||
quadFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||
quadFactors.edgeTessellationFactor[2] = tessLevelOuter[2];
|
||||
quadFactors.edgeTessellationFactor[3] = tessLevelOuter[3];
|
||||
quadFactors.insideTessellationFactor[0] = tessLevelInner[0];
|
||||
quadFactors.insideTessellationFactor[1] = tessLevelInner[1];
|
||||
OsdComputePerPatchGregoryFactors(
|
||||
patchParam,
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
patchVertices,
|
||||
#if !USE_PTVS_FACTORS
|
||||
osdBuffer.patchTessBuffer[patchID],
|
||||
#endif
|
||||
quadFactors
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -115,6 +175,11 @@ void OsdComputePerPatchVertex(
|
||||
template<typename PerPatchVertexGregoryBasis>
|
||||
#endif
|
||||
OsdPatchVertex ds_gregory_basis_patches(
|
||||
const float tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
float4 tessOuterLo,
|
||||
float4 tessOuterHi,
|
||||
#endif
|
||||
#if USE_STAGE_IN
|
||||
PerPatchVertexGregoryBasis patch,
|
||||
#else
|
||||
@ -125,10 +190,6 @@ OsdPatchVertex ds_gregory_basis_patches(
|
||||
float2 domainCoord
|
||||
)
|
||||
{
|
||||
OsdPatchVertex output;
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||
|
||||
#if USE_STAGE_IN
|
||||
float3 cv[20];
|
||||
for(int i = 0; i < 20; i++)
|
||||
@ -153,7 +214,20 @@ OsdPatchVertex ds_gregory_basis_patches(
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float2 UV = domainCoord.xy;
|
||||
#if USE_PTVS_FACTORS
|
||||
float4 tessOuterLo(0), tessOuterHi(0);
|
||||
OsdGetTessLevelsUniform(tessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
float2 UV = OsdGetTessParameterization(domainCoord,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P = float3(0), dPu = float3(0), dPv = float3(0);
|
||||
float3 N = float3(0), dNu = float3(0), dNv = float3(0);
|
||||
|
||||
OsdEvalPatchGregory(patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
output.position = P;
|
||||
@ -186,6 +260,16 @@ OsdPatchVertex OsdComputePatch(
|
||||
)
|
||||
{
|
||||
return ds_gregory_basis_patches(
|
||||
tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.tessOuterLo,
|
||||
osdPatch.tessOuterHi,
|
||||
#else
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
|
||||
#endif
|
||||
#endif
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.cv,
|
||||
osdPatch.patchParam,
|
||||
|
@ -53,14 +53,15 @@ void OsdComputePerVertex(
|
||||
// Patches.GregoryTriangle.Factors
|
||||
//----------------------------------------------------------
|
||||
|
||||
void OsdComputePerPatchFactors(
|
||||
void OsdComputePerPatchGregoryTriangleFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
unsigned patchID,
|
||||
float4x4 projectionMatrix,
|
||||
float4x4 modelViewMatrix,
|
||||
OsdPatchParamBufferSet osdBuffer,
|
||||
threadgroup PatchVertexType* patchVertices,
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors& patchFactors,
|
||||
#endif
|
||||
device MTLTriangleTessellationFactorsHalf& triFactors
|
||||
)
|
||||
{
|
||||
@ -114,6 +115,34 @@ void OsdComputePerPatchFactors(
|
||||
triFactors.edgeTessellationFactor[1] = tessLevelOuter[1];
|
||||
triFactors.edgeTessellationFactor[2] = tessLevelOuter[2];
|
||||
triFactors.insideTessellationFactor = tessLevelInner[0];
|
||||
#if !USE_PTVS_FACTORS
|
||||
patchFactors.tessOuterLo = tessOuterLo;
|
||||
patchFactors.tessOuterHi = tessOuterHi;
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsdComputePerPatchFactors(
|
||||
int3 patchParam,
|
||||
float tessLevel,
|
||||
unsigned patchID,
|
||||
float4x4 projectionMatrix,
|
||||
float4x4 modelViewMatrix,
|
||||
OsdPatchParamBufferSet osdBuffer,
|
||||
threadgroup PatchVertexType* patchVertices,
|
||||
device MTLTriangleTessellationFactorsHalf& triFactors
|
||||
)
|
||||
{
|
||||
OsdComputePerPatchGregoryTriangleFactors(
|
||||
patchParam,
|
||||
tessLevel,
|
||||
projectionMatrix,
|
||||
modelViewMatrix,
|
||||
patchVertices,
|
||||
#if !USE_PTVS_FACTORS
|
||||
osdBuffer.patchTessBuffer[patchID],
|
||||
#endif
|
||||
triFactors
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
@ -140,6 +169,11 @@ void OsdComputePerPatchVertex(
|
||||
template<typename PerPatchVertexGregoryBasis>
|
||||
#endif
|
||||
OsdPatchVertex ds_gregory_triangle_patches(
|
||||
const float tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
float4 tessOuterLo,
|
||||
float4 tessOuterHi,
|
||||
#endif
|
||||
#if USE_STAGE_IN
|
||||
PerPatchVertexGregoryBasis patch,
|
||||
#else
|
||||
@ -150,10 +184,6 @@ OsdPatchVertex ds_gregory_triangle_patches(
|
||||
float3 domainCoord
|
||||
)
|
||||
{
|
||||
OsdPatchVertex output;
|
||||
float3 P = float3(0,0,0), dPu = float3(0,0,0), dPv = float3(0,0,0);
|
||||
float3 N = float3(0,0,0), dNu = float3(0,0,0), dNv = float3(0,0,0);
|
||||
|
||||
#if USE_STAGE_IN
|
||||
float3 cv[18];
|
||||
for(int i = 0; i < 18; i++)
|
||||
@ -165,7 +195,20 @@ OsdPatchVertex ds_gregory_triangle_patches(
|
||||
}
|
||||
#endif
|
||||
|
||||
float2 UV = domainCoord.xy;
|
||||
#if USE_PTVS_FACTORS
|
||||
float4 tessOuterLo(0), tessOuterHi(0);
|
||||
OsdGetTessLevelsUniform(tessLevel, patchParam, tessOuterLo, tessOuterHi);
|
||||
#endif
|
||||
|
||||
float2 UV = OsdGetTessParameterizationTriangle(domainCoord,
|
||||
tessOuterLo,
|
||||
tessOuterHi);
|
||||
|
||||
OsdPatchVertex output;
|
||||
|
||||
float3 P = float3(0), dPu = float3(0), dPv = float3(0);
|
||||
float3 N = float3(0), dNu = float3(0), dNv = float3(0);
|
||||
|
||||
OsdEvalPatchGregoryTriangle(
|
||||
patchParam, UV, cv, P, dPu, dPv, N, dNu, dNv);
|
||||
|
||||
@ -199,6 +242,16 @@ OsdPatchVertex OsdComputePatch(
|
||||
)
|
||||
{
|
||||
return ds_gregory_triangle_patches(
|
||||
tessLevel,
|
||||
#if !USE_PTVS_FACTORS
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.tessOuterLo,
|
||||
osdPatch.tessOuterHi,
|
||||
#else
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterLo,
|
||||
osdBuffers.patchTessBuffer[patchID].tessOuterHi,
|
||||
#endif
|
||||
#endif
|
||||
#if USE_STAGE_IN
|
||||
osdPatch.cv,
|
||||
osdPatch.patchParam,
|
||||
@ -210,4 +263,3 @@ OsdPatchVertex OsdComputePatch(
|
||||
domainCoord
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user