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

The ARB specs on fragment programs is quite a long one, so you probably haven’t read it thoroughly enough, but it’s all in there.

ARB specs are complete descriptions of ARB extensions, but IMHO they could have been written in some nicer manner (not just plain TXT) and grouped, so they would be an easier resource to learn from for new OpenGL programmers.

For someone, who previously sticked with say Direct 3D and its nice helps, it’s rather annoying to have to read / search through such long texts.
Just my opinion:)

Originally posted by penetrator:
[b]I bet now this topic “deserves” the beginners forum :stuck_out_tongue:
I found a very simple ARB Vertex & Pixel Shader, which render a quad. After studying the arb_fragment_program paper i started experimenting on both fp and vp, trying several commands. So far i think i’m getting the swing of it. However, i couldn’t find on the arb paper, how to manage more textures. Do i have to write one fp for every texture ? Or i can input more texture on one fp ?
The code of the pixel shader is the following, can you teach me how would i, for example, modulate two textures to blend them ?

!!ARBfp1.0

Fragment inputs

ATTRIB inTexCoord = fragment.texcoord; # First set of texture coordinates
ATTRIB inColor = fragment.color.primary; # Diffuse interpolated color

Fragment outputs

OUTPUT outColor = result.color;

TEMP texelColor;
TXP texelColor, inTexCoord, texture, 2D;

MUL outColor, texelColor, inColor; # Modulate texel color with vertex color
#ADD outColor, texelColor, inColor; # Add texel color to vertex color

END[/b]
You can access almost every part of the current OpenGL state such as textures, texure coordinates, lights, materials, …
“ATTRIB inTexCoord = fragment.texcoord[5];” will give you the texture coordinates of the 6th texture unit. IIRC, you even don’t have to enable the texture units to use them. simply bind a texture and that’s it. Oh, and the number of texture units accessible by the fragment program may be different (greater) than the number of texture units on the fixed func pipe, so you need to query this separately.

The following code will sample from two textures, modulate them together and output the resulting color:

TEMP tex0;
TEMP tex1;
TEX tex0, fragment.texcoord[0], texture[0], 2D;
TEX tex1, fragment.texcoord[0], texture[1], 2D;
MUL oColor, tex0, tex1;

MickeyMouse:
From my opinion the DirectX help looks much nicer but has much less indepth content. So it’s much harder to understand how to use some advanced functionality. But i agree that the specs could be written with some kind of html or so to make them easier to navigate and read (especially the ultra long vertex_program_ARB one).

I have just loaded two textures (g_textureID and g_textureID2) in the initgl() function.
And this is the render() function:

glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_VERTEX_PROGRAM_ARB );
glBindProgramARB( GL_VERTEX_PROGRAM_ARB, g_vertexProgramID );
glEnable( GL_FRAGMENT_PROGRAM_ARB );
glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, g_pixelProgramID );
glBindTexture(GL_TEXTURE_2D, g_textureID);
glutSolidTeapot(.5);
glDisable( GL_FRAGMENT_PROGRAM_ARB );
glDisable( GL_VERTEX_PROGRAM_ARB );
SwapBuffers( g_hDC );

How do i tell the fp that texture[1] is g_textureID2 ?
I searched all of the arb paper on how to load and use textures, but didn’t find anything.
Thanks for helping

Hi
Just one bit to the offtopic theme of not welformed extensions. I transformed all extensions into a compiled html file with indexing and some structure. You can find it under http://www.larswolter.de/OpenGL-Extensions.chm

And ontopic:
You use the glActiveTextureARB(…) function before binding, which takes as parameter GL_TEXTURE1_ARB to tell the gl that you want to bind something to stage 1. Dont forget to switch back to stage 0 by supplying GL_TEXTURE0_ARB. When you want to do something on stage 0.

greetings
Lars

So do i have to use arb_multitexture ?

I prefer using the extension (especially under Windows). But if you have an OpenGL 1.3 compliant implementation it is a core Function.

The use of glActiveTexture with fragment programs is described in the fragment program extension, under “Additions to Chapter 2”. You can then also read about glClientActiveTexture() which could also be necessary for you to set different texture coordinates.

Lars

Lars, i downloaded your .chm file and i want to thank you, finally arb papers are readable and indexed.
Regarding my questions about fp’s, since i get an “undeclared identifier” running some opengl 1.3 commands, do i need to download other libraries and include files other than glut 3.7.6 ?

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.

Ok, i think i fixed it, it works like i wanted to, but i’m not sure this is the “common” way to do it. I modified the fragment program as follows:

!!ARBfp1.0

ATTRIB inTexCoord = fragment.texcoord[0]; # First set of texture coordinates
ATTRIB inColor = fragment.color.primary; # Diffuse interpolated color
OUTPUT outColor = result.color;
TEMP tex0;
TEMP tex1;
TEX tex0, fragment.texcoord[0], texture[1], 2D;
SUB tex0.x, tex0.x, 0.01;
TEX tex1, fragment.texcoord[0], texture[0], 2D;
MUL outColor, tex0, tex1;
KIL tex0.x;
END

I’ve read the FRAGMENT_ARB paper, it specifies the syntax of all the commands you can use, but there is something more in detail, i.e. some examples on how to displace or warp a texture ?

Can you post a result screenshot? Also, what’s loaded in texture 0 and texture 1?

At this page you can see the two textures, and the result, which is exactly what i wanted. Here below is the fragment code, can you help me “translating” it into cG ?

!!ARBfp1.0
ATTRIB inTexCoord = fragment.texcoord[0];
ATTRIB inColor    = fragment.color.primary; OUTPUT outColor   = result.color;
TEMP tex0;
TEMP tex1;
TEX tex0, fragment.texcoord[0], texture[1], 2D;
SUB tex0.x, tex0.x, 0.01;
TEX tex1, fragment.texcoord[0], texture[0], 2D;
MUL outColor, tex0, tex1;
KIL tex0.x;
END
  

With regards to doing a refracting shimmer coming form a fan or exhaust, I did a similiar thing a while ago, but using DirectX mind you. (www.pulsefire.com/ernests) theres a divx video showing a heat shimmer caused by a fire. basicly what I did was render a sprite with a scrolling texture of a ripple into a fullscreen texture mask, then using this texture mask and a texture of the actual scene I perturbed the scene using the distortion scene using a pixel shader that samples from another part of the scene based on the amount of distortion in the mask. I believe this is how the half-life II effects are done (the big walker thing distorts the screen before it fires it’s weapon), someone also told me metroid prime on gc does it as well. It’s a really slick effect and all you have to do is render distorted objects into one buffer to effect the whole scene.

EvilE, what you describe is a common technique - peturbation can be done at pixel or vertex level…I don’t think a heat haze effect would benefit too much from being done at the pixel level, especially since it involves a dependent texture read, which requires a bit of grunt from the graphics card (and is impossible on anything below a geforce3). There’s really no need to get pixel shaders involved in this one.
Stick with a reasonably tesselated mesh and do it per vertex, pretty much as dorbie suggests.

Well using the pixel shader is faster that using a mesh, and provides more accurate perturbation. We also used the distortion effect on rain drops rolling down on the screen. It’s also easier to draw distortion to a seperate buffer than alter the uv’s of a mesh.

Only faster if you’re t&l bound, but I always seem to be fill rate bound :slight_smile:

Thanks to all your suggestions and hints, i finally coded the first version of this so called “heat effect”. On my web page you can see two screenshots reproducing the scene with and without the heat blur. The effect is achieved in the following steps:

  1. grabbing the screen to a texture
  2. rendering the heat cone volume
    to a black & white texture
  3. using a pixel shader which multiply and lerp the above textures and a perlin noise generated texture (used to perturb the texture).

The animated effect looks quite good (also if screenshots don’t tell much): one more thing to do, when i’ll have the time, is to add a small particle engine and render it to the b&w hat cone texture to make it more “unstable” and fuzzy.

Thanks again to everybody for helping !

Nice :slight_smile:
Keep it goin’

I’m sure it looks a lot better in real time, screenshots don’t do the effect any justice. By the way I used a sprite with a rolling noise texture for my heat effect, and I faded it out (alpha blending) by distance. In your situation a particle would be best or simply a series of smaller sprites coming out of the exhaust.

Hi EvilE, did you use a pixel shader to achieve your heat effect ?