mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-26 13:30:07 +00:00
improved glViewer shaders for Loop
Removed the use of the LOOP preprocessor symbol from the glFVarViewer shaders code. The shader code is now configured according to the types of the resulting patches without depending on the subdivision scheme of the mesh topology. Improved the implementation of face-varying interpolation similar to the glFVarViewer. Now the face-varying patch type is obtained from the face-varying patch array descriptor instead of being hard-coded by subdivison scheme.
This commit is contained in:
parent
5d33f7c28e
commit
9fe1284ae3
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user