Merge pull request #1126 from davidgyu/examples_shaders

Minor improvements to examples for Loop
This commit is contained in:
George ElKoura 2019-06-17 21:11:02 -07:00 committed by GitHub
commit 3c4081aac3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 129 additions and 112 deletions

View File

@ -465,13 +465,7 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
};
int patchType = 0;
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
if (sharpness > 0) {
pattern = 1;
}
#endif
int pattern = countbits(OsdGetPatchTransitionMask(patchParam));
int edgeCount = countbits(OsdGetPatchBoundaryMask(patchParam));
if (edgeCount == 1) {
patchType = 2; // BOUNDARY
@ -480,9 +474,11 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
patchType = 3; // CORNER
}
// XXX: it looks like edgeCount != 0 for some gregory boundary patches.
// there might be a bug somewhere...
#if defined OSD_PATCH_GREGORY
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
if (sharpness > 0) {
patchType = 1;
}
#elif defined OSD_PATCH_GREGORY
patchType = 4;
#elif defined OSD_PATCH_GREGORY_BOUNDARY
patchType = 5;
@ -490,6 +486,8 @@ getAdaptivePatchColor(int3 patchParam, float sharpness)
patchType = 6;
#endif
int pattern = countbits(OsdGetPatchTransitionMask(patchParam));
return patchColors[6*patchType + pattern];
}

View File

@ -416,11 +416,7 @@ getAdaptivePatchColor(int3 patchParam, float2 vSegments)
if (vSegments.y > 0) {
patchType = 1;
}
#endif
// XXX: it looks like edgeCount != 0 for gregory_boundary.
// there might be a bug somewhere.
#if defined OSD_PATCH_GREGORY
#elif defined OSD_PATCH_GREGORY
patchType = 4;
#elif defined OSD_PATCH_GREGORY_BOUNDARY
patchType = 5;

View File

