Thought I would share this with people. The shader doesn’t actually handle the cloud movement unfortunately. There was an issue with switching direction and having the clouds jump from the previous placement to another. So, you pass in the offset (shown below). It does, however, allow you to define a color which is ramped both in color and intensity, based on transparency… which looks pretty nice. Will be adding a control for simulating rain/snow etc soon as well. It’s done… just needs to be cleaned up.
Here is an example vid:
http://youtu.be/YEWkBUlTkXw
Anyways, use it if you want...
First off... here is the j3md, vert & frag...
Clouds.j3md
[java]
MaterialDef Clouds {
MaterialParameters {
Texture2D ColorMap
Color Color ( Color )
Vector2 Offset
Float Alpha
}
Technique {
VertexShader GLSL100: Clouds.vert
FragmentShader GLSL100: Clouds.frag
WorldParameters {
WorldViewProjectionMatrix
}
Defines {
HAS_COLORMAP : ColorMap
HAS_COLOR : Color
HAS_ALPHA : Alpha
HAS_OFFSET : Offset
}
}
}
[/java]
Clouds.vert
[java]
uniform mat4 g_WorldViewProjectionMatrix;
attribute vec3 inPosition;
#ifdef HAS_COLORMAP
attribute vec2 inTexCoord;
varying vec2 texCoord1;
uniform vec2 m_Offset;
#endif
void main(){
#ifdef HAS_COLORMAP
texCoord1 = vec2((inTexCoord[0]+m_Offset[0]),(inTexCoord[1]+m_Offset[1]));
#endif
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}
[/java]
Clouds.frag
[java]
#ifdef HAS_COLORMAP
uniform sampler2D m_ColorMap;
varying vec2 texCoord1;
#endif
#ifdef HAS_COLOR
uniform vec4 m_Color;
#endif
#ifdef HAS_ALPHA
uniform float m_Alpha;
#endif
void main(){
vec4 color = vec4(1.0);
#ifdef HAS_COLORMAP
color *= texture2D(m_ColorMap, texCoord1);
#endif
#ifdef HAS_COLOR
vec4 n_Color = vec4((m_Color[0]*color.a),(m_Color[1]*color.a),(m_Color[2]*color.a),color.a);
color = mix(color, n_Color, 0.25f);
#endif
#ifdef HAS_ALPHA
color.a *= m_Alpha;
#endif
gl_FragColor = color;
}
[/java]
Here is how you might use it in a control:
[java]
// Define the mat and texture at somepoint
tex_SkyClouds1 = assetManager.loadTexture("Textures/Clouds1.png");
tex_SkyClouds1.setMinFilter(MinFilter.BilinearNoMipMaps);
tex_SkyClouds1.setMagFilter(MagFilter.Bilinear);
tex_SkyClouds1.setWrap(WrapMode.Repeat);
mat_SkyClouds1 = new Material(assetManager, "MatDefs/Clouds.j3md");
mat_SkyClouds1.setTexture("ColorMap", tex_SkyClouds1);
mat_SkyClouds1.setVector2("Offset", new Vector2f(0,0));
mat_SkyClouds1.setFloat("Alpha", 1f);
mat_SkyClouds1.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
mat_SkyClouds1.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
mat_SkyClouds1.getAdditionalRenderState().setDepthWrite(false);
// Also need to define a few variables for modifying speed and direction
float cloud1IncX = 0.0f, cloud2IncY = 0.0f;
float cloudSpeed = 0.3f,
float cloudRotation = FastMath.HALF_PI+0.02f;
Vector2f cloudOffset = Vector2f.ZERO;
// In the update loop...
cloud1IncX += ((cloudSpeed*tpf)*FastMath.sin(cloudRotation));
cloud1IncY += ((cloudSpeed*tpf)*FastMath.cos(cloudRotation));
// This next step is actually not necessary... but whatever.
if (cloud1IncX > 1) cloud1IncX -= 1;
if (cloud1IncX < 1) cloud1IncX += 1;
if (cloud1IncY > 1) cloud1IncY -= 1;
if (cloud1IncY < 1) cloud1IncY += 1;
// Update the material - this is necessary
mat_SkyClouds1.setVector2("Offset", new Vector2f(cloud1IncX,cloud1IncY));
[/java]
And here is how to create decent looking clouds in Photoshop:
1. Create new layer
2. Filters > Render > Clouds (better with Filter Forge as it creates seamless tiles)
3. In Layer Palet click the Add Layer Mask button
4. Select the Mask icon on the layer (Layer Palet.. you'll see it)
5. Do a select all on the image and Ctrl+C
6. Select the Channels tab
7. Click the View icon next to the added mask channel (looks like an eye) to turn it on
8. Click the RGB view icon to turn it off
9. Click the Mask channel to make sure you have it selected and Ctrl+V the image into the mask
10. That's all that is needed to create the grayscale transparency.
One last thing about using this method of rendering moving clouds. Using 2 seperate layers moving at two different speeds in slightly different directions give the clouds a measure of depth and makes them appear to change in shape over time.
Anyways... good luck with. Feel free to change/update/expand/clean up/improve/etc anything. But please do share your improvements for the rest of us!