Archived

This topic is now archived and is closed to further replies.

Miksan

Changing the alpha of a point sprite

Recommended Posts

I have set my rendered like this: SetRenderState(D3DRS_LIGHTING, false); SetRenderState(D3DRS_ZWRITEENABLE, false); SetRenderState(D3DRS_ALPHABLENDENABLE, true); SetRenderState(D3DRS_POINTSPRITEENABLE, true); SetRenderState(D3DRS_POINTSCALEENABLE, true); SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); float size = 100.0; SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&size)); The point sprite''s vertex is like this: #define PARTICLEVERTEX_FVF (D3DFVF_XYZ | D3DFVF_DIFFUSE) struct PARTICLEVERTEX { D3DVECTOR vPosition; D3DCOLOR color; }; Now how do I get this to work? color = D3DCOLOR_ARGB(255, 255, 255, 255); // Fully opaque point sprite color = D3DCOLOR_ARGB(0, 255, 255, 255); // Fully transparent point sprite The problem is that the point sprites visibility isn''t affected at all when changing the alpha value. I''d like to simulate the particle''s lifetime with the alpha value. Thanks for suggestions!

Share this post


Link to post
Share on other sites
Try to remember, please

SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);

That gives some quite funny results... There is such many combinations, that I won''t ever find the right one...

Share this post


Link to post
Share on other sites
quote:
Original post by Miksan
Try to remember, please

SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);

That gives some quite funny results... There is such many combinations, that I won't ever find the right one...


Use D3DBLEND_SRCALPHA for D3DBLEND_SRCCOLOR.
Use D3DBLEND_INVSRCALPHA for D3DBLEND_INVSRCCOLOR.

And you should set the Alpha Texturestates to use Argument1 and set Argument1 to diffuse:
SetTextureStageState( 0, D3DTTS_ALPHAOP, D3DTOP_SELECTARG1 );
SetTextureStageState( 0, D3DTTS_ALPHAARG1, D3DTA_DIFFUSE );


--
You're Welcome,
Rick Wong
- sitting in his chair doing the most time-consuming thing..

[edited by - Pipo DeClown on October 23, 2003 10:08:13 AM]

Share this post


Link to post
Share on other sites
I still don't get it. Here's what I tried:


SetRenderState(D3DRS_LIGHTING, false);
SetRenderState(D3DRS_ZWRITEENABLE, false);
SetRenderState(D3DRS_POINTSPRITEENABLE, true);
SetRenderState(D3DRS_POINTSCALEENABLE, false);
SetRenderState(D3DRS_ALPHABLENDENABLE, true);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);

SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);

float size = 50.0f;
SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&size));


Here are the results:

D3DCOLOR_RGBA(255, 255, 255, 255): Alpha 255
D3DCOLOR_RGBA(255, 255, 255, 0): Alpha 0

What should I do?

[edited by - Miksan on October 23, 2003 10:54:20 AM]

Share this post


Link to post
Share on other sites
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

is what you want I think.

Try to think of it in terms of a blending equation. The end result will be (SrcBlend*SrcColor) + (DestBlend*DestColor).

Share this post


Link to post
Share on other sites
I''m sorry, but even that doesn''t work. I''m quite newbie in these things, so I''m not able think it out myself. I''ve been trying with some variations, but it feels weird cause I really don''t know what am I doing...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Don''t ever use "true and false" in place of "TRUE and FALSE". You''ll get unexpected results sometimes.

Share this post


Link to post
Share on other sites
You need to tell DirectX where to get its colors from. The vertex or the material. Just because you have diffuse color in the vertex buffer doesn''t mean DirectX is going to use that one, you need to tell it specifically with these commands:


p_Device->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
p_Device->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR2);
p_Device->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
p_Device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);



(Since you do not an emissive color in the vertex, you would change that renderstate to be material)

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
Don''t ever use "true and false" in place of "TRUE and FALSE". You''ll get unexpected results sometimes.


You sure? Cause I''d like to know more about this.

--
You''re Welcome,
Rick Wong
- sitting in his chair doing the most time-consuming thing..

Share this post


Link to post
Share on other sites
Well, it still doesn't work...

I'll put the code again:


SetRenderState(D3DRS_LIGHTING, FALSE);
SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

float size = 40.0f;
SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&size));

SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);


Now with full alpha (255) I've got my particles like this:
Not working
Here's the same situation, but I've disabled the alpha:
Working

With zero alpha, I can't see anything, which seems to be just what I'm lookin here. Though the particles render quite wrong... I think that the solution might be just one little switch somewhere...



[edited by - Miksan on October 23, 2003 1:22:42 PM]

Share this post


Link to post
Share on other sites
If you are using additive blending (ONE:ONE) for the fire, then the correct way to fade a particle is to darken its colour, instead of decreasing its alpha value.

Forget about alpha-blending for a second and try this:

SetRenderState(D3DRS_LIGHTING, FALSE);
SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);

float size = 40.0f;
SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&size));
SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);

Then use the alpha value you are calculating for each particle to multiply its colour, so as a particle gets older it gets darker.

Share this post


Link to post
Share on other sites
Try some (or all) of these...


p_Device->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
p_Device->SetRenderState(D3DRS_ALPHAREF, 0x01);
p_Device->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
p_Device->SetRenderState(D3DRS_COLORVERTEX, TRUE);

Share this post


Link to post
Share on other sites
Here's a pic of the same lava fire version, but now I'm trying to fade the color as the particle gets older.

With color fade

When the particle is added, I calculate the fade constant, which is the original color value divided by the lifetime. Then I substract that constant from the fade variable every iteration. Fade is at the start 1.0. Fade is actually three dimensional vector for every color. Then I use this macro to place the color to the particles color variable:

m_particleVerts[iCount].color = D3DCOLOR_XRGB((int)((((*it)->color >> 16) & 0xFF) * (*it)->vFade.x), (int)((((*it)->color >> 8) & 0xFF) * (*it)->vFade.y), (int)(((*it)->color & 0xFF) * (*it)->vFade.z));

Obviously something is kicking my ass here.

quote:
Original post by Pipo DeClown
In this case, you should REALLY use texture-alpha. Add an alpha-channel into your texture, and set Direct3D to use the texture's alpha-channel.



Could you explain a bit more?


edit: forgot to mention that the particle doesn't fade anywhere with this...

[edited by - Miksan on October 23, 2003 2:51:07 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Miksan
quote:
Original post by Pipo DeClown
In this case, you should REALLY use texture-alpha. Add an alpha-channel into your texture, and set Direct3D to use the texture''s alpha-channel.


Could you explain a bit more?
Textures in certain format (ie PNG, TGA, DDS) can have its own alpha channel. However, this is for the texture itself and can''t be modified at runtime (correct me if I am wrong), though you still can use it for alpha blending.

If everything still doesn''t work, try this.

Share this post


Link to post
Share on other sites