Sign in to follow this  

Implementing the Tron 2.0 glow effect

This topic is 4217 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

Hi Guys, I posted and found a description of the Tron 2.0-style glow effect: http://www.gamasutra.com/features/20040526/james_pfv.htm In fact, the Nvidia SDK has a glow sample, implementing this technique in DirectX: http://download.nvidia.com/developer/SDK/Individual_Samples/samples.html#Glow Problem is, they are using compiled shaders and have a horrible implementation for code that's targeted for developers trying to learn (and especially developers trying to convert c++ to managed directx). Anyone know of any other implementations of this technique that are maybe easier to understand/break-down/reuse? Bonus points for MDX version (but I know I'm pushing my luck). Thanks, David

Share this post


Link to post
Share on other sites
Those are neat, but the most important part of the effect is the artist pipeline, where the artist can specify the glow amount through the alpha channel of the texture. The examples above don't implement the glow in quite the same way.

Share this post


Link to post
Share on other sites
Hi,

I'd been meaning to implement this myself as I think the effect looks great and is pretty cheap (when compared to full blown hdr and bloom). So when I saw your post I figured i'd give it a shot [wink]

Anyway ...these are the steps I took (this is probably not the fastest way of doing it and if anyone else has some optimisations then please jump in [smile])

Step 1: Render your scene as normal to a texture (let's call it "originalScene") with the dimensions of your viewport. We keep this texture for later as it is used a couple of times.

Step 2: Render a screen aligned quad, with the texture "originalScene" mapped to it, into a second texture. This texture has half the width and half the height of the viewport (quarter the area). Also in the pixel shader you multiply the R, G and B by the A (just like it says in the gamasutra article). We will call this texture "glowTexture".

Step 3: Render a screen aligned quad, with the texture "glowTexture" mapped to it, into a third texture. Like before this texture's dimensions are half of the viewport dimensions. In the pixel shader we blur it along the horizontal and we'll call this texture "glowBlurH".

Step 4: Render a screen aligned quad, with the texture "glowBlurH" mapped to it, into a forth texture. As before its dimensions are half of the viewport dimensions. In the pixel shader we blur it along the vertical and we'll call this texture "glowBlurV".

At this stage you have all you need to render the final glow enhanced scene [smile] So....

Step 5: Render a screen aligned quad as normal (no render targets this time) and map "originalScene" and "glowBlurV" to it. Perform a simple additive blend and there you have it [grin]

Here is the result from the app I just knocked out (with MDX btw)...

My blur weights aren't the best and it could do with a lot of tweaking, but you get the idea [smile]

All the best,
ViLiO

Share this post


Link to post
Share on other sites
Sweet!

Would you mind posting a few relevant parts of the MDX source code? Specifically, the syntax for rendering to a texture. Are you using multiple surfaces or the StretchRect method?

-Dave

Share this post


Link to post
Share on other sites
I'd suggest you check out some of the resources on mdxinfo as I know a few of the intermediate samples use render targets (the Simple Bloom Sample may in fact be the Tron 2.0 technique but i'm not sure)

Anyway....

private Texture originalScene;

/*When the device is created, initialize the rendertarget texture*/
originalScene = new Texture(device, device.Viewport.Width, device.Viewport.Height,
1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
/*I'm pretty sure render targets can't sit in the Managed Pool so you
will have to recreate these when the device is lost*/


/*Rendering time*/
Surface originalSurface = device.GetRenderTarget(0);
/*Grab the original surface so we can set this back later*/

/*Use our render target texture*/
using (Surface sceneSurface = originalScene.GetSurfaceLevel(0)) {
device.SetRenderTarget(0, sceneSurface);
device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, Color.Black, 1.0f, 0);
try {
/*Render Scene Here...*/
}
catch (InvalidCallException e) {
MessageBox.Show(e.ToString(), "Error!", MessageBoxButtons.OK);
}
}


Regards,
ViLiO

Share this post


Link to post
Share on other sites
One thing to bare in mind if you're doing this on "traditional" texture formats (that is, not floating point!) is you can get the filtering hardware to do a lot of the work for you [grin]

If you're careful about your placement of sampling points/offsets then you can get the filtering hardware to sample two texels and automagically return the average of both (which is very similar to what the bloom filters do anyway).

Thus you can either get "crazy bloom" for the same cost, or you can get the same bloom for a lower cost. With particular reference to the latter, you might even be able to combine the 2-pass approach into a single. YMMV.

This post (seemingly from an ATI person) suggests a slide deck I found very useful in this matter.

hth
Jack

Share this post


Link to post
Share on other sites
Any way to do something similar using a fixed function pipeline? I'm trying to support old cards/ laptops that do not have shaders yet. I think the only way in this case is to write new textures to the polygons (switching between texture colors).

Share this post


Link to post
Share on other sites
It's possible to do it with the FF, but the performance will likely be lower.

At the crudest level the blur can be done with just single texturing and lots of blending and offsets (using vertex alpha to set your weights). When I did my FF version I was using a symetrical kernal/filter, so I used two texture units at a time (you start with the center sample and then other passes do samples to the left and the right at the same time, as they have the same weight).

It's probably possible to use more texture units, but it's a right pain to get the weights setup right (especially in a cross-vendor way). If you really want to do it that way you might be better off using Cg.

Edit: I notice I've strayed into the DX forums. [grin] In that case setting the weights might not be as difficult as in GL.

Share this post


Link to post
Share on other sites
Sign in to follow this