The correct way to do fog

What it says on the tin: a place to discuss proposed new features.
Post Reply
User avatar
fantasian
Halfling
Posts: 81
Joined: Fri May 29, 2009 8:47 am
Location: Selanic, Greece
Contact:

The correct way to do fog

Post by fantasian » Fri Mar 18, 2011 7:42 pm

Hi. I have stumbled across a problem with fog in my game. Setting it globally with the SceneManager doesn't work with all kinds of materials. I suspect this is because it just sets the same value for each pass of each technique. This produces wrong results when e.g 1 technique is consisted of passes that are added together (thus producing a lighter effect).

I have posted screenshots of this problem in the past : http://www.ogre3d.org/forums/viewtopic.php?f=1&t=57526

Now, I am coding a new global way that checks what type of passes each technique has and tries to split the fogging values so that the end result is correct. But this is oh so hard to do correctly, given all those different types of scene blending.

I think that the right way to do it would be with post-processing, checking the z-buffered value for each pixel drawn in the viewport, THEN blending it with the fog value according to it's z distance and fog equation.

What do people think about this? Could this actually be done with a Compositor filter?

Kind regards,

Bill Kotsias

Producer, Designer, Senior Software Engineer & Programmer : Kyball, 2011 - http://www.youtube.com/watch?v=VkB-kQ9ovVU
0 x

User avatar
koirat
Orc
Posts: 446
Joined: Mon Feb 25, 2008 7:56 pm

Re: The correct way to do fog

Post by koirat » Sat Mar 19, 2011 1:57 am

Yes you can do the fog with post processing. I'm doing it like this and it is working.
What you have to do is to set fog_override for all your material passes so the fog is not calculated for them.
Next you have to render your scene to depth texture.
With depth texture you can do the compositor with fog calculations.
0 x
This is a block of text that can be added to posts you make. There is a 255 character limit.

User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
Contact:

Re: The correct way to do fog

Post by Jabberwocky » Sat Mar 19, 2011 4:01 am

What happens if you set fog_override true on any pass which is scene_blend add or scene_blend modulate? I'm wondering if you can avoid the post processing.
0 x
Image

User avatar
fantasian
Halfling
Posts: 81
Joined: Fri May 29, 2009 8:47 am
Location: Selanic, Greece
Contact:

Re: The correct way to do fog

Post by fantasian » Sat Mar 19, 2011 11:15 am

Jabberwocky wrote:What happens if you set fog_override true on any pass which is scene_blend add or scene_blend modulate? I'm wondering if you can avoid the post processing.
The results would be wrong. See my previous messages. Fog must be applied in every pass, else the result will look wrong.
0 x

User avatar
fantasian
Halfling
Posts: 81
Joined: Fri May 29, 2009 8:47 am
Location: Selanic, Greece
Contact:

Re: The correct way to do fog

Post by fantasian » Sat Mar 19, 2011 11:19 am

koirat wrote:Yes you can do the fog with post processing. I'm doing it like this and it is working.
What you have to do is to set fog_override for all your material passes so the fog is not calculated for them.
Next you have to render your scene to depth texture.
With depth texture you can do the compositor with fog calculations.
1) Since this is a Feature Requests forum, could you please share the inner workings of your method so that Ogre can benefit from this? (like adding it for the next version) :D
2) I have just thought of yet another problem : what happens when you have transparent objects? Depth-writing is disabled for them? How would they look with a post-processed fog?
0 x

User avatar
koirat
Orc
Posts: 446
Joined: Mon Feb 25, 2008 7:56 pm

Re: The correct way to do fog

Post by koirat » Sat Mar 19, 2011 1:05 pm

To tell you the truth i do not do any tests about the transparent objects. As i see now i have done it a little different than what i have told you before. I do not store depth inside a texture but fog color and alpha component. It was a test if you can add fog in a post process and it was a success so i did not dig into this any more. But still I was planning to release it for the community later, since i could not find such a solution on the forum.

The code is in C#/Mogre

Add Compositor and it's material listener (don't forget to enable fog in ogre)

Code: Select all

            Camera cam = ServiceManager.GetService<ICameraService>().Camera;
            CompositorInstance ci = CompositorManager.Singleton.AddCompositor(cam.Viewport, "Fog");
            ci.Enabled = true ;
            this.ServiceManager.GetService<MaterialListenerService>().AddListener("Fog", new FogMaterialListener("fog"));

MaterialListeners

Code: Select all

   public abstract class SchemeBasedMaterialListener:Mogre.MaterialManager.Listener
    {
        public bool Enabled { get; set; }

        public string SchemeName { get; set; }

        protected SchemeBasedMaterialListener(string schemeName)
        {
            Enabled = true;
            this.SchemeName = schemeName;
        }

        public override Technique HandleSchemeNotFound(ushort schemeIndex, string schemeName, Material originalMaterial, ushort lodIndex, IRenderable rend)
        {
            if (Enabled && SchemeName == schemeName)
                return OnHandleSchemeNotFound(schemeIndex, schemeName, originalMaterial, lodIndex, rend);
            else
                return null;
        }

        protected abstract Technique OnHandleSchemeNotFound(ushort schemeIndex, string schemeName, Material originalMaterial, ushort lodIndex, IRenderable rend);
    }

class FogMaterialListener : SchemeBasedMaterialListener
    {
        string fogMaterialName = "FogMaterial";
        ulong mFogHandle;
        public FogMaterialListener(string schemeName)
            : base(schemeName)
        {
            if (!MaterialManager.Singleton.ResourceExists(fogMaterialName))
                throw new ApplicationException(fogMaterialName + " do not exists!");
            using(MaterialPtr mFog=Mogre.MaterialManager.Singleton.Load(fogMaterialName, ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME))
            {
                mFogHandle = mFog.Handle;
            }
        }

        protected override Technique OnHandleSchemeNotFound(ushort schemeIndex, string schemeName, Material originalMaterial, ushort lodIndex, IRenderable rend)
        {
            if (schemeName == this.SchemeName)
            {
                return ((MaterialPtr)MaterialManager.Singleton.GetByHandle(mFogHandle)).GetTechnique(0);
            }
            return null;
        }

    };
fog.program (I do not know why it is not allowed as an attachment !!)

Code: Select all

vertex_program FogVS cg
{
    source Fog.cg
    profiles vs_2_0
    entry_point fogVS

    default_params
    {
	param_named_auto worldViewProj worldviewproj_matrix
    }
}

fragment_program FogPS cg
{
    source Fog.cg
    profiles ps_2_0
    entry_point fogPS

    default_params
    {
	param_named_auto fogColor fog_colour
	param_named_auto iFogParams fog_params
	param_named_auto worldViewProj worldviewproj_matrix
    }
}
Attachments
FogMaterial.material
inside this material is also AlphaBlendTexture material
(399 Bytes) Downloaded 147 times
fog.compositor
(414 Bytes) Downloaded 143 times
Fog.cg
devilish shader
(666 Bytes) Downloaded 176 times
0 x
This is a block of text that can be added to posts you make. There is a 255 character limit.

User avatar
fantasian
Halfling
Posts: 81
Joined: Fri May 29, 2009 8:47 am
Location: Selanic, Greece
Contact:

Re: The correct way to do fog

Post by fantasian » Sat Mar 19, 2011 9:00 pm

Thank you so much. Here is hope that the fog issue will be tackled in a more "modern" way in the next version of Ogre. :D
0 x

Post Reply