3
\$\begingroup\$

I want to achieve a distortion effect which distorts the full screen. For that I spawn a couple of images with normal maps. I render their normal map part on some camera facing quads onto a rendertarget which is cleared with the color (127,127,255,255). This color means that there is no distortion whatsoever. Then I want to render some images like this one onto it:
enter image description here
If I draw one somewhere on the screen, then it looks correct because it blends in seamlessly with the background (which is the same color that appears on the edges of this image). If I draw another one on top of it then it will no longer be a seamless transition. For this I created a blendstate in directX 11 that keeps the maximum of two colors, so it is now a seamless transition, but this way, the colors lower than 127 (0.5f normalized) will not contribute. I am not making a simulation and the effect looks quite convincing and nice for a game, but in my spare time I am thinking how I could achieve a nicer or a more correct effect with a blend state, maybe averaging the colors somehow? I I did it with a shader, I would add the colors and then I would normalize them, but I need to combine arbitrary number of images onto a rendertarget. This is my blend state now which blends them seamlessly but not correctly:

    D3D11_BLEND_DESC bd;
    bd.RenderTarget[0].BlendEnable=true;
    bd.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
    bd.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
    bd.RenderTarget[0].BlendOp = D3D11_BLEND_OP_MAX;
    bd.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
    bd.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
    bd.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_MAX;
    bd.RenderTarget[0].RenderTargetWriteMask = 0x0f;

Is there any way of improving upon this?
(PS. I considered rendering each one with a separate shader incementally on top of each other but that would consume a lot of render targets which is unacceptable)

\$\endgroup\$
  • 1
    \$\begingroup\$ Have you tried simple additive blending to signed RT where you render normal xy-components mapped to range [-1, 1]? \$\endgroup\$ – JarkkoL Sep 20 '14 at 12:14
  • \$\begingroup\$ I tried it now and works quite well, thank you! If you write this as an answer, I will accept it. \$\endgroup\$ – János Turánszki Sep 20 '14 at 22:19
2
\$\begingroup\$

Have a look at Reoriented Normal Mapping, it will allow you to blend several normal maps on top of each other and give the intuitively expected result. The main idea is to transform the the normal to blend to the local space of the surface your blending on, or in this scenario, the normal mapped space of the surface.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply. I have seen that article, but is is a shader approach, I don't want to blend 200 or 2000 particles with a shader, but would rather do it with a blend state. I have already tried and done the shader approach for something else though. \$\endgroup\$ – János Turánszki Jul 21 '14 at 21:46
0
\$\begingroup\$

I am doing this by first remapping the normal map to the range [-1,1], then blending them onto a signed normalized 32 bit render target (DXGI_FORMAT_R8G8B8A8_SNORM). The additive blend state I am using is of course like this:

BlendOp: ADD
SRCBlend: SRC_ALPHA
DSTBlend: ONE

The signed render target is first cleared to ZERO of course.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.