Blade like dissolve effect

Started by
6 comments, last by fitfool 13 years, 6 months ago
Hallo,

I am trying to work out how to do a dissolve effect like the one you can see in the Blade movies where the vampires die. Im very unsure about how to go about this. Simply growing a circle on the texture map would almost give the desired effect, but it would only work if the texture map is created very precisely with no gaps and with edges which match, something that is very unlikely to happen on a more complicated model like say a 3d model of a human.

My current idea is to have spheres attached to the mesh and increase the size of them as the effect progresses. Then in the shader check if a vertex is inside of one of the spheres and if it is shade it black. But to me this does not sound like a very clever way of doing it.

Is there an better way of "growing" something on a 3d mesh or a better way of trying to solve this problem?

EDIT:
Here is a good exampleof what I would like to recreate:
">Youtube Video

Kind regards,

[Edited by - h3ro on October 15, 2010 6:19:05 AM]
Advertisement
Could you have each vertex reference any other verts attached to it, and use that to grow your patches? That would avoid checking every single vert in the mesh to see if they're inside the sphere, or indeed, having 'spheres' at all - you just maintain a list of 'dissolved' verts and then have this spread out to others that are joined to them, using the distance between them to control the speed of 'infection'.
Thats a good idea. It sounds like it definatly would be a more efficent way of doing it. I still have some concern about having it as a vertex based effect tho. Would it not look better if it was pixel based? Im sure you would be able to have more interesting looking and more detailed "grow patters" that way?
Doesn't Doom3 / Quake4 have such an effect? I thought it looked pretty well, and this is with a simple "dissolve" texture that grows over the normal texture map. Not sure though if it would grow nicely from the impact point. Probably not. Anyway, you could download a demo and peek in their shaders?


The sphere check seems reasonable to me though. It only requires an attachment point (which could be the closest vertex where you hit) and the current radius. Just store the point where you hit the enemy last time. Depending if you calculate in local or absolute space, you may need to transform the local point each cycle though. You could pick the closest vertex and use that point from the results you would get with animating/skinning the model. Then increase the radius each cycle a little bit.
uniform float3 impactPointuniform float dissolveRadius// Calculate distance between pixel and impact point// Make sure both positions are in the same spacefloat dist = length( normalize( pixelPos - impactPos ) ); float dissolveFactor = saturate( dist / dissolveRadius ); // 1 means not dissolving yetfloat3 color1 = tex2D( defaultTex, texcoords.xy );float3 color2 = tex2D( dissolveTex, texcoords.xy + animatedTexcoords.xy );resultColor.rgb = lerp( color2, color1, dissolveFactor );resultColor.a = lerp( 0, 1, saturate( dissolveRadius + 0.66 - dist ) ); // Completely hide pixels after a while


Rick
Here is a fx composer project with my take on the effect. I didn't really finish it, but maybe it can serve as a starting point for you.
Should look something like this:



(But you get can another look by playing with the noise/color parameters.)

EDIT:
Maybe some comments about the most important parameters are appropriate:
NoiseBias: Percentage of object burned [0,1]
NoiseScale: 'width' of the burn
WorldScale: Granularity of the burn

And of course you would replace some of the Noise functions with pre-baked texture reads in production code.
The Doom3 implementation was pretty simple, actually. There was a single random noise texture that had a single channel of noise (0 - 255). When something was dissolving, it was rendered with alpha test enabled, and the reference value for the test was animated from 0 to 255. The shader emitted the contents of the noise texture (looked up using the normal model UVs) as the alpha value. You can also have the shader check the alpha of that texture against the current "burn limit" and change the material to create the burning edge effect.
How about this (this is just off the top of my head, I've not tested it):

Like I mentioned before, you store a reference to adjacent verts in each vertices' structure, allowing you to grow the dissolve effect across an arbitrary mesh. You also create a 1-dimensional gradient texture. The vertex shader then looks to see if a vertex should be involved in a dissolve and if so how far between two verts it has reached. This is then used to give the vert a U lookup into the gradient texture as a measure of how dissolved it has become. Using a texture means you can then use the pixel shader to interpolate any pixel depending on the dissolve level of the verts making up the triangle.
Seems actually pretty simple. Create some noise, for each texel, multiple some given time stamp by the noise, if the product is less the some given threshold, set the alpha of the texel to 0. The timestamp will allow you to control how fast the material dissolves away. Combined with edge detection of the noise with a 1 dimensional fire texture(such as http://freespace.virgin.net/hugo.elias/models/m_ffire.htm), it should be a pretty good effect.

This topic is closed to new replies.

Advertisement