I’ve rarely used GLSL shaders before and am trying to make some real-ish looking water in JMonkeyEngine using sine waves and GLSL shaders. I used f(x,t)=asin(xw+t*p) where x is the coordinate, w is frequency a is amplitude, t is time and p is phase shift, I then took 3 of these and took the sum to get a final height value for each vertex coordinate. My fragment Shader is very simple and just makes everything blue for now (I plan on adding some stuff later when it renders properly). I was too lazy (and didn’t have the knowledge of GLSL) to write this on my own so I asked chatGPT to write it.
This is the Vertex shader it spat out.
// Input vertex position from vertex array
attribute vec3 inPosition;
// Uniform variables for wave parameters
uniform float g_Time; // Time variable for animation
uniform float amplitude1;
uniform float frequency1;
uniform float phase1;
uniform float amplitude2;
uniform float frequency2;
uniform float phase2;
uniform float amplitude3;
uniform float frequency3;
uniform float phase3;
// Output position for the fragment shader
varying vec3 fragPos;
void main()
{
// Calculate the wave offsets for x and y axes
float wave1 = amplitude1 * sin(inPosition.x * frequency1 + g_Time * phase1);
float wave2 = amplitude2 * sin(inPosition.y * frequency2 + g_Time * phase2);
float wave3 = amplitude3 * sin(inPosition.x * frequency3 + inPosition.y * frequency3 + g_Time * phase3);
// Sum the wave offsets
float wave = wave1 + wave2 + wave3;
// Apply the wave offset to the z-coordinate of the vertex position
vec3 pos = inPosition;
pos.y += wave; // Assuming y is the up-axis in a 3D space
// Set the final vertex position
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);
// Pass the position to the fragment shader
fragPos = pos;
}
I implemented it like this in my code
public void setUpWater(){
waterGeom = new Geometry("waterGeo", new Box(10,1,10));
waterGeom.setLocalTranslation(0,-10,0);
waterMaterial = new Material(assetManager, "MatDefs/water.j3md");
waterMaterial.setFloat("amplitude1", 0.5f);
waterMaterial.setFloat("frequency1", 2.0f);
waterMaterial.setFloat("phase1", 1.0f);
waterMaterial.setFloat("amplitude2", 0.3f);
waterMaterial.setFloat("frequency2", 1.5f);
waterMaterial.setFloat("phase2", 0.8f);
waterMaterial.setFloat("amplitude3", 0.2f);
waterMaterial.setFloat("frequency3", 1.0f);
waterMaterial.setFloat("phase3", 1.2f);
waterMaterial.setColor("Color", ColorRGBA.Blue);
waterGeom.setMaterial(waterMaterial);
rootNode.attachChild(waterGeom);
}
// some more of my code
public void simpleUpdate(float tpf) {
float time = getTimer().getTimeInSeconds();
waterMaterial.setFloat("g_Time", time);
//rest of my update function
}
water.j3md
MaterialDef Water {
MaterialParameters {
Float g_Time
Float amplitude1
Float frequency1
Float phase1
Float amplitude2
Float frequency2
Float phase2
Float amplitude3
Float frequency3
Float phase3
}
Technique {
VertexShader GLSL100: Shaders/water.vert
FragmentShader GLSL100: Shaders/water.frag
WorldParameters {
WorldViewProjectionMatrix
}
}
}
is there anything I am doing wrong or that says why this doesn’t render? I do call setUpWater() in my simpleInitApp() function
all help is appreciated!