Merge pull request #1113 from davidgyu/gregory_transitional_fix

Thanks, David
This commit is contained in:
Barry Fowler 2019-06-04 09:57:54 -07:00 committed by GitHub
commit 692949fc87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 644 additions and 253 deletions

View File

@ -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;
//

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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){

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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
);
}