Veki
Forum Replies Created
-
AuthorPosts
-
VekiParticipantHi Peterigz.
Sorry for a bit late replay, but after some digging I have found all the information needed to render particles correctly as they are rendered in TimeLineFX Editor.
Just to confirm, TimLineFX Editor uses TimeLineFX BlitzMax code library. Yes or no?
First, blend states from BlitzMax module you linked on the 1st page are not used. TimeLineFX has its own BlitzMax module where it configures blend states :
Case ALPHABLEND glEnable GL_BLEND glBlendFunc GL_ONE, GL_ONE_MINUS_SRC_ALPHA glDisable GL_ALPHA_TEST Case LIGHTBLEND glEnable GL_BLEND glBlendFunc GL_ONE, GL_ONE glDisable GL_ALPHA_TEST
https://github.com/peterigz/rigz.mod/blob/master/glmax2dext.mod/glmax2dext.bmx
Second, color is not used “as is”, but is multiplied by alpha value :
Method SetColor(red:Int, green:Int, blue:Int) currentred = red currentgreen = green currentblue = blue color4ubext[0] = Min(Max(red, 0), 255) * currentalpha color4ubext[1] = Min(Max(green, 0), 255) * currentalpha color4ubext[2] = Min(Max(blue, 0), 255) * currentalpha glColor4ubv color4ubext End Method
https://github.com/peterigz/rigz.mod/blob/master/glmax2dext.mod/glmax2dext.bmx
Third, since color is multiplied by alpha, I assume texture color should also be multiplied by texture alpha :
float4 texture_pixel = shaderTexture.Sample (SampleType, input.texture_coordinates); texture_pixel.x = texture_pixel.x * texture_pixel.w; texture_pixel.y = texture_pixel.y * texture_pixel.w; texture_pixel.z = texture_pixel.z * texture_pixel.w; return texture_pixel * input.color;
Fourth, C++ library is ignoring IMPORT_OPTION attribute so images with GREYSCALE option are not loaded correctly. TimeLineFX loads such images by running them through this function first :
Function GreyScale:TPixmap(pixmap:TPixmap) Local pixmapcopy:TPixmap = CopyPixmap(pixmap).Convert(PF_RGBA8888) Local p:Byte Ptr Local c:Int For Local loc:Int = 0 Until pixmapcopy.capacity Step 4 p = pixmapcopy.pixels + loc c = Min((p[0] *.3) + (p[1] *.59) + (p[2] *.11), p[3]) p[0] = 255 p[1] = p[0] p[2] = p[0] p[3] = c Next Return pixmapcopy End Function
https://github.com/peterigz/rigz.mod/blob/master/singlesurface.mod/singlesurface.bmx
With all that information I can now render correctly particles with alpha blending. š
VekiParticipantThanks Peterigz, this information is just what I needed.
By changing the blend mode fromSrcBlend = 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;
to
SrcBlend = D3D11_BLEND_SRC_ALPHA; DestBlend = D3D11_BLEND_ONE; BlendOp = D3D11_BLEND_OP_ADD; SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; DestBlendAlpha = D3D11_BLEND_ZERO; BlendOpAlpha = D3D11_BLEND_OP_ADD;
I managed to get this in my test program :
Now that looks a lot like the image the TimeLineFX Editor is rendering.
Explosions also look the same as in TimeLineFX Editor :
I still need to work out the alpha blending as there is big difference in rendering.
TimeLineFX Editor :
My test program :
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?
VekiParticipantA small difference :
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 :
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))?
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;
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 15
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?
-
AuthorPosts