笔记
- 采用 three 的后处理。
- 使用两个画布,一个画布捕捉手势,并以颜色存储偏移数据;一个画布为 three 渲染场景。
<Canvas>
<Screen />
<EffectComposer>
<WaterEffect texture={texture} />
<Noise />
</EffectComposer>
</Canvas>
<canvas ref={canvasRef} className='absolute left-0 top-0 opacity-0' width={500} height={300} />
import * as THREE from 'three'
import { Effect } from 'postprocessing'
import { forwardRef, useMemo } from 'react'
let _texture: any
class WaterEffectImpl extends Effect {
constructor({ texture }: { texture: THREE.Texture | null }) {
super('WaterEffect', fragment, {
uniforms: new Map([['uTexture', new THREE.Uniform(texture)]])
})
_texture = texture
}
update() {
if (this.uniforms.get('uTexture')) this.uniforms.get('uTexture')!.value = _texture
}
}
const fragment = `
uniform sampler2D uTexture;
void mainUv(inout vec2 uv) {
vec4 tex = texture2D(uTexture, uv);
float angle = -((tex.r) * (PI * 2.) - PI) ;
float vx = -(tex.r *2. - 1.);
float vy = -(tex.g *2. - 1.);
float intensity = tex.b;
uv.x += vx * 0.15 * intensity;
uv.y += vy * 0.15 *intensity;
}
`
// Effect component
export const WaterEffect = forwardRef<any, { texture: THREE.Texture | null }>(({ texture }, ref) => {
const effect = useMemo(() => new WaterEffectImpl({ texture }), [texture])
return <primitive ref={ref} object={effect} dispose={null} />
})
export default WaterEffect