Multiply color (particle system). Dark smoke?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Multiply color (particle system). Dark smoke?

Post by suliman »

Hi
I asked some time ago but i understand more now so I ask again:)

I want to use particle effect, but to make dark smoke. Someone explained to me if i want to use alpha channel (so not all particles are square images) i need to use addative color blend mode. This works. But this can only brighten colors (add to color value). So i cannot use black smoke or any dark colors.

1. Is this true?

2. But if i skip alpha channel, could I use multiply blend mode to get "darkening particles"? The particle image would be white in the corners (no multiply effect, color would be unchanged) and dark in the middle (the actual "smoke" part of the picture, would darken those pixels on screen).

Any input is appriciated!
Erik
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Multiply color (particle system). Dark smoke?

Post by mongoose7 »

Yes, or use EMT_TRANSPARENT_ALPHA_CHANNEL.
Kojack
Posts: 67
Joined: Sun Jan 20, 2008 2:39 am

Re: Multiply color (particle system). Dark smoke?

Post by Kojack »

You could also try using subtractive blending by setting the blend operation to EBO_SUBTRACT.
The same kind of texture as in additive (black areas have no effect) will now get darker as more of them overlap, giving a dark smoke.

(Modulative (multiply) and subtractive will look a bit different. Modulative is non linear while subtractive is linear. For example, 1.0 * 0.8 is the same as 1.0 - 0.2, but 1.0 * 0.8 * 0.8 * 0.8 is 0.512 and 1.0 - 0.2 - 0.2 - 0.2 is 0.4)
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Re: Multiply color (particle system). Dark smoke?

Post by suliman »

Moongoose:
This is my setup

Code: Select all

 
    o->ps->setMaterialFlag(video::EMF_LIGHTING, false);
    sprintf(tempText,"gfx/particles/%s.png",textureName);
    o->ps->setMaterialTexture(0, gfx.driver->getTexture(tempText));
    o->ps->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL);
 
When i fixed my png-image it DOES put dark pixels on the screen! So thats progress. But they are simply copied so they are rather lifeless.

1. The createFadeOutParticleAffector() doenst seem to work when i use EMT_TRANSPARENT_ALPHA_CHANNEL. The particles just stay on screen with same intensity and then dissapear (they do NOT fade away). Any way to get the same effect? (smoke particles etc needs to be faded away otherwise it looks really ugly).

2. Maybe EBO_SUBTRACT could be used? But i dont know how to pass it, and to what function. Care to help me out a bit?

Thanks a lot!
Erik
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Multiply color (particle system). Dark smoke?

Post by hendu »

Write a shader ;) Then you can have spinning, fading out, alpha-ed particles.
Kojack
Posts: 67
Joined: Sun Jan 20, 2008 2:39 am

Re: Multiply color (particle system). Dark smoke?

Post by Kojack »

suliman wrote:2. Maybe EBO_SUBTRACT could be used? But i dont know how to pass it, and to what function. Care to help me out a bit?
It's put in the BlendOperation member of the SMaterial class.
I don't actually know where to use the SMaterial though, I'm not actually an Irrlicht user. :D
suliman
Posts: 379
Joined: Sat Sep 23, 2006 2:06 pm

Re: Multiply color (particle system). Dark smoke?

Post by suliman »

I have to much on my plate to go into shaders now unfortunately.
No affector that works with EMT_TRANSPARENT_ALPHA_CHANNEL that could work? Such as changing to "global alpha" on the particles so they can softly fade out?

I can do this:

Code: Select all

o->ps->getMaterial(0).BlendOperation = irr::video::EBO_SUBTRACT;
But that just makes the particles almost black rectangles. Also, running that line for a specific particle system (should change the material for that particle system only right?) changes that blending mode for ALL sprites and particle systems in the game, which seems like a bug...
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Multiply color (particle system). Dark smoke?

Post by hendu »

You are combining more than one type of alpha - the texture's, and the fade's. No built-in material does that, to do so you have to use a shader.
chronologicaldot
Competition winner
Posts: 688
Joined: Mon Sep 10, 2012 8:51 am

Re: Multiply color (particle system). Dark smoke?

Post by chronologicaldot »

You'd think there would be a simple interpolate-between-color-values-by-alpha, but there isn't, at least, not that I'm aware of (for this job). Though maybe "add" is what some people expect to do the job?

Edit: Erased edit. I see now. So much for rereading.
Joe_R
Posts: 10
Joined: Wed Aug 10, 2016 10:38 am

Re: Multiply color (particle system). Dark smoke?

Post by Joe_R »

I'm trying to achieve the same as suliman (I want my textured particles to fade out with time), but I have no problem with using a shader for that purpose. I could render textured particles without using a shader. After that I tried to do the same in a shader, but the texture is not appearing (geometry itself is OK, I tested it by setting the pixel shader output to constant float4(1,1,1,1) ). Here is my vertex shader:

Code: Select all

 
float4x4 VP;
 
struct VSOut {
    float4 Pos : POSITION;
    float2 uvCoord : TEXCOORD0;
};
 
void main(in float4 vertPos : POSITION, in float2 uvCoord : TEXCOORD0, out VSOut OUT)
{
    OUT.Pos = mul(vertPos, VP);
    uvCoord = OUT.uvCoord;
}
 

Code: Select all

 
sampler2D tex[1];
 
struct PSIn {
    float4 Pos : POSITION;
    float2 uvCoord : TEXCOORD0;
};
 
void main(in PSIn IN, out float4 colOUT : COLOR)
{
    colOUT = tex2D(tex[0], IN.uvCoord);
}
 
After that I tried to use the fade out affector. It works with the fixed function (not with textures tho, only untextured particles), however when I tried to access the faded colors in the OnSetMaterial function and use them in my shader all the colors in the material were fully white and opaque.

Question: what is the correct way to use shaders to render irrlicht's particles?
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Multiply color (particle system). Dark smoke?

Post by mongoose7 »

You've got this backwards:

uvCoord = OUT.uvCoord;
Joe_R
Posts: 10
Joined: Wed Aug 10, 2016 10:38 am

Re: Multiply color (particle system). Dark smoke?

Post by Joe_R »

Yeah, you're right :D Don't know how I couldn't find this typo on my own :) Kind of embarassing. Still can't access the correct material colors though, but I'll take another look. Seems like I'm not in a good form today :)
Last edited by Joe_R on Fri Aug 12, 2016 3:19 pm, edited 1 time in total.
Joe_R
Posts: 10
Joined: Wed Aug 10, 2016 10:38 am

Re: Multiply color (particle system). Dark smoke?

Post by Joe_R »

When I create my particle fade out affector I do the following:

Code: Select all

 
    IParticleAffector* pafFade = ps->createFadeOutParticleAffector(irr::video::SColor(0, 255, 255, 255), 1750);
 
If I don't set a texture and use the EMT_TRANSPARENT_ALPHA_CHANNEL material type, the fade effect works like a charm, but I want my textured particles to fade out. If I apply the texture and set the shader material up with the corrected shader code, the smoke appears perfectly, so I tried to add the fading. I did the following:

Shader callback:

Code: Select all

 
if (firstupdate)
{
    fadeValID = services->getPixelShaderConstantID("fadeVal");
 
...
 
    firstupdate = false;
}
 
...
 
irr::f32 fadeVal = irr::video::SColorf(currMat.DiffuseColor).getAlpha();
services->setPixelShaderConstant(fadeValID, &fadeVal, 1);
 
and in the fragment shader:

Code: Select all

 
sampler2D tex[1];
 
float fadeVal;
 
struct PSIn {
    float4 Pos : POSITION;
    float2 uvCoord : TEXCOORD0;
};
 
void main(in PSIn IN, out float4 colOUT : COLOR)
{
    float4 textureColor = tex2D(tex[0], IN.uvCoord);
    colOUT = float4(textureColor.rgb, textureColor.a * fadeVal);
}
 
But no fading effect appears. I don't know what I'm messing up. I tried the alpha values from specular and ambient too, without success. Should it work like this, or the fade out affector modifies some other color value?
Joe_R
Posts: 10
Joined: Wed Aug 10, 2016 10:38 am

Re: Multiply color (particle system). Dark smoke?

Post by Joe_R »

OK, it's solved. I looked it up in the Irrlicht source code, the correct color values are written to the vertex's color attribute. So the following shaders can do the desired, fading-out texured particles:

vertex:

Code: Select all

 
float4x4 realVP;
 
struct VSOut {
    float4 Pos : POSITION;
    float4 color : COLOR0;
    float2 uvCoord : TEXCOORD0;
};
 
void main(in float4 vertPos : POSITION, in float2 uvCoord : TEXCOORD0, in float4 color : COLOR, out VSOut OUT)
{
    OUT.Pos = mul(vertPos, realVP);
    OUT.uvCoord = uvCoord;
    OUT.color = color;
}
 
fragment:

Code: Select all

 
sampler2D tex[1];
 
struct PSIn {
    float4 Pos : POSITION;
    float4 color : COLOR0;
    float2 uvCoord : TEXCOORD0;
};
 
void main(in PSIn IN, out float4 colOUT : COLOR)
{
    float4 textureColor = tex2D(tex[0], IN.uvCoord);
    colOUT = float4(textureColor.rgb, textureColor.a * IN.color.a);
}
 
Post Reply