[OLD] Skydome (Update video, game calendar, automated lighting direction update)

Please note: This library is being developed further by another developer under the name SkyControl. Please refer to that thread for more up to date code.

I’ll post the code soonish, but the updates allow you to create a game calendar/time system which automates all the previous functions based on the params you set the calendar up with. I also added sunlight direction control automation. Here is a vid of it doing… um… stuff!

Game time accelerated to 1 second = 1 minute, 1 minute per hour

[video]http://youtu.be/9YN6BdIXuiU[/video]

I want to add the ability to control either the basic or PSSM shadow renderer as well, so your shadows cast properly depending on time of day.

/cheers

The basic idea was to create a sky that:

  1. Renders cloud movement in a way that make the clouds appear to have depth
  2. Has a seamless transition from fog to sky
  3. Allows you to have seperate fog, lighting and texture/colors for night & day
  4. Handles day-to-night, night-to-day transitions for you
  5. Handles cycling clouds in and out. Can set min/max opacity and color ramp for both cloud layers.
  6. Allows you to add a moon texture, set speed roatation. Renders after night sky and day color… prior to clouds and fog.

I have a little bit of clean-up to do before posting the code & associated files + sample textures, but here is a video of what it does…

[video]http://youtu.be/RPKfB6B2OtM[/video]

Cloud cycling:

[video]http://youtu.be/FLvuSU2KP2k[/video]

Orbiting moon:

[video]http://youtu.be/fZJ-sxW0rrs[/video]

How about some usage?
[java]SkyDome skyDome = new SkyDome(assetManager, cam,
“Models/Skies/SkyDome.j3o”,
“Textures/Skies/SkyNight_L.png”,
“Textures/Skies/Moon_L.png”,
“Textures/Skies/Clouds_L.png”,
“Textures/Skies/Fog_Alpha.png”);
Node sky = new Node();
sky.setQueueBucket(Bucket.Sky);
sky.addControl(skyDome);
sky.setCullHint(Spatial.CullHint.Never);

// Either add a reference to the control for the existing JME fog filter or use the one I posted…
// But… REMEMBER! If you use JME’s… the sky dome will have fog rendered over it.
// Sorta pointless at that point
skyDome.setFogFilter(fog, viewPort);

// Set some fog colors… or not (defaults are cool)
skyDome.setFogColor(fogColor);
skyDome.setFogNightColor(fogNightColor);

// Enable the control to modify the fog filter
skyDome.setControlFog(true);

// Add the directional light you use for sun… or not
skyDome.setSun(sun);

// Set some sunlight day/night colors… or not
skyDome.setSunDayLight(dayLight);
skyDome.setSunNightLight(nightLight);

// Enable the control to modify your sunlight
skyDome.setControlSun(true);

// Enable the control
skyDome.setEnabled(true);

// Add the skydome to the root… or where ever
rootNode.attachChild(sky);[/java]

And zeee code:

SkyDome.java
[java]package mygame;

import com.jme3.asset.AssetManager;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture.MinFilter;
import com.jme3.texture.Texture.WrapMode;
import java.io.IOException;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;

/**
*

  • @author t0neg0d
    */
    public class SkyDome implements Control {
    private ViewPort viewPort;
    private Spatial spatial;
    private AssetManager assetManager;
    private Node skyNight;
    private Camera cam;
    private boolean enabled = true;
    private FogFilter fog = null;
    private DirectionalLight sun = null;
    private ColorRGBA sunDayLight = new ColorRGBA(1f, 1f, 1f, 1f);
    private ColorRGBA sunNightLight = new ColorRGBA(.45f, .45f, .45f, 1f);
    private boolean controlFog = false;
    private boolean controlSun = false;
    private String model, nightSkyMap, moonMap, cloudsMap, fogAlphaMap;
    private boolean cycleCI = false, cycleCO = false;
    private float cloudMaxAlpha = 1f, cloudMinAlpha = 0f, cloudsAlpha = 1;
    private float cloudCycleSpeed = .125f;
    private float cloud1Rotation = FastMath.HALF_PI+0.02f;
    private float cloud1Speed = .025f;
    private float cloud2Rotation = FastMath.HALF_PI+0.023f;
    private float cloud2Speed = .05f;
    private float moonRotation = 75f;
    private float moonSpeed = .0185f;
    private boolean isDay = false;
    private boolean cycleN2D = false, cycleD2N = false;
    private float dayAlpha = 0;
    private float cycleSpeed = .125f;
    private ColorRGBA fogColor = new ColorRGBA(0.7f, 0.7f, 0.7f, 0.6f);
    private ColorRGBA fogNightColor = new ColorRGBA(0.3f, 0.3f, 0.3f, 0.6f);
    private ColorRGBA dayColor = new ColorRGBA(.7f,.7f,1.0f,1.0f);
    private ColorRGBA nightColor = new ColorRGBA(.4f,.3f,.6f,1.0f);
    private Texture tex_Sky, tex_Moon, tex_FogAlpha, tex_Clouds;
    private Material mat_Sky;

/**

  • Creates a new SkyDome control
  • @param assetManager A pointer to the JME application AssetManager
  • @param cam A pointer to the default Camera of the JME application
  • @param model j3o to use as the Sky Dome
  • @param nightSkyMap The string value of the texture asset for night time sky
  • @param moonMap The string value of the texture asset for the moon. This is the only param that accepts null
  • @param cloudsMap The string value of the texture asset for the clouds
  • @param fogAlphaMap The string value of the texture asset for the blending alpha map for fog coloring
    */
    public SkyDome(AssetManager assetManager, Camera cam, String model, String nightSkyMap, String moonMap, String cloudsMap, String fogAlphaMap) {
    this.assetManager = assetManager;
    this.cam = cam;

this.model = model;
this.nightSkyMap = nightSkyMap;
this.moonMap = moonMap;
this.cloudsMap = cloudsMap;
this.fogAlphaMap = fogAlphaMap;

tex_FogAlpha = assetManager.loadTexture(fogAlphaMap);
tex_FogAlpha.setMinFilter(MinFilter.NearestNoMipMaps);
tex_FogAlpha.setMagFilter(MagFilter.Nearest);
tex_FogAlpha.setWrap(WrapMode.Repeat);

tex_Sky = assetManager.loadTexture(nightSkyMap);
tex_Sky.setMinFilter(MinFilter.BilinearNearestMipMap);
tex_Sky.setMagFilter(MagFilter.Bilinear);
tex_Sky.setWrap(WrapMode.Repeat);

if (moonMap != null) {
tex_Moon = assetManager.loadTexture(moonMap);
tex_Moon.setMinFilter(MinFilter.BilinearNearestMipMap);
tex_Moon.setMagFilter(MagFilter.Bilinear);
tex_Moon.setWrap(WrapMode.Repeat);
}

tex_Clouds = assetManager.loadTexture(cloudsMap);
tex_Clouds.setMinFilter(MinFilter.BilinearNoMipMaps);
tex_Clouds.setMagFilter(MagFilter.Bilinear);
tex_Clouds.setWrap(WrapMode.Repeat);

mat_Sky = new Material(assetManager, “MatDefs/SkyDome.j3md”);
mat_Sky.setTexture(“SkyNightMap”, tex_Sky);
if (moonMap != null) {
mat_Sky.setTexture(“MoonMap”, tex_Moon);
mat_Sky.setFloat(“MoonDirection”, moonRotation);
mat_Sky.setFloat(“MoonSpeed”, moonSpeed);
}
mat_Sky.setColor(“ColorDay”, dayColor);
mat_Sky.setColor(“ColorNight”, nightColor);
mat_Sky.setFloat(“Alpha”, dayAlpha);
mat_Sky.setTexture(“FogAlphaMap”,tex_FogAlpha);
mat_Sky.setTexture(“CloudMap1”, tex_Clouds);
mat_Sky.setFloat(“CloudDirection1”, cloud1Rotation);
mat_Sky.setFloat(“CloudSpeed1”, cloud1Speed);
mat_Sky.setFloat(“CloudDirection2”, cloud2Rotation);
mat_Sky.setFloat(“CloudSpeed2”, cloud2Speed);
mat_Sky.setFloat(“CloudsAlpha”, cloudsAlpha);
mat_Sky.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
mat_Sky.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
mat_Sky.getAdditionalRenderState().setDepthWrite(false);

skyNight = (Node)assetManager.loadModel(model);
skyNight.setCullHint(Spatial.CullHint.Never);
skyNight.setLocalScale(5f, 5f, 5f);
skyNight.setMaterial(mat_Sky);
}

public void setSpatial(Spatial spatial) {
this.spatial = spatial;
((Node)spatial).attachChild(skyNight);
}
/**

  • Enable the SkyDome control
  • @param enabled
    /
    public void setEnabled(boolean enabled) {
    this.enabled = enabled;
    }
    /
    *
  • Returns if the SkyDome control is enabled
  • @return enabled
    */
    public boolean isEnabled() {
    return this.enabled;
    }

// Transitions
public boolean getIsDay() {
return this.isDay;
}
/**

  • Sets the speed at which the transition from night to day/day to night happens
  • @param cycleSpeed Default value is .125f
    /
    public void setDayNightTransitionSpeed(float cycleSpeed) {
    this.cycleSpeed = cycleSpeed;
    }
    /
    *
  • Gets the speed at which the transition from night to day/day to night happens
  • @return cycleSpeed Default value is .125f
    /
    public float getDayNightTransitionSpeed() {
    return this.cycleSpeed;
    }
    /
    *
  • Begins cycle day to night
    /
    public void cycleDayToNight() {
    this.cycleD2N = true;
    this.cycleN2D = false;
    }
    /
    *
  • Begins cycle night to day
    */
    public void cycleNightToDay() {
    this.cycleD2N = false;
    this.cycleN2D = true;
    }

// Fog
/**

  • Sets a pointer to the fog filter used by the JME application that initialized the SkyDome control
  • @param fog The FogFilter to adjust during transitions
  • @param viewPort The default ViewPort for background color manipulation used for fog blending
    /
    public void setFogFilter(FogFilter fog, ViewPort viewPort) {
    this.fog = fog;
    this.viewPort = viewPort;
    }
    /
    *
  • Sets the day time fog color to use
  • @param fogColor Default value is 0.7f, 0.7f, 0.7f, 0.6f
    /
    public void setFogColor(ColorRGBA fogColor) {
    this.fogColor = fogColor;
    if (mat_Sky != null)
    mat_Sky.setColor(“FogColor”, fogColor);
    }
    /
    *
  • Gets the day time fog color
  • @return fogColor Default value is 0.7f, 0.7f, 0.7f, 0.6f
    /
    public ColorRGBA getFogColor() {
    return this.fogColor;
    }
    /
    *
  • Sets the night time fog color to use
  • @param fogNightColor Default value is 0.3f, 0.3f, 0.3f, 0.6f
    /
    public void setFogNightColor(ColorRGBA fogNightColor) {
    this.fogNightColor = fogNightColor;
    if (mat_Sky != null)
    mat_Sky.setColor(“FogNightColor”, fogNightColor);
    }
    /
    *
  • Gets the night time fog color
  • @return fogNightColor Default value is 0.3f, 0.3f, 0.3f, 0.6f
    /
    public ColorRGBA getFogNightColor() {
    return this.fogNightColor;
    }
    /
    *
  • Enable SkyDome to control the JME application FogFilter
  • @param controlFog Default value is false
    /
    public void setControlFog(boolean controlFog) { this.controlFog = controlFog; }
    /
    *
  • Returns if SkyDome controls the JME application FogFilter
  • @return controlFog Default value is false
    */
    public boolean getControlFog() { return this.controlFog; }

// Sun
/**

  • Pointer to the Directional Light used by your JME application as a sun light
  • @param sun
    /
    public void setSun(DirectionalLight sun) {
    this.sun = sun;
    }
    /
    *
  • Sets the color used by the sun during day time
  • @param sunDayLight Default value is 1f, 1f, 1f, 1f
    /
    public void setSunDayLight(ColorRGBA sunDayLight) {
    this.sunDayLight = sunDayLight;
    }
    /
    *
  • Sets the color used by the sun during night time
  • @param sunNightLight Default value is .45f, .45f, .45f, 1f
    /
    public void setSunNightLight(ColorRGBA sunNightLight) {
    this.sunNightLight = sunNightLight;
    }
    /
    *
  • Gets the color used by the sun during day time
  • @return sunDayLight Default value is 1f, 1f, 1f, 1f
    /
    public ColorRGBA getSunDayLight() {
    return this.sunDayLight;
    }
    /
    *
  • Gets the color used by the sun during night time
  • @return sunNightLight Default value is .45f, .45f, .45f, 1f
    /
    public ColorRGBA getSunNightLight() {
    return this.sunNightLight;
    }
    /
    *
  • Enable SkyDome to control the JME application DirectionLight
  • @param controlSun Default value is false
    /
    public void setControlSun(boolean controlSun) { this.controlSun = controlSun; }
    /
    *
  • Returns if SkyDome controls the JME application DirectionalLight
  • @return controlSun Default value is false
    */
    public boolean getControlSun() { return this.controlSun; }

// Day time color
/**

  • Sets the color used for day time sky
  • @param dayColor Default value is .7f, .7f, 1f, 1f
    /
    public void setDaySkyColor(ColorRGBA dayColor) {
    this.dayColor = dayColor;
    if (mat_Sky != null)
    mat_Sky.setColor(“ColorDay”, dayColor);
    }
    /
    *
  • Gets the color used for day time sky
  • @return dayColor Default value is .7f, .7f, 1f, 1f
    /
    public ColorRGBA getDaySkyColor() {
    return this.dayColor;
    }
    /
    *
  • Sets the color blended to the day time sky for transitioning from day to night/night to day
  • @param nightColor Default value is .4f, .3f, .6f, 1f
    /
    public void setSkyNightColor(ColorRGBA nightColor) {
    this.nightColor = nightColor;
    if (mat_Sky != null)
    mat_Sky.setColor(“ColorNight”, nightColor);
    }
    /
    *
  • Gets the color blended to the day time sky for transitioning from day to night/night to day
  • @return nightColor Default value is .4f, .3f, .6f, 1f
    */
    public ColorRGBA getSkyNightColor() {
    return this.nightColor;
    }

// Moon
/**

  • Sets the rotation/direction the moon moves in
  • @param moonRotation Default value 75f
    /
    public void setMoonRotation(float moonRotation) {
    this.moonRotation = moonRotation;
    if (mat_Sky != null)
    mat_Sky.setFloat(“MoonRotation”, moonRotation);
    }
    /
    *
  • Gets the rotation/direction the moon moves in
  • @return moonRotation Default value 75f
    /
    public float getMoonRotation() {
    return this.moonRotation;
    }
    /
    *
  • Sets the speed the moon moves
  • @param moonSpeed Default value .0185f
    /
    public void setMoonSpeed(float moonSpeed) {
    this.moonSpeed = moonSpeed;
    if (mat_Sky != null)
    mat_Sky.setFloat(“MoonSpeed”, moonSpeed);
    }
    /
    *
  • Gets the speed the moon moves
  • @return moonSpeed Default value .0185f
    */
    public float getMoonSpeed() {
    return this.moonSpeed;
    }

// Clouds
/**

  • Sets the near cloud layer movement rotation/direction
  • @param cloudRotation Default value FastMath.HALF_PI+0.02f
    /
    public void setCloudsNearRotation(float cloudRotation) {
    this.cloud2Rotation = cloudRotation;
    if (mat_Sky != null)
    mat_Sky.setFloat(“CloudDirection2”, cloudRotation);
    }
    /
    *
  • Gets the near cloud layer movement rotation/direction
  • @return cloud2Rotation Default value FastMath.HALF_PI+0.02f
    /
    public float getCloudsNearRotation() {
    return this.cloud2Rotation;
    }
    /
    *
  • Sets the near cloud layer movement speed
  • @param cloudSpeed Default value .05f
    /
    public void setCloudsNearSpeed(float cloudSpeed) {
    this.cloud2Speed = cloudSpeed;
    if (mat_Sky != null)
    mat_Sky.setFloat(“CloudSpeed2”, cloudSpeed);
    }
    /
    *
  • Gets the near cloud layer movement speed
  • @param cloud2Speed Default value .05f
    /
    public float getCloudsNearSpeed() {
    return this.cloud2Speed;
    }
    /
    *
  • Sets the far cloud layer movement rotation/direction
  • @param cloudRotation Default value FastMath.HALF_PI+0.023f
    /
    public void setCloudsFarRotation(float cloudRotation) {
    this.cloud1Rotation = cloudRotation;
    if (mat_Sky != null)
    mat_Sky.setFloat(“CloudDirection1”, cloudRotation);
    }
    /
    *
  • Gets the near cloud layer movement rotation/direction
  • @return cloud1Rotation Default value FastMath.HALF_PI+0.02f
    /
    public float getCloudsFarRotation() {
    return this.cloud1Rotation;
    }
    /
    *
  • Sets the far cloud layer movement speed
  • @param cloudSpeed Default value .025f
    /
    public void setCloudsFarSpeed(float cloudSpeed) {
    this.cloud1Speed = cloudSpeed;
    if (mat_Sky != null)
    mat_Sky.setFloat(“CloudSpeed1”, cloudSpeed);
    }
    /
    *
  • Gets the far cloud layer movement speed
  • @return cloud1Speed Default value .025f
    */
    public float getCloudsFarSpeed() {
    return this.cloud1Speed;
    }

/**

  • Sets the near and far cloud layers maximum opacity for cycling clouds in/out
  • @param cloudMaxOpacity Default value 1f
    /
    public void setCloudMaxOpacity(float cloudMaxOpacity) {
    this.cloudMaxAlpha = cloudMaxOpacity;
    }
    /
    *
  • Gets the near and far cloud layers maximum opacity for cycling clouds in/out
  • @return cloudMaxOpacity Default value 1f
    /
    public float getCloudMaxOpacity() {
    return this.cloudMaxAlpha;
    }
    /
    *
  • Sets the near and far cloud layers minimum opacity for cycling clouds in/out
  • @param cloudMinOpacity Default value 0f
    /
    public void setCloudMinOpacity(float cloudMinOpacity) {
    this.cloudMinAlpha = cloudMinOpacity;
    }
    /
    *
  • Gets the near and far cloud layers minimum opacity for cycling clouds in/out
  • @return cloudMinOpacity Default value 0f
    /
    public float getCloudMinOpacity() {
    return this.cloudMinAlpha;
    }
    /
    *
  • Sets the speed at which the near and far cloud layers are cycled in/out
  • @param cloudCycleSpeed Default value .125f
    /
    public void setCloudCycleSpeed(float cloudCycleSpeed) {
    this.cloudCycleSpeed = cloudCycleSpeed;
    }
    /
    *
  • Gets the speed at which the near and far cloud layers are cycled in/out
  • @return cloudCycleSpeed Default value .125f
    */
    public float getCloudCycleSpeed() {
    return this.cloudCycleSpeed;
    }

// Color mix function
/**

  • Blends two ColorRGBAs by the amount passed in
  • @param c1 The color being blended into
  • @param c2 The color to blend
  • @param amount The amount of c2 to blend into c1
  • @return r The resulting ColorRGBA
    */
    private ColorRGBA mix(ColorRGBA c1, ColorRGBA c2, float amount) {
    ColorRGBA r = new ColorRGBA();
    r.interpolate(c1, c2, amount);
    return r;
    }

// Day to night/night to day cycles
/**

  • Begin cycle clouds in
    /
    public void cycleCloudsIn() {
    this.cycleCI = true;
    this.cycleCO = false;
    }
    /
    *
  • Begin cycle clouds out
    */
    public void cycleCloudsOut() {
    this.cycleCI = false;
    this.cycleCO = true;
    }

public void update(float tpf) {
if (spatial != null && enabled) {
Vector3f camLoc = cam.getLocation();
float[] camLF = camLoc.toArray(null);
spatial.setLocalTranslation(camLF[0], camLF[1]+.25f, camLF[2]);

// Day/Night Cycle
if (cycleN2D) {
if (dayAlpha < 1.0f) {
dayAlpha += tpf * cycleSpeed;
mat_Sky.setFloat(“Alpha”, dayAlpha);
if (fog != null && controlFog) {
viewPort.setBackgroundColor(mix(fogNightColor,fogColor,dayAlpha));
fog.setFogColor(mix(fogNightColor,fogColor,dayAlpha));
}
if (controlSun) sun.setColor(mix(sunNightLight,sunDayLight,dayAlpha));
} else {
dayAlpha = 1.0f;
mat_Sky.setFloat(“Alpha”, dayAlpha);
if (fog != null && controlFog) {
viewPort.setBackgroundColor(fogColor);
fog.setFogColor(fogColor);
}
if (controlSun) sun.setColor(sunDayLight);
cycleN2D = false;
}
} else if (cycleD2N) {
if (dayAlpha > 0.0f) {
dayAlpha -= tpf * cycleSpeed;
mat_Sky.setFloat(“Alpha”, dayAlpha);
if (fog != null && controlFog) {
viewPort.setBackgroundColor(mix(fogNightColor,fogColor,dayAlpha));
fog.setFogColor(mix(fogNightColor,fogColor,dayAlpha));
}
if (controlSun) sun.setColor(mix(sunNightLight,sunDayLight,dayAlpha));
} else {
dayAlpha = 0.0f;
mat_Sky.setFloat(“Alpha”, dayAlpha);
if (fog != null && controlFog) {
viewPort.setBackgroundColor(fogNightColor);
fog.setFogColor(fogNightColor);
}
if (controlSun) sun.setColor(sunNightLight);
cycleD2N = false;
}
}

// Clouds Cycle
if (cycleCI) {
if (cloudsAlpha < cloudMaxAlpha) {
cloudsAlpha += tpf * cloudCycleSpeed;
mat_Sky.setFloat(“CloudsAlpha”, cloudsAlpha);
} else {
cloudsAlpha = cloudMaxAlpha;
mat_Sky.setFloat(“CloudsAlpha”, cloudsAlpha);
cycleCI = false;
}
} else if (cycleCO) {
if (cloudsAlpha > cloudMinAlpha) {
cloudsAlpha -= tpf * cloudCycleSpeed;
mat_Sky.setFloat(“CloudsAlpha”, cloudsAlpha);
} else {
cloudsAlpha = cloudMinAlpha;
mat_Sky.setFloat(“CloudsAlpha”, cloudsAlpha);
cycleCO = false;
}
}
}
}

public void render(RenderManager rm, ViewPort vp) {

}

public Control cloneForSpatial(Spatial spatial) {
SkyDome control = new SkyDome(this.assetManager, this.cam,
this.model,
this.nightSkyMap,
this.moonMap,
this.cloudsMap,
this.fogAlphaMap);
control.spatial.addControl(control);
return control;
}
public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = ex.getCapsule(this);
oc.write(enabled, “enabled”, true);
oc.write(spatial, “spatial”, null);
}
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
enabled = ic.readBoolean(“enabled”, true);
spatial = (Spatial) ic.readSavable(“spatial”, null);
}
}[/java]

Le MatDef:

SkyDome.j3md
[java]MaterialDef SkyDome {

MaterialParameters {
Color FogColor
Color FogNightColor

Texture2D FogAlphaMap
Texture2D SkyNightMap
Color ColorDay
Color ColorNight

Float Alpha : 1.0

Boolean VertexColor
Boolean SeperateTexCoord

Texture2D MoonMap
Vector2 MoonDirection
Vector2 MoonSpeed

Texture2D CloudMap1
Float CloudsAlpha

Color CloudColorRamp1
Float CloudDirection1
Float CloudSpeed1

Color CloudColorRamp2
Float CloudDirection2
Float CloudSpeed2
}

Technique {
VertexShader GLSL100: Shaders/SkyDome.vert
FragmentShader GLSL100: Shaders/SkyDome.frag

WorldParameters {
WorldViewProjectionMatrix
Time
}

Defines {
SEPERATE_TEXCOORD : SeperateTexCoord
HAS_VERTEXCOLOR : VertexColor
HAS_GLOWMAP : GlowMap
HAS_CLOUDS1 : CloudSpeed1
HAS_CLOUDS2 : CloudSpeed2
HAS_COLORRAMP1 : CloudColorRamp1
HAS_COLORRAMP2 : CloudColorRamp2
HAS_MOON : MoonMap
}
}
}[/java]

Le Shaders:

SkyDome.vert
[java]uniform mat4 g_WorldViewProjectionMatrix;
uniform float g_Time;
attribute vec3 inPosition;

attribute vec2 inTexCoord;
varying vec2 texCoord1;

varying float cycleTime;
uniform float m_Cycle;
uniform float m_CycleSpeed;

#ifdef SEPERATE_TEXCOORD
attribute vec2 inTexCoord2;
varying vec2 texCoord2;
#endif

#ifdef HAS_CLOUDS1
uniform vec2 m_CloudOffset1;
uniform float m_CloudDirection1;
uniform float m_CloudSpeed1;
varying vec2 cloudCoord1;
#endif

#ifdef HAS_CLOUDS2
uniform vec2 m_CloudOffset2;
uniform float m_CloudDirection2;
uniform float m_CloudSpeed2;
varying vec2 cloudCoord2;
#endif

#ifdef HAS_MOON
uniform float m_MoonSpeed;
uniform float m_MoonDirection;
varying vec2 moonCoord;
#endif

#ifdef HAS_VERTEXCOLOR
attribute vec4 inColor;
varying vec4 vertColor;
#endif

const float pi = 3.14159;

void main(){
texCoord1 = inTexCoord;

cycleTime = mod(g_Time,100.0);//* m_CycleSpeed;

#ifdef HAS_CLOUDS1
cloudCoord1 = inTexCoord;
float cloudTime1 = (g_Time*(m_CloudSpeed10.1));
cloudCoord1.x += (cloudTime1
sin((m_CloudDirection1*(pi/180.0))));
cloudCoord1.y += (cloudTime1cos((m_CloudDirection1(pi/180.0))));
#endif

#ifdef HAS_CLOUDS2
cloudCoord2 = inTexCoord + vec2(0.14);
float cloudTime2 = (g_Time*(m_CloudSpeed20.1));
cloudCoord2.x += (cloudTime2
sin((m_CloudDirection2*(pi/180.0))));
cloudCoord2.y += (cloudTime2cos((m_CloudDirection2(pi/180.0))));
#endif

#ifdef HAS_MOON
moonCoord = inTexCoord;
float time = (g_Time*(m_MoonSpeed0.1));
moonCoord.x += (time
sin((m_MoonDirection*(pi/180.0))));
moonCoord.y += (timecos((m_MoonDirection(pi/180.0))));
#endif

#ifdef SEPERATE_TEXCOORD
texCoord2 = inTexCoord2;
#endif

#ifdef HAS_VERTEXCOLOR
vertColor = inColor;
#endif

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}[/java]

SkyDome.frag
[java]uniform vec4 m_ColorNight;
uniform vec4 m_ColorDay;
uniform sampler2D m_SkyNightMap;
uniform sampler2D m_FogAlphaMap;
uniform vec4 m_FogColor;
uniform vec4 m_FogNightColor;

varying float cycleTime;
uniform bool m_CycleDayToNight;
uniform bool m_CycleNightToDay;

varying vec2 texCoord1;
uniform float m_Alpha;

uniform sampler2D m_CloudMap1;
uniform float m_CloudsAlpha;

#ifdef HAS_CLOUDS1
varying vec2 cloudCoord1;
#endif

#ifdef HAS_CLOUDS2
varying vec2 cloudCoord2;
#endif

#ifdef HAS_MOON
uniform sampler2D m_MoonMap;
varying vec2 moonCoord;
#endif

#ifdef HAS_COLORRAMP1
uniform vec4 m_CloudColorRamp1;
#endif

#ifdef HAS_COLORRAMP2
uniform vec4 m_CloudColorRamp2;
#endif

#ifdef HAS_LIGHTMAP
uniform sampler2D m_LightMap;
#ifdef SEPERATE_TEXCOORD
varying vec2 texCoord2;
#endif
#endif

#ifdef HAS_VERTEXCOLOR
varying vec4 vertColor;
#endif

void main(){
vec4 color = vec4(1.0);
color *= texture2D(m_SkyNightMap, texCoord1);

#ifdef HAS_VERTEXCOLOR
color *= vertColor;
#endif

#ifdef HAS_MOON
vec4 moon = texture2D(m_MoonMap, moonCoord);
color = mix(color, moon, moon.a);
#endif

vec4 fColor = mix(m_ColorNight, m_ColorDay, m_Alpha);
color = mix(color, fColor, m_Alpha);
vec4 fogColor = mix(m_FogNightColor, m_FogColor, m_Alpha);

vec4 c_Color;
#if defined(HAS_COLORRAMP1) || defined(HAS_COLORRAMP2)
vec4 n_Color;
#endif
#if defined(HAS_CLOUDS1) || defined(HAS_CLOUDS2)
vec4 cloud;
#endif

#ifdef HAS_CLOUDS1
cloud = texture2D(m_CloudMap1, cloudCoord1);
c_Color = vec4(1.0,1.0,1.0,cloud.rm_CloudsAlpha);
#ifdef HAS_COLORRAMP1
n_Color = vec4(vec3(m_CloudColorRamp1.rgb
cloud.r),cloud.r);
c_Color = mix(c_Color, n_Color, 0.25f);
#endif
color = mix(color,c_Color,cloud.rm_CloudsAlpha);
#endif
#ifdef HAS_CLOUDS2
cloud = texture2D(m_CloudMap1, cloudCoord2);
c_Color = vec4(1.0,1.0,1.0,cloud.r
m_CloudsAlpha);
#ifdef HAS_COLORRAMP2
n_Color = vec4(vec3(m_CloudColorRamp2.rgbcloud.r),cloud.r);
c_Color = mix(c_Color, n_Color, 0.25f);
#endif
color = mix(color,c_Color,cloud.r
m_CloudsAlpha);
#endif

float fogAlpha = 1.0-texture2D(m_FogAlphaMap, texCoord1).r;
color = mix(color,fogColor,fogAlpha);

gl_FragColor = color;
}[/java]

Le j3o:
SkyDome.j3o

Le Textures (one size fits all):

Le Test Textures (512x512):


Le Test Textures (1024x1024):


Licence Agreement:
No shirt, no shoes… no service (depending on how you look with no shirt)
You break it, you buy it.
Um… fetch… the comfy chair
The larch
Feel free to use and abuse this.

17 Likes
@t0neg0d said:
This seems like it hasn't been actually considered past... this solves our immediate problem. Everyone is asking that we contribute this way, but no thought has gone into the impact it will have when people start doing this as the norm. The thought "Impending Cluster-F" comes to mind.

No one expects the Spanish Inquisition. :)


A) it presumes that people actually do it
B) the problems are not so great anyway. Even a thousand plug-ins would be manageable with some better categorization. I'd be very surprised if we see even 100.
C) it's still better than scattering it around the internet and around in code blocks on the forums. It's easily found, already packaged and labeled, and one-click ready to go.

I think plug-in contributors will feel swamped with user questions and requests for updates long before the plug-in system becomes an issue.

That’s very nice!

so you have a separate fog for ground and sky? or is it the same?

@nehon said:
That's very nice!
so you have a separate fog for ground and sky? or is it the same?


I have a flag in the FogFilter to exclude the sky (or you could use shader-based fog) The fog layer in the sky is an alpha map texture that renders the fog color over the other textures.

The textures needed are (and these could be dropped by one, but I like the effect):

Night sky
Night Sky glow map
Single cloud map
Fog alpha map

It renders the night sky and then then blends in the daytime color based on alpha. Then the furthest cloud layer (has a direction & speed associated with it) is added, then the second cloud layer (separate direction & speed associated with it) is added. Then it renders the fog color based on the alpha map. Ends up looking really cool.

Oh… the control will handle lighting and the FogFilter for you (if you set the flags). The FogFilter can be the one with JME or the one one I posted out here. Some mods would need to added for shader-based fog. Usually if you’re rendering fog this way, you have some global routine for updating all textures appropriately. The calls in cycleDayToNight() & cycleNightToDay() would need to be changed from the FogFilter updates to whatever the material update method you have is.

It also allows you to do a few other things, like add a moon that orbits… couple other things I didn’t add to the video above.

Yeah… after revisiting the glow map… I think I’m going to ditch it before posting the code. It’s an extra bit of nonsense that helps make crappy looking night sky textures look better. But… hey! That’s not my responsibility! People who use this should make nice looking night sky textures to begin with!! :slight_smile:

another nice shader :slight_smile: even if you make it public, i can’t use it(because of game type) :expressionless:



anyway, great work!

Just wanted to show cycling clouds in and out. You can set the minimum and maximum opacity range & speed for cycling. This is used for cycling storms, etc, etc. You can set color ramps on the clouds to darken/lighten them.



Here is a vid of the cloud cycling:



http://youtu.be/FLvuSU2KP2k



Adding this to the OP as well... almost done cleaning up the code and adding the javadoc info
2 Likes

And another vid showing orbiting moon. You set the texture on initialization (or don’t if you don’t want to use it), the either use the defaults or set rotation/direction and speed of movement.



http://youtu.be/fZJ-sxW0rrs

2 Likes

Those clouds look really convincing, I’m impressed :slight_smile:

Does it look convincing when moving around also?

@kwando said:
Does it look convincing when moving around also?


I think so... I'll post the code tomorrow and you can give it a go and see whatcha think. I'll post textures to test with at both 512 and 1024... I think the 512's are livable... but the moon map and night sky at 1024 look muuuuuuch better. The vids are using the lower res textures.

I’t would be awesome if you put all your things in a library/plugin/repository somewhere with demos already setup (like the jME test suite). I personally hate copying code from the forum and paste into new files… it is easy but messy and a nightmare to keep up to date…



If all your good work where put into a google-code repo or something like it, the code would be much easier to obtain and keep updated :slight_smile:

We. Have. A. Contribution. Repository. Please don’t all start to ignore and circumvent it like @mifth does. If everybody keeps his own repo we are back to jME2 times. (And I’m out then ;))

1 Like

It looks very nice, good job.

Code posted

I also wanted to mention that this eventually will be updated with a “game-time/calendar” system and the ability to add your shadow renderer as well.



This will probably be the coolest thing the SkyDome will do. It will allow you to set scaling minutes-to-hours, hours in day, days in week, weeks in month, months in year, etc, etc. Yeah… boring stuff. But, the purpose (aside from usage for games that rely on a calendaring system) will be this:



It will adjust the suns direction based on game time (for lighting) and update your shadow renderer to cast shadows in the appropriate direction as well.



The calendar system is all in place, I just need to add a bit of code for manipulating the suns direction and then make sure it will work with the PSSM and Basic shadow renderers.



I’ll also be automating day-to-night/night-to-day transitions based on the setting for the calendar. This sky dome is the one I was using for my game, though I paired some of these features back, as they relied on certain server based mechanisms that I was completely sure how to transfer. Anyways, long story short… I think I have it worked out now and I will add the features soon(ish).

One step closer to the Warlock One-Click MMORPG Creator as we all envisioned it.



I got to reiterate what Normen already pointed out though: This contribution would be immensely more useful as a plugin. We want to start making this the default way of contributing additional features to jMonkeyEngine 3. If you can explain to us why you’re hesitant about getting into plugin development, we’d greatly appreciate it.

@erlend_sh said:
One step closer to the Warlock One-Click MMORPG Creator as we all envisioned it.


Not sure how this was meant :( But no happy feeling are surfacing atm

@erlend_sh said:
I got to reiterate what Normen already pointed out though: This contribution would be immensely more useful as a plugin. We want to start making this the default way of contributing additional features to jMonkeyEngine 3. If you can explain to us why you're hesitant about getting into plugin development, we'd greatly appreciate it.


User Code & Projects
Code sources and community projects. Request reviews and feedback for your free resource.


Did I read the title of this group wrong? This is easiest for me atm.

More than this though... Some of the code I've posted here has prompted changes to core that wouldn't have been considered otherwise (I know this for a fact because I have made requests that made sense, were completely ignored after I was told they were pointless and then magically appear a couple days after posting a filter or shader or control or etc, etc, that show exactly why the change should have been implemented). I have no idea if posting contributions there will have the same impact, so until I can think of another way of having my ideas considered, post code here suites me well.

I believe this one is going to have the same effect (counting the days til I see the change I'm expecting from it). It might sound mean and underhanded, but after close to two year of working with JME... this seems to be the only way to get some people attention.