Page 1 of 1

[TUTORIAL???] Volumetric Fog + Bloom

Posted: Mon Apr 29, 2013 2:02 pm
by Abraxas)
Hello guys,

I recently completed my 4th year of mechanical engineering and spent a few days trying to best my old nemesis, multipass shaders. Somehow it all came together after a couple days and I managed to do the following, in Irrlicht:

- Depth maps (seperate, multipass)
- Blur
- Bloom
- Volumetric Fog
- VMF + Bloom

Here are some screens:

Image
Image
Image
Image
Image
Image

I was so relieved that with my limited understanding and with absolutely no optimizations I was able to acheive 60 FPS running a HD5770 card ( from ~2009, you can buy one today for 20$, so I would consider that "middle end" ?)

I can put together a basic tutorial in the same manner as my bumpmapping one, if you guys are interested.

I'm sure this seems like a basic achievement to some of you who either studied graphics, or have much more experience than I do, but it's one I'm proud of nonetheless!

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 07, 2013 11:19 am
by robmar
Looks great, the more examples the better so please go ahead and post. You should get some feedback for sure on optimisation and stuff.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Fri May 10, 2013 4:49 pm
by christianclavet
Would be nice to have tutorial on how to use Irrlicht with shaders/creating shader and use it in Irrlicht. There is very few information on this.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Mon May 13, 2013 4:51 pm
by hendu
I found the example 10 (or whatever number it was) pretty clear. Is there something wrong with it?

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Mon May 13, 2013 6:47 pm
by CuteAlien
Yeah, an example how to do multipass rendering would probably not hurt. I've finally also started shader coding last week (yes, it's 2013 and I do my very first shaders ...) and that was something I thought we could add to the examples. Also the stuff with using registers in samples to access textures in hlsl took me some hours forum searching until I figured it out.

Anyway - I'll never say no to having more code and tutorials in the public, that's always great :-)

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 14, 2013 10:41 am
by hendu
Multipass as in overdraw of normal meshes shouldn't be done, it's bad form and bad for performance. So an example teaching it would prod newbies to a wrong direction.

Or do you mean with screen quads/postprocessing? In that case, one should be added to the engine before an example could be made ;)

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 14, 2013 1:47 pm
by CuteAlien
Yes, I meant screen quads/postprocessing. And well, the quad is 2 triangles... but I guess it's useful enough that adding it might indeed make indeed sense.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 14, 2013 4:54 pm
by Abraxas)
I'll begin writing this tutorial soon. Overdraw was a necessary step to draw the depth map as the fogs are draw separately in their own depth map textures.

This way you can have multiple fog clouds, and you only have to draw your world twice, the first time limiting your frustum to limit fog range can really increase performance on old hardware.

The fog effect is added IN postprocess OVER the normal backbuffer image, blur done in parallel, and then everything is combined.

I didn't see a way of drawing the scene and at the same time drawing it's depth map to another texture.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 14, 2013 6:02 pm
by mikkis
I didn't see a way of drawing the scene and at the same time drawing it's depth map to another texture.
You can do that using MRT.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Tue May 14, 2013 7:04 pm
by Abraxas)
I'm sure there is a way, but until someone writes a tutorial for doing so, it's a complete mystery to me.

If there was a way of defining in the shader output to return an array of colors, one for each render texture, it would definitely be useful.

Thanks.

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Wed May 15, 2013 5:02 am
by mikkis
Some code from my unfinished def renderer (so you get the idea).
It creates 3 RT and renders all of them at once.

init:

Code: Select all

 
irr::core::array<irr::video::IRenderTarget> multiRenderTarget;
 
    colorRT = driver->addRenderTargetTexture(core::dimension2d<u32>(w,h), "colorMap", ECF_A8R8G8B8);
    normalRT = driver->addRenderTargetTexture(core::dimension2d<u32>(w,h), "normalMap", ECF_A8R8G8B8);
    depthRT = driver->addRenderTargetTexture(core::dimension2d<u32>(w,h), "depthMap", ECF_R32F); // ECF_R16F
    multiRenderTarget.push_back(colorRT);
    multiRenderTarget.push_back(normalRT);
    multiRenderTarget.push_back(depthRT);
 
    createGBufferEffect = world.loadShader("RenderGBuffer.cg", &deferredRendererShaderCallBack, 1);
 
render:

Code: Select all

 
    world.useShader(createGBufferEffect); // bind shader (
 
    driver->setRenderTarget(multiRenderTarget, true, true, video::SColor(0,0,0,0));
    sceneManager->drawAll();
 
    driver->setRenderTarget(0, true, true, 0);
 
RenderGBuffer.cg: (not made by me)

Code: Select all

 
float4x4 World;
float4x4 View;
float4x4 Projection;
float specularIntensity;
float specularPower; 
 
sampler TextureMap;
sampler SpecularMap;
sampler NormalMap;
 
struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Normal : NORMAL0;
    float2 TexCoord : TEXCOORD0;
    float4 Binormal : BINORMAL0;
    float4 Tangent : TANGENT0;
};
 
struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
    float2 Depth : TEXCOORD1;
    float3x3 tangentToWorld : TEXCOORD2;
};
 
VertexShaderOutput main_v(VertexShaderInput input)
{
    VertexShaderOutput output;
 
    float4 worldPosition = mul(float4(input.Position.xyz,1), World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
 
    output.TexCoord = input.TexCoord;
    output.Depth.x = output.Position.z;
    output.Depth.y = output.Position.w;
 
    // calculate tangent space to world space matrix using the world space tangent,
    // binormal, and normal as basis vectors
    output.tangentToWorld[0] = mul(input.Tangent, World);
    output.tangentToWorld[1] = mul(input.Binormal, World);
    output.tangentToWorld[2] = mul(input.Normal, World);
 
    return output;
}
struct PixelShaderOutput
{
    half4 Color : COLOR0;
    half4 Normal : COLOR1;
    half4 Depth : COLOR2;
};
 
PixelShaderOutput main_f(VertexShaderOutput input)
{
    PixelShaderOutput output;
    output.Color = tex2D(TextureMap, input.TexCoord.xy);
    
//    float4 specularAttributes = tex2D(SpecularMap, input.TexCoord.xy);
    //specular Intensity
//    output.Color.a = specularAttributes.r;
    
    // read the normal from the normal map
    float3 normalFromMap =  float3(0,1,0); //tex2D(NormalMap, input.TexCoord.xy);
    //tranform to [-1,1]
    normalFromMap = 2.0f * normalFromMap - 1.0f;
    //transform into world space
    normalFromMap = mul(normalFromMap, input.tangentToWorld);
    //normalize the result
    normalFromMap = normalize(normalFromMap);
    //output the normal, in [0,1] space
    output.Normal.rgb = 0.5f * (normalFromMap + 1.0f);
 
    //specular Power
//    output.Normal.a = specularAttributes.a;
 
    output.Depth = input.Depth.x / input.Depth.y;
 
    return output;
}
 

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Wed May 15, 2013 6:07 pm
by Abraxas)
Oh awesome it actually does work by outputting an array of colors. I'll adjust my tutorial accordingly (It's actually a very minor change, both the depthmap and raster shader are in the same branched file).

Thanks!

Re: [TUTORIAL???] Volumetric Fog + Bloom

Posted: Wed May 15, 2013 10:59 pm
by CuteAlien
Also thanks from me, we just talked about MRT's today and I didn't know yet how to do them :-)