├── .gitignore ├── .npmignore ├── index.html ├── index.js ├── frag.glsl ├── vert.glsl ├── LICENSE.md ├── package.json ├── demo.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | .DS_Store 4 | bundle.js 5 | test 6 | test.js 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | three-shader-fxaa 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var glslify = require('glslify') 2 | module.exports = threeShaderFXAA 3 | function threeShaderFXAA (opt) { 4 | if (typeof global.THREE === 'undefined') { 5 | throw new TypeError('You must have THREE in global scope for this module.') 6 | } 7 | opt = opt || {} 8 | return { 9 | uniforms: { 10 | tDiffuse: { type: 't', value: new THREE.Texture() }, 11 | resolution: { type: 'v2', value: opt.resolution || new THREE.Vector2() } 12 | }, 13 | vertexShader: glslify('./vert.glsl'), 14 | fragmentShader: glslify('./frag.glsl') 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /frag.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | //texcoords computed in vertex step 4 | //to avoid dependent texture reads 5 | varying vec2 v_rgbNW; 6 | varying vec2 v_rgbNE; 7 | varying vec2 v_rgbSW; 8 | varying vec2 v_rgbSE; 9 | varying vec2 v_rgbM; 10 | 11 | //make sure to have a resolution uniform set to the screen size 12 | uniform vec2 resolution; 13 | uniform sampler2D tDiffuse; 14 | 15 | #pragma glslify: fxaa = require('glsl-fxaa/fxaa.glsl') 16 | 17 | void main() { 18 | vec2 fragCoord = vUv * resolution; 19 | gl_FragColor = fxaa(tDiffuse, fragCoord, resolution, v_rgbNW, v_rgbNE, v_rgbSW, v_rgbSE, v_rgbM); 20 | } 21 | -------------------------------------------------------------------------------- /vert.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | varying vec2 v_rgbNW; 4 | varying vec2 v_rgbNE; 5 | varying vec2 v_rgbSW; 6 | varying vec2 v_rgbSE; 7 | varying vec2 v_rgbM; 8 | 9 | uniform vec2 resolution; 10 | 11 | void main() { 12 | vUv = uv; 13 | vec2 fragCoord = uv * resolution; 14 | vec2 inverseVP = 1.0 / resolution.xy; 15 | v_rgbNW = (fragCoord + vec2(-1.0, -1.0)) * inverseVP; 16 | v_rgbNE = (fragCoord + vec2(1.0, -1.0)) * inverseVP; 17 | v_rgbSW = (fragCoord + vec2(-1.0, 1.0)) * inverseVP; 18 | v_rgbSE = (fragCoord + vec2(1.0, 1.0)) * inverseVP; 19 | v_rgbM = vec2(fragCoord * inverseVP); 20 | 21 | gl_Position = projectionMatrix * 22 | modelViewMatrix * 23 | vec4(position,1.0); 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2014 Matt DesLauriers 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "three-shader-fxaa", 3 | "version": "5.1.1", 4 | "description": "optimized FXAA shader for ThreeJS", 5 | "main": "./build/index.js", 6 | "license": "MIT", 7 | "author": "Matt DesLauriers ", 8 | "dependencies": {}, 9 | "standard": { 10 | "globals": [ 11 | "THREE" 12 | ] 13 | }, 14 | "devDependencies": { 15 | "glsl-fxaa": "^3.0.0", 16 | "glslify": "^4.0.0", 17 | "browserify": "^12.0.1", 18 | "budo": "^7.0.2", 19 | "npm-run-all": "^1.6.0", 20 | "onchange": "^2.1.2", 21 | "standard": "^5.4.1", 22 | "three": "^0.73.0", 23 | "three-effectcomposer": "0.0.1", 24 | "transpilify": "^2.0.0", 25 | "uglify-js": "^2.6.1" 26 | }, 27 | "scripts": { 28 | "start": "npm-run-all --parallel watch dev", 29 | "watch": "onchange 'index.js' '*.glsl' -- npm run transpile", 30 | "dev": "budo demo.js:bundle.js --live", 31 | "build": "browserify demo.js | uglifyjs -cm > bundle.js", 32 | "transpile": "transpilify index.js --out-file build/index.js -t glslify", 33 | "prepublish": "npm run transpile", 34 | "test": "standard" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "git://github.com/mattdesl/three-shader-fxaa.git" 39 | }, 40 | "homepage": "https://github.com/mattdesl/three-shader-fxaa", 41 | "bugs": { 42 | "url": "https://github.com/mattdesl/three-shader-fxaa/issues" 43 | }, 44 | "keywords": [ 45 | "fxaa", 46 | "glsl", 47 | "webgl", 48 | "threejs", 49 | "three", 50 | "anti", 51 | "aliasing", 52 | "anti-aliasing", 53 | "alias", 54 | "anti-alias", 55 | "smooth", 56 | "screen", 57 | "space" 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | global.THREE = require('three') 2 | var EffectComposer = require('three-effectcomposer')(THREE) 3 | var fxaa = require('./') 4 | 5 | var dpr = window.devicePixelRatio 6 | var width = 512 7 | var height = 512 8 | var canvas = document.createElement('canvas') 9 | canvas.width = width * dpr 10 | canvas.height = height * dpr 11 | canvas.style.width = width + 'px' 12 | canvas.style.height = height + 'px' 13 | document.body.appendChild(canvas) 14 | 15 | var renderer = new THREE.WebGLRenderer({ 16 | antialias: false, 17 | canvas: canvas 18 | }) 19 | 20 | renderer.setClearColor(0x000000, 1) 21 | 22 | var scene = new THREE.Scene() 23 | var camera = new THREE.PerspectiveCamera(50, width / height, 0.01, 1000) 24 | 25 | camera.position.copy(new THREE.Vector3(3, 2, -2)) 26 | camera.lookAt(new THREE.Vector3()) 27 | 28 | var geo = new THREE.BoxGeometry(1, 1, 1) 29 | var mat = new THREE.MeshBasicMaterial({ color: 0xffffff }) 30 | var box = new THREE.Mesh(geo, mat) 31 | scene.add(box) 32 | 33 | var target = new THREE.WebGLRenderTarget(width * dpr, height * dpr) 34 | target.format = THREE.RGBFormat 35 | target.minFilter = THREE.LinearFilter 36 | target.generateMipmaps = false 37 | 38 | var composer = new EffectComposer(renderer, target) 39 | 40 | composer.addPass(new EffectComposer.RenderPass(scene, camera)) 41 | 42 | var shaderPass = new EffectComposer.ShaderPass(fxaa()) 43 | shaderPass.renderToScreen = true 44 | composer.addPass(shaderPass) 45 | 46 | var tick = 0 47 | 48 | render() 49 | setInterval(render, 1000) 50 | 51 | function render () { 52 | if (tick++ % 2 === 0) { 53 | renderer.render(scene, camera) 54 | } else { 55 | // ensure FXAA has correct target resolution 56 | shaderPass.uniforms.resolution.value.set(width, height) 57 | composer.render() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # three-shader-fxaa 2 | 3 | [![stable](http://badges.github.io/stability-badges/dist/stable.svg)](http://github.com/badges/stability-badges) 4 | 5 | [Demo](http://mattdesl.github.io/three-shader-fxaa/) 6 | 7 | Optimized FXAA shader for ThreeJS, passing some texture coordinates from the vertex shader to avoid 5 dependent texture reads. This is well suited for PowerVR GPUs (iOS). 8 | 9 | [![screen](http://i.imgur.com/Qsjt7z5.png)](http://mattdesl.github.io/three-shader-fxaa/) 10 | 11 | Tested on Three r69-78, works with the [three](http://npmjs.com/package/three) module. 12 | 13 | ## Install 14 | 15 | ```sh 16 | npm install three-shader-fxaa --save 17 | ``` 18 | 19 | ## Usage 20 | 21 | This is typically used with EffectComposer, like so: 22 | 23 | ```js 24 | // Make sure THREE is in global if not already 25 | window.THREE = require('three') 26 | 27 | // Grab EffectComposer from npm or ThreeJS examples 28 | var EffectComposer = require('three-effectcomposer')(THREE) 29 | 30 | // Grab this module! 31 | var fxaa = require('three-shader-fxaa') 32 | 33 | // Setup bare-bones composer 34 | var effectComposer = new EffectComposer(renderer) 35 | composer.addPass(new EffectComposer.RenderPass(scene, camera)) 36 | 37 | // Add FXAA pass 38 | var shaderPass = new EffectComposer.ShaderPass(fxaa()) 39 | shaderPass.renderToScreen = true 40 | composer.addPass(shaderPass) 41 | 42 | // Make sure screen resolution is set! 43 | shaderPass.uniforms.resolution.value.set(width, height) 44 | 45 | // Render scene 46 | composer.render() 47 | ``` 48 | 49 | ## Usage 50 | 51 | [![NPM](https://nodei.co/npm/three-shader-fxaa.png)](https://nodei.co/npm/three-shader-fxaa/) 52 | 53 | ### ```shader = fxaa([opt])``` 54 | 55 | Calling the function returns a new object with the following properties. This can be piped into `THREE.ShaderMaterial` or `THREE.EffectComposer`. 56 | 57 | ```js 58 | { 59 | vertexShader: '...shader source...', 60 | fragmentShader: '...shader source...', 61 | uniforms: { 62 | tDiffuse: { type: 't', value: new THREE.Texture() }, 63 | resolution: { type: 'v2', value: new THREE.Vector2() } 64 | } 65 | } 66 | ``` 67 | 68 | You can specify the following option: 69 | 70 | - `opt.resolution` which is a default `THREE.Vector2` to use 71 | 72 | ## From Source 73 | 74 | To build/run from source, first `git clone` this repo and then: 75 | 76 | ```sh 77 | npm install 78 | ``` 79 | 80 | Once installed, you can test/build the demo like this: 81 | 82 | ```sh 83 | # to run demo dev server/scripts 84 | npm run start 85 | 86 | # to run demo build scripts 87 | npm run build 88 | ``` 89 | 90 | Or, you can test/build the source code. It needs to be transpiled with `glslify` so that the final npm distribution has its source inlined. 91 | 92 | ```sh 93 | # watch index and shaders and transpile on change 94 | npm run dev 95 | 96 | # transpile index and shaders to build/ folder 97 | npm run transpile 98 | ``` 99 | 100 | ## License 101 | 102 | MIT, see [LICENSE.md](http://github.com/mattdesl/three-shader-fxaa/blob/master/LICENSE.md) for details. 103 | --------------------------------------------------------------------------------