Merge pull request #511 from davidgyu/shadingRefactor

Sync'ed up GLSL and HLSL patch shader source.
This commit is contained in:
Takahito Tejima 2015-05-21 11:51:40 -07:00
commit 2008e6ca05
8 changed files with 398 additions and 493 deletions

View File

@ -37,7 +37,7 @@ out block {
void main()
{
outpt.v.position = OsdModelViewMatrix() * position;
outpt.v.position = position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
OSD_USER_VARYING_PER_VERTEX();
}
@ -180,7 +180,7 @@ void main()
barrier();
#endif
if (ID == 0) {
OSD_PATCH_CULL(OSD_PATCH_INPUT_SIZE);
OSD_PATCH_CULL(16);
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
// Gather bezier control points to compute limit surface tess levels
@ -315,9 +315,9 @@ void main()
#endif
// ----------------------------------------------------------------
vec3 WorldPos = vec3(0);
vec3 Tangent = vec3(0);
vec3 BiTangent = vec3(0);
vec3 position = vec3(0);
vec3 uTangent = vec3(0);
vec3 vTangent = vec3(0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
// used for weingarten term
@ -328,9 +328,9 @@ void main()
vec3 dUV = vec3(0);
for (int k=0; k<4; ++k) {
WorldPos += B[k] * BUCP[k];
Tangent += B[k] * DUCP[k];
BiTangent += D[k] * BUCP[k];
position += B[k] * BUCP[k];
uTangent += B[k] * DUCP[k];
vTangent += D[k] * BUCP[k];
dUU += B[k] * CUCP[k];
dVV += C[k] * BUCP[k];
@ -338,52 +338,49 @@ void main()
}
int level = inpt[0].v.patchCoord.z;
Tangent *= 3 * level;
BiTangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
vec3 n = cross(Tangent, BiTangent);
vec3 n = cross(uTangent, vTangent);
vec3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
vec3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
vec3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
outpt.v.tangent = Tangent;
outpt.v.bitangent = BiTangent;
outpt.v.Nu = Nu;
outpt.v.Nv = Nv;
#else
Univar4x4(UV.y, B, D);
for (int k=0; k<4; ++k) {
WorldPos += B[k] * BUCP[k];
Tangent += B[k] * DUCP[k];
BiTangent += D[k] * BUCP[k];
position += B[k] * BUCP[k];
uTangent += B[k] * DUCP[k];
vTangent += D[k] * BUCP[k];
}
int level = inpt[0].v.patchCoord.z;
Tangent *= 3 * level;
BiTangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
vec3 normal = normalize(cross(Tangent, BiTangent));
outpt.v.tangent = Tangent;
outpt.v.bitangent = BiTangent;
vec3 normal = normalize(cross(uTangent, vTangent));
#endif
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.position = OsdModelViewMatrix() * vec4(position, 1.0f);
outpt.v.normal = (OsdModelViewMatrix() * vec4(normal, 0.0f)).xyz;
outpt.v.tangent = (OsdModelViewMatrix() * vec4(uTangent, 0.0f)).xyz;
outpt.v.bitangent = (OsdModelViewMatrix() * vec4(vTangent, 0.0f)).xyz;
OSD_USER_VARYING_PER_EVAL_POINT(UV, 5, 6, 9, 10);

View File

@ -75,8 +75,6 @@
#undef OSD_FRACTIONAL_ODD_SPACING
#undef OSD_FRACTIONAL_EVEN_SPACING
#define OSD_PATCH_INPUT_SIZE 16
#define M_PI 3.14159265359f
#if __VERSION__ < 420
@ -532,8 +530,8 @@ OsdComputeBSplineBoundaryPoints(inout vec3 cpt[16], ivec3 patchParam)
float OsdComputePostProjectionSphereExtent(vec3 center, float diameter)
{
vec4 p = OsdProjectionMatrix() * vec4(center, 1.0);
return abs(diameter * OsdProjectionMatrix()[1][1] / p.w);
vec4 p = OsdModelViewProjectionMatrix() * vec4(center, 1.0);
return abs(diameter * OsdModelViewProjectionMatrix()[1][1] / p.w);
}
float OsdComputeTessLevel(vec3 p0, vec3 p1)

View File

@ -43,7 +43,6 @@ uniform float ef[27] = float[](
);
#endif
float cosfn(uint n, uint j) {
return cos((2.0f * M_PI * j)/float(n));
}
@ -68,23 +67,34 @@ out block {
OSD_USER_VARYING_DECLARE
} outpt;
vec3 readVertex(uint vertexIndex)
vec3 OsdReadVertex(uint vertexIndex)
{
vertexIndex += OsdBaseVertex();
return vec3(texelFetch(OsdVertexBuffer, int(OSD_NUM_ELEMENTS*vertexIndex)).x,
texelFetch(OsdVertexBuffer, int(OSD_NUM_ELEMENTS*vertexIndex+1)).x,
texelFetch(OsdVertexBuffer, int(OSD_NUM_ELEMENTS*vertexIndex+2)).x);
int index = int(OSD_NUM_ELEMENTS * (vertexIndex + OsdBaseVertex()));
return vec3(texelFetch(OsdVertexBuffer, index).x,
texelFetch(OsdVertexBuffer, index+1).x,
texelFetch(OsdVertexBuffer, index+2).x);
}
int OsdReadVertexValence(int vertexID)
{
int index = int(vertexID * (2 * OSD_MAX_VALENCE + 1));
return texelFetch(OsdValenceBuffer, index).x;
}
int OsdReadVertexIndex(int vertexID, uint valenceVertex)
{
int index = int(vertexID * (2 * OSD_MAX_VALENCE + 1) + 1 + valenceVertex);
return texelFetch(OsdValenceBuffer, index).x;
}
void main()
{
int vID = gl_VertexID;
outpt.v.hullPosition = (OsdModelViewMatrix() * position).xyz;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
OSD_USER_VARYING_PER_VERTEX();
int ivalence = texelFetch(OsdValenceBuffer,int(vID * (2 * OSD_MAX_VALENCE + 1))).x;
int ivalence = OsdReadVertexValence(vID);
outpt.v.valence = ivalence;
uint valence = uint(abs(ivalence));
@ -104,11 +114,11 @@ void main()
uint im=(i+valence-1)%valence;
uint ip=(i+1)%valence;
uint idx_neighbor = uint(texelFetch(OsdValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)).x);
uint idx_neighbor = uint(OsdReadVertexIndex(vID, 2*i));
#ifdef OSD_PATCH_GREGORY_BOUNDARY
bool isBoundaryNeighbor = false;
int valenceNeighbor = texelFetch(OsdValenceBuffer,int(idx_neighbor * (2*OSD_MAX_VALENCE+1))).x;
int valenceNeighbor = OsdReadVertexValence(int(idx_neighbor));
if (valenceNeighbor < 0) {
isBoundaryNeighbor = true;
@ -116,7 +126,7 @@ void main()
boundaryEdgeNeighbors[currNeighbor] = int(idx_neighbor);
}
currNeighbor++;
if (currNeighbor == 1) {
if (currNeighbor == 1) {
ibefore = i;
zerothNeighbor = i;
} else {
@ -130,23 +140,19 @@ void main()
}
#endif
vec3 neighbor = readVertex(idx_neighbor);
vec3 neighbor = OsdReadVertex(idx_neighbor);
uint idx_diagonal = uint(texelFetch(OsdValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)).x);
uint idx_diagonal = uint(OsdReadVertexIndex(vID, 2*i + 1));
vec3 diagonal = OsdReadVertex(idx_diagonal);
vec3 diagonal = readVertex(idx_diagonal);
uint idx_neighbor_p = uint(OsdReadVertexIndex(vID, 2*ip));
vec3 neighbor_p = OsdReadVertex(idx_neighbor_p);
uint idx_neighbor_p = uint(texelFetch(OsdValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)).x);
uint idx_neighbor_m = uint(OsdReadVertexIndex(vID, 2*im));
vec3 neighbor_m = OsdReadVertex(idx_neighbor_m);
vec3 neighbor_p = readVertex(idx_neighbor_p);
uint idx_neighbor_m = uint(texelFetch(OsdValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)).x);
vec3 neighbor_m = readVertex(idx_neighbor_m);
uint idx_diagonal_m = uint(texelFetch(OsdValenceBuffer, int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)).x);
vec3 diagonal_m = readVertex(idx_diagonal_m);
uint idx_diagonal_m = uint(OsdReadVertexIndex(vID, 2*im + 1));
vec3 diagonal_m = OsdReadVertex(idx_diagonal_m);
f[i] = (pos * float(valence) + (neighbor_p + neighbor)*2.0f + diagonal) / (float(valence)+5.0f);
@ -178,18 +184,15 @@ void main()
if (ivalence < 0) {
if (valence > 2) {
outpt.v.position = (
readVertex(boundaryEdgeNeighbors[0]) +
readVertex(boundaryEdgeNeighbors[1]) +
4.0f * pos)/6.0f;
outpt.v.position = (OsdReadVertex(boundaryEdgeNeighbors[0]) +
OsdReadVertex(boundaryEdgeNeighbors[1]) +
4.0f * pos)/6.0f;
} else {
outpt.v.position = pos;
outpt.v.position = pos;
}
outpt.v.e0 = (
readVertex(boundaryEdgeNeighbors[0]) -
readVertex(boundaryEdgeNeighbors[1])
)/6.0;
outpt.v.e0 = (OsdReadVertex(boundaryEdgeNeighbors[0]) -
OsdReadVertex(boundaryEdgeNeighbors[1]))/6.0;
float k = float(float(valence) - 1.0f); //k is the number of faces
float c = cos(M_PI/k);
@ -198,14 +201,13 @@ void main()
float alpha_0k = -((1.0f+2.0f*c)*sqrt(1.0f+c))/((3.0f*k+c)*sqrt(1.0f-c));
float beta_0 = s/(3.0f*k + c);
int idx_diagonal = texelFetch(OsdValenceBuffer,int((vID) * (2*OSD_MAX_VALENCE+1) + 2*zerothNeighbor + 1 + 1)).x;
int idx_diagonal = OsdReadVertexIndex(vID, 2*zerothNeighbor + 1);
idx_diagonal = abs(idx_diagonal);
vec3 diagonal = readVertex(idx_diagonal);
vec3 diagonal = OsdReadVertex(idx_diagonal);
outpt.v.e1 = gamma * pos +
alpha_0k * readVertex(boundaryEdgeNeighbors[0]) +
alpha_0k * readVertex(boundaryEdgeNeighbors[1]) +
outpt.v.e1 = gamma * pos +
alpha_0k * OsdReadVertex(boundaryEdgeNeighbors[0]) +
alpha_0k * OsdReadVertex(boundaryEdgeNeighbors[1]) +
beta_0 * diagonal;
for (uint x=1; x<valence - 1; ++x) {
@ -213,16 +215,14 @@ void main()
float alpha = (4.0f*sin((M_PI * float(x))/k))/(3.0f*k+c);
float beta = (sin((M_PI * float(x))/k) + sin((M_PI * float(x+1))/k))/(3.0f*k+c);
int idx_neighbor = texelFetch(OsdValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 0 + 1)).x;
int idx_neighbor = OsdReadVertexIndex(vID, 2*curri);
idx_neighbor = abs(idx_neighbor);
vec3 neighbor = OsdReadVertex(idx_neighbor);
vec3 neighbor = readVertex(idx_neighbor);
idx_diagonal = OsdReadVertexIndex(vID, 2*curri + 1);
diagonal = OsdReadVertex(idx_diagonal);
idx_diagonal = texelFetch(OsdValenceBuffer, int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 1 + 1)).x;
diagonal = readVertex(idx_diagonal);
outpt.v.e1 += alpha * neighbor + beta * diagonal;
outpt.v.e1 += alpha * neighbor + beta * diagonal;
}
outpt.v.e1 /= 3.0f;
@ -241,6 +241,12 @@ layout(vertices = 4) out;
uniform isamplerBuffer OsdQuadOffsetBuffer;
int OsdReadQuadOffset(int primitiveID, uint offsetVertex)
{
int index = int(4*primitiveID+OsdGregoryQuadOffsetBase() + offsetVertex);
return texelFetch(OsdQuadOffsetBuffer, index).x;
}
in block {
GregControlVertex v;
OSD_USER_VARYING_DECLARE
@ -260,16 +266,15 @@ void main()
uint im = (i+3)%4;
uint valence = abs(inpt[i].v.valence);
uint n = valence;
int base = OsdGregoryQuadOffsetBase();
outpt[ID].v.position = inpt[ID].v.position;
uint start = uint(texelFetch(OsdQuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0x00ffu;
uint prev = uint(texelFetch(OsdQuadOffsetBuffer, int(4*gl_PrimitiveID+base + i)).x) & 0xff00u;
uint start = uint(OsdReadQuadOffset(gl_PrimitiveID, i)) & 0x00ffu;
uint prev = uint(OsdReadQuadOffset(gl_PrimitiveID, i)) & 0xff00u;
prev = uint(prev/256);
uint start_m = uint(texelFetch(OsdQuadOffsetBuffer, int(4*gl_PrimitiveID+base + im)).x) & 0x00ffu;
uint prev_p = uint(texelFetch(OsdQuadOffsetBuffer, int(4*gl_PrimitiveID+base + ip)).x) & 0xff00u;
uint start_m = uint(OsdReadQuadOffset(gl_PrimitiveID, im)) & 0x00ffu;
uint prev_p = uint(OsdReadQuadOffset(gl_PrimitiveID, ip)) & 0xff00u;
prev_p = uint(prev_p/256);
uint np = abs(inpt[ip].v.valence);
@ -333,12 +338,12 @@ void main()
if (inpt[i].v.valence > 2) {
Ep = inpt[i].v.position + inpt[i].v.e0*cosfn(n, start) + inpt[i].v.e1*sinfn(n, start);
Em = inpt[i].v.position + inpt[i].v.e0*cosfn(n, prev ) + inpt[i].v.e1*sinfn(n, prev);
Em = inpt[i].v.position + inpt[i].v.e0*cosfn(n, prev ) + inpt[i].v.e1*sinfn(n, prev);
float s1=3-2*cosfn(n,1)-cosfn(np,1);
float s2=2*cosfn(n,1);
Fp = (cosfn(np,1)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
Fp = (cosfn(np,1)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
s1 = 3.0f-2.0f*cos(2.0f*M_PI/float(n))-cos(2.0f*M_PI/float(nm));
Fm = (cosfn(nm,1)*inpt[i].v.position + s1*Em + s2*Ep_im - inpt[i].v.r[prev])/3.0f;
@ -355,7 +360,7 @@ void main()
float s1 = 3-2*cosfn(n,1)-cosfn(np,1);
float s2 = 2*cosfn(n,1);
Fp = (cosfn(np,1)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
Fp = (cosfn(np,1)*inpt[i].v.position + s1*Ep + s2*Em_ip + inpt[i].v.r[start])/3.0f;
s1 = 3.0f-2.0f*cos(2.0f*M_PI/float(n))-cos(2.0f*M_PI/float(nm));
Fm = (cosfn(nm,1)*inpt[i].v.position + s1*Em + s2*Ep_im - inpt[i].v.r[prev])/3.0f;
@ -411,19 +416,8 @@ void main()
vec4 tessLevelOuter = vec4(0);
vec2 tessLevelInner = vec2(0);
vec3 p[4];
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
p[0] = (OsdModelViewMatrix() * vec4(inpt[0].v.position, 1)).xyz;
p[1] = (OsdModelViewMatrix() * vec4(inpt[1].v.position, 1)).xyz;
p[2] = (OsdModelViewMatrix() * vec4(inpt[2].v.position, 1)).xyz;
p[3] = (OsdModelViewMatrix() * vec4(inpt[3].v.position, 1)).xyz;
#else
p[0] = inpt[0].v.position.xyz;
p[1] = inpt[1].v.position.xyz;
p[2] = inpt[2].v.position.xyz;
p[3] = inpt[3].v.position.xyz;
#endif
OsdGetTessLevels(p[0], p[3], p[2], p[1],
OsdGetTessLevels(inpt[0].v.position.xyz, inpt[3].v.position.xyz,
inpt[2].v.position.xyz, inpt[1].v.position.xyz,
patchParam, tessLevelOuter, tessLevelInner);
gl_TessLevelOuter[0] = tessLevelOuter[0];
@ -463,8 +457,7 @@ out block {
void main()
{
float u = gl_TessCoord.x,
v = gl_TessCoord.y;
vec2 UV = gl_TessCoord.xy;
vec3 p[20];
@ -494,6 +487,7 @@ void main()
vec3 q[16];
float u = UV.x, v=UV.y;
float U = 1-u, V=1-v;
float d11 = u+v; if(u+v==0.0f) d11 = 1.0f;
@ -519,9 +513,9 @@ void main()
q[14] = p[11];
q[15] = p[10];
vec3 WorldPos = vec3(0, 0, 0);
vec3 Tangent = vec3(0, 0, 0);
vec3 BiTangent = vec3(0, 0, 0);
vec3 position = vec3(0, 0, 0);
vec3 uTangent = vec3(0, 0, 0);
vec3 vTangent = vec3(0, 0, 0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
float B[4], D[4], C[4];
@ -532,7 +526,7 @@ void main()
vec3 dVV = vec3(0);
vec3 dUV = vec3(0);
Univar4x4(u, B, D, C);
Univar4x4(UV.x, B, D, C);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -543,54 +537,48 @@ void main()
}
}
Univar4x4(v, B, D, C);
Univar4x4(UV.y, B, D, C);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
dUU += B[i] * CUCP[i];
dVV += C[i] * BUCP[i];
dUV += D[i] * DUCP[i];
}
int level = inpt[0].v.patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
vec3 n = cross(Tangent, BiTangent);
vec3 n = cross(uTangent, vTangent);
vec3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
vec3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
vec3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
BiTangent = (OsdModelViewMatrix() * vec4(BiTangent, 0)).xyz;
Tangent = (OsdModelViewMatrix() * vec4(Tangent, 0)).xyz;
normal = normalize(cross(Tangent, BiTangent));
outpt.v.Nu = Nu;
outpt.v.Nv = Nv;
#else
float B[4], D[4];
vec3 BUCP[4] = vec3[4](vec3(0,0,0), vec3(0,0,0), vec3(0,0,0), vec3(0,0,0)),
DUCP[4] = vec3[4](vec3(0,0,0), vec3(0,0,0), vec3(0,0,0), vec3(0,0,0));
Univar4x4(u, B, D);
Univar4x4(UV.x, B, D);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -600,30 +588,24 @@ void main()
}
}
Univar4x4(v, B, D);
Univar4x4(UV.y, B, D);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
}
int level = inpt[0].v.patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
BiTangent = (OsdModelViewMatrix() * vec4(BiTangent, 0)).xyz;
Tangent = (OsdModelViewMatrix() * vec4(Tangent, 0)).xyz;
vec3 normal = normalize(cross(Tangent, BiTangent));
uTangent *= 3 * level;
vTangent *= 3 * level;
vec3 normal = normalize(cross(uTangent, vTangent));
#endif
outpt.v.position = OsdModelViewMatrix() * vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.tangent = Tangent;
outpt.v.bitangent = BiTangent;
vec2 UV = vec2(u, v);
outpt.v.position = OsdModelViewMatrix() * vec4(position, 1.0f);
outpt.v.normal = (OsdModelViewMatrix() * vec4(normal, 0.0f)).xyz;
outpt.v.tangent = (OsdModelViewMatrix() * vec4(uTangent, 0.0f)).xyz;
outpt.v.bitangent = (OsdModelViewMatrix() * vec4(vTangent, 0.0f)).xyz;
OSD_USER_VARYING_PER_EVAL_POINT(UV, 0, 1, 3, 2);
@ -632,7 +614,7 @@ void main()
OSD_DISPLACEMENT_CALLBACK;
gl_Position = OsdModelViewProjectionMatrix() * vec4(WorldPos, 1.0f);
gl_Position = OsdProjectionMatrix() * outpt.v.position;
}
#endif

View File

@ -37,7 +37,7 @@ out block {
void main()
{
outpt.v.position = OsdModelViewMatrix() * position;
outpt.v.position = position;
outpt.v.patchCoord = ivec4(0);
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(position);
OSD_USER_VARYING_PER_VERTEX();
@ -74,7 +74,7 @@ void main()
outpt[ID].v.patchCoord = OsdGetPatchCoord(patchParam);
if (ID == 0) {
OSD_PATCH_CULL(OSD_PATCH_INPUT_SIZE);
OSD_PATCH_CULL(20);
vec4 tessLevelOuter = vec4(0);
vec2 tessLevelInner = vec2(0);
@ -120,16 +120,15 @@ out block {
void main()
{
float u = gl_TessCoord.x,
v = gl_TessCoord.y;
vec2 UV = gl_TessCoord.xy;
vec3 p[20];
for (int i = 0; i < 20; ++i) {
p[i] = inpt[i].v.position.xyz;
}
vec3 q[16];
float u = UV.x, v=UV.y;
float U = 1-u, V=1-v;
float d11 = u+v; if(u+v==0.0f) d11 = 1.0f;
@ -137,17 +136,10 @@ void main()
float d21 = u+V; if(u+V==0.0f) d21 = 1.0f;
float d22 = U+V; if(U+V==0.0f) d22 = 1.0f;
#if 1
q[ 5] = (u*p[3] + v*p[4])/d11;
q[ 6] = (U*p[9] + v*p[8])/d12;
q[ 9] = (u*p[19] + V*p[18])/d21;
q[10] = (U*p[13] + V*p[14])/d22;
#else
q[ 5] = (p[3] + p[4])/2.0;
q[ 6] = (p[9] + p[8])/2.0;
q[ 9] = (p[19] + p[18])/2.0;
q[10] = (p[13] + p[14])/2.0;
#endif
q[ 0] = p[0];
q[ 1] = p[1];
@ -162,9 +154,9 @@ void main()
q[14] = p[11];
q[15] = p[10];
vec3 WorldPos = vec3(0, 0, 0);
vec3 Tangent = vec3(0, 0, 0);
vec3 BiTangent = vec3(0, 0, 0);
vec3 position = vec3(0, 0, 0);
vec3 uTangent = vec3(0, 0, 0);
vec3 vTangent = vec3(0, 0, 0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
float B[4], D[4], C[4];
@ -175,7 +167,7 @@ void main()
vec3 dVV = vec3(0);
vec3 dUV = vec3(0);
Univar4x4(u, B, D, C);
Univar4x4(UV.x, B, D, C);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -186,49 +178,48 @@ void main()
}
}
Univar4x4(v, B, D, C);
Univar4x4(UV.y, B, D, C);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
dUU += B[i] * CUCP[i];
dVV += C[i] * BUCP[i];
dUV += D[i] * DUCP[i];
}
int level = inpt[0].v.patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
vec3 n = cross(Tangent, BiTangent);
vec3 n = cross(uTangent, vTangent);
vec3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
vec3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
vec3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
vec3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
outpt.v.Nu = Nu;
outpt.v.Nv = Nv;
#else
float B[4], D[4];
vec3 BUCP[4] = vec3[4](vec3(0,0,0), vec3(0,0,0), vec3(0,0,0), vec3(0,0,0)),
DUCP[4] = vec3[4](vec3(0,0,0), vec3(0,0,0), vec3(0,0,0), vec3(0,0,0));
Univar4x4(u, B, D);
Univar4x4(UV.x, B, D);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -238,26 +229,24 @@ void main()
}
}
Univar4x4(v, B, D);
Univar4x4(UV.y, B, D);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
}
int level = inpt[0].v.patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
vec3 normal = normalize(cross(Tangent, BiTangent));
uTangent *= 3 * level;
vTangent *= 3 * level;
vec3 normal = normalize(cross(uTangent, vTangent));
#endif
outpt.v.position = vec4(WorldPos, 1.0f);
outpt.v.normal = normal;
outpt.v.tangent = Tangent;
outpt.v.bitangent = BiTangent;
vec2 UV = vec2(u, v);
outpt.v.position = OsdModelViewMatrix() * vec4(position, 1.0f);
outpt.v.normal = (OsdModelViewMatrix() * vec4(normal, 0.0f)).xyz;
outpt.v.tangent = (OsdModelViewMatrix() * vec4(uTangent, 0.0f)).xyz;
outpt.v.bitangent = (OsdModelViewMatrix() * vec4(vTangent, 0.0f)).xyz;
OSD_USER_VARYING_PER_EVAL_POINT(UV, 0, 5, 15, 10);

View File

@ -37,7 +37,7 @@
void vs_main_patches( in InputVertex input,
out HullVertex output )
{
output.position = mul(OsdModelViewMatrix(), input.position);
output.position = input.position;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(input.position);
}
@ -81,49 +81,6 @@ ComputeMatrixSimplified(float sharpness)
return m;
}
HS_CONSTANT_FUNC_OUT
HSConstFunc(
InputPatch<HullVertex, 16> patch,
OutputPatch<HullVertex, 16> bezierPatch,
uint primitiveID : SV_PrimitiveID)
{
HS_CONSTANT_FUNC_OUT output;
float3 position[16];
for (int p=0; p<16; ++p) {
position[p] = bezierPatch[p].position.xyz;
}
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
OsdComputeBSplineBoundaryPoints(position, patchParam);
OSD_PATCH_CULL(16);
float4 tessLevelOuter = float4(0,0,0,0);
float4 tessLevelInner = float4(0,0,0,0);
float4 tessOuterLo = float4(0,0,0,0);
float4 tessOuterHi = float4(0,0,0,0);
OsdGetTessLevels(position, patchParam,
tessLevelOuter, tessLevelInner,
tessOuterLo, tessOuterHi);
output.tessLevelOuter[0] = tessLevelOuter[0];
output.tessLevelOuter[1] = tessLevelOuter[1];
output.tessLevelOuter[2] = tessLevelOuter[2];
output.tessLevelOuter[3] = tessLevelOuter[3];
output.tessLevelInner[0] = tessLevelInner[0];
output.tessLevelInner[1] = tessLevelInner[1];
output.tessOuterLo = tessOuterLo;
output.tessOuterHi = tessOuterHi;
return output;
}
[domain("quad")]
[partitioning(HS_PARTITION)]
[outputtopology("triangle_cw")]
@ -187,11 +144,13 @@ HullVertex hs_main_patches(
output.sharpness = 0;
}
#else
float3 pos = float3(0,0,0);
for (int k=0; k<4; ++k){
pos += Q[j][k]*H[k];
{
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.position = float4(pos, 1.0);
#endif
output.patchCoord = OsdGetPatchCoord(patchParam);
@ -199,6 +158,48 @@ HullVertex hs_main_patches(
return output;
}
HS_CONSTANT_FUNC_OUT
HSConstFunc(
InputPatch<HullVertex, 16> patch,
OutputPatch<HullVertex, 16> bezierPatch,
uint primitiveID : SV_PrimitiveID)
{
HS_CONSTANT_FUNC_OUT output;
float3 position[16];
for (int p=0; p<16; ++p) {
position[p] = bezierPatch[p].position.xyz;
}
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
OsdComputeBSplineBoundaryPoints(position, patchParam);
OSD_PATCH_CULL(16);
float4 tessLevelOuter = float4(0,0,0,0);
float4 tessLevelInner = float4(0,0,0,0);
float4 tessOuterLo = float4(0,0,0,0);
float4 tessOuterHi = float4(0,0,0,0);
OsdGetTessLevels(position, patchParam,
tessLevelOuter, tessLevelInner,
tessOuterLo, tessOuterHi);
output.tessLevelOuter[0] = tessLevelOuter[0];
output.tessLevelOuter[1] = tessLevelOuter[1];
output.tessLevelOuter[2] = tessLevelOuter[2];
output.tessLevelOuter[3] = tessLevelOuter[3];
output.tessLevelInner[0] = tessLevelInner[0];
output.tessLevelInner[1] = tessLevelInner[1];
output.tessOuterLo = tessOuterLo;
output.tessOuterHi = tessOuterHi;
return output;
}
//----------------------------------------------------------
// Patches.DomainBSpline
//----------------------------------------------------------
@ -282,9 +283,9 @@ void ds_main_patches(
#endif
// ----------------------------------------------------------------
float3 WorldPos = float3(0,0,0);
float3 Tangent = float3(0,0,0);
float3 BiTangent = float3(0,0,0);
float3 position = float3(0,0,0);
float3 uTangent = float3(0,0,0);
float3 vTangent = float3(0,0,0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
// used for weingarten term
@ -295,9 +296,9 @@ void ds_main_patches(
float3 dUV = float3(0,0,0);
for (int k=0; k<4; ++k) {
WorldPos += B[k] * BUCP[k];
Tangent += B[k] * DUCP[k];
BiTangent += D[k] * BUCP[k];
position += B[k] * BUCP[k];
uTangent += B[k] * DUCP[k];
vTangent += D[k] * BUCP[k];
dUU += B[k] * CUCP[k];
dVV += C[k] * BUCP[k];
@ -305,58 +306,54 @@ void ds_main_patches(
}
int level = patch[0].patchCoord.z;
Tangent *= 3 * level;
BiTangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
float3 n = cross(Tangent, BiTangent);
float3 n = cross(uTangent, vTangent);
float3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
float3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
float3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
output.tangent = Tangent;
output.bitangent = BiTangent;
output.Nu = Nu;
output.Nv = Nv;
#else
Univar4x4(UV.y, B, D);
for (int k=0; k<4; ++k) {
WorldPos += B[k] * BUCP[k];
Tangent += B[k] * DUCP[k];
BiTangent += D[k] * BUCP[k];
position += B[k] * BUCP[k];
uTangent += B[k] * DUCP[k];
vTangent += D[k] * BUCP[k];
}
int level = patch[0].patchCoord.z;
Tangent *= 3 * level;
BiTangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
float3 normal = normalize(cross(Tangent, BiTangent));
output.tangent = Tangent;
output.bitangent = BiTangent;
float3 normal = normalize(cross(uTangent, vTangent));
#endif
output.position = float4(WorldPos, 1.0f);
output.normal = normal;
output.position = mul(OsdModelViewMatrix(), float4(position, 1.0f));
output.normal = mul(OsdModelViewMatrix(), float4(normal, 0.0f)).xyz;
output.tangent = mul(OsdModelViewMatrix(), float4(uTangent, 0.0f)).xyz;
output.bitangent = mul(OsdModelViewMatrix(), float4(vTangent, 0.0f)).xyz;
output.patchCoord = OsdInterpolatePatchCoord(UV, patch[0].patchCoord);
OSD_DISPLACEMENT_CALLBACK;
output.positionOut = mul(OsdProjectionMatrix(),
float4(output.position.xyz, 1.0f));
output.positionOut = mul(OsdProjectionMatrix(), output.position);
output.edgeDistance = 0;
}

View File

@ -407,8 +407,8 @@ OsdComputeBSplineBoundaryPoints(inout float3 cpt[16], int3 patchParam)
float OsdComputePostProjectionSphereExtent(float3 center, float diameter)
{
float4 p = mul(OsdProjectionMatrix(), float4(center, 1.0));
return abs(diameter * OsdProjectionMatrix()[1][1] / p.w);
float4 p = mul(OsdModelViewProjectionMatrix(), float4(center, 1.0));
return abs(diameter * OsdModelViewProjectionMatrix()[1][1] / p.w);
}
float OsdComputeTessLevel(float3 p0, float3 p1)

View File

@ -59,22 +59,40 @@ float sinfn(uint n, uint j) {
return sin((2.0f * M_PI * j)/float(n));
}
//----------------------------------------------------------
// Patches.TessVertexGregory
//----------------------------------------------------------
Buffer<float> VertexBuffer : register( t2 );
Buffer<float> OsdVertexBuffer : register( t2 );
Buffer<int> OsdValenceBuffer : register( t3 );
float3 OsdReadVertex(uint vertexIndex)
{
int index = int(OSD_NUM_ELEMENTS * (vertexIndex /*+ OsdBaseVertex()*/));
return float3(OsdVertexBuffer[index],
OsdVertexBuffer[index+1],
OsdVertexBuffer[index+2]);
}
int OsdReadVertexValence(int vertexID)
{
int index = int(vertexID * (2 * OSD_MAX_VALENCE + 1));
return OsdValenceBuffer[index];
}
int OsdReadVertexIndex(int vertexID, uint valenceVertex)
{
int index = int(vertexID * (2 * OSD_MAX_VALENCE + 1) + 1 + valenceVertex);
return OsdValenceBuffer[index];
}
void vs_main_patches( in InputVertex input,
uint vID : SV_VertexID,
out GregHullVertex output )
{
output.hullPosition = mul(OsdModelViewMatrix(), input.position).xyz;
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(input.position);
int ivalence = OsdValenceBuffer[int(vID * (2 * OSD_MAX_VALENCE + 1))];
int ivalence = OsdReadVertexValence(vID);
output.valence = ivalence;
uint valence = uint(abs(ivalence));
@ -94,11 +112,11 @@ void vs_main_patches( in InputVertex input,
uint im=(i+valence-1)%valence;
uint ip=(i+1)%valence;
uint idx_neighbor = uint(OsdValenceBuffer[int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 0 + 1)]);
uint idx_neighbor = uint(OsdReadVertexIndex(vID, 2*i));
#ifdef OSD_PATCH_GREGORY_BOUNDARY
bool isBoundaryNeighbor = false;
int valenceNeighbor = OsdValenceBuffer[int(idx_neighbor * (2*OSD_MAX_VALENCE+1))];
int valenceNeighbor = OsdReadVertexValence(int(idx_neighbor));
if (valenceNeighbor < 0) {
isBoundaryNeighbor = true;
@ -106,7 +124,7 @@ void vs_main_patches( in InputVertex input,
boundaryEdgeNeighbors[currNeighbor] = int(idx_neighbor);
}
currNeighbor++;
if (currNeighbor == 1) {
if (currNeighbor == 1) {
ibefore = i;
zerothNeighbor = i;
} else {
@ -120,38 +138,19 @@ void vs_main_patches( in InputVertex input,
}
#endif
float3 neighbor =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor+2)]);
float3 neighbor = OsdReadVertex(idx_neighbor);
uint idx_diagonal = uint(OsdValenceBuffer[int(vID * (2*OSD_MAX_VALENCE+1) + 2*i + 1 + 1)]);
uint idx_diagonal = uint(OsdReadVertexIndex(vID, 2*i + 1));
float3 diagonal = OsdReadVertex(idx_diagonal);
float3 diagonal =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+2)]);
uint idx_neighbor_p = uint(OsdReadVertexIndex(vID, 2*ip));
float3 neighbor_p = OsdReadVertex(idx_neighbor_p);
uint idx_neighbor_p = uint(OsdValenceBuffer[int(vID * (2*OSD_MAX_VALENCE+1) + 2*ip + 0 + 1)]);
uint idx_neighbor_m = uint(OsdReadVertexIndex(vID, 2*im));
float3 neighbor_m = OsdReadVertex(idx_neighbor_m);
float3 neighbor_p =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_p)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_p+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_p+2)]);
uint idx_neighbor_m = uint(OsdValenceBuffer[int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 0 + 1)]);
float3 neighbor_m =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_m)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_m+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor_m+2)]);
uint idx_diagonal_m = uint(OsdValenceBuffer[int(vID * (2*OSD_MAX_VALENCE+1) + 2*im + 1 + 1)]);
float3 diagonal_m =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal_m)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal_m+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal_m+2)]);
uint idx_diagonal_m = uint(OsdReadVertexIndex(vID, 2*im + 1));
float3 diagonal_m = OsdReadVertex(idx_diagonal_m);
f[i] = (pos * float(valence) + (neighbor_p + neighbor)*2.0f + diagonal) / (float(valence)+5.0f);
@ -183,26 +182,15 @@ void vs_main_patches( in InputVertex input,
if (ivalence < 0) {
if (valence > 2) {
output.position = (
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)]) +
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)]) +
4.0f * pos)/6.0f;
output.position = (OsdReadVertex(boundaryEdgeNeighbors[0]) +
OsdReadVertex(boundaryEdgeNeighbors[1]) +
4.0f * pos)/6.0f;
} else {
output.position = pos;
}
output.e0 = (
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)]) -
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)])
)/6.0;
output.e0 = (OsdReadVertex(boundaryEdgeNeighbors[0]) -
OsdReadVertex(boundaryEdgeNeighbors[1]))/6.0;
float k = float(float(valence) - 1.0f); //k is the number of faces
float c = cos(M_PI/k);
@ -211,21 +199,13 @@ void vs_main_patches( in InputVertex input,
float alpha_0k = -((1.0f+2.0f*c)*sqrt(1.0f+c))/((3.0f*k+c)*sqrt(1.0f-c));
float beta_0 = s/(3.0f*k + c);
int idx_diagonal = OsdValenceBuffer[int((vID) * (2*OSD_MAX_VALENCE+1) + 2*zerothNeighbor + 1 + 1)];
int idx_diagonal = OsdReadVertexIndex(vID, 2*zerothNeighbor + 1);
idx_diagonal = abs(idx_diagonal);
float3 diagonal =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+2)]);
float3 diagonal = OsdReadVertex(idx_diagonal);
output.e1 = gamma * pos +
alpha_0k * float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[0]+2)]) +
alpha_0k * float3(VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1])],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*boundaryEdgeNeighbors[1]+2)]) +
alpha_0k * OsdReadVertex(boundaryEdgeNeighbors[0]) +
alpha_0k * OsdReadVertex(boundaryEdgeNeighbors[1]) +
beta_0 * diagonal;
for (uint x=1; x<valence - 1; ++x) {
@ -233,20 +213,12 @@ void vs_main_patches( in InputVertex input,
float alpha = (4.0f*sin((M_PI * float(x))/k))/(3.0f*k+c);
float beta = (sin((M_PI * float(x))/k) + sin((M_PI * float(x+1))/k))/(3.0f*k+c);
int idx_neighbor = OsdValenceBuffer[int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 0 + 1)];
int idx_neighbor = OsdReadVertexIndex(vID, 2*curri);
idx_neighbor = abs(idx_neighbor);
float3 neighbor = OsdReadVertex(idx_neighbor);
float3 neighbor =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_neighbor+2)]);
idx_diagonal = OsdValenceBuffer[int((vID) * (2*OSD_MAX_VALENCE+1) + 2*curri + 1 + 1)];
diagonal =
float3(VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+1)],
VertexBuffer[int(OSD_NUM_ELEMENTS*idx_diagonal+2)]);
idx_diagonal = OsdReadVertexIndex(vID, 2*curri + 1);
diagonal = OsdReadVertex(idx_diagonal);
output.e1 += alpha * neighbor + beta * diagonal;
}
@ -262,46 +234,10 @@ void vs_main_patches( in InputVertex input,
Buffer<int> OsdQuadOffsetBuffer : register( t4 );
HS_CONSTANT_FUNC_OUT HSConstFunc(
InputPatch<GregHullVertex, 4> patch,
uint primitiveID : SV_PrimitiveID)
int OsdReadQuadOffset(int primitiveID, uint offsetVertex)
{
HS_CONSTANT_FUNC_OUT output;
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
OSD_PATCH_CULL(4);
float4 tessLevelOuter = float4(0,0,0,0);
float4 tessLevelInner = float4(0,0,0,0);
float3 p[4];
#if defined OSD_ENABLE_SCREENSPACE_TESSELLATION
p[0] = mul(OsdModelViewMatrix(), float4(patch[0].position, 1)).xyz;
p[1] = mul(OsdModelViewMatrix(), float4(patch[1].position, 1)).xyz;
p[2] = mul(OsdModelViewMatrix(), float4(patch[2].position, 1)).xyz;
p[3] = mul(OsdModelViewMatrix(), float4(patch[3].position, 1)).xyz;
#else
p[0] = patch[0].position.xyz;
p[1] = patch[1].position.xyz;
p[2] = patch[2].position.xyz;
p[3] = patch[3].position.xyz;
#endif
OsdGetTessLevels(p[0], p[3], p[2], p[1],
patchParam, tessLevelOuter, tessLevelInner);
output.tessLevelOuter[0] = tessLevelOuter[0];
output.tessLevelOuter[1] = tessLevelOuter[1];
output.tessLevelOuter[2] = tessLevelOuter[2];
output.tessLevelOuter[3] = tessLevelOuter[3];
output.tessLevelInner[0] = tessLevelInner[0];
output.tessLevelInner[1] = tessLevelInner[1];
output.tessOuterLo = float4(0,0,0,0);
output.tessOuterHi = float4(0,0,0,0);
return output;
int index = int(4*primitiveID+OsdGregoryQuadOffsetBase() + offsetVertex);
return OsdQuadOffsetBuffer[index];
}
[domain("quad")]
@ -319,17 +255,16 @@ GregDomainVertex hs_main_patches(
uint im = (i+3)%4;
uint valence = abs(patch[i].valence);
uint n = valence;
int base = OsdGregoryQuadOffsetBase();
GregDomainVertex output;
output.position = patch[ID].position;
uint start = uint(OsdQuadOffsetBuffer[int(4*primitiveID+base + i)]) & 0x00ffu;
uint prev = uint(OsdQuadOffsetBuffer[int(4*primitiveID+base + i)]) & 0xff00u;
uint start = uint(OsdReadQuadOffset(primitiveID, i)) & 0x00ffu;
uint prev = uint(OsdReadQuadOffset(primitiveID, i)) & 0xff00u;
prev = uint(prev/256);
uint start_m = uint(OsdQuadOffsetBuffer[int(4*primitiveID+base + im)]) & 0x00ffu;
uint prev_p = uint(OsdQuadOffsetBuffer[int(4*primitiveID+base + ip)]) & 0xff00u;
uint start_m = uint(OsdReadQuadOffset(primitiveID, im)) & 0x00ffu;
uint prev_p = uint(OsdReadQuadOffset(primitiveID, ip)) & 0xff00u;
prev_p = uint(prev_p/256);
uint np = abs(patch[ip].valence);
@ -462,6 +397,37 @@ GregDomainVertex hs_main_patches(
return output;
}
HS_CONSTANT_FUNC_OUT HSConstFunc(
InputPatch<GregHullVertex, 4> patch,
uint primitiveID : SV_PrimitiveID)
{
HS_CONSTANT_FUNC_OUT output;
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
OSD_PATCH_CULL(4);
float4 tessLevelOuter = float4(0,0,0,0);
float4 tessLevelInner = float4(0,0,0,0);
OsdGetTessLevels(patch[0].position.xyz, patch[3].position.xyz,
patch[2].position.xyz, patch[1].position.xyz,
patchParam, tessLevelOuter, tessLevelInner);
output.tessLevelOuter[0] = tessLevelOuter[0];
output.tessLevelOuter[1] = tessLevelOuter[1];
output.tessLevelOuter[2] = tessLevelOuter[2];
output.tessLevelOuter[3] = tessLevelOuter[3];
output.tessLevelInner[0] = tessLevelInner[0];
output.tessLevelInner[1] = tessLevelInner[1];
output.tessOuterLo = float4(0,0,0,0);
output.tessOuterHi = float4(0,0,0,0);
return output;
}
//----------------------------------------------------------
// Patches.DomainGregory
//----------------------------------------------------------
@ -470,12 +436,9 @@ GregDomainVertex hs_main_patches(
void ds_main_patches(
in HS_CONSTANT_FUNC_OUT input,
in OutputPatch<GregDomainVertex, 4> patch,
in float2 uv : SV_DomainLocation,
in float2 UV : SV_DomainLocation,
out OutputVertex output )
{
float u = uv.x,
v = uv.y;
float3 p[20];
p[0] = patch[0].position;
@ -504,6 +467,7 @@ void ds_main_patches(
float3 q[16];
float u = UV.x, v=UV.y;
float U = 1-u, V=1-v;
float d11 = u+v; if(u+v==0.0f) d11 = 1.0f;
@ -529,22 +493,20 @@ void ds_main_patches(
q[14] = p[11];
q[15] = p[10];
float3 WorldPos = float3(0, 0, 0);
float3 Tangent = float3(0, 0, 0);
float3 BiTangent = float3(0, 0, 0);
float3 position = float3(0, 0, 0);
float3 uTangent = float3(0, 0, 0);
float3 vTangent = float3(0, 0, 0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
float B[4], D[4], C[4];
float3 BUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
DUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
CUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)};
float3 dUU = float3(0, 0, 0);
float3 dVV = float3(0, 0, 0);
float3 dUV = float3(0, 0, 0);
Univar4x4(u, B, D, C);
Univar4x4(UV.x, B, D, C);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -555,54 +517,48 @@ void ds_main_patches(
}
}
Univar4x4(v, B, D, C);
Univar4x4(UV.y, B, D, C);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
dUU += B[i] * CUCP[i];
dVV += C[i] * BUCP[i];
dUV += D[i] * DUCP[i];
}
int level = patch[0].patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
float3 n = cross(Tangent, BiTangent);
float3 n = cross(uTangent, vTangent);
float3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
float3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
float3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
BiTangent = mul(OsdModelViewMatrix(), float4(BiTangent, 0)).xyz;
Tangent = mul(OsdModelViewMatrix(), float4(Tangent, 0)).xyz;
normal = normalize(cross(Tangent, BiTangent));
output.Nu = Nu;
output.Nv = Nv;
#else
float B[4], D[4];
float3 BUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
DUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)};
Univar4x4(uv.x, B, D);
Univar4x4(UV.x, B, D);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -612,36 +568,29 @@ void ds_main_patches(
}
}
Univar4x4(uv.y, B, D);
Univar4x4(UV.y, B, D);
for (uint i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
}
int level = patch[0].patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
BiTangent = mul(OsdModelViewMatrix(), float4(BiTangent, 0)).xyz;
Tangent = mul(OsdModelViewMatrix(), float4(Tangent, 0)).xyz;
float3 normal = normalize(cross(Tangent, BiTangent));
uTangent *= 3 * level;
vTangent *= 3 * level;
float3 normal = normalize(cross(uTangent, vTangent));
#endif
output.position = mul(OsdModelViewMatrix(), float4(WorldPos, 1.0f));
output.normal = normal;
output.tangent = Tangent;
output.bitangent = BiTangent;
output.position = mul(OsdModelViewMatrix(), float4(position, 1.0f));
output.normal = mul(OsdModelViewMatrix(), float4(normal, 0.0f)).xyz;
output.tangent = mul(OsdModelViewMatrix(), float4(uTangent, 0.0f)).xyz;
output.bitangent = mul(OsdModelViewMatrix(), float4(vTangent, 0.0f)).xyz;
output.edgeDistance = 0;
float2 UV = float2(u, v);
output.patchCoord = OsdInterpolatePatchCoord(UV, patch[0].patchCoord);
OSD_DISPLACEMENT_CALLBACK;
output.positionOut = mul(OsdProjectionMatrix(),
float4(output.position.xyz, 1.0f));
output.positionOut = mul(OsdProjectionMatrix(), output.position);
output.edgeDistance = 0;
}

