mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-09 13:50:05 +00:00
Reorganized legacy patch drawing shader source
Relocated from PatchCommon to PatchLegacy several aspects of the shader source which can cause problems with typical use cases. Specifically, things like resource bindings, input assembler and interstage declarations are best left to client code. These are not removed, just relocated and remain available for backward compatibility. Updated the GLSL, HLSL, and MSL source.
This commit is contained in:
parent
18f3b91c28
commit
c2ed7d5cf0
@ -22,101 +22,11 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//
|
||||
// typical shader composition ordering (see glDrawRegistry:_CompileShader)
|
||||
//
|
||||
//
|
||||
// - glsl version string (#version 430)
|
||||
//
|
||||
// - common defines (#define OSD_ENABLE_PATCH_CULL, ...)
|
||||
// - source defines (#define VERTEX_SHADER, ...)
|
||||
//
|
||||
// - osd headers (glslPatchCommon: varying structs,
|
||||
// glslPtexCommon: ptex functions)
|
||||
// - client header (Osd*Matrix(), displacement callback, ...)
|
||||
//
|
||||
// - osd shader source (glslPatchBSpline, glslPatchGregory, ...)
|
||||
// or
|
||||
// client shader source (vertex/geometry/fragment shader)
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
// XXXdyu all handling of varying data can be managed by client code
|
||||
#ifndef OSD_USER_VARYING_DECLARE
|
||||
#define OSD_USER_VARYING_DECLARE
|
||||
// type var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
// layout(location = loc) in type var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_VERTEX
|
||||
#define OSD_USER_VARYING_PER_VERTEX()
|
||||
// output.var = var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_CONTROL_POINT
|
||||
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN)
|
||||
// output[ID_OUT].var = input[ID_IN].var
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_EVAL_POINT
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d)
|
||||
// output.var =
|
||||
// mix(mix(input[a].var, input[b].var, UV.x),
|
||||
// mix(input[c].var, input[d].var, UV.x), UV.y)
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c)
|
||||
// output.var =
|
||||
// input[a].var * (1.0f-UV.x-UV.y) +
|
||||
// input[b].var * UV.x +
|
||||
// input[c].var * UV.y;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ < 420
|
||||
#define centroid
|
||||
#endif
|
||||
|
||||
struct ControlVertex {
|
||||
vec4 position;
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
ivec3 clipFlag;
|
||||
#endif
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OutputVertex {
|
||||
vec4 position;
|
||||
vec3 normal;
|
||||
vec3 tangent;
|
||||
vec3 bitangent;
|
||||
vec4 patchCoord; // u, v, faceLevel, faceId
|
||||
vec2 tessCoord; // tesscoord.st
|
||||
#if defined OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
vec3 Nu;
|
||||
vec3 Nv;
|
||||
#endif
|
||||
};
|
||||
|
||||
// osd shaders need following functions defined
|
||||
// The following callback functions are used when evaluating tessellation
|
||||
// rates and when using legacy patch drawing.
|
||||
mat4 OsdModelViewMatrix();
|
||||
mat4 OsdProjectionMatrix();
|
||||
mat4 OsdModelViewProjectionMatrix();
|
||||
float OsdTessLevel();
|
||||
int OsdGregoryQuadOffsetBase();
|
||||
int OsdPrimitiveIdBase();
|
||||
int OsdBaseVertex();
|
||||
|
||||
#ifndef OSD_DISPLACEMENT_CALLBACK
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Patch Parameters
|
||||
@ -130,22 +40,6 @@ int OsdBaseVertex();
|
||||
// bitfield -- refinement-level, non-quad, boundary, transition, uv-offset
|
||||
// sharpness -- crease sharpness for single-crease patches
|
||||
//
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
//
|
||||
|
||||
uniform isamplerBuffer OsdPatchParamBuffer;
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return (primitiveId + OsdPrimitiveIdBase());
|
||||
}
|
||||
|
||||
ivec3 OsdGetPatchParam(int patchIndex)
|
||||
{
|
||||
return texelFetch(OsdPatchParamBuffer, patchIndex).xyz;
|
||||
}
|
||||
|
||||
int OsdGetPatchFaceId(ivec3 patchParam)
|
||||
{
|
||||
@ -239,38 +133,6 @@ vec4 OsdInterpolatePatchCoordTriangle(vec2 localUV, ivec3 patchParam)
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
|
||||
vec4 clipPos = OsdModelViewProjectionMatrix() * P; \
|
||||
bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \
|
||||
bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \
|
||||
outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
|
||||
|
||||
#define OSD_PATCH_CULL(N) \
|
||||
ivec3 clipFlag = ivec3(0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= inpt[i].v.clipFlag; \
|
||||
} \
|
||||
if (clipFlag != ivec3(3) ) { \
|
||||
gl_TessLevelInner[0] = 0; \
|
||||
gl_TessLevelInner[1] = 0; \
|
||||
gl_TessLevelOuter[0] = 0; \
|
||||
gl_TessLevelOuter[1] = 0; \
|
||||
gl_TessLevelOuter[2] = 0; \
|
||||
gl_TessLevelOuter[3] = 0; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
|
||||
#define OSD_PATCH_CULL(N)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@ -582,7 +444,7 @@ OsdFlipMatrix(mat4 m)
|
||||
}
|
||||
|
||||
// Regular BSpline to Bezier
|
||||
uniform mat4 Q = mat4(
|
||||
const mat4 Q = mat4(
|
||||
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,
|
||||
@ -590,7 +452,7 @@ uniform mat4 Q = mat4(
|
||||
);
|
||||
|
||||
// Infinitely Sharp (boundary)
|
||||
uniform mat4 Mi = mat4(
|
||||
const mat4 Mi = mat4(
|
||||
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,
|
||||
|
@ -22,6 +22,128 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
// XXXdyu all handling of varying data can be managed by client code
|
||||
#ifndef OSD_USER_VARYING_DECLARE
|
||||
#define OSD_USER_VARYING_DECLARE
|
||||
// type var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
#define OSD_USER_VARYING_ATTRIBUTE_DECLARE
|
||||
// layout(location = loc) in type var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_VERTEX
|
||||
#define OSD_USER_VARYING_PER_VERTEX()
|
||||
// output.var = var;
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_CONTROL_POINT
|
||||
#define OSD_USER_VARYING_PER_CONTROL_POINT(ID_OUT, ID_IN)
|
||||
// output[ID_OUT].var = input[ID_IN].var
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_EVAL_POINT
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT(UV, a, b, c, d)
|
||||
// output.var =
|
||||
// mix(mix(input[a].var, input[b].var, UV.x),
|
||||
// mix(input[c].var, input[d].var, UV.x), UV.y)
|
||||
#endif
|
||||
|
||||
#ifndef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
|
||||
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c)
|
||||
// output.var =
|
||||
// input[a].var * (1.0f-UV.x-UV.y) +
|
||||
// input[b].var * UV.x +
|
||||
// input[c].var * UV.y;
|
||||
#endif
|
||||
|
||||
#if __VERSION__ < 420
|
||||
#define centroid
|
||||
#endif
|
||||
|
||||
struct ControlVertex {
|
||||
vec4 position;
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
ivec3 clipFlag;
|
||||
#endif
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OutputVertex {
|
||||
vec4 position;
|
||||
vec3 normal;
|
||||
vec3 tangent;
|
||||
vec3 bitangent;
|
||||
vec4 patchCoord; // u, v, faceLevel, faceId
|
||||
vec2 tessCoord; // tesscoord.st
|
||||
#if defined OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
vec3 Nu;
|
||||
vec3 Nv;
|
||||
#endif
|
||||
};
|
||||
|
||||
mat4 OsdModelViewProjectionMatrix();
|
||||
int OsdGregoryQuadOffsetBase();
|
||||
int OsdPrimitiveIdBase();
|
||||
int OsdBaseVertex();
|
||||
|
||||
#ifndef OSD_DISPLACEMENT_CALLBACK
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
|
||||
uniform isamplerBuffer OsdPatchParamBuffer;
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return (primitiveId + OsdPrimitiveIdBase());
|
||||
}
|
||||
|
||||
ivec3 OsdGetPatchParam(int patchIndex)
|
||||
{
|
||||
return texelFetch(OsdPatchParamBuffer, patchIndex).xyz;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
|
||||
vec4 clipPos = OsdModelViewProjectionMatrix() * P; \
|
||||
bvec3 clip0 = lessThan(clipPos.xyz, vec3(clipPos.w)); \
|
||||
bvec3 clip1 = greaterThan(clipPos.xyz, -vec3(clipPos.w)); \
|
||||
outpt.v.clipFlag = ivec3(clip0) + 2*ivec3(clip1); \
|
||||
|
||||
#define OSD_PATCH_CULL(N) \
|
||||
ivec3 clipFlag = ivec3(0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= inpt[i].v.clipFlag; \
|
||||
} \
|
||||
if (clipFlag != ivec3(3) ) { \
|
||||
gl_TessLevelInner[0] = 0; \
|
||||
gl_TessLevelInner[1] = 0; \
|
||||
gl_TessLevelOuter[0] = 0; \
|
||||
gl_TessLevelOuter[1] = 0; \
|
||||
gl_TessLevelOuter[2] = 0; \
|
||||
gl_TessLevelOuter[3] = 0; \
|
||||
return; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
|
||||
#define OSD_PATCH_CULL(N)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Legacy Gregory
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -22,52 +22,11 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct InputVertex {
|
||||
float4 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
struct HullVertex {
|
||||
float4 position : POSITION;
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
int3 clipFlag : CLIPFLAG;
|
||||
#endif
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OutputVertex {
|
||||
float4 positionOut : SV_Position;
|
||||
float4 position : POSITION1;
|
||||
float3 normal : NORMAL;
|
||||
float3 tangent : TANGENT;
|
||||
float3 bitangent : TANGENT1;
|
||||
float4 patchCoord : PATCHCOORD; // u, v, faceLevel, faceId
|
||||
noperspective float4 edgeDistance : EDGEDISTANCE;
|
||||
#if defined(OSD_COMPUTE_NORMAL_DERIVATIVES)
|
||||
float3 Nu : TANGENT2;
|
||||
float3 Nv : TANGENT3;
|
||||
#endif
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments : VSEGMENTS;
|
||||
#endif
|
||||
};
|
||||
|
||||
// osd shaders need following functions defined
|
||||
// The following callback functions are used when evaluating tessellation
|
||||
// rates and when using legacy patch drawing.
|
||||
float4x4 OsdModelViewMatrix();
|
||||
float4x4 OsdProjectionMatrix();
|
||||
float4x4 OsdModelViewProjectionMatrix();
|
||||
float OsdTessLevel();
|
||||
int OsdGregoryQuadOffsetBase();
|
||||
int OsdPrimitiveIdBase();
|
||||
int OsdBaseVertex();
|
||||
|
||||
#ifndef OSD_DISPLACEMENT_CALLBACK
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Patch Parameters
|
||||
@ -81,31 +40,6 @@ int OsdBaseVertex();
|
||||
// bitfield -- refinement-level, non-quad, boundary, transition, uv-offset
|
||||
// sharpness -- crease sharpness for single-crease patches
|
||||
//
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
//
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
Buffer<uint3> OsdPatchParamBuffer : register( t0 );
|
||||
#else
|
||||
Buffer<uint2> OsdPatchParamBuffer : register( t0 );
|
||||
#endif
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return (primitiveId + OsdPrimitiveIdBase());
|
||||
}
|
||||
|
||||
int3 OsdGetPatchParam(int patchIndex)
|
||||
{
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
return OsdPatchParamBuffer[patchIndex].xyz;
|
||||
#else
|
||||
uint2 p = OsdPatchParamBuffer[patchIndex].xy;
|
||||
return int3(p.x, p.y, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int OsdGetPatchFaceId(int3 patchParam)
|
||||
{
|
||||
@ -199,60 +133,6 @@ float4 OsdInterpolatePatchCoordTriangle(float2 localUV, int3 patchParam)
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
|
||||
float4 clipPos = mul(OsdModelViewProjectionMatrix(), P); \
|
||||
int3 clip0 = int3(clipPos.x < clipPos.w, \
|
||||
clipPos.y < clipPos.w, \
|
||||
clipPos.z < clipPos.w); \
|
||||
int3 clip1 = int3(clipPos.x > -clipPos.w, \
|
||||
clipPos.y > -clipPos.w, \
|
||||
clipPos.z > -clipPos.w); \
|
||||
output.clipFlag = int3(clip0) + 2*int3(clip1); \
|
||||
|
||||
#define OSD_PATCH_CULL(N) \
|
||||
int3 clipFlag = int3(0,0,0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= patch[i].clipFlag; \
|
||||
} \
|
||||
if (any(clipFlag != int3(3,3,3))) { \
|
||||
output.tessLevelInner[0] = 0; \
|
||||
output.tessLevelInner[1] = 0; \
|
||||
output.tessLevelOuter[0] = 0; \
|
||||
output.tessLevelOuter[1] = 0; \
|
||||
output.tessLevelOuter[2] = 0; \
|
||||
output.tessLevelOuter[3] = 0; \
|
||||
output.tessOuterLo = float4(0,0,0,0); \
|
||||
output.tessOuterHi = float4(0,0,0,0); \
|
||||
return output; \
|
||||
}
|
||||
|
||||
#define OSD_PATCH_CULL_TRIANGLE(N) \
|
||||
int3 clipFlag = int3(0,0,0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= patch[i].clipFlag; \
|
||||
} \
|
||||
if (any(clipFlag != int3(3,3,3))) { \
|
||||
output.tessLevelInner[0] = 0; \
|
||||
output.tessLevelOuter[0] = 0; \
|
||||
output.tessLevelOuter[1] = 0; \
|
||||
output.tessLevelOuter[2] = 0; \
|
||||
output.tessOuterLo = float4(0,0,0,0); \
|
||||
output.tessOuterHi = float4(0,0,0,0); \
|
||||
return output; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
|
||||
#define OSD_PATCH_CULL(N)
|
||||
#define OSD_PATCH_CULL_TRIANGLE(N)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@ -564,7 +444,7 @@ OsdFlipMatrix(float4x4 m)
|
||||
}
|
||||
|
||||
// Regular BSpline to Bezier
|
||||
static float4x4 Q = {
|
||||
static const float4x4 Q = {
|
||||
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,
|
||||
@ -572,7 +452,7 @@ static float4x4 Q = {
|
||||
};
|
||||
|
||||
// Infinitely Sharp (boundary)
|
||||
static float4x4 Mi = {
|
||||
static const 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,
|
||||
|
@ -22,6 +22,128 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct InputVertex {
|
||||
float4 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
struct HullVertex {
|
||||
float4 position : POSITION;
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
int3 clipFlag : CLIPFLAG;
|
||||
#endif
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OutputVertex {
|
||||
float4 positionOut : SV_Position;
|
||||
float4 position : POSITION1;
|
||||
float3 normal : NORMAL;
|
||||
float3 tangent : TANGENT;
|
||||
float3 bitangent : TANGENT1;
|
||||
float4 patchCoord : PATCHCOORD; // u, v, faceLevel, faceId
|
||||
noperspective float4 edgeDistance : EDGEDISTANCE;
|
||||
#if defined(OSD_COMPUTE_NORMAL_DERIVATIVES)
|
||||
float3 Nu : TANGENT2;
|
||||
float3 Nv : TANGENT3;
|
||||
#endif
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments : VSEGMENTS;
|
||||
#endif
|
||||
};
|
||||
|
||||
float4x4 OsdModelViewProjectionMatrix();
|
||||
int OsdGregoryQuadOffsetBase();
|
||||
int OsdPrimitiveIdBase();
|
||||
int OsdBaseVertex();
|
||||
|
||||
#ifndef OSD_DISPLACEMENT_CALLBACK
|
||||
#define OSD_DISPLACEMENT_CALLBACK
|
||||
#endif
|
||||
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
Buffer<uint3> OsdPatchParamBuffer : register( t0 );
|
||||
#else
|
||||
Buffer<uint2> OsdPatchParamBuffer : register( t0 );
|
||||
#endif
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return (primitiveId + OsdPrimitiveIdBase());
|
||||
}
|
||||
|
||||
int3 OsdGetPatchParam(int patchIndex)
|
||||
{
|
||||
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
return OsdPatchParamBuffer[patchIndex].xyz;
|
||||
#else
|
||||
uint2 p = OsdPatchParamBuffer[patchIndex].xy;
|
||||
return int3(p.x, p.y, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef OSD_ENABLE_PATCH_CULL
|
||||
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P) \
|
||||
float4 clipPos = mul(OsdModelViewProjectionMatrix(), P); \
|
||||
int3 clip0 = int3(clipPos.x < clipPos.w, \
|
||||
clipPos.y < clipPos.w, \
|
||||
clipPos.z < clipPos.w); \
|
||||
int3 clip1 = int3(clipPos.x > -clipPos.w, \
|
||||
clipPos.y > -clipPos.w, \
|
||||
clipPos.z > -clipPos.w); \
|
||||
output.clipFlag = int3(clip0) + 2*int3(clip1); \
|
||||
|
||||
#define OSD_PATCH_CULL(N) \
|
||||
int3 clipFlag = int3(0,0,0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= patch[i].clipFlag; \
|
||||
} \
|
||||
if (any(clipFlag != int3(3,3,3))) { \
|
||||
output.tessLevelInner[0] = 0; \
|
||||
output.tessLevelInner[1] = 0; \
|
||||
output.tessLevelOuter[0] = 0; \
|
||||
output.tessLevelOuter[1] = 0; \
|
||||
output.tessLevelOuter[2] = 0; \
|
||||
output.tessLevelOuter[3] = 0; \
|
||||
output.tessOuterLo = float4(0,0,0,0); \
|
||||
output.tessOuterHi = float4(0,0,0,0); \
|
||||
return output; \
|
||||
}
|
||||
|
||||
#define OSD_PATCH_CULL_TRIANGLE(N) \
|
||||
int3 clipFlag = int3(0,0,0); \
|
||||
for(int i = 0; i < N; ++i) { \
|
||||
clipFlag |= patch[i].clipFlag; \
|
||||
} \
|
||||
if (any(clipFlag != int3(3,3,3))) { \
|
||||
output.tessLevelInner[0] = 0; \
|
||||
output.tessLevelOuter[0] = 0; \
|
||||
output.tessLevelOuter[1] = 0; \
|
||||
output.tessLevelOuter[2] = 0; \
|
||||
output.tessOuterLo = float4(0,0,0,0); \
|
||||
output.tessOuterHi = float4(0,0,0,0); \
|
||||
return output; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define OSD_PATCH_CULL_COMPUTE_CLIPFLAGS(P)
|
||||
#define OSD_PATCH_CULL(N)
|
||||
#define OSD_PATCH_CULL_TRIANGLE(N)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Legacy Gregory
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -24,173 +24,15 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
#include <metal_stdlib>
|
||||
|
||||
#define offsetof_(X, Y) &(((device X*)nullptr)->Y)
|
||||
|
||||
#define OSD_IS_ADAPTIVE (OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY)
|
||||
|
||||
#ifndef OSD_MAX_TESS_LEVEL
|
||||
#define OSD_MAX_TESS_LEVEL 64
|
||||
#endif
|
||||
|
||||
#ifndef OSD_NUM_ELEMENTS
|
||||
#define OSD_NUM_ELEMENTS 3
|
||||
#endif
|
||||
|
||||
using namespace metal;
|
||||
|
||||
using OsdPatchParamBufferType = packed_int3;
|
||||
|
||||
struct OsdPerVertexGregory {
|
||||
float3 P;
|
||||
short3 clipFlag;
|
||||
int valence;
|
||||
float3 e0;
|
||||
float3 e1;
|
||||
#if OSD_PATCH_GREGORY_BOUNDARY
|
||||
int zerothNeighbor;
|
||||
float3 org;
|
||||
#endif
|
||||
float3 r[OSD_MAX_VALENCE];
|
||||
};
|
||||
|
||||
struct OsdPerPatchVertexGregory {
|
||||
packed_float3 P;
|
||||
packed_float3 Ep;
|
||||
packed_float3 Em;
|
||||
packed_float3 Fp;
|
||||
packed_float3 Fm;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
// HLSL->Metal Compatibility
|
||||
//----------------------------------------------------------
|
||||
|
||||
float4 mul(float4x4 a, float4 b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
float3 mul(float4x4 a, float3 b)
|
||||
{
|
||||
float3x3 m(a[0].xyz, a[1].xyz, a[2].xyz);
|
||||
return m * b;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct HullVertex {
|
||||
float4 position;
|
||||
#if OSD_ENABLE_PATCH_CULL
|
||||
short3 clipFlag;
|
||||
#endif
|
||||
|
||||
float3 GetPosition() threadgroup
|
||||
{
|
||||
return position.xyz;
|
||||
}
|
||||
|
||||
void SetPosition(float3 v) threadgroup
|
||||
{
|
||||
position.xyz = v;
|
||||
}
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OsdPatchVertex {
|
||||
float3 position;
|
||||
float3 normal;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
float4 patchCoord; //u, v, faceLevel, faceId
|
||||
float2 tessCoord; // tesscoord.st
|
||||
#if OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
float3 Nu;
|
||||
float3 Nv;
|
||||
#endif
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OsdPerPatchTessFactors {
|
||||
float4 tessOuterLo;
|
||||
float4 tessOuterHi;
|
||||
};
|
||||
|
||||
struct OsdPerPatchVertexBezier {
|
||||
packed_float3 P;
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
packed_float3 P1;
|
||||
packed_float3 P2;
|
||||
#if !USE_PTVS_SHARPNESS
|
||||
float2 vSegments;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OsdPerPatchVertexGregoryBasis {
|
||||
packed_float3 P;
|
||||
};
|
||||
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE
|
||||
using PatchVertexType = HullVertex;
|
||||
using PerPatchVertexType = OsdPerPatchVertexBezier;
|
||||
#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
using PatchVertexType = OsdPerVertexGregory;
|
||||
using PerPatchVertexType = OsdPerPatchVertexGregory;
|
||||
#elif OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE
|
||||
using PatchVertexType = HullVertex;
|
||||
using PerPatchVertexType = OsdPerPatchVertexGregoryBasis;
|
||||
#else
|
||||
using PatchVertexType = OsdInputVertexType;
|
||||
using PerPatchVertexType = OsdInputVertexType;
|
||||
#endif
|
||||
|
||||
//Shared buffers used by OSD that are common to all kernels
|
||||
struct OsdPatchParamBufferSet
|
||||
{
|
||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||
|
||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||
|
||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]];
|
||||
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||
#endif
|
||||
|
||||
#if OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
|
||||
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
|
||||
#endif
|
||||
|
||||
const constant unsigned& kernelExecutionLimit [[buffer(OSD_KERNELLIMIT_BUFFER_INDEX)]];
|
||||
};
|
||||
|
||||
//Shared buffers used by OSD that are common to all PTVS implementations
|
||||
struct OsdVertexBufferSet
|
||||
{
|
||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||
|
||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||
|
||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]];
|
||||
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||
#endif
|
||||
};
|
||||
// The following callback functions are used when evaluating tessellation
|
||||
// rates and when using legacy patch drawing.
|
||||
float4x4 OsdModelViewMatrix();
|
||||
float4x4 OsdProjectionMatrix();
|
||||
float OsdTessLevel();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Patch Parameters
|
||||
@ -204,25 +46,6 @@ struct OsdVertexBufferSet
|
||||
// bitfield -- refinement-level, non-quad, boundary, transition, uv-offset
|
||||
// sharpness -- crease sharpness for single-crease patches
|
||||
//
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
//
|
||||
|
||||
int3 OsdGetPatchParam(int patchIndex, const device OsdPatchParamBufferType* osdPatchParamBuffer)
|
||||
{
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
return int3(osdPatchParamBuffer[patchIndex]);
|
||||
#else
|
||||
auto p = osdPatchParamBuffer[patchIndex];
|
||||
return int3(p[0], p[1], 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return primitiveId;
|
||||
}
|
||||
|
||||
int OsdGetPatchFaceId(int3 patchParam)
|
||||
{
|
||||
@ -316,40 +139,6 @@ float4 OsdInterpolatePatchCoordTriangle(float2 localUV, int3 patchParam)
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool OsdCullPerPatchVertex(
|
||||
threadgroup PatchVertexType* patch,
|
||||
float4x4 ModelViewMatrix
|
||||
)
|
||||
{
|
||||
#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR
|
||||
auto v0 = float3(ModelViewMatrix * patch[5].position);
|
||||
auto v3 = float3(ModelViewMatrix * patch[6].position);
|
||||
auto v12 = float3(ModelViewMatrix * patch[9].position);
|
||||
|
||||
auto n = normalize(cross(v3 - v0, v12 - v0));
|
||||
v0 = normalize(v0 + v3 + v12);
|
||||
|
||||
if(dot(v0, n) > 0.6f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if OSD_ENABLE_PATCH_CULL
|
||||
short3 clipFlag = short3(0,0,0);
|
||||
for(int i = 0; i < CONTROL_POINTS_PER_PATCH; ++i) {
|
||||
clipFlag |= patch[i].clipFlag;
|
||||
}
|
||||
if (any(clipFlag != short3(3,3,3))) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
@ -421,6 +210,17 @@ OsdUnivar4x4(float u, thread float* B, thread float* D, thread float* C)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct OsdPerPatchVertexBezier {
|
||||
packed_float3 P;
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
packed_float3 P1;
|
||||
packed_float3 P2;
|
||||
#if !USE_PTVS_SHARPNESS
|
||||
float2 vSegments;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
float3
|
||||
OsdEvalBezier(float3 cp[16], float2 uv)
|
||||
{
|
||||
@ -1088,6 +888,10 @@ OsdEvalPatchBezier(int3 patchParam, float2 UV,
|
||||
// Gregory Basis
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
struct OsdPerPatchVertexGregoryBasis {
|
||||
packed_float3 P;
|
||||
};
|
||||
|
||||
void
|
||||
OsdComputePerPatchVertexGregoryBasis(int3 patchParam, int ID, float3 cv,
|
||||
device OsdPerPatchVertexGregoryBasis& result)
|
||||
@ -1444,3 +1248,4 @@ OsdEvalPatchGregoryTriangle(int3 patchParam, float2 UV, float3 cv[18],
|
||||
|
||||
OsdEvalPatchBezierTriangle(patchParam, UV, bezcv, P, dPu, dPv, N, dNu, dNv);
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,10 @@
|
||||
// (0,0) (1,0)
|
||||
//
|
||||
|
||||
#ifndef OSD_MAX_TESS_LEVEL
|
||||
#define OSD_MAX_TESS_LEVEL 64
|
||||
#endif
|
||||
|
||||
float OsdComputePostProjectionSphereExtent(
|
||||
const float4x4 OsdProjectionMatrix, float3 center, float diameter)
|
||||
{
|
||||
|
@ -24,6 +24,200 @@
|
||||
// language governing permissions and limitations under the Apache License.
|
||||
//
|
||||
|
||||
//----------------------------------------------------------
|
||||
// Patches.Common
|
||||
//----------------------------------------------------------
|
||||
|
||||
#define offsetof_(X, Y) &(((device X*)nullptr)->Y)
|
||||
|
||||
#define OSD_IS_ADAPTIVE (OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE || OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE || OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY)
|
||||
|
||||
#ifndef OSD_NUM_ELEMENTS
|
||||
#define OSD_NUM_ELEMENTS 3
|
||||
#endif
|
||||
|
||||
struct OsdPerVertexGregory {
|
||||
float3 P;
|
||||
short3 clipFlag;
|
||||
int valence;
|
||||
float3 e0;
|
||||
float3 e1;
|
||||
#if OSD_PATCH_GREGORY_BOUNDARY
|
||||
int zerothNeighbor;
|
||||
float3 org;
|
||||
#endif
|
||||
float3 r[OSD_MAX_VALENCE];
|
||||
};
|
||||
|
||||
struct OsdPerPatchVertexGregory {
|
||||
packed_float3 P;
|
||||
packed_float3 Ep;
|
||||
packed_float3 Em;
|
||||
packed_float3 Fp;
|
||||
packed_float3 Fm;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
// HLSL->Metal Compatibility
|
||||
//----------------------------------------------------------
|
||||
|
||||
float4 mul(float4x4 a, float4 b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
float3 mul(float4x4 a, float3 b)
|
||||
{
|
||||
float3x3 m(a[0].xyz, a[1].xyz, a[2].xyz);
|
||||
return m * b;
|
||||
|
||||
}
|
||||
|
||||
struct HullVertex {
|
||||
float4 position;
|
||||
#if OSD_ENABLE_PATCH_CULL
|
||||
short3 clipFlag;
|
||||
#endif
|
||||
|
||||
float3 GetPosition() threadgroup
|
||||
{
|
||||
return position.xyz;
|
||||
}
|
||||
|
||||
void SetPosition(float3 v) threadgroup
|
||||
{
|
||||
position.xyz = v;
|
||||
}
|
||||
};
|
||||
|
||||
// XXXdyu all downstream data can be handled by client code
|
||||
struct OsdPatchVertex {
|
||||
float3 position;
|
||||
float3 normal;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
float4 patchCoord; //u, v, faceLevel, faceId
|
||||
float2 tessCoord; // tesscoord.st
|
||||
#if OSD_COMPUTE_NORMAL_DERIVATIVES
|
||||
float3 Nu;
|
||||
float3 Nv;
|
||||
#endif
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
float2 vSegments;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct OsdPerPatchTessFactors {
|
||||
float4 tessOuterLo;
|
||||
float4 tessOuterHi;
|
||||
};
|
||||
|
||||
using OsdPatchParamBufferType = packed_int3;
|
||||
|
||||
#if OSD_PATCH_REGULAR || OSD_PATCH_BOX_SPLINE_TRIANGLE
|
||||
using PatchVertexType = HullVertex;
|
||||
using PerPatchVertexType = OsdPerPatchVertexBezier;
|
||||
#elif OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
using PatchVertexType = OsdPerVertexGregory;
|
||||
using PerPatchVertexType = OsdPerPatchVertexGregory;
|
||||
#elif OSD_PATCH_GREGORY_BASIS || OSD_PATCH_GREGORY_TRIANGLE
|
||||
using PatchVertexType = HullVertex;
|
||||
using PerPatchVertexType = OsdPerPatchVertexGregoryBasis;
|
||||
#else
|
||||
using PatchVertexType = OsdInputVertexType;
|
||||
using PerPatchVertexType = OsdInputVertexType;
|
||||
#endif
|
||||
|
||||
//Shared buffers used by OSD that are common to all kernels
|
||||
struct OsdPatchParamBufferSet
|
||||
{
|
||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||
|
||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||
|
||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]];
|
||||
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||
#endif
|
||||
|
||||
#if OSD_PATCH_GREGORY || OSD_PATCH_GREGORY_BOUNDARY
|
||||
const device int* quadOffsetBuffer [[buffer(OSD_QUADOFFSET_BUFFER_INDEX)]];
|
||||
const device int* valenceBuffer [[buffer(OSD_VALENCE_BUFFER_INDEX)]];
|
||||
#endif
|
||||
|
||||
const constant unsigned& kernelExecutionLimit [[buffer(OSD_KERNELLIMIT_BUFFER_INDEX)]];
|
||||
};
|
||||
|
||||
//Shared buffers used by OSD that are common to all PTVS implementations
|
||||
struct OsdVertexBufferSet
|
||||
{
|
||||
const device OsdInputVertexType* vertexBuffer [[buffer(VERTEX_BUFFER_INDEX)]];
|
||||
const device unsigned* indexBuffer [[buffer(CONTROL_INDICES_BUFFER_INDEX)]];
|
||||
|
||||
const device OsdPatchParamBufferType* patchParamBuffer [[buffer(OSD_PATCHPARAM_BUFFER_INDEX)]];
|
||||
|
||||
device PerPatchVertexType* perPatchVertexBuffer [[buffer(OSD_PERPATCHVERTEX_BUFFER_INDEX)]];
|
||||
|
||||
#if !USE_PTVS_FACTORS
|
||||
device OsdPerPatchTessFactors* patchTessBuffer [[buffer(OSD_PERPATCHTESSFACTORS_BUFFER_INDEX)]];
|
||||
#endif
|
||||
};
|
||||
|
||||
// These are stored in OsdPatchParamBuffer indexed by the value returned
|
||||
// from OsdGetPatchIndex() which is a function of the current PrimitiveID
|
||||
// along with an optional client provided offset.
|
||||
|
||||
int3 OsdGetPatchParam(int patchIndex, const device OsdPatchParamBufferType* osdPatchParamBuffer)
|
||||
{
|
||||
#if OSD_PATCH_ENABLE_SINGLE_CREASE
|
||||
return int3(osdPatchParamBuffer[patchIndex]);
|
||||
#else
|
||||
auto p = osdPatchParamBuffer[patchIndex];
|
||||
return int3(p[0], p[1], 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
int OsdGetPatchIndex(int primitiveId)
|
||||
{
|
||||
return primitiveId;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// patch culling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool OsdCullPerPatchVertex(
|
||||
threadgroup PatchVertexType* patch,
|
||||
float4x4 ModelViewMatrix
|
||||
)
|
||||
{
|
||||
#if OSD_ENABLE_BACKPATCH_CULL && OSD_PATCH_REGULAR
|
||||
auto v0 = float3(ModelViewMatrix * patch[5].position);
|
||||
auto v3 = float3(ModelViewMatrix * patch[6].position);
|
||||
auto v12 = float3(ModelViewMatrix * patch[9].position);
|
||||
|
||||
auto n = normalize(cross(v3 - v0, v12 - v0));
|
||||
v0 = normalize(v0 + v3 + v12);
|
||||
|
||||
if(dot(v0, n) > 0.6f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if OSD_ENABLE_PATCH_CULL
|
||||
short3 clipFlag = short3(0,0,0);
|
||||
for(int i = 0; i < CONTROL_POINTS_PER_PATCH; ++i) {
|
||||
clipFlag |= patch[i].clipFlag;
|
||||
}
|
||||
if (any(clipFlag != short3(3,3,3))) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Legacy Gregory
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user