[英]Open GL Translucid Sprites
所以,我的目標是用透明像素繪制精靈。
首先,我使用僅渲染不透明像素的着色器渲染精靈。 然后,我禁用深度緩沖區寫入並使用僅渲染透明(或透明精靈)的着色器渲染相同的精靈,如下所述:
這是我用作測試的動畫精靈表:
https://i.stack.imgur.com/MMs2W.png
這是我的渲染器更新功能:
updateRenderData();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);
glUseProgram(_translucencyPogramID);
render();
_window->SwapBuffers();
這是我的渲染函數(以防萬一你想知道我如何渲染精靈):
GLint baseInstance = 0;
GLsizei spriteCount;
for (int i = 0; i < _spriteManager->GetSpriteBatchVector()->size(); i++)
{
_SpriteBatch* spriteBatch = _spriteManager->GetSpriteBatchVector()->at(i);
setTexture(spriteBatch->GetTexture());
spriteCount = (GLsizei)spriteBatch->GetSpriteVector()->size();
glDrawElementsInstancedBaseInstance(_quad.renderMode, _quad.indexCount, _quad.indexDataType, 0, spriteCount, baseInstance);
baseInstance += spriteCount;
}
但是,當我執行此代碼時,它只呈現透明像素: https : //i.stack.imgur.com/f4AY6.png
實際上,如果我刪除第二個render()調用(僅調用,我仍然更改着色器並將深度掩碼設置為false),則不會渲染(黑屏),如下所示:
updateRenderData();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);
glUseProgram(_translucencyPogramID);
_window->SwapBuffers();
但是如果我沒有更改着色器,也沒有在第一次渲染后將glDepthMask設置為false,它會正確渲染我的精靈的不透明像素。
編輯:這是我用於第二遍的片段着色器:
out layout(location = 0) vec4 outColor;
in vec2 texCoord;
uniform sampler2D tex;
void main()
{
vec4 texel = texture(tex, texCoord);
if(texel.a == 1)
{
discard;
}
outColor = texel;
}
第一遍是相同的,但如果alpha <1則丟棄。頂點着色器是標准的。
所以,我的問題是:造成這種情況的原因是什么?
編輯2:
為了澄清,這正確呈現(沒有半透明像素):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
這根本不會呈現:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glDepthMask(GL_FALSE);//Just added this line
這根本不會呈現:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE);
glUseProgram(_programID);
render();
glUseProgram(_translucencyPogramID);//Just added this line
假設_programID
用於繪制鳥的不透明部分, _translucencyPogramID
用於繪制半透明部分。
您提供的代碼中沒有任何內容顯示原因可能是什么。 然而,它可能是以下結果:
_programID
您實際上並未調用render()
。 _programID
你glClear(GL_COLOR_BUFFER_BIT)
GL_ONE_MINUS_SRC_ALPHA
作為glBlendFunc()
的sfactor
因此,您的_programID
的片段着色器包含:
if (texel.a < 1.0)
discard;
你的_translucencyPogramID
的片段着色器包括:
if (texel.a == 1.0)
discard;
然后授予你的繪制循環就像這樣(偽代碼):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthMask(GL_TRUE)
glUseProgram(_programID)
for each sprite
glDrawArrays(....)
glDepthMask(GL_FALSE)
glUseProgram(_translucencyPogramID)
for each sprite
glDrawArrays(....)
glDepthMask(GL_TRUE)
然后在使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
,那應該給出所需的結果。
編輯
然后當你添加glDepthMask(GL_FALSE)
時它會中斷它,因為你之后沒有再啟用它。 你可以通過這樣做來檢查:
GLboolean enabled;
glGetBooleanv(GL_DEPTH_WRITEMASK, &enabled);
assert(enabled == GL_TRUE);
在你glClear(GL_DEPTH_BUFFER_BIT)
之前glClear(GL_DEPTH_BUFFER_BIT)
。
這個原因中斷是因為如果禁用寫入深度緩沖區,則glClear(GL_DEPTH_BUFFER_BIT)
將不執行任何操作,因此保留深度緩沖區。
正如你在下面看到的那樣,在第二張照片上,它會描繪出所有鳥類畫面的輪廓。 這是因為深度緩沖區永遠不會被清除,這只鳥是最前面的鳥。 如果在調用glClear(GL_DEPTH_BUFFER_BIT)
啟用寫入深度緩沖區,則它會正確生成第一個圖片。
左:在glClear上啟用深度寫入。 右:在glClear上禁用深度寫入。
請注意,這種關系適用於glClear(...)
和任何gl*Mask(GL_FALSE)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.