View File

@ -1,5 +1,5 @@
//
// Copyright 2013 Pixar
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
@ -37,7 +37,8 @@
void vs_main_patches( in InputVertex input,
out HullVertex output )
{
output.position = mul(OsdModelViewMatrix(), input.position);
output.position = input.position;
output.patchCoord = int4(0,0,0,0);
OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(input.position);
}
@ -45,6 +46,25 @@ void vs_main_patches( in InputVertex input,
// Patches.HullGregoryBasis
//----------------------------------------------------------
[domain("quad")]
[partitioning(HS_PARTITION)]
[outputtopology("triangle_cw")]
[outputcontrolpoints(20)]
[patchconstantfunc("HSConstFunc")]
HullVertex hs_main_patches(
in InputPatch<HullVertex, 20> patch,
uint primitiveID : SV_PrimitiveID,
in uint ID : SV_OutputControlPointID )
{
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
HullVertex output;
output.position = float4(patch[ID].position.xyz, 1.0);
output.patchCoord = OsdGetPatchCoord(patchParam);
return output;
}
HS_CONSTANT_FUNC_OUT
HSConstFunc(
InputPatch<HullVertex, 20> patch,
@ -76,25 +96,6 @@ HSConstFunc(
return output;
}
[domain("quad")]
[partitioning(HS_PARTITION)]
[outputtopology("triangle_cw")]
[outputcontrolpoints(20)]
[patchconstantfunc("HSConstFunc")]
HullVertex hs_main_patches(
in InputPatch<HullVertex, 20> patch,
uint primitiveID : SV_PrimitiveID,
in uint ID : SV_OutputControlPointID )
{
int3 patchParam = OsdGetPatchParam(OsdGetPatchIndex(primitiveID));
HullVertex output;
output.position = float4(patch[ID].position.xyz, 1.0);
output.patchCoord = OsdGetPatchCoord(patchParam);
return output;
}
//----------------------------------------------------------
// Patches.DomainGregory
//----------------------------------------------------------
@ -103,18 +104,16 @@ HullVertex hs_main_patches(
void ds_main_patches(
in HS_CONSTANT_FUNC_OUT input,
in OutputPatch<HullVertex, 20> patch,
in float2 uv : SV_DomainLocation,
in float2 UV : SV_DomainLocation,
out OutputVertex output )
{
float u = uv.x,
v = uv.y;
float3 p[20];
for (int i = 0; i < 20; ++i) {
p[i] = patch[i].position.xyz;
}
float3 q[16];
float u = UV.x, v=UV.y;
float U = 1-u, V=1-v;
float d11 = u+v; if(u+v==0.0f) d11 = 1.0f;
@ -140,22 +139,20 @@ void ds_main_patches(
q[14] = p[11];
q[15] = p[10];
float3 WorldPos = float3(0, 0, 0);
float3 Tangent = float3(0, 0, 0);
float3 BiTangent = float3(0, 0, 0);
float3 position = float3(0, 0, 0);
float3 uTangent = float3(0, 0, 0);
float3 vTangent = float3(0, 0, 0);
#ifdef OSD_COMPUTE_NORMAL_DERIVATIVES
float B[4], D[4], C[4];
float3 BUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
DUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
CUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)};
float3 dUU = float3(0, 0, 0);
float3 dVV = float3(0, 0, 0);
float3 dUV = float3(0, 0, 0);
Univar4x4(u, B, D, C);
Univar4x4(UV.x, B, D, C);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -166,49 +163,48 @@ void ds_main_patches(
}
}
Univar4x4(v, B, D, C);
Univar4x4(UV.y, B, D, C);
for (int i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
dUU += B[i] * CUCP[i];
dVV += C[i] * BUCP[i];
dUV += D[i] * DUCP[i];
}
int level = patch[0].patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
uTangent *= 3 * level;
vTangent *= 3 * level;
dUU *= 6 * level;
dVV *= 6 * level;
dUV *= 9 * level;
float3 n = cross(Tangent, BiTangent);
float3 n = cross(uTangent, vTangent);
float3 normal = normalize(n);
float E = dot(Tangent, Tangent);
float F = dot(Tangent, BiTangent);
float G = dot(BiTangent, BiTangent);
float E = dot(uTangent, uTangent);
float F = dot(uTangent, vTangent);
float G = dot(vTangent, vTangent);
float e = dot(normal, dUU);
float f = dot(normal, dUV);
float g = dot(normal, dVV);
float3 Nu = (f*F-e*G)/(E*G-F*F) * Tangent + (e*F-f*E)/(E*G-F*F) * BiTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * Tangent + (f*F-g*E)/(E*G-F*F) * BiTangent;
float3 Nu = (f*F-e*G)/(E*G-F*F) * uTangent + (e*F-f*E)/(E*G-F*F) * vTangent;
float3 Nv = (g*F-f*G)/(E*G-F*F) * uTangent + (f*F-g*E)/(E*G-F*F) * vTangent;
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));
output.Nu = Nu;
output.Nv = Nv;
#else
float B[4], D[4];
float3 BUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)},
DUCP[4] = {float3(0,0,0), float3(0,0,0), float3(0,0,0), float3(0,0,0)};
Univar4x4(uv.x, B, D);
Univar4x4(UV.x, B, D);
for (int i=0; i<4; ++i) {
for (uint j=0; j<4; ++j) {
@ -218,32 +214,29 @@ void ds_main_patches(
}
}
Univar4x4(uv.y, B, D);
Univar4x4(UV.y, B, D);
for (uint i=0; i<4; ++i) {
WorldPos += B[i] * BUCP[i];
Tangent += B[i] * DUCP[i];
BiTangent += D[i] * BUCP[i];
position += B[i] * BUCP[i];
uTangent += B[i] * DUCP[i];
vTangent += D[i] * BUCP[i];
}
int level = patch[0].patchCoord.z;
BiTangent *= 3 * level;
Tangent *= 3 * level;
float3 normal = normalize(cross(Tangent, BiTangent));
uTangent *= 3 * level;
vTangent *= 3 * level;
float3 normal = normalize(cross(uTangent, vTangent));
#endif
output.position = float4(WorldPos, 1.0f);
output.normal = normal;
output.tangent = Tangent;
output.bitangent = BiTangent;
output.position = mul(OsdModelViewMatrix(), float4(position, 1.0f));
output.normal = mul(OsdModelViewMatrix(), float4(normal, 0.0f)).xyz;
output.tangent = mul(OsdModelViewMatrix(), float4(uTangent, 0.0f)).xyz;
output.bitangent = mul(OsdModelViewMatrix(), float4(vTangent, 0.0f)).xyz;
output.edgeDistance = 0;
float2 UV = float2(u, v);
output.patchCoord = OsdInterpolatePatchCoord(UV, patch[0].patchCoord);
OSD_DISPLACEMENT_CALLBACK;
output.positionOut = mul(OsdProjectionMatrix(), output.position);
output.edgeDistance = 0;
}