Add subtractive blending mode to backends

This commit is contained in:
Jack Andersen 2017-09-04 16:59:41 -10:00
parent 18cbfd2865
commit dd6e53119a
6 changed files with 71 additions and 11 deletions

View File

@ -216,7 +216,10 @@ enum class BlendFactor
DstAlpha,
InvDstAlpha,
SrcColor1,
InvSrcColor1
InvSrcColor1,
/* Special value that activates DstColor - SrcColor blending */
Subtract
};
/** Factory object for creating batches of resources as an IGraphicsData token */

View File

@ -575,8 +575,18 @@ class D3D11ShaderPipeline : public IShaderPipeline
CD3D11_BLEND_DESC blDesc(D3D11_DEFAULT);
blDesc.RenderTarget[0].BlendEnable = (dstFac != BlendFactor::Zero);
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
{
blDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_DEST_COLOR;
blDesc.RenderTarget[0].DestBlend = D3D11_BLEND_SRC_COLOR;
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_SUBTRACT;
}
else
{
blDesc.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
blDesc.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
blDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
}
blDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blDesc.RenderTarget[0].RenderTargetWriteMask =

View File

@ -694,8 +694,18 @@ class D3D12ShaderPipeline : public IShaderPipeline
if (dstFac != BlendFactor::Zero)
{
desc.BlendState.RenderTarget[0].BlendEnable = true;
desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
{
desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_DEST_COLOR;
desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_SRC_COLOR;
desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_SUBTRACT;
}
else
{
desc.BlendState.RenderTarget[0].SrcBlend = BLEND_FACTOR_TABLE[int(srcFac)];
desc.BlendState.RenderTarget[0].DestBlend = BLEND_FACTOR_TABLE[int(dstFac)];
desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
}
desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
}

View File

@ -451,6 +451,7 @@ class GLShaderPipeline : public IShaderPipeline
bool m_depthWrite = true;
bool m_colorWrite = true;
bool m_alphaWrite = true;
bool m_subtractBlend = false;
CullMode m_culling;
std::vector<GLint> m_uniLocs;
GLShaderPipeline(GLData* parent) : IShaderPipeline(parent) {}
@ -472,6 +473,7 @@ public:
m_depthWrite = other.m_depthWrite;
m_colorWrite = other.m_colorWrite;
m_alphaWrite = other.m_alphaWrite;
m_subtractBlend = other.m_subtractBlend;
m_culling = other.m_culling;
m_uniLocs = std::move(other.m_uniLocs);
return *this;
@ -487,6 +489,10 @@ public:
{
glEnable(GL_BLEND);
glBlendFuncSeparate(m_sfactor, m_dfactor, GL_ONE, GL_ZERO);
if (m_subtractBlend)
glBlendEquation(GL_FUNC_SUBTRACT);
else
glBlendEquation(GL_FUNC_ADD);
}
else
glDisable(GL_BLEND);
@ -688,8 +694,19 @@ IShaderPipeline* GLDataFactory::Context::newShaderPipeline
}
}
shader.m_sfactor = BLEND_FACTOR_TABLE[int(srcFac)];
shader.m_dfactor = BLEND_FACTOR_TABLE[int(dstFac)];
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
{
shader.m_sfactor = GL_DST_COLOR;
shader.m_dfactor = GL_SRC_COLOR;
shader.m_subtractBlend = true;
}
else
{
shader.m_sfactor = BLEND_FACTOR_TABLE[int(srcFac)];
shader.m_dfactor = BLEND_FACTOR_TABLE[int(dstFac)];
shader.m_subtractBlend = false;
}
shader.m_depthTest = depthTest;
shader.m_depthWrite = depthWrite;
shader.m_colorWrite = colorWrite;

View File

@ -631,8 +631,18 @@ class MetalShaderPipeline : public IShaderPipeline
desc.colorAttachments[0].writeMask = (colorWrite ? COLOR_WRITE_MASK : 0) |
(alphaWrite ? MTLColorWriteMaskAlpha : 0);
desc.colorAttachments[0].blendingEnabled = dstFac != BlendFactor::Zero;
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
{
desc.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorDestinationColor;
desc.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorSourceColor;
desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationSubtract;
}
else
{
desc.colorAttachments[0].sourceRGBBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
desc.colorAttachments[0].destinationRGBBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
desc.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
}
desc.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
desc.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorZero;
desc.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float;

View File

@ -1988,8 +1988,18 @@ class VulkanShaderPipeline : public IShaderPipeline
VkPipelineColorBlendAttachmentState colorAttachment = {};
colorAttachment.blendEnable = dstFac != BlendFactor::Zero;
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
if (srcFac == BlendFactor::Subtract || dstFac == BlendFactor::Subtract)
{
colorAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_DST_COLOR;
colorAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_SRC_COLOR;
colorAttachment.colorBlendOp = VK_BLEND_OP_SUBTRACT;
}
else
{
colorAttachment.srcColorBlendFactor = BLEND_FACTOR_TABLE[int(srcFac)];
colorAttachment.dstColorBlendFactor = BLEND_FACTOR_TABLE[int(dstFac)];
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
}
colorAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;