How to create/use own shaders (parallax)

Hi, i tried the lighting MatDef from JME, but the parallax function doesn’t work (or work well).

It looks a but shitty^^, i dont know if i make some mistakes by using it, or if it doesn’t work generally??

If it works to you, you may give me a little tut how to use it…



But the main question is: How to use own shaders / shaders from other programs?



I downloadet a program where the parallax shader looked very well und tryed to use that shaders, but i realy dont know how to use it in JME



I tried these:

save the .vert / .frag in Shaders



vert:

#version 110



varying vec3 lightDir;

varying vec3 halfVector;



void main()

{

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

gl_TexCoord[0] = gl_MultiTexCoord0;



vec3 n = normalize(gl_NormalMatrix * gl_Normal);

vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz);

vec3 b = cross(n, t) * gl_MultiTexCoord1.w;



mat3 tbnMatrix = mat3(t.x, b.x, n.x,

t.y, b.y, n.y,

t.z, b.z, n.z);



lightDir = gl_LightSource[0].position.xyz;

lightDir = tbnMatrix * lightDir;



halfVector = gl_LightSource[0].halfVector.xyz;

halfVector = tbnMatrix * halfVector;

}


frag:
#version 110

uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D heightMap;

uniform bool enableParallax;
uniform float scale;
uniform float bias;

varying vec3 lightDir;
varying vec3 halfVector;

void main()
{
vec2 newTexCoord;
vec3 h = normalize(halfVector);

if (enableParallax == true)
{
float height = texture2D(heightMap, gl_TexCoord[0].st).r;

height = height * scale + bias;
newTexCoord = gl_TexCoord[0].st + (height * h.xy);
}
else
{
newTexCoord = gl_TexCoord[0].st;
}

vec3 n = normalize(texture2D(normalMap, newTexCoord).rgb * 2.0 - 1.0);
vec3 l = normalize(lightDir);

float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL;
vec4 specular = gl_FrontLightProduct[0].specular * power;
vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;

gl_FragColor = color * texture2D(colorMap, newTexCoord);
}
and wrote this as MatDef, and i think heres the problem, because i dont know how t write a good Matdef:
MaterialDef pn {

MaterialParameters {
Texture2D ColorMap
Texture2D NormalMap
Texture2D HeightMap
Boolean EnableParallax;
Float Scale;
Float Bias;
Vector3 LightDir;
Vector3 HalfVector;

}

Technique {
VertexShader GLSL110: Shaders/pn.vert
FragmentShader GLSL110: Shaders/pn.frag

WorldParameters {
WorldViewProjectionMatrix
}

Defines {
colorMap : ColorMap
normalMap : NormalMap
heightMap : HeightMap
scale : Scale
bias : bias
lightDir : LightDir
halfVector : HalfVector

}

}

}

And wrote this in the program:
Box redBox = new Box(new Vector3f(0,2.5f,0), 1,1,1);
Geometry redBGeo = new Geometry("Box2", redBox);

TangentBinormalGenerator.generate(redBox);

Material bumpMat = new Material(assetManager, "MatDefs/pn.j3md");
bumpMat.setTexture("HeightMap", assetManager.loadTexture("Textures/bricks_DISP.jpg"));
bumpMat.setTexture("NormalMap", assetManager.loadTexture("Textures/bricks_normal.jpg"));
bumpMat.setTexture("ColorMap", assetManager.loadTexture("Textures/bricks.jpg"));
bumpMat.setBoolean("EnableParallax", true);
bumpMat.setFloat("Scale", 1f);
bumpMat.setFloat("Bias", 1f);
bumpMat.setVector3("LightDir", new Vector3f(1,-1,-2).normalize());
bumpMat.setVector3("HalfVector", new Vector3f(1,-1,-2).normalize());

redBGeo.setMaterial(bumpMat);
//redBGeo.setShadowMode(ShadowMode.CastAndReceive);

rootNode.attachChild(redBGeo);

As result i get this error:

28.06.2011 15:56:16 com.jme3.app.Application handleError
SCHWERWIEGEND: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Shaders/pn.vert, defines, type=Vertex] error:ERROR: 0:10: '1' : syntax error parse error

so i don't know how to write the matDef, or if theres a problem with the shader.
So please help me, and may give me a tut how to write a matdef file^^

And sorry for my bad english, its not my mother language :)

JME’s parallax support works. Mythruna uses a cut and pasted version for nearly all of its textures and they definitely have parallax bump mapping. Maybe we can start by figuring out why it is not working in your case.



As far as your shader goes, it’s complaining about the first line. Try taking out the #vertex 110 line. There will probably be other problems, though.

ok read somthing about a problem in Lighting.j3md where the parallaxMap is used with swaped coordinates.

So i had a look on the shader of the intern Lighting shaders, and changed for eq. the height scale, and i sow the right effects^^.

So the internal parallax shader of the Lighting.j3md works now, but doesn’t look so well as some other parallax shaders i found in the net. And if you look in an angle of ca 170° on the cube the parallax effect looses on strangth instead of giving a good 3d feeling.

But im happy that i get it to work^^



But all in all it would be nice if i get the shader i postet above to work.

I deleted the line with #version 110 and i get the error here in between these lines in the .vert :

gl_TexCoord[0] = gl_MultiTexCoord0;



vec3 n = normalize(gl_NormalMatrix * gl_Normal);

Finally i got it (to implement the shaders i found in the internet):

But it looks a bit strange, like the x and y coords are swaped, maybe someone can look over the code?

http://i.imgur.com/4P9Q7.jpg

here is the new code:

[java]

package mygame;

import com.jme3.app.SimpleApplication;

import com.jme3.material.Material;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.RenderManager;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.light.DirectionalLight;

import com.jme3.light.PointLight;

import com.jme3.renderer.queue.RenderQueue.ShadowMode;

import com.jme3.util.TangentBinormalGenerator;

import com.jme3.shadow.BasicShadowRenderer;

import com.jme3.shadow.PssmShadowRenderer;

public class test extends SimpleApplication {

public static void main(String[] args) {

test app = new test();

app.start();

}

@Override

public void simpleInitApp() {

initBox2();

initLight();

}

public void initBox2(){

Box redBox = new Box(new Vector3f(0,2.5f,0), 1,1,1);

Geometry redBGeo = new Geometry(“Box2”, redBox);

TangentBinormalGenerator.generate(redBox);

Material bumpMat = new Material(assetManager, “MatDefs/pn.j3md”);

bumpMat.setTexture(“HeightMap”, assetManager.loadTexture(“Textures/height_map.jpg”));

bumpMat.setTexture(“NormalMap”, assetManager.loadTexture(“Textures/normal_map.jpg”));

bumpMat.setTexture(“ColorMap”, assetManager.loadTexture(“Textures/color_map.jpg”));

bumpMat.setBoolean(“EnableParallax”, true);

bumpMat.setFloat(“Scale”, 0.04f);

bumpMat.setFloat(“Bias”, -0.03f);

redBGeo.setMaterial(bumpMat);

redBGeo.setShadowMode(ShadowMode.CastAndReceive);

rootNode.attachChild(redBGeo);

}

public void initLight(){

DirectionalLight sun = new DirectionalLight();

sun.setDirection(new Vector3f(1,-1,-2).normalizeLocal());

sun.setColor(ColorRGBA.White);

rootNode.addLight(sun);

}

@Override

public void simpleUpdate(float tpf) {

//TODO: add update code

}

@Override

public void simpleRender(RenderManager rm) {

//TODO: add render code

}

}

[/java]

the vert :

[java]

//vert

uniform mat4 g_WorldViewProjectionMatrix;



attribute vec3 inPosition;

attribute vec4 inTexCoord;

attribute vec4 inTexCoord1;

uniform mat3 g_NormalMatrix;

attribute vec3 inNormal;

varying vec3 lightDir;

varying vec3 halfVector;

void main(){

gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);

gl_TexCoord[0] = inTexCoord;

vec3 n = normalize(g_NormalMatrix * inNormal);

vec3 t = normalize(g_NormalMatrix * inTexCoord1.xyz);

vec3 b = cross(n, t) * inTexCoord1.w;

mat3 tbnMatrix = mat3(t.x, b.x, n.x,

t.y, b.y, n.y,

t.z, b.z, n.z);

lightDir = gl_LightSource[0].position.xyz;

lightDir = tbnMatrix * lightDir;

halfVector = gl_LightSource[0].halfVector.xyz;

halfVector = tbnMatrix * halfVector;

}

[/java]

frag:

[java]

//was

uniform sampler2D m_ColorMap;

uniform sampler2D m_NormalMap;

uniform sampler2D m_HeightMap;

uniform float m_Bias;

uniform bool m_EnableParallax;

uniform float m_Scale;

varying vec3 lightDir;

varying vec3 halfVector;

void main()

{

vec2 newTexCoord;

vec3 h = normalize(halfVector);

if (m_EnableParallax == true)

{

float height = texture2D(m_HeightMap, gl_TexCoord[0].st).r;

height = height * m_Scale + m_Bias;

newTexCoord = gl_TexCoord[0].st + (height * h.xy);

}

else

{

newTexCoord = gl_TexCoord[0].st;

}

vec3 n = normalize(texture2D(m_NormalMap, newTexCoord).rgb * 2.0 - 1.0);

vec3 l = normalize(lightDir);

float nDotL = max(0.0, dot(n, l));

float nDotH = max(0.0, dot(n, h));

float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

vec4 ambient = gl_FrontLightProduct[0].ambient;

vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL;

vec4 specular = gl_FrontLightProduct[0].specular * power;

vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;

gl_FragColor = color * texture2D(m_ColorMap, newTexCoord);

}

[/java]

and the .j3md

[java]

MaterialDef pn {

MaterialParameters {

Texture2D ColorMap

Texture2D NormalMap

Texture2D HeightMap

Boolean EnableParallax;

Float Scale;

Float Bias;

Vector3 LightDir;

Vector3 HalfVector;

}

Technique {

VertexShader GLSL110: Shaders/pn.vert

FragmentShader GLSL110: Shaders/pn.frag

WorldParameters {

WorldViewProjectionMatrix

NormalMatrix

WorldViewMatrix

ViewMatrix

CameraPosition

WorldMatrix

}

Defines {

colorMap : ColorMap

normalMap : NormalMap

heightMap : HeightMap

scale : Scale

bias : Bias

enableParallax :EnableParallax

}

}

}

[/java]

i think it gives a bit bether results (if it works correctly^^) as the lighting or its my imagination ^^

have your tried flipping the texture ?



use assetManager.loadMaterial(“Materials/bumpMat.j3m”);



Material bumpMat : “MatDefs/pn.j3md” {

MaterialParameters {

EnableParallax: true

Scale: 0.04f

Bias: -0.03f

HeightMap: Textures/height_map.jpg

ColorMap: Flip Textures/color_map.jpg

NormalMap: Flip Textures/normal_map.jpg

}

}

Looks to me like a tangent vector problem. JME’s shader will behave this way too if the tangent vectors aren’t setup right.



In both faces of the cube picture the effect is inverted in different ways.



Really, there are only so many ways to displace texture coordinates to fake bumps. Can you show me the 170 degree problem with the standard lighting shader? Personally, I get really good looking bumps from all angles.