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:
Takahito Tejima 2015-06-02 12:02:52 -07:00
parent 71470b1ab7
commit 1e02fbebf8
5 changed files with 259 additions and 109 deletions

View File

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

View File

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

View File

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

View File

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

View File

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