@ -236,7 +236,7 @@ struct FVarData
glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
@ -251,7 +251,7 @@ struct FVarData
glBindTexture(GL_TEXTURE_BUFFER, textureParamBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindTexture(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
}
@ -545,13 +545,11 @@ GetEffect(bool uvDraw = false) {
struct EffectDesc {
EffectDesc(OpenSubdiv::Far::PatchDescriptor desc,
OpenSubdiv::Far::PatchDescriptor fvarDesc,
Effect effect) : desc(desc), fvarDesc(fvarDesc),
Effect effect) : desc(desc),
effect(effect),
maxValence(0), numElements(0) { }
OpenSubdiv::Far::PatchDescriptor desc;
OpenSubdiv::Far::PatchDescriptor fvarDesc;
Effect effect;
int maxValence;
int numElements;
@ -559,10 +557,9 @@ struct EffectDesc {
bool operator < (const EffectDesc &e) const {
return
(desc < e.desc || ((desc == e.desc &&
(fvarDesc < e.fvarDesc || ((fvarDesc == e.fvarDesc &&
(maxValence < e.maxValence || ((maxValence == e.maxValence) &&
(numElements < e.numElements || ((numElements == e.numElements) &&
(effect < e.effect)))))))))));
(effect < e.effect))))))));
}
};
@ -589,11 +586,6 @@ public:
if (type == Far::PatchDescriptor::QUADS) {
ss << "#define PRIM_QUAD\n";
} else if (type == Far::PatchDescriptor::TRIANGLES ||
type == Far::PatchDescriptor::LOOP ||
type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define PRIM_TRI\n";
ss << "#define LOOP\n";
} else {
ss << "#define PRIM_TRI\n";
}
@ -626,14 +618,6 @@ public:
ss << "#define SHADING_FACEVARYING_UNIFORM_SUBDIVISION\n";
}
if (effectDesc.desc.IsAdaptive()) {
if (effectDesc.fvarDesc.GetType() == Far::PatchDescriptor::REGULAR) {
ss << "#define SHADING_FACEVARYING_SMOOTH_BSPLINE_BASIS\n";
} else if (effectDesc.fvarDesc.GetType() == Far::PatchDescriptor::GREGORY_BASIS) {
ss << "#define SHADING_FACEVARYING_SMOOTH_GREGORY_BASIS\n";
}
}
// include osd PatchCommon
ss << "#define OSD_PATCH_BASIS_GLSL\n";
ss << Osd::GLSLPatchShaderSource::GetPatchBasisShaderSource();
@ -699,7 +683,7 @@ public:
glUniformBlockBinding(program, uboIndex, g_tessellationBinding);
g_fvarArrayDataBinding = 2;
uboIndex = glGetUniformBlockIndex(program, "FVarArrayData");
uboIndex = glGetUniformBlockIndex(program, "OsdFVarArrayData");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_fvarArrayDataBinding);
@ -802,10 +786,9 @@ bindTextures() {
static GLenum
bindProgram(Effect effect,
OpenSubdiv::Osd::PatchArray const & patch,
OpenSubdiv::Far::PatchDescriptor const & fvarDesc) {
OpenSubdiv::Osd::PatchArray const & patch) {
EffectDesc effectDesc(patch.GetDescriptor(), fvarDesc, effect);
EffectDesc effectDesc(patch.GetDescriptor(), effect);
typedef OpenSubdiv::Far::PatchDescriptor Descriptor;
@ -884,9 +867,6 @@ display() {
glBindVertexArray(g_vao);
OpenSubdiv::Far::PatchDescriptor fvarDesc =
g_mesh->GetFarPatchTable()->GetFVarPatchDescriptor(0);
OpenSubdiv::Osd::PatchArrayVector const & patches =
g_mesh->GetPatchTable()->GetPatchArrays();
@ -900,7 +880,7 @@ display() {
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::PatchArray const & patch = patches[i];
GLenum primType = bindProgram(GetEffect(), patch, fvarDesc);
GLenum primType = bindProgram(GetEffect(), patch);
glDrawElements(
primType,
@ -934,7 +914,7 @@ display() {
for (int i = 0; i < (int)patches.size(); ++i) {
OpenSubdiv::Osd::PatchArray const & patch = patches[i];
GLenum primType = bindProgram(GetEffect(/*uvDraw=*/ true), patch, fvarDesc);
GLenum primType = bindProgram(GetEffect(/*uvDraw=*/ true), patch);
glDrawElements(
primType,

View File

@ -167,7 +167,7 @@ out block {
} outpt;
uniform isamplerBuffer OsdFVarParamBuffer;
layout(std140) uniform FVarArrayData {
layout(std140) uniform OsdFVarArrayData {
OsdPatchArray fvarPatchArray[2];
};
@ -211,25 +211,22 @@ void emit(int index, vec3 normal)
outpt.v.normal = normal;
#endif
#ifdef LOOP // ----- scheme : LOOP
#ifdef SHADING_FACEVARYING_UNIFORM_SUBDIVISION
// interpolate fvar data at refined tri or quad vertex locations
#ifdef PRIM_TRI
vec2 trist[3] = vec2[](vec2(0,0), vec2(1,0), vec2(0,1));
#ifdef SHADING_FACEVARYING_UNIFORM_SUBDIVISION
vec2 st = trist[index];
#else
vec2 st = inpt[index].v.tessCoord;
#endif
vec2 uv = interpolateFaceVarying(st, /*fvarOffset*/0);
#else // ----- scheme : CATMARK / BILINEAR
#ifdef SHADING_FACEVARYING_UNIFORM_SUBDIVISION
#ifdef PRIM_QUAD
vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
vec2 st = quadst[index];
#endif
#else
// interpolate fvar data at tessellated vertex locations
vec2 st = inpt[index].v.tessCoord;
#endif
vec2 uv = interpolateFaceVarying(st, /*fvarOffset*/0);
#endif // ------ scheme
outpt.color = vec3(uv.s, uv.t, 0);

View File

@ -117,11 +117,6 @@ public:
} else if (type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define OSD_PATCH_GREGORY_TRIANGLE\n";
}
if (type == Far::PatchDescriptor::TRIANGLES ||
type == Far::PatchDescriptor::LOOP ||
type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define LOOP\n";
}
if (desc.IsAdaptive()) {
ss << "#define SMOOTH_NORMALS\n";

View File

@ -44,6 +44,13 @@
mix(mix(inpt[a].color, inpt[b].color, UV.x), \
mix(inpt[c].color, inpt[d].color, UV.x), UV.y)
#undef OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE
#define OSD_USER_VARYING_PER_EVAL_POINT_TRIANGLE(UV, a, b, c) \
outpt.color = \
inpt[a].color * (1.0f - UV.x - UV.y) + \
inpt[b].color * UV.x + \
inpt[c].color * UV.y;
//--------------------------------------------------------------
// Uniforms / Uniform Blocks
//--------------------------------------------------------------
@ -358,7 +365,7 @@ getAdaptivePatchColor(ivec3 patchParam)
patchType = 3; // CORNER (not correct for patches that are not isolated)
}
#if defined(OSD_PATCH_ENABLE_SINGLE_CREASE) && !defined(LOOP)
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
// check this after boundary/corner since single crease patch also has edgeCount.
if (inpt.vSegments.y > 0) {
patchType = 1;

View File

@ -704,11 +704,6 @@ public:
} else if (type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define OSD_PATCH_GREGORY_TRIANGLE\n";
}
if (type == Far::PatchDescriptor::TRIANGLES ||
type == Far::PatchDescriptor::LOOP ||
type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define LOOP\n";
}
// include osd PatchCommon
ss << Osd::GLSLPatchShaderSource::GetCommonShaderSource();

View File

@ -475,7 +475,7 @@ GetOverrideColor(ivec3 patchParam)
patchType = 3; // CORNER (not correct for patches that are not isolated)
}
#if defined(OSD_PATCH_ENABLE_SINGLE_CREASE) && !defined(LOOP)
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
// check this after boundary/corner since single crease patch also has edgeCount.
if (inpt.vSegments.y > 0) {
patchType = 1;

View File

@ -378,11 +378,6 @@ public:
} else if (type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define OSD_PATCH_GREGORY_TRIANGLE\n";
}
if (type == Far::PatchDescriptor::TRIANGLES ||
type == Far::PatchDescriptor::LOOP ||
type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define LOOP\n";
}
// for legacy gregory
ss << "#define OSD_MAX_VALENCE " << effectDesc.maxValence << "\n";

View File

@ -424,7 +424,7 @@ getAdaptivePatchColor(ivec3 patchParam)
patchType = 3; // CORNER (not correct for patches that are not isolated)
}
#if defined(OSD_PATCH_ENABLE_SINGLE_CREASE) && !defined(LOOP)
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
// check this after boundary/corner since single crease patch also has edgeCount.
if (inpt.vSegments.y > 0) {
patchType = 1;

View File

@ -233,7 +233,9 @@ GLuint g_transformUB = 0,
g_tessellationUB = 0,
g_tessellationBinding = 1,
g_lightingUB = 0,
g_lightingBinding = 2;
g_lightingBinding = 2,
g_fvarArrayDataUB = 0,
g_fvarArrayDataBinding = 3;
struct Transform {
float ModelViewMatrix[16];
@ -251,7 +253,7 @@ GLuint g_vao = 0;
struct FVarData
{
FVarData() :
textureBuffer(0) {
textureBuffer(0), textureParamBuffer(0) {
}
~FVarData() {
Release();
@ -260,11 +262,17 @@ struct FVarData
if (textureBuffer)
glDeleteTextures(1, &textureBuffer);
textureBuffer = 0;
if (textureParamBuffer)
glDeleteTextures(1, &textureParamBuffer);
textureParamBuffer = 0;
}
void Create(OpenSubdiv::Far::PatchTable const *patchTable,
int fvarWidth, std::vector<float> const & fvarSrcData) {
using namespace OpenSubdiv;
Release();
OpenSubdiv::Far::ConstIndexArray indices = patchTable->GetFVarValues();
Far::ConstIndexArray indices = patchTable->GetFVarValues();
// expand fvardata to per-patch array
std::vector<float> data;
@ -289,8 +297,22 @@ struct FVarData
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
Far::ConstPatchParamArray fvarParam = patchTable->GetFVarPatchParams();
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, fvarParam.size()*sizeof(Far::PatchParam),
&fvarParam[0], GL_STATIC_DRAW);
glGenTextures(1, &textureParamBuffer);
glBindTexture(GL_TEXTURE_BUFFER, textureParamBuffer);
glTexBuffer(GL_TEXTURE_BUFFER, GL_RG32I, buffer);
glBindTexture(GL_TEXTURE_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &buffer);
}
GLuint textureBuffer;
GLuint textureBuffer, textureParamBuffer;
} g_fvarData;
//------------------------------------------------------------------------------
@ -780,11 +802,6 @@ public:
break;
}
if (type == Far::PatchDescriptor::TRIANGLES ||
type == Far::PatchDescriptor::LOOP ||
type == Far::PatchDescriptor::GREGORY_TRIANGLE) {
ss << "#define LOOP\n";
}
if (type != Far::PatchDescriptor::TRIANGLES &&
type != Far::PatchDescriptor::QUADS) {
ss << "#define SMOOTH_NORMALS\n";
@ -869,6 +886,10 @@ public:
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_lightingBinding);
uboIndex = glGetUniformBlockIndex(program, "OsdFVarArrayData");
if (uboIndex != GL_INVALID_INDEX)
glUniformBlockBinding(program, uboIndex, g_fvarArrayDataBinding);
// assign texture locations
GLint loc;
glUseProgram(program);
@ -878,16 +899,19 @@ public:
if ((loc = glGetUniformLocation(program, "OsdFVarDataBuffer")) != -1) {
glUniform1i(loc, 1); // GL_TEXTURE1
}
// for legacy gregory patches
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdFVarParamBuffer")) != -1) {
glUniform1i(loc, 2); // GL_TEXTURE2
}
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
// for legacy gregory patches
if ((loc = glGetUniformLocation(program, "OsdVertexBuffer")) != -1) {
glUniform1i(loc, 3); // GL_TEXTURE3
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
if ((loc = glGetUniformLocation(program, "OsdValenceBuffer")) != -1) {
glUniform1i(loc, 4); // GL_TEXTURE4
}
if ((loc = glGetUniformLocation(program, "OsdQuadOffsetBuffer")) != -1) {
glUniform1i(loc, 5); // GL_TEXTURE5
}
glUseProgram(0);
return config;
@ -899,6 +923,9 @@ ShaderCache g_shaderCache;
//------------------------------------------------------------------------------
static void
updateUniformBlocks() {
using namespace OpenSubdiv;
if (! g_transformUB) {
glGenBuffers(1, &g_transformUB);
glBindBuffer(GL_UNIFORM_BUFFER, g_transformUB);
@ -932,6 +959,29 @@ updateUniformBlocks() {
glBindBufferBase(GL_UNIFORM_BUFFER, g_tessellationBinding, g_tessellationUB);
// Update and bind fvar patch array state
if (g_mesh->GetPatchTable()->GetNumFVarChannels() > 0) {
Osd::PatchArrayVector const &fvarPatchArrays =
g_mesh->GetPatchTable()->GetFVarPatchArrays();
// bind patch arrays UBO (std140 struct size padded to vec4 alignment)
int patchArraySize =
sizeof(GLint) * ((sizeof(Osd::PatchArray)/sizeof(GLint) + 3) & ~3);
if (!g_fvarArrayDataUB) {
glGenBuffers(1, &g_fvarArrayDataUB);
}
glBindBuffer(GL_UNIFORM_BUFFER, g_fvarArrayDataUB);
glBufferData(GL_UNIFORM_BUFFER,
fvarPatchArrays.size()*patchArraySize, NULL, GL_STATIC_DRAW);
for (int i=0; i<(int)fvarPatchArrays.size(); ++i) {
glBufferSubData(GL_UNIFORM_BUFFER,
i*patchArraySize, sizeof(Osd::PatchArray), &fvarPatchArrays[i]);
}
glBindBufferBase(GL_UNIFORM_BUFFER,
g_fvarArrayDataBinding, g_fvarArrayDataUB);
}
// Update and bind lighting state
struct Lighting {
struct Light {
@ -978,17 +1028,20 @@ bindTextures() {
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_BUFFER,
g_fvarData.textureBuffer);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_fvarData.textureParamBuffer);
}
// legacy gregory
if (g_legacyGregoryPatchTable) {
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_BUFFER,
g_legacyGregoryPatchTable->GetVertexTextureBuffer());
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_BUFFER,
g_legacyGregoryPatchTable->GetVertexValenceTextureBuffer());
g_legacyGregoryPatchTable->GetVertexTextureBuffer());
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_BUFFER,
g_legacyGregoryPatchTable->GetVertexValenceTextureBuffer());
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_BUFFER,
g_legacyGregoryPatchTable->GetQuadOffsetsTextureBuffer());
}

View File

@ -179,23 +179,29 @@ out block {
OSD_USER_VARYING_DECLARE
} outpt;
uniform isamplerBuffer OsdFVarParamBuffer;
layout(std140) uniform OsdFVarArrayData {
OsdPatchArray fvarPatchArray[2];
};
vec2
interpolateFaceVarying(vec2 uv, int fvarOffset)
{
int patchIndex = OsdGetPatchIndex(gl_PrimitiveID);
OsdPatchArray array = fvarPatchArray[0];
ivec3 fvarPatchParam = texelFetch(OsdFVarParamBuffer, patchIndex).xyz;
OsdPatchParam param = OsdPatchParamInit(fvarPatchParam.x,
fvarPatchParam.y,
fvarPatchParam.z);
int patchType = OsdPatchParamIsRegular(param) ? array.regDesc : array.desc;
float wP[20], wDu[20], wDv[20], wDuu[20], wDuv[20], wDvv[20];
#ifdef LOOP
int patchType = OSD_PATCH_DESCRIPTOR_TRIANGLES;
OsdPatchParam param = OsdPatchParamInit(0, 0, 0);
int numPoints = OsdEvaluatePatchBasisNormalized(patchType, param,
uv.s, uv.t, wP, wDu, wDv, wDuu, wDuv, wDvv);
#else
int patchType = OSD_PATCH_DESCRIPTOR_QUADS;
OsdPatchParam param = OsdPatchParamInit(0, 0, 0);
int numPoints = OsdEvaluatePatchBasisNormalized(patchType, param,
uv.s, uv.t, wP, wDu, wDv, wDuu, wDuv, wDvv);
#endif
int patchArrayStride = numPoints;
int primOffset = patchIndex * patchArrayStride;
@ -230,27 +236,22 @@ void emit(int index, vec3 normal)
#endif
#ifdef SHADING_FACEVARYING_COLOR
#ifdef LOOP // ----- scheme : LOOP
#ifdef SHADING_FACEVARYING_UNIFORM_SUBDIVISION
// interpolate fvar data at refined tri or quad vertex locations
#ifdef PRIM_TRI
vec2 trist[3] = vec2[](vec2(0,0), vec2(1,0), vec2(0,1));
vec2 st = trist[index];
#else
vec2 st = inpt[index].v.tessCoord;
#endif
vec2 uv = interpolateFaceVarying(st, /*fvarOffset=*/0);
#else // ----- scheme : CATMARK / BILINEAR
#ifdef SHADING_FACEVARYING_UNIFORM_SUBDIVISION
#ifdef PRIM_QUAD
vec2 quadst[4] = vec2[](vec2(0,0), vec2(1,0), vec2(1,1), vec2(0,1));
vec2 st = quadst[index];
#endif
#else
// interpolate fvar data at tessellated vertex locations
vec2 st = inpt[index].v.tessCoord;
#endif
vec2 uv = interpolateFaceVarying(st, /*fvarOffset=*/0);
#endif // ------ scheme
vec2 uv = interpolateFaceVarying(st, /*fvarOffset*/0);
outpt.color = vec3(uv.s, uv.t, 0);
#endif
@ -324,8 +325,8 @@ void main()
#endif // PRIM_QUAD
#ifdef PRIM_TRI
vec3 A = (inpt[1].v.position - inpt[0].v.position).xyz;
vec3 B = (inpt[2].v.position - inpt[0].v.position).xyz;
vec3 A = (inpt[0].v.position - inpt[1].v.position).xyz;
vec3 B = (inpt[2].v.position - inpt[1].v.position).xyz;
vec3 n0 = normalize(cross(B, A));
#if defined(GEOMETRY_OUT_WIRE) || defined(GEOMETRY_OUT_LINE)
@ -502,7 +503,7 @@ getAdaptivePatchColor(ivec3 patchParam)
patchType = 3; // CORNER (not correct for patches that are not isolated)
}
#if defined(OSD_PATCH_ENABLE_SINGLE_CREASE) && !defined(LOOP)
#if defined OSD_PATCH_ENABLE_SINGLE_CREASE
// check this after boundary/corner since single crease patch also has edgeCount.
if (inpt.vSegments.y > 0) {
patchType = 1;