DX 11 implementation
Home › Forums › TimelineFX Module › DX 11 implementation
Tagged: DX 11
- This topic has 18 replies, 2 voices, and was last updated 6 years, 7 months ago by peterigz.
-
AuthorPosts
-
March 12, 2018 at 8:20 am #6437
VekiParticipantHi
I’m trying to implement TimeLineFX C++ library with DirectX 11 and I’m having some problems.
One problem is that I just can’t get the colors and blending of particles correctly.
This is a shot from TimeLineFX editor :
And this is a shot from my test program :
The most obvious difference is the center dot. In the editor it’s white, in my program it’s green. I think there is a difference between blending modes used in editor and my test program.
Colors are a bit off, in my program they look washed out.
Also particles are a bit bigger in my program, especially at the start of the effect.Second problem I have is with rendering effects that have animations, like explosions.
This is a shot from TimeLineFX editor :
And this is a shot from my test program :
In the function “DrawSprite”, how is the information which sprite to render passed in. Is that the input variable “float frame”? If it is, how is it used?March 12, 2018 at 11:48 pm #6438
peterigzKeymasterHi, the blending in the editor is either Alpha blending where the colours are just mixed together based on the alpha values, or additive blending where colours are added together. It looks like you are only using alpha blending? It might be called Lightblend in DX but not sure.
The animated particles are just sprite sheets. These are drawn based on the start frame and the frames per second as set on the Frame Rate graph. You can see on the Particle tab in the editor that you can also set the animation to play in reverse. The frame number is what’s passed in – it’s passed in as a float because you can change the frame rate that it’s played so it’s just converted to an int to draw the nearest available frame.
March 13, 2018 at 1:31 pm #6439
VekiParticipantHi Peterigz.
I’m using alpha blending. I tried using additive blending, but the result is much worse.
Here are my alpha and additive blend states configuration :
ALPHASrcBlend = D3D11_BLEND_SRC_ALPHA; DestBlend = D3D11_BLEND_INV_SRC_ALPHA; BlendOp = D3D11_BLEND_OP_ADD; SrcBlendAlpha = D3D11_BLEND_ONE; DestBlendAlpha = D3D11_BLEND_ZERO; BlendOpAlpha = D3D11_BLEND_OP_ADD;
ADDITIVE
SrcBlend = D3D11_BLEND_ONE; DestBlend = D3D11_BLEND_ONE; BlendOp = D3D11_BLEND_OP_ADD; SrcBlendAlpha = D3D11_BLEND_ONE; DestBlendAlpha = D3D11_BLEND_ZERO; BlendOpAlpha = D3D11_BLEND_OP_ADD;
Vertex color is calculated like this (<< is displayed incorrectly, should be left shift) :
color = ((r << 0) | (g << 8) | (b << 16) | ((a * 255) << 24));
In pixel shader I sample texture and multiply it with color :
return shaderTexture.Sample (SampleType, input.texture_coordinates) * input.color;
I don’t know what I’m doing different than what TimeLineFX editor is doing. Could you tell me what you’re doing in editor so I could get the same result?
For animated particles, how do I calculate texture coordinates of a sprite in a sprite sheet? I know I can get width and height of a texture, and I can get frames count. Do sprite sheets always have NxN sprites so I can get N by doing a square root of frames count. And then dividing texture width / height with N to get sprite texture coordinates?
March 13, 2018 at 5:22 pm #6443
peterigzKeymasterIt looks like it’s not respecting the alpha values in the image, so maybe it’s an issue with the way image is being loaded rather then the actual blend mode? Looks like all alpha values in the image are 1. Maybe it’s being loaded with RGB rather then RGBA or something along those lines.
I think in the data.xml file in the eff file the animated images have the details about the width and height of each frame and the number of each frame so you should be able to use that to load the sprite sheets correctly.
March 14, 2018 at 9:50 am #6444
VekiParticipantI checked the image and it is loaded correctly (RGBA), alpha channel is loaded and it’s not 1.
The only change in code I made are these 2 lines :SrcBlend = D3D11_BLEND_SRC_ALPHA; DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
changed to
SrcBlend = D3D11_BLEND_ONE; DestBlend = D3D11_BLEND_ONE;
Thanks, I managed to load sprite sheets correctly. Just one more details about sprite sheets : do frames start at 0 and are sorted in rows?
Example :
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15March 14, 2018 at 4:25 pm #6445
peterigzKeymasterI think that my load script just measured the width and height of the image and then determined how to load the animation based on the size of each frame and the number of frame. Most images are square and laid out as per your example though. Yes frames start from 0 I believe.
As for the blend mode, I’m not really sure about how blend modes work in DX11, it looks correct how you’re doing it as both source and destination need to be ONE but maybe there’s something else that needs to be done else where in the code?
March 15, 2018 at 8:06 am #6447
VekiParticipantWell, I believe blend modes in DX work very similar to blend modes in other APIs. Just to be clear, blend state configuration from above post do this :
ALPHA
FinalColor = SourceColor * SourceAlpha + DestinationColor * (1 – SourceAlpha)
FinalAlpha = SourceAlphaADDITIVE
FinalColor = SourceColor + DestinationColor
FinalAlpha = SourceAlphaIf blend mode looks good, there are 2 more places in code where things might be amiss.
1. Vertex color calculation – r, g, b, a values are bit shifted to create RGBA “four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.”
Vertex color is calculated like this (<< is displayed incorrectly as “& lt;& lt;”) :
color = ((r << 0) | (g << 8) | (b << 16) | ((a * 255) << 24));
2. Pixel shader – output pixel is calculated by multiplying color and sample from texture at uv coordinates
return shaderTexture.Sample (SampleType, input.texture_coordinates) * input.color;
March 20, 2018 at 1:37 pm #6452
VekiParticipantHi Peterigz.
Did you maybe check TimeLineFX Editor source code and see how it is rendering particles (blend mode, color calculation, fragment shader (if there is one at all))?
March 22, 2018 at 12:59 am #6453
peterigzKeymasterFrom your image it does look light additive blend is working as it should, but the image is wrong – like the whole image is just a white square. Is there somehow you can verify that the image is correct? The additive code you have does look correct to me so maybe it’s something with the image, that’s the only thing that I can think of at the moment.
March 22, 2018 at 12:43 pm #6454
VekiParticipantHi Peterigz.
I checked image loading and it’s fine.
This the image I used for testing :
With alpha blending it looks like this :
With additive blending it looks like this :
March 22, 2018 at 6:15 pm #6455
peterigzKeymasterCan you try the following for additive blend, see if it makes any difference:
SrcBlend = D3D11_BLEND_ONE; DestBlend = D3D11_BLEND_ONE; BlendOp = D3D11_BLEND_OP_ADD; SrcBlendAlpha = D3D11_BLEND_ONE; DestBlendAlpha = D3D11_BLEND_ONE; BlendOpAlpha = D3D11_BLEND_OP_ADD;
March 23, 2018 at 7:14 am #6456
VekiParticipantA small difference :
March 25, 2018 at 1:05 am #6457
peterigzKeymasterHmm, unfortunately I just don’t know enough about dx11 to know why it might be doing that. You might have to ask around on more DX oriented forums. Let me know how you get on.
March 26, 2018 at 7:53 am #6458
VekiParticipantThanks for trying to help me, Peterigz.
Lets try a different approach.
TimeLineFX Editor is written in BlitzMax, right?
How do you draw particles in BlitzMax and how do you setup blend modes in BlitzMax?March 26, 2018 at 8:07 am #6459
peterigzKeymasterWell, in blitzmax you simply do SetBlend LightBlend. But looking into the directx module that handles it all for you the setblend function looks like this: (bear in mind that this is DX9)
Method SetBlend( blend ) If blend=_active_blend Return Select blend Case SOLIDBLEND _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False Case MASKBLEND _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,True _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False Case ALPHABLEND _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA Case LIGHTBLEND _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_ONE Case SHADEBLEND _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_ZERO _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR End Select _active_blend=blend End Method
You can find the source code for the DX9 module for blitzmax here: https://github.com/blitz-research/blitzmax/blob/master/mod/brl.mod/d3d9max2d.mod/d3d9max2d.bmx
-
AuthorPosts
You must be logged in to reply to this topic.