Sunday, October 1, 2017

libgdx - 2d water animation is jagged and not smooth


As a solution for this question I implemented the shader with a test program:


import com.badlogic.gdx.ApplicationAdapter
import com.badlogic.gdx.Gdx

import com.badlogic.gdx.backends.lwjgl.LwjglApplication
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.Sprite
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.ShaderProgram

class ShaderTestApp : ApplicationAdapter() {
lateinit var batch: SpriteBatch

lateinit var noiseTexture: Texture
lateinit var sprite: Sprite
lateinit var shaderProgram: ShaderProgram

private val vertexShaderString = """
attribute vec4 a_position;
attribute vec4 a_color; //required by libgdx
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;


varying vec4 v_color;
varying vec2 v_texCoords;

void main() {
v_color = a_color;
v_texCoords = a_texCoord0;
gl_Position = u_projTrans * a_position;
}
""".trimIndent()


private val fragmentShaderString = """
#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_color;
varying vec2 v_texCoords;

uniform sampler2D u_noise;

uniform sampler2D u_texture;
uniform mat4 u_projTrans;

uniform float u_noise_scale;
uniform vec2 u_noise_scroll_velocity;
uniform float u_distortion;
uniform float u_time;

void main() {
vec2 waveUV = v_texCoords * u_noise_scale;

vec2 travel = u_noise_scroll_velocity * u_time;
vec2 uv = v_texCoords;
uv = uv + (u_distortion * (texture2D(u_noise, waveUV + travel).rgb - 0.5));
waveUV += 0.2;
uv = uv + (u_distortion * (texture2D(u_noise, waveUV - travel).rgb - 0.5));
vec3 color = texture2D(u_texture, uv).rgb;
gl_FragColor = vec4(color, 1.0);
}
""".trimIndent()


override fun create() {
batch = SpriteBatch()
val img = Texture("background/water-surface-reflection-withBg.png")
img.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat)
noiseTexture = Texture("background/gradient.png")
noiseTexture.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat)
sprite = Sprite(img)
sprite.setSize(Gdx.graphics.width.toFloat(), Gdx.graphics.height.toFloat())

shaderProgram = ShaderProgram(vertexShaderString, fragmentShaderString)

if (!shaderProgram.isCompiled) {
println(shaderProgram.log)
}
}

var time = 0f
override fun render() {
time += Gdx.graphics.deltaTime
Gdx.gl.glClearColor(1f, 0f, 0f, 1f)
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT)


batch.begin()
noiseTexture.bind()
shaderProgram.setUniformf("u_noise_scale", 0.1f)
shaderProgram.setUniform2fv("u_noise_scroll_velocity", floatArrayOf(.006f, .007f), 0, 2)
shaderProgram.setUniformf("u_distortion", 0.04f)
shaderProgram.setUniformf("u_time", time)
batch.shader = shaderProgram
batch.draw(sprite, sprite.x, sprite.y, sprite.width, sprite.height)
batch.end()

}
}

object ShaderTestLauncher {
@JvmStatic
fun main(arg: Array) {
val config = LwjglApplicationConfiguration()
config.samples = 2
config.width = 640
config.height = 640

LwjglApplication(ShaderTestApp(), config)
}
}

Which looks like this:


enter image description here



Answer



After an input from DMGregory I added the following lines after instantiating all textures:


img.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
noiseTexture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)


It looks perfect now.


Result as requested:


enter image description here


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...