├── .gitignore ├── LICENSE.md ├── README.md ├── app ├── Audio.js ├── Webgl.js ├── audio │ └── ordinary.mp3 ├── index.js ├── objects │ ├── BaseThreeObj.js │ ├── Cube.js │ ├── Plane.js │ ├── Ring.js │ └── Sphere.js └── styles │ └── styles.css ├── build └── vendors │ └── wagner │ ├── ShaderLoader.js │ ├── Wagner.base.js │ ├── Wagner.js │ ├── fragment-shaders │ ├── art-fs.glsl │ ├── ascii-fs.glsl │ ├── barrel-blur-fs.glsl │ ├── bleach-fs.glsl │ ├── blend-fs.glsl │ ├── bloom-fs.glsl │ ├── bloom2-fs.glsl │ ├── bokeh-poison-dof-fs.glsl │ ├── bokeh-poison-fs.glsl │ ├── box-blur-fs.glsl │ ├── box-blur2-fs.glsl │ ├── brightness-contrast-fs.glsl │ ├── cga-fs.glsl │ ├── chromatic-aberration-fs.glsl │ ├── circular-blur-fs.glsl │ ├── copy-fs.glsl │ ├── crossfade-fs.glsl │ ├── denoise-fs.glsl │ ├── dof-fs.glsl │ ├── dot-screen-fs.glsl │ ├── frei-chen-fs.glsl │ ├── fxaa-fs.glsl │ ├── fxaa2-fs.glsl │ ├── grayscale-fs.glsl │ ├── guided-box-blur-fs.glsl │ ├── guided-box-blur2-fs.glsl │ ├── guided-directional-blur-fs.glsl │ ├── halftone-fs.glsl │ ├── halftone2-fs.glsl │ ├── high-pass-fs.glsl │ ├── invert-fs.glsl │ ├── led-fs.glsl │ ├── noise-fs.glsl │ ├── old-video-fs.glsl │ ├── packed-depth-fs.glsl │ ├── pixelate-fs.glsl │ ├── poisson-disc-blur-fs.glsl │ ├── rgb-split-fs.glsl │ ├── sepia-fs.glsl │ ├── sobel-fs.glsl │ ├── sobel2-fs.glsl │ ├── ssao-fs.glsl │ ├── ssao-simple-fs.glsl │ ├── symetric-fs.glsl │ ├── toon-fs.glsl │ ├── vignette-fs.glsl │ ├── vignette2-fs.glsl │ ├── vr-compose-fs.glsl │ ├── zoom-blur-fs.glsl │ └── zoom-blur2-fs.glsl │ └── vertex-shaders │ ├── basic-vs.glsl │ ├── orto-vs.glsl │ └── packed-depth-vs.glsl ├── index.html ├── package.json └── preview.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | build/main.js 3 | node_modules 4 | app/audio/foals.mp3 5 | app/audio/lookbook.mp3 6 | *.log 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## creative commons 2 | 3 | # Attribution-NonCommercial-ShareAlike 4.0 International 4 | 5 | Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. 6 | 7 | ### Using Creative Commons Public Licenses 8 | 9 | Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. 10 | 11 | * __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). 12 | 13 | * __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). 14 | 15 | ## Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License 16 | 17 | By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. 18 | 19 | ### Section 1 – Definitions. 20 | 21 | a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. 22 | 23 | b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. 24 | 25 | c. __BY-NC-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. 26 | 27 | d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. 28 | 29 | e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. 30 | 31 | f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. 32 | 33 | g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike. 34 | 35 | h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. 36 | 37 | i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. 38 | 39 | h. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. 40 | 41 | i. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange. 42 | 43 | j. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. 44 | 45 | k. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. 46 | 47 | l. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. 48 | 49 | ### Section 2 – Scope. 50 | 51 | a. ___License grant.___ 52 | 53 | 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: 54 | 55 | A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and 56 | 57 | B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only. 58 | 59 | 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. 60 | 61 | 3. __Term.__ The term of this Public License is specified in Section 6(a). 62 | 63 | 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. 64 | 65 | 5. __Downstream recipients.__ 66 | 67 | A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. 68 | 69 | B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. 70 | 71 | C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. 72 | 73 | 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). 74 | 75 | b. ___Other rights.___ 76 | 77 | 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. 78 | 79 | 2. Patent and trademark rights are not licensed under this Public License. 80 | 81 | 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes. 82 | 83 | ### Section 3 – License Conditions. 84 | 85 | Your exercise of the Licensed Rights is expressly made subject to the following conditions. 86 | 87 | a. ___Attribution.___ 88 | 89 | 1. If You Share the Licensed Material (including in modified form), You must: 90 | 91 | A. retain the following if it is supplied by the Licensor with the Licensed Material: 92 | 93 | i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); 94 | 95 | ii. a copyright notice; 96 | 97 | iii. a notice that refers to this Public License; 98 | 99 | iv. a notice that refers to the disclaimer of warranties; 100 | 101 | v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; 102 | 103 | B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and 104 | 105 | C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. 106 | 107 | 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. 108 | 109 | 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. 110 | 111 | b. ___ShareAlike.___ 112 | 113 | In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. 114 | 115 | 1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License. 116 | 117 | 2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. 118 | 119 | 3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. 120 | 121 | ### Section 4 – Sui Generis Database Rights. 122 | 123 | Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: 124 | 125 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only; 126 | 127 | b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and 128 | 129 | c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. 130 | 131 | For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. 132 | 133 | ### Section 5 – Disclaimer of Warranties and Limitation of Liability. 134 | 135 | a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ 136 | 137 | b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ 138 | 139 | c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. 140 | 141 | ### Section 6 – Term and Termination. 142 | 143 | a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. 144 | 145 | b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: 146 | 147 | 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or 148 | 149 | 2. upon express reinstatement by the Licensor. 150 | 151 | For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. 152 | 153 | c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. 154 | 155 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. 156 | 157 | ### Section 7 – Other Terms and Conditions. 158 | 159 | a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. 160 | 161 | b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License. 162 | 163 | ### Section 8 – Interpretation. 164 | 165 | a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. 166 | 167 | b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. 168 | 169 | c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. 170 | 171 | d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. 172 | 173 | ``` 174 | Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. 175 | 176 | Creative Commons may be contacted at creativecommons.org 177 | ``` 178 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Three js + Audio HTML5 API 2 | ================== 3 | 4 | Little experiment using three js + audio html5 api. 5 | Written in ES2015. 6 | 7 | 8 | Demo available [here](http://lab.hengpatrick.fr/three-js-audio-experiment-2/). 9 | 10 | 11 | ![Preview](http://lab.hengpatrick.fr/three-js-audio-experiment-2/preview.png) 12 | 13 | 14 | ## Getting started 15 | After cloning install all dependencies : 16 | ```bash 17 | npm i 18 | ``` 19 | 20 | ## Task 21 | ### Start development 22 | It starts devlopement server at [localhost:3000](http://localhost:3000), browser-sync and watch files. 23 | ```bash 24 | npm start 25 | ``` 26 | ### Prepare for deploy 27 | ```bash 28 | npm run build 29 | ``` 30 | 31 | Hope you like it ! <3 32 | -------------------------------------------------------------------------------- /app/Audio.js: -------------------------------------------------------------------------------- 1 | export default class Audio { 2 | constructor(sepValue) { 3 | let self = this; 4 | 5 | this.ctx = new AudioContext(); 6 | this.audio = document.getElementById('myAudio'); 7 | this.audioSrc = this.ctx.createMediaElementSource(this.audio); 8 | this.analyser = this.ctx.createAnalyser(); 9 | this.audioData = []; 10 | this.sepValue = sepValue; 11 | 12 | // Connect the MediaElementSource with the analyser 13 | this.audioSrc.connect(this.analyser); 14 | this.audioSrc.connect(this.ctx.destination); 15 | 16 | // FrequencyBinCount tells how many values are receive from the analyser 17 | this.frequencyData = new Uint8Array(this.analyser.frequencyBinCount); 18 | 19 | this.audio.play(); 20 | }; 21 | 22 | 23 | getFrequencyData() { 24 | this.analyser.getByteFrequencyData(this.frequencyData); 25 | return this.frequencyData; 26 | }; 27 | 28 | getAudioData() { 29 | this.analyser.getByteFrequencyData(this.frequencyData); 30 | 31 | // Split array into 3 32 | let frequencyArray = this.splitFrenquencyArray(this.frequencyData, 33 | this.sepValue); 34 | 35 | // Make average of frenquency array entries 36 | for (let i = 0; i < frequencyArray.length - 100; i++) { 37 | let average = 0; 38 | 39 | for (let j = 0; j < frequencyArray[i].length; j++) { 40 | average += frequencyArray[i][j]; 41 | } 42 | this.audioData[i] = average / frequencyArray[i].length; 43 | } 44 | return this.audioData; 45 | } 46 | 47 | splitFrenquencyArray(arr, n) { 48 | let tab = Object.keys(arr).map(function(key) { 49 | return arr[key] 50 | }); 51 | let len = tab.length, 52 | result = [], 53 | i = 0; 54 | 55 | while (i < len) { 56 | let size = Math.ceil((len - i) / n--); 57 | result.push(tab.slice(i, i + size)); 58 | i += size; 59 | } 60 | 61 | return result; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /app/Webgl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import Sphere from './objects/Sphere'; 4 | import Plane from './objects/Plane'; 5 | import Cube from './objects/Cube'; 6 | import Ring from './objects/Ring'; 7 | import THREE from 'three'; 8 | 9 | window.THREE = THREE; 10 | 11 | let OrbitControls = require('three-orbit-controls')(THREE) 12 | 13 | 14 | export default class Webgl { 15 | constructor(width, height, audio) { 16 | this.audio = audio; 17 | 18 | 19 | 20 | this.scene = new THREE.Scene(); 21 | 22 | this.camera = new THREE.PerspectiveCamera(50, width / height, 1, 1000); 23 | this.camera.position.z = 100; 24 | this.camera.lookAt(new THREE.Vector3(0, 0, 0)) 25 | 26 | this.renderer = new THREE.WebGLRenderer(); 27 | this.renderer.setSize(width, height); 28 | this.renderer.setClearColor(0x262626); 29 | 30 | this.usePostprocessing = true; 31 | this.composer = new WAGNER.Composer(this.renderer); 32 | this.composer.setSize(width, height); 33 | this.initPostprocessing(); 34 | 35 | this.controls = new OrbitControls(this.camera, this.renderer.domElement); 36 | 37 | this.plane = new Plane(); 38 | this.plane.position.set(0, 0, 0); 39 | this.scene.add(this.plane); 40 | 41 | this.cube = new Cube(); 42 | this.cube.position.set(0, 0, 0); 43 | this.scene.add(this.cube); 44 | 45 | this.sphere = new Sphere(); 46 | this.sphere.position.set(0, 0, 0); 47 | this.scene.add(this.sphere); 48 | 49 | this.ring = new Ring(); 50 | this.ring.position.set(0, 0, 0); 51 | this.scene.add(this.ring); 52 | 53 | this.ring.removeMesh(); 54 | this.cube.removeMesh(); 55 | this.plane.removeMesh(); 56 | 57 | } 58 | 59 | initPostprocessing() { 60 | if (!this.usePostprocessing) return; 61 | 62 | this.vignette2Pass = new WAGNER.Vignette2Pass(); 63 | } 64 | 65 | resize(width, height) { 66 | this.composer.setSize(width, height); 67 | 68 | this.camera.aspect = width / height; 69 | this.camera.updateProjectionMatrix(); 70 | 71 | this.renderer.setSize(width, height); 72 | }; 73 | 74 | render() { 75 | if (this.usePostprocessing) { 76 | this.composer.reset(); 77 | this.composer.renderer.clear(); 78 | this.composer.render(this.scene, this.camera); 79 | this.composer.pass(this.vignette2Pass); 80 | this.composer.toScreen(); 81 | } else { 82 | this.renderer.autoClear = false; 83 | this.renderer.clear(); 84 | this.renderer.render(this.scene, this.camera); 85 | } 86 | 87 | let audiData = this.audio.getAudioData(); 88 | 89 | if(this.plane.active) 90 | this.plane.update(audiData); 91 | if(this.sphere.active) 92 | this.sphere.update(audiData); 93 | if(this.cube.active) 94 | this.cube.update(audiData); 95 | if(this.ring) 96 | this.ring.update(audiData); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/audio/ordinary.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickheng/three-js-audio-experiment-v2/e42a3a492fd38475c23a64b1fd2e9792f26d2f93/app/audio/ordinary.mp3 -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import domready from 'domready'; 4 | import Webgl from './Webgl'; 5 | import Audio from './Audio'; 6 | import raf from 'raf'; 7 | import dat from 'dat-gui'; 8 | import Stats from 'stats-js'; 9 | import 'gsap'; 10 | 11 | let webgl; 12 | let audio; 13 | let gui; 14 | let stats; 15 | 16 | domready(() => { 17 | // webgl settings 18 | audio = new Audio(435); 19 | webgl = new Webgl(window.innerWidth, window.innerHeight, 20 | audio); 21 | 22 | document.body.appendChild(webgl.renderer.domElement); 23 | 24 | // GUI settings 25 | gui = new dat.GUI(); 26 | 27 | let sphereFolder = gui.addFolder('Sphere'); 28 | let cubeFolder = gui.addFolder('Cube'); 29 | let ringFolder = gui.addFolder('Ring'); 30 | let planeFolder = gui.addFolder('Plane'); 31 | 32 | gui.add(webgl, 'usePostprocessing'); 33 | 34 | sphereFolder.add(webgl.sphere, 'active').onChange(function(value) { 35 | webgl.sphere.toggleMesh(); 36 | }); 37 | cubeFolder.add(webgl.cube, 'active').onChange(function(value) { 38 | webgl.cube.toggleMesh(); 39 | }); 40 | ringFolder.add(webgl.ring, 'active').onChange(function(value) { 41 | webgl.ring.toggleMesh(); 42 | }); 43 | planeFolder.add(webgl.plane, 'active').onChange(function(value) { 44 | webgl.plane.toggleMesh(); 45 | }); 46 | 47 | sphereFolder.open(); 48 | cubeFolder.open(); 49 | ringFolder.open(); 50 | planeFolder.open(); 51 | 52 | //Stats js 53 | stats = new Stats(); 54 | stats.setMode(0); // 0: fps, 1: ms 55 | 56 | // Align top-left 57 | stats.domElement.style.position = 'absolute'; 58 | stats.domElement.style.left = '0px'; 59 | stats.domElement.style.top = '0px'; 60 | 61 | document.body.appendChild(stats.domElement); 62 | 63 | // handle resize 64 | window.onresize = resizeHandler; 65 | 66 | 67 | // let's play ! 68 | animate(); 69 | }); 70 | 71 | function resizeHandler() { 72 | webgl.resize(window.innerWidth, window.innerHeight); 73 | } 74 | 75 | function animate() { 76 | stats.begin(); 77 | raf(animate); 78 | webgl.render(); 79 | stats.end(); 80 | } 81 | 82 | function rgbToHex(color) { 83 | let hex = { 84 | r: (parseInt(color.r) + 0x10000).toString(16).substr(-2).toUpperCase(), 85 | g: (parseInt(color.g) + 0x10000).toString(16).substr(-2).toUpperCase(), 86 | b: (parseInt(color.b) + 0x10000).toString(16).substr(-2).toUpperCase() 87 | } 88 | let newColor = "0x" + hex.r + hex.g + hex.b; 89 | console.log('newColor', newColor) 90 | return newColor; 91 | } 92 | -------------------------------------------------------------------------------- /app/objects/BaseThreeObj.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import THREE from 'three'; 4 | 5 | export default class BaseThreeObj extends THREE.Object3D { 6 | constructor() { 7 | super(); 8 | } 9 | 10 | saveVertices() { 11 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 12 | this.initialGeomVertices[i] = {}; 13 | this.initialGeomVertices[i].x = this.mesh.geometry.vertices[i].x; 14 | this.initialGeomVertices[i].y = this.mesh.geometry.vertices[i].y; 15 | this.initialGeomVertices[i].z = this.mesh.geometry.vertices[i].z; 16 | } 17 | } 18 | 19 | toggleMesh() { 20 | if (!this.active) { 21 | this.removeMesh(); 22 | } else { 23 | this.addMesh(); 24 | } 25 | } 26 | 27 | addMesh() { 28 | this.mesh = new THREE.Mesh(this.geom, this.mat); 29 | this.mesh.position.y = -10; 30 | this.add(this.mesh); 31 | this.active = true; 32 | } 33 | 34 | removeMesh() { 35 | this.remove(this.mesh); 36 | this.active = false; 37 | } 38 | 39 | update(audioData) { 40 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 41 | 42 | this.mesh.geometry.vertices[i].x = this.initialGeomVertices[i].x * (audioData[i] / 100); 43 | this.mesh.geometry.vertices[i].y = this.initialGeomVertices[i].y * (audioData[i] / 100); 44 | this.mesh.geometry.vertices[i].z = this.initialGeomVertices[i].z * (audioData[i] / 100); 45 | } 46 | this.mesh.geometry.verticesNeedUpdate = true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/objects/Cube.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import THREE from 'three'; 4 | import BaseThreeObj from './BaseThreeObj.js'; 5 | 6 | export default class Cube extends BaseThreeObj { 7 | constructor() { 8 | super(); 9 | 10 | this.initialGeomVertices = []; 11 | 12 | this.geom = new THREE.CubeGeometry(25, 25, 25, 5, 5, 5); 13 | 14 | this.mat = new THREE.MeshBasicMaterial({ 15 | color: 0x16a085, 16 | side: THREE.DoubleSide, 17 | wireframe: true, 18 | opacity: 0.8, 19 | transparent : true 20 | }); 21 | 22 | this.active = true; 23 | this.addMesh(); 24 | this.saveVertices(); 25 | } 26 | 27 | update(audioData) { 28 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 29 | 30 | this.mesh.geometry.vertices[i].x = this.initialGeomVertices[i].x * (audioData[i] / 400); 31 | this.mesh.geometry.vertices[i].y = -this.initialGeomVertices[i].y * (audioData[i] / 400); 32 | this.mesh.geometry.vertices[i].z = this.initialGeomVertices[i].z * (audioData[i] / 400); 33 | } 34 | this.mesh.geometry.verticesNeedUpdate = true; 35 | this.rotation.y -= 0.005; 36 | this.rotation.x += 0.005; 37 | this.rotation.z += 0.005; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/objects/Plane.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import THREE from 'three'; 4 | import BaseThreeObj from './BaseThreeObj.js'; 5 | 6 | export default class Plane extends BaseThreeObj { 7 | constructor() { 8 | super(); 9 | 10 | this.initialGeomVertices = []; 11 | 12 | this.geom = new THREE.PlaneGeometry(50, 50, 20, 20); 13 | 14 | this.mat = new THREE.MeshBasicMaterial({ 15 | color: 0x34495e, 16 | side: THREE.DoubleSide, 17 | wireframe: true 18 | }); 19 | 20 | this.active = true; 21 | this.addMesh(); 22 | this.saveVertices(); 23 | 24 | } 25 | 26 | update(audioData) { 27 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 28 | 29 | this.mesh.geometry.vertices[i].x = this.initialGeomVertices[i].x * (audioData[i] / 100); 30 | this.mesh.geometry.vertices[i].y = -this.initialGeomVertices[i].y * (audioData[i] / 200); 31 | this.mesh.geometry.vertices[i].z = this.initialGeomVertices[i].z * (audioData[i] / 100); 32 | } 33 | this.mesh.geometry.verticesNeedUpdate = true; 34 | this.rotation.y -= 0.005; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/objects/Ring.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import THREE from 'three'; 4 | import BaseThreeObj from './BaseThreeObj.js'; 5 | 6 | export default class Ring extends BaseThreeObj { 7 | constructor() { 8 | super(); 9 | 10 | this.initialGeomVertices = []; 11 | 12 | this.geom = new THREE.RingGeometry(20, 5, 32); 13 | 14 | this.mat = new THREE.MeshBasicMaterial({ 15 | color: 0xa66bbe, 16 | side: THREE.DoubleSide, 17 | wireframe: true, 18 | opacity: 0.2, 19 | transparent : true 20 | }); 21 | 22 | this.active = true; 23 | this.addMesh(); 24 | this.saveVertices(); 25 | } 26 | 27 | addMesh() { 28 | this.mesh = new THREE.Mesh(this.geom, this.mat); 29 | this.mesh.position.y = -10; 30 | this.mesh.rotation.x = 1.5; 31 | this.add(this.mesh); 32 | this.active = true; 33 | } 34 | 35 | update(audioData) { 36 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 37 | 38 | this.mesh.geometry.vertices[i].x = this.initialGeomVertices[i].x * (audioData[i] / 100); 39 | this.mesh.geometry.vertices[i].y = this.initialGeomVertices[i].y * (audioData[i] / 300); 40 | this.mesh.geometry.vertices[i].z = this.initialGeomVertices[i].z * (audioData[i] / 100); 41 | } 42 | this.mesh.geometry.verticesNeedUpdate = true; 43 | this.rotation.y += 0.005; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/objects/Sphere.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import THREE from 'three'; 4 | import BaseThreeObj from './BaseThreeObj.js'; 5 | 6 | export default class Sphere extends BaseThreeObj { 7 | constructor() { 8 | super(); 9 | 10 | this.initialGeomVertices = []; 11 | 12 | this.geom = new THREE.SphereGeometry(60, 40, 40); 13 | 14 | this.mat = new THREE.MeshBasicMaterial({ 15 | color: 0xFF5252, 16 | side: THREE.DoubleSide, 17 | wireframe: true 18 | }); 19 | 20 | this.active = true; 21 | this.addMesh(); 22 | this.saveVertices(); 23 | } 24 | 25 | update(audioData) { 26 | for (let i = 0; i < this.mesh.geometry.vertices.length; i++) { 27 | 28 | this.mesh.geometry.vertices[i].x = this.initialGeomVertices[i].x * (audioData[i] / 100); 29 | this.mesh.geometry.vertices[i].y = this.initialGeomVertices[i].y * (audioData[i] / 300); 30 | this.mesh.geometry.vertices[i].z = this.initialGeomVertices[i].z * (audioData[i] / 100); 31 | } 32 | this.mesh.geometry.verticesNeedUpdate = true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/styles/styles.css: -------------------------------------------------------------------------------- 1 | body, 2 | html 3 | { 4 | position : relative; 5 | overflow: hidden; 6 | 7 | width: 100%; 8 | height: 100%; 9 | margin: 0; 10 | padding: 0; 11 | } 12 | 13 | canvas 14 | { 15 | cursor: move; 16 | } 17 | 18 | p 19 | { 20 | font-size: .8em; 21 | 22 | color: white; 23 | } 24 | 25 | .mention 26 | { 27 | position: absolute; 28 | right: 25px; 29 | bottom: 30px; 30 | animation : fadeInLeft 1s ease-out; 31 | } 32 | 33 | .credits 34 | { 35 | position: absolute; 36 | right: 25px; 37 | bottom: 10px; 38 | animation : fadeInLeft 1s ease-out 0.5s backwards; 39 | } 40 | 41 | a 42 | { 43 | transition: all .3s ease; 44 | text-decoration: none; 45 | 46 | color: #e74c3c; 47 | } 48 | a:hover 49 | { 50 | color: #c0392b; 51 | } 52 | 53 | @keyframes fadeInLeft { 54 | 0%{ 55 | opacity: 0; 56 | transform: translateX(100%); 57 | } 58 | 100%{ 59 | opacity: 1; 60 | transform: translateX(0%); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /build/vendors/wagner/ShaderLoader.js: -------------------------------------------------------------------------------- 1 | var ShaderLoader = function() { 2 | 3 | this.loaded = 0; 4 | this.toLoad = 0; 5 | this.shaders = {}; 6 | this.queue = []; 7 | this.onLoadedCallback = function(){}; 8 | 9 | } 10 | 11 | ShaderLoader.prototype.add = function( id, name ) { 12 | 13 | this.toLoad++; 14 | this.shaders[ id ] = { 15 | id: id, 16 | name: name, 17 | content: '', 18 | loaded: false 19 | } 20 | this.queue.push( this.shaders[ id ] ); 21 | 22 | } 23 | 24 | ShaderLoader.prototype.processQueue = function() { 25 | 26 | var shader = this.queue.pop(); 27 | 28 | var oReq = new XMLHttpRequest(); 29 | oReq.onload = function() { 30 | this.loaded++; 31 | shader.content = oReq.responseText; 32 | if( this.loaded != this.toLoad ) { 33 | this.processQueue(); 34 | } else { 35 | this.onLoadedCallback(); 36 | } 37 | }.bind( this ); 38 | oReq.open( 'get', shader.name, true ); 39 | oReq.send(); 40 | 41 | } 42 | 43 | ShaderLoader.prototype.load = function() { 44 | 45 | this.processQueue(); 46 | 47 | } 48 | 49 | ShaderLoader.prototype.onLoaded = function( callback ) { 50 | 51 | if( this.loaded == this.toLoad ) callback(); 52 | else this.onLoadedCallback = callback; 53 | 54 | } 55 | 56 | ShaderLoader.prototype.get = function( id ) { 57 | 58 | function ShaderLoaderGetException( message ) { 59 | this.message = 'Cannot find shader "' + id + '".'; 60 | this.name = "ShaderLoaderGetException"; 61 | this.toString = function() { 62 | return this.message 63 | }; 64 | } 65 | 66 | var s = this.shaders[ id ]; 67 | if( !s ) { 68 | throw new ShaderLoaderGetException( id ); 69 | return; 70 | } 71 | 72 | return s.content; 73 | 74 | } -------------------------------------------------------------------------------- /build/vendors/wagner/Wagner.base.js: -------------------------------------------------------------------------------- 1 | WAGNER.BlendPass = function() { 2 | 3 | WAGNER.Pass.call( this ); 4 | WAGNER.log( 'BlendPass constructor' ); 5 | this.loadShader( 'blend-fs.glsl' ); 6 | 7 | this.params.mode = 1; 8 | this.params.opacity = 1; 9 | this.params.tInput2 = null; 10 | this.params.resolution2 = new THREE.Vector2(); 11 | this.params.sizeMode = 1; 12 | this.params.aspectRatio = 1; 13 | this.params.aspectRatio2 = 1; 14 | 15 | }; 16 | 17 | WAGNER.BlendMode = { 18 | Normal: 1, 19 | Dissolve: 2, 20 | Darken: 3, 21 | Multiply: 4, 22 | ColorBurn: 5, 23 | LinearBurn: 6, 24 | DarkerColor: 7, 25 | Lighten: 8, 26 | Screen: 9, 27 | ColorDodge: 10, 28 | LinearDodge: 11, 29 | LighterColor: 12, 30 | Overlay: 13, 31 | SoftLight: 14, 32 | HardLight: 15, 33 | VividLight: 16, 34 | LinearLight: 17, 35 | PinLight: 18, 36 | HardMix: 19, 37 | Difference: 20, 38 | Exclusion: 21, 39 | Substract: 22, 40 | Divide: 23 41 | }; 42 | 43 | WAGNER.BlendPass.prototype = Object.create( WAGNER.Pass.prototype ); 44 | 45 | WAGNER.BlendPass.prototype.run = function( c ) { 46 | 47 | this.shader.uniforms.mode.value = this.params.mode; 48 | this.shader.uniforms.opacity.value = this.params.opacity; 49 | this.shader.uniforms.tInput2.value = this.params.tInput2; 50 | this.shader.uniforms.sizeMode.value = this.params.sizeMode; 51 | this.shader.uniforms.aspectRatio.value = this.params.aspectRatio; 52 | this.shader.uniforms.aspectRatio2.value = this.params.aspectRatio2; 53 | c.pass( this.shader ); 54 | 55 | } 56 | 57 | WAGNER.InvertPass = function() { 58 | 59 | WAGNER.Pass.call( this ); 60 | WAGNER.log( 'InvertPass constructor' ); 61 | this.loadShader( 'invert-fs.glsl' ); 62 | 63 | }; 64 | 65 | WAGNER.InvertPass.prototype = Object.create( WAGNER.Pass.prototype ); 66 | 67 | WAGNER.SymetricPass = function() { 68 | 69 | WAGNER.Pass.call( this ); 70 | WAGNER.log( 'SymetricPass constructor' ); 71 | this.loadShader( 'symetric-fs.glsl' ); 72 | 73 | this.params.xReverse = false; 74 | this.params.yReverse = false; 75 | this.params.xMirror = false; 76 | this.params.yMirror = false; 77 | this.params.mirrorCenter = new THREE.Vector2( 0.5, 0.5); 78 | this.params.angle = 0; 79 | 80 | 81 | }; 82 | 83 | WAGNER.SymetricPass.prototype = Object.create( WAGNER.Pass.prototype ); 84 | 85 | WAGNER.SymetricPass.prototype.run = function( c ) { 86 | 87 | this.shader.uniforms.xReverse.value = this.params.xReverse; 88 | this.shader.uniforms.yReverse.value = this.params.yReverse; 89 | this.shader.uniforms.xMirror.value = this.params.xMirror; 90 | this.shader.uniforms.yMirror.value = this.params.yMirror; 91 | this.shader.uniforms.mirrorCenter.value = this.params.mirrorCenter; 92 | this.shader.uniforms.angle.value = this.params.angle; 93 | 94 | c.pass( this.shader ); 95 | 96 | } 97 | 98 | 99 | WAGNER.SepiaPass = function() { 100 | 101 | WAGNER.Pass.call( this ); 102 | WAGNER.log( 'SepiaPass constructor' ); 103 | this.loadShader( 'sepia-fs.glsl' ); 104 | 105 | this.params.amount = 1; 106 | 107 | }; 108 | 109 | WAGNER.SepiaPass.prototype = Object.create( WAGNER.Pass.prototype ); 110 | 111 | WAGNER.SepiaPass.prototype.run = function( c ) { 112 | 113 | this.shader.uniforms.amount.value = this.params.amount; 114 | c.pass( this.shader ); 115 | 116 | } 117 | 118 | WAGNER.BrightnessContrastPass = function() { 119 | 120 | WAGNER.Pass.call( this ); 121 | WAGNER.log( 'BrightnessContrastPass constructor' ); 122 | this.loadShader( 'brightness-contrast-fs.glsl' ); 123 | 124 | this.params.brightness = 1; 125 | this.params.contrast = 1; 126 | 127 | }; 128 | 129 | WAGNER.BrightnessContrastPass.prototype = Object.create( WAGNER.Pass.prototype ); 130 | 131 | WAGNER.BrightnessContrastPass.prototype.run = function( c ) { 132 | 133 | this.shader.uniforms.brightness.value = this.params.brightness; 134 | this.shader.uniforms.contrast.value = this.params.contrast; 135 | 136 | c.pass( this.shader ); 137 | 138 | } 139 | 140 | WAGNER.Pass.prototype.bindUniform = function( p, s, v, c ) { 141 | 142 | Object.defineProperty( p, v, { 143 | get : function(){ return s.uniforms[ id ].value; }, 144 | set : c, 145 | configurable : false 146 | } ); 147 | 148 | }; 149 | 150 | WAGNER.NoisePass = function() { 151 | 152 | WAGNER.Pass.call( this ); 153 | WAGNER.log( 'Noise Pass constructor' ); 154 | this.loadShader( 'noise-fs.glsl' ); 155 | 156 | this.params.amount = 0.1; 157 | this.params.speed = 0; 158 | 159 | }; 160 | 161 | WAGNER.NoisePass.prototype = Object.create( WAGNER.Pass.prototype ); 162 | 163 | WAGNER.NoisePass.prototype.run = function( c ) { 164 | 165 | this.shader.uniforms.amount.value = this.params.amount; 166 | this.shader.uniforms.speed.value = this.params.speed; 167 | c.pass( this.shader ); 168 | 169 | }; 170 | 171 | WAGNER.VignettePass = function() { 172 | 173 | WAGNER.Pass.call( this ); 174 | WAGNER.log( 'Vignette Pass constructor' ); 175 | this.loadShader( 'vignette-fs.glsl' ); 176 | 177 | this.params.amount = 1; 178 | this.params.falloff = 0.1; 179 | 180 | }; 181 | 182 | WAGNER.VignettePass.prototype = Object.create( WAGNER.Pass.prototype ); 183 | 184 | WAGNER.VignettePass.prototype.run = function( c ) { 185 | 186 | this.shader.uniforms.amount.value = this.params.amount; 187 | this.shader.uniforms.falloff.value = this.params.falloff; 188 | c.pass( this.shader ); 189 | 190 | }; 191 | 192 | WAGNER.Vignette2Pass = function() { 193 | 194 | WAGNER.Pass.call( this ); 195 | WAGNER.log( 'Vignette Pass constructor' ); 196 | this.loadShader( 'vignette2-fs.glsl' ); 197 | 198 | this.params.boost = 2; 199 | this.params.reduction = 2; 200 | 201 | }; 202 | 203 | WAGNER.Vignette2Pass.prototype = Object.create( WAGNER.Pass.prototype ); 204 | 205 | WAGNER.Vignette2Pass.prototype.run = function( c ) { 206 | 207 | this.shader.uniforms.boost.value = this.params.boost; 208 | this.shader.uniforms.reduction.value = this.params.reduction; 209 | c.pass( this.shader ); 210 | 211 | }; 212 | 213 | WAGNER.DenoisePass = function() { 214 | 215 | WAGNER.Pass.call( this ); 216 | WAGNER.log( 'Denoise Pass constructor' ); 217 | this.loadShader( 'denoise-fs.glsl' ); 218 | 219 | this.params.exponent = 5; 220 | this.params.strength = 10; 221 | 222 | }; 223 | 224 | WAGNER.DenoisePass.prototype = Object.create( WAGNER.Pass.prototype ); 225 | 226 | WAGNER.DenoisePass.prototype.run = function( c ) { 227 | 228 | this.shader.uniforms.exponent.value = this.params.exponent; 229 | this.shader.uniforms.strength.value = this.params.strength; 230 | c.pass( this.shader ); 231 | 232 | }; 233 | 234 | WAGNER.BoxBlurPass = function() { 235 | 236 | WAGNER.Pass.call( this ); 237 | WAGNER.log( 'BoxBlurPass Pass constructor' ); 238 | this.loadShader( 'box-blur2-fs.glsl' ); 239 | this.params.delta = new THREE.Vector2( 0, 0 ); 240 | this.params.taps = 1; 241 | 242 | }; 243 | 244 | WAGNER.BoxBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 245 | 246 | WAGNER.BoxBlurPass.prototype.run = function( c ) { 247 | 248 | this.shader.uniforms.delta.value.copy( this.params.delta ); 249 | /*for( var j = 0; j < this.params.taps; j++ ) { 250 | this.shader.uniforms.delta.value.copy( this.params.delta ); 251 | c.pass( this.shader ); 252 | }*/ 253 | c.pass( this.shader ); 254 | 255 | } 256 | 257 | WAGNER.FullBoxBlurPass = function() { 258 | 259 | WAGNER.Pass.call( this ); 260 | WAGNER.log( 'FullBoxBlurPass Pass constructor' ); 261 | this.boxPass = new WAGNER.BoxBlurPass(); 262 | this.params.amount = 20; 263 | this.params.taps = 1; 264 | 265 | }; 266 | 267 | WAGNER.FullBoxBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 268 | 269 | WAGNER.FullBoxBlurPass.prototype.isLoaded = function() { 270 | 271 | if( this.boxPass.isLoaded() ) { 272 | this.loaded = true; 273 | } 274 | return WAGNER.Pass.prototype.isLoaded.call( this ); 275 | 276 | }; 277 | 278 | WAGNER.FullBoxBlurPass.prototype.run = function( c ) { 279 | 280 | var s = this.params.amount; 281 | this.boxPass.params.delta.set( s, 0 ); 282 | this.boxPass.params.taps = this.params.taps; 283 | c.pass( this.boxPass ); 284 | this.boxPass.params.delta.set( 0, s ); 285 | c.pass( this.boxPass ); 286 | 287 | }; 288 | 289 | WAGNER.ZoomBlurPass = function() { 290 | 291 | WAGNER.Pass.call( this ); 292 | WAGNER.log( 'ZoomBlurPass Pass constructor' ); 293 | this.loadShader( 'zoom-blur-fs.glsl' ); 294 | 295 | this.params.center = new THREE.Vector2( 0.5, 0.5 ); 296 | this.params.strength = 2; 297 | 298 | }; 299 | 300 | WAGNER.ZoomBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 301 | 302 | WAGNER.ZoomBlurPass.prototype.run = function( c ) { 303 | 304 | this.shader.uniforms.center.value.copy ( this.params.center ); 305 | this.shader.uniforms.strength.value = this.params.strength; 306 | c.pass( this.shader ); 307 | 308 | }; 309 | 310 | WAGNER.MultiPassBloomPass = function( w, h ) { 311 | 312 | WAGNER.Pass.call( this ); 313 | WAGNER.log( 'MultiPassBloomPass Pass constructor' ); 314 | 315 | this.composer = null; 316 | 317 | this.tmpTexture = this.getOfflineTexture( w, h, true ); 318 | this.blurPass = new WAGNER.FullBoxBlurPass(); 319 | this.blendPass = new WAGNER.BlendPass(); 320 | this.zoomBlur = new WAGNER.ZoomBlurPass(); 321 | this.brightnessContrastPass = new WAGNER.BrightnessContrastPass(); 322 | 323 | this.width = w || 512; 324 | this.height = h || 512; 325 | 326 | this.params.blurAmount = 20; 327 | this.params.applyZoomBlur = false; 328 | this.params.zoomBlurStrength = 2; 329 | this.params.useTexture = false; 330 | this.params.zoomBlurCenter = new THREE.Vector2( 0,0 ); 331 | this.params.blendMode = WAGNER.BlendMode.Screen; 332 | 333 | }; 334 | 335 | WAGNER.MultiPassBloomPass.prototype = Object.create( WAGNER.Pass.prototype ); 336 | 337 | WAGNER.MultiPassBloomPass.prototype.isLoaded = function() { 338 | 339 | if( this.blurPass.isLoaded() && 340 | this.blendPass.isLoaded() && 341 | this.zoomBlur.isLoaded() ) { 342 | this.loaded = true; 343 | } 344 | return WAGNER.Pass.prototype.isLoaded.call( this ); 345 | 346 | }; 347 | 348 | WAGNER.MultiPassBloomPass.prototype.run = function( c ) { 349 | 350 | if( !this.composer ) { 351 | this.composer = new WAGNER.Composer( c.renderer, { useRGBA: true } ); 352 | this.composer.setSize( this.width, this.height ); 353 | //this.composer.setSize( this.tmpTexture.width, this.tmpTexture.height ); 354 | } 355 | 356 | /*var s = 0.5; 357 | if( c.width != this.tmpTexture.width / s || c.height != this.tmpTexture.height / s ) { 358 | this.tmpTexture = this.getOfflineTexture( c.width * s, c.height * s, true ); 359 | this.composer.setSize( this.tmpTexture.width, this.tmpTexture.height ); 360 | }*/ 361 | 362 | this.composer.reset(); 363 | 364 | if( this.params.useTexture === true ) { 365 | this.composer.setSource( this.params.glowTexture ); 366 | } else { 367 | this.composer.setSource( c.output ); 368 | /*this.brightnessContrastPass.params.brightness = -1; 369 | this.brightnessContrastPass.params.contrast = 5; 370 | this.composer.pass( this.brightnessContrastPass );*/ 371 | } 372 | 373 | this.blurPass.params.amount = this.params.blurAmount; 374 | this.composer.pass( this.blurPass ); 375 | 376 | if( this.params.applyZoomBlur ) { 377 | this.zoomBlur.params.center.set( .5 * this.composer.width, .5 * this.composer.height ); 378 | this.zoomBlur.params.strength = this.params.zoomBlurStrength; 379 | this.composer.pass( this.zoomBlur ); 380 | } 381 | 382 | if( this.params.useTexture === true ) { 383 | this.blendPass.params.mode = WAGNER.BlendMode.Screen; 384 | this.blendPass.params.tInput = this.params.glowTexture; 385 | c.pass( this.blendPass ); 386 | } 387 | 388 | this.blendPass.params.mode = this.params.blendMode; 389 | this.blendPass.params.tInput2 = this.composer.output; 390 | c.pass( this.blendPass ); 391 | 392 | }; 393 | 394 | WAGNER.CGAPass = function() { 395 | 396 | WAGNER.Pass.call( this ); 397 | WAGNER.log( 'CGA Pass constructor' ); 398 | this.loadShader( 'cga-fs.glsl', function() { 399 | this.shader.uniforms.pixelDensity.value = window.devicePixelRatio; 400 | } ); 401 | 402 | }; 403 | 404 | WAGNER.CGAPass.prototype = Object.create( WAGNER.Pass.prototype ); 405 | 406 | WAGNER.SobelEdgeDetectionPass = function() { 407 | 408 | WAGNER.Pass.call( this ); 409 | WAGNER.log( 'SobelEdgeDetectionPass Pass constructor' ); 410 | this.loadShader( 'sobel-fs.glsl' ); 411 | 412 | }; 413 | 414 | WAGNER.SobelEdgeDetectionPass.prototype = Object.create( WAGNER.Pass.prototype ); 415 | 416 | WAGNER.FreiChenEdgeDetectionPass = function() { 417 | 418 | WAGNER.Pass.call( this ); 419 | WAGNER.log( 'FreiChenEdgeDetectionPass Pass constructor' ); 420 | this.loadShader( 'frei-chen-fs.glsl' ); 421 | 422 | }; 423 | 424 | WAGNER.FreiChenEdgeDetectionPass.prototype = Object.create( WAGNER.Pass.prototype ); 425 | 426 | WAGNER.DirtPass = function() { 427 | 428 | WAGNER.Pass.call( this ); 429 | this.blendPass = new WAGNER.BlendPass(); 430 | this.dirtTexture = THREE.ImageUtils.loadTexture( WAGNER.assetsPath + '/textures/dirt8.jpg' ); 431 | 432 | this.params.blendMode = WAGNER.BlendMode.SoftLight; 433 | 434 | }; 435 | 436 | WAGNER.DirtPass.prototype = Object.create( WAGNER.Pass.prototype ); 437 | 438 | WAGNER.DirtPass.prototype.isLoaded = function() { 439 | 440 | if( this.blendPass.isLoaded() ) { 441 | this.loaded = true; 442 | } 443 | return WAGNER.Pass.prototype.isLoaded.call( this ); 444 | 445 | }; 446 | 447 | WAGNER.DirtPass.prototype.run = function( c ) { 448 | 449 | this.blendPass.params.sizeMode = 1; 450 | this.blendPass.params.mode = this.params.blendMode; 451 | this.blendPass.params.tInput2 = this.dirtTexture; 452 | if( this.dirtTexture.image ) { 453 | this.blendPass.params.resolution2.set( this.dirtTexture.image.width, this.dirtTexture.image.height ); 454 | this.blendPass.params.aspectRatio2 = this.dirtTexture.image.width / this.dirtTexture.image.height; 455 | } 456 | this.blendPass.params.aspectRatio = c.read.width / c.read.height; 457 | c.pass( this.blendPass ); 458 | 459 | }; 460 | 461 | WAGNER.GuidedBoxBlurPass = function() { 462 | 463 | WAGNER.Pass.call( this ); 464 | WAGNER.log( 'GuidedBoxBlurPass Pass constructor' ); 465 | this.loadShader( 'guided-box-blur2-fs.glsl' ); 466 | 467 | this.params.tBias = null; 468 | this.params.delta = new THREE.Vector2( 1., 0 ); 469 | this.params.invertBiasMap = false; 470 | this.params.isPacked = 0; 471 | this.params.from = 0; 472 | this.params.to = 1; 473 | 474 | }; 475 | 476 | WAGNER.GuidedBoxBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 477 | 478 | WAGNER.GuidedBoxBlurPass.prototype.run = function( c ) { 479 | 480 | this.shader.uniforms.tBias.value = this.params.tBias, 481 | this.shader.uniforms.delta.value.copy( this.params.delta ); 482 | this.shader.uniforms.delta.value.multiplyScalar( .0001 ); 483 | this.shader.uniforms.invertBiasMap.value = this.params.invertBiasMap; 484 | this.shader.uniforms.isPacked.value = this.params.isPacked; 485 | this.shader.uniforms.from.value = this.params.from; 486 | this.shader.uniforms.to.value = this.params.to; 487 | c.pass( this.shader ); 488 | 489 | } 490 | 491 | WAGNER.GuidedFullBoxBlurPass = function() { 492 | 493 | WAGNER.Pass.call( this ); 494 | WAGNER.log( 'FullBoxBlurPass Pass constructor' ); 495 | this.guidedBoxPass = new WAGNER.GuidedBoxBlurPass(); 496 | 497 | this.params.tBias = null; 498 | this.params.invertBiasMap = false; 499 | this.params.isPacked = 0; 500 | this.params.amount = 10; 501 | this.params.from = 0; 502 | this.params.to = 1; 503 | this.params.taps = 1; 504 | 505 | }; 506 | 507 | WAGNER.GuidedFullBoxBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 508 | 509 | WAGNER.GuidedFullBoxBlurPass.prototype.isLoaded = function() { 510 | 511 | if( this.guidedBoxPass.isLoaded() ) { 512 | this.loaded = true; 513 | } 514 | return WAGNER.Pass.prototype.isLoaded.call( this ); 515 | 516 | }; 517 | 518 | WAGNER.GuidedFullBoxBlurPass.prototype.run = function( c ) { 519 | 520 | this.guidedBoxPass.params.invertBiasMap = this.params.invertBiasMap; 521 | this.guidedBoxPass.params.isPacked = this.params.isPacked; 522 | this.guidedBoxPass.params.tBias = this.params.tBias; 523 | this.guidedBoxPass.params.from = this.params.from; 524 | this.guidedBoxPass.params.to = this.params.to; 525 | var s = this.params.amount; 526 | for( var j = 0; j < this.params.taps; j++ ) { 527 | this.guidedBoxPass.params.delta.set( s, 0 ); 528 | c.pass( this.guidedBoxPass ); 529 | this.guidedBoxPass.params.delta.set( 0, s ); 530 | c.pass( this.guidedBoxPass ); 531 | } 532 | 533 | }; 534 | 535 | WAGNER.PixelatePass = function() { 536 | 537 | WAGNER.Pass.call( this ); 538 | WAGNER.log( 'PixelatePass Pass constructor' ); 539 | this.loadShader( 'pixelate-fs.glsl' ); 540 | 541 | this.params.amount = 320; 542 | 543 | }; 544 | 545 | WAGNER.PixelatePass.prototype = Object.create( WAGNER.Pass.prototype ); 546 | 547 | WAGNER.PixelatePass.prototype.run = function( c ) { 548 | 549 | this.shader.uniforms.amount.value = this.params.amount; 550 | c.pass( this.shader ); 551 | 552 | } 553 | 554 | WAGNER.RGBSplitPass = function() { 555 | 556 | WAGNER.Pass.call( this ); 557 | WAGNER.log( 'RGBSplitPass Pass constructor' ); 558 | this.loadShader( 'rgb-split-fs.glsl', function() { 559 | } ); 560 | 561 | this.params.delta = new THREE.Vector2(); 562 | 563 | }; 564 | 565 | WAGNER.RGBSplitPass.prototype = Object.create( WAGNER.Pass.prototype ); 566 | 567 | WAGNER.RGBSplitPass.prototype.run = function( c ) { 568 | 569 | this.shader.uniforms.delta.value.copy( this.params.delta ); 570 | c.pass( this.shader ); 571 | 572 | } 573 | 574 | /* 575 | 576 | https://www.shadertoy.com/view/XssGz8 577 | 578 | Simulates Chromatic Aberration by linearly interpolating blur-weights from red to green to blue. 579 | Original idea by Kusma: https://github.com/kusma/vlee/blob/master/data/postprocess.fx 580 | Barrel Blur forked from https://www.shadertoy.com/view/XslGz8 581 | 582 | */ 583 | 584 | WAGNER.ChromaticAberrationPass = function() { 585 | 586 | WAGNER.Pass.call( this ); 587 | WAGNER.log( 'ChromaticAberrationPass Pass constructor' ); 588 | this.loadShader( 'chromatic-aberration-fs.glsl' ); 589 | 590 | }; 591 | 592 | WAGNER.ChromaticAberrationPass.prototype = Object.create( WAGNER.Pass.prototype ); 593 | 594 | WAGNER.BarrelBlurPass = function() { 595 | 596 | WAGNER.Pass.call( this ); 597 | WAGNER.log( 'BarrelBlurPass Pass constructor' ); 598 | this.loadShader( 'barrel-blur-fs.glsl' ); 599 | 600 | }; 601 | 602 | WAGNER.BarrelBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 603 | 604 | WAGNER.OldVideoPass = function() { 605 | 606 | WAGNER.Pass.call( this ); 607 | WAGNER.log( 'OldVideoPass Pass constructor' ); 608 | this.loadShader( 'old-video-fs.glsl' ); 609 | 610 | }; 611 | 612 | WAGNER.OldVideoPass.prototype = Object.create( WAGNER.Pass.prototype ); 613 | 614 | WAGNER.DotScreenPass = function() { 615 | 616 | WAGNER.Pass.call( this ); 617 | WAGNER.log( 'DotScreenPass Pass constructor' ); 618 | this.loadShader( 'dot-screen-fs.glsl' ); 619 | 620 | }; 621 | 622 | WAGNER.DotScreenPass.prototype = Object.create( WAGNER.Pass.prototype ); 623 | 624 | WAGNER.PoissonDiscBlurPass = function() { 625 | 626 | WAGNER.Pass.call( this ); 627 | WAGNER.log( 'PoissonDiscBlurPass Pass constructor' ); 628 | this.loadShader( 'poisson-disc-blur-fs.glsl' ); 629 | 630 | }; 631 | 632 | WAGNER.PoissonDiscBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 633 | 634 | WAGNER.CircularBlurPass = function() { 635 | 636 | WAGNER.Pass.call( this ); 637 | WAGNER.log( 'CircularBlurPass Pass constructor' ); 638 | this.loadShader( 'circular-blur-fs.glsl' ); 639 | 640 | }; 641 | 642 | WAGNER.CircularBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 643 | 644 | WAGNER.ToonPass = function() { 645 | 646 | WAGNER.Pass.call( this ); 647 | WAGNER.log( 'ToonPass Pass constructor' ); 648 | this.loadShader( 'toon-fs.glsl' ); 649 | 650 | }; 651 | 652 | WAGNER.ToonPass.prototype = Object.create( WAGNER.Pass.prototype ); 653 | 654 | WAGNER.FXAAPass = function() { 655 | 656 | WAGNER.Pass.call( this ); 657 | WAGNER.log( 'FXAA Pass constructor' ); 658 | this.loadShader( 'fxaa-fs.glsl' ); 659 | 660 | }; 661 | 662 | WAGNER.FXAAPass.prototype = Object.create( WAGNER.Pass.prototype ); 663 | 664 | WAGNER.HighPassPass = function() { 665 | 666 | WAGNER.Pass.call( this ); 667 | WAGNER.log( 'HighPass Pass constructor' ); 668 | this.loadShader( 'high-pass-fs.glsl' ); 669 | 670 | }; 671 | 672 | WAGNER.HighPassPass.prototype = Object.create( WAGNER.Pass.prototype ); 673 | 674 | WAGNER.GrayscalePass = function() { 675 | 676 | WAGNER.Pass.call( this ); 677 | WAGNER.log( 'GrayscalePass Pass constructor' ); 678 | this.loadShader( 'grayscale-fs.glsl' ); 679 | 680 | }; 681 | 682 | WAGNER.GrayscalePass.prototype = Object.create( WAGNER.Pass.prototype ); 683 | 684 | WAGNER.ASCIIPass = function() { 685 | 686 | WAGNER.Pass.call( this ); 687 | WAGNER.log( 'ASCIIPass Pass constructor' ); 688 | this.loadShader( 'ascii-fs.glsl', function() { 689 | this.shader.uniforms.tAscii.value = THREE.ImageUtils.loadTexture( WAGNER.assetsPath + '/ascii/8x16_ascii_font_sorted.gif' ); 690 | } ); 691 | 692 | }; 693 | 694 | WAGNER.ASCIIPass.prototype = Object.create( WAGNER.Pass.prototype ); 695 | 696 | WAGNER.LEDPass = function() { 697 | 698 | WAGNER.Pass.call( this ); 699 | WAGNER.log( 'LEDPass Pass constructor' ); 700 | this.loadShader( 'led-fs.glsl', function() { 701 | 702 | //this.shader.uniforms.noiseTexture.value = 1; 703 | } ); 704 | 705 | this.params.pixelSize = 10; 706 | this.params.tolerance = .25; 707 | this.params.pixelRadius = .25; 708 | this.params.luminanceSteps = 100; 709 | this.params.luminanceBoost = .2; 710 | this.params.colorBoost = .01; 711 | this.params.burntOutPercent = 50; 712 | }; 713 | 714 | WAGNER.LEDPass.prototype = Object.create( WAGNER.Pass.prototype ); 715 | 716 | WAGNER.LEDPass.prototype.run = function( c ) { 717 | 718 | this.shader.uniforms.pixelSize.value = this.params.pixelSize; 719 | this.shader.uniforms.tolerance.value = this.params.tolerance; 720 | this.shader.uniforms.pixelRadius.value = this.params.pixelRadius; 721 | this.shader.uniforms.luminanceSteps.value = this.params.luminanceSteps; 722 | this.shader.uniforms.luminanceBoost.value = this.params.luminanceBoost; 723 | this.shader.uniforms.colorBoost.value = this.params.colorBoost; 724 | this.shader.uniforms.burntOutPercent.value = this.params.burntOutPercent; 725 | 726 | c.pass( this.shader ); 727 | 728 | } 729 | 730 | WAGNER.HalftonePass = function() { 731 | 732 | WAGNER.Pass.call( this ); 733 | WAGNER.log( 'HalftonePass Pass constructor' ); 734 | this.loadShader( 'halftone-fs.glsl', function() { 735 | this.shader.uniforms.pixelSize.value = 6; 736 | } ); 737 | 738 | }; 739 | 740 | WAGNER.HalftonePass.prototype = Object.create( WAGNER.Pass.prototype ); 741 | 742 | WAGNER.Halftone2Pass = function() { 743 | 744 | WAGNER.Pass.call( this ); 745 | WAGNER.log( 'Halftone2Pass Pass constructor' ); 746 | this.loadShader( 'halftone2-fs.glsl' ); 747 | 748 | this.params.amount = 128; 749 | this.params.smoothness = .25; 750 | 751 | }; 752 | 753 | WAGNER.Halftone2Pass.prototype = Object.create( WAGNER.Pass.prototype ); 754 | 755 | WAGNER.Halftone2Pass.prototype.run = function( c ) { 756 | 757 | this.shader.uniforms.amount.value = this.params.amount; 758 | this.shader.uniforms.smoothness.value = this.params.smoothness; 759 | 760 | c.pass( this.shader ); 761 | 762 | } 763 | 764 | WAGNER.HalftoneCMYKPass = function() { 765 | 766 | WAGNER.Pass.call( this ); 767 | WAGNER.log( 'HalftoneCMYKPass Pass constructor' ); 768 | this.loadShader( 'halftone-cmyk-fs.glsl', function() { 769 | 770 | } ); 771 | 772 | }; 773 | 774 | WAGNER.HalftoneCMYKPass.prototype = Object.create( WAGNER.Pass.prototype ); 775 | 776 | WAGNER.CrossFadePass = function() { 777 | 778 | WAGNER.Pass.call( this ); 779 | WAGNER.log( 'CrossFadePass Pass constructor' ); 780 | this.loadShader( 'crossfade-fs.glsl' ); 781 | 782 | this.params.tInput2 = null; 783 | this.params.tFadeMap = null; 784 | this.params.amount = 0; 785 | 786 | }; 787 | 788 | WAGNER.CrossFadePass.prototype = Object.create( WAGNER.Pass.prototype ); 789 | 790 | WAGNER.CrossFadePass.prototype.run = function( c ) { 791 | 792 | this.shader.uniforms.tInput2.value = this.params.tInput2; 793 | this.shader.uniforms.tFadeMap.value = this.params.tFadeMap; 794 | this.shader.uniforms.amount.value = this.params.amount; 795 | 796 | c.pass( this.shader ); 797 | 798 | } 799 | 800 | WAGNER.SSAOPass = function() { 801 | 802 | WAGNER.Pass.call( this ); 803 | WAGNER.log( 'SSAOPass Pass constructor' ); 804 | this.loadShader( 'ssao-fs.glsl', function( fs ) { 805 | 806 | /*this.shader.uniforms.pSphere.value = [ 807 | new THREE.Vector3(-0.010735935, 0.01647018, 0.0062425877), 808 | new THREE.Vector3(-0.06533369, 0.3647007, -0.13746321), 809 | new THREE.Vector3(-0.6539235, -0.016726388, -0.53000957), 810 | new THREE.Vector3(0.40958285, 0.0052428036, -0.5591124), 811 | new THREE.Vector3(-0.1465366, 0.09899267, 0.15571679), 812 | new THREE.Vector3(-0.44122112, -0.5458797, 0.04912532), 813 | new THREE.Vector3(0.03755566, -0.10961345, -0.33040273), 814 | new THREE.Vector3(0.019100213, 0.29652783, 0.066237666), 815 | new THREE.Vector3(0.8765323, 0.011236004, 0.28265962), 816 | new THREE.Vector3(0.29264435, -0.40794238, 0.15964167) 817 | ];*/ 818 | 819 | } ); 820 | 821 | this.params.texture = null; 822 | this.params.isPacked = false; 823 | this.params.onlyOcclusion = false; 824 | 825 | this.blurPass = new WAGNER.FullBoxBlurPass(); 826 | this.blendPass = new WAGNER.BlendPass(); 827 | this.composer = null; 828 | 829 | }; 830 | 831 | WAGNER.SSAOPass.prototype = Object.create( WAGNER.Pass.prototype ); 832 | 833 | WAGNER.SSAOPass.prototype.run = function( c ) { 834 | 835 | if( !this.composer ) { 836 | var s = 4; 837 | this.composer = new WAGNER.Composer( c.renderer, { useRGBA: true } ); 838 | this.composer.setSize( c.width / s, c.height / s ); 839 | } 840 | 841 | this.composer.reset(); 842 | 843 | this.composer.setSource( c.output ); 844 | 845 | this.shader.uniforms.tDepth.value = this.params.texture; 846 | //this.shader.uniforms.isPacked.value = this.params.isPacked; 847 | this.shader.uniforms.onlyOcclusion.value = this.params.onlyOcclusion; 848 | this.composer.pass( this.shader ); 849 | 850 | this.blurPass.params.amount = .1; 851 | this.composer.pass( this.blurPass ); 852 | 853 | if( this.params.onlyOcclusion ) { 854 | c.setSource( this.composer.output ); 855 | } else { 856 | this.blendPass.params.mode = WAGNER.BlendMode.Multiply; 857 | this.blendPass.params.tInput2 = this.composer.output; 858 | 859 | c.pass( this.blendPass ); 860 | } 861 | 862 | } 863 | 864 | WAGNER.SimpleSSAOPass = function() { 865 | 866 | WAGNER.Pass.call( this ); 867 | WAGNER.log( 'SimpleSSAOPass Pass constructor' ); 868 | this.loadShader( 'ssao-simple-fs.glsl', function( fs ) { 869 | } ); 870 | 871 | this.params.texture = null; 872 | this.params.onlyOcclusion = 0; 873 | this.params.zNear = 1; 874 | this.params.zFar = 10000; 875 | this.params.strength = 1; 876 | 877 | }; 878 | 879 | WAGNER.SimpleSSAOPass.prototype = Object.create( WAGNER.Pass.prototype ); 880 | 881 | WAGNER.SimpleSSAOPass.prototype.run = function( c ) { 882 | 883 | this.shader.uniforms.tDepth.value = this.params.texture; 884 | // this.shader.uniforms.onlyOcclusion.value = this.params.onlyOcclusion; 885 | this.shader.uniforms.zNear.value = this.params.zNear; 886 | this.shader.uniforms.zFar.value = this.params.zFar; 887 | this.shader.uniforms.strength.value = this.params.strength; 888 | 889 | c.pass( this.shader ); 890 | 891 | } 892 | 893 | WAGNER.DirectionalBlurPass = function() { 894 | 895 | WAGNER.Pass.call( this ); 896 | WAGNER.log( 'Directional Blur Pass constructor' ); 897 | this.loadShader( 'guided-directional-blur-fs.glsl', function( fs ) { 898 | 899 | } ); 900 | 901 | this.params.tBias = null; 902 | this.params.delta = .1; 903 | 904 | } 905 | 906 | WAGNER.DirectionalBlurPass.prototype = Object.create( WAGNER.Pass.prototype ); 907 | 908 | WAGNER.DirectionalBlurPass.prototype.run = function( c ) { 909 | 910 | this.shader.uniforms.tBias.value = this.params.tBias; 911 | this.shader.uniforms.delta.value = this.params.delta; 912 | 913 | c.pass( this.shader ); 914 | 915 | } 916 | 917 | WAGNER.BleachPass = function() { 918 | 919 | WAGNER.Pass.call( this ); 920 | WAGNER.log( 'Bleach Pass constructor' ); 921 | this.loadShader( 'bleach-fs.glsl', function( fs ) { 922 | 923 | } ); 924 | 925 | this.params.amount = 1; 926 | 927 | } 928 | 929 | WAGNER.BleachPass.prototype = Object.create( WAGNER.Pass.prototype ); 930 | 931 | WAGNER.BleachPass.prototype.run = function( c ) { 932 | 933 | this.shader.uniforms.amount.value = this.params.amount; 934 | 935 | c.pass( this.shader ); 936 | 937 | } 938 | 939 | WAGNER.DOFPass = function() { 940 | 941 | WAGNER.Pass.call( this ); 942 | WAGNER.log( 'DOFPass Pass constructor' ); 943 | this.loadShader( 'dof-fs.glsl' ); 944 | 945 | this.params.focalDistance = 0; 946 | this.params.aperture = .005; 947 | this.params.tBias = null; 948 | this.params.blurAmount = 1; 949 | 950 | }; 951 | 952 | WAGNER.DOFPass.prototype = Object.create( WAGNER.Pass.prototype ); 953 | 954 | WAGNER.DOFPass.prototype.run = function( c ) { 955 | 956 | this.shader.uniforms.tBias.value = this.params.tBias; 957 | this.shader.uniforms.focalDistance.value = this.params.focalDistance; 958 | this.shader.uniforms.aperture.value = this.params.aperture; 959 | this.shader.uniforms.blurAmount.value = this.params.blurAmount; 960 | 961 | this.shader.uniforms.delta.value.set( 1, 0 ); 962 | c.pass( this.shader ); 963 | 964 | this.shader.uniforms.delta.value.set( 0, 1 ); 965 | c.pass( this.shader ); 966 | 967 | } -------------------------------------------------------------------------------- /build/vendors/wagner/Wagner.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | 'use strict'; 4 | 5 | var WAGNER = WAGNER || {}; 6 | 7 | WAGNER.vertexShadersPath = './vertex-shaders'; 8 | WAGNER.fragmentShadersPath = './fragment-shaders'; 9 | WAGNER.assetsPath = './assets'; 10 | 11 | WAGNER.log = function() { 12 | //console.log( Array.prototype.slice.call( arguments ).join( ' ' ) ); 13 | }; 14 | 15 | WAGNER.Composer = function( renderer, settings ) { 16 | 17 | this.width = 1; 18 | this.height = 1; 19 | 20 | this.settings = settings || {}; 21 | this.useRGBA = this.settings.useRGBA || false; 22 | 23 | this.renderer = renderer; 24 | this.copyPass = new WAGNER.CopyPass( this.settings ); 25 | 26 | this.scene = new THREE.Scene(); 27 | this.quad = new THREE.Mesh( 28 | new THREE.PlaneBufferGeometry( 1, 1 ), 29 | this.defaultMaterial 30 | ); 31 | this.scene.add( this.quad ); 32 | this.camera = new THREE.OrthographicCamera( 1, 1, 1, 1, -10000, 10000 ); 33 | 34 | this.front = new THREE.WebGLRenderTarget(1, 1, { 35 | minFilter: this.settings.minFilter !== undefined ? this.settings.minFilter : THREE.LinearFilter, 36 | magFilter: this.settings.magFilter !== undefined ? this.settings.magFilter : THREE.LinearFilter, 37 | wrapS: this.settings.wrapS !== undefined ? this.settings.wrapS : THREE.ClampToEdgeWrapping, 38 | wrapT: this.settings.wrapT !== undefined ? this.settings.wrapT : THREE.ClampToEdgeWrapping, 39 | format: this.useRGBA ? THREE.RGBAFormat : THREE.RGBFormat, 40 | type: this.settings.type !== undefined ? this.settings.type : THREE.UnsignedByteType, 41 | stencilBuffer: this.settings.stencilBuffer !== undefined ? this.settings.stencilBuffer : true 42 | }); 43 | 44 | this.back = this.front.clone(); 45 | 46 | this.startTime = Date.now(); 47 | 48 | this.passes = {}; 49 | 50 | }; 51 | 52 | WAGNER.Composer.prototype.linkPass = function( id, pass ) { 53 | 54 | function WagnerLoadPassException( message ) { 55 | this.message = 'Pass "' + id + '" already loaded.'; 56 | this.name = "WagnerLoadPassException"; 57 | this.toString = function() { 58 | return this.message; 59 | }; 60 | } 61 | 62 | if( this.passes[ id ] ) { 63 | throw new WagnerLoadPassException( id, pass ); 64 | } 65 | 66 | this.passes[ id ] = pass; 67 | 68 | }; 69 | 70 | WAGNER.Composer.prototype.swapBuffers = function() { 71 | 72 | this.output = this.write; 73 | this.input = this.read; 74 | 75 | var t = this.write; 76 | this.write = this.read; 77 | this.read = t; 78 | 79 | }; 80 | 81 | WAGNER.Composer.prototype.render = function( scene, camera, keep, output ) { 82 | 83 | if( this.copyPass.isLoaded() ) { 84 | if( keep ) this.swapBuffers(); 85 | this.renderer.render( scene, camera, output?output:this.write, true ); 86 | if( !output ) this.swapBuffers(); 87 | } 88 | 89 | }; 90 | 91 | WAGNER.Composer.prototype.toScreen = function() { 92 | 93 | if( this.copyPass.isLoaded() ) { 94 | this.quad.material = this.copyPass.shader; 95 | this.quad.material.uniforms.tInput.value = this.read; 96 | this.quad.material.uniforms.resolution.value.set( this.width, this.height ); 97 | this.renderer.render( this.scene, this.camera ); 98 | } 99 | 100 | }; 101 | 102 | WAGNER.Composer.prototype.toTexture = function( t ) { 103 | 104 | if( this.copyPass.isLoaded() ) { 105 | this.quad.material = this.copyPass.shader; 106 | this.quad.material.uniforms.tInput.value = this.read; 107 | this.renderer.render( this.scene, this.camera, t, false ); 108 | } 109 | 110 | }; 111 | 112 | WAGNER.Composer.prototype.pass = function( pass ) { 113 | 114 | if( pass instanceof WAGNER.Stack ) { 115 | 116 | this.passStack(pass); 117 | 118 | } else { 119 | 120 | if( typeof pass === 'string' ) { 121 | this.quad.material = this.passes[ pass ]; 122 | } 123 | if( pass instanceof THREE.ShaderMaterial ) { 124 | this.quad.material = pass; 125 | } 126 | if( pass instanceof WAGNER.Pass ) { 127 | if( !pass.isLoaded() ) return; 128 | pass.run( this ); 129 | return; 130 | } 131 | 132 | if( !pass.isSim ) this.quad.material.uniforms.tInput.value = this.read; 133 | 134 | this.quad.material.uniforms.resolution.value.set( this.width, this.height ); 135 | this.quad.material.uniforms.time.value = 0.001 * ( Date.now() - this.startTime ); 136 | this.renderer.render( this.scene, this.camera, this.write, false ); 137 | this.swapBuffers(); 138 | 139 | } 140 | 141 | }; 142 | 143 | WAGNER.Composer.prototype.passStack = function( stack ) { 144 | 145 | stack.getPasses().forEach( function ( pass ) { 146 | 147 | this.pass( pass ); 148 | 149 | }.bind(this)); 150 | 151 | }; 152 | 153 | WAGNER.Composer.prototype.reset = function() { 154 | 155 | this.read = this.front; 156 | this.write = this.back; 157 | 158 | this.output = this.write; 159 | this.input = this.read; 160 | 161 | }; 162 | 163 | WAGNER.Composer.prototype.setSource = function( src ) { 164 | 165 | if( this.copyPass.isLoaded() ) { 166 | this.quad.material = this.copyPass.shader; 167 | this.quad.material.uniforms.tInput.value = src; 168 | this.renderer.render( this.scene, this.camera, this.write, true ); 169 | this.swapBuffers(); 170 | } 171 | 172 | }; 173 | 174 | WAGNER.Composer.prototype.setSize = function( w, h ) { 175 | 176 | this.width = w; 177 | this.height = h; 178 | 179 | this.camera.projectionMatrix.makeOrthographic( w / - 2, w / 2, h / 2, h / - 2, this.camera.near, this.camera.far ); 180 | this.quad.scale.set( w, h, 1 ); 181 | 182 | var rt = this.front.clone(); 183 | rt.width = w; 184 | rt.height = h; 185 | if( this.quad.material instanceof WAGNER.Pass ) this.quad.material.uniforms.tInput.value = rt; 186 | this.front = rt; 187 | 188 | rt = this.back.clone(); 189 | rt.width = w; 190 | rt.height = h; 191 | this.back = rt; 192 | 193 | }; 194 | 195 | WAGNER.Composer.prototype.defaultMaterial = new THREE.MeshBasicMaterial(); 196 | 197 | WAGNER.loadShader = function( file, callback ) { 198 | 199 | var oReq = new XMLHttpRequest(); 200 | oReq.onload = function() { 201 | var content = oReq.responseText; 202 | callback( content ); 203 | }.bind( this ); 204 | oReq.onerror = function() { 205 | 206 | function WagnerLoadShaderException( f ) { 207 | this.message = 'Shader "' + f + '" couldn\'t be loaded.'; 208 | this.name = "WagnerLoadShaderException"; 209 | this.toString = function() { 210 | return this.message; 211 | }; 212 | } 213 | throw new WagnerLoadShaderException( file ); 214 | }; 215 | oReq.onabort = function() { 216 | 217 | function WagnerLoadShaderException( f ) { 218 | this.message = 'Shader "' + f + '" load was aborted.'; 219 | this.name = "WagnerLoadShaderException"; 220 | this.toString = function() { 221 | return this.message; 222 | }; 223 | } 224 | throw new WagnerLoadShaderException( file ); 225 | }; 226 | oReq.open( 'get', file, true ); 227 | oReq.send(); 228 | 229 | }; 230 | 231 | WAGNER.processShader = function( vertexShaderCode, fragmentShaderCode ) { 232 | 233 | WAGNER.log( 'Processing Shader | Performing uniform Reflection...' ); 234 | 235 | var regExp = /uniform\s+([^\s]+)\s+([^\s]+)\s*;/gi; 236 | var regExp2 = /uniform\s+([^\s]+)\s+([^\s]+)\s*\[\s*(\w+)\s*\]*\s*;/gi; 237 | 238 | var typesMap = { 239 | 240 | sampler2D: { type: 't', value: function() { return new THREE.Texture(); } }, 241 | samplerCube: { type: 't', value: function() {} }, 242 | 243 | bool: { type: 'b', value: function() { return 0; } }, 244 | int: { type: 'i', value: function() { return 0; } }, 245 | float: { type: 'f', value: function() { return 0; } }, 246 | 247 | vec2: { type: 'v2', value: function() { return new THREE.Vector2(); } }, 248 | vec3: { type: 'v3', value: function() { return new THREE.Vector3(); } }, 249 | vec4: { type: 'v4', value: function() { return new THREE.Vector4(); } }, 250 | 251 | bvec2: { type: 'v2', value: function() { return new THREE.Vector2(); } }, 252 | bvec3: { type: 'v3', value: function() { return new THREE.Vector3(); } }, 253 | bvec4: { type: 'v4', value: function() { return new THREE.Vector4(); } }, 254 | 255 | ivec2: { type: 'v2', value: function() { return new THREE.Vector2(); } }, 256 | ivec3: { type: 'v3', value: function() { return new THREE.Vector3(); } }, 257 | ivec4: { type: 'v4', value: function() { return new THREE.Vector4(); } }, 258 | 259 | mat2: { type: 'v2', value: function() { return new THREE.Matrix2(); } }, 260 | mat3: { type: 'v3', value: function() { return new THREE.Matrix3(); } }, 261 | mat4: { type: 'v4', value: function() { return new THREE.Matrix4(); } } 262 | 263 | }; 264 | 265 | var arrayTypesMap = { 266 | float: { type: 'fv', value: function() { return []; } }, 267 | vec3: { type: 'v3v', value: function() { return []; } } 268 | }; 269 | 270 | var matches; 271 | var uniforms = { 272 | resolution: { type: 'v2', value: new THREE.Vector2( 1, 1 ), default: true }, 273 | time: { type: 'f', value: Date.now(), default: true }, 274 | tInput: { type: 't', value: new THREE.Texture(), default: true } 275 | }; 276 | 277 | var uniformType, uniformName, arraySize; 278 | 279 | while( ( matches = regExp.exec( fragmentShaderCode ) ) !== null) { 280 | if( matches.index === regExp.lastIndex) { 281 | regExp.lastIndex++; 282 | } 283 | uniformType = matches[ 1 ]; 284 | uniformName = matches[ 2 ]; 285 | WAGNER.log( ' > SINGLE', uniformType, uniformName ); 286 | uniforms[ uniformName ] = { 287 | type: typesMap[ uniformType ].type, 288 | value: typesMap[ uniformType ].value() 289 | }; 290 | } 291 | 292 | while( ( matches = regExp2.exec( fragmentShaderCode ) ) !== null) { 293 | if( matches.index === regExp.lastIndex) { 294 | regExp.lastIndex++; 295 | } 296 | uniformType = matches[ 1 ]; 297 | uniformName = matches[ 2 ]; 298 | arraySize = matches[ 3 ]; 299 | WAGNER.log( ' > ARRAY', arraySize, uniformType, uniformName ); 300 | uniforms[ uniformName ] = { 301 | type: arrayTypesMap[ uniformType ].type, 302 | value: arrayTypesMap[ uniformType ].value() 303 | }; 304 | } 305 | 306 | WAGNER.log( 'Uniform reflection completed. Compiling...' ); 307 | 308 | var shader = new THREE.ShaderMaterial( { 309 | uniforms: uniforms, 310 | vertexShader: vertexShaderCode, 311 | fragmentShader: fragmentShaderCode, 312 | shading: THREE.FlatShading, 313 | depthWrite: false, 314 | depthTest: false, 315 | transparent: true 316 | } ); 317 | 318 | WAGNER.log( 'Compiled' ); 319 | 320 | return shader; 321 | 322 | }; 323 | 324 | WAGNER.Pass = function() { 325 | 326 | WAGNER.log( 'Pass constructor' ); 327 | this.shader = null; 328 | this.loaded = null; 329 | this.params = {}; 330 | this.isSim = false; 331 | 332 | }; 333 | 334 | WAGNER.Pass.prototype.loadShader = function( id, c ) { 335 | 336 | var self = this; 337 | var vs = 'varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); }'; 338 | WAGNER.loadShader( WAGNER.fragmentShadersPath + '/' + id, function( fs ) { 339 | self.shader = WAGNER.processShader( vs, fs ); 340 | //self.mapUniforms( self.shader.uniforms ); 341 | if( c ) c.apply( self ); 342 | } ); 343 | 344 | }; 345 | 346 | WAGNER.Pass.prototype.mapUniforms = function( uniforms ) { 347 | 348 | var params = this.params; 349 | 350 | for( var j in uniforms ) { 351 | if( !uniforms[ j ].default ) { 352 | (function( id ) { 353 | Object.defineProperty( params, id, { 354 | get : function(){ return uniforms[ id ].value; }, 355 | set : function( v ){ uniforms[ id ].value = v; }, 356 | configurable : false 357 | } ); 358 | })( j ); 359 | } 360 | } 361 | 362 | }; 363 | 364 | WAGNER.Pass.prototype.run = function( c ) { 365 | 366 | //WAGNER.log( 'Pass run' ); 367 | c.pass( this.shader ); 368 | 369 | }; 370 | 371 | WAGNER.Pass.prototype.isLoaded = function() { 372 | 373 | if( this.loaded === null ) { 374 | if( this.shader instanceof THREE.ShaderMaterial ) { 375 | this.loaded = true; 376 | } 377 | } else { 378 | return this.loaded; 379 | } 380 | 381 | }; 382 | 383 | WAGNER.Pass.prototype.getOfflineTexture = function( w, h, useRGBA ){ 384 | 385 | var rtTexture = new THREE.WebGLRenderTarget( w, h, { 386 | minFilter: THREE.LinearFilter, 387 | magFilter: THREE.LinearFilter, 388 | format: useRGBA?THREE.RGBAFormat:THREE.RGBFormat 389 | } ); 390 | 391 | return rtTexture; 392 | 393 | }; 394 | 395 | WAGNER.CopyPass = function() { 396 | 397 | WAGNER.Pass.call( this ); 398 | WAGNER.log( 'CopyPass constructor' ); 399 | this.loadShader( 'copy-fs.glsl' ); 400 | 401 | }; 402 | 403 | WAGNER.CopyPass.prototype = Object.create( WAGNER.Pass.prototype ); 404 | 405 | WAGNER.GenericPass = function( fragmentShaderSource, c ) { 406 | 407 | WAGNER.Pass.call( this ); 408 | var self = this; 409 | WAGNER.loadShader( WAGNER.vertexShadersPath + '/orto-vs.glsl', function( vs ) { 410 | WAGNER.loadShader( fragmentShaderSource, function( fs ) { 411 | self.shader = WAGNER.processShader( vs, fs ); 412 | if( c ) c.apply( self ); 413 | } ); 414 | } ); 415 | 416 | } 417 | 418 | WAGNER.GenericPass.prototype = Object.create( WAGNER.Pass.prototype ); 419 | 420 | 421 | 422 | WAGNER.Stack = function ( shadersPool ) { 423 | 424 | this.passItems = []; 425 | this.shadersPool = shadersPool; 426 | this.passes = []; 427 | 428 | }; 429 | 430 | WAGNER.Stack.prototype.addPass = function ( shaderName, enabled, params, index ) { 431 | 432 | var length, 433 | passItem = { 434 | shaderName: shaderName, 435 | enabled: enabled || false 436 | }; 437 | 438 | //todo: use and store params values 439 | 440 | this.passItems.push( passItem ); 441 | length = this.passItems.length; 442 | 443 | this.updatePasses(); 444 | 445 | if ( index ) { 446 | 447 | return this.movePassToIndex( this.passItems[ length ], index ); 448 | 449 | } else { 450 | 451 | return length - 1; 452 | 453 | } 454 | 455 | }; 456 | 457 | WAGNER.Stack.prototype.removePass = function ( index ) { 458 | 459 | this.passItems.splice(index, 1); 460 | this.updatePasses(); 461 | 462 | }; 463 | 464 | WAGNER.Stack.prototype.enablePass = function ( index ) { 465 | 466 | this.passItems[ index ].enabled = true; 467 | this.updatePasses(); 468 | 469 | }; 470 | 471 | WAGNER.Stack.prototype.disablePass = function ( index ) { 472 | 473 | this.passItems[ index ].enabled = false; 474 | this.updatePasses(); 475 | 476 | }; 477 | 478 | WAGNER.Stack.prototype.isPassEnabled = function ( index ) { 479 | 480 | return this.passItems[ index ].enabled; 481 | 482 | }; 483 | 484 | WAGNER.Stack.prototype.movePassToIndex = function ( index, destIndex ) { 485 | 486 | this.passItems.splice( destIndex, 0, this.passItems.splice( index, 1 )[ 0 ] ); 487 | this.updatePasses(); 488 | return destIndex; //TODO: check if destIndex is final index 489 | 490 | }; 491 | 492 | WAGNER.Stack.prototype.reverse = function () { 493 | 494 | this.passItems.reverse(); 495 | this.updatePasses(); 496 | 497 | }; 498 | 499 | WAGNER.Stack.prototype.updatePasses = function () { 500 | 501 | this.passes = this.shadersPool.getPasses( this.passItems ); 502 | 503 | // init default params for new passItems 504 | this.passItems.forEach( function ( passItem, index ) { 505 | 506 | if (passItem.params === undefined) { 507 | 508 | passItem.params = JSON.parse(JSON.stringify(this.passes[index].params)); // clone params without reference to the real shader instance params 509 | // console.log('updatePasses', passItem, passItem.params); 510 | 511 | } 512 | 513 | }.bind(this) ); 514 | 515 | // console.log('Updated stack passes list from shaders pool. Stack contains', this.passes.length, 'shaders, and there are', this.shadersPool.availableShaders.length, 'shaders in the pool.'); 516 | 517 | }; 518 | 519 | WAGNER.Stack.prototype.getPasses = function () { 520 | 521 | return this.passes; 522 | 523 | }; 524 | 525 | 526 | 527 | 528 | WAGNER.ShadersPool = function () { 529 | 530 | this.availableShaders = []; 531 | 532 | }; 533 | 534 | WAGNER.ShadersPool.prototype.getPasses = function ( passItems ) { 535 | 536 | var pass, 537 | passes = []; 538 | 539 | this.availableShaders.forEach( function ( availableShader ) { 540 | 541 | availableShader.used = false; 542 | 543 | } ); 544 | 545 | if ( passItems ) { 546 | 547 | passItems.forEach( function ( passItem, index ) { 548 | 549 | if ( passItem.enabled ) { 550 | 551 | pass = this.getShaderFromPool( passItem.shaderName ); 552 | 553 | if ( passItem.params ) { 554 | 555 | pass.params = this.extendParams(pass.params, passItem.params) 556 | 557 | } 558 | 559 | passes.push( pass ); 560 | 561 | } 562 | 563 | }.bind( this ) ); 564 | 565 | } 566 | 567 | return passes; 568 | 569 | }; 570 | 571 | WAGNER.ShadersPool.prototype.getShaderFromPool = function ( shaderName ) { 572 | 573 | var pass, 574 | shaderItem; 575 | 576 | if ( shaderName && WAGNER[ shaderName ] ) { 577 | 578 | for (var i = this.availableShaders.length - 1; i >= 0; i--) { 579 | 580 | shaderItem = this.availableShaders[i]; 581 | 582 | if ( !shaderItem.used && shaderItem.name === shaderName ) { 583 | 584 | shaderItem.used = true; 585 | pass = shaderItem.pass; 586 | break; 587 | 588 | } 589 | 590 | }; 591 | 592 | if ( !pass ) { 593 | 594 | pass = new WAGNER[ shaderName ](); 595 | 596 | shaderItem = { 597 | pass: pass, 598 | name: shaderName, 599 | used: true 600 | }; 601 | 602 | this.availableShaders.push( shaderItem ); 603 | 604 | } 605 | 606 | return pass; 607 | 608 | } 609 | 610 | }; 611 | 612 | 613 | WAGNER.ShadersPool.prototype.extendParams = function(target, source) { 614 | 615 | var obj = {}, 616 | i = 0, 617 | il = arguments.length, 618 | key; 619 | 620 | for (; i < il; i++) { 621 | 622 | for (key in arguments[i]) { 623 | 624 | if (arguments[i].hasOwnProperty(key)) { 625 | 626 | obj[key] = arguments[i][key]; 627 | 628 | } 629 | } 630 | } 631 | 632 | return obj; 633 | 634 | } 635 | 636 | 637 | 638 | 639 | 640 | window.WAGNER = WAGNER; 641 | })(); 642 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/art-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | varying vec2 vUv; 4 | float level( in float value, in float min, in float max ) { 5 | return min / 255.0 + ( max - min ) * value / 255.0; 6 | } 7 | float gamma( in float value, in float g ) { 8 | return pow( value, 1.0 / g ); 9 | } 10 | void main(void) { 11 | 12 | vec4 color = texture2D( tInput, vUv ); 13 | float r = color.r; 14 | float g = color.g; 15 | float b = color.b; 16 | r = level( r, 0.0, 255.0 ); 17 | g = level( g, 0.0, 184.0 ); 18 | b = level( b, 0.0, 113.0 ); 19 | r = gamma( r, 1.10 ); 20 | g = gamma( g, 0.95 ); 21 | b = gamma( b, 1.04 ); 22 | r = level( r, 10.0, 240.0 ); 23 | g = level( g, 10.0, 240.0 ); 24 | b = level( b, 10.0, 240.0 ); 25 | r = gamma( r, 0.87 ); 26 | g = gamma( g, 0.87 ); 27 | b = gamma( b, 0.87 ); 28 | float yL = .2126 * color.r + .7152 * color.g + .0722 * color.b; 29 | r += yL; g += yL; b += yL; 30 | gl_FragColor = vec4( r, g, b, color.a ); 31 | 32 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/ascii-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform vec2 resolution; 3 | uniform sampler2D tInput; 4 | uniform sampler2D tAscii; 5 | const vec2 fontSize = vec2(8.0,16.0); 6 | 7 | vec4 lookupASCII(float asciiValue){ 8 | 9 | vec2 pos = mod(gl_FragCoord.xy,fontSize.xy); 10 | 11 | pos = pos / vec2(2048.0,16.0); 12 | pos.x += asciiValue; 13 | return vec4(texture2D(tAscii,pos).rgb,1.0); 14 | 15 | } 16 | 17 | void main(void) { 18 | 19 | vec2 invViewport = vec2(1.0) / resolution; 20 | vec2 pixelSize = fontSize; 21 | vec4 sum = vec4(0.0); 22 | vec2 uvClamped = vUv-mod(vUv,pixelSize * invViewport); 23 | for (float x=0.0;x aspectRatio ) { 63 | vUv2.x = vUv.x * aspectRatio / aspectRatio2; 64 | vUv2.x += .5 * ( 1. - aspectRatio / aspectRatio2 ); 65 | vUv2.y = vUv.y; 66 | } 67 | 68 | if( aspectRatio2 < aspectRatio ) { 69 | vUv2.x = vUv.x; 70 | vUv2.y = vUv.y * aspectRatio2 / aspectRatio; 71 | vUv2.y += .5 * ( 1. - aspectRatio2 / aspectRatio ); 72 | } 73 | 74 | } 75 | 76 | vec4 base = texture2D( tInput, vUv ); 77 | vec4 blend = texture2D( tInput2, vUv2 ); 78 | 79 | if( mode == 1 ) { // normal 80 | 81 | gl_FragColor = base; 82 | gl_FragColor.a *= opacity; 83 | return; 84 | 85 | } 86 | 87 | if( mode == 2 ) { // dissolve 88 | 89 | } 90 | 91 | if( mode == 3 ) { // darken 92 | 93 | gl_FragColor = min( base, blend ); 94 | return; 95 | 96 | } 97 | 98 | if( mode == 4 ) { // multiply 99 | 100 | gl_FragColor = base * blend; 101 | return; 102 | 103 | } 104 | 105 | if( mode == 5 ) { // color burn 106 | 107 | gl_FragColor = vec4( 108 | applyColorBurnToChannel( base.r, blend.r ), 109 | applyColorBurnToChannel( base.g, blend.g ), 110 | applyColorBurnToChannel( base.b, blend.b ), 111 | applyColorBurnToChannel( base.a, blend.a ) 112 | ); 113 | return; 114 | 115 | } 116 | 117 | if( mode == 6 ) { // linear burn 118 | 119 | gl_FragColor = max(base + blend - 1.0, 0.0); 120 | return; 121 | 122 | } 123 | 124 | if( mode == 7 ) { // darker color 125 | 126 | } 127 | 128 | if( mode == 8 ) { // lighten 129 | 130 | gl_FragColor = max( base, blend ); 131 | return; 132 | 133 | } 134 | 135 | if( mode == 9 ) { // screen 136 | 137 | gl_FragColor = (1.0 - ((1.0 - base) * (1.0 - blend))); 138 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 139 | return; 140 | 141 | } 142 | 143 | if( mode == 10 ) { // color dodge 144 | 145 | gl_FragColor = vec4( 146 | applyColorDodgeToChannel( base.r, blend.r ), 147 | applyColorDodgeToChannel( base.g, blend.g ), 148 | applyColorDodgeToChannel( base.b, blend.b ), 149 | applyColorDodgeToChannel( base.a, blend.a ) 150 | ); 151 | return; 152 | 153 | } 154 | 155 | if( mode == 11 ) { // linear dodge 156 | 157 | gl_FragColor = min(base + blend, 1.0); 158 | return; 159 | 160 | } 161 | 162 | if( mode == 12 ) { // lighter color 163 | 164 | } 165 | 166 | if( mode == 13 ) { // overlay 167 | 168 | gl_FragColor = gl_FragColor = vec4( 169 | applyOverlayToChannel( base.r, blend.r ), 170 | applyOverlayToChannel( base.g, blend.g ), 171 | applyOverlayToChannel( base.b, blend.b ), 172 | applyOverlayToChannel( base.a, blend.a ) 173 | ); 174 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 175 | 176 | return; 177 | 178 | } 179 | 180 | if( mode == 14 ) { // soft light 181 | 182 | gl_FragColor = vec4( 183 | applySoftLightToChannel( base.r, blend.r ), 184 | applySoftLightToChannel( base.g, blend.g ), 185 | applySoftLightToChannel( base.b, blend.b ), 186 | applySoftLightToChannel( base.a, blend.a ) 187 | ); 188 | return; 189 | 190 | } 191 | 192 | if( mode == 15 ) { // hard light 193 | 194 | gl_FragColor = vec4( 195 | applyOverlayToChannel( base.r, blend.r ), 196 | applyOverlayToChannel( base.g, blend.g ), 197 | applyOverlayToChannel( base.b, blend.b ), 198 | applyOverlayToChannel( base.a, blend.a ) 199 | ); 200 | gl_FragColor = gl_FragColor * opacity + base * ( 1. - opacity ); 201 | return; 202 | 203 | } 204 | 205 | if( mode == 16 ) { // vivid light 206 | 207 | } 208 | 209 | if( mode == 17 ) { // linear light 210 | 211 | gl_FragColor = vec4( 212 | applyLinearLightToChannel( base.r, blend.r ), 213 | applyLinearLightToChannel( base.g, blend.g ), 214 | applyLinearLightToChannel( base.b, blend.b ), 215 | applyLinearLightToChannel( base.a, blend.a ) 216 | ); 217 | return; 218 | 219 | } 220 | 221 | if( mode == 18 ) { // pin light 222 | 223 | } 224 | 225 | if( mode == 19 ) { // hard mix 226 | 227 | } 228 | 229 | if( mode == 20 ) { // difference 230 | 231 | gl_FragColor = abs( base - blend ); 232 | gl_FragColor.a = base.a + blend.b; 233 | return; 234 | 235 | } 236 | 237 | if( mode == 21 ) { // exclusion 238 | 239 | gl_FragColor = base + blend - 2. * base * blend; 240 | 241 | } 242 | 243 | if( mode == 22 ) { // substract 244 | 245 | } 246 | 247 | if( mode == 23 ) { // divide 248 | 249 | } 250 | 251 | gl_FragColor = vec4( 1., 0., 1., 1. ); 252 | 253 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/bloom-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | 4 | void main() 5 | { 6 | vec4 sum = vec4(0); 7 | vec2 texcoord = vUv; 8 | 9 | for( int i= -4 ;i < 4; i++) 10 | { 11 | for ( int j = -3; j < 3; j++) 12 | { 13 | sum += texture2D(tInput, texcoord + vec2(j, i)*0.004) * 0.25; 14 | } 15 | } 16 | if (texture2D(tInput, texcoord).r < 0.3) 17 | { 18 | gl_FragColor = sum*sum*0.012 + texture2D(tInput, texcoord); 19 | } 20 | else 21 | { 22 | if (texture2D(tInput, texcoord).r < 0.5) 23 | { 24 | gl_FragColor = sum*sum*0.009 + texture2D(tInput, texcoord); 25 | } 26 | else 27 | { 28 | gl_FragColor = sum*sum*0.0075 + texture2D(tInput, texcoord); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/bloom2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | float kernel = .005; 4 | float scale = 1.; 5 | float thresh = 1.; 6 | 7 | void main() 8 | { 9 | vec4 sum = vec4(0); 10 | 11 | // mess of for loops due to gpu compiler/hardware limitations 12 | int j=-2; 13 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 14 | j=-1; 15 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 16 | j=0; 17 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 18 | j=1; 19 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 20 | j=2; 21 | for( int i=-2; i<=2; i++) sum+=texture2D(tInput,vUv+vec2(i,j)*kernel); 22 | sum/=25.0; 23 | 24 | vec4 s=texture2D(tInput, vUv); 25 | gl_FragColor=s; 26 | 27 | // use the blurred colour if it's bright enough 28 | if (length(sum)>thresh) 29 | { 30 | gl_FragColor +=sum*scale; 31 | } 32 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/bokeh-poison-dof-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform float radius; 5 | uniform float amount; 6 | uniform vec2 resolution; 7 | uniform float focalDistance; 8 | uniform float aperture; 9 | 10 | // Bokeh disc. 11 | // by David Hoskins. 12 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 13 | 14 | #define ITERATIONS 150.0 15 | 16 | #define ONEOVER_ITR 1.0 / ITERATIONS 17 | #define PI 3.141596 18 | 19 | // This is (3.-sqrt(5.0))*PI radians, which doesn't precompiled for some reason. 20 | // The compiler is a dunce I tells-ya!! 21 | #define GOLDEN_ANGLE 2.39996323 22 | 23 | //------------------------------------------------------------------------------------------- 24 | // This creates the 2D offset for the next point. 25 | // (r-1.0) is the same as sqrt(0, 1, 2, 3...) 26 | vec2 Sample(in float theta, inout float r) 27 | { 28 | r += 1.0 / r; 29 | return (r-1.0) * vec2(cos(theta), sin(theta)) * .06; 30 | } 31 | 32 | //------------------------------------------------------------------------------------------- 33 | vec3 Bokeh(sampler2D tex, vec2 uv, float radius, float amount) 34 | { 35 | vec3 acc = vec3(0.0); 36 | vec3 div = vec3(0.0); 37 | vec2 pixel = vec2(resolution.y/resolution.x, 1.0) * radius * .025; 38 | float r = 1.0; 39 | for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE) 40 | { 41 | 42 | vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz; 43 | // col = col * col * 1.2; // ...contrast it for better highlights 44 | vec3 bokeh = vec3(.5) + pow(col, vec3(10.0)) * amount; 45 | acc += col * bokeh; 46 | div += bokeh; 47 | } 48 | return acc / div; 49 | } 50 | 51 | float sampleBias( vec2 uv ) { 52 | float d = abs( texture2D( tBias, uv ).r - focalDistance ); 53 | return d * aperture;//min( d * aperture, .005 ); 54 | //return unpack_depth( texture2D( tBias, uv ) ); 55 | } 56 | 57 | //------------------------------------------------------------------------------------------- 58 | void main(void) 59 | { 60 | vec2 uv = gl_FragCoord.xy / resolution.xy; 61 | float bias = sampleBias( vUv ); 62 | 63 | gl_FragColor = vec4(Bokeh(tInput, uv*vec2(1.0, 1.0), radius * bias, amount ), 1.0); 64 | 65 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/bokeh-poison-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform float radius; 5 | uniform float amount; 6 | uniform vec2 resolution; 7 | 8 | // Bokeh disc. 9 | // by David Hoskins. 10 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. 11 | 12 | #define ITERATIONS 150.0 13 | 14 | #define ONEOVER_ITR 1.0 / ITERATIONS 15 | #define PI 3.141596 16 | 17 | // This is (3.-sqrt(5.0))*PI radians, which doesn't precompiled for some reason. 18 | // The compiler is a dunce I tells-ya!! 19 | #define GOLDEN_ANGLE 2.39996323 20 | 21 | //------------------------------------------------------------------------------------------- 22 | // This creates the 2D offset for the next point. 23 | // (r-1.0) is the same as sqrt(0, 1, 2, 3...) 24 | vec2 Sample(in float theta, inout float r) 25 | { 26 | r += 1.0 / r; 27 | return (r-1.0) * vec2(cos(theta), sin(theta)) * .06; 28 | } 29 | 30 | //------------------------------------------------------------------------------------------- 31 | vec3 Bokeh(sampler2D tex, vec2 uv, float radius, float amount) 32 | { 33 | vec3 acc = vec3(0.0); 34 | vec3 div = vec3(0.0); 35 | vec2 pixel = vec2(resolution.y/resolution.x, 1.0) * radius * .025; 36 | float r = 1.0; 37 | for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE) 38 | { 39 | 40 | vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz; 41 | // col = col * col * 1.2; // ...contrast it for better highlights 42 | vec3 bokeh = vec3(.5) + pow(col, vec3(10.0)) * amount; 43 | acc += col * bokeh; 44 | div += bokeh; 45 | } 46 | return acc / div; 47 | } 48 | 49 | //------------------------------------------------------------------------------------------- 50 | void main(void) 51 | { 52 | vec2 uv = gl_FragCoord.xy / resolution.xy; 53 | 54 | gl_FragColor = vec4(Bokeh(tInput, uv*vec2(1.0, 1.0), radius * ( 1. - texture2D( tBias, uv ).r ), amount ), 1.0); 55 | 56 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/box-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | 5 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 6 | 7 | void main() { 8 | 9 | vec4 color=vec4(0.0); 10 | float total=0.0; 11 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 12 | for(float t=-30.0;t<=30.0;t++){ 13 | float percent=(t+offset-0.5)/30.0; 14 | float weight=1.0-abs(percent); 15 | vec4 sample=texture2D(tInput,vUv+delta*percent); 16 | sample.rgb*=sample.a; 17 | color+=sample*weight; 18 | total+=weight; 19 | } 20 | 21 | gl_FragColor=color/total; 22 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 23 | 24 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/box-blur2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | uniform vec2 resolution; 5 | 6 | void main() { 7 | 8 | vec4 sum = vec4( 0. ); 9 | vec2 inc = delta / resolution; 10 | 11 | sum += texture2D( tInput, ( vUv - inc * 4. ) ) * 0.051; 12 | sum += texture2D( tInput, ( vUv - inc * 3. ) ) * 0.0918; 13 | sum += texture2D( tInput, ( vUv - inc * 2. ) ) * 0.12245; 14 | sum += texture2D( tInput, ( vUv - inc * 1. ) ) * 0.1531; 15 | sum += texture2D( tInput, ( vUv + inc * 0. ) ) * 0.1633; 16 | sum += texture2D( tInput, ( vUv + inc * 1. ) ) * 0.1531; 17 | sum += texture2D( tInput, ( vUv + inc * 2. ) ) * 0.12245; 18 | sum += texture2D( tInput, ( vUv + inc * 3. ) ) * 0.0918; 19 | sum += texture2D( tInput, ( vUv + inc * 4. ) ) * 0.051; 20 | 21 | gl_FragColor = sum; 22 | 23 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/brightness-contrast-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform float brightness; 2 | uniform float contrast; 3 | uniform sampler2D tInput; 4 | 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | 9 | vec3 color = texture2D(tInput, vUv).rgb; 10 | vec3 colorContrasted = (color) * contrast; 11 | vec3 bright = colorContrasted + vec3(brightness,brightness,brightness); 12 | gl_FragColor.rgb = bright; 13 | gl_FragColor.a = 1.; 14 | 15 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/cga-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | uniform sampler2D cgaMap; 5 | uniform float pixelDensity; 6 | 7 | void main() { 8 | 9 | float size = 2. * pixelDensity; 10 | float dSize = 2. * size; 11 | 12 | float amount = resolution.x / size; 13 | float d = 1.0 / amount; 14 | float ar = resolution.x / resolution.y; 15 | float sx = floor( vUv.x / d ) * d; 16 | d = ar / amount; 17 | float sy = floor( vUv.y / d ) * d; 18 | 19 | vec4 base = texture2D( tInput, vec2( sx, sy ) ); 20 | 21 | float lum = .2126 * base.r + .7152 * base.g + .0722 * base.b; 22 | float o = floor( 6. * lum ); 23 | 24 | vec3 c1; 25 | vec3 c2; 26 | 27 | vec3 black = vec3( 0. ); 28 | vec3 light = vec3( 85., 255., 255. ) / 255.; 29 | vec3 dark = vec3( 254., 84., 255. ) / 255.; 30 | vec3 white = vec3( 1. ); 31 | 32 | /*dark = vec3( 89., 255., 17. ) / 255.; 33 | light = vec3( 255., 87., 80. ) / 255.; 34 | white = vec3( 255., 255., 0. ) / 255.;*/ 35 | 36 | /*light = vec3( 85., 255., 255. ) / 255.; 37 | dark = vec3( 255., 86., 80. ) / 255.;*/ 38 | 39 | if( o == 0. ) { c1 = black; c2 = c1; } 40 | if( o == 1. ) { c1 = black; c2 = dark; } 41 | if( o == 2. ) { c1 = dark; c2 = c1; } 42 | if( o == 3. ) { c1 = dark; c2 = light; } 43 | if( o == 4. ) { c1 = light; c2 = c1; } 44 | if( o == 5. ) { c1 = light; c2 = white; } 45 | if( o == 6. ) { c1 = white; c2 = c1; } 46 | 47 | if( mod( gl_FragCoord.x, dSize ) > size ) { 48 | if( mod( gl_FragCoord.y, dSize ) > size ) { 49 | base.rgb = c1; 50 | } else { 51 | base.rgb = c2; 52 | } 53 | } else { 54 | if( mod( gl_FragCoord.y, dSize ) > size ) { 55 | base.rgb = c2; 56 | } else { 57 | base.rgb = c1; 58 | } 59 | } 60 | 61 | gl_FragColor = vec4( base.rgb, base.a ); 62 | 63 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/chromatic-aberration-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | 4 | vec2 barrelDistortion(vec2 coord, float amt) { 5 | vec2 cc = coord - 0.5; 6 | float dist = dot(cc, cc); 7 | return coord + cc * dist * amt; 8 | } 9 | 10 | float sat( float t ) 11 | { 12 | return clamp( t, 0.0, 1.0 ); 13 | } 14 | 15 | float linterp( float t ) { 16 | return sat( 1.0 - abs( 2.0*t - 1.0 ) ); 17 | } 18 | 19 | float remap( float t, float a, float b ) { 20 | return sat( (t - a) / (b - a) ); 21 | } 22 | 23 | vec4 spectrum_offset( float t ) { 24 | vec4 ret; 25 | float lo = step(t,0.5); 26 | float hi = 1.0-lo; 27 | float w = linterp( remap( t, 1.0/6.0, 5.0/6.0 ) ); 28 | ret = vec4(lo,1.0,hi, 1.) * vec4(1.0-w, w, 1.0-w, 1.); 29 | 30 | return pow( ret, vec4(1.0/2.2) ); 31 | } 32 | 33 | const float max_distort = 2.2; 34 | const int num_iter = 12; 35 | const float reci_num_iter_f = 1.0 / float(num_iter); 36 | 37 | void main() 38 | { 39 | vec2 uv=(gl_FragCoord.xy/resolution.xy*.5)+.25; 40 | 41 | vec4 sumcol = vec4(0.0); 42 | vec4 sumw = vec4(0.0); 43 | for ( int i=0; i lumaMax ) ) { 48 | gl_FragColor = rgbA; 49 | } else { 50 | gl_FragColor = rgbB; 51 | } 52 | 53 | //gl_FragColor = vec4( texture2D( tInput,vUv ).xyz, 1. ); 54 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/fxaa2-fs.glsl: -------------------------------------------------------------------------------- 1 | // FXAA shader, GLSL code adapted from: 2 | // http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA 3 | // Whitepaper describing the technique: 4 | // http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf 5 | 6 | // from: https://code.google.com/p/processing/source/browse/trunk/processing/java/libraries/opengl/examples/Shaders/FXAA/data/fxaa.glsl?r=9668 7 | 8 | uniform sampler2D tInput; 9 | uniform vec2 resolution; 10 | varying vec2 vUv; 11 | // The inverse of the texture dimensions along X and Y 12 | vec2 texcoordOffset = 1. / resolution; 13 | 14 | //varying vec4 vertColor; 15 | vec4 vertTexcoord = vec4( vUv, 1., 1. ); 16 | 17 | void main() { 18 | // The parameters are hardcoded for now, but could be 19 | // made into uniforms to control fromt he program. 20 | float FXAA_SPAN_MAX = 8.0; 21 | float FXAA_REDUCE_MUL = 1.0/8.0; 22 | float FXAA_REDUCE_MIN = (1.0/128.0); 23 | 24 | vec3 rgbNW = texture2D(tInput, vertTexcoord.xy + (vec2(-1.0, -1.0) * texcoordOffset)).xyz; 25 | vec3 rgbNE = texture2D(tInput, vertTexcoord.xy + (vec2(+1.0, -1.0) * texcoordOffset)).xyz; 26 | vec3 rgbSW = texture2D(tInput, vertTexcoord.xy + (vec2(-1.0, +1.0) * texcoordOffset)).xyz; 27 | vec3 rgbSE = texture2D(tInput, vertTexcoord.xy + (vec2(+1.0, +1.0) * texcoordOffset)).xyz; 28 | vec3 rgbM = texture2D(tInput, vertTexcoord.xy).xyz; 29 | 30 | vec3 luma = vec3(0.299, 0.587, 0.114); 31 | float lumaNW = dot(rgbNW, luma); 32 | float lumaNE = dot(rgbNE, luma); 33 | float lumaSW = dot(rgbSW, luma); 34 | float lumaSE = dot(rgbSE, luma); 35 | float lumaM = dot( rgbM, luma); 36 | 37 | float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); 38 | float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); 39 | 40 | vec2 dir; 41 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 42 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 43 | 44 | float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN); 45 | 46 | float rcpDirMin = 1.0/(min(abs(dir.x), abs(dir.y)) + dirReduce); 47 | 48 | dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), 49 | max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset; 50 | 51 | vec3 rgbA = (1.0/2.0) * ( 52 | texture2D(tInput, vertTexcoord.xy + dir * (1.0/3.0 - 0.5)).xyz + 53 | texture2D(tInput, vertTexcoord.xy + dir * (2.0/3.0 - 0.5)).xyz); 54 | vec3 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( 55 | texture2D(tInput, vertTexcoord.xy + dir * (0.0/3.0 - 0.5)).xyz + 56 | texture2D(tInput, vertTexcoord.xy + dir * (3.0/3.0 - 0.5)).xyz); 57 | float lumaB = dot(rgbB, luma); 58 | 59 | if((lumaB < lumaMin) || (lumaB > lumaMax)){ 60 | gl_FragColor.xyz=rgbA; 61 | } else { 62 | gl_FragColor.xyz=rgbB; 63 | } 64 | gl_FragColor.a = 1.0; 65 | 66 | //gl_FragColor *= vertColor; 67 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/grayscale-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | 5 | void main() { 6 | 7 | vec3 luma = vec3( .299, 0.587, 0.114 ); 8 | vec4 color = texture2D( tInput, vUv ); 9 | gl_FragColor = vec4( vec3( dot( color.rgb, luma ) ), color.a ); 10 | 11 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/guided-box-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform vec2 delta; 5 | uniform float invertBiasMap; 6 | uniform float isPacked; 7 | uniform float from; 8 | uniform float to; 9 | 10 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 11 | 12 | float unpack_depth(const in vec4 color) { 13 | return ( color.r * 256. * 256. * 256. + color.g * 256. * 256. + color.b * 256. + color.a ) / ( 256. * 256. * 256. ); 14 | } 15 | 16 | float sampleBias( vec2 uv ) { 17 | return smoothstep( from, to, texture2D( tBias, uv ).r ); 18 | //return unpack_depth( texture2D( tBias, uv ) ); 19 | } 20 | 21 | void main() { 22 | 23 | float f = sampleBias( vUv ); 24 | if( invertBiasMap == 1. ) f = 1. - f; 25 | vec4 o = texture2D( tInput,vUv ); 26 | vec4 color=vec4(0.0); 27 | float total=0.0; 28 | vec2 tDelta = f * delta; 29 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 30 | for(float t=-30.0;t<=30.0;t++){ 31 | float percent=(t+offset-0.5)/30.0; 32 | float weight=1.0-abs(percent); 33 | vec4 sample=texture2D(tInput,vUv+tDelta*percent); 34 | sample.rgb*=sample.a; 35 | color+=sample*weight; 36 | total+=weight; 37 | } 38 | 39 | if( total == 0. ) total = 1.; 40 | gl_FragColor = mix( o, color/total, f ); 41 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 42 | 43 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/guided-box-blur2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform vec2 delta; 5 | uniform float invertBiasMap; 6 | uniform float isPacked; 7 | uniform float from; 8 | uniform float to; 9 | 10 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 11 | 12 | float unpack_depth(const in vec4 color) { 13 | return ( color.r * 256. * 256. * 256. + color.g * 256. * 256. + color.b * 256. + color.a ) / ( 256. * 256. * 256. ); 14 | } 15 | 16 | float sampleBias( vec2 uv ) { 17 | float b = ( texture2D( tBias, uv ).r - from ) / ( to - from ); 18 | b = clamp( b, 0., 1. ); 19 | if( invertBiasMap == 1. ) b = 1. - b; 20 | return b; 21 | //return unpack_depth( texture2D( tBias, uv ) ); 22 | } 23 | 24 | void main() { 25 | 26 | vec4 sum = vec4( 0. ); 27 | float bias = sampleBias( vUv ); 28 | 29 | sum += texture2D( tInput, ( vUv - bias * delta * 4. ) ) * 0.051; 30 | sum += texture2D( tInput, ( vUv - bias * delta * 3. ) ) * 0.0918; 31 | sum += texture2D( tInput, ( vUv - bias * delta * 2. ) ) * 0.12245; 32 | sum += texture2D( tInput, ( vUv - bias * delta * 1. ) ) * 0.1531; 33 | sum += texture2D( tInput, ( vUv + bias * delta * 0. ) ) * 0.1633; 34 | sum += texture2D( tInput, ( vUv + bias * delta * 1. ) ) * 0.1531; 35 | sum += texture2D( tInput, ( vUv + bias * delta * 2. ) ) * 0.12245; 36 | sum += texture2D( tInput, ( vUv + bias * delta * 3. ) ) * 0.0918; 37 | sum += texture2D( tInput, ( vUv + bias * delta * 4. ) ) * 0.051; 38 | 39 | gl_FragColor = sum; 40 | 41 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/guided-directional-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform sampler2D tBias; 4 | uniform float delta; 5 | 6 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 7 | 8 | float sampleBias( vec2 uv ) { 9 | //return texture2D( tBias, uv ).r; 10 | vec3 luma = vec3( .299, 0.587, 0.114 ); 11 | return dot( texture2D( tBias, uv ).rgb, luma ); 12 | } 13 | 14 | void main() { 15 | 16 | float f = sampleBias( vUv ); 17 | float a = - f * 3.14159; 18 | vec4 o = texture2D( tInput,vUv ); 19 | vec4 color=vec4(0.0); 20 | float total=0.0; 21 | vec2 tDelta = delta * vec2( cos( a ), sin( a ) ); 22 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 23 | for(float t=-30.0;t<=30.0;t++){ 24 | float percent=(t+offset-0.5)/30.0; 25 | float weight=1.0-abs(percent); 26 | vec4 sample=texture2D(tInput,vUv+tDelta*percent); 27 | sample.rgb*=sample.a; 28 | color+=sample*weight; 29 | total+=weight; 30 | } 31 | 32 | if( total == 0. ) total = 1.; 33 | gl_FragColor = color / total; 34 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 35 | 36 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/halftone-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | uniform float pixelSize; 5 | 6 | void main(void) { 7 | 8 | vec2 p = vUv; 9 | 10 | float pixelsPerRow = resolution.x / pixelSize; 11 | float pixelsPerCol = resolution.y / pixelSize; 12 | 13 | float pixelSizeX = 1.0 / pixelsPerRow; 14 | float dx = mod(p.x, pixelSizeX ) - pixelSizeX *0.5; 15 | float pixelSizeY = 1.0 / pixelsPerCol; 16 | float dy = mod(p.y, pixelSizeY ) - pixelSizeY * 0.5; 17 | float pixelSize = pixelSizeX;//sqrt( pixelSizeX * pixelSizeX + pixelSizeY + pixelSizeY ); 18 | 19 | p.x -= dx; 20 | p.y -= dy; 21 | vec3 col = texture2D(tInput, p).rgb; 22 | vec3 luma = vec3( .299, 0.587, 0.114 ); 23 | float bright = dot( col.rgb, luma ); 24 | 25 | float dist = sqrt(dx*dx + dy*dy); 26 | float rad = bright * pixelSize * 1.; 27 | float m = step( dist, rad ); 28 | 29 | vec3 col2 = mix(vec3(0.0), vec3(1.0), m); 30 | gl_FragColor = vec4(col2, 1.0); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/halftone2-fs.glsl: -------------------------------------------------------------------------------- 1 | // adapted from http://www.is-real.net/experiments/webgl/wwdc2014/ 2 | 3 | varying vec2 vUv; 4 | uniform sampler2D tInput; 5 | uniform vec2 resolution; 6 | uniform float pixelSize; 7 | uniform float amount; 8 | uniform float smoothness; 9 | 10 | float antialiasStep( float threshold, float value ) { 11 | 12 | float afwidth = amount * ( 1.0 / 200.0 ); 13 | return smoothstep( threshold - afwidth, threshold, value ); 14 | 15 | } 16 | 17 | float roundedBox( vec2 position, vec2 size, float radius ) { 18 | 19 | return length( max( abs( position ) - size, 0.0 ) ) - radius; 20 | 21 | } 22 | 23 | void main(void) { 24 | 25 | float ar = resolution.x / resolution.y; 26 | vec2 nearest = 2.0 * fract( amount * vec2( 1., 1. / ar ) * vUv ) - 1.0; 27 | float distX = length( nearest.x ); 28 | float distY = length( nearest.y ); 29 | float dist = length( nearest ); 30 | 31 | vec2 d = vec2( 1. / amount ) * vec2( 1., ar ); 32 | vec2 tUv = floor( vUv / d ) * d; 33 | vec3 dotColorCalculation = texture2D( tInput, tUv ).rgb; 34 | vec3 luma = vec3( .299, 0.587, 0.114 ); 35 | vec3 gradientColor = dotColorCalculation ;//texture2D( tInput, vUv ).rgb; 36 | float radius = sqrt( dot( dotColorCalculation, luma ) ); 37 | 38 | vec3 bkgColor = vec3( 0. );//1.0, 1.0, 1.0 ); 39 | 40 | vec4 halfToneDotColor = vec4( mix( gradientColor.rgb, bkgColor, antialiasStep( radius, dist ) ), 1.0 ); 41 | 42 | float b = roundedBox( vec2( distX+0.02, distY+0.02 ), vec2( .5 * radius ), 0.4 * radius ); 43 | vec4 halfToneSquircleColor = vec4( mix( bkgColor, gradientColor.rgb, smoothstep( smoothness, 0.0, b) ), 1.0 ); 44 | 45 | gl_FragColor = halfToneSquircleColor; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/high-pass-fs.glsl: -------------------------------------------------------------------------------- 1 | // from: http://www.ozone3d.net/smf/index.php?topic=68.0 2 | 3 | uniform sampler2D tInput; 4 | uniform vec2 resolution; 5 | 6 | //uniform float kernel[9]; 7 | 8 | varying vec2 vUv; 9 | 10 | float step_w = 1.0/resolution.x; 11 | float step_h = 1.0/resolution.y; 12 | 13 | void main(void) 14 | { 15 | 16 | vec2 offset[9]; 17 | float kernel[ 9 ]; 18 | 19 | offset[ 0 ] = vec2(-step_w, -step_h); 20 | offset[ 1 ] = vec2(0.0, -step_h); 21 | offset[ 2 ] = vec2(step_w, -step_h); 22 | 23 | offset[ 3 ] = vec2(-step_w, 0.0); 24 | offset[ 4 ] = vec2(0.0, 0.0); 25 | offset[ 5 ] = vec2(step_w, 0.0); 26 | 27 | offset[ 6 ] = vec2(-step_w, step_h); 28 | offset[ 7 ] = vec2(0.0, step_h); 29 | offset[ 8 ] = vec2(step_w, step_h); 30 | 31 | kernel[ 0 ] = -1.; 32 | kernel[ 1 ] = -1.; 33 | kernel[ 2 ] = -1.; 34 | 35 | kernel[ 3 ] = -1.; 36 | kernel[ 4 ] = 8.; 37 | kernel[ 5 ] = -1.; 38 | 39 | kernel[ 6 ] = -1.; 40 | kernel[ 7 ] = -1.; 41 | kernel[ 8 ] = -1.; 42 | 43 | 44 | int i = 0; 45 | vec4 sum = vec4(0.0); 46 | 47 | for( int i=0; i<9; i++ ) 48 | { 49 | vec4 tmp = texture2D(tInput, vUv + offset[i]); 50 | sum += tmp * kernel[i]; 51 | sum.a = 1.0; 52 | } 53 | 54 | gl_FragColor = sum; 55 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/invert-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | 4 | void main() { 5 | 6 | gl_FragColor = texture2D( tInput, vUv ); 7 | gl_FragColor.rgb = 1. - gl_FragColor.rgb; 8 | 9 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/led-fs.glsl: -------------------------------------------------------------------------------- 1 | /************************************************************* 2 | *Shader by: Jason Gorski 3 | *Email: jasejc@aol.com 4 | *CS594 University of Illinios at Chicago 5 | * 6 | *LED Billboard Tutorial 7 | *For more information about this shader view the tutorial page 8 | *at http://www2.uic.edu/~jgorsk2 or email me 9 | *************************************************************/ 10 | 11 | #define KERNEL_SIZE 9 12 | 13 | uniform int pixelSize; //size of bigger "pixel regions". These regions are forced to be square 14 | uniform vec2 resolution; //dimensions in pixels of tInput 15 | uniform sampler2D tInput; //texure to be applied to billboard quad 16 | 17 | //uniforms added since billboard1 18 | uniform float tolerance; //a tolerance used to determine the amount of blurring along the edge of the circle defining our "pixel region" 19 | uniform float pixelRadius; //the radius of the circle that will be our "pixel region", values > 0.5 hit the edge of the "pixel region" 20 | 21 | //uniforms added since billboard2 22 | uniform int luminanceSteps; //number of shades of color our LED billboard will display 23 | uniform float luminanceBoost; //used to brighten or darken image 24 | 25 | //uniforms added since billboard3 26 | uniform float colorBoost; //used to adjust the color intensity 27 | uniform float burntOutPercent; //not exactly a "percent", but it determines how many LEDs are burnt out 28 | uniform sampler2D noiseTexture; //noise texture used with burntOutPercent 29 | 30 | varying vec2 vUv; 31 | 32 | vec2 texCoords[KERNEL_SIZE]; //stores texture lookup offsets from a base case 33 | 34 | //gets the light intensity of the color (same as luminance in applyLuminanceStepping) 35 | float getIntensity(in vec4 color) 36 | { return (color.r + color.g + color.b)/3.0; } 37 | 38 | //apply colorBoost 39 | vec4 applyColorBoost(in vec4 color) 40 | { 41 | vec4 boostedColor = color; 42 | float max = max(color.r,max(color.g, color.b)); //determine max intensity of channels 43 | bvec3 maxes = equal(vec3(color),vec3(max)); //contains which channels == max 44 | 45 | //any channels == max are boosted by the colorBoost 46 | if(maxes.r) 47 | boostedColor += vec4(2.0*colorBoost,-colorBoost,-colorBoost,0.0); 48 | 49 | if(maxes.g) 50 | boostedColor += vec4(-colorBoost,2.0*colorBoost,-colorBoost,0.0); 51 | 52 | if(maxes.b) 53 | boostedColor += vec4(-colorBoost,-colorBoost,2.0*colorBoost,0.0); 54 | 55 | return boostedColor; 56 | } 57 | 58 | //apply luminanceSteps & luminanceBoost 59 | vec4 applyLuminanceStepping(in vec4 color) 60 | { 61 | float sum = color.r + color.g + color.b; 62 | float luminance = sum/3.0; //brightness or luminance of color 63 | vec3 ratios = vec3(color.r/luminance, color.g/luminance, color.b/luminance); //ratio stores each channel's contribution to the luminance 64 | 65 | float luminanceStep = 1.0/float(luminanceSteps); //how big each luminance bin is 66 | float luminanceBin = ceil(luminance/luminanceStep); //figure out which bin the color is in 67 | float luminanceFactor = luminanceStep * luminanceBin + luminanceBoost; //store the luminance of the color we are making including luminanceBoost 68 | 69 | return vec4(ratios * luminanceFactor,1.0); //use ratios * luminanceFactor as our new color so that original color hue is maintained 70 | } 71 | 72 | void main(void) 73 | { 74 | vec4 avgColor; //will hold our averaged color from our sample points 75 | vec2 texCoordsStep = 1.0/(vec2(float(resolution.x),float(resolution.y))/float(pixelSize)); //width of "pixel region" in texture coords 76 | vec2 pixelRegionCoords = fract( vUv/texCoordsStep); //x and y coordinates within "pixel region" 77 | vec2 pixelBin = floor( vUv/texCoordsStep); //"pixel region" number counting away from base case 78 | vec2 inPixelStep = texCoordsStep/3.0; //width of "pixel region" divided by 3 (for KERNEL_SIZE = 9, 3x3 square) 79 | vec2 inPixelHalfStep = inPixelStep/2.0; 80 | 81 | //the center of our "pixel region" is computed earlier now so we don't waste time computing other colors if we are in a burnt out region 82 | texCoords[4] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 83 | 84 | //if light intensity of our noise texture <= burntOutPercent we are burnt out, otherwise continue computing "pixel region" color 85 | /* if(getIntensity(texture2D(noiseTexture, texCoords[4].st)) <= burntOutPercent) { 86 | gl_FragColor = vec4(0.1,0.1,0.1,1.0) + (0.3*(tolerance + luminanceBoost)); //try to match up color-wise with the edge of our "pixel region" 87 | } else {*/ 88 | //use offset (pixelBin * texCoordsStep) from base case (the lower left corner of billboard) to compute texCoords 89 | texCoords[0] = vec2(inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 90 | texCoords[1] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 91 | texCoords[2] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelStep.y*2.0 + inPixelHalfStep.y) + pixelBin * texCoordsStep; 92 | texCoords[3] = vec2(inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 93 | //texCoords[4] moved to top. See note above. 94 | texCoords[5] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelStep.y + inPixelHalfStep.y) + pixelBin * texCoordsStep; 95 | texCoords[6] = vec2(inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 96 | texCoords[7] = vec2(inPixelStep.x + inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 97 | texCoords[8] = vec2(inPixelStep.x*2.0 + inPixelHalfStep.x, inPixelHalfStep.y) + pixelBin * texCoordsStep; 98 | 99 | //take average of 9 pixel samples 100 | avgColor = texture2D(tInput, texCoords[0]) + 101 | texture2D(tInput, texCoords[1]) + 102 | texture2D(tInput, texCoords[2]) + 103 | texture2D(tInput, texCoords[3]) + 104 | texture2D(tInput, texCoords[4]) + 105 | texture2D(tInput, texCoords[5]) + 106 | texture2D(tInput, texCoords[6]) + 107 | texture2D(tInput, texCoords[7]) + 108 | texture2D(tInput, texCoords[8]); 109 | 110 | avgColor /= float(KERNEL_SIZE); 111 | 112 | //get a new color with the discretized luminance value 113 | avgColor = applyLuminanceStepping(avgColor); 114 | //adjust the color 115 | avgColor = applyColorBoost(avgColor); 116 | 117 | //blend between fragments in the circle and out of the circle defining our "pixel region" 118 | //Equation of a circle: (x - h)^2 + (y - k)^2 = r^2 119 | vec2 powers = pow(abs(pixelRegionCoords - 0.5),vec2(2.0)); 120 | float radiusSqrd = pow(pixelRadius,2.0); 121 | float gradient = smoothstep(radiusSqrd-tolerance, radiusSqrd+tolerance, powers.x+powers.y); 122 | 123 | gl_FragColor = mix(avgColor, vec4(0.1,0.1,0.1,1.0), gradient); 124 | // } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/noise-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float amount; 3 | uniform float speed; 4 | uniform float time; 5 | varying vec2 vUv; 6 | 7 | float random(vec2 n, float offset ){ 8 | //return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453); 9 | return .5 - fract(sin(dot(n.xy + vec2( offset, 0. ), vec2(12.9898, 78.233)))* 43758.5453); 10 | } 11 | 12 | void main() { 13 | 14 | vec4 color = texture2D(tInput, vUv); 15 | 16 | //color += amount * ( .5 - random( vec3( 1. ), length( gl_FragCoord ) + speed * .01 * time ) ); 17 | color += vec4( vec3( amount * random( vUv, .00001 * speed * time ) ), 1. ); 18 | 19 | gl_FragColor = color; 20 | 21 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/old-video-fs.glsl: -------------------------------------------------------------------------------- 1 | #define BLACK_AND_WHITE 2 | #define LINES_AND_FLICKER 3 | #define BLOTCHES 4 | #define GRAIN 5 | 6 | #define FREQUENCY 15.0 7 | 8 | uniform sampler2D tInput; 9 | uniform vec2 resolution; 10 | uniform float time; 11 | 12 | vec2 uv; 13 | 14 | float rand(vec2 co){ 15 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 16 | } 17 | 18 | float rand(float c){ 19 | return rand(vec2(c,1.0)); 20 | } 21 | 22 | float randomLine(float seed) 23 | { 24 | float b = 0.01 * rand(seed); 25 | float a = rand(seed+1.0); 26 | float c = rand(seed+2.0) - 0.5; 27 | float mu = rand(seed+3.0); 28 | 29 | float l = 1.0; 30 | 31 | if ( mu > 0.2) 32 | l = pow( abs(a * uv.x + b * uv.y + c ), 1.0/8.0 ); 33 | else 34 | l = 2.0 - pow( abs(a * uv.x + b * uv.y + c), 1.0/8.0 ); 35 | 36 | return mix(0.5, 1.0, l); 37 | } 38 | 39 | // Generate some blotches. 40 | float randomBlotch(float seed) 41 | { 42 | float x = rand(seed); 43 | float y = rand(seed+1.0); 44 | float s = 0.01 * rand(seed+2.0); 45 | 46 | vec2 p = vec2(x,y) - uv; 47 | p.x *= resolution.x / resolution.y; 48 | float a = atan(p.y,p.x); 49 | float v = 1.0; 50 | float ss = s*s * (sin(6.2831*a*x)*0.1 + 1.0); 51 | 52 | if ( dot(p,p) < ss ) v = 0.2; 53 | else 54 | v = pow(dot(p,p) - ss, 1.0/16.0); 55 | 56 | return mix(0.3 + 0.2 * (1.0 - (s / 0.02)), 1.0, v); 57 | } 58 | 59 | 60 | void main(void) 61 | { 62 | uv = gl_FragCoord.xy / resolution.xy; 63 | 64 | // Set frequency of global effect to 20 variations per second 65 | float t = float(int(time * FREQUENCY)); 66 | 67 | // Get some image movement 68 | vec2 suv = uv + 0.002 * vec2( rand(t), rand(t + 23.0)); 69 | 70 | // Get the image 71 | vec3 image = texture2D( tInput, vec2(suv.x, suv.y) ).xyz; 72 | 73 | #ifdef BLACK_AND_WHITE 74 | // Pass it to B/W 75 | float luma = dot( vec3(0.2126, 0.7152, 0.0722), image ); 76 | vec3 oldImage = luma * vec3(0.7, 0.7, 0.7); 77 | #else 78 | vec3 oldImage = image; 79 | #endif 80 | 81 | // Create a time-varyting vignetting effect 82 | float vI = 16.0 * (uv.x * (1.0-uv.x) * uv.y * (1.0-uv.y)); 83 | vI *= mix( 0.7, 1.0, rand(t + 0.5)); 84 | 85 | // Add additive flicker 86 | vI += 1.0 + 0.4 * rand(t+8.); 87 | 88 | // Add a fixed vignetting (independent of the flicker) 89 | vI *= pow(16.0 * uv.x * (1.0-uv.x) * uv.y * (1.0-uv.y), 0.4); 90 | 91 | // Add some random lines (and some multiplicative flicker. Oh well.) 92 | #ifdef LINES_AND_FLICKER 93 | int l = int(8.0 * rand(t+7.0)); 94 | 95 | if ( 0 < l ) vI *= randomLine( t+6.0+17.* float(0)); 96 | if ( 1 < l ) vI *= randomLine( t+6.0+17.* float(1)); 97 | if ( 2 < l ) vI *= randomLine( t+6.0+17.* float(2)); 98 | if ( 3 < l ) vI *= randomLine( t+6.0+17.* float(3)); 99 | if ( 4 < l ) vI *= randomLine( t+6.0+17.* float(4)); 100 | if ( 5 < l ) vI *= randomLine( t+6.0+17.* float(5)); 101 | if ( 6 < l ) vI *= randomLine( t+6.0+17.* float(6)); 102 | if ( 7 < l ) vI *= randomLine( t+6.0+17.* float(7)); 103 | 104 | #endif 105 | 106 | // Add some random blotches. 107 | #ifdef BLOTCHES 108 | int s = int( max(8.0 * rand(t+18.0) -2.0, 0.0 )); 109 | 110 | if ( 0 < s ) vI *= randomBlotch( t+6.0+19.* float(0)); 111 | if ( 1 < s ) vI *= randomBlotch( t+6.0+19.* float(1)); 112 | if ( 2 < s ) vI *= randomBlotch( t+6.0+19.* float(2)); 113 | if ( 3 < s ) vI *= randomBlotch( t+6.0+19.* float(3)); 114 | if ( 4 < s ) vI *= randomBlotch( t+6.0+19.* float(4)); 115 | if ( 5 < s ) vI *= randomBlotch( t+6.0+19.* float(5)); 116 | 117 | #endif 118 | 119 | // Show the image modulated by the defects 120 | gl_FragColor.xyz = oldImage * vI; 121 | 122 | // Add some grain (thanks, Jose!) 123 | #ifdef GRAIN 124 | gl_FragColor.xyz *= (1.0+(rand(uv+t*.01)-.2)*.15); 125 | #endif 126 | 127 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/packed-depth-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform float mNear; 2 | uniform float mFar; 3 | uniform float isPacked; 4 | varying float depth; 5 | 6 | vec4 pack_depth( const in float f ) { 7 | vec4 color; 8 | color.r = floor( f / ( 256. * 256. * 256. ) ); 9 | color.g = floor( ( mod( f, 256. * 256. * 256. ) ) / ( 256. * 256. ) ); 10 | color.b = floor( ( mod( f, 256. * 256. ) ) / 256. ); 11 | color.a = floor( mod( f, 256.) ); 12 | return color / 256.0; 13 | } 14 | 15 | void main() { 16 | 17 | /*float z = gl_FragCoord.z * 2.0 - 1.0 18 | float depth = gl_FragCoord.z / gl_FragCoord.w; 19 | float color = 1. - ( depth - mNear ) / ( mFar - mNear ); 20 | 21 | if( isPacked == 1. ) { 22 | color *= 256. * 256. * 256. * 256.; 23 | gl_FragColor = pack_depth( color ); 24 | } else { 25 | gl_FragColor = vec4( vec3( color ), 1. ); 26 | }*/ 27 | 28 | gl_FragColor = vec4( vec3( 1. - depth ), 1. ); 29 | // gl_FragColor = vec4( vNormal.xyz, color ); 30 | 31 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/pixelate-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | uniform float amount; 5 | 6 | void main() { 7 | 8 | float d = 1.0 / amount; 9 | float ar = resolution.x / resolution.y; 10 | float u = floor( vUv.x / d ) * d; 11 | d = ar / amount; 12 | float v = floor( vUv.y / d ) * d; 13 | gl_FragColor = texture2D( tInput, vec2( u, v ) ); 14 | 15 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/poisson-disc-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | varying vec2 vUv; 4 | 5 | float nrand( vec2 n ) { 6 | return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); 7 | } 8 | 9 | vec2 rot2d( vec2 p, float a ) { 10 | vec2 sc = vec2(sin(a),cos(a)); 11 | return vec2( dot( p, vec2(sc.y, -sc.x) ), dot( p, sc.xy ) ); 12 | } 13 | 14 | void main(void) 15 | { 16 | const int NUM_TAPS = 12; 17 | float max_siz = 42.0;// * (0.5+0.5*sin(iGlobalTime)); 18 | 19 | vec2 fTaps_Poisson[NUM_TAPS]; 20 | fTaps_Poisson[0] = vec2(-.326,-.406); 21 | fTaps_Poisson[1] = vec2(-.840,-.074); 22 | fTaps_Poisson[2] = vec2(-.696, .457); 23 | fTaps_Poisson[3] = vec2(-.203, .621); 24 | fTaps_Poisson[4] = vec2( .962,-.195); 25 | fTaps_Poisson[5] = vec2( .473,-.480); 26 | fTaps_Poisson[6] = vec2( .519, .767); 27 | fTaps_Poisson[7] = vec2( .185,-.893); 28 | fTaps_Poisson[8] = vec2( .507, .064); 29 | fTaps_Poisson[9] = vec2( .896, .412); 30 | fTaps_Poisson[10] = vec2(-.322,-.933); 31 | fTaps_Poisson[11] = vec2(-.792,-.598); 32 | 33 | vec2 uv = gl_FragCoord.xy / resolution.xy; 34 | //uv.x += 0.05*iGlobalTime; 35 | vec4 sum = vec4(0); 36 | float rnd = 6.28 * nrand( uv /*+fract(iGlobalTime)*/ ); 37 | 38 | vec4 basis = vec4( rot2d(vec2(1,0),rnd), rot2d(vec2(0,1),rnd) ); 39 | for (int i=0; i < NUM_TAPS; i++) 40 | { 41 | vec2 ofs = fTaps_Poisson[i]; ofs = vec2(dot(ofs,basis.xz),dot(ofs,basis.yw) ); 42 | //vec2 ofs = rot2d( fTaps_Poisson[i], rnd ); 43 | vec2 texcoord = uv + max_siz * ofs / resolution.xy; 44 | sum += texture2D(tInput, texcoord, -10.0); 45 | } 46 | gl_FragColor = sum / vec4(NUM_TAPS); 47 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/rgb-split-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 delta; 4 | uniform vec2 resolution; 5 | 6 | void main() { 7 | 8 | vec2 dir = vUv - vec2( .5 ); 9 | float d = .7 * length( dir ); 10 | normalize( dir ); 11 | vec2 value = d * dir * delta; 12 | 13 | vec4 c1 = texture2D( tInput, vUv - value / resolution.x ); 14 | vec4 c2 = texture2D( tInput, vUv ); 15 | vec4 c3 = texture2D( tInput, vUv + value / resolution.y ); 16 | 17 | gl_FragColor = vec4( c1.r, c2.g, c3.b, c1.a + c2.a + c3.b ); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/sepia-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float amount; 3 | varying vec2 vUv; 4 | 5 | void main() { 6 | 7 | vec4 color = texture2D(tInput, vUv); 8 | float r = color.r; 9 | float g = color.g; 10 | float b = color.b; 11 | 12 | color.r = min(1.0, (r * (1.0 - (0.607 * amount))) + (g * (0.769 * amount)) + (b * (0.189 * amount))); 13 | color.g = min(1.0, (r * 0.349 * amount) + (g * (1.0 - (0.314 * amount))) + (b * 0.168 * amount)); 14 | color.b = min(1.0, (r * 0.272 * amount) + (g * 0.534 * amount) + (b * (1.0 - (0.869 * amount)))); 15 | 16 | gl_FragColor = color; 17 | 18 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/sobel-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | varying vec2 vUv; 4 | 5 | void main(void) { 6 | 7 | float x = 1.0 / resolution.x; 8 | float y = 1.0 / resolution.y; 9 | vec4 horizEdge = vec4( 0.0 ); 10 | horizEdge -= texture2D( tInput, vec2( vUv.x - x, vUv.y - y ) ) * 1.0; 11 | horizEdge -= texture2D( tInput, vec2( vUv.x - x, vUv.y ) ) * 2.0; 12 | horizEdge -= texture2D( tInput, vec2( vUv.x - x, vUv.y + y ) ) * 1.0; 13 | horizEdge += texture2D( tInput, vec2( vUv.x + x, vUv.y - y ) ) * 1.0; 14 | horizEdge += texture2D( tInput, vec2( vUv.x + x, vUv.y ) ) * 2.0; 15 | horizEdge += texture2D( tInput, vec2( vUv.x + x, vUv.y + y ) ) * 1.0; 16 | vec4 vertEdge = vec4( 0.0 ); 17 | vertEdge -= texture2D( tInput, vec2( vUv.x - x, vUv.y - y ) ) * 1.0; 18 | vertEdge -= texture2D( tInput, vec2( vUv.x , vUv.y - y ) ) * 2.0; 19 | vertEdge -= texture2D( tInput, vec2( vUv.x + x, vUv.y - y ) ) * 1.0; 20 | vertEdge += texture2D( tInput, vec2( vUv.x - x, vUv.y + y ) ) * 1.0; 21 | vertEdge += texture2D( tInput, vec2( vUv.x , vUv.y + y ) ) * 2.0; 22 | vertEdge += texture2D( tInput, vec2( vUv.x + x, vUv.y + y ) ) * 1.0; 23 | vec3 edge = sqrt((horizEdge.rgb * horizEdge.rgb) + (vertEdge.rgb * vertEdge.rgb)); 24 | 25 | gl_FragColor = vec4( edge, texture2D( tInput, vUv ).a ); 26 | 27 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/sobel2-fs.glsl: -------------------------------------------------------------------------------- 1 | /** 2 | * @author zz85 / https://github.com/zz85 | https://www.lab4games.net/zz85/blog 3 | * 4 | * Edge Detection Shader using Sobel filter 5 | * Based on http://rastergrid.com/blog/2011/01/frei-chen-edge-detector 6 | * 7 | * aspect: vec2 of (1/width, 1/height) 8 | */ 9 | 10 | uniform sampler2D tInput; 11 | varying vec2 vUv; 12 | uniform vec2 resolution; 13 | 14 | vec2 texel = vec2(1.0 / resolution.x, 1.0 / resolution.y); 15 | mat3 G[2]; 16 | 17 | const mat3 g0 = mat3( 1.0, 2.0, 1.0, 0.0, 0.0, 0.0, -1.0, -2.0, -1.0 ); 18 | const mat3 g1 = mat3( 1.0, 0.0, -1.0, 2.0, 0.0, -2.0, 1.0, 0.0, -1.0 ); 19 | 20 | void main(void) { 21 | 22 | mat3 I; 23 | float cnv[2]; 24 | vec3 sample; 25 | 26 | G[0] = g0; 27 | G[1] = g1; 28 | 29 | /* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */ 30 | for (float i=0.0; i<3.0; i++) { 31 | for (float j=0.0; j<3.0; j++) { 32 | sample = texture2D( tInput, vUv + texel * vec2(i-1.0,j-1.0) ).rgb; 33 | I[int(i)][int(j)] = length(sample); 34 | } 35 | } 36 | 37 | /* calculate the convolution values for all the masks */ 38 | for (int i=0; i<2; i++) { 39 | float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]); 40 | cnv[i] = dp3 * dp3; 41 | } 42 | 43 | gl_FragColor = vec4(0.5 * sqrt(cnv[0]*cnv[0]+cnv[1]*cnv[1])); 44 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/ssao-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tDepth; 3 | uniform sampler2D tInput; 4 | uniform vec2 resolution; 5 | uniform float isPacked; 6 | uniform float onlyOcclusion; 7 | 8 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 9 | 10 | float unpack_depth(const in vec4 color) { 11 | return ( color.r * 256. * 256. * 256. + color.g * 256. * 256. + color.b * 256. + color.a ) / ( 256. * 256. * 256. ); 12 | } 13 | 14 | float sampleDepth( vec2 uv ) { 15 | if( isPacked == 1. ) { 16 | return unpack_depth( texture2D( tDepth, uv ) ); 17 | } else { 18 | return texture2D( tDepth, uv ).r; 19 | } 20 | } 21 | 22 | float occlusion = 0.; 23 | float depth = sampleDepth( vUv ); 24 | float ac = 0.; 25 | 26 | void checkDepth( vec2 uv ) { // from iq's tutorial 27 | float zd = 10.0 * min( depth - sampleDepth( uv ), 0.0 ); 28 | ac += zd; 29 | occlusion += 1.0 / ( 1. + zd * zd ); 30 | } 31 | 32 | void main() { 33 | 34 | float r = 4.; 35 | float xi = r / resolution.x; 36 | float yi = r / resolution.y; 37 | 38 | checkDepth( vUv + vec2( - 2. * xi, - 2. * yi ) ); 39 | checkDepth( vUv + vec2( - xi, - 2. * yi ) ); 40 | checkDepth( vUv + vec2( 0., - 2. * yi ) ); 41 | checkDepth( vUv + vec2( xi, - 2. * yi ) ); 42 | checkDepth( vUv + vec2( 2. * xi, - 2. * yi ) ); 43 | 44 | checkDepth( vUv + vec2( - 2. * xi, - yi ) ); 45 | checkDepth( vUv + vec2( - xi, - yi ) ); 46 | checkDepth( vUv + vec2( 0., - yi ) ); 47 | checkDepth( vUv + vec2( xi, - yi ) ); 48 | checkDepth( vUv + vec2( 2. * xi, - yi ) ); 49 | 50 | checkDepth( vUv + vec2( - 2. * xi, 0. ) ); 51 | checkDepth( vUv + vec2( - xi, 0. ) ); 52 | checkDepth( vUv + vec2( xi, 0. ) ); 53 | checkDepth( vUv + vec2( 2. * xi, 0. ) ); 54 | 55 | checkDepth( vUv + vec2( - 2. * xi, yi ) ); 56 | checkDepth( vUv + vec2( - xi, yi ) ); 57 | checkDepth( vUv + vec2( 0., yi ) ); 58 | checkDepth( vUv + vec2( xi, yi ) ); 59 | checkDepth( vUv + vec2( 2. * xi, yi ) ); 60 | 61 | checkDepth( vUv + vec2( - 2. * xi, 2. * yi ) ); 62 | checkDepth( vUv + vec2( - xi, 2. * yi ) ); 63 | checkDepth( vUv + vec2( 0., 2. * yi ) ); 64 | checkDepth( vUv + vec2( xi, 2. * yi ) ); 65 | checkDepth( vUv + vec2( 2. * xi, 2. * yi ) ); 66 | 67 | occlusion /= 24.; 68 | occlusion += .02 * random( vec3( gl_FragCoord.xy, depth ), length( gl_FragCoord ) ); 69 | 70 | /*if( onlyOcclusion == 1. ) { 71 | gl_FragColor = vec4( vec3( occlusion ), 1. ); 72 | } else { 73 | vec3 color = texture2D( tInput, vUv ).rgb; 74 | color = mix( vec3( 0. ), color, occlusion ); 75 | gl_FragColor = vec4( color, 1. ); 76 | }*/ 77 | 78 | 79 | float inBlack = 0.; 80 | float inWhite = 255.; 81 | float inGamma = 10.; 82 | float outBlack = 0.; 83 | float outWhite = 255.; 84 | 85 | //occlusion = ( pow( ( ( occlusion * 255.0) - inBlack) / (inWhite - inBlack), inGamma) * (outWhite - outBlack) + outBlack) / 255.0; 86 | 87 | gl_FragColor = vec4( vec3( occlusion ), 1. ); 88 | 89 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/ssao-simple-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | uniform sampler2D tDepth; 4 | uniform vec2 resolution; 5 | uniform float zNear; 6 | uniform float zFar; 7 | uniform float strength; 8 | 9 | // ------------- 10 | 11 | /* 12 | SSAO GLSL shader v1.2 13 | assembled by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com) 14 | original technique is made by Arkano22 (www.gamedev.net/topic/550699-ssao-no-halo-artifacts/) 15 | 16 | changelog: 17 | 1.2 - added fog calculation to mask AO. Minor fixes. 18 | 1.1 - added spiral sampling method from here: 19 | (http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere) 20 | */ 21 | //uniform sampler2D bgl_RenderedTexture; 22 | 23 | #define PI 3.14159265 24 | 25 | float width = resolution.x; //texture width 26 | float height = resolution.y; //texture height 27 | 28 | vec2 texCoord = vUv; 29 | 30 | //------------------------------------------ 31 | //general stuff 32 | 33 | //user variables 34 | uniform int samples; //ao sample count //64.0 35 | uniform float radius; //ao radius //5.0 36 | 37 | float aoclamp = 0.125; //depth clamp - reduces haloing at screen edges 38 | bool noise = true; //use noise instead of pattern for sample dithering 39 | float noiseamount = 0.0002; //dithering amount 40 | 41 | float diffarea = 0.3; //self-shadowing reduction 42 | float gdisplace = 0.4; //gauss bell center //0.4 43 | 44 | bool mist = false; //use mist? 45 | float miststart = 0.0; //mist start 46 | float mistend = zFar; //mist end 47 | 48 | bool onlyAO = false; //use only ambient occlusion pass? 49 | float lumInfluence = 0.7; //how much luminance affects occlusion 50 | 51 | //-------------------------------------------------------- 52 | 53 | vec2 rand(vec2 coord) //generating noise/pattern texture for dithering 54 | { 55 | float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0; 56 | float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0; 57 | 58 | if (noise) 59 | { 60 | noiseX = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0; 61 | noiseY = clamp(fract(sin(dot(coord ,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0; 62 | } 63 | return vec2(noiseX,noiseY)*noiseamount; 64 | } 65 | 66 | float doMist() 67 | { 68 | float zdepth = texture2D(tDepth,texCoord.xy).x; 69 | float depth = -zFar * zNear / (zdepth * (zFar - zNear) - zFar); 70 | return clamp((depth-miststart)/mistend,0.0,1.0); 71 | } 72 | 73 | float readDepth(vec2 coord) 74 | { 75 | if (vUv.x<0.0||vUv.y<0.0) return 1.0; 76 | else { 77 | float z_b = texture2D(tDepth, coord ).x; 78 | float z_n = 2.0 * z_b - 1.0; 79 | return (2.0 * zNear) / (zFar + zNear - z_n * (zFar-zNear)); 80 | } 81 | } 82 | 83 | int compareDepthsFar(float depth1, float depth2) { 84 | float garea = 2.0; //gauss bell width 85 | float diff = (depth1 - depth2)*100.0; //depth difference (0-100) 86 | //reduce left bell width to avoid self-shadowing 87 | if (diff 0) 128 | { 129 | temp2 = compareDepths(readDepth(coord2),depth); 130 | temp += (1.0-temp)*temp2; 131 | } 132 | 133 | return temp; 134 | } 135 | 136 | void main(void) 137 | { 138 | vec2 noise = rand(texCoord); 139 | float depth = readDepth(texCoord); 140 | 141 | float w = (1.0 / width)/clamp(depth,aoclamp,1.0)+(noise.x*(1.0-noise.x)); 142 | float h = (1.0 / height)/clamp(depth,aoclamp,1.0)+(noise.y*(1.0-noise.y)); 143 | 144 | float pw = 0.0; 145 | float ph = 0.0; 146 | 147 | float ao = 0.0; 148 | 149 | float dl = PI * (3.0 - sqrt(5.0)); 150 | float dz = 1.0 / float(samples); 151 | float l = 0.0; 152 | float z = 1.0 - dz/2.0; 153 | 154 | for (int i = 0; i < 64; i++) 155 | { 156 | if (i > samples) break; 157 | float r = sqrt(1.0 - z); 158 | 159 | pw = cos(l) * r; 160 | ph = sin(l) * r; 161 | ao += calAO(depth,pw*w,ph*h); 162 | z = z - dz; 163 | l = l + dl; 164 | } 165 | 166 | 167 | ao /= float(samples); 168 | ao *= strength; 169 | ao = 1.0-ao; 170 | 171 | if (mist) 172 | { 173 | ao = mix(ao, 1.0, doMist()); 174 | } 175 | 176 | /* 177 | vec3 color = texture2D(bgl_RenderedTexture,texCoord).rgb; 178 | 179 | vec3 lumcoeff = vec3(0.299,0.587,0.114); 180 | float lum = dot(color.rgb, lumcoeff); 181 | vec3 luminance = vec3(lum, lum, lum); 182 | 183 | vec3 final = vec3(color*mix(vec3(ao),vec3(1.0),luminance*lumInfluence));//mix(color*ao, white, luminance) 184 | 185 | if (onlyAO) 186 | { 187 | final = vec3(mix(vec3(ao),vec3(1.0),luminance*lumInfluence)); //ambient occlusion only 188 | } 189 | */ 190 | //vec3 final = vec3(depth/1.0); 191 | vec3 final = vec3(depth); 192 | 193 | gl_FragColor = vec4(final,1.0); 194 | 195 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/symetric-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform float xReverse; 4 | uniform float yReverse; 5 | uniform float xMirror; 6 | uniform float yMirror; 7 | uniform float angle; 8 | uniform vec2 mirrorCenter; 9 | vec2 nvUv; 10 | 11 | void main() { 12 | 13 | nvUv = vUv; 14 | 15 | if (xReverse == 1.) { 16 | 17 | nvUv.x = (1.0 - vUv.x ); 18 | 19 | if(xMirror == 1.) { 20 | 21 | if(vUv.x < 0.5) { 22 | nvUv.x = 1.0 - (nvUv.x) - (0.5 - mirrorCenter.x ) ; 23 | } 24 | else { 25 | nvUv.x = nvUv.x - (0.5 - mirrorCenter.x); 26 | } 27 | } 28 | } 29 | 30 | else if(xMirror == 1.) { 31 | 32 | if(vUv.x < 0.5) { 33 | nvUv.x = 1.0 - (nvUv.x) - (0.5 - mirrorCenter.x ) ; 34 | } 35 | else { 36 | nvUv.x = nvUv.x - (0.5 - mirrorCenter.x); 37 | } 38 | } 39 | 40 | if (yReverse == 1.) { 41 | 42 | nvUv.y = (1.0 - vUv.y ); 43 | 44 | if(yMirror == 1.) { 45 | if(vUv.y < 0.5) { 46 | nvUv.y = 1.0 - (nvUv.y) - (0.5 - mirrorCenter.y ) ; 47 | } 48 | else { 49 | nvUv.y = nvUv.y - (0.5 - mirrorCenter.y); 50 | } 51 | } 52 | } 53 | 54 | else if(yMirror == 1.) { 55 | 56 | if(vUv.y < 0.5) { 57 | nvUv.y = 1.0 - (nvUv.y) - (0.5 - mirrorCenter.y ) ; 58 | } 59 | else { 60 | nvUv.y = nvUv.y - (0.5 - mirrorCenter.y); 61 | } 62 | } 63 | 64 | 65 | float sin_factor = sin(angle); 66 | float cos_factor = cos(angle); 67 | vec2 origin = vec2(0.5 ,0.5); 68 | 69 | vec2 temp = (nvUv - origin); 70 | 71 | temp = temp * mat2(cos_factor, sin_factor, -sin_factor, cos_factor); 72 | 73 | nvUv = (temp + origin); 74 | 75 | gl_FragColor = texture2D( tInput, nvUv ); 76 | gl_FragColor.rgb = gl_FragColor.rgb; 77 | } 78 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/toon-fs.glsl: -------------------------------------------------------------------------------- 1 | // Based on http://coding-experiments.blogspot.sg/2011/01/toon-pixel-shader.html 2 | 3 | uniform vec3 resolution; 4 | uniform sampler2D tInput; 5 | varying vec2 vUv; 6 | 7 | #define HueLevCount 6 8 | #define SatLevCount 7 9 | #define ValLevCount 4 10 | float HueLevels[HueLevCount]; 11 | float SatLevels[SatLevCount]; 12 | float ValLevels[ValLevCount]; 13 | 14 | vec3 RGBtoHSV( float r, float g, float b) { 15 | float minv, maxv, delta; 16 | vec3 res; 17 | 18 | minv = min(min(r, g), b); 19 | maxv = max(max(r, g), b); 20 | res.z = maxv; // v 21 | 22 | delta = maxv - minv; 23 | 24 | if( maxv != 0.0 ) 25 | res.y = delta / maxv; // s 26 | else { 27 | // r = g = b = 0 // s = 0, v is undefined 28 | res.y = 0.0; 29 | res.x = -1.0; 30 | return res; 31 | } 32 | 33 | if( r == maxv ) 34 | res.x = ( g - b ) / delta; // between yellow & magenta 35 | else if( g == maxv ) 36 | res.x = 2.0 + ( b - r ) / delta; // between cyan & yellow 37 | else 38 | res.x = 4.0 + ( r - g ) / delta; // between magenta & cyan 39 | 40 | res.x = res.x * 60.0; // degrees 41 | if( res.x < 0.0 ) 42 | res.x = res.x + 360.0; 43 | 44 | return res; 45 | } 46 | 47 | vec3 HSVtoRGB(float h, float s, float v ) { 48 | int i; 49 | float f, p, q, t; 50 | vec3 res; 51 | 52 | if( s == 0.0 ) { 53 | // achromatic (grey) 54 | res.x = v; 55 | res.y = v; 56 | res.z = v; 57 | return res; 58 | } 59 | 60 | h /= 60.0; // sector 0 to 5 61 | i = int(floor( h )); 62 | f = h - float(i); // factorial part of h 63 | p = v * ( 1.0 - s ); 64 | q = v * ( 1.0 - s * f ); 65 | t = v * ( 1.0 - s * ( 1.0 - f ) ); 66 | 67 | if (i==0) { 68 | res.x = v; 69 | res.y = t; 70 | res.z = p; 71 | } else if (i==1) { 72 | res.x = q; 73 | res.y = v; 74 | res.z = p; 75 | } else if (i==2) { 76 | res.x = p; 77 | res.y = v; 78 | res.z = t; 79 | } else if (i==3) { 80 | res.x = p; 81 | res.y = q; 82 | res.z = v; 83 | } else if (i==4) { 84 | res.x = t; 85 | res.y = p; 86 | res.z = v; 87 | } else if (i==5) { 88 | res.x = v; 89 | res.y = p; 90 | res.z = q; 91 | } 92 | 93 | return res; 94 | } 95 | 96 | float nearestLevel(float col, int mode) { 97 | 98 | if (mode==0) { 99 | for (int i =0; i= HueLevels[i] && col <= HueLevels[i+1]) { 101 | return HueLevels[i+1]; 102 | } 103 | } 104 | } 105 | 106 | if (mode==1) { 107 | for (int i =0; i= SatLevels[i] && col <= SatLevels[i+1]) { 109 | return SatLevels[i+1]; 110 | } 111 | } 112 | } 113 | 114 | 115 | if (mode==2) { 116 | for (int i =0; i= ValLevels[i] && col <= ValLevels[i+1]) { 118 | return ValLevels[i+1]; 119 | } 120 | } 121 | } 122 | 123 | 124 | } 125 | 126 | // averaged pixel intensity from 3 color channels 127 | float avg_intensity(vec4 pix) { 128 | return (pix.r + pix.g + pix.b)/3.; 129 | } 130 | 131 | vec4 get_pixel(vec2 coords, float dx, float dy) { 132 | return texture2D(tInput,coords + vec2(dx, dy)); 133 | } 134 | 135 | // returns pixel color 136 | float IsEdge(in vec2 coords){ 137 | float dxtex = 1.0 / resolution.x ; 138 | float dytex = 1.0 / resolution.y ; 139 | 140 | float pix[9]; 141 | 142 | int k = -1; 143 | float delta; 144 | 145 | // read neighboring pixel intensities 146 | float pix0 = avg_intensity(get_pixel(coords,-1.0*dxtex, -1.0*dytex)); 147 | float pix1 = avg_intensity(get_pixel(coords,-1.0*dxtex, 0.0*dytex)); 148 | float pix2 = avg_intensity(get_pixel(coords,-1.0*dxtex, 1.0*dytex)); 149 | float pix3 = avg_intensity(get_pixel(coords,0.0*dxtex, -1.0*dytex)); 150 | float pix4 = avg_intensity(get_pixel(coords,0.0*dxtex, 0.0*dytex)); 151 | float pix5 = avg_intensity(get_pixel(coords,0.0*dxtex, 1.0*dytex)); 152 | float pix6 = avg_intensity(get_pixel(coords,1.0*dxtex, -1.0*dytex)); 153 | float pix7 = avg_intensity(get_pixel(coords,1.0*dxtex, 0.0*dytex)); 154 | float pix8 = avg_intensity(get_pixel(coords,1.0*dxtex, 1.0*dytex)); 155 | // average color differences around neighboring pixels 156 | delta = (abs(pix1-pix7)+ 157 | abs(pix5-pix3) + 158 | abs(pix0-pix8)+ 159 | abs(pix2-pix6) 160 | )/4.; 161 | 162 | return clamp(5.5*delta,0.0,1.0); 163 | } 164 | 165 | void main(void) 166 | { 167 | 168 | HueLevels[0] = 0.0; 169 | HueLevels[1] = 80.0; 170 | HueLevels[2] = 160.0; 171 | HueLevels[3] = 240.0; 172 | HueLevels[4] = 320.0; 173 | HueLevels[5] = 360.0; 174 | 175 | SatLevels[0] = 0.0; 176 | SatLevels[1] = 0.1; 177 | SatLevels[2] = 0.3; 178 | SatLevels[3] = 0.5; 179 | SatLevels[4] = 0.6; 180 | SatLevels[5] = 0.8; 181 | SatLevels[6] = 1.0; 182 | 183 | ValLevels[0] = 0.0; 184 | ValLevels[1] = 0.3; 185 | ValLevels[2] = 0.6; 186 | ValLevels[3] = 1.0; 187 | 188 | vec4 colorOrg = texture2D( tInput, vUv ); 189 | vec3 vHSV = RGBtoHSV(colorOrg.r,colorOrg.g,colorOrg.b); 190 | vHSV.x = nearestLevel(vHSV.x, 0); 191 | vHSV.y = nearestLevel(vHSV.y, 1); 192 | vHSV.z = nearestLevel(vHSV.z, 2); 193 | float edg = IsEdge(vUv); 194 | vec3 vRGB = (edg >= 0.3)? vec3(0.0,0.0,0.0):HSVtoRGB(vHSV.x,vHSV.y,vHSV.z); 195 | gl_FragColor = vec4(vRGB.x,vRGB.y,vRGB.z,1.0); 196 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/vignette-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform float falloff; 3 | uniform float amount; 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | 8 | vec4 color = texture2D(tInput, vUv); 9 | 10 | float dist = distance(vUv, vec2(0.5, 0.5)); 11 | color.rgb *= smoothstep(0.8, falloff * 0.799, dist * (amount + falloff)); 12 | 13 | gl_FragColor = color; 14 | 15 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/vignette2-fs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | uniform sampler2D tInput; 3 | uniform vec2 resolution; 4 | 5 | uniform float reduction; 6 | uniform float boost; 7 | 8 | void main() { 9 | 10 | vec4 color = texture2D( tInput, vUv ); 11 | 12 | vec2 center = resolution * 0.5; 13 | float vignette = distance( center, gl_FragCoord.xy ) / resolution.x; 14 | vignette = boost - vignette * reduction; 15 | 16 | color.rgb *= vignette; 17 | gl_FragColor = color; 18 | 19 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/vr-compose-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 resolution; 3 | uniform sampler2D leftEyeTexture; 4 | uniform sampler2D rightEyeTexture; 5 | 6 | varying vec2 vUv; 7 | 8 | 9 | void main(void) { 10 | 11 | if( vUv.x < .5 ) { 12 | gl_FragColor = texture2D( leftEyeTexture, vUv * vec2( 2., 1. ) ); 13 | } else { 14 | gl_FragColor = texture2D( rightEyeTexture, vUv * vec2( 2., 1. ) - vec2( 1., 0. ) ); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/zoom-blur-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 center; 3 | uniform float strength; 4 | uniform vec2 resolution; 5 | varying vec2 vUv; 6 | 7 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 8 | 9 | void main(){ 10 | vec4 color=vec4(0.0); 11 | float total=0.0; 12 | vec2 toCenter=center-vUv*resolution; 13 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 14 | for(float t=0.0;t<=40.0;t++){ 15 | float percent=(t+offset)/40.0; 16 | float weight=4.0*(percent-percent*percent); 17 | vec4 sample=texture2D(tInput,vUv+toCenter*percent*strength/resolution); 18 | sample.rgb*=sample.a; 19 | color+=sample*weight; 20 | total+=weight; 21 | } 22 | gl_FragColor=color/total; 23 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 24 | } 25 | -------------------------------------------------------------------------------- /build/vendors/wagner/fragment-shaders/zoom-blur2-fs.glsl: -------------------------------------------------------------------------------- 1 | uniform sampler2D tInput; 2 | uniform vec2 center; 3 | uniform float strength; 4 | uniform vec2 resolution; 5 | varying vec2 vUv; 6 | 7 | /*float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 8 | 9 | void main(){ 10 | vec4 color=vec4(0.0); 11 | float total=0.0; 12 | vec2 toCenter=center-vUv*resolution; 13 | float offset=random(vec3(12.9898,78.233,151.7182),0.0); 14 | for(float t=0.0;t<=40.0;t++){ 15 | float percent=(t+offset)/40.0; 16 | float weight=4.0*(percent-percent*percent); 17 | vec4 sample=texture2D(tInput,); 18 | sample.rgb*=sample.a; 19 | color+=sample*weight; 20 | total+=weight; 21 | } 22 | gl_FragColor=color/total; 23 | gl_FragColor.rgb/=gl_FragColor.a+0.00001; 24 | }*/ 25 | 26 | void main() { 27 | 28 | vec4 sum = vec4( 0. ); 29 | 30 | vec2 toCenter = center - vUv * resolution; 31 | vec2 inc = toCenter * strength / resolution; 32 | float boost = 2.; 33 | 34 | inc = center / resolution - vUv; 35 | 36 | sum += texture2D( tInput, ( vUv - inc * 4. ) ) * 0.051; 37 | sum += texture2D( tInput, ( vUv - inc * 3. ) ) * 0.0918; 38 | sum += texture2D( tInput, ( vUv - inc * 2. ) ) * 0.12245; 39 | sum += texture2D( tInput, ( vUv - inc * 1. ) ) * 0.1531; 40 | sum += texture2D( tInput, ( vUv + inc * 0. ) ) * 0.1633; 41 | sum += texture2D( tInput, ( vUv + inc * 1. ) ) * 0.1531; 42 | sum += texture2D( tInput, ( vUv + inc * 2. ) ) * 0.12245; 43 | sum += texture2D( tInput, ( vUv + inc * 3. ) ) * 0.0918; 44 | sum += texture2D( tInput, ( vUv + inc * 4. ) ) * 0.051; 45 | 46 | gl_FragColor = sum; 47 | 48 | } -------------------------------------------------------------------------------- /build/vendors/wagner/vertex-shaders/basic-vs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | varying vec3 vNormal; 3 | 4 | void main() { 5 | 6 | vUv = uv; 7 | vNormal = normalMatrix * normal; 8 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 9 | 10 | } -------------------------------------------------------------------------------- /build/vendors/wagner/vertex-shaders/orto-vs.glsl: -------------------------------------------------------------------------------- 1 | varying vec2 vUv; 2 | 3 | void main() { 4 | 5 | vUv = uv; 6 | // vPosition = vec4( modelViewMatrix * vec4( position, 1.0 ) ).xyz; 7 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 8 | 9 | } -------------------------------------------------------------------------------- /build/vendors/wagner/vertex-shaders/packed-depth-vs.glsl: -------------------------------------------------------------------------------- 1 | varying float depth; 2 | 3 | uniform float mNear; 4 | uniform float mFar; 5 | 6 | void main() { 7 | 8 | vec4 viewPos = vec4( modelViewMatrix * vec4( position, 1.0 ) ); // this will transform the vertex into eyespace 9 | depth = 1. - ( mNear + viewPos.z ) / ( mNear - mFar ); 10 | 11 | vec3 vPosition = vec4( modelViewMatrix * vec4( position, 1.0 ) ).xyz; 12 | gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); 13 | 14 | depth = -viewPos.z; 15 | 16 | depth = (-viewPos.z-mNear)/(mFar-mNear); // will map near..far to 0..1 17 | 18 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Patrick HENG - Audio experiement 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Music : Ordinary by Fakear

14 | 15 |

HTML5 Audio API + Three JS experiement by Patrick HENG |  Source Code

16 | 17 | 18 | 19 | 20 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threejs-audio", 3 | "version": "1.0.0", 4 | "description": "Little exercise using three js and audio html 5 api", 5 | "main": "build/main.js", 6 | "scripts": { 7 | "start": "npm run dev:script & npm run dev:server", 8 | "dev:script": "watchify -t babelify app/index.js -o build/main.js", 9 | "dev:server": "browser-sync start --server --files './' --port 3000 --no-ui", 10 | "build": "browserify -t babelify -t stripify app/index.js | uglifyjs -o build/main.js" 11 | }, 12 | "author": "HENG Patrick", 13 | "license" : 14 | { "type" : "CC-BY-NC-SA", 15 | "url" : "https://github.com/patrickheng/three-js-audio-experiment-v2/blob/master/LICENSE.md" 16 | }, 17 | "dependencies": { 18 | "dat-gui": "^0.5.0", 19 | "domready": "^1.0.8", 20 | "gsap": "^1.17.0", 21 | "raf": "^3.0.0", 22 | "stats-js": "^1.0.0-alpha1", 23 | "three": "^0.71.0", 24 | "three-orbit-controls": "^71.0.0" 25 | }, 26 | "devDependencies": { 27 | "babelify": "^6.1.2", 28 | "browser-sync": "^2.7.5", 29 | "browserify": "^10.2.1", 30 | "stripify": "^3.0.0", 31 | "uglifyjs": "^2.4.10", 32 | "watchify": "^3.2.1" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickheng/three-js-audio-experiment-v2/e42a3a492fd38475c23a64b1fd2e9792f26d2f93/preview.png --------------------------------------------------------------------------------