Skip to content

Commit 3597371

Browse files
authored
Merge pull request #1320 from davidgyu/dev_osd_patch_drawing_compatibilty
Improved osd patch drawing compatibility
2 parents 18f3b91 + fdb9ac9 commit 3597371

13 files changed

Lines changed: 572 additions & 498 deletions

opensubdiv/osd/glslPatchCommon.glsl

Lines changed: 4 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -22,101 +22,11 @@
2222
// language governing permissions and limitations under the Apache License.
2323
//
2424

25-
//
26-
// typical shader composition ordering (see glDrawRegistry:_CompileShader)
27-
//
28-
//
29-
// - glsl version string (#version 430)
30-
//
31-
// - common defines (#define OSD_ENABLE_PATCH_CULL, ...)
32-
// - source defines (#define VERTEX_SHADER, ...)
33-
//
34-
// - osd headers (glslPatchCommon: varying structs,
35-
// glslPtexCommon: ptex functions)
36-
// - client header (Osd*Matrix(), displacement callback, ...)
37-
//
38-
// - osd shader source (glslPatchBSpline, glslPatchGregory, ...)
39-
// or
40-
// client shader source (vertex/geometry/fragment shader)
41-
//
42-
43-
//----------------------------------------------------------
44-
// Patches.Common
45-
//----------------------------------------------------------
46-
47-
// XXXdyu all handling of varying data can be managed by client code
48-
#ifndef OSD_USER_VARYING_DECLARE
49-
#define OSD_USER_VARYING_DECLARE
50-
// type var;
51-
#endif
52-
53-
#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE
54-
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE
55-
// layout(location = loc) in type var;
56-
#endif
57-
58-
#ifndef OSD_USER_VARYING_PER_VERTEX
59-
#define OSD_USER_VARYING_PER_VERTEX()
60-
// output.var = var;
61-
#endif
62-
63-
#ifndef OSD_USER_VARYING_PER_CONTROL_POINT
64-
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN)
65-
// output[ID_OUT].var = input[ID_IN].var
66-
#endif
67-
68-
#ifndef OSD_USER_VARYING_PER_EVAL_POINT
69-
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d)
70-
// output.var =
71-
// mix(mix(input[a].var, input[b].var, UV.x),
72-
// mix(input[c].var, input[d].var, UV.x), UV.y)
73-
#endif
74-
75-
#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
76-
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c)
77-
// output.var =
78-
// input[a].var * (1.0f-UV.x-UV.y) +
79-
// input[b].var * UV.x +
80-
// input[c].var * UV.y;
81-
#endif
82-
83-
#if __VERSION__ < 420
84-
#define centroid
85-
#endif
86-
87-
struct ControlVertex {
88-
vec4 position;
89-
#ifdef OSD_ENABLE_PATCH_CULL
90-
ivec3 clipFlag;
91-
#endif
92-
};
93-
94-
// XXXdyu all downstream data can be handled by client code
95-
struct OutputVertex {
96-
vec4 position;
97-
vec3 normal;
98-
vec3 tangent;
99-
vec3 bitangent;
100-
vec4 patchCoord; // u, v, faceLevel, faceId
101-
vec2 tessCoord; // tesscoord.st
102-
#if defined OSD_COMPUTE_NORMAL_DERIVATIVES
103-
vec3 Nu;
104-
vec3 Nv;
105-
#endif
106-
};
107-
108-
// osd shaders need following functions defined
25+
// The following callback functions are used when evaluating tessellation
26+
// rates and when using legacy patch drawing.
10927
mat4 OsdModelViewMatrix();
11028
mat4 OsdProjectionMatrix();
111-
mat4 OsdModelViewProjectionMatrix();
11229
float OsdTessLevel();
113-
int OsdGregoryQuadOffsetBase();
114-
int OsdPrimitiveIdBase();
115-
int OsdBaseVertex();
116-
117-
#ifndef OSD_DISPLACEMENT_CALLBACK
118-
#define OSD_DISPLACEMENT_CALLBACK
119-
#endif
12030

12131
// ----------------------------------------------------------------------------
12232
// Patch Parameters
@@ -130,22 +40,6 @@ int OsdBaseVertex();
13040
// bitfield -- refinement-level, non-quad, boundary, transition, uv-offset
13141
// sharpness -- crease sharpness for single-crease patches
13242
//
133-
// These are stored in OsdPatchParamBuffer indexed by the value returned
134-
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
135-
// along with an optional client provided offset.
136-
//
137-
138-
uniform isamplerBuffer OsdPatchParamBuffer;
139-
140-
int OsdGetPatchIndex(int primitiveId)
141-
{
142-
return (primitiveId + OsdPrimitiveIdBase());
143-
}
144-
145-
ivec3 OsdGetPatchParam(int patchIndex)
146-
{
147-
return texelFetch(OsdPatchParamBuffer, patchIndex).xyz;
148-
}
14943

15044
int OsdGetPatchFaceId(ivec3 patchParam)
15145
{
@@ -239,38 +133,6 @@ vec4 OsdInterpolatePatchCoordTriangle(vec2 localUV, ivec3 patchParam)
239133
return result;
240134
}
241135

242-
// ----------------------------------------------------------------------------
243-
// patch culling
244-
// ----------------------------------------------------------------------------
245-
246-
#ifdef OSD_ENABLE_PATCH_CULL
247-
248-
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
249-
vec4 clipPos = OsdModelViewProjectionMatrix() * P; \
250-
bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \
251-
bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \
252-
outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
253-
254-
#define OSD_PATCH_CULL(N) \
255-
ivec3 clipFlag = ivec3(0); \
256-
for(int i = 0; i < N; ++i) { \
257-
clipFlag |= inpt[i].v.clipFlag; \
258-
} \
259-
if (clipFlag != ivec3(3) ) { \
260-
gl_TessLevelInner[0] = 0; \
261-
gl_TessLevelInner[1] = 0; \
262-
gl_TessLevelOuter[0] = 0; \
263-
gl_TessLevelOuter[1] = 0; \
264-
gl_TessLevelOuter[2] = 0; \
265-
gl_TessLevelOuter[3] = 0; \
266-
return; \
267-
}
268-
269-
#else
270-
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
271-
#define OSD_PATCH_CULL(N)
272-
#endif
273-
274136
// ----------------------------------------------------------------------------
275137

276138
void
@@ -582,15 +444,15 @@ OsdFlipMatrix(mat4 m)
582444
}
583445

584446
// Regular BSpline to Bezier
585-
uniform mat4 Q = mat4(
447+
const mat4 Q = mat4(
586448
1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f,
587449
0.f, 4.f/6.f, 2.f/6.f, 0.f,
588450
0.f, 2.f/6.f, 4.f/6.f, 0.f,
589451
0.f, 1.f/6.f, 4.f/6.f, 1.f/6.f
590452
);
591453

592454
// Infinitely Sharp (boundary)
593-
uniform mat4 Mi = mat4(
455+
const mat4 Mi = mat4(
594456
1.f/6.f, 4.f/6.f, 1.f/6.f, 0.f,
595457
0.f, 4.f/6.f, 2.f/6.f, 0.f,
596458
0.f, 2.f/6.f, 4.f/6.f, 0.f,

opensubdiv/osd/glslPatchLegacy.glsl

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,128 @@
2222
// language governing permissions and limitations under the Apache License.
2323
//
2424

25+
//----------------------------------------------------------
26+
// Patches.Common
27+
//----------------------------------------------------------
28+
29+
// XXXdyu all handling of varying data can be managed by client code
30+
#ifndef OSD_USER_VARYING_DECLARE
31+
#define OSD_USER_VARYING_DECLARE
32+
// type var;
33+
#endif
34+
35+
#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE
36+
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE
37+
// layout(location = loc) in type var;
38+
#endif
39+
40+
#ifndef OSD_USER_VARYING_PER_VERTEX
41+
#define OSD_USER_VARYING_PER_VERTEX()
42+
// output.var = var;
43+
#endif
44+
45+
#ifndef OSD_USER_VARYING_PER_CONTROL_POINT
46+
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN)
47+
// output[ID_OUT].var = input[ID_IN].var
48+
#endif
49+
50+
#ifndef OSD_USER_VARYING_PER_EVAL_POINT
51+
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d)
52+
// output.var =
53+
// mix(mix(input[a].var, input[b].var, UV.x),
54+
// mix(input[c].var, input[d].var, UV.x), UV.y)
55+
#endif
56+
57+
#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
58+
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c)
59+
// output.var =
60+
// input[a].var * (1.0f-UV.x-UV.y) +
61+
// input[b].var * UV.x +
62+
// input[c].var * UV.y;
63+
#endif
64+
65+
#if __VERSION__ < 420
66+
#define centroid
67+
#endif
68+
69+
struct ControlVertex {
70+
vec4 position;
71+
#ifdef OSD_ENABLE_PATCH_CULL
72+
ivec3 clipFlag;
73+
#endif
74+
};
75+
76+
// XXXdyu all downstream data can be handled by client code
77+
struct OutputVertex {
78+
vec4 position;
79+
vec3 normal;
80+
vec3 tangent;
81+
vec3 bitangent;
82+
vec4 patchCoord; // u, v, faceLevel, faceId
83+
vec2 tessCoord; // tesscoord.st
84+
#if defined OSD_COMPUTE_NORMAL_DERIVATIVES
85+
vec3 Nu;
86+
vec3 Nv;
87+
#endif
88+
};
89+
90+
mat4 OsdModelViewProjectionMatrix();
91+
int OsdGregoryQuadOffsetBase();
92+
int OsdPrimitiveIdBase();
93+
int OsdBaseVertex();
94+
95+
#ifndef OSD_DISPLACEMENT_CALLBACK
96+
#define OSD_DISPLACEMENT_CALLBACK
97+
#endif
98+
99+
// These are stored in OsdPatchParamBuffer indexed by the value returned
100+
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
101+
// along with an optional client provided offset.
102+
103+
uniform isamplerBuffer OsdPatchParamBuffer;
104+
105+
int OsdGetPatchIndex(int primitiveId)
106+
{
107+
return (primitiveId + OsdPrimitiveIdBase());
108+
}
109+
110+
ivec3 OsdGetPatchParam(int patchIndex)
111+
{
112+
return texelFetch(OsdPatchParamBuffer, patchIndex).xyz;
113+
}
114+
115+
// ----------------------------------------------------------------------------
116+
// patch culling
117+
// ----------------------------------------------------------------------------
118+
119+
#ifdef OSD_ENABLE_PATCH_CULL
120+
121+
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
122+
vec4 clipPos = OsdModelViewProjectionMatrix() * P; \
123+
bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \
124+
bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \
125+
outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
126+
127+
#define OSD_PATCH_CULL(N) \
128+
ivec3 clipFlag = ivec3(0); \
129+
for(int i = 0; i < N; ++i) { \
130+
clipFlag |= inpt[i].v.clipFlag; \
131+
} \
132+
if (clipFlag != ivec3(3) ) { \
133+
gl_TessLevelInner[0] = 0; \
134+
gl_TessLevelInner[1] = 0; \
135+
gl_TessLevelOuter[0] = 0; \
136+
gl_TessLevelOuter[1] = 0; \
137+
gl_TessLevelOuter[2] = 0; \
138+
gl_TessLevelOuter[3] = 0; \
139+
return; \
140+
}
141+
142+
#else
143+
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
144+
#define OSD_PATCH_CULL(N)
145+
#endif
146+
25147
// ----------------------------------------------------------------------------
26148
// Legacy Gregory
27149
// ----------------------------------------------------------------------------

opensubdiv/osd/glslPatchShaderSource.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,18 @@ static const char *gregoryTriangleShaderSource =
6767

6868
/*static*/
6969
std::string
70-
GLSLPatchShaderSource::GetCommonShaderSource() {
70+
GLSLPatchShaderSource::GetPatchDrawingShaderSource() {
7171
std::stringstream ss;
7272
ss << std::string(commonShaderSource);
7373
ss << std::string(commonTessShaderSource);
74+
return ss.str();
75+
}
76+
77+
/*static*/
78+
std::string
79+
GLSLPatchShaderSource::GetCommonShaderSource() {
80+
std::stringstream ss;
81+
ss << GetPatchDrawingShaderSource();
7482
ss << std::string(patchLegacyShaderSource);
7583
return ss.str();
7684
}

opensubdiv/osd/glslPatchShaderSource.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,39 @@
2626
#define OPENSUBDIV3_OSD_GLSL_PATCH_SHADER_SOURCE_H
2727

2828
#include "../version.h"
29-
#include <string>
29+
3030
#include "../far/patchDescriptor.h"
3131

32+
#include <string>
33+
3234
namespace OpenSubdiv {
3335
namespace OPENSUBDIV_VERSION {
3436

3537
namespace Osd {
3638

39+
/// \brief Provides shader source which can be used by client code.
3740
class GLSLPatchShaderSource {
3841
public:
39-
static std::string GetCommonShaderSource();
40-
42+
/// \brief Returns shader source which can be used to evaluate
43+
/// position and first and second derivatives on piecewise parametric
44+
/// patches resulting from subdivision refinement.
4145
static std::string GetPatchBasisShaderSource();
4246

47+
/// \brief Returns shader source which can be used while drawing
48+
/// piecewise parametric patches resulting from subdivision refinement,
49+
/// e.g. while using GPU HW tessellation.
50+
static std::string GetPatchDrawingShaderSource();
51+
52+
/// \name Alternative methods
53+
/// \{
54+
/// These methods return shader source which can be used
55+
/// while drawing. Unlike the methods above, the source returned
56+
/// by these methods includes support for legacy patch types along
57+
/// with dependencies on specific resource bindings and interstage
58+
/// shader variable declarations.
59+
60+
static std::string GetCommonShaderSource();
61+
4362
static std::string GetVertexShaderSource(
4463
Far::PatchDescriptor::Type type);
4564

@@ -48,6 +67,8 @@ class GLSLPatchShaderSource {
4867

4968
static std::string GetTessEvalShaderSource(
5069
Far::PatchDescriptor::Type type);
70+
71+
/// \}
5172
};
5273

5374
} // end namespace Osd

0 commit comments

Comments
 (0)