mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-04-05 00:51:05 +00:00
fixed OIT fog resolve blend equations for both accumulators
This commit is contained in:
parent
3aef00f466
commit
2825b5bb04
1 changed files with 34 additions and 19 deletions
|
@ -147,27 +147,38 @@ float4 DepthFadeFragmentColor(float4 color, OIT_Fragment fragment, float opaqueV
|
|||
return dst;
|
||||
}
|
||||
|
||||
float3 BlendInScatteredLight(float4 srcColor, float3 dstColor, uint blendBits)
|
||||
/*
|
||||
Volumetric light blending with split accumulators
|
||||
|
||||
D = S * BlendFactor(S, D1 + D2, SM) + (D1 + D2) * BlendFactor(S, D1 + D2, DM)
|
||||
= S * BlendFactor(S, D1 + D2, SM) + D1 * BlendFactor(S, D1 + D2, DM) + D2 * BlendFactor(S, D1 + D2, DM)
|
||||
D1 = S * BlendFactor(S, D1 + D2, SM) + D1 * BlendFactor(S, D1 + D2, DM)
|
||||
D2 = D2 * BlendFactor(S, D1 + D2, DM)
|
||||
*/
|
||||
|
||||
#if defined(VOLUMETRIC_LIGHT)
|
||||
|
||||
float4 VLBlendMain(float4 src, float4 dstMain, float3 dstScatter, uint stateBits)
|
||||
{
|
||||
// source blend must not double source contributions, so we can't call BlendSource
|
||||
uint srcBlend = blendBits & GLS_SRCBLEND_BITS;
|
||||
float3 srcContrib = float3(0, 0, 0);
|
||||
if(srcBlend == GLS_SRCBLEND_DST_COLOR)
|
||||
{
|
||||
srcContrib = dstColor * (float3(1, 1, 1) - dstColor);
|
||||
}
|
||||
else if(srcBlend == GLS_SRCBLEND_ONE_MINUS_DST_COLOR)
|
||||
{
|
||||
srcContrib = dstColor * (float3(1, 1, 1) - dstColor);
|
||||
}
|
||||
// we must let destination alpha be the one from the main accumulator
|
||||
float4 dst = saturate(dstMain + float4(dstScatter, 0.0));
|
||||
float4 srcOut = src * BlendFactorSource(src, dst, stateBits & GLS_SRCBLEND_BITS);
|
||||
float4 dstOut = dstMain * BlendFactorDest(src, dst, stateBits & GLS_DSTBLEND_BITS);
|
||||
|
||||
uint dstBlend = blendBits & GLS_DSTBLEND_BITS;
|
||||
float3 dstContrib = dstColor * BlendFactorDest(srcColor, float4(dstColor, 1), dstBlend).rgb;
|
||||
float3 result = srcContrib + dstContrib;
|
||||
|
||||
return result;
|
||||
return srcOut + dstOut;
|
||||
}
|
||||
|
||||
float3 VLBlendScatter(float4 src, float4 dstMain, float3 dstScatter, uint stateBits)
|
||||
{
|
||||
// we must let destination alpha be the one from the main accumulator
|
||||
float4 dst = saturate(dstMain + float4(dstScatter, 0.0));
|
||||
float3 dstOut = dstScatter * BlendFactorDest(src, dst, stateBits & GLS_DSTBLEND_BITS).rgb;
|
||||
|
||||
return dstOut;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
struct OIT_Resolve
|
||||
{
|
||||
bool InitScissorRect(VOut input)
|
||||
|
@ -262,7 +273,11 @@ struct OIT_Resolve
|
|||
float4 fragColor = UnpackColor(frag.color);
|
||||
float4 prevColor = color;
|
||||
fragColor = DepthFadeFragmentColor(fragColor, frag, opaqueViewDepth);
|
||||
color = Blend(fragColor, color, stateBits);
|
||||
#if defined(VOLUMETRIC_LIGHT)
|
||||
color = VLBlendMain(fragColor, prevColor, inScatterAccum, stateBits);
|
||||
#else
|
||||
color = Blend(fragColor, prevColor, stateBits);
|
||||
#endif
|
||||
color = saturate(color);
|
||||
if((stateBits & GLS_DEPTHMASK_TRUE) != 0u &&
|
||||
fragDepth != dstDepth)
|
||||
|
@ -280,7 +295,7 @@ struct OIT_Resolve
|
|||
float4 closerScatterData = FindCloserScatterData(i + 1, dstDepth, input, volumeSize);
|
||||
float3 inScattering = scatterData.rgb - closerScatterData.rgb;
|
||||
float transmittance = min(scatterData.a / max(closerScatterData.a, 0.000001), 1.0);
|
||||
inScatterAccum = inScattering + BlendInScatteredLight(fragColor, inScatterAccum, stateBits & GLS_BLEND_BITS);
|
||||
inScatterAccum = inScattering + VLBlendScatter(fragColor, prevColor, inScatterAccum, stateBits);
|
||||
color.rgb *= transmittance;
|
||||
scatterData = closerScatterData;
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue