我正在绘制一些 alpha 混合精灵。我使用 D3D 和 OpenGL 在 Win32 上渲染相同的资产,当顶点颜色为 0xFFFFFF 且背景颜色为 0xC0D0E0 时,正确的结果如下所示
在 Win32/OpenGL 我启用混合如下:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
在 Win32/D3D 上如下:
CD3D11_BLEND_DESC blendDesc(D3D11_DEFAULT);
D3D11_RENDER_TARGET_BLEND_DESC rtBlendDesc;
rtBlendDesc.BlendEnable = true;
rtBlendDesc.BlendOp = D3D11_BLEND_OP_ADD;
rtBlendDesc.BlendOpAlpha = D3D11_BLEND_OP_ADD;
rtBlendDesc.DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
rtBlendDesc.DestBlendAlpha = D3D11_BLEND_ZERO;
rtBlendDesc.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
rtBlendDesc.SrcBlend = D3D11_BLEND_SRC_ALPHA;
rtBlendDesc.SrcBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0] = rtBlendDesc;
gDevice->CreateBlendState(&blendDesc, &mBlendState);
然后,在渲染时:
gContext->OMSetBlendState(mBlendState, NULL, 0xffffffff);
在 Win32/OpenGL 上我使用固定函数管道,在 DX11 上我使用非常简单的垂直/像素着色器:
float4 SpritePixelShader(PS_INPUT input) : SV_Target
{
return (txDiffuse.Sample(samLinear, input.Tex)) * input.Col;
}
PS_INPUT SpriteVertexShader(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT)0;
output.Pos = mul(float4(input.Pos.x, input.Pos.y, 0.5, 1.0), projection);
output.Tex = input.Tex;
output.Col = input.Col;
return output;
}
一切都很好。OpenGL 和 D3D 给了我相同的结果。
在 iPhone 模拟器上的 OpenGL ES 2.0 上(不确定这是否是模拟器的东西,我还不能在设备上测试):
我启用了类似的混合:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
我的片段/顶点着色器类似:
// fragment shader
void main()
{
gl_FragColor = color * texture2D(s_texture, texCoord);
}
// vertex shader
void main()
{
color = vertexColor;
texCoord = vertexTexCoord;
gl_Position = matrix * vec4(vertexPosition, 0, 1);
}
但我明白了:
这似乎是使用调制而不是加法。我试过打电话:
glBlendEquation(GL_FUNC_ADD);
但这似乎没有任何作用,也没有
glBlendEquationOES(GL_FUNC_ADD_OES);
如果我使用:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
然后它看起来正确,但顶点颜色的 alpha 分量被忽略(我需要使用它)。
有没有人有任何想法?
谢谢!查理。