SL-18852 Refactor GLTF material rendering to not be special compared to other types. Hook GLTF alpha masking up to highlight transparent.

meow-7.2.2
Dave Parks 2022-12-16 11:12:06 -06:00
parent 57c54ec4b7
commit d27d23ab26
10 changed files with 162 additions and 105 deletions

View File

@ -425,6 +425,85 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
}
}
void setup_texture_matrix(LLDrawInfo& params)
{
if (params.mTextureMatrix)
{ //special case implementation of texture animation here because of special handling of textures for PBR batches
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((GLfloat*)params.mTextureMatrix->mMatrix);
gPipeline.mTextureMatrixOps++;
}
}
void teardown_texture_matrix(LLDrawInfo& params)
{
if (params.mTextureMatrix)
{
gGL.matrixMode(LLRender::MM_TEXTURE0);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
void LLRenderPass::pushGLTFBatches(U32 type, U32 mask)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
LLDrawInfo& params = **i;
auto& mat = params.mGLTFMaterial;
mat->bind();
LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
setup_texture_matrix(params);
applyModelMatrix(params);
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
teardown_texture_matrix(params);
}
}
void LLRenderPass::pushRiggedGLTFBatches(U32 type, U32 mask)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
LLDrawInfo& params = **i;
auto& mat = params.mGLTFMaterial;
mat->bind();
LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
setup_texture_matrix(params);
applyModelMatrix(params);
if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
{
uploadMatrixPalette(params);
lastAvatar = params.mAvatar;
lastMeshId = params.mSkinInfo->mHash;
}
params.mVertexBuffer->setBufferFast(mask);
params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
teardown_texture_matrix(params);
}
}
void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;

View File

@ -201,6 +201,8 @@ public:
PASS_ALPHA_INVISIBLE_RIGGED,
PASS_GLTF_PBR,
PASS_GLTF_PBR_RIGGED,
PASS_GLTF_PBR_ALPHA_MASK,
PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
NUM_RENDER_TYPES,
};
@ -350,6 +352,8 @@ public:
static void applyModelMatrix(const LLDrawInfo& params);
virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
void pushGLTFBatches(U32 type, U32 mask);
void pushRiggedGLTFBatches(U32 type, U32 mask);
virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);

View File

@ -317,39 +317,42 @@ void LLDrawPoolAlpha::renderDebugAlpha()
gGL.diffuseColor4f(1, 0, 0, 1);
gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::getSmokeImage());
renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0);
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0;
pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
renderAlphaHighlight(mask);
pushBatches(LLRenderPass::PASS_ALPHA_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, mask, FALSE);
// Material alpha mask
gGL.diffuseColor4f(0, 0, 1, 1);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_NORMMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_SPECMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_NORMMAP_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_SPECMAP_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, FALSE);
pushBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK, mask, FALSE);
gGL.diffuseColor4f(0, 1, 0, 1);
pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushBatches(LLRenderPass::PASS_INVISIBLE, mask, FALSE);
gHighlightProgram.mRiggedVariant->bind();
gGL.diffuseColor4f(1, 0, 0, 1);
pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, mask, FALSE);
// Material alpha mask
gGL.diffuseColor4f(0, 0, 1, 1);
pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, mask, FALSE);
pushRiggedBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED, mask, FALSE);
gGL.diffuseColor4f(0, 1, 0, 1);
pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, mask, FALSE);
LLGLSLShader::sCurBoundShaderPtr->unbind();
}
}
@ -679,7 +682,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
gPipeline.bindDeferredShaderFast(*target_shader);
}
params.mGLTFMaterial->bind(target_shader);
params.mGLTFMaterial->bind();
}
else
{

View File

@ -38,79 +38,18 @@ LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR() :
void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)
{
const U32 type = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR;
const U32 types[] = { LLPipeline::RENDER_TYPE_PASS_GLTF_PBR, LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK };
gGL.flush();
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
for (int i = 0; i < 2; ++i)
for (U32 type : types)
{
bool rigged = (i == 1);
LLGLSLShader* shader = LLPipeline::sShadowRender ? &gDeferredShadowGLTFAlphaMaskProgram : &gDeferredPBROpaqueProgram;
U32 vertex_data_mask = getVertexDataMask();
if (rigged)
{
shader = shader->mRiggedVariant;
vertex_data_mask |= LLVertexBuffer::MAP_WEIGHT4;
}
shader->bind();
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type+i);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type+i);
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo* pparams = *i;
auto& mat = pparams->mGLTFMaterial;
mat->bind(shader);
LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
bool tex_setup = false;
if (pparams->mTextureMatrix)
{ //special case implementation of texture animation here because of special handling of textures for PBR batches
tex_setup = true;
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
gGL.loadMatrix((GLfloat*)pparams->mTextureMatrix->mMatrix);
gPipeline.mTextureMatrixOps++;
}
if (rigged)
{
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
uploadMatrixPalette(*pparams);
lastAvatar = pparams->mAvatar;
lastMeshId = pparams->mSkinInfo->mHash;
}
pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
}
else
{
pushBatch(*pparams, vertex_data_mask, FALSE, FALSE);
}
if (tex_setup)
{
gGL.matrixMode(LLRender::MM_TEXTURE0);
gGL.loadIdentity();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
}
gDeferredPBROpaqueProgram.bind();
pushGLTFBatches(type, getVertexDataMask());
gDeferredPBROpaqueProgram.bind(true);
pushRiggedGLTFBatches(type+1, getVertexDataMask());
}
LLGLSLShader::sCurBoundShaderPtr->unbind();
}
void LLDrawPoolGLTFPBR::renderShadow(S32 pass)
{
renderDeferred(pass);
}

View File

@ -50,11 +50,6 @@ public:
S32 getNumDeferredPasses() override { return 1; }
void renderDeferred(S32 pass) override;
S32 getNumShadowPasses() override { return 1; }
void renderShadow(S32 pass) override;
};
#endif // LL_LLDRAWPOOLPBROPAQUE_H

View File

@ -46,12 +46,14 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
}
void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader)
void LLFetchedGLTFMaterial::bind()
{
// glTF 2.0 Specification 3.9.4. Alpha Coverage
// mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
F32 min_alpha = -1.0;
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
{
min_alpha = mAlphaCutoff;

View File

@ -40,7 +40,7 @@ public:
virtual ~LLFetchedGLTFMaterial();
// bind this material for rendering
void bind(LLGLSLShader* shader);
void bind();
// Textures used for fetching/rendering
LLPointer<LLViewerFetchedTexture> mBaseColorTexture;

View File

@ -6570,9 +6570,17 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
if (gltf_mat)
{ // all other parameters ignored if gltf material is present
if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
else if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
{
registerFace(group, facep, LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK);
}
else
{
registerFace(group, facep, LLRenderPass::PASS_GLTF_PBR);
}
}
else
// do NOT use 'fullbright' for this logic or you risk sending

View File

@ -9437,7 +9437,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_NORMMAP,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
LLRenderPass::PASS_NORMSPEC_EMISSIVE
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
LLRenderPass::PASS_GLTF_PBR
};
LLGLEnable cull(GL_CULL_FACE);
@ -9538,6 +9539,12 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha");
LL_PROFILE_GPU_ZONE("shadow alpha");
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
@ -9546,11 +9553,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
U32 mask = LLVertexBuffer::MAP_VERTEX |
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked");
renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
@ -9562,7 +9564,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
renderAlphaObjects(mask, TRUE, TRUE, rigged);
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked");
gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
@ -9571,7 +9572,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged);
}
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass");
gDeferredTreeShadowProgram.bind(rigged);
@ -9588,9 +9588,32 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged);
}
}
}
//glCullFace(GL_BACK);
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
U32 type = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK;
if (rigged)
{
mAlphaMaskPool->pushRiggedGLTFBatches(type + 1, mask);
}
else
{
mAlphaMaskPool->pushGLTFBatches(type, mask);
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
}
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
@ -9929,6 +9952,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
END_RENDER_TYPES);
gGL.setColorMask(false, false);

View File

@ -538,7 +538,9 @@ public:
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
RENDER_TYPE_PASS_GLTF_PBR = LLRenderPass::PASS_GLTF_PBR,
RENDER_TYPE_PASS_GLTF_PBR_RIGGED = LLRenderPass::PASS_GLTF_PBR_RIGGED,
RENDER_TYPE_PASS_GLTF_PBR_RIGGED = LLRenderPass::PASS_GLTF_PBR_RIGGED,
RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK,
RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,