I decided to try shaders and learn with Youtube videos where images are represented / mapped to via particles. My image has a 1920 by 1080 resolution, 2 values which I would like to use in the fragment shader. From what I (think to have) learned to far is:
-
in the THREE.ShaderMaterial define the values as a uniform:
// app.js this.material = new THREE.ShaderMaterial({ uniforms: { t1: { type: "t", value: this.textures[0] }, aTotalParticles: { type: "f", value: this.totalParticles }, aParticlesX: { type: "f", value: this.particlesX }, aParticlesY: { type: "f", value: this.particlesY }, }, fragmentShader: fragment, vertexShader: vertex }); this.geometry = new THREE.BufferGeometry(); this.positions = new THREE.BufferAttribute(new Float32Array(this.totalParticles * 3), 3) this.coordinates = new THREE.BufferAttribute(new Float32Array(this.totalParticles * 3), 3) let index = 0; for (let i = 0; i < this.particlesX; i++) { for (let j = 0; j < this.particlesY; j++) { ... } } this.geometry.setAttribute( 'position', this.positions ); this.geometry.setAttribute( 'aCoordinates', this.coordinates );
-
in the VertexShader.glsl import those values as attributes and assign them to varyings:
// vertextShader.glsl attribute vec2 aCoordinates; attribute float aTotalParticles; attribute float aParticlesX; attribute float aParticlesY; varying vec2 vUv; varying vec2 vCoordinates; varying float vTotalParticles; varying float vParticlesX; varying float vParticlesY; void main() { vUv = uv; vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); gl_PointSize = 2000. * (1. / - mvPosition.z); gl_Position = projectionMatrix * mvPosition; vCoordinates = aCoordinates.xy; vTotalParticles = aTotalParticles; vTotalParticles = aTotalParticles; vParticlesX = aParticlesX; vParticlesY = aParticlesY; }
-
and eventually in the fragmentShader import those values the varyings again (same name):
// fragmentShader.glsl varying vec2 vCoordinates; varying float vTotalParticles; varying float vParticlesX; varying float vParticlesY; uniform sampler2D t1; void main() { vec2 myUV = vec2(vCoordinates.x / vParticlesX, vCoordinates.y / vParticlesY); vec4 image = texture2D(t1, myUV); gl_FragColor = image; }
However, the fragmentShader calculates only one color that all particles receive. If I use floats directly
vec2 myUV = vec2(vCoordinates.x / 1920., vCoordinates.y / 1080.);
the output is what is expected.
What am I doing wrong in my script?