mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-12-29 03:01:24 +00:00
Updated HLSL shaders for unified patch drawing
This commit is contained in:
parent
963d952c7b
commit
9f1da077e8
@ -89,13 +89,16 @@ D3D11DrawRegistryBase::_CreateDrawSourceConfig(
|
||||
case Far::PatchDescriptor::CORNER:
|
||||
sconfig->commonShader.AddDefine("OSD_PATCH_BSPLINE");
|
||||
sconfig->commonShader.AddDefine("OSD_PATCH_ENABLE_SINGLE_CREASE");
|
||||
sconfig->vertexShader.source = bsplineShaderSource;
|
||||
sconfig->vertexShader.source =
|
||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||
sconfig->vertexShader.target = "vs_5_0";
|
||||
sconfig->vertexShader.entry = "vs_main_patches";
|
||||
sconfig->hullShader.source = bsplineShaderSource;
|
||||
sconfig->hullShader.source =
|
||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||
sconfig->hullShader.target = "hs_5_0";
|
||||
sconfig->hullShader.entry = "hs_main_patches";
|
||||
sconfig->domainShader.source = bsplineShaderSource;
|
||||
sconfig->domainShader.source =
|
||||
std::string(transitionShaderSource) + bsplineShaderSource;
|
||||
sconfig->domainShader.target = "ds_5_0";
|
||||
sconfig->domainShader.entry = "ds_main_patches";
|
||||
break;
|
||||
|
@ -22,12 +22,6 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
#define HS_DOMAIN "tri"
|
||||
#else
|
||||
#define HS_DOMAIN "quad"
|
||||
#endif
|
||||
|
||||
#if defined OSD_FRACTIONAL_ODD_SPACING
|
||||
#define HS_PARTITION "fractional_odd"
|
||||
#elif defined OSD_FRACTIONAL_EVEN_SPACING
|
||||
@ -67,13 +61,34 @@ static float4x4 Mi = {
|
||||
0.f, 0.f, 1.f, 0.f
|
||||
};
|
||||
|
||||
// Boundary / Corner
|
||||
static float4x3 B = {
|
||||
1.f, 0.f, 0.f,
|
||||
4.f/6.f, 2.f/6.f, 0.f,
|
||||
2.f/6.f, 4.f/6.f, 0.f,
|
||||
1.f/6.f, 4.f/6.f, 1.f/6.f
|
||||
};
|
||||
void
|
||||
reflectBoundaryEdges(inout float3 cpt[24], int patchParam)
|
||||
{
|
||||
if (((patchParam >> 4) & 1) != 0) {
|
||||
cpt[0] = 2*cpt[4] - cpt[8];
|
||||
cpt[1] = 2*cpt[5] - cpt[9];
|
||||
cpt[2] = 2*cpt[6] - cpt[10];
|
||||
cpt[3] = 2*cpt[7] - cpt[11];
|
||||
}
|
||||
if (((patchParam >> 4) & 2) != 0) {
|
||||
cpt[3] = 2*cpt[2] - cpt[1];
|
||||
cpt[7] = 2*cpt[6] - cpt[5];
|
||||
cpt[11] = 2*cpt[10] - cpt[9];
|
||||
cpt[15] = 2*cpt[14] - cpt[13];
|
||||
}
|
||||
if (((patchParam >> 4) & 4) != 0) {
|
||||
cpt[12] = 2*cpt[8] - cpt[4];
|
||||
cpt[13] = 2*cpt[9] - cpt[5];
|
||||
cpt[14] = 2*cpt[10] - cpt[6];
|
||||
cpt[15] = 2*cpt[11] - cpt[7];
|
||||
}
|
||||
if (((patchParam >> 4) & 8) != 0) {
|
||||
cpt[0] = 2*cpt[1] - cpt[2];
|
||||
cpt[4] = 2*cpt[5] - cpt[6];
|
||||
cpt[8] = 2*cpt[9] - cpt[10];
|
||||
cpt[12] = 2*cpt[13] - cpt[14];
|
||||
}
|
||||
}
|
||||
|
||||
// compute single-crease patch matrix
|
||||
float4x4
|
||||
@ -96,62 +111,47 @@ ComputeMatrixSimplified(float sharpness)
|
||||
}
|
||||
|
||||
|
||||
#ifdef OSD_PATCH_TRANSITION
|
||||
HS_CONSTANT_TRANSITION_FUNC_OUT
|
||||
#else
|
||||
HS_CONSTANT_FUNC_OUT
|
||||
#endif
|
||||
HS_CONSTANT_FUNC_OUT
|
||||
HSConstFunc(
|
||||
InputPatch<HullVertex, OSD_PATCH_INPUT_SIZE> patch,
|
||||
uint primitiveID : SV_PrimitiveID)
|
||||
{
|
||||
#ifdef OSD_PATCH_TRANSITION
|
||||
HS_CONSTANT_TRANSITION_FUNC_OUT output;
|
||||
#else
|
||||
HS_CONSTANT_FUNC_OUT output;
|
||||
#endif
|
||||
int patchParam = GetPatchParam(primitiveID);
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
|
||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
OSD_PATCH_CULL_TRIANGLE(OSD_PATCH_INPUT_SIZE);
|
||||
#else
|
||||
float3 position[24];
|
||||
for (int p=0; p<16; ++p) {
|
||||
position[p] = patch[p].position.xyz;
|
||||
}
|
||||
|
||||
reflectBoundaryEdges(position, patchParam);
|
||||
|
||||
OSD_PATCH_CULL(OSD_PATCH_INPUT_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef OSD_PATCH_TRANSITION
|
||||
float3 cp[OSD_PATCH_INPUT_SIZE];
|
||||
for(int k = 0; k < OSD_PATCH_INPUT_SIZE; ++k) cp[k] = patch[k].position.xyz;
|
||||
SetTransitionTessLevels(output, cp, patchLevel, primitiveID);
|
||||
#else
|
||||
#if defined OSD_PATCH_BOUNDARY
|
||||
const int p[4] = { 1, 2, 5, 6 };
|
||||
#elif defined OSD_PATCH_CORNER
|
||||
const int p[4] = { 1, 2, 4, 5 };
|
||||
#else
|
||||
const int p[4] = { 5, 6, 9, 10 };
|
||||
#endif
|
||||
float4 outerLevel = float4(0,0,0,0);
|
||||
float4 innerLevel = float4(0,0,0,0);
|
||||
float4 tessOuterLo = float4(0,0,0,0);
|
||||
float4 tessOuterHi = float4(0,0,0,0);
|
||||
GetTransitionTessLevels(position, patchParam, patchLevel,
|
||||
outerLevel, innerLevel,
|
||||
tessOuterLo, tessOuterHi);
|
||||
|
||||
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
output.tessLevelOuter[0] = TessAdaptive(patch[p[0]].position.xyz, patch[p[2]].position.xyz);
|
||||
output.tessLevelOuter[1] = TessAdaptive(patch[p[0]].position.xyz, patch[p[1]].position.xyz);
|
||||
output.tessLevelOuter[2] = TessAdaptive(patch[p[1]].position.xyz, patch[p[3]].position.xyz);
|
||||
output.tessLevelOuter[3] = TessAdaptive(patch[p[2]].position.xyz, patch[p[3]].position.xyz);
|
||||
output.tessLevelInner[0] = max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] = max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#else
|
||||
output.tessLevelInner[0] = GetTessLevel(patchLevel);
|
||||
output.tessLevelInner[1] = GetTessLevel(patchLevel);
|
||||
output.tessLevelOuter[0] = GetTessLevel(patchLevel);
|
||||
output.tessLevelOuter[1] = GetTessLevel(patchLevel);
|
||||
output.tessLevelOuter[2] = GetTessLevel(patchLevel);
|
||||
output.tessLevelOuter[3] = GetTessLevel(patchLevel);
|
||||
#endif
|
||||
#endif
|
||||
output.tessLevelOuter[0] = outerLevel[0];
|
||||
output.tessLevelOuter[1] = outerLevel[1];
|
||||
output.tessLevelOuter[2] = outerLevel[2];
|
||||
output.tessLevelOuter[3] = outerLevel[3];
|
||||
|
||||
output.tessLevelInner[0] = innerLevel[0];
|
||||
output.tessLevelInner[1] = innerLevel[0];
|
||||
|
||||
output.tessOuterLo = tessOuterLo;
|
||||
output.tessOuterHi = tessOuterHi;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[domain(HS_DOMAIN)]
|
||||
[domain("quad")]
|
||||
[partitioning(HS_PARTITION)]
|
||||
[outputtopology("triangle_cw")]
|
||||
[outputcontrolpoints(16)]
|
||||
@ -164,76 +164,61 @@ HullVertex hs_main_patches(
|
||||
int i = ID%4;
|
||||
int j = ID/4;
|
||||
|
||||
#if defined OSD_PATCH_BOUNDARY
|
||||
float3 H[3];
|
||||
for (int l=0; l<3; ++l) {
|
||||
H[l] = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k) {
|
||||
H[l] += Q[i][k] * patch[l*4 + k].position.xyz;
|
||||
}
|
||||
float3 position[24];
|
||||
for (int p=0; p<16; ++p) {
|
||||
position[p] = patch[p].position.xyz;
|
||||
}
|
||||
|
||||
float3 pos = float3(0,0,0);
|
||||
for (int k=0; k<3; ++k) {
|
||||
pos += B[j][k]*H[k];
|
||||
}
|
||||
int patchParam = GetPatchParam(primitiveID);
|
||||
|
||||
#elif defined OSD_PATCH_CORNER
|
||||
float3 H[3];
|
||||
for (int l=0; l<3; ++l) {
|
||||
H[l] = float3(0,0,0);
|
||||
for (int k=0; k<3; ++k) {
|
||||
H[l] += B[3-i][2-k] * patch[l*3 + k].position.xyz;
|
||||
}
|
||||
}
|
||||
reflectBoundaryEdges(position, patchParam);
|
||||
|
||||
float3 pos = float3(0,0,0);
|
||||
for (int k=0; k<3; ++k) {
|
||||
pos += B[j][k]*H[k];
|
||||
}
|
||||
|
||||
#else // not OSD_PATCH_BOUNDARY, not OSD_PATCH_CORNER
|
||||
float3 H[4];
|
||||
for (int l=0; l<4; ++l) {
|
||||
H[l] = float3(0,0,0);
|
||||
for(int k=0; k<4; ++k) {
|
||||
H[l] += Q[i][k] * patch[l*4 + k].position.xyz;
|
||||
H[l] += Q[i][k] * position[l*4 + k];
|
||||
}
|
||||
}
|
||||
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
HullVertex output;
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float sharpness = GetSharpness(primitiveID);
|
||||
float Sf = floor(sharpness);
|
||||
float Sc = ceil(sharpness);
|
||||
float Sr = frac(sharpness);
|
||||
float4x4 Mf = ComputeMatrixSimplified(Sf);
|
||||
float4x4 Mc = ComputeMatrixSimplified(Sc);
|
||||
float4x4 Mj = (1-Sr) * Mf + Sr * Mi;
|
||||
float4x4 Ms = (1-Sr) * Mf + Sr * Mc;
|
||||
if (sharpness > 0) {
|
||||
float Sf = floor(sharpness);
|
||||
float Sc = ceil(sharpness);
|
||||
float Sr = frac(sharpness);
|
||||
float4x4 Mf = ComputeMatrixSimplified(Sf);
|
||||
float4x4 Mc = ComputeMatrixSimplified(Sc);
|
||||
float4x4 Mj = (1-Sr) * Mf + Sr * Mi;
|
||||
float4x4 Ms = (1-Sr) * Mf + Sr * Mc;
|
||||
|
||||
float3 pos = float3(0,0,0);
|
||||
float3 P1 = float3(0,0,0);
|
||||
float3 P2 = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k) {
|
||||
pos += Mi[j][k]*H[k]; // 0 to 1-2^(-Sf)
|
||||
P1 += Mj[j][k]*H[k]; // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
P2 += Ms[j][k]*H[k]; // 1-2^(-Sc) to 1
|
||||
float3 pos = float3(0,0,0);
|
||||
float3 P1 = float3(0,0,0);
|
||||
float3 P2 = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k) {
|
||||
pos += Mi[j][k]*H[k]; // 0 to 1-2^(-Sf)
|
||||
P1 += Mj[j][k]*H[k]; // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
P2 += Ms[j][k]*H[k]; // 1-2^(-Sc) to 1
|
||||
}
|
||||
output.position = float4(pos, 1.0);
|
||||
output.P1 = float4(P1, 1.0);
|
||||
output.P2 = float4(P2, 1.0);
|
||||
output.sharpness = sharpness;
|
||||
} else {
|
||||
float3 pos = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k){
|
||||
pos += Q[j][k]*H[k];
|
||||
}
|
||||
output.position = float4(pos, 1.0);
|
||||
output.sharpness = 0;
|
||||
}
|
||||
#else
|
||||
float3 pos = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k){
|
||||
pos += Q[j][k]*H[k];
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
HullVertex output;
|
||||
output.position = float4(pos, 1.0);
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
output.P1 = float4(P1, 1.0);
|
||||
output.P2 = float4(P2, 1.0);
|
||||
output.sharpness = sharpness;
|
||||
#endif
|
||||
|
||||
int patchLevel = GetPatchLevel(primitiveID);
|
||||
@ -252,26 +237,14 @@ HullVertex hs_main_patches(
|
||||
// Patches.DomainBSpline
|
||||
//----------------------------------------------------------
|
||||
|
||||
[domain(HS_DOMAIN)]
|
||||
[domain("quad")]
|
||||
void ds_main_patches(
|
||||
#ifdef OSD_PATCH_TRANSITION
|
||||
in HS_CONSTANT_TRANSITION_FUNC_OUT input,
|
||||
#else
|
||||
in HS_CONSTANT_FUNC_OUT input,
|
||||
#endif
|
||||
in OutputPatch<HullVertex, 16> patch,
|
||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
in float3 domainCoord : SV_DomainLocation,
|
||||
#else
|
||||
in float2 domainCoord : SV_DomainLocation,
|
||||
#endif
|
||||
out OutputVertex output )
|
||||
{
|
||||
#ifdef OSD_PATCH_TRANSITION
|
||||
float2 UV = GetTransitionSubpatchUV(domainCoord);
|
||||
#else
|
||||
float2 UV = domainCoord;
|
||||
#endif
|
||||
float2 UV = GetTransitionParameterization(input, domainCoord);
|
||||
|
||||
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
float B[4], D[4], C[4];
|
||||
@ -286,52 +259,60 @@ void ds_main_patches(
|
||||
Univar4x4(UV.x, B, D);
|
||||
#endif
|
||||
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
// ----------------------------------------------------------------
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
// sharpness
|
||||
float sharpness = patch[0].sharpness;
|
||||
float s0 = 1.0 - pow(2.0f, -floor(sharpness));
|
||||
float s1 = 1.0 - pow(2.0f, -ceil(sharpness));
|
||||
#endif
|
||||
if (sharpness != 0) {
|
||||
float s0 = 1.0 - pow(2.0f, -floor(sharpness));
|
||||
float s1 = 1.0 - pow(2.0f, -ceil(sharpness));
|
||||
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
#if OSD_TRANSITION_ROTATE == 1
|
||||
int k = 4*(3-j) + i;
|
||||
float s = 1-UV.x;
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
int k = 4*(3-i) + (3-j);
|
||||
float s = 1-UV.y;
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
int k = 4*j + (3-i);
|
||||
float s = UV.x;
|
||||
#else // ROTATE=0 or non-transition
|
||||
int k = 4*i + j;
|
||||
float s = UV.y;
|
||||
#endif
|
||||
float3 A = (s < s0) ?
|
||||
patch[k].position.xyz :
|
||||
((s < s1) ?
|
||||
patch[k].P1.xyz :
|
||||
patch[k].P2.xyz);
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
int k = 4*i + j;
|
||||
float s = UV.y;
|
||||
|
||||
#else // !SINGLE_CREASE
|
||||
#if OSD_TRANSITION_ROTATE == 1
|
||||
float3 A = patch[4*(3-j) + i].position.xyz;
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
float3 A = patch[4*(3-i) + (3-j)].position.xyz;
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
float3 A = patch[4*j + (3-i)].position.xyz;
|
||||
#else // OSD_TRANSITION_ROTATE == 0, or non-transition patch
|
||||
float3 A = patch[4*i + j].position.xyz;
|
||||
#endif
|
||||
#endif
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
float3 A = (s < s0) ?
|
||||
patch[k].position.xyz :
|
||||
((s < s1) ?
|
||||
patch[k].P1.xyz :
|
||||
patch[k].P2.xyz);
|
||||
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
CUCP[i] += A * C[j];
|
||||
CUCP[i] += A * C[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
output.sharpness = sharpness;
|
||||
} else {
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
float3 A = patch[4*i + j].position.xyz;
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
CUCP[i] += A * C[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
output.sharpness = 0;
|
||||
}
|
||||
#else
|
||||
// ----------------------------------------------------------------
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
float3 A = patch[4*i + j].position.xyz;
|
||||
BUCP[i] += A * B[j];
|
||||
DUCP[i] += A * D[j];
|
||||
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
CUCP[i] += A * C[j];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
float3 WorldPos = float3(0,0,0);
|
||||
float3 Tangent = float3(0,0,0);
|
||||
@ -378,7 +359,10 @@ void ds_main_patches(
|
||||
Nu = Nu/length(n) - n * (dot(Nu,n)/pow(dot(n,n), 1.5));
|
||||
Nv = Nv/length(n) - n * (dot(Nv,n)/pow(dot(n,n), 1.5));
|
||||
|
||||
OSD_COMPUTE_PTEX_COMPATIBLE_DERIVATIVES(OSD_TRANSITION_ROTATE);
|
||||
output.tangent = Tangent;
|
||||
output.bitangent = BiTangent;
|
||||
output.Nu = Nu;
|
||||
output.Nv = Nv;
|
||||
#else
|
||||
Univar4x4(UV.y, B, D);
|
||||
|
||||
@ -393,7 +377,8 @@ void ds_main_patches(
|
||||
|
||||
float3 normal = normalize(cross(Tangent, BiTangent));
|
||||
|
||||
OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(OSD_TRANSITION_ROTATE);
|
||||
output.tangent = Tangent;
|
||||
output.bitangent = BiTangent;
|
||||
#endif
|
||||
|
||||
output.position = float4(WorldPos, 1.0f);
|
||||
@ -401,20 +386,13 @@ void ds_main_patches(
|
||||
|
||||
output.patchCoord = patch[0].patchCoord;
|
||||
|
||||
#if OSD_TRANSITION_ROTATE == 1
|
||||
output.patchCoord.xy = float2(UV.y, 1.0-UV.x);
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
output.patchCoord.xy = float2(1.0-UV.x, 1.0-UV.y);
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
output.patchCoord.xy = float2(1.0-UV.y, UV.x);
|
||||
#else // OSD_TRANNSITION_ROTATE == 0, or non-transition patch
|
||||
output.patchCoord.xy = float2(UV.x, UV.y);
|
||||
#endif
|
||||
|
||||
OSD_COMPUTE_PTEX_COORD_DOMAIN_SHADER;
|
||||
|
||||
OSD_DISPLACEMENT_CALLBACK;
|
||||
output.edgeDistance = 0;
|
||||
|
||||
output.positionOut = mul(OsdProjectionMatrix(),
|
||||
float4(output.position.xyz, 1.0f));
|
||||
output.edgeDistance = 0;
|
||||
}
|
||||
|
@ -26,17 +26,11 @@
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
#ifndef OSD_TRANSITION_ROTATE
|
||||
#define OSD_TRANSITION_ROTATE 0
|
||||
#endif
|
||||
// XXXdyu-patch-drawing support for fractional spacing
|
||||
#undef OSD_FRACTIONAL_ODD_SPACING
|
||||
#undef OSD_FRACTIONAL_EVEN_SPACING
|
||||
|
||||
#if defined OSD_PATCH_BOUNDARY
|
||||
#define OSD_PATCH_INPUT_SIZE 12
|
||||
#elif defined OSD_PATCH_CORNER
|
||||
#define OSD_PATCH_INPUT_SIZE 9
|
||||
#else
|
||||
#define OSD_PATCH_INPUT_SIZE 16
|
||||
#endif
|
||||
#define OSD_PATCH_INPUT_SIZE 16
|
||||
|
||||
#define M_PI 3.14159265359f
|
||||
|
||||
@ -50,7 +44,7 @@ struct HullVertex {
|
||||
float4 patchCoord : PATCHCOORD; // u, v, level, faceID
|
||||
int4 ptexInfo : PTEXINFO; // u offset, v offset, 2^ptexlevel, rotation
|
||||
int3 clipFlag : CLIPFLAG;
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float4 P1 : POSITION1;
|
||||
float4 P2 : POSITION2;
|
||||
float sharpness : BLENDWEIGHT0;
|
||||
@ -69,6 +63,9 @@ struct OutputVertex {
|
||||
float3 Nu : TANGENT2;
|
||||
float3 Nv : TANGENT3;
|
||||
#endif
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float sharpness : BLENDWEIGHT0;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct GregHullVertex {
|
||||
@ -98,6 +95,8 @@ struct GregDomainVertex {
|
||||
struct HS_CONSTANT_FUNC_OUT {
|
||||
float tessLevelInner[2] : SV_InsideTessFactor;
|
||||
float tessLevelOuter[4] : SV_TessFactor;
|
||||
float4 tessOuterLo : TRANSITIONLO;
|
||||
float4 tessOuterHi : TRANSITIONHI;
|
||||
};
|
||||
|
||||
// osd shaders need following functions defined
|
||||
@ -141,12 +140,15 @@ float TessAdaptive(float3 p0, float3 p1)
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
#if defined OSD_PATCH_SINGLE_CREASE
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
Buffer<uint3> OsdPatchParamBuffer : register( t3 );
|
||||
#else
|
||||
Buffer<uint2> OsdPatchParamBuffer : register( t3 );
|
||||
#endif
|
||||
|
||||
#define GetPatchParam(primitiveID) \
|
||||
(OsdPatchParamBuffer[GetPrimitiveID(primitiveID)].y)
|
||||
|
||||
#define GetPatchLevel(primitiveID) \
|
||||
(OsdPatchParamBuffer[GetPrimitiveID(primitiveID)].y & 0xf)
|
||||
|
||||
@ -157,12 +159,11 @@ float TessAdaptive(float3 p0, float3 p1)
|
||||
{ \
|
||||
int2 ptexIndex = OsdPatchParamBuffer[GetPrimitiveID(primitiveID)].xy; \
|
||||
int faceID = ptexIndex.x; \
|
||||
int lv = 1 << ((ptexIndex.y & 0xf) - ((ptexIndex.y >> 4) & 1)); \
|
||||
int u = (ptexIndex.y >> 17) & 0x3ff; \
|
||||
int v = (ptexIndex.y >> 7) & 0x3ff; \
|
||||
int rotation = (ptexIndex.y >> 5) & 0x3; \
|
||||
int lv = 1 << ((ptexIndex.y & 0x7) - ((ptexIndex.y >> 3) & 1)); \
|
||||
int u = (ptexIndex.y >> 22) & 0x3ff; \
|
||||
int v = (ptexIndex.y >> 12) & 0x3ff; \
|
||||
output.patchCoord.w = faceID+0.5; \
|
||||
output.ptexInfo = int4(u, v, lv, rotation); \
|
||||
output.ptexInfo = int4(u, v, lv, 0); \
|
||||
}
|
||||
|
||||
#define OSD_COMPUTE_PTEX_COORD_DOMAIN_SHADER \
|
||||
@ -171,57 +172,9 @@ float TessAdaptive(float3 p0, float3 p1)
|
||||
int2 p = patch[0].ptexInfo.xy; \
|
||||
int lv = patch[0].ptexInfo.z; \
|
||||
int rot = patch[0].ptexInfo.w; \
|
||||
uv.xy = float(rot==0)*uv.xy \
|
||||
+ float(rot==1)*float2(1.0-uv.y, uv.x) \
|
||||
+ float(rot==2)*float2(1.0-uv.x, 1.0-uv.y) \
|
||||
+ float(rot==3)*float2(uv.y, 1.0-uv.x); \
|
||||
output.patchCoord.xy = (uv * float2(1.0,1.0)/lv) + float2(p.x, p.y)/lv; \
|
||||
}
|
||||
|
||||
#define OSD_COMPUTE_PTEX_COMPATIBLE_TANGENT(ROTATE) \
|
||||
{ \
|
||||
int rot = (patch[0].ptexInfo.w + 4 - ROTATE)%4; \
|
||||
if (rot == 1) { \
|
||||
output.tangent = -BiTangent; \
|
||||
output.bitangent = Tangent; \
|
||||
} else if (rot == 2) { \
|
||||
output.tangent = -Tangent; \
|
||||
output.bitangent = -BiTangent; \
|
||||
} else if (rot == 3) { \
|
||||
output.tangent = BiTangent; \
|
||||
output.bitangent = -Tangent; \
|
||||
} else { \
|
||||
output.tangent = Tangent; \
|
||||
output.bitangent = BiTangent; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define OSD_COMPUTE_PTEX_COMPATIBLE_DERIVATIVES(ROTATE) \
|
||||
{ \
|
||||
int rot = (patch[0].ptexInfo.w + 4 - ROTATE)%4; \
|
||||
if (rot == 1) { \
|
||||
output.tangent = -BiTangent; \
|
||||
output.bitangent = Tangent; \
|
||||
output.Nu = -Nv; \
|
||||
output.Nv = Nv; \
|
||||
} else if (rot == 2) { \
|
||||
output.tangent = -Tangent; \
|
||||
output.bitangent = -BiTangent; \
|
||||
output.Nu = -Nu; \
|
||||
output.Nv = -Nv; \
|
||||
} else if (rot == 3) { \
|
||||
output.tangent = BiTangent; \
|
||||
output.bitangent = -Tangent; \
|
||||
output.Nu = Nv; \
|
||||
output.Nv = -Nu; \
|
||||
} else { \
|
||||
output.tangent = Tangent; \
|
||||
output.bitangent = BiTangent; \
|
||||
output.Nu = Nu; \
|
||||
output.Nv = Nv; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
|
@ -22,600 +22,118 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
#if defined(OSD_TRANSITION_PATTERN00) || defined(OSD_TRANSITION_PATTERN01) || defined(OSD_TRANSITION_PATTERN02) || defined(OSD_TRANSITION_PATTERN10) || defined(OSD_TRANSITION_PATTERN11) || defined(OSD_TRANSITION_PATTERN12) || defined(OSD_TRANSITION_PATTERN13) || defined(OSD_TRANSITION_PATTERN21) || defined(OSD_TRANSITION_PATTERN22) || defined(OSD_TRANSITION_PATTERN23)
|
||||
|
||||
#define OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
|
||||
#else
|
||||
|
||||
#undef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
|
||||
#endif
|
||||
|
||||
struct HS_CONSTANT_TRANSITION_FUNC_OUT {
|
||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
float tessLevelInner : SV_InsideTessFactor;
|
||||
float tessLevelOuter[3] : SV_TessFactor;
|
||||
#else
|
||||
float tessLevelInner[2] : SV_InsideTessFactor;
|
||||
float tessLevelOuter[4] : SV_TessFactor;
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.HullTransition
|
||||
//----------------------------------------------------------
|
||||
|
||||
float
|
||||
TessAdaptiveRound(float3 p0, float3 p1)
|
||||
{
|
||||
return round(TessAdaptive(p0, p1));
|
||||
}
|
||||
|
||||
void
|
||||
SetTransitionTessLevels(inout HS_CONSTANT_TRANSITION_FUNC_OUT output, float3 cp[OSD_PATCH_INPUT_SIZE], int patchLevel, uint primitiveID) {
|
||||
GetTransitionTessLevels(
|
||||
float3 cp[24], int patchParam, int patchLevel,
|
||||
inout float4 outer, inout float4 inner,
|
||||
inout float4 tessOuterLo, inout float4 tessOuterHi)
|
||||
{
|
||||
// Each edge of a transition patch is adjacent to one or two patches
|
||||
// at the next refined level of subdivision. We COmpute the corresponding
|
||||
// vertex-vertex and edge-vertex refined points along the edges of the
|
||||
// patch using Catmull-Clark subdivision stencil weights.
|
||||
// For simplicity, we let the optimizer discard unused computation.
|
||||
cp[16] = (cp[0] + cp[2] + cp[8] + cp[10]) * 0.015625 +
|
||||
(cp[1] + cp[4] + cp[6] + cp[9]) * 0.09375 + cp[5] * 0.5625;
|
||||
cp[17] = (cp[1] + cp[2] + cp[9] + cp[10]) * 0.0625 + (cp[5] + cp[6]) * 0.375;
|
||||
|
||||
cp[18] = (cp[1] + cp[3] + cp[9] + cp[11]) * 0.015625 +
|
||||
(cp[2] + cp[5] + cp[7] + cp[10]) * 0.09375 + cp[6] * 0.5625;
|
||||
cp[19] = (cp[5] + cp[7] + cp[9] + cp[11]) * 0.0625 + (cp[6] + cp[10]) * 0.375;
|
||||
|
||||
cp[20] = (cp[5] + cp[7] + cp[13] + cp[15]) * 0.015625 +
|
||||
(cp[6] + cp[9] + cp[11] + cp[14]) * 0.09375 + cp[10] * 0.5625;
|
||||
cp[21] = (cp[5] + cp[6] + cp[13] + cp[14]) * 0.0625 + (cp[9] + cp[10]) * 0.375;
|
||||
|
||||
cp[22] = (cp[4] + cp[6] + cp[12] + cp[14]) * 0.015625 +
|
||||
(cp[5] + cp[8] + cp[10] + cp[13]) * 0.09375 + cp[9] * 0.5625;
|
||||
cp[23] = (cp[4] + cp[6] + cp[8] + cp[10]) * 0.0625 + (cp[5] + cp[9]) * 0.375;
|
||||
tessOuterLo = float4(1,1,1,1);
|
||||
tessOuterHi = float4(0,0,0,0);
|
||||
|
||||
#ifdef OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
// These tables map the 9, 12, or 16 input control points onto the
|
||||
// canonical 16 control points for a regular patch.
|
||||
#if defined OSD_PATCH_BOUNDARY
|
||||
const int p[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
|
||||
#elif defined OSD_PATCH_CORNER
|
||||
const int p[16] = { 0, 1, 2, 2, 0, 1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 8 };
|
||||
if (((patchParam >> 11) & 1) != 0) {
|
||||
tessOuterLo[0] = TessAdaptiveRound(cp[23], cp[16]);
|
||||
tessOuterHi[0] = TessAdaptiveRound(cp[22], cp[23]);
|
||||
} else {
|
||||
tessOuterLo[0] = TessAdaptiveRound(cp[5], cp[9]);
|
||||
}
|
||||
if (((patchParam >> 8) & 1) != 0) {
|
||||
tessOuterLo[1] = TessAdaptiveRound(cp[16], cp[17]);
|
||||
tessOuterHi[1] = TessAdaptiveRound(cp[17], cp[18]);
|
||||
} else {
|
||||
tessOuterLo[1] = TessAdaptiveRound(cp[5], cp[6]);
|
||||
}
|
||||
if (((patchParam >> 9) & 1) != 0) {
|
||||
tessOuterLo[2] = TessAdaptiveRound(cp[18], cp[19]);
|
||||
tessOuterHi[2] = TessAdaptiveRound(cp[19], cp[20]);
|
||||
} else {
|
||||
tessOuterLo[2] = TessAdaptiveRound(cp[6], cp[10]);
|
||||
}
|
||||
if (((patchParam >> 10) & 1) != 0) {
|
||||
tessOuterLo[3] = TessAdaptiveRound(cp[21], cp[22]);
|
||||
tessOuterHi[3] = TessAdaptiveRound(cp[20], cp[21]);
|
||||
} else {
|
||||
tessOuterLo[3] = TessAdaptiveRound(cp[9], cp[10]);
|
||||
}
|
||||
#else
|
||||
const int p[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
float tessAmount = GetTessLevel(patchLevel);
|
||||
|
||||
tessOuterLo[0] = tessAmount;
|
||||
tessOuterLo[1] = tessAmount;
|
||||
tessOuterLo[2] = tessAmount;
|
||||
tessOuterLo[3] = tessAmount;
|
||||
#endif
|
||||
|
||||
#if OSD_TRANSITION_ROTATE == 0
|
||||
const int r[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
#elif OSD_TRANSITION_ROTATE == 1
|
||||
const int r[16] = { 12, 8, 4, 0, 13, 9, 5, 1, 14, 10, 6, 2, 15, 11, 7, 3 };
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
const int r[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
const int r[16] = { 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 };
|
||||
#endif
|
||||
|
||||
// Expand and rotate control points using remapping tables above
|
||||
float3 pv0 = cp[p[r[0]]];
|
||||
float3 pv1 = cp[p[r[1]]];
|
||||
float3 pv2 = cp[p[r[2]]];
|
||||
float3 pv3 = cp[p[r[3]]];
|
||||
|
||||
float3 pv4 = cp[p[r[4]]];
|
||||
float3 pv5 = cp[p[r[5]]];
|
||||
float3 pv6 = cp[p[r[6]]];
|
||||
float3 pv7 = cp[p[r[7]]];
|
||||
|
||||
float3 pv8 = cp[p[r[8]]];
|
||||
float3 pv9 = cp[p[r[9]]];
|
||||
float3 pv10 = cp[p[r[10]]];
|
||||
float3 pv11 = cp[p[r[11]]];
|
||||
|
||||
float3 pv12 = cp[p[r[12]]];
|
||||
float3 pv13 = cp[p[r[13]]];
|
||||
float3 pv14 = cp[p[r[14]]];
|
||||
float3 pv15 = cp[p[r[15]]];
|
||||
|
||||
// Each edge of a transition patch is adjacent to one or two
|
||||
// patches at the next refined level of subdivision.
|
||||
// Compute the corresponding vertex-vertex and edge-vertex refined
|
||||
// points along the edges of the patch using Catmull-Clark subdivision
|
||||
// stencil weights.
|
||||
// For simplicity, we let the optimizer discard unused computation.
|
||||
float3 vv0 = (pv0 + pv2 + pv8 + pv10) * 0.015625 +
|
||||
(pv1 + pv4 + pv6 + pv9) * 0.09375 + pv5 * 0.5625;
|
||||
float3 ev01 = (pv1 + pv2 + pv9 + pv10) * 0.0625 + (pv5 + pv6) * 0.375;
|
||||
|
||||
float3 vv1 = (pv1 + pv3 + pv9 + pv11) * 0.015625 +
|
||||
(pv2 + pv5 + pv7 + pv10) * 0.09375 + pv6 * 0.5625;
|
||||
float3 ev12 = (pv5 + pv7 + pv9 + pv11) * 0.0625 + (pv6 + pv10) * 0.375;
|
||||
|
||||
float3 vv2 = (pv5 + pv7 + pv13 + pv15) * 0.015625 +
|
||||
(pv6 + pv9 + pv11 + pv14) * 0.09375 + pv10 * 0.5625;
|
||||
float3 ev23 = (pv5 + pv6 + pv13 + pv14) * 0.0625 + (pv9 + pv10) * 0.375;
|
||||
|
||||
float3 vv3 = (pv4 + pv6 + pv12 + pv14) * 0.015625 +
|
||||
(pv5 + pv8 + pv10 + pv13) * 0.09375 + pv9 * 0.5625;
|
||||
float3 ev30 = (pv4 + pv6 + pv8 + pv10) * 0.0625 + (pv5 + pv9) * 0.375;
|
||||
|
||||
// The vertices along boundaries and at corners are refined specially.
|
||||
#if defined OSD_PATCH_BOUNDARY
|
||||
#if OSD_TRANSITION_ROTATE == 0
|
||||
vv0 = (pv4 + pv6) * 0.125 + pv5 * 0.75;
|
||||
vv1 = (pv5 + pv7) * 0.125 + pv6 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 1
|
||||
vv1 = (pv2 + pv10) * 0.125 + pv6 * 0.75;
|
||||
vv2 = (pv6 + pv14) * 0.125 + pv10 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
vv2 = (pv9 + pv11) * 0.125 + pv10 * 0.75;
|
||||
vv3 = (pv8 + pv10) * 0.125 + pv9 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
vv3 = (pv5 + pv13) * 0.125 + pv9 * 0.75;
|
||||
vv0 = (pv1 + pv9) * 0.125 + pv5 * 0.75;
|
||||
#endif
|
||||
#elif defined OSD_PATCH_CORNER
|
||||
#if OSD_TRANSITION_ROTATE == 0
|
||||
vv0 = (pv4 + pv6) * 0.125 + pv5 * 0.75;
|
||||
vv1 = pv6;
|
||||
vv2 = (pv6 + pv14) * 0.125 + pv10 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 1
|
||||
vv1 = (pv2 + pv10) * 0.125 + pv6 * 0.75;
|
||||
vv2 = pv10;
|
||||
vv3 = (pv8 + pv10) * 0.125 + pv9 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 2
|
||||
vv2 = (pv9 + pv11) * 0.125 + pv10 * 0.75;
|
||||
vv3 = pv9;
|
||||
vv0 = (pv1 + pv9) * 0.125 + pv5 * 0.75;
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
vv3 = (pv5 + pv13) * 0.125 + pv9 * 0.75;
|
||||
vv0 = pv5;
|
||||
vv1 = (pv5 + pv7) * 0.125 + pv6 * 0.75;
|
||||
#endif
|
||||
#elif defined OSD_PATCH_SINGLE_CREASE
|
||||
// apply smooth, sharp or fractional-semisharp (linear interpolate) rules
|
||||
float weight = min(1, GetSharpness(primitiveID));
|
||||
|
||||
// XXX: current rotation of single-crease patch is inconsistent
|
||||
// to boundary patch. should be fixed.
|
||||
#if OSD_TRANSITION_ROTATE == 2
|
||||
vv0 = lerp(vv0, (pv4 + pv6) * 0.125 + pv5 * 0.75, weight);
|
||||
vv1 = lerp(vv1, (pv5 + pv7) * 0.125 + pv6 * 0.75, weight);
|
||||
#elif OSD_TRANSITION_ROTATE == 3
|
||||
vv1 = lerp(vv1, (pv2 + pv10) * 0.125 + pv6 * 0.75, weight);
|
||||
vv2 = lerp(vv2, (pv6 + pv14) * 0.125 + pv10 * 0.75, weight);
|
||||
#elif OSD_TRANSITION_ROTATE == 0
|
||||
vv2 = lerp(vv2, (pv9 + pv11) * 0.125 + pv10 * 0.75, weight);
|
||||
vv3 = lerp(vv3, (pv8 + pv10) * 0.125 + pv9 * 0.75, weight);
|
||||
#elif OSD_TRANSITION_ROTATE == 1
|
||||
vv3 = lerp(vv3, (pv5 + pv13) * 0.125 + pv9 * 0.75, weight);
|
||||
vv0 = lerp(vv0, (pv1 + pv9) * 0.125 + pv5 * 0.75, weight);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN00
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, pv9) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, pv10) * 0.5;
|
||||
output.tessLevelOuter[2] = TessAdaptive(pv9, pv10);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.5;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN01
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, vv1);
|
||||
output.tessLevelOuter[1] = TessAdaptive(pv6, pv10);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev01, pv10) * 0.5;
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.25;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN02
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, vv0);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, pv9) * 0.5;
|
||||
output.tessLevelOuter[2] = TessAdaptive(pv5, pv9);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.25;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN10
|
||||
output.tessLevelOuter[0] = TessAdaptive(pv6, pv10);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, pv10);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev01, vv1);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1]) * 0.25;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN11
|
||||
output.tessLevelOuter[0] = TessAdaptive(pv9, pv10);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev30, vv3);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev30, pv10);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[2]) * 0.25;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN12
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev30, vv0);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, vv0);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev01, ev30);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.25;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN13
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, pv10);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev30, pv10);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev01, ev30);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.25;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN20
|
||||
output.tessLevelOuter[0] = TessAdaptive(pv5, pv6);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev12, vv1);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev12, ev30);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev30, vv0);
|
||||
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN21
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev23, ev30) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev23, vv3);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev30, vv3);
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.5;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN22
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev12, vv2);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev23, vv2);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev12, ev23) * 0.5;
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1]) * 0.5;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN23
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev12, ev30);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev12, ev23) * 0.5;
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev23, ev30) * 0.5;
|
||||
|
||||
output.tessLevelInner =
|
||||
(output.tessLevelOuter[0] + output.tessLevelOuter[1] + output.tessLevelOuter[2]) * 0.5;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN30
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev30, ev12) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev30, vv0);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev01, vv0);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev01, ev23) * 0.5;
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN31
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, ev23) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev23, vv3);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev30, vv3);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev30, ev12) * 0.5;
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN32
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev23, ev01) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, vv1);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev12, vv1);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev12, ev30) * 0.5;
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN33
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev12, ev30) * 0.5;
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev12, vv2);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev23, vv2);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev01, ev23) * 0.5;
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN40
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, vv0);
|
||||
output.tessLevelOuter[1] = TessAdaptive(ev01, ev23);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev23, vv3);
|
||||
output.tessLevelOuter[3] = TessAdaptive(pv5, pv9);
|
||||
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN41
|
||||
output.tessLevelOuter[0] = TessAdaptive(ev01, vv1);
|
||||
output.tessLevelOuter[1] = TessAdaptive(pv6, pv10);
|
||||
output.tessLevelOuter[2] = TessAdaptive(ev23, vv2);
|
||||
output.tessLevelOuter[3] = TessAdaptive(ev01, ev23);
|
||||
|
||||
output.tessLevelInner[0] =
|
||||
max(output.tessLevelOuter[1], output.tessLevelOuter[3]);
|
||||
output.tessLevelInner[1] =
|
||||
max(output.tessLevelOuter[0], output.tessLevelOuter[2]);
|
||||
#endif
|
||||
|
||||
#else // OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
|
||||
// XXX: HLSL compiler crashes with an internal compiler error occasionaly
|
||||
// if this shader accesses a shader resource buffer or a constant buffer
|
||||
// from this hull constant function.
|
||||
//float TessAmount = GetTessLevel(patchLevel);
|
||||
//float TessAmount = GetTessLevel(0);
|
||||
float TessAmount = 2.0;
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN00
|
||||
float side = sqrt(1.25)*TessAmount;
|
||||
output.tessLevelOuter[0] = side;
|
||||
output.tessLevelOuter[1] = side;
|
||||
output.tessLevelOuter[2] = TessAmount;
|
||||
|
||||
output.tessLevelInner = TessAmount;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN01
|
||||
float side = sqrt(1.25)*TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = TessAmount;
|
||||
output.tessLevelOuter[2] = side;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN02
|
||||
float side = sqrt(1.25)*TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = side;
|
||||
output.tessLevelOuter[2] = TessAmount;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN10
|
||||
float side = sqrt(1.25) * TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount;
|
||||
output.tessLevelOuter[1] = side;
|
||||
output.tessLevelOuter[2] = TessAmount/2.0;
|
||||
|
||||
output.tessLevelInner = TessAmount/2;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN11
|
||||
float side = sqrt(1.25) * TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount;
|
||||
output.tessLevelOuter[1] = TessAmount/2.0;
|
||||
output.tessLevelOuter[2] = side;
|
||||
|
||||
output.tessLevelInner = TessAmount/2;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN12
|
||||
float side = sqrt(0.125) * TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = TessAmount/2.0;
|
||||
output.tessLevelOuter[2] = side;
|
||||
|
||||
output.tessLevelInner = TessAmount/2;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN13
|
||||
float side1 = sqrt(1.25) * TessAmount;
|
||||
float side2 = sqrt(0.125) * TessAmount;
|
||||
output.tessLevelOuter[0] = side1;
|
||||
output.tessLevelOuter[1] = side1;
|
||||
output.tessLevelOuter[2] = side2;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0*1.414;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN20
|
||||
output.tessLevelOuter[0] = TessAmount;
|
||||
output.tessLevelOuter[1] = TessAmount/2.0;
|
||||
output.tessLevelOuter[2] = TessAmount;
|
||||
output.tessLevelOuter[3] = TessAmount/2.0;
|
||||
|
||||
output.tessLevelInner[0] = TessAmount/2.0;
|
||||
output.tessLevelInner[1] = TessAmount;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN21
|
||||
float side = sqrt(0.125) * TessAmount;
|
||||
output.tessLevelOuter[0] = side;
|
||||
output.tessLevelOuter[1] = TessAmount/2.0;
|
||||
output.tessLevelOuter[2] = TessAmount/2.0;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN22
|
||||
float side = sqrt(0.125) * TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = TessAmount/2.0;
|
||||
output.tessLevelOuter[2] = side;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN23
|
||||
float side = sqrt(0.125) * TessAmount;
|
||||
output.tessLevelOuter[0] = TessAmount;
|
||||
output.tessLevelOuter[1] = side;
|
||||
output.tessLevelOuter[2] = side;
|
||||
|
||||
output.tessLevelInner = TessAmount/2.0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN30
|
||||
output.tessLevelOuter[0] = output.tessLevelOuter[1] =
|
||||
output.tessLevelOuter[2] = output.tessLevelOuter[3] = TessAmount/2.0;
|
||||
output.tessLevelInner[0] = output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN31
|
||||
output.tessLevelOuter[0] = output.tessLevelOuter[1] =
|
||||
output.tessLevelOuter[2] = output.tessLevelOuter[3] = TessAmount/2.0;
|
||||
output.tessLevelInner[0] = output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN32
|
||||
output.tessLevelOuter[0] = output.tessLevelOuter[1] =
|
||||
output.tessLevelOuter[2] = output.tessLevelOuter[3] = TessAmount/2.0;
|
||||
output.tessLevelInner[0] = output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN33
|
||||
output.tessLevelOuter[0] = output.tessLevelOuter[1] =
|
||||
output.tessLevelOuter[2] = output.tessLevelOuter[3] = TessAmount/2.0;
|
||||
output.tessLevelInner[0] = output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN40
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = TessAmount;
|
||||
output.tessLevelOuter[2] = TessAmount/2.0;
|
||||
output.tessLevelOuter[3] = TessAmount;
|
||||
|
||||
output.tessLevelInner[0] = TessAmount;
|
||||
output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN41
|
||||
output.tessLevelOuter[0] = TessAmount/2.0;
|
||||
output.tessLevelOuter[1] = TessAmount;
|
||||
output.tessLevelOuter[2] = TessAmount/2.0;
|
||||
output.tessLevelOuter[3] = TessAmount;
|
||||
|
||||
output.tessLevelInner[0] = TessAmount;
|
||||
output.tessLevelInner[1] = TessAmount/2.0;
|
||||
#endif
|
||||
|
||||
#endif // OSD_ENABLE_SCREENSPACE_TESSELLATION
|
||||
outer = tessOuterLo + tessOuterHi;
|
||||
inner[0] = (outer[0] + outer[2]) * 0.5;
|
||||
inner[1] = (outer[1] + outer[3]) * 0.5;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.DomainTransition
|
||||
//----------------------------------------------------------
|
||||
|
||||
float2
|
||||
GetTransitionSubpatchUV(
|
||||
#ifdef OSD_TRANSITION_TRIANGLE_SUBPATCH
|
||||
in float3 uvw
|
||||
#else
|
||||
in float2 uv
|
||||
#endif
|
||||
)
|
||||
float
|
||||
GetTransitionSplit(float t, float n0, float n1)
|
||||
{
|
||||
float2 UV = float2(0.0, 0.0);
|
||||
float n = round(n0 + n1);
|
||||
float ti = round(t * n);
|
||||
|
||||
// OSD_TRANSITION_PATTERN0*
|
||||
// +-------------+
|
||||
// | /\\ |
|
||||
// | 1 / \\ 2 |
|
||||
// | / \\ |
|
||||
// | / \\ |
|
||||
// | / 0 \\ |
|
||||
// |/ \\|
|
||||
// +-------------+
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN00
|
||||
UV.x = 1.0-uvw.y-uvw.z/2;
|
||||
UV.y = 1.0-uvw.z;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN01
|
||||
UV.x = 1.0-uvw.y/2;
|
||||
UV.y = uvw.x;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN02
|
||||
UV.x = uvw.z/2;
|
||||
UV.y = uvw.x;
|
||||
#endif
|
||||
|
||||
// OSD_TRANSITION_PATTERN1*
|
||||
// +-------------+
|
||||
// | 0 /\\ 2 |
|
||||
// | / \\ |
|
||||
// | / 3 \\ |
|
||||
// | / / |
|
||||
// | / / 1 |
|
||||
// |/ / |
|
||||
// +-------------+
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN10
|
||||
UV.x = 1.0-uvw.x/2.0;
|
||||
UV.y = uvw.z;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN11
|
||||
UV.x = uvw.y;
|
||||
UV.y = 1.0-uvw.x/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN12
|
||||
UV.x = uvw.x/2.0;
|
||||
UV.y = uvw.y/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN13
|
||||
UV.x = 1.0-uvw.x-uvw.y/2.0;
|
||||
UV.y = 1.0-uvw.y-uvw.x/2.0;
|
||||
#endif
|
||||
|
||||
// OSD_TRANSITION_PATTERN2*
|
||||
// +-------------+
|
||||
// | |
|
||||
// | 0 |
|
||||
// | |
|
||||
// |-------------|
|
||||
// |\\ 3 / |
|
||||
// | \\ / |
|
||||
// | 1 \\ / 2 |
|
||||
// +-------------+
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN20
|
||||
UV.x = 1.0-uv.y;
|
||||
UV.y = uv.x/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN21
|
||||
UV.x = uvw.z/2.0;
|
||||
UV.y = 1.0-uvw.y/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN22
|
||||
UV.x = 1.0-uvw.x/2.0;
|
||||
UV.y = 1.0-uvw.y/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN23
|
||||
UV.x = 1.0-uvw.y-uvw.x/2;
|
||||
UV.y = 0.5+uvw.x/2.0;
|
||||
#endif
|
||||
|
||||
// OSD_TRANSITION_PATTERN3*
|
||||
// +-------------+
|
||||
// | | |
|
||||
// | 1 | 0 |
|
||||
// | | |
|
||||
// |------|------|
|
||||
// | | |
|
||||
// | 3 | 2 |
|
||||
// | | |
|
||||
// +-------------+
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN30
|
||||
UV.x = uv.y/2.0;
|
||||
UV.y = 0.5 - uv.x/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN31
|
||||
UV.x = 0.5 - uv.x/2.0;
|
||||
UV.y = 1.0 - uv.y/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN32
|
||||
UV.x = 0.5 + uv.x/2.0;
|
||||
UV.y = uv.y/2.0;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN33
|
||||
UV.x = 1.0 - uv.y/2.0;
|
||||
UV.y = 0.5 + uv.x/2.0;
|
||||
#endif
|
||||
|
||||
// OSD_TRANSITION_PATTERN4*
|
||||
// +-------------+
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// | 1 | 0 |
|
||||
// | | |
|
||||
// | | |
|
||||
// | | |
|
||||
// +-------------+
|
||||
|
||||
#ifdef OSD_TRANSITION_PATTERN40
|
||||
UV.x = 0.5 - uv.y/2.0;
|
||||
UV.y = uv.x;
|
||||
#endif
|
||||
#ifdef OSD_TRANSITION_PATTERN41
|
||||
UV.x = 1.0 - uv.y/2.0;
|
||||
UV.y = uv.x;
|
||||
#endif
|
||||
if (ti <= n0) {
|
||||
return 0.5 * (ti / n0);
|
||||
} else {
|
||||
return 0.5 * ((ti - n0) / n1) + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
float2
|
||||
GetTransitionParameterization(
|
||||
in HS_CONSTANT_FUNC_OUT input,
|
||||
in float2 uv)
|
||||
{
|
||||
float2 UV = uv.xy;
|
||||
if (UV.x == 0 && input.tessOuterHi[0] > 0) {
|
||||
UV.y = GetTransitionSplit(UV.y, input.tessOuterLo[0], input.tessOuterHi[0]);
|
||||
} else
|
||||
if (UV.y == 0 && input.tessOuterHi[1] > 0) {
|
||||
UV.x = GetTransitionSplit(UV.x, input.tessOuterLo[1], input.tessOuterHi[1]);
|
||||
} else
|
||||
if (UV.x == 1 && input.tessOuterHi[2] > 0) {
|
||||
UV.y = GetTransitionSplit(UV.y, input.tessOuterLo[2], input.tessOuterHi[2]);
|
||||
} else
|
||||
if (UV.y == 1 && input.tessOuterHi[3] > 0) {
|
||||
UV.x = GetTransitionSplit(UV.x, input.tessOuterLo[3], input.tessOuterHi[3]);
|
||||
}
|
||||
return UV;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user