Megabyte Softworks
C++, OpenGL, Algorithms

Current series: OpenGL 3.3

12.) Fog Outside

Welcome to the 12th OpenGL 3.3 tutorial! This time we'll discuss fog and how to program it using shaders. Fog is really nice and simple effect, which is often used in games not only to give a flavour to it, but also because it eliminates need of far clipping plane, because we won't see things far from us, because they are covered by fog anyway. So let's get started.

Fog

Fog is a collection of liquid water droplets or ice crystals suspended in the air at or near the Earth's surface. While fog is a type of stratus cloud, the term "fog" is typically... just Wikipedia definition. But I think there's no need to explain to anyone what is a fog, we all know that . We are going right to its implementation using shaders.

The basic idea behind fog should be something like that - the further object from camera is, the more covered in fog it should be. And we won't be calculating just how far objects are, but we'll do it for every single fragment in final image, because that's what modern GPU programming paradigms allows us. So the main idea is to calculate each fragment's distance from camera (it's reffered to as fogCoordinate, and then apply some function, which will calculate the fogFactor - how much fog to add to this fragment. Our fog will also have its color, so depending on fogFactor, we'll calculate final fragment color by mixing it with fog's color.

There are 3 basic functions, that calculate fog factor depending on fog coordinate. These are:

• linear - nothing difficult, just linear interpolation, additional two parameters - fogStart and fogEnd are required. The fog is exactly between he fogStart and fogEnd, before the start there is fogFactor 0.0, and at the end of fog and beyond, fogFactor is 1.0.
• exp - we'll take euler number e which is base of natural logarithm and its value is approx. 2.718, and raise it to fogCoord*(-fogDensity). fogDensity is additional parameter for this equation, and simply tells us how dense the fog is
• exp2 - similar to previous, but this time we'll raise e to -( (fogCoord*(fogDensity)^2)

We'll go through each of these equations now.

Linear equation

There's not much to think of here. Simply fog factor should be linear interpolation between fog start and fog end, so the equation looks like this:

which can be easily written in GLSL as:
fogFactor = 1.0-clamp( (fogEnd-fogCoord)/(fogEnd-fogStart), 0.0, 1.0)

Exp equation

This is my favourite equation, I think it gives nicest results. It takes one additional parameter - fog density. It should be a number ranging somewhere between 0.0 and 0.1, beyond these numbers fog is too dense or none (you can try to play with this value in application). It looks like this:

The distribution now isn't linear, but exponential, and as you can see in application, it seems a lot better than linear fog. The graph of this function looks like this (it's for density 0.04, but you should get an idea of how it looks):

There is a function exp in GLSL, that raises e to a specified power, so it's easy to write in GLSL:
fogFactor = 1.0-clamp( exp(-fogDensity*fogCoord), 0.0, 1.0)

Exp2 equation

The third and the last fog equation that is commonly used is exp2 equation. It looks like this:

Again, the power to 2 changes game a little. The density is even more sensible, so optimal range is somewhere between the 0.0 and 0.05, otherwise fog gets too intense (again, play with this value in demo so that you will see it). The graph of function looks like this (it's for density 0.03):

In GLSL, we can write with exp and pow functions (pow takes two parameters - number to raise, and number to raise to):
fogFactor = 1.0-clamp(exp(-pow(fogDensity*fogCoord, 2.0)), 0.0, 1.0)

Calculating fog coordinate

This is a key to success in order to program fog. But luckily, it's very easy. I would even say unbelievable easy . You just need to calculate eye space position of every vertex (we already know that), and then send it to fragment shader interpolated between every fragment to get eye space position of every fragment. We are interested in how deep or how far from us it is, so we are interested in z value. And since the eye space position is in homogeneous coordinates (we discussed it in 4th tutorial), we divide it with its w coordinate to obtain cartesian coordinates. And to top of all, we make an absolute value from it, because the result of these operations seems to be negative.

Here is a vertex shader for this:

#version 330

uniform struct Matrices
{
mat4 projectionMatrix;
mat4 modelViewMatrix;
mat4 normalMatrix;
} matrices;

layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;

smooth out vec2 texCoord;
smooth out vec3 vNormal;
smooth out vec4 vEyeSpacePos;

void main()
{
vec4 vEyeSpacePosVertex = matrices.modelViewMatrix*vec4(inPosition, 1.0);
gl_Position = matrices.projectionMatrix*vEyeSpacePosVertex;
texCoord = inCoord;
vec4 vRes = matrices.normalMatrix*vec4(inNormal, 0.0);
vNormal = vRes.xyz;

vEyeSpacePos = vEyeSpacePosVertex;
}

#version 330

uniform struct FogParameters
{
vec4 vFogColor; // Fog color
float fStart; // This is only for linear fog
float fEnd; // This is only for linear fog
float fDensity; // For exp and exp2 equation

int iEquation; // 0 = linear, 1 = exp, 2 = exp2
} fogParams;

float getFogFactor(FogParameters params, float fFogCoord)
{
float fResult = 0.0;
if(params.iEquation == 0)
fResult = (params.fEnd-fFogCoord)/(params.fEnd-params.fStart);
else if(params.iEquation == 1)
fResult = exp(-params.fDensity*fFogCoord);
else if(params.iEquation == 2)
fResult = exp(-pow(params.fDensity*fFogCoord, 2.0));

fResult = 1.0-clamp(fResult, 0.0, 1.0);

return fResult;
}

As you can see, there is only struct containing fog parameters and fog factor calculatiion function. Now if we want to use this function in another shader file, we just need to declare it in it. And with it, also the struct must be declared in that shader file (that's why something like #includefile would be very useful). Of course, you can't forget to add this shader into shader program in initScene function. Now, let's have a look at fragment shader file with main function:

#version 330

smooth in vec2 texCoord;
smooth in vec3 vNormal;
smooth in vec4 vEyeSpacePos;
out vec4 outputColor;

uniform sampler2D gSampler;
uniform vec4 vColor;

uniform struct SimpleDirectionalLight
{
vec3 vColor;
vec3 vDirection;
float fAmbientIntensity;
} sunLight;

uniform struct FogParameters
{
vec4 vFogColor; // Fog color
float fStart; // This is only for linear fog
float fEnd; // This is only for linear fog
float fDensity; // For exp and exp2 equation

int iEquation; // 0 = linear, 1 = exp, 2 = exp2
} fogParams;

float getFogFactor(FogParameters params, float fFogCoord);

void main()
{
vec4 vTexColor = texture2D(gSampler, texCoord);
float fDiffuseIntensity = max(0.0, dot(normalize(vNormal), -sunLight.vDirection));
outputColor = vTexColor*vColor*vec4(sunLight.vColor*(sunLight.fAmbientIntensity+fDiffuseIntensity), 1.0);

float fFogCoord = abs(vEyeSpacePos.z/vEyeSpacePos.w);
outputColor = mix(outputColor, fogParams.vFogColor, getFogFactor(fogParams, fFogCoord));
}

In the end of it, we can see that we are calculating fog coordinate using the interpolated vEyeSpacePos, and then just mix colors depending on fog factor. GLSL function mix just adds two colors together, depending on third parameter factor like this: (1.0-factor)*color1 + factor*color2. One optimization that would save some processing time is not to interpolate whole eye space position, because we are not using x and y coordinates anyway, but rather directly calculate the fog factor in vertex shader, and send it interpolated into fragment shader. You can try it on your own, it should work as well.

In render scene function, fog parameters must be set before rendering. We do it as we always set uniforms:

#define FOG_EQUATION_LINEAR 0
#define FOG_EQUATION_EXP 1
#define FOG_EQUATION_EXP2 2

namespace FogParameters
{
float fDensity = 0.04f;
float fStart = 10.0f;
float fEnd = 75.0f;
glm::vec4 vFogColor = glm::vec4(0.7f, 0.7f, 0.7f, 1.0f);
int iFogEquation = FOG_EQUATION_EXP; // 0 = linear, 1 = exp, 2 = exp2
};

void renderScene(LPVOID lpParam)
{
// ...

spFogAndLight.setUniform("fogParams.iEquation", FogParameters::iFogEquation);
spFogAndLight.setUniform("fogParams.vFogColor", FogParameters::vFogColor);

if(FogParameters::iFogEquation == FOG_EQUATION_LINEAR)
{
spFogAndLight.setUniform("fogParams.fStart", FogParameters::fStart);
spFogAndLight.setUniform("fogParams.fEnd", FogParameters::fEnd);
}
else
spFogAndLight.setUniform("fogParams.fDensity", FogParameters::fDensity);

// ..
}

We just set these parameters, and we're ready to render a scene with fog. There is spiral made of box, it's coded in a minimalistic manner, but it shouldn't be a problem to understand how it works. If it is, let me know.

Result

Result seems to be very nice, see for yourself:

Don't forget to play around with keys 'F', '+', '-', PageUp and PageDown to change fog parameters and see the difference between different equations and their settings.

If you have problems with code compilation, don't forget to update libraries glm and FreeType to their latest versions. I'm trying to use latest versions in these tutorials.

Well, that's all for now, hope you liked it and the fog using shaders has been demystified for you . See you next time with lighting continued, we'll discuss point lights.

Name:

E-mail:
(Optional)
Entry:

Enter the text from image:

Smileys

 WilliamRus (mtpv50396@first.baburn.com) on 03.12.2017 04:45:51 Supra Nederland Kopen When you're done outdoor camping and ready to go house, you must pick up right after yourself. Maintaining nature neat and safeguarded can enable long term travelers to take pleasure from it way too. Before leaving, tidy up any messes you've made at the internet site and check out the best to depart the outdoors while you actually found it. https://www.catharijne-concerten.nl/images/baz2/18805-adidas-oranje-schoenen.jpg It is important that you figure out how to recognize the main difference in actual physical effort and actual physical pain if you want to remove back discomfort. At the onset of soreness, you can begin to accomplish several expands to release your muscle mass. With effort, you will be aware that it's a chance to require a sleep prior to deciding to damage oneself. https://www.adidasgazelledames.nl/images/adh2/12975-adidas-stan-smith-rood.jpg
 Gregoryjeory (tzlw66758@first.baburn.com) on 28.11.2017 16:30:24 Zx Flux Grijs Attempt to purchase video games together with your children. Choosing game titles everyone will love brings about great family activity nights. It can also help mothers and fathers to learn that game titles are era appropriate for their children. Keeping involved in the online games children are taking part in is simple when moms and dads are a part of the buying procedure. https://www.befc.nl/images/kap2/11161-louboutins-zwarte-pumps.jpg Allow yourself be spoiled. Specifically within the last couple of months you will probably be quite uneasy. Talk with your nearby therapeutic massage parlors and day spas. The majority of them will provide carrying a child massages that are designed for your requirements. If you are previous your thanks date a number of them could actually be able to use strain points to induce labour. https://www.adidaszxfluxsale.nl/images/svu2/6044-yeezy-350-moonrock.jpg
 DonaldDom (favg82701@first.baburn.com) on 28.11.2017 12:56:59 Nike Huarache Dames Print Externally searching in, offering in the real estate marketplace might seem like a difficult move to make. But following you've read this report and placed these straightforward real estate property ideas to use for you, you are going to fully grasp precisely how basic it might be to market your own home for a wonderful cost on the market.Suggestions Which Will Help Enhance Your Interior Designing https://www.asicssneakers.nl/images/djw2/142-asics-gel-kayano-21-decathlon.jpg When hiring a home with a boyfriend or partner, in no way hire a location that you would be unable to manage all by yourself. There may be circumstances like shedding a job or breaking up that might leave you in the place to pay the complete rent alone. https://www.converseschoenenkopen.nl/images/sie2/1000-converse-all-stars-herenschoenen.jpg
 HenryGailm (nmjd50923@first.baburn.com) on 27.11.2017 11:47:47 kbfljzd http://www.svoren.se/253-uggs-mini-rea.php http://www.pangchristianshavn.dk/woolrich-jakker-805.html http://www.moose-sys.co.uk/woolrich-green-525.htm http://www.gordonfights.se/pris-pĂĄ-parajumper-930.html http://www.alsurdelpirineo.es/botas-uggs-falabella-531.html Moncler Dunjacka Quincy Barbour Alnwick Parajumpers Daunenparka Irene Veste Belstaff Classic Tourist Trophy Barbour Steve Mcqueen
 Thomasagoms (hili14064@catch@first.baburn.com) on 10.11.2017 18:57:06 twldnsz http://www.agateassociates.co.uk/988-adidas-ace-16.4.htm http://www.zapatillasmizunomujer.es/saucony-casual-hombre-147.html http://www.bluemotorbike.fr/693-chaussures-fila-2016.php http://www.guccibeltsuk.ru/michael-kors-belt-brown-306 http://www.cohen-investigation.fr/525-adidas-superstar-rose-foncÃ©.php Purple Converse High Tops Childrens Nike Free 5.0 Boys' Running Shoe (3.5y-7y) Nike Mercurial Superfly 5 Dark Lightning Adidas Original Nere Adidas Gazelle Kate Moss
 JamesPsymn (sddc32308@first.baburn.com) on 07.11.2017 14:59:55 liylhdu http://www.probaiedumontsaintmichel.fr/221-new-balance-574-marron.php http://www.scarpembtestive.it/993-skechers-recensioni.htm http://www.army-vo.fr/367-chaussures-puma-femme-noeud.html http://www.jesuisextrabelle.fr/nike-air-max-2016-cuir-234.html http://www.alpenny.it/air-jordan-low-585.html Nike Lunarglide 7 Rouge Nike 2016 Rosse Nike Janoski Nere Zalando Gucci Belt Black And Red Nike Mercurial 2013
 MatthewCreve (lzlv39420@first.baburn.com) on 20.10.2017 22:10:24 bqziefn http://www.scarpevibramprezzo.it/scarpe-goretex-vibram-064.html http://www.eccellenzabirra.it/288-puma-scarpe-creeper-nere.html http://www.farnham-park-hotel.co.uk/pumps-with-fur-999.html http://www.botasfutboloutlet.es/botas-de-futbol-hypervenom-baratas-539.html http://www.probaiedumontsaintmichel.fr/125-new-balance-femme-u420-grise-pas-cher.php Nike Sb Homegrown Buy Fila Shoes Online Amazon Hogan Grigie Pelle Polo Lacoste A Righe Zapatos Adidas De Dama
 AnthonyDob (zsig83596@first.baburn.com) on 20.10.2017 22:10:20 vpsgnnk http://www.gressoneywalserfestival.it/270-maglioni-hollister.html http://www.massagenow.co.uk/680-louboutin-thigh-boots.htm http://www.netcarco.co.uk/asics-womens-asics-gel-lyte33-2-pink-running-shoe-223.htm http://www.cost2insure.co.uk/nike-presto-shoes-womens-749.html http://www.asicstrainers.ru/714-asics-running-shoes-2016.html Felpe Lacoste Costo Adidas Femme Dentelle Nike Sb Zoom Stefan Janoski Mujer Jordans 5 Michael Kors Totes Images
 VictorTrurn (wqqe89180@first.baburn.com) on 15.10.2017 21:06:09 wwossuh http://www.progettotanzio.it/865-longchamp-backpack.asp http://www.alpenny.it/nike-free-4.0-v2-womens-gray-pink-running-shoes-871.html http://www.borsesitoufficiale.it/vuitton-speedy-25-825.htm http://www.mhcreativemedia.co.uk/under-armour-shoes-on-feet-102.htm http://www.sujoncla-terriers.co.uk/nike-roshe-uk-6-857.htm Scarpe Da Uomo Gucci 2017 Nike Air Presto Br Qs White Black Ray Ban Clubmaster Polarised Uk Adidas Los Angeles Bright Red Polo Lacoste Uomo Zalando
 HenryGailm (lbdr96659@first.baburn.com) on 15.10.2017 20:48:05 zuedesw http://www.scarpeadidasnuove.it/adidas-superstar-dorate-prezzo-749.html http://www.mpkju.fr/nike-cortez-shark-noir-811.php http://www.zapatillasmodabaratas.es/mbt-sapatu-blanco-984.php http://www.elconsejo.es/698-adidas-ultra-boost-foro.html http://www.farnham-park-hotel.co.uk/ysl-heels-sale-636.html Air Jordan EspaĂ±a Reebok Fucsia Nike Shoes Latest Design Timberland De Colores Para Mujer Abercrombie Parka Mens
 JamesCex (jsvo77974@first.baburn.com) on 15.10.2017 08:03:13 Saucony Omni 13 Dam Selecting the best schools may affect your personal financing. Probably the most expense great ways to have a renowned education or qualification is actually by attending cheaper schools for element of your education and learning, and switch to some more expensive or far better-rated school for that remainder. Your credits will merge in the previous university and you will still acquire the graduation benefits from the brand new institution. https://www.cvaanmeldservice.nl/images/cva2/20930-adidas-slippers-zwart-rood.jpg Get some excellent reasons to chuckle with the entire world. You can watch an interesting motion picture or television show and will also also acquire your thoughts off from any problems you may have to deal with. So locate a funny on the television set, sit back, and make sure you allow out all those jokes. https://www.jochem.nu/images/joc2/9689-ray-ban-aviator-synsam.jpg
 EarnestRisee (gtrw25298@first.baburn.com) on 09.10.2017 02:48:01 Tincan Oakley
 Felipemetty (felipesam@kinobum.top) on 22.09.2017 07:01:56 the canadian pharmacy canadian pharmacy overseas pharmacy forum sertraline 100mg buy cialis difference between cymbalta and duloxetine
 RalphBoync (ralphshier@canadianpharmacyseo.us) on 09.09.2017 08:41:51 cialis and cancer risk cialis generic relatos de cialis cialis generic
 KennethMon (ixjz28921@first.baburn.com) on 27.08.2017 12:20:09 nwgjpfu http://www.cfdspros.fr/stan-smith-adidas-vert-560.html http://www.hd3d.fr/huarache-homme-kaki-560.html http://www.lyceerenedescartes77.fr/497-huarache-nike-noir.html http://www.scootracer.fr/gazelle-adidas-blanc-137.htm http://www.treguier-immobilier.fr/chaussure-a-talon-femme-confortable-888.html Nike Air Max 90 Ultra Se Bleu Converse Rose Pale Basse Air Jordan Rouge Foot Locker Nike Sb Basse Femme Zx Flux Adv Noir
 MerlinBot (ugut82224@first.baburn.com) on 25.08.2017 00:31:32 Adidas Los Angeles Leder Refreshments are an essential part for each dinner as you will want to have the appropriate wines with your recipe should you be ingesting various meats. Be sure that you choose a fine red wine should you be developing a good quality meat, and that is certain to optimize the quality of your knowledge about relatives and buddies. https://www.altgold-ankauf-mannheim.de/images/newaltgcon/4181-converse-all-star-hellblau.jpg Obtain your child in to a every day schedule and stay constant along with it. It will help your youngster really feel steady at home and with every single day routines. Keep dish periods, bathroom periods and examine times constant. This can also assist you to keep a lot more organized and will help to keep your time together. https://www.buchsalon-angelibri.de/images/newbuafho/1056-abercrombie-fitch-berlin.jpg
 DavidWroto (nybv81197@first.baburn.com) on 25.08.2017 00:25:48 Nike Air Presto Schwarz Weiss Individuals feel they learn how to correctly treat their epidermis, but the truth is lots of people don't actually know what they already want to do to make sure their pores and skin is at its greatest. The one thing you should do is understand around you are able to about proper skincare, so keep in mind using this write-up mainly because it includes a good amount of details for you personally. https://www.dokutv-online.de/images/dok2/16087-adidas-neo-ballerinas-piona---dunkelblau.jpg Making use of a credit card intelligently is an essential aspect of being a wise buyer. It is essential to become knowledgeable extensively in the techniques credit cards function and how they may come to be useful resources. By using the suggestions with this item, you can have what must be done to get manage of your fiscal prospects.How To Fully grasp More Details On Common Insurance plan. https://www.vom-albtrauf.de/images/newvomrv/4877-vans-schuhe-damen-high.jpg
 Matthewstets (hsmw54804@first.baburn.com) on 18.08.2017 13:27:01 kzgooxp http://www.separacion.com.es/carteras-michael-kors-2018-182.php http://www.letrasdiscografia.es/590-nike-shox-hombre-costa-rica.html http://www.qgames.es/adidas-los-angeles-woman-151.html http://www.probaiedumontsaintmichel.fr/879-chaussures-new-balance-running.php http://www.probaiedumontsaintmichel.fr/937-running-new-balance-femme-pas-cher.php Oakley Radar Path Mujer New Balance Look Mujer New Balance 574 Bleu Ciel Polo Ralph Lauren Madrid Tiendas Jordan Flight 2017 Para Mujer
 Richarddync (jsrd59589@first.baburn.com) on 14.08.2017 10:44:48 knalrwq http://www.iloveshoes.fr/nouvelle-nike-2015-933.html http://www.soleil-vert.fr/395-sac-longchamps-camel.html http://www.hd3d.fr/huarache-2017-femme-149.html http://www.tableduterroir.fr/548-air-max-nike-pas-cher-femme.php http://www.schwoerer-regio.fr/polo-ralph-lauren-jacket-518.html Ralph Lauren Veste MatelassĂ©e Chaussures Fila Annees 90 Louboutin Sandales 2015 Chaussures Louboutin Femme Nouvelle Collection Site Lunettes