Dynamic clouds with glsl

dynamic clouds-shader



! tweak params !  :wink:



vertex-shader:

uniform vec3 eyePosition;
uniform vec3 sunDirection;
uniform float scale;
                    
varying vec2  oUv;
varying float oGlow;

void main(void)
{
   vec4 position = gl_Vertex;
  
   // get vertex-position
   gl_Position = gl_ModelViewProjectionMatrix * position;
  
   // get vertex-normal
   vec3 normal = gl_Normal;

   oGlow = pow (clamp (dot ((position.xyz - eyePosition), sunDirection), 0.0, 1.0), 7.0);
                  
   // UV-coordiantes
   oUv = vec2 (gl_MultiTexCoord0.xy) * scale;
  
}



fragment-shader

uniform sampler2D cloud;
uniform sampler2D detail;
uniform vec3  sunDirection;
uniform float time;
uniform vec4  fogColor;
uniform vec4  cloudColor;
uniform float density;
uniform float cloudInvScale;
uniform float detailInvScale;
uniform vec2 cloudSpeed;
uniform vec2 detailSpeed;

varying vec2  oUv;
varying float oGlow;

void main(void)
{
  
   vec2 cloudOffset = cloudSpeed * time;
   vec2 detailOffset = detailSpeed * time;

   float a1 = texture2D (cloud, (oUv + cloudOffset) * cloudInvScale).b;
   float a2 = texture2D (detail,(oUv + detailOffset) * detailInvScale).b;
  
   vec3 p_sunDirection = normalize (sunDirection) * -0.01;
        p_sunDirection.x = p_sunDirection.x;
        p_sunDirection.y = -p_sunDirection.z;
        p_sunDirection.z = 0.0;

   vec4 p_fogColor = fogColor;
    
   vec4 oCol = cloudColor * (p_fogColor *2.0);
   oCol.a *= clamp (a1 + a2 - 1.0, 0.0, 1.0);
   oCol.rgb *= 1 - oCol.a * density;

   vec3  absorption = vec3(0.0);
         absorption += clamp (
                         texture2D (cloud,  (oUv + sunDirection.xy * 0.2 + cloudOffset) * cloudInvScale).rgb +
                         texture2D (detail, (oUv + sunDirection.xy * 0.2 + detailOffset) * detailInvScale).rgb - 1.0, 0.0, 1.0);
         absorption += clamp (
                         texture2D (cloud,  (oUv + sunDirection.xy * 0.4 + cloudOffset) * cloudInvScale).rgb +
                         texture2D (detail, (oUv + sunDirection.xy * 0.4 + detailOffset) * detailInvScale).rgb - 1.0, 0.0, 1.0);
         absorption += clamp (
                         texture2D (cloud,  (oUv + sunDirection.xy * 0.6 + cloudOffset) * cloudInvScale).rgb +
                         texture2D (detail, (oUv + sunDirection.xy * 0.6 + detailOffset) * detailInvScale).rgb - 1.0, 0.0, 1.0);
         absorption += clamp (
                         texture2D (cloud,  (oUv + sunDirection.xy * 0.8 + cloudOffset) * cloudInvScale).rgb +
                         texture2D (detail, (oUv + sunDirection.xy * 0.8 + detailOffset) * detailInvScale).rgb - 1.0, 0.0, 1.0);
         absorption += clamp (
                         texture2D (cloud,  (oUv + sunDirection.xy * 1.0 + cloudOffset) * cloudInvScale).rgb +
                         texture2D (detail, (oUv + sunDirection.xy * 1.0 + detailOffset) * detailInvScale).rgb - 1.0, 0.0, 1.0);
  
   oCol.rgb *= 1.0 - clamp (absorption * 0.2, 0.0, 1.0) * density;

   oCol.rgb *= oGlow;
  
   gl_FragColor = oCol;
}



Test-class

import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.SceneElement;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.FogState;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;

/**
 * Test for cloud shader in glsl
 *
 * @author Lutz G

nice :slight_smile:

Not much of an improvement, but you could shorten your vertex shade to the the below. I havent looked at the fragment in detail to comment on improvements.



uniform vec3 eyePosition;
uniform vec3 sunDirection;
uniform float scale;

Nice  :smiley: can you post a bigger screenshot? I want to compare this to my software cloud generator (see page)

what a cool little shader, great work!

Doesn’t seem to display well at my end.



Here’s the results:







Using the posted code with the latest jme trunk.




Jumped the gun, sorry. I forgot to add the shader folder to the build :slight_smile:

Gotta say thanks for this, it really works well :slight_smile:

Hello, I can’t see the TestCase, could you repost it please?



Thanks in advance! :slight_smile:

N.