在GLSL Shader中,如何平滑地移动图像'没有'擦洗'

时间:2017-03-04 18:26:19

标签: java glsl shader processing

特别是我正在使用一个使用GLSL着色器的处理Java示例(它被称为InfiniteTiles)。原始草图实际上只是移动平铺图像。

我有一个名为time的统一变量,我在java中调用。

tileShader.set("time", millis() / 1000.0);

现在在片段着色器中有一个代码部分

vec2 pos = gl_FragCoord.xy - vec2(TILES_COUNT_X * time);
vec2 p = (resolution - TILES_COUNT_X * pos) / resolution.x;
vec3 col = texture2D (tileImage, p).xyz;

我在java代码中尝试做的是设置时间变量,以便我可以增加和减少图像滚动的速度。

我写了这个

float t =millis() / 1000.0;
float pctX = map (mouseX, 0, width, 0, 1);
tileShader.set("time", t*pctX);

当我移动鼠标时,整个图像会向左或向右快速移动,具体取决于我移动的位置,就好像它的擦拭一样'擦拭'图片。当我停止移动鼠标时,它将以所需的速度移动。

我想避免这种'擦洗'效果并使图像滚动速度随着鼠标移动而平滑过渡。

通常我只需在java中绘制图像并滚动它就能完成这样的事情,但我认为我并不了解glsl在图形卡上实现相同效果的方式。

任何帮助表示赞赏。

示例中的完整处理代码:

//-------------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//-------------------------------------------------------------

PImage tileTexture;
PShader tileShader;

void setup() {
  size(640, 480, P2D);
  textureWrap(REPEAT);
  tileTexture = loadImage("penrose.jpg");
  loadTileShader();
}

void loadTileShader() {  
  tileShader = loadShader("scroller.glsl");
  tileShader.set("resolution", float(width), float(height));  
  tileShader.set("tileImage", tileTexture);
}

void draw() {
  tileShader.set("time", millis() / 1000.0);
  shader(tileShader);                    
  rect(0, 0, width, height);
}

完整着色器代码

//---------------------------------------------------------
// Display endless moving background using a tile texture.
// Contributed by martiSteiger
//---------------------------------------------------------

uniform float time;
uniform vec2 resolution;
uniform sampler2D tileImage;

#define TILES_COUNT_X 4.0

void main() {
  vec2 pos = gl_FragCoord.xy - vec2(4.0 * time);
  vec2 p = (resolution - TILES_COUNT_X * pos) / resolution.x;
  vec3 col = texture2D (tileImage, p).xyz;
  gl_FragColor = vec4 (col, 1.0);
}

1 个答案:

答案 0 :(得分:1)

叹息......它比我想象的要简单一些。 JeremyDouglass在这里提供的答案

https://forum.processing.org/two/discussion/comment/90488

溶液:

“此问题并非特定于着色器 - 如果您使用img()执行此操作,则会遇到同样的问题。您无法以这种方式进行时钟数学运算。乘以millis()乘以任何内容将始终创建缩放效果 - 在这种情况下将始终创建所谓的“擦洗”。例如,如果更改乘数,则10秒突然变为15。

相反,为了改变时钟在未来的变化速度而不是改变它到目前为止的进度,将自己的时钟变量与millis()分开,并改变步长(使用加法,而不是乘法)每个画框。现在时钟前进的速度会改变,但基本偏移(最后一个时钟时间)不会跳转,因为原始值没有被缩放(乘以)。“