How to implements a custom GLSL Shader?

Hi all. Recently I by a question puzzle for a long time, that is how to implements a custom GLSL Shader?

I knew the jMonkeyEngine3 is a Shader Base Engine, and provide many fit shader(work in j3md file).Now I also would like to use j3md file and tools generated by the standard GLSL *.vert and *.frag file to implement custom Shader.

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_shaders

I have read this tutorial in detail.

I should be in accordance with this step to operate, but always unsuccess.

So…I need you help…

there are two file(Glass.frag;Glass.vert. from http://www.3dshaders.com).

What should I do to make them work correctly under the JME3?

like this:


Glass.frag
//
// Fragment shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);
uniform vec3 BaseColor;
uniform float Depth;
uniform float MixRatio;
// need to scale our framebuffer - it has a fixed width/height of 2048
uniform float FrameWidth;
uniform float FrameHeight;
uniform sampler2D EnvMap;
uniform sampler2D RefractionMap;
varying vec3 Normal;
varying vec3 EyeDir;
varying vec4 EyePos;
varying float LightIntensity;
void main (void)
{
// Compute reflection vector
vec3 reflectDir = reflect(EyeDir, Normal);
// Compute altitude and azimuth angles
vec2 index;
index.y = dot(normalize(reflectDir), Yunitvec);
reflectDir.y = 0.0;
index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;
// Translate index values into proper range
if (reflectDir.z >= 0.0)
index = (index + 1.0) * 0.5;
else
{
index.t = (index.t + 1.0) * 0.5;
index.s = (-index.s) * 0.5 + 1.0;
}
// if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
// if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and
// that's OK, because we've set the texture to wrap.
// Do a lookup into the environment map.
vec3 envColor = vec3 (texture2D(EnvMap, index));
// calc fresnels term. This allows a view dependant blend of reflection/refraction
float fresnel = abs(dot(normalize(EyeDir), Normal));
fresnel *= MixRatio;
fresnel = clamp(fresnel, 0.1, 0.9);
// calc refraction
vec3 refractionDir = normalize(EyeDir) - normalize(Normal);
// Scale the refraction so the z element is equal to depth
float depthVal = Depth / -refractionDir.z;
// perform the div by w
float recipW = 1.0 / EyePos.w;
vec2 eye = EyePos.xy * vec2(recipW);
// calc the refraction lookup
index.s = (eye.x + refractionDir.x * depthVal);
index.t = (eye.y + refractionDir.y * depthVal);
// scale and shift so we're in the range 0-1
index.s = index.s / 2.0 + 0.5;
index.t = index.t / 2.0 + 0.5;
// as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture,
// so we clamp before scaling to fit
float recip1k = 1.0 / 2048.0;
index.s = clamp(index.s, 0.0, 1.0 - recip1k);
index.t = clamp(index.t, 0.0, 1.0 - recip1k);
// scale the texture so we just see the rendered framebuffer
index.s = index.s * FrameWidth * recip1k;
index.t = index.t * FrameHeight * recip1k;
vec3 RefractionColor = vec3 (texture2D(RefractionMap, index));
// Add lighting to base color and mix
vec3 base = LightIntensity * BaseColor;
envColor = mix(envColor, RefractionColor, fresnel);
envColor = mix(envColor, base, 0.2);
gl_FragColor = vec4 (envColor, 1.0);
}

Glass.vert
//
// Vertex shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
varying vec3 Normal;
varying vec3 EyeDir;
varying vec4 EyePos;
varying float LightIntensity;
uniform vec3 LightPos;
void main(void)
{
gl_Position = ftransform();
Normal = normalize(gl_NormalMatrix * gl_Normal);
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
EyeDir = pos.xyz;
EyePos = gl_ModelViewProjectionMatrix * gl_Vertex;
LightIntensity = max(dot(normalize(LightPos - EyeDir), Normal), 0.0);
}

This will help you: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_shaders?do=export_xhtmlbody

There is a difference between attributes in JME and OpenGL.

[xml]GLSL 1.2 attributes JME3 equivalent

gl_Vertex inPosition

gl_Normal inNormal

gl_Color inColor

gl_MultiTexCoord0 inTexCoord

gl_ModelViewMatrix g_WorldViewMatrix

gl_ProjectionMatrix g_ProjectionMatrix

gl_ModelViewProjectionMatrix g_WorldViewProjectionMatrix

gl_NormalMatrix g_NormalMatrix[/xml]

Also, have a look at Lighting shader… how it works… it’s located in jme library.

Or have a look at mine: Google Code Archive - Long-term storage for Google Code Project Hosting.

mifth said:
This will help you: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_shaders?do=export_xhtmlbody
There is a difference between attributes in JME and OpenGL.
[xml]GLSL 1.2 attributes JME3 equivalent
gl_Vertex inPosition
gl_Normal inNormal
gl_Color inColor
gl_MultiTexCoord0 inTexCoord
gl_ModelViewMatrix g_WorldViewMatrix
gl_ProjectionMatrix g_ProjectionMatrix
gl_ModelViewProjectionMatrix g_WorldViewProjectionMatrix
gl_NormalMatrix g_NormalMatrix[/xml]
Also, have a look at Lighting shader... how it works... it's located in jme library.
Or have a look at mine: http://code.google.com/p/jme-glsl-shaders/

Thanks..
Please help me find this Shader issue.

glass.j3md

[xml]MaterialDef glass {
MaterialParameters {

Vector3 LightPos
Vector3 BaseColor
Float Depth
Float MixRatio
Float FrameWidth
Float FrameHeight
Texture2D EnvMap
Texture2D RefractionMap
}
Technique {

VertexShader GLSL120 : Common/MatDefs/Misc/Glass.vert
FragmentShader GLSL120 : Common/MatDefs/Misc/Glass.frag

WorldParameters {
WorldViewProjectionMatrix
NormalMatrix
WorldViewMatrix
}

RenderState {

}
}
}[/xml]

Glass.vert

[xml]//
// Vertex shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

uniform mat4 g_WorldViewProjectionMatrix;
uniform mat4 g_WorldViewMatrix;
uniform mat3 g_NormalMatrix;
uniform mat4 g_ViewMatrix;

varying vec3 Normal;
varying vec3 EyeDir;
varying vec4 EyePos;
varying float LightIntensity;

uniform vec3 m_LightPos;

attribute vec3 inPosition;
attribute vec3 inNormal;

void main(void)
{
gl_Position = ftransform();
Normal = normalize(g_NormalMatrix * inNormal);
vec4 pos = g_WorldViewMatrix * vec4(inPosition, 1.0);
EyeDir = pos.xyz;
EyePos = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
LightIntensity = max(dot(normalize(m_LightPos - EyeDir), Normal), 0.0);
}[/xml]

Glass.frag


[xml]//
// Fragment shader for environment mapping with an
// equirectangular 2D texture and refraction mapping
// with a background texture blended together using
// the fresnel terms
//
// Author: Jon Kennedy, based on the envmap shader by John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//

const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);

uniform vec3 m_BaseColor;
uniform float m_Depth;
uniform float m_MixRatio;

// need to scale our framebuffer - it has a fixed width/height of 2048
uniform float m_FrameWidth;
uniform float m_FrameHeight;

uniform sampler2D m_EnvMap;
uniform sampler2D m_RefractionMap;

varying vec3 Normal;
varying vec3 EyeDir;
varying vec4 EyePos;
varying float LightIntensity;

void main (void)
{
// Compute reflection vector
vec3 reflectDir = reflect(EyeDir, Normal);

// Compute altitude and azimuth angles

vec2 index;

index.y = dot(normalize(reflectDir), Yunitvec);
reflectDir.y = 0.0;
index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;

// Translate index values into proper range

if (reflectDir.z >= 0.0)
index = (index + 1.0) * 0.5;
else
{
index.t = (index.t + 1.0) * 0.5;
index.s = (-index.s) * 0.5 + 1.0;
}

// if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
// if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and
// that's OK, because we've set the texture to wrap.

// Do a lookup into the environment map.

vec3 envColor = vec3 (texture2D(m_EnvMap, index));

// calc fresnels term. This allows a view dependant blend of reflection/refraction
float fresnel = abs(dot(normalize(EyeDir), Normal));
fresnel *= m_MixRatio;
fresnel = clamp(fresnel, 0.1, 0.9);

// calc refraction
vec3 refractionDir = normalize(EyeDir) - normalize(Normal);

// Scale the refraction so the z element is equal to depth
float depthVal = m_Depth / -refractionDir.z;

// perform the div by w
float recipW = 1.0 / EyePos.w;
vec2 eye = EyePos.xy * vec2(recipW);

// calc the refraction lookup
index.s = (eye.x + refractionDir.x * depthVal);
index.t = (eye.y + refractionDir.y * depthVal);

// scale and shift so we're in the range 0-1
index.s = index.s / 2.0 + 0.5;
index.t = index.t / 2.0 + 0.5;

// as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture,
// so we clamp before scaling to fit
float recip1k = 1.0 / 2048.0;
index.s = clamp(index.s, 0.0, 1.0 - recip1k);
index.t = clamp(index.t, 0.0, 1.0 - recip1k);

// scale the texture so we just see the rendered framebuffer
index.s = index.s * m_FrameWidth * recip1k;
index.t = index.t * m_FrameHeight * recip1k;

vec3 RefractionColor = vec3 (texture2D(m_RefractionMap, index));

// Add lighting to base color and mix
vec3 base = LightIntensity * m_BaseColor;
envColor = mix(envColor, RefractionColor, fresnel);
envColor = mix(envColor, base, 0.2);

gl_FragColor = vec4 (envColor, 1.0);
}[/xml]

test

[java]

import jme3test.model.shape.*;
import com.jme3.app.SimpleApplication;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;

public class TestBox extends SimpleApplication {

public static void main(String[] args){
TestBox app = new TestBox();
app.start();
}

@Override
public void simpleInitApp() {

DirectionalLight dl = new DirectionalLight();
dl.setColor(ColorRGBA.White);
dl.setDirection(new Vector3f(-1,-1,-1));
rootNode.addLight(dl);

Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom = new Geometry("Box", b);

Material mat = new Material(assetManager, "Common/MatDefs/Misc/glass.j3md");
mat.setVector3("LightPos", new Vector3f(0.0f, 0.0f, 4.0f));
mat.setVector3("BaseColor", new Vector3f(0.4f, 0.4f, 1.0f));
mat.setFloat("Depth", 0.1f);
mat.setFloat("MixRatio", 1.0f);
mat.setFloat("FrameWidth", 255.0f);
mat.setFloat("FrameHeight", 255.0f);
mat.setTexture("EnvMap", assetManager.loadTexture("Interface/Fonts/Default.png"));
mat.setTexture("RefractionMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));



geom.setMaterial(mat);
rootNode.attachChild(geom);
}

}

[/java]
The program starts, did not see anything..

Well…if the screen is black there might be a compilation error in the shader, look in the console output, there should be the entire code that fail to compile with the errors at the end of the stack trace.



Also, you know that lighting material supports reflection and refraction right?