Hi @ all,
here the source from the demo in my thread
http://www.jmonkeyengine.com/jmeforum/index.php?topic=3710.msg33286#msg33286
terrain_dot3_vert.glsl
uniform float groundTexMult;
uniform float rockTexMult;
uniform float detailFadeFactor;
uniform float LightScaleFactor;
uniform vec3 LightPosition;
uniform vec3 SkyColor;
uniform vec3 HazeColor;
varying float fade;
varying float vHeight;
varying vec4 viewCoords;
varying vec3 diffuseColor;
varying vec3 lightVec;
const float C1 = 0.429043;
const float C2 = 0.511664;
const float C3 = 0.743125;
const float C4 = 0.886227;
const float C5 = 0.247708;
const vec3 L00 = vec3( 1.0351604, 0.7603549, 0.7074635);
const vec3 L1m1 = vec3( 0.4442150, 0.3430402, 0.3403777);
const vec3 L10 = vec3(-0.2247797, -0.1828517, -0.1705181);
const vec3 L11 = vec3( 0.7110400, 0.5423169, 0.5587956);
const vec3 L2m2 = vec3( 0.6430452, 0.4971454, 0.5156357);
const vec3 L2m1 = vec3(-0.1150112, -0.0936603, -0.0839287);
const vec3 L20 = vec3(-0.3742487, -0.2755962, -0.2875017);
const vec3 L21 = vec3(-0.1694954, -0.1343096, -0.1335315);
const vec3 L22 = vec3( 0.5515260, 0.4222179, 0.4162488);
void main( void )
{
gl_Position = ftransform();
vec3 ecPosition = vec3 (gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_Normal);
lightVec = normalize(LightPosition - ecPosition);
float cosTheta = dot(tnorm, lightVec);
float a = 0.5 + 0.5 * cosTheta;
viewCoords = gl_ModelViewProjectionMatrix * gl_Vertex;
diffuseColor = vec3(mix(HazeColor , SkyColor , a));
diffuseColor *= C1 * L22 * (tnorm.x * tnorm.x - tnorm.y * tnorm.y) +
C3 * L20 * tnorm.z * tnorm.z + C4 * L00 - C5 * L20 +
2.0 * C1 * L2m2 * tnorm.x * tnorm.y +
2.0 * C1 * L21 * tnorm.x * tnorm.z +
2.0 * C1 * L2m1 * tnorm.y * tnorm.z +
2.0 * C2 * L11 * tnorm.x +
2.0 * C2 * L1m1 * tnorm.y +
2.0 * C2 * L10 * tnorm.z;
diffuseColor *= LightScaleFactor;
fade = pow(tnorm.y, detailFadeFactor);
vHeight = gl_Vertex.y;
gl_TexCoord[0]= gl_MultiTexCoord0;
gl_TexCoord[1]= gl_MultiTexCoord0 * groundTexMult;
gl_TexCoord[2]= gl_MultiTexCoord0 * rockTexMult;
}
terrain_dot3_frag.glsl
uniform sampler2D groundTex;
uniform sampler2D rockTex;
uniform sampler2D splatTex;
uniform sampler2D rockNormalMap;
uniform vec3 fogColor;
uniform float groundTexMult;
uniform float rockTexMult;
uniform float fadeOutEnabled;
uniform float distanceFadeOutFactor;
varying float fade;
varying float vHeight;
varying vec4 viewCoords;
varying vec3 diffuseColor;
varying vec3 lightVec;
void main( void )
{
// orginal tex-coord from model
vec2 texCoord0 = vec2(gl_TexCoord[0].st);
// texcoord multiply by groundTexMult
vec2 texCoord1 = vec2(gl_TexCoord[1].st);
// texcoord multiply by rockTexMult
vec2 texCoord2 = vec2(gl_TexCoord[2].st);
// get texel
vec3 ground = texture2D( groundTex, texCoord1 ).rgb;
vec3 splat = texture2D( splatTex, texCoord0 ).rgb;
vec3 rock = texture2D( rockTex, texCoord2 ).rgb;
// fade between rock and ground texture
vec3 color = mix(rock, ground*splat ,vec3(fade));
// generate bump from bumpmap
vec3 norm = texture2D(rockNormalMap, texCoord2).xyz;
// convert values between -1 and 1
norm = (norm - 0.5) * 2.0;
// fade between rock bump and plane terrain
norm = mix(norm, vec3(0.92) ,vec3(fade));
// Calculate the bump value as n dot l (dot product of the normal map and light vec).
float dp = clamp(dot(norm, lightVec), 0.5, 0.7);
// Combine the decal with the bump value and diffuse light from vertex-program
color = color * dp * diffuseColor;
// fog color from distance
float fogDist = clamp((viewCoords.z-gl_Fog.start)*gl_Fog.scale,0.0,1.0);
// distance fade out
float fogFade = 1.0;
if (fadeOutEnabled == 1.0) {
fogFade = 1.0-clamp(pow((viewCoords.z-gl_Fog.start)*gl_Fog.scale,
distanceFadeOutFactor),0.0,1.0);
}
// final compose
gl_FragColor = vec4(mix(color, fogColor , fogDist), fogFade);
}
TerrainRenderPass.java
package de.mistudios.enginex;
import java.net.URL;
import com.jme.image.Texture;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.renderer.pass.Pass;
import com.jme.scene.Spatial;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.GLSLShaderObjectsState;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
/**
* GLSL TerrainShadingPass
*
* @author Lutz Guettler http://www.mi-studios.de
* @version 1.00
* @since 2006-11-16
*/
public class TerrainRenderPass extends Pass {
/**
*
*/
private static final long serialVersionUID = 7022982191313273671L;
private boolean supported = true;
private DisplaySystem display;
private GLSLShaderObjectsState shader;
private CullState cullBackFace;
private TextureState ts;
private AlphaState as;
protected URL verticsShader;
protected URL fragmentShader;
private ColorRGBA skyColor;
private ColorRGBA hazeColor;
private ColorRGBA fogColor;
private String groundTexture;
private String rockTexture;
private String splatTexture;
private String rockNormalMap;
private boolean fadeOutEnabled;
private float distanceFadeOut;
private float detailFadeFactor;
private float groundTexMult;
private float rockTexMult;
private float lightScaleFactor;
private Vector3f lightPosition;
public void resetParameters() {
verticsShader = getClass().getClassLoader().getResource("shader/terrain_dot3_vert.glsl");
fragmentShader = getClass().getClassLoader().getResource("shader/terrain_dot3_frag.glsl");
fadeOutEnabled = true;
distanceFadeOut = 95f;
detailFadeFactor = 25f;
groundTexMult = 51f;
rockTexMult = 51f;
lightScaleFactor = 0.95f;
lightPosition = new Vector3f(2000.0f , 2000.0f , 1000.0f);
skyColor = new ColorRGBA(0.9882f , 0.9609f , 0.8164f, 1.0f);
hazeColor = new ColorRGBA(0.49f , 0.495f , 0.49f, 1.0f);
fogColor = new ColorRGBA(0.4f, 0.4f, 0.4f, 1.0f);
}
public boolean isSupported() {
return supported;
}
public TerrainRenderPass( String groundTexture,
String rockTexture,
String rockNormalMap,
String splatTexture ) {
resetParameters();
this.groundTexture = groundTexture;
this.rockTexture = rockTexture;
this.rockNormalMap = rockNormalMap;
this.splatTexture = splatTexture;
display = DisplaySystem.getDisplaySystem();
shader = display.getRenderer().createGLSLShaderObjectsState();
if( !shader.isSupported() ) {
supported = false;
}
else {
}
cullBackFace = display.getRenderer().createCullState();
cullBackFace.setEnabled( true );
cullBackFace.setCullMode( CullState.CS_BACK );
if( isSupported() ) {
createRenderStates();
shader.load( verticsShader, fragmentShader );
shader.setEnabled( true );
}
else {
supported = false;
}
if( !isSupported() ) {
ts = display.getRenderer().createTextureState();
ts.setEnabled( true );
Texture t1 = TextureManager.loadTexture(
getClass().getClassLoader().getResource( groundTexture ),
Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR );
ts.setTexture( t1, 0 );
t1.setWrap( Texture.WM_WRAP_S_WRAP_T );
}
}
protected void createRenderStates() {
Texture t;
ts = display.getRenderer().createTextureState();
{
ts.setEnabled(true);
}
if (groundTexture!=null) {
t = TextureManager.loadTexture(
getClass().getClassLoader()
.getResource(groundTexture ),
Texture.MM_NEAREST_LINEAR, Texture.FM_LINEAR);
{
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
ts.setTexture(t, 0);
}
}
if (rockTexture!=null) {
t = TextureManager.loadTexture(
getClass().getClassLoader()
.getResource(rockTexture ),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
{
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
ts.setTexture(t, 1);
}
}
if (splatTexture!=null) {
t = TextureManager.loadTexture(
getClass().getClassLoader()
.getResource(splatTexture ),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
{
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
ts.setTexture(t, 2);
}
}
if (rockNormalMap!=null) {
t = TextureManager.loadTexture(
getClass().getClassLoader()
.getResource(rockNormalMap ),
Texture.MM_LINEAR_LINEAR, Texture.FM_LINEAR);
{
t.setWrap(Texture.WM_WRAP_S_WRAP_T);
ts.setTexture(t, 3);
}
}
as = display.getRenderer().createAlphaState();
as.setBlendEnabled( true );
as.setSrcFunction( AlphaState.SB_SRC_ALPHA );
as.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );
as.setEnabled( true );
}
@Override
protected void doUpdate( float tpf ) {
super.doUpdate( tpf );
}
public void setShadingOnSpatial( Spatial spatial ) {
spatial.setRenderState( cullBackFace );
if( isSupported() ) {
spatial.setRenderState( shader );
spatial.setRenderState( ts );
spatial.setRenderQueueMode( Renderer.QUEUE_TRANSPARENT );
spatial.setLightCombineMode( LightState.OFF );
spatial.setRenderState( as );
}
spatial.updateRenderState();
}
/* (non-Javadoc)
* @see com.jme.renderer.pass.Pass#doRender(com.jme.renderer.Renderer)
*/
@Override
protected void doRender(Renderer r) {
if( isSupported() ) {
shader.clearUniforms();
shader.setUniform("groundTex", 0);
shader.setUniform("rockTex", 1);
shader.setUniform("splatTex", 2);
shader.setUniform("rockNormalMap", 3);
shader.setUniform("LightScaleFactor", lightScaleFactor);
shader.setUniform("LightPosition", lightPosition.x,lightPosition.y,lightPosition.z);
shader.setUniform("SkyColor", skyColor.r , skyColor.g , skyColor.b);
shader.setUniform("HazeColor", hazeColor.r , hazeColor.g , hazeColor.b);
shader.setUniform("fogColor", fogColor.r, fogColor.g, fogColor.b);
shader.setUniform("fadeOutEnabled", fadeOutEnabled?1f:0f);
shader.setUniform("distanceFadeOutFactor", distanceFadeOut);
shader.setUniform("detailFadeFactor", detailFadeFactor);
shader.setUniform("groundTexMult", groundTexMult);
shader.setUniform("rockTexMult", rockTexMult);
shader.apply();
}
}
/**
* @return the detailFadeFactor
*/
public float getDetailFadeFactor() {
return this.detailFadeFactor;
}
/**
* @param detailFadeFactor the detailFadeFactor to set
*/
public void setDetailFadeFactor(float detailFadeFactor) {
this.detailFadeFactor = detailFadeFactor;
}
/**
* @return the distanceFadeOut
*/
public float getDistanceFadeOut() {
return this.distanceFadeOut;
}
/**
* @param distanceFadeOut the distanceFadeOut to set
*/
public void setDistanceFadeOut(float distanceFadeOut) {
this.distanceFadeOut = distanceFadeOut;
}
/**
* @return the fadeOutEnabled
*/
public boolean isFadeOutEnabled() {
return this.fadeOutEnabled;
}
/**
* @param fadeOutEnabled the fadeOutEnabled to set
*/
public void setFadeOutEnabled(boolean fadeOutEnabled) {
this.fadeOutEnabled = fadeOutEnabled;
}
/**
* @return the fogColor
*/
public ColorRGBA getFogColor() {
return this.fogColor;
}
/**
* @param fogColor the fogColor to set
*/
public void setFogColor(ColorRGBA fogColor) {
this.fogColor = fogColor;
}
/**
* @return the groundTexMult
*/
public float getGroundTexMult() {
return this.groundTexMult;
}
/**
* @param groundTexMult the groundTexMult to set
*/
public void setGroundTexMult(int groundTexMult) {
this.groundTexMult = groundTexMult;
}
/**
* @return the groundTexture
*/
public String getGroundTexture() {
return this.groundTexture;
}
/**
* @param groundTexture the groundTexture to set
*/
public void setGroundTexture(String groundTexture) {
this.groundTexture = groundTexture;
}
/**
* @return the hazeColor
*/
public ColorRGBA getHazeColor() {
return this.hazeColor;
}
/**
* @param hazeColor the hazeColor to set
*/
public void setHazeColor(ColorRGBA hazeColor) {
this.hazeColor = hazeColor;
}
/**
* @return the lightPosition
*/
public Vector3f getLightPosition() {
return this.lightPosition;
}
/**
* @param lightPosition the lightPosition to set
*/
public void setLightPosition(Vector3f lightPosition) {
this.lightPosition = lightPosition;
}
/**
* @return the lightScaleFactor
*/
public float getLightScaleFactor() {
return this.lightScaleFactor;
}
/**
* @param lightScaleFactor the lightScaleFactor to set
*/
public void setLightScaleFactor(float lightScaleFactor) {
this.lightScaleFactor = lightScaleFactor;
}
/**
* @return the rockNormalMap
*/
public String getRockNormalMap() {
return this.rockNormalMap;
}
/**
* @param rockNormalMap the rockNormalMap to set
*/
public void setRockNormalMap(String rockNormalMap) {
this.rockNormalMap = rockNormalMap;
}
/**
* @return the rockTexMult
*/
public float getRockTexMult() {
return this.rockTexMult;
}
/**
* @param rockTexMult the rockTexMult to set
*/
public void setRockTexMult(int rockTexMult) {
this.rockTexMult = rockTexMult;
}
/**
* @return the rockTexture
*/
public String getRockTexture() {
return this.rockTexture;
}
/**
* @param rockTexture the rockTexture to set
*/
public void setRockTexture(String rockTexture) {
this.rockTexture = rockTexture;
}
/**
* @return the skyColor
*/
public ColorRGBA getSkyColor() {
return this.skyColor;
}
/**
* @param skyColor the skyColor to set
*/
public void setSkyColor(ColorRGBA skyColor) {
this.skyColor = skyColor;
}
/**
* @return the splatTexture
*/
public String getSplatTexture() {
return this.splatTexture;
}
/**
* @param splatTexture the splatTexture to set
*/
public void setSplatTexture(String splatTexture) {
this.splatTexture = splatTexture;
}
}