# Lighting of 2D clouds

This topic is 1050 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## 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

##### Share on other sites

Unfortunately all the images seem to be broken by now, so I don't know how useful it still is.

You can also probably find some useful info here: http://vterrain.org/Atmosphere/Clouds/

##### Share on other sites

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

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)
continue;

T *= 1.0 - absorption * stepSize;
if (T <= 0.01)
break;
}

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

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:

[attachment=26349:cloud1.PNG]

Light direction is slightly rotated. Starts to look unrealistic:

[attachment=26350:cloud2.PNG]

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

[attachment=26351:cloud3.PNG]

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

[attachment=26352:cloud4.PNG]

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