Jump to content
  • Advertisement
Sign in to follow this  

Lighting of 2D clouds

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

Hello everyone,


i had the idea the make a simple cloud layer by rendering a 2D perlin noise texture and light it a bit. To my surprise i couldn't find any resources how to do the lighting of a 2D perlin noise so it looks like a cloud layer. I tried the standard lighting with the help of a normalmap but it looked aweful. Then i tried a few things like dividing the light factor by the alpha value etc. but nothing looked like a real cloud layer.

Has anyone a idea how to do this? Finding resources for the lighting of a 3D perlin noise was a lot easier rolleyes.gif

Share this post

Link to post
Share on other sites

Thanks for the link but I decided to try it on my own first after I got an idea wink.png

My idea is that the alpha value of the pixel also represent the height of the cloud at this pixel. With this assumption I tried to raycast this fake volume like I did with 3D clouds. You can't transfer the code 1:1 of course but this is my result:

#version 440

out vec4 fragColor;

layout(binding = 0) uniform sampler2D cloudTexture;

uniform vec3 lightDirection;
uniform int numSamples;
uniform float maxHeight;
uniform float emptiness;
uniform float absorption;

in vec2 texCoords;

const float maxDist = 1.73205080757; // sqrt(3)

void main()
    vec3 rayStart = vec3(texCoords, 0);
    //float t = -(dot(rayStart, planeNormal) - maxHeight) / dot(lightDirection, planeNormal);
    float t = maxHeight / lightDirection.z;
    vec3 rayStop = rayStart + t * lightDirection;
    float travel = distance(rayStart, rayStop);
    float stepSize = maxDist / float(numSamples);
    vec3 Step = normalize(rayStop - rayStart) * stepSize;
    vec3 pos = rayStart;
    float T = 1.0;
    for (int i = 0; i < numSamples && travel > 0.0; ++i, pos += Step, travel -= stepSize)
        float texData = texture(cloudTexture, pos.xy).a;
        float alpha = (texData - emptiness) / emptiness;
        float height = alpha * maxHeight;
        if (pos.z > height)
        T *= 1.0 - absorption * stepSize;
        if (T <= 0.01)
    float texData = texture(cloudTexture, texCoords).a;
    float alpha = clamp((texData - emptiness) / emptiness, 0, 1);
    fragColor.rgb = vec3(T);
    fragColor.a = alpha;

The problem is, this doesn't work fine sad.png

Here are some screenshots which demonstrate my problem (for demonstration purposes the alpha value is always 1 and the absorption factor is way above useful values):


Light direction is parallel to plane normal. Looks boring but ok:



Light direction is slightly rotated. Starts to look unrealistic:



Light direction is heavily rotated. Doesn't look like anything anymore:



Light direction is nearly orthogonal to plane normal. This is not what I wanted:



By now I didn't find a solution for this problem. Any ideas or is my attempt totally crap?

Share this post

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

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!