Hello everyone,
I'm here looking for help with an issue I've been losing hair from.
I am currently making a game in Java & lwjgl and everything have so far gone OK but I feel like I've hit a wall with this problem I have.
I am trying to do bouyancy physics for my FFT ocean so for that I need to be able to get the height from a world position. Easy thing I thought since when I generate the ocean I have a texture "dy" that is pretty much the height of all the waves. Here is the code I currently have to get the height
public float getHeight(Vector3f worldPosition, float offset) {
// Ignore y coordinate
Vector3f wp = new Vector3f(worldPosition.x, 0, worldPosition.z);
Vector2f uv = new Vector2f(wp.x, wp.z);
float x = uv.x;
float y = uv.y;
int resolution = fft.getResolution();
int size = resolution * resolution;
// We create a floatbuffer to store all pixels from the DY texture
FloatBuffer fb = BufferUtils.createFloatBuffer(size);
glBindTexture(GL_TEXTURE_2D, fft.getDy().getId());
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, fb);
// get the val from the x y coordinate
float val = (x + y * resolution);
// Keep it at a positive value
val = Math.abs(val);
// And keep the value within the size of the buffer
val %= size;
// Get the raw height
float r = fb.get((int)val);
// Multiply it by 6 because thats the scale we use in the shader (Not uniform yet)
float height = r * 6;
return height;
}
please ignore redundant code and bad practices, I will optimize everything later I promise
Some extra info
-It *works* when the world position is 0,0,0 and I get index 0 (duh)
-The resolution of the texture is 512 and is repeated * 50
-The ocean is based on the videos from Oreon Engine
-The ocean is scaled by 6000 and moved to -3000 to be centered around 0,0,0
After some more researching I found a youtube video where the he got the height from all three textures (dx, dy, dz). I tried this aswell but still feel kinda lost.
My brain have a hard time with Floatbuffers.
New functions
public float getHeight(Vector3f worldPosition) {
return getWaterHeight(worldPosition);
}
private float getWaterHeight(Vector3f position) {
Vector3f p = new Vector3f(position);
Vector3f displacement = getWaterDisplacement(p);
p = new Vector3f(position);
Vector3f d = new Vector3f(displacement);
displacement = getWaterDisplacement(p.sub(d));
p = new Vector3f(position);
d = new Vector3f(displacement);
displacement = getWaterDisplacement(p.sub(d));
p = new Vector3f(position);
d = new Vector3f(displacement);
return getWaterDisplacement(p.sub(d)).y;
}
private Vector3f getWaterDisplacement(Vector3f position) {
Vector3f p = new Vector3f(position.x, 0, position.z);
int index = (int)p.x + (int)p.z;
if(index < 0 || index > (fft.getResolution() * fft.getResolution())) {
System.err.println("Invalid index: " + index);
return new Vector3f();
}
float y = fbY.get(index);
float x = fbX.get(index);
float z = fbZ.get(index);
return new Vector3f(x, y, z);
}
Also I store the textures inside floatbuffers every frame for testing
fbY.clear();
glBindTexture(GL_TEXTURE_2D, fft.getDy().getId());
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, fbY);
fbX.clear();
glBindTexture(GL_TEXTURE_2D, fft.getDx().getId());
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, fbX);
fbZ.clear();
glBindTexture(GL_TEXTURE_2D, fft.getDz().getId());
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, fbZ);
I appreciate any help or suggestions. Thanks!