Animated shader without using animMap..


(C) #1

Since animMap shaders are bugged, (server uptime >24h == animMaps are static), it makes them pretty useless.
However, an animated shader can often make things more fancy.
I was busy creating an animated shader that does not use animMap at all, but is still animated.

It is possible to use up to 8 render-passes in a shader.
My example shader has 1 base texture + 7 animation frames.
All frames of the animation are packed into 1 texture.

The shader itself does a lot of number fiddling, it might need some explaining…

  • “tcMod transform” is used to get one of the 7 images of the texture. (the T coordinate is transformed so it starts at the “Y”-position of each sub-texture).
  • alphaGen is used to alternate the texture translucency
  • rgbGen is used to make the texture colors alternate black/normal
  • blendfunc add is used, in the example case, to add the texture to the screen. Blending a black texture this way will have no visual effect, a normal colored texture will be seen on screen…

By choosing the correct intervals at which alpha-values and rgb-colors are changing, You can make only 1 of the 7 images be visible at a time…

In the example i use “wave sine” because it looked well on the caustic effect. When using “wave Square” the transition is immediate.

Here is the example shader:

// C's caustics shader..
// using a faked animMap to display up to 8 textures in an animated sequence..
textures/mapname/fake_animmap
{
	{
		// this is Your rock/wall/bricks/whatever..
		map textures/mapname/basetexture.tga
		blendfunc filter
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0
		blendFunc add
		alphaGen wave sine 0 1 0 1
		rgbGen wave sine 0 0.015 0.35714285714285714285714285714286 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.14285714285714285714285714285714
		blendFunc add
		alphaGen wave sine 0 1 0.14285714285714285714285714285714 1
		rgbGen wave sine 0 0.015 0.5 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.28571428571428571428571428571429
		blendFunc add
		alphaGen wave sine 0 1 0.28571428571428571428571428571429 1
		rgbGen wave sine 0 0.015 0.64285714285714285714285714285714 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.42857142857142857142857142857143
		blendFunc add
		alphaGen wave sine 0 1 0.42857142857142857142857142857143 1
		rgbGen wave sine 0 0.015 0.78571428571428571428571428571429 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.57142857142857142857142857142857
		blendFunc add
		alphaGen wave sine 0 1 0.57142857142857142857142857142857 1
		rgbGen wave sine 0 0.015 0.92857142857142857142857142857143 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.71428571428571428571428571428571
		blendFunc add
		alphaGen wave sine 0 1 0.71428571428571428571428571428571 1
		rgbGen wave sine 0 0.015 0.0714285714285714285714285714286 1
	}
	{
		map textures/mapname/c_caustics.tga
		tcMod transform 1 0 0 0.14285714285714285714285714285714 0 0.85714285714285714285714285714286
		blendFunc add
		alphaGen wave sine 0 1 0.85714285714285714285714285714286 1
		rgbGen wave sine 0 0.015 0.2142857142857142857142857142857 1
	}
}

Maybe someone can do something with this info…


(IndyJones) #2

video would be nice :slight_smile:


(C) #3

I prepared a little pk3 for download…
You can put it in etmain and run the map… The map is called “anim_shader_demo”

The pk3 includes 4 demo shaders:

Three caustics shader variations:
* 8 frames no lightmap,
* 7 frames + lightmap,
* 7 frames animation + extra tcmod

One special shader that displays the current framenumber of the shader at a low frequency. (So You can clearly see it is really displaying 7 seperate images in an animated sequence (+ a lightmap))…

-------------------------------------------------------------------------------------------------------------------------------
Here is the download link: http://members.home.nl/core/ETpro/anim_shader_demo.pk3
-------------------------------------------------------------------------------------------------------------------------------

C…


(Scennative) #4

Looks good :slight_smile: Maybe i will try it with bloody hud.
Then i use the normal animmap.
Maybe i have with your´s more fps…

bloodsight_8
{
	{
		animmap 9 gfx/hud/blut/sight03.tga gfx/hud/blut/sight04.tga gfx/hud/blut/sight05.tga gfx/hud/blut/sight06.tga gfx/hud/blut/sight07.tga gfx/hud/blut/sight08.tga gfx/hud/blut/sight09.tga gfx/hud/blut/sight10.tga gfx/hud/blut/sight11.tga gfx/hud/blut/sight10.tga gfx/hud/blut/sight09.tga gfx/hud/blut/sight08.tga gfx/hud/blut/sight07.tga gfx/hud/blut/sight06.tga gfx/hud/blut/sight05.tga gfx/hud/blut/sight04.tga gfx/hud/blut/sight03.tga //C ha os
		blendfunc filter		
	}
}

Greetz sCenna.


(C) #5

quote: “Maybe i have with your´s more fps”
Unlikely… i don’t think an 8-pass shader will be rendered faster than a single-stage shader.

The meaning of my demo shader is not to be fancy or fast, but to illustrate a trick for rendering specific parts of the shader (single images) at specific times and for specific durations (frametimes).
Because normally, when using just one “wave square” function (in an alphaGen or rgbGen command), the pattern repeats with just 2 states each loop… half the time it’s ON, other half it’s OFF.
By combining 2 wave functions with different phases, but with a same frequency, it is possible to create the illusion that 8 different images are drawn at different times…
…But it is just an illusion, because still 8 images are drawn all of the time. The images that are not currently displayed are completely rendered with a black color. The black images are added with what’s already on screen, using “blendfunc add”. Since a black color is represented as all 0 (zero) values internally, no visual effect is seen. (something + 0 = still the same something = no change)…

If Q3/ET would support more render-stages in a shader, it would even be possible to create an animation with more frames. You could display a new frame every 50 ms (that’s 20 FPS).

  ___     ___
 |   |   |   |
_|   |___|   |___    alphaGen
     ___     ___
    |   |   |   |
   _|   |___|   |___ rgbGen

     #       #       frame displayed when alpha && rgb are both at max.

By shifting the phase of the rgbGen wave a bit to the right,
the duration at which both waves are at max. will be shorter.
If You time that to 50 ms, You could get 20 FPS..

It might even be possible to extend my 7-frame shader with an additional 8 frames in a backshader. This way a single brushface could be displaying a 15 frame animation.


(ailmanki) #6

Nice idea, I add a link to this on my page :slight_smile: