mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-27 05:50:05 +00:00
Sync HLSL shaders for the single crease orientation fix.
- add HLSL equivalents of the previous GLSL change - rename OsdGetSingleCreaseSegmentParameter to OsdGetPatchSingleCreaseSegmentParameter. - add shadingMode UI for dxViewer similar to glViewer
This commit is contained in:
parent
71470b1ab7
commit
1e02fbebf8
@ -91,10 +91,16 @@ enum KernelType { kCPU = 0,
|
||||
kCL = 4,
|
||||
kDirectCompute = 5 };
|
||||
|
||||
enum DisplayStyle { kWire = 0,
|
||||
kShaded,
|
||||
kWireShaded,
|
||||
kPoint };
|
||||
enum DisplayStyle { kDisplayStyleWire = 0,
|
||||
kDisplayStyleShaded,
|
||||
kDisplayStyleWireOnShaded };
|
||||
|
||||
enum ShadingMode { kShadingMaterial,
|
||||
kShadingPatchType,
|
||||
kShadingPatchCoord,
|
||||
kShadingNormal,
|
||||
kShadingCurvature,
|
||||
kShadingAnalyticCurvature };
|
||||
|
||||
enum EndCap { kEndCapNone = 0,
|
||||
kEndCapBSplineBasis,
|
||||
@ -119,7 +125,8 @@ int g_frame = 0,
|
||||
|
||||
// GUI variables
|
||||
int g_freeze = 0,
|
||||
g_displayStyle = kWireShaded,
|
||||
g_shadingMode = kShadingPatchType,
|
||||
g_displayStyle = kDisplayStyleWireOnShaded,
|
||||
g_adaptive = 1,
|
||||
g_endCap = kEndCapBSplineBasis,
|
||||
g_singleCreasePatch = 1,
|
||||
@ -423,8 +430,11 @@ fitFrame() {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
union Effect {
|
||||
Effect(int displayStyle_, int screenSpaceTess_, int fractionalSpacing_, int patchCull_, int singleCreasePatch_) : value(0) {
|
||||
Effect(int displayStyle_, int shadingMode_, int screenSpaceTess_,
|
||||
int fractionalSpacing_, int patchCull_, int singleCreasePatch_)
|
||||
: value(0) {
|
||||
displayStyle = displayStyle_;
|
||||
shadingMode = shadingMode_;
|
||||
screenSpaceTess = screenSpaceTess_;
|
||||
fractionalSpacing = fractionalSpacing_;
|
||||
patchCull = patchCull_;
|
||||
@ -432,7 +442,8 @@ union Effect {
|
||||
}
|
||||
|
||||
struct {
|
||||
unsigned int displayStyle:3;
|
||||
unsigned int displayStyle:2;
|
||||
unsigned int shadingMode:4;
|
||||
unsigned int screenSpaceTess:1;
|
||||
unsigned int fractionalSpacing:1;
|
||||
unsigned int patchCull:1;
|
||||
@ -468,6 +479,7 @@ static Effect
|
||||
GetEffect()
|
||||
{
|
||||
return Effect(g_displayStyle,
|
||||
g_shadingMode,
|
||||
g_screenSpaceTess,
|
||||
g_fractionalSpacing,
|
||||
g_patchCull,
|
||||
@ -517,19 +529,42 @@ public:
|
||||
if (effectDesc.desc.IsAdaptive()) gs_entry += "_smooth";
|
||||
|
||||
switch (effectDesc.effect.displayStyle) {
|
||||
case kWire:
|
||||
case kDisplayStyleWire:
|
||||
ss << "#define GEOMETRY_OUT_WIRE\n";
|
||||
gs_entry = gs_entry + "_wire";
|
||||
break;
|
||||
case kWireShaded:
|
||||
case kDisplayStyleWireOnShaded:
|
||||
ss << "#define GEOMETRY_OUT_LINE\n";
|
||||
gs_entry = gs_entry + "_wire";
|
||||
break;
|
||||
case kShaded:
|
||||
case kDisplayStyleShaded:
|
||||
ss << "#define GEOMETRY_OUT_FILL\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// shading mode
|
||||
switch(effectDesc.effect.shadingMode) {
|
||||
case kShadingMaterial:
|
||||
ss << "#define SHADING_MATERIAL\n";
|
||||
break;
|
||||
case kShadingPatchType:
|
||||
ss << "#define SHADING_PATCH_TYPE\n";
|
||||
break;
|
||||
case kShadingPatchCoord:
|
||||
ss << "#define SHADING_PATCH_COORD\n";
|
||||
break;
|
||||
case kShadingNormal:
|
||||
ss << "#define SHADING_NORMAL\n";
|
||||
break;
|
||||
case kShadingCurvature:
|
||||
ss << "#define SHADING_CURVATURE\n";
|
||||
break;
|
||||
case kShadingAnalyticCurvature:
|
||||
ss << "#define OSD_COMPUTE_NORMAL_DERIVATIVES\n";
|
||||
ss << "#define SHADING_ANALYTIC_CURVATURE\n";
|
||||
break;
|
||||
}
|
||||
|
||||
// need for patch color-coding : we need these defines in the fragment shader
|
||||
if (type == Far::PatchDescriptor::GREGORY) {
|
||||
ss << "#define OSD_PATCH_GREGORY\n";
|
||||
@ -641,6 +676,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::PatchArray const & patch) {
|
||||
float ModelViewMatrix[16];
|
||||
float ProjectionMatrix[16];
|
||||
float ModelViewProjectionMatrix[16];
|
||||
float ModelViewInverseMatrix[16];
|
||||
};
|
||||
|
||||
if (not g_pcbPerFrame) {
|
||||
@ -666,6 +702,7 @@ bindProgram(Effect effect, OpenSubdiv::Osd::PatchArray const & patch) {
|
||||
rotate(pData->ModelViewMatrix, g_rotate[0], 0, 1, 0);
|
||||
translate(pData->ModelViewMatrix, -g_center[0], -g_center[2], g_center[1]); // z-up model
|
||||
rotate(pData->ModelViewMatrix, -90, 1, 0, 0); // z-up model
|
||||
inverseMatrix(pData->ModelViewInverseMatrix, pData->ModelViewMatrix);
|
||||
|
||||
identity(pData->ProjectionMatrix);
|
||||
perspective(pData->ProjectionMatrix, 45.0, aspect, 0.01f, 500.0);
|
||||
@ -1062,6 +1099,12 @@ callbackDisplayNormal(bool checked, int n) {
|
||||
g_drawNormals = checked;
|
||||
}
|
||||
|
||||
static void
|
||||
callbackShadingMode(int b) {
|
||||
g_shadingMode = b;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
callbackAnimate(bool checked, int m) {
|
||||
g_moveScale = checked;
|
||||
@ -1146,19 +1189,35 @@ initHUD() {
|
||||
#endif
|
||||
g_hud->AddPullDownButton(compute_pulldown, "HLSL Compute", kDirectCompute);
|
||||
|
||||
int shading_pulldown = g_hud->AddPullDown("Shading (W)", 200, 10, 250, callbackDisplayStyle, 'W');
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Wire", 0, g_displayStyle==kWire);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Shaded", 1, g_displayStyle==kShaded);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Wire+Shaded", 2, g_displayStyle==kWireShaded);
|
||||
int displaystyle_pulldown = g_hud->AddPullDown("DisplayStyle (W)", 200, 10, 250,
|
||||
callbackDisplayStyle, 'w');
|
||||
g_hud->AddPullDownButton(displaystyle_pulldown, "Wire", kDisplayStyleWire,
|
||||
g_displayStyle == kDisplayStyleWire);
|
||||
g_hud->AddPullDownButton(displaystyle_pulldown, "Shaded", kDisplayStyleShaded,
|
||||
g_displayStyle == kDisplayStyleShaded);
|
||||
g_hud->AddPullDownButton(displaystyle_pulldown, "Wire+Shaded", kDisplayStyleWireOnShaded,
|
||||
g_displayStyle == kDisplayStyleWireOnShaded);
|
||||
|
||||
g_hud->AddCheckBox("Control edges (H)",
|
||||
g_controlMeshDisplay->GetEdgesDisplay(),
|
||||
10, 10, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_EDGES, 'H');
|
||||
g_hud->AddCheckBox("Control vertices (J)",
|
||||
g_controlMeshDisplay->GetVerticesDisplay(),
|
||||
10, 30, callbackCheckBox,
|
||||
kHUD_CB_DISPLAY_CONTROL_MESH_VERTS, 'J');
|
||||
int shading_pulldown = g_hud->AddPullDown("Shading (C)", 200, 70, 250,
|
||||
callbackShadingMode, 'c');
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Material",
|
||||
kShadingMaterial,
|
||||
g_shadingMode == kShadingMaterial);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Patch Type",
|
||||
kShadingPatchType,
|
||||
g_shadingMode == kShadingPatchType);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Patch Coord",
|
||||
kShadingPatchCoord,
|
||||
g_shadingMode == kShadingPatchCoord);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Normal",
|
||||
kShadingNormal,
|
||||
g_shadingMode == kShadingNormal);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Curvature",
|
||||
kShadingCurvature,
|
||||
g_shadingMode == kShadingCurvature);
|
||||
g_hud->AddPullDownButton(shading_pulldown, "Analytic Curvature",
|
||||
kShadingAnalyticCurvature,
|
||||
g_shadingMode == kShadingAnalyticCurvature);
|
||||
|
||||
g_hud->AddCheckBox("Patch CVs (L)", false, 10, 50, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_CVs, 'L');
|
||||
g_hud->AddCheckBox("Patch Color (P)", true, 10, 70, callbackCheckBox, kHUD_CB_DISPLAY_PATCH_COLOR, 'P');
|
||||
|
@ -30,6 +30,7 @@ cbuffer Transform : register( b0 ) {
|
||||
float4x4 ModelViewMatrix;
|
||||
float4x4 ProjectionMatrix;
|
||||
float4x4 ModelViewProjectionMatrix;
|
||||
float4x4 ModelViewInverseMatrix;
|
||||
};
|
||||
|
||||
cbuffer Tessellation : register( b1 ) {
|
||||
@ -348,7 +349,7 @@ edgeColor(float4 Cfill, float4 edgeDistance)
|
||||
}
|
||||
|
||||
float4
|
||||
getAdaptivePatchColor(int3 patchParam, float sharpness)
|
||||
getAdaptivePatchColor(int3 patchParam, float2 vSegments)
|
||||
{
|
||||
const float4 patchColors[7*6] = {
|
||||
float4(1.0f, 1.0f, 1.0f, 1.0f), // regular
|
||||
@ -402,12 +403,6 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
|
||||
};
|
||||
|
||||
int patchType = 0;
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
if (sharpness > 0) {
|
||||
patchType = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int pattern = countbits(OsdGetPatchTransitionMask(patchParam));
|
||||
int edgeCount = countbits(OsdGetPatchBoundaryMask(patchParam));
|
||||
if (edgeCount == 1) {
|
||||
@ -417,6 +412,12 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
|
||||
patchType = 3; // CORNER
|
||||
}
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
if (vSegments.y > 0) {
|
||||
patchType = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX: it looks like edgeCount != 0 for gregory_boundary.
|
||||
// there might be a bug somewhere.
|
||||
#if defined OSD_PATCH_GREGORY
|
||||
@ -441,15 +442,38 @@ ps_main( in OutputVertex input,
|
||||
bool isFrontFacing : SV_IsFrontFace,
|
||||
out float4 colorOut : SV_Target )
|
||||
{
|
||||
float sharpness = 0;
|
||||
float2 vSegments = float2(0,0);
|
||||
#ifdef OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
sharpness = input.vSegments.y;
|
||||
vSegments = input.vSegments;
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SHADING_PATCH_TYPE)
|
||||
float4 color = getAdaptivePatchColor(
|
||||
OsdGetPatchParam(OsdGetPatchIndex(primitiveID)), sharpness);
|
||||
OsdGetPatchParam(OsdGetPatchIndex(primitiveID)), vSegments);
|
||||
#elif defined(SHADING_PATCH_COORD)
|
||||
float4 color = float4(input.patchCoord.x, input.patchCoord.y, 0, 1);
|
||||
#elif defined(SHADING_MATERIAL)
|
||||
float4 color = float4(0.4, 0.4, 0.8, 1.0);
|
||||
#else
|
||||
float4 color = float4(1, 1, 1, 1);
|
||||
#endif
|
||||
|
||||
float3 N = (isFrontFacing ? input.normal : -input.normal);
|
||||
colorOut = edgeColor(lighting(color, input.position.xyz, N), input.edgeDistance);
|
||||
float3 Nobj = mul(ModelViewInverseMatrix, float4(input.normal, 0)).xyz;
|
||||
float4 Cf = lighting(color, input.position.xyz, N);
|
||||
|
||||
#if defined(SHADING_NORMAL)
|
||||
Cf.rgb = N;
|
||||
#elif defined(SHADING_CURVATURE)
|
||||
float3 pc = fwidth(input.position.xyz);
|
||||
Cf.rgb = 0.1 * fwidth(Nobj) / length(pc);
|
||||
#elif defined(SHADING_ANALYTIC_CURVATURE)
|
||||
int level = OsdGetPatchFaceLevel(OsdGetPatchParam(OsdGetPatchIndex(primitiveID)));
|
||||
Cf.rgb = 0.1 * level *(abs(input.Nu) + abs(input.Nv));
|
||||
#endif
|
||||
|
||||
colorOut = edgeColor(Cf, input.edgeDistance);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -186,7 +186,7 @@ void emit(int index, vec3 normal)
|
||||
#if defined(SHADING_ANALYTIC_CURVATURE)
|
||||
outpt.v.Nu = vec3(0);
|
||||
outpt.v.Nv = vec3(0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
@ -330,7 +330,6 @@ in block {
|
||||
} inpt;
|
||||
|
||||
out vec4 outColor;
|
||||
out vec3 outNormal;
|
||||
|
||||
#define NUM_LIGHTS 2
|
||||
|
||||
@ -525,7 +524,6 @@ main()
|
||||
#endif
|
||||
|
||||
outColor = Cf;
|
||||
outNormal = N;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -190,7 +190,7 @@ float OsdGetPatchSharpness(ivec3 patchParam)
|
||||
return intBitsToFloat(patchParam.z);
|
||||
}
|
||||
|
||||
float OsdGetSingleCreaseSegmentParameter(ivec3 patchParam, vec2 uv)
|
||||
float OsdGetPatchSingleCreaseSegmentParameter(ivec3 patchParam, vec2 uv)
|
||||
{
|
||||
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
|
||||
float s = 0;
|
||||
@ -471,7 +471,7 @@ OsdEvalBezier(OsdPerPatchVertexBezier cp[16], ivec3 patchParam, vec2 uv)
|
||||
vec3 BUCP[4] = vec3[4](vec3(0), vec3(0), vec3(0), vec3(0));
|
||||
|
||||
float B[4], D[4];
|
||||
float s = OsdGetSingleCreaseSegmentParameter(patchParam, uv);
|
||||
float s = OsdGetPatchSingleCreaseSegmentParameter(patchParam, uv);
|
||||
|
||||
OsdUnivar4x4(uv.x, B, D);
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
@ -909,6 +909,7 @@ OsdComputeMs(float sharpness)
|
||||
return m;
|
||||
}
|
||||
|
||||
// flip matrix orientation
|
||||
mat4
|
||||
OsdFlipMatrix(mat4 m)
|
||||
{
|
||||
@ -958,14 +959,14 @@ OsdComputePerPatchVertexBSpline(ivec3 patchParam, int ID, vec3 cv[16],
|
||||
Ms = (1-Sr) * Mf + Sr * Mc;
|
||||
float s0 = 1 - pow(2, -floor(sharpness));
|
||||
float s1 = 1 - pow(2, -ceil(sharpness));
|
||||
result.P = vec3(0); // 0 to 1-2^(-Sf)
|
||||
result.P1 = vec3(0); // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
result.P2 = vec3(0); // 1-2^(-Sc) to 1
|
||||
result.vSegments = vec2(s0, s1);
|
||||
} else {
|
||||
result.vSegments = vec2(0);
|
||||
Mj = Ms = Mi;
|
||||
result.vSegments = vec2(0);
|
||||
}
|
||||
result.P = vec3(0); // 0 to 1-2^(-Sf)
|
||||
result.P1 = vec3(0); // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
result.P2 = vec3(0); // 1-2^(-Sc) to 1
|
||||
|
||||
mat4 MUi, MUj, MUs;
|
||||
mat4 MVi, MVj, MVs;
|
||||
@ -1049,7 +1050,7 @@ OsdEvalPatchBezier(ivec3 patchParam, vec2 UV,
|
||||
// ----------------------------------------------------------------
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
vec2 vSegments = cv[0].vSegments;
|
||||
float s = OsdGetSingleCreaseSegmentParameter(patchParam, UV);
|
||||
float s = OsdGetPatchSingleCreaseSegmentParameter(patchParam, UV);
|
||||
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
|
@ -165,6 +165,22 @@ float OsdGetPatchSharpness(int3 patchParam)
|
||||
return asfloat(patchParam.z);
|
||||
}
|
||||
|
||||
float OsdGetPatchSingleCreaseSegmentParameter(int3 patchParam, float2 uv)
|
||||
{
|
||||
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
|
||||
float s = 0;
|
||||
if ((boundaryMask & 1) != 0) {
|
||||
s = 1 - uv.y;
|
||||
} else if ((boundaryMask & 2) != 0) {
|
||||
s = uv.x;
|
||||
} else if ((boundaryMask & 4) != 0) {
|
||||
s = uv.y;
|
||||
} else if ((boundaryMask & 8) != 0) {
|
||||
s = 1 - uv.x;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
int4 OsdGetPatchCoord(int3 patchParam)
|
||||
{
|
||||
int faceId = OsdGetPatchFaceId(patchParam);
|
||||
@ -323,23 +339,24 @@ OsdEvalBezier(float3 cp[16], float2 uv)
|
||||
// +------------------+-------------------+------------------+
|
||||
//
|
||||
float3
|
||||
OsdEvalBezier(OsdPerPatchVertexBezier cp[16], float2 uv)
|
||||
OsdEvalBezier(OsdPerPatchVertexBezier cp[16], int3 patchParam, float2 uv)
|
||||
{
|
||||
float3 BUCP[4] = {float3(0,0,0),float3(0,0,0),float3(0,0,0),float3(0,0,0)};
|
||||
|
||||
float B[4], D[4];
|
||||
float s = OsdGetPatchSingleCreaseSegmentParameter(patchParam, uv);
|
||||
|
||||
OsdUnivar4x4(uv.x, B, D);
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments = cp[0].vSegments;
|
||||
if (uv.y < vSegments.x) {
|
||||
if (s <= vSegments.x) {
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
float3 A = cp[4*i + j].P;
|
||||
BUCP[i] += A * B[j];
|
||||
}
|
||||
}
|
||||
} else if (uv.y < vSegments.y) {
|
||||
} else if (s <= vSegments.y) {
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
float3 A = cp[4*i + j].P1;
|
||||
@ -568,58 +585,63 @@ OsdGetTessLevelsLimitPoints(OsdPerPatchVertexBezier cpBezier[16],
|
||||
int transitionMask = OsdGetPatchTransitionMask(patchParam);
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
// PERFOMANCE: we just need to pick the correct corner points from P, P1, P2
|
||||
float3 p0 = OsdEvalBezier(cpBezier, patchParam, float2(0.0, 0.0));
|
||||
float3 p3 = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.0));
|
||||
float3 p12 = OsdEvalBezier(cpBezier, patchParam, float2(0.0, 1.0));
|
||||
float3 p15 = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 1.0));
|
||||
if ((transitionMask & 8) != 0) {
|
||||
float3 ev03 = OsdEvalBezier(cpBezier, float2(0.0, 0.5));
|
||||
tessOuterLo[0] = OsdComputeTessLevel(cpBezier[0].P, ev03);
|
||||
tessOuterHi[0] = OsdComputeTessLevel(cpBezier[12].P2, ev03);
|
||||
float3 ev03 = OsdEvalBezier(cpBezier, patchParam, float2(0.0, 0.5));
|
||||
tessOuterLo[0] = OsdComputeTessLevel(p0, ev03);
|
||||
tessOuterHi[0] = OsdComputeTessLevel(p12, ev03);
|
||||
} else {
|
||||
tessOuterLo[0] = OsdComputeTessLevel(cpBezier[0].P, cpBezier[12].P2);
|
||||
tessOuterLo[0] = OsdComputeTessLevel(p0, p12);
|
||||
}
|
||||
if ((transitionMask & 1) != 0) {
|
||||
float3 ev01 = OsdEvalBezier(cpBezier, float2(0.5, 0.0));
|
||||
tessOuterLo[1] = OsdComputeTessLevel(cpBezier[0].P, ev01);
|
||||
tessOuterHi[1] = OsdComputeTessLevel(cpBezier[3].P, ev01);
|
||||
float3 ev01 = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 0.0));
|
||||
tessOuterLo[1] = OsdComputeTessLevel(p0, ev01);
|
||||
tessOuterHi[1] = OsdComputeTessLevel(p3, ev01);
|
||||
} else {
|
||||
tessOuterLo[1] = OsdComputeTessLevel(cpBezier[0].P, cpBezier[3].P);
|
||||
tessOuterLo[1] = OsdComputeTessLevel(p0, p3);
|
||||
}
|
||||
if ((transitionMask & 2) != 0) {
|
||||
float3 ev12 = OsdEvalBezier(cpBezier, float2(1.0, 0.5));
|
||||
tessOuterLo[2] = OsdComputeTessLevel(cpBezier[3].P, ev12);
|
||||
tessOuterHi[2] = OsdComputeTessLevel(cpBezier[15].P2, ev12);
|
||||
float3 ev12 = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.5));
|
||||
tessOuterLo[2] = OsdComputeTessLevel(p3, ev12);
|
||||
tessOuterHi[2] = OsdComputeTessLevel(p15, ev12);
|
||||
} else {
|
||||
tessOuterLo[2] = OsdComputeTessLevel(cpBezier[3].P, cpBezier[15].P2);
|
||||
tessOuterLo[2] = OsdComputeTessLevel(p3, p15);
|
||||
}
|
||||
if ((transitionMask & 4) != 0) {
|
||||
float3 ev23 = OsdEvalBezier(cpBezier, float2(0.5, 1.0));
|
||||
tessOuterLo[3] = OsdComputeTessLevel(cpBezier[12].P2, ev23);
|
||||
tessOuterHi[3] = OsdComputeTessLevel(cpBezier[15].P2, ev23);
|
||||
float3 ev23 = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 1.0));
|
||||
tessOuterLo[3] = OsdComputeTessLevel(p12, ev23);
|
||||
tessOuterHi[3] = OsdComputeTessLevel(p15, ev23);
|
||||
} else {
|
||||
tessOuterLo[3] = OsdComputeTessLevel(cpBezier[12].P2, cpBezier[15].P2);
|
||||
tessOuterLo[3] = OsdComputeTessLevel(p12, p15);
|
||||
}
|
||||
#else
|
||||
if ((transitionMask & 8) != 0) {
|
||||
float3 ev03 = OsdEvalBezier(cpBezier, float2(0.0, 0.5));
|
||||
float3 ev03 = OsdEvalBezier(cpBezier, patchParam, float2(0.0, 0.5));
|
||||
tessOuterLo[0] = OsdComputeTessLevel(cpBezier[0].P, ev03);
|
||||
tessOuterHi[0] = OsdComputeTessLevel(cpBezier[12].P, ev03);
|
||||
} else {
|
||||
tessOuterLo[0] = OsdComputeTessLevel(cpBezier[0].P, cpBezier[12].P);
|
||||
}
|
||||
if ((transitionMask & 1) != 0) {
|
||||
float3 ev01 = OsdEvalBezier(cpBezier, float2(0.5, 0.0));
|
||||
float3 ev01 = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 0.0));
|
||||
tessOuterLo[1] = OsdComputeTessLevel(cpBezier[0].P, ev01);
|
||||
tessOuterHi[1] = OsdComputeTessLevel(cpBezier[3].P, ev01);
|
||||
} else {
|
||||
tessOuterLo[1] = OsdComputeTessLevel(cpBezier[0].P, cpBezier[3].P);
|
||||
}
|
||||
if ((transitionMask & 2) != 0) {
|
||||
float3 ev12 = OsdEvalBezier(cpBezier, float2(1.0, 0.5));
|
||||
float3 ev12 = OsdEvalBezier(cpBezier, patchParam, float2(1.0, 0.5));
|
||||
tessOuterLo[2] = OsdComputeTessLevel(cpBezier[3].P, ev12);
|
||||
tessOuterHi[2] = OsdComputeTessLevel(cpBezier[15].P, ev12);
|
||||
} else {
|
||||
tessOuterLo[2] = OsdComputeTessLevel(cpBezier[3].P, cpBezier[15].P);
|
||||
}
|
||||
if ((transitionMask & 4) != 0) {
|
||||
float3 ev23 = OsdEvalBezier(cpBezier, float2(0.5, 1.0));
|
||||
float3 ev23 = OsdEvalBezier(cpBezier, patchParam, float2(0.5, 1.0));
|
||||
tessOuterLo[3] = OsdComputeTessLevel(cpBezier[12].P, ev23);
|
||||
tessOuterHi[3] = OsdComputeTessLevel(cpBezier[15].P, ev23);
|
||||
} else {
|
||||
@ -759,6 +781,16 @@ OsdComputeMs(float sharpness)
|
||||
return m;
|
||||
}
|
||||
|
||||
// flip matrix orientation
|
||||
float4x4
|
||||
OsdFlipMatrix(float4x4 m)
|
||||
{
|
||||
return float4x4(m[3][3], m[3][2], m[3][1], m[3][0],
|
||||
m[2][3], m[2][2], m[2][1], m[2][0],
|
||||
m[1][3], m[1][2], m[1][1], m[1][0],
|
||||
m[0][3], m[0][2], m[0][1], m[0][0]);
|
||||
}
|
||||
|
||||
// convert BSpline cv to Bezier cv
|
||||
void
|
||||
OsdComputePerPatchVertexBSpline(int3 patchParam, int ID, float3 cv[16],
|
||||
@ -774,11 +806,85 @@ OsdComputePerPatchVertexBSpline(int3 patchParam, int ID, float3 cv[16],
|
||||
|
||||
result.patchParam = patchParam;
|
||||
|
||||
OsdComputeBSplineBoundaryPoints(cv, patchParam);
|
||||
|
||||
int i = ID%4;
|
||||
int j = ID/4;
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
|
||||
// Infinitely Sharp (boundary)
|
||||
float4x4 Mi = {
|
||||
1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f,
|
||||
0.f, 4.f/6.f, 2.f/6.f, 0.f,
|
||||
0.f, 2.f/6.f, 4.f/6.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f
|
||||
};
|
||||
|
||||
float4x4 Mj, Ms;
|
||||
float sharpness = OsdGetPatchSharpness(patchParam);
|
||||
if (sharpness > 0) {
|
||||
float Sf = floor(sharpness);
|
||||
float Sc = ceil(sharpness);
|
||||
float Sr = frac(sharpness);
|
||||
float4x4 Mf = OsdComputeMs(Sf);
|
||||
float4x4 Mc = OsdComputeMs(Sc);
|
||||
Mj = (1-Sr) * Mf + Sr * Mi;
|
||||
Ms = (1-Sr) * Mf + Sr * Mc;
|
||||
float s0 = 1 - pow(2, -floor(sharpness));
|
||||
float s1 = 1 - pow(2, -ceil(sharpness));
|
||||
result.vSegments = float2(s0, s1);
|
||||
|
||||
} else {
|
||||
Mj = Ms = Mi;
|
||||
result.vSegments = float2(0, 0);
|
||||
}
|
||||
result.P = float3(0,0,0); // 0 to 1-2^(-Sf)
|
||||
result.P1 = float3(0,0,0); // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
result.P2 = float3(0,0,0); // 1-2^(-Sc) to 1
|
||||
|
||||
float4x4 MUi, MUj, MUs;
|
||||
float4x4 MVi, MVj, MVs;
|
||||
MUi = MUj = MUs = Q;
|
||||
MVi = MVj = MVs = Q;
|
||||
|
||||
int boundaryMask = OsdGetPatchBoundaryMask(patchParam);
|
||||
if ((boundaryMask & 1) != 0) {
|
||||
MVi = OsdFlipMatrix(Mi);
|
||||
MVj = OsdFlipMatrix(Mj);
|
||||
MVs = OsdFlipMatrix(Ms);
|
||||
}
|
||||
if ((boundaryMask & 2) != 0) {
|
||||
MUi = Mi;
|
||||
MUj = Mj;
|
||||
MUs = Ms;
|
||||
}
|
||||
if ((boundaryMask & 4) != 0) {
|
||||
MVi = Mi;
|
||||
MVj = Mj;
|
||||
MVs = Ms;
|
||||
}
|
||||
if ((boundaryMask & 8) != 0) {
|
||||
MUi = OsdFlipMatrix(Mi);
|
||||
MUj = OsdFlipMatrix(Mj);
|
||||
MUs = OsdFlipMatrix(Ms);
|
||||
}
|
||||
|
||||
float3 Hi[4], Hj[4], Hs[4];
|
||||
for (int l=0; l<4; ++l) {
|
||||
Hi[l] = Hj[l] = Hs[l] = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k) {
|
||||
Hi[l] += MUi[i][k] * cv[l*4 + k];
|
||||
Hj[l] += MUj[i][k] * cv[l*4 + k];
|
||||
Hs[l] += MUs[i][k] * cv[l*4 + k];
|
||||
}
|
||||
}
|
||||
for (int k=0; k<4; ++k) {
|
||||
result.P += MVi[j][k]*Hi[k];
|
||||
result.P1 += MVj[j][k]*Hj[k];
|
||||
result.P2 += MVs[j][k]*Hs[k];
|
||||
}
|
||||
#else
|
||||
OsdComputeBSplineBoundaryPoints(cv, patchParam);
|
||||
|
||||
float3 H[4];
|
||||
for (int l=0; l<4; ++l) {
|
||||
H[l] = float3(0,0,0);
|
||||
@ -787,45 +893,6 @@ OsdComputePerPatchVertexBSpline(int3 patchParam, int ID, float3 cv[16],
|
||||
}
|
||||
}
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
// Infinitely Sharp (boundary)
|
||||
float4x4 Mi = {
|
||||
1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f,
|
||||
0.f, 4.f/6.f, 2.f/6.f, 0.f,
|
||||
0.f, 2.f/6.f, 4.f/6.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f
|
||||
};
|
||||
|
||||
float sharpness = OsdGetPatchSharpness(patchParam);
|
||||
if (sharpness > 0) {
|
||||
float Sf = floor(sharpness);
|
||||
float Sc = ceil(sharpness);
|
||||
float Sr = frac(sharpness);
|
||||
float4x4 Mf = OsdComputeMs(Sf);
|
||||
float4x4 Mc = OsdComputeMs(Sc);
|
||||
float4x4 Mj = (1-Sr) * Mf + Sr * Mi;
|
||||
float4x4 Ms = (1-Sr) * Mf + Sr * Mc;
|
||||
float s0 = 1 - pow(2, -floor(sharpness));
|
||||
float s1 = 1 - pow(2, -ceil(sharpness));
|
||||
result.P = float3(0,0,0);
|
||||
result.P1 = float3(0,0,0);
|
||||
result.P2 = float3(0,0,0);
|
||||
result.vSegments = float2(s0, s1);
|
||||
for (int k=0; k<4; ++k) {
|
||||
result.P += Mi[j][k]*H[k]; // 0 to 1-2^(-Sf)
|
||||
result.P1 += Mj[j][k]*H[k]; // 1-2^(-Sf) to 1-2^(-Sc)
|
||||
result.P2 += Ms[j][k]*H[k]; // 1-2^(-Sc) to 1
|
||||
}
|
||||
} else {
|
||||
result.P = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k){
|
||||
result.P += Q[j][k]*H[k];
|
||||
}
|
||||
result.P1 = result.P;
|
||||
result.P2 = result.P;
|
||||
result.vSegments = float2(0,0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
result.P = float3(0,0,0);
|
||||
for (int k=0; k<4; ++k){
|
||||
@ -857,10 +924,11 @@ OsdEvalPatchBezier(int3 patchParam, float2 UV,
|
||||
// ----------------------------------------------------------------
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments = cv[0].vSegments;
|
||||
float s = OsdGetPatchSingleCreaseSegmentParameter(patchParam, UV);
|
||||
|
||||
for (int i=0; i<4; ++i) {
|
||||
for (int j=0; j<4; ++j) {
|
||||
int k = 4*i + j;
|
||||
float s = UV.y;
|
||||
|
||||
float3 A = (s <= vSegments.x) ? cv[k].P
|
||||
: ((s <= vSegments.y) ? cv[k].P1
|
||||
@ -1043,7 +1111,7 @@ OsdEvalPatchGregory(int3 patchParam, float2 UV, float3 cv[20],
|
||||
dUV *= 9 * level;
|
||||
|
||||
float3 n = cross(dPu, dPv);
|
||||
float3 N = normalize(n);
|
||||
N = normalize(n);
|
||||
|
||||
float E = dot(dPu, dPu);
|
||||
float F = dot(dPu, dPv);
|
||||
|
Loading…
Reference in New Issue
Block a user