In case someone is interested, a simple way to decrease the number of points needed to get a decent cloud is to splat a distorted texture. Since each splatted point is no longer radially symmetric, what's needed is to change the offset into the fractal noise texture depending on the rotation angle. Playing around with the scaling value of the extracted angles, which depends on how noisy the fractal noise texture is, can give a good illusion where the change of each point roughly matches the rotation.
With this, I use fewer and larger points. colMap is a radially symmetric gaussian alpha falloff with an extra border, and noiseMap has one perlin noise in the red channel, and a different one in the green.
// Vertex shader
varying vec2 pos;
attribute float size;
void main(void)
{
gl_Position = ftransform();
pos = gl_Vertex.xy + vec2(asin(gl_ModelViewMatrix[0].z), asin(gl_ModelViewMatrix[2].y)) * 0.075; // Randomize index by position and rotation angles
vec4 eye = gl_ModelViewMatrix * gl_Vertex;
gl_PointSize = size / (-eye.z);
gl_FrontColor = gl_Color;
}
// Fragment shader
varying vec2 pos;
uniform sampler2D colMap, noiseMap;
void main(void)
{
vec2 noise = vec2(texture2D(noiseMap, pos + gl_PointCoord * 0.2)) - 0.5;
gl_FragColor = gl_Color * texture2D(colMap, gl_PointCoord + noise * 0.5); // Note: splat texture should have a sufficient transparent border to accomodate the maximum offset
}
The particles should be lit and sorted as per the cloud article on this site.
For generating cloud data, I did something really simple, using a bunch of ellipsoids as below. The random number generator is from the excellent asmlib, which I started using initially for the faster memcpy() etc.
MersenneRandomInit(MODULE_ID);
for (int i = 0; i < 800; i += 4)
{
float cpx, cpy, cpz;
do // Generate random coordinates in an ellipse
{
cpx = 2.0f * (static_cast<float>(MersenneRandom()) - 0.5f);
cpy = static_cast<float>(MersenneRandom()) - 0.5f;
cpz = static_cast<float>(MersenneRandom()) - 0.5f;
} while (0.25f * cpx * cpx + cpy * cpy + cpz * cpz > 0.25f);
cloud = cpx * 0.67f;
cloud = cpy * <span class="cpp-number">0</span>.67f;
cloud = cpz * <span class="cpp-number">0</span>.67f;
cloud = <span class="cpp-number">100</span>.0f * <span class="cpp-keyword">static_cast</span><<span class="cpp-keyword">float</span>>(MersenneRandom()) + <span class="cpp-number">200</span>.0f; <span class="cpp-comment">// Particle size</span>
}
</pre></div><!–ENDSCRIPT–>
<!–EDIT–><span class=editedby><!–/EDIT–>[Edited by - Prune on January 16, 2009 2:46:23 AM]<!–EDIT–></span><!–/EDIT–>