GLSL Filters

FBO: same size as image perform filter in RTT

by jmcjc5u

HTML

<div id="info">
  <br/> RTT, Mosaic
  <br/>
</div>
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js">
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5.1/dat.gui.min.js"></script>

<script id="vsFilter" type="x-shader/x-vertex">
  varying vec2 vUv; 
  void main() { 
      gl_Position = projectionMatrix* modelViewMatrix * vec4( position, 1.0); 
      vUv = uv; 
  }
</script>
<script id="fsFilter" type="x-shader/x-fragment">
  uniform sampler2D mytex; 
  varying vec2 vUv; 
	uniform float gran;
  
  void main() { 
    vec2 vUvm;
    if (gran == 1.0)
    	vUvm = vUv;
    else  
  	  vUvm = floor (vUv/gran)*gran; 
  	gl_FragColor = texture2D(mytex, vUvm); 
  }
</script>

CSS

body {
	  background-color: #fff;
	  color: #111;
	  margin: 0px;
	  overflow: hidden;
	  font-family: Monospace;
	  font-size: 20px;
	  position: absolute;
	}
  
	#info {
	  position: absolute;
	  top: 0px;
	  width: 100%;
	  padding: 5px;
	  text-align: center;
	  color: #ffff00
	}

JavaScript

var scene, renderer, camera;
var material_shh;
var sceneRTT, cameraRTT;
var renderTarget;
var granValue = 0.1;
var gcontrols;

init();
animate();

function init() {
  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
  renderer.setClearColor(0x888888);

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 1000);
  //camera.position.y = 80;
  camera.position.z = 100;
  camera.lookAt(new THREE.Vector3(0, 0, 0));

  let controls = new THREE.OrbitControls(camera, renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);
  ///////////////////////////////////////////////////////
  gcontrols = {
    gran: 0.1,
    mosaic: true
  };

  var gui = new dat.GUI();
  gui.domElement.id = 'gui';

  gui.add(gcontrols, 'gran', 0.01,0.15);
  gui.add(gcontrols, 'mosaic');

  ///////////////////////////////////////////////////////////////////////
  let loader = new THREE.TextureLoader();
  loader.crossOrigin = '';
  var tex1 = loader.load ('https://i.imgur.com/A7iqfXD.png'); // olympic-c:256x256

	var uniforms = {
    mytex: {
    	type: 't',
      value: tex1
    }, 
    gran: {
    	type: 'f',
      value: granValue
    }
  };

  renderTarget = new THREE.WebGLRenderTarget( 
   	256,256,  // size of the FBO
		{ minFilter: THREE.LinearFilter, magFilter: THREE.NearestFilter, format: THREE.RGBFormat } 
		);

	var vertShader = document.getElementById('vsFilter').innerHTML;
  var fragShader = document.getElementById('fsFilter').innerHTML;
	material_shh = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: vertShader,
    fragmentShader: fragShader
  });

	var geometry = new THREE.PlaneGeometry(100,100);
  var bs = new THREE.Mesh(geometry, material_shh);

  sceneRTT = new THREE.Scene();
  cameraRTT = new THREE.OrthographicCamera(-50, 50, 50, -50, -10, 10);
 ...