2
\$\begingroup\$

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<String>) {
    val config = LwjglApplicationConfiguration()
    config.samples = 2
    config.width = 640
    config.height = 640
    LwjglApplication(ShaderTestApp(), config)
  }
}

Which looks like this:

enter image description here

\$\endgroup\$
3
  • 1
    \$\begingroup\$ It looks like you might be using nearest / point filtering on the noise texture, instead of bilinear. Can you confirm? \$\endgroup\$
    – DMGregory
    Sep 23, 2018 at 21:14
  • \$\begingroup\$ It was set to Nearest (GL_NEAREST) but replacing it with Linear (GL_LINEAR) but it had no effect on the noise texture. Setting it on the main texture hat a BIG impact, it looks perfect now. \$\endgroup\$
    – morpheus05
    Sep 23, 2018 at 21:31
  • 1
    \$\begingroup\$ Sweet! Feel free to write up the changes you made as an answer. :) \$\endgroup\$
    – DMGregory
    Sep 23, 2018 at 21:32

1 Answer 1

2
\$\begingroup\$

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

\$\endgroup\$
2
  • 1
    \$\begingroup\$ For the sake of completeness, you might want to add an animated gif of the result :) \$\endgroup\$
    – Vaillancourt
    Sep 24, 2018 at 0:26
  • \$\begingroup\$ ok, I added an gif with the result \$\endgroup\$
    – morpheus05
    Sep 24, 2018 at 19:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .