• Advertisement

Archived

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

Problem building a heat effect using a particle engine (with screenshots)

This topic is 5024 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m developing a F-35B flight simulator. One of the aircraft features is the vertical takeoff. I''d like to show the heat effect coming out from the lift fan, and so far i have a working particle engine. What i would like to do, is to texture the particles to reproduce the heat effect, i.e. they must be transparent and perturbated (applying a distortion that simulates hot steam). So i rendered the whole screen to a texture, but now that i have the texture i don''t have any idea how to provide the correct texture coordinates to each particle, which has to show a portion of the screen-rendered texture. Any idea ? At the following page you can see a screenshot showing what is the current dynamic of the particle engine. http://www.web-discovery.net/temp/problem_explanation.jpg

Share this post


Link to post
Share on other sites
Advertisement
I'm also planning to make the heat effect in my game. My idea is to render the whole scene into screen, transform each of the particle vertex coordinate into screen coordinate(using gluProject or gluUnproject? I'm confuse right now. then just copy the portion on the screen that is covered by the coordinates into the particle texture. this way i don't have to render the whole scene into the texture.
then distort the texture using texCoord - to do that each particle need to have something like of 4x4 quads. I've never tried this yet.

[edited by - ctoa on April 14, 2004 7:33:10 PM]

Share this post


Link to post
Share on other sites
This is of the top of my head

You can actually visualize this sort of the heat effect using your desktop (if you are using windows and your GUI settings are right.) Click and drag an icon, you should have a transperent version of the icon moving under your cursor and the original in place (that is if you GUI settings are right.) Move the transparent version (that you are dragging) right over the original one, BUT a pixel off either down or to the left or both a pixell off to the left and down. What you should see is a blury and distorted icon sort of like heat

So from this you can infer how to do you heat effect. So for each portion of the screen that you heat particle covers , make a copy of that portion, make it semi transparent, and render it on top of the original part of the screen but offseet by a pixel or two. To make the effect even better, make two copies of two different tranparancies and two different pixel offsets. And even better improvement would be to flactuate the pixel offsets (for each portion) so the heat is animated.

P.S. I do not guarantee this will work

Share this post


Link to post
Share on other sites
use a normalmap and the background as textures for your particles and then trough the use of glsl shaders you could distort the uv using the normalmap and then read the color from that uv pos on the background picture.

to provide the coorect texture cordiates you need to use shaders or gluunproject.

Personaly i prefer shaders, because then you get the xy screen coords and its just the matter of dividing those coords with the screen size.

or something like that.

O, and by the way, the front lift fan of the F-35B is cold air only and doesn't poduce heatwaves(only the tail nossle has hot air).
It does however produce a mighty strong airflow so dust should be spreading out from the position where the airflow hit's the ground.
just so you know.


---------------------------------
For an overdose of l33tness, flashbang.nu




[edited by - lc_overlord on April 15, 2004 4:17:11 AM]

Share this post


Link to post
Share on other sites
Hi, i made some progress. I first rendered a pass to a texture which is all white except a black cone (which is where the hot air is). After that i render the whole scene, and at the end i draw two quads (size of the whole screen): the first contains the black&white texture, the second contains the whole screen texture (previously saved). Then i blend the two quads so that only the screen texture matching the "black cone" will be drawn. But, if you look at the screenshot, i seem to have a blending problem: the cone correctly shows the "portion" of texture i want, but the rest of the scene is extremely bright. I suppose my blendfunc has incorrect parameters.
At the following link [url]http://www.web-discovery.net/temp/help1.htm[/url]
you will find some screenshots and the code. Thanks

Share this post


Link to post
Share on other sites
Also, i searched the forum faqs but couldn''t find the right tag to insert links to a page. Tought it was [url] ...

Share this post


Link to post
Share on other sites
I don't quite get your algorithm (explain the reasoning for your steps and how exactly are you trying to do your heat effect). As far as I can see you want to blend a transaprent copy of your scene over the exact area of the scene that the heat cone covers.

(i am assuming your black and white texture is changing every frame, since the heat source is moving. Except for this you'll need your cone to be white and everything else black)
if so do this:
1. Render your whole scene to a texture
2. Render your black and white texture onto this texture using glBlendFunc(GL_DST_COLOR,GL_ZERO); (like you did before, except your black and whit is reversed)
3. Then render your render your actual scene (to the color buffer of course )
4. Then you render that texture on top of your whole scene using this:

glColor4f(1.0f,1.0f,1.0f,your_blending_factor);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);




_________________________________________________
if that doesn't work try this for blending function:
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )


If that doesn't work read this whole tutorial

http://www.wake.tec.nc.us/%7Erhgrove/Alpha-Blending-Antialiasing.html

[edited by - snisarenko on April 17, 2004 11:39:08 PM]

[edited by - snisarenko on April 17, 2004 12:06:07 AM]

Share this post


Link to post
Share on other sites
The steps i take are the following:

1) I render the white cone on black background to a texture named VOLUMETEXTURE. This texture changes every frame, since the heat source is moving.
2) I render the whole scene normally
3) I copy the screen frame to a texture named SCREENTEXTURE
4) At this point, as you see, i have to textures, where the VOLUMETEXTURE is nothing but the alpha channel of the VOLUMETEXTURE. I''d like just blend the to textures so that only the SCREENTEXTURE area corresponding to the white cone of the VOLUMETEXTURE is displayed, while the rest is discarded. Can it be done with blendfunc or do i need a fragment program ? If you go at this link you will see some screenshots of the problem and the code.

Share this post


Link to post
Share on other sites
ok, got it

your VOLUMETEXTURE, is not really an alpha channel its a mask.

so continuing with your step 4...

4) Render your VOLUMETEXTURE to the SCREENTEXTURE
using glBlendFunc(GL_DST_COLOR,GL_ZERO);
5) Then you render the SCREENTEXTURE on top of your whole scene using this:

glColor4f(1.0f,1.0f,1.0f,your_blending_factor);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);

or, this:

glColor4f(1.0f,1.0f,1.0f,your_blending_factor);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

Share this post


Link to post
Share on other sites
Hi snisarenko, and thx for helping. What do you mean exactly with
4) Render your VOLUMETEXTURE to the SCREENTEXTURE
using glBlendFunc(GL_DST_COLOR,GL_ZERO);

Do you mean i just render the VOLUMETEXTURE on top of the whole scene too ?

Share this post


Link to post
Share on other sites
-penetrator
Do you mean i just render the VOLUMETEXTURE on top of the whole scene too ?

I mean you render your VOLUMETEXTURE on top of the whole scene in you SCENETEXTURE (you render to the SCENETEXTURE itself), not in the frame buffer. Then you render your modified SCENETEXTURE on top of the actual scene. Hope its clear



P.S. the way your trying to do this is not the fastest. You should try it with particles instead of a cone volume.

[edited by - snisarenko on April 18, 2004 6:29:01 PM]

Share this post


Link to post
Share on other sites
The fastest and cheapest way to do it is to smear oil on your screen were the heat should be. Works great for still images

Share this post


Link to post
Share on other sites
you don''t really need the second texture (volume texture) - render the texture using a colour mask of glColorMask(1,1,1,0) - so the alpha stays black - assuming that you clear it to black - then when finished rendering the scene, set glColorMask(0,0,0,1) and render the cone as white (or better yet, render many cones of different size additivly, so you get a blur for the volume)...

When rendering the texture onto the screen, just use simple alpha blending (glBlendFunc(GL_SRC_ALPHA,GL_SRC_ONE_MINUS_ALPHA);...
that should work a treat.

go one step further with a shader to add some shimer and your done.

| - My project website - | - email me - |

Share this post


Link to post
Share on other sites
Finally i found out how to make it work, thanks to everybody. If you take a look at this page , you will see that i''m rendering a simple quad with a texture which is the result of two "modulated" textures (through a fragment program). Any idea on how to get rid of the black area, making i.e. transparent with the blackground ? I tried with several blendfunc combinations and didn''t work.

This is the render() function:

void render( void )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glClearColor(1,1,1,1);
setShaderConstants();
glMatrixMode( GL_MODELVIEW );
glEnable( GL_VERTEX_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, g_vertexProgramID );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, g_pixelProgramID );
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTextureARB( GL_TEXTURE0_ARB );
glBindTexture( GL_TEXTURE_2D, g_textureID_1 );
glActiveTextureARB( GL_TEXTURE1_ARB );
glBindTexture( GL_TEXTURE_2D, g_textureID_0 );
glLoadIdentity();
glTranslatef( 0.0f, 0.0f, -3.8f );
glRotatef( -g_fSpinY, 1.0f, 0.0f, 0.0f );
glRotatef( -g_fSpinX, 0.0f, 1.0f, 0.0f );
glColor4f(0,1,0,1);
glInterleavedArrays( GL_T2F_C3F_V3F, 0, g_quadVertices );
glDrawArrays( GL_QUADS, 0, 4 );
glEnd();
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
SwapBuffers( g_hDC );
}

If you "feel" like it, at this link you can download the complete VC++ project (it''s about 270Kb). It''s a modified version of a Kevin Harris tutorial which i found very useful.

Share this post


Link to post
Share on other sites
the RGB of texture 2 you are showing is black with a white oval, is the alpha channel also like this? or is the alpha channel completely white, or, does the texture not have an alpha channel, in which case it''s treated as completely white?

because if it is completly white, then your output will always have alpha value of 1, so it won''t be transparent, and it will have a black background.

BTW. also, you don''t need to mutliply the RGB components, otherwise you will get a black edge to your shape (when you get the transparency right)

on the other hand, you could do what I suggested before and not have the second texture, and just write directly the the alpha channel of the first texture, which I still think is your best bet.

| - My project website - | - email me - |

Share this post


Link to post
Share on other sites

  • Advertisement