read vertex position as pixel

by brunoimbrizi

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/95/three.min.js"></script>
<div class='container'></div>
<div class='info rgba'></div>
<div class='info xyz'></div>

CSS

body {
  margin: 0;
  overflow: hidden;
  color: #FFF;
  background-color: #000;
  font-family: monospace;
}

.container {
  position: absolute;
  top: 20px;
  left: 20px;
}

.info {
  position: absolute;
  top: 20px;
  left: 170px;
}

.info.xyz {
  left: 260px;
}

JavaScript

// pass vertex position to fragment
// render as texture and read pixels
// shouldn't R == X ?

var renderer, camera, scene, texture, geometry, material, buffer;

var width = 4;
var height = 4;

function init() {
	scene = new THREE.Scene();
	
  camera = new THREE.OrthographicCamera(width / -2, width / 2, height / 2, height / -2, -1, 1);
  
  renderer = new THREE.WebGLRenderer({ premultipliedAlpha: false });
  renderer.setSize(128, 128);
  document.querySelector('.container').appendChild(renderer.domElement);

  texture = new THREE.WebGLRenderTarget(width, height, { 
  	minFilter: THREE.LinearFilter,
    magFilter: THREE.NearestFilter,
    format: THREE.RGBAFormat,
    type: THREE.FloatType
  });
  
  material = new THREE.ShaderMaterial( {
    uniforms: { },
    vertexShader: `
    	varying vec4 vOut;
  
			void main() {
      	gl_Position = vec4(position, 1.0);
        vOut = vec4(position, 1.0);
			}
    `,
    fragmentShader: `
    	varying vec4 vOut;
    
    	void main() {
				gl_FragColor = vOut;
    	}
    `,
  });
  
  geometry = new THREE.PlaneBufferGeometry(width, height);

  var quad = new THREE.Mesh(geometry, material);
  scene.add(quad);
  
  buffer = new Float32Array(4 * width * height);
}

function animate() {
  requestAnimationFrame(animate);
  render();
  read();
}

function render() {
  renderer.render(scene, camera, texture, true);
  renderer.render(scene, camera);
}

function read() {
	renderer.readRenderTargetPixels(texture, 0, 0, width, height, buffer);
  
  var positions = geometry.attributes.position.array;
  
  var p = 0;
  var str = `Index: ${p}
  
  R: ${buffer[p * 4 + 0]}
  G: ${buffer[p * 4 + 1]}
  B: ${buffer[p * 4 + 2]}
  A: ${buffer[p * 4 + 3]}`;
  
	document.querySelector('.info.rgba').innerText = str;
  
  str = `
  
  X: ${positions[p * 3 + 0]}
  Y: ${positions[p * 3 + 1]}
  Z: ${positions[p * 3 + 2]}`;
  
  document.querySelector('.info.xyz').innerText = str;
}

init();
animate();