如何用 three.js 的 GLSL 着色器置换平面上的 2D 纹理?

How can a 2D texture on a plane be displaced with a GLSL shader with three.js?

假设我们有一个简单的 PlaneBufferGeometry,应用了如下纹理:

知道材质将使用 ShaderMaterial,要像这样渲染纹理需要进行什么操作通过从第一个状态变形到结果状态 通过提供给片段着色器的某种 uProgress/uTime 制服?

我希望通过开始在 glsl 中编写此类操作,我将能够实现更高级的效果(如 2D 火焰动画)。

你可以按照

的方式做一些事情
vec2 mySkewUv = vec2(vUv.x + vUv.y , vUv.y);

从@pailhead 的回答开始,我能够创建最终的动画代码如下:

除了由 three.js 传递的基本制服和属性外,我们还传递时间(自开始动画循环以来)和一个 uMap,它是使用纹理加载器加载并作为制服公开的纹理

顶点着色器是基本的。它只是将 uv 位置传递给片段着色器:

变化的 vec2 vUv;

void main() {
  vUv = uv;  
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}

在片段着色器中,我们使用 sin 函数来改变位移,使其 'circles around' 到初始位置并且也向负方向移动。

varying vec2 vUv;

uniform float uTime;
uniform sampler2D uMap;

void main() {
  vec4 map = texture2D(uMap, vec2(vUv.x + (vUv.y - 0.5) * sin(uTime * 0.01), vUv.y) );
  gl_FragColor = vec4( map.rgb,  1.0 );
}

sin 函数的 book of shaders 可视化和练习帮助我可视化并提出了解决方案。

附上结果的屏幕剪辑(由于 Whosebug 对图像的最大尺寸限制,质量较低)