├── .editorconfig ├── .eslintrc.json ├── .gitignore ├── .npmignore ├── README.md ├── docs ├── ArrayBuffer.html ├── ArrayBuffer.js.html ├── CreateContextWebgl.html ├── Extension.html ├── Extension.js.html ├── Foo.html ├── FrameBuffer.html ├── FrameBuffer.js.html ├── IndexBuffer.html ├── IndexBuffer.js.html ├── Object3D.html ├── Object3D.js.html ├── Program.html ├── Program.js.html ├── State.html ├── State.js.html ├── Webgl.html ├── Webgl.js.html ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ ├── OpenSans-Regular-webfont.woff │ ├── OpenSans-Semibold-webfont.eot │ ├── OpenSans-Semibold-webfont.svg │ ├── OpenSans-Semibold-webfont.ttf │ ├── OpenSans-Semibold-webfont.woff │ ├── OpenSans-SemiboldItalic-webfont.eot │ ├── OpenSans-SemiboldItalic-webfont.svg │ ├── OpenSans-SemiboldItalic-webfont.ttf │ └── OpenSans-SemiboldItalic-webfont.woff ├── global.html ├── index.clsA.html ├── index.html ├── module.exports_module.exports.html ├── screenshot.png ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── Apache-License-2.0.txt │ │ ├── lang-css.js │ │ └── prettify.js └── styles │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── package-lock.json ├── package.json ├── public ├── assets │ └── img │ │ ├── colors.jpg │ │ ├── ground_asphalt_05_normal.jpg │ │ ├── height.png │ │ └── normal.png ├── index.html └── main.js ├── snipnet ├── functions.glsl └── shaders │ ├── attractor.frag │ ├── attractor.vert │ ├── base.frag │ ├── base.vert │ ├── bg.frag │ ├── bg.vert │ ├── bg │ ├── bg.frag │ └── bg.vert │ ├── debug.vert │ ├── envMap.frag │ ├── envMap.vert │ ├── floor.frag │ ├── floor.vert │ ├── floor │ ├── floor.frag │ └── floor.vert │ ├── instancing.frag │ ├── instancing.vert │ ├── line │ ├── base.frag │ ├── base.vert │ └── sim.frag │ ├── matcap.frag │ ├── matcap.vert │ ├── normal.frag │ ├── particles │ ├── particle.frag │ ├── particle.vert │ ├── position.frag │ ├── sim.frag │ └── velocity.frag │ ├── sphere.frag │ ├── sphere.vert │ ├── texture.frag │ ├── textureCube.frag │ └── textureCube.vert └── src ├── DefaultConfig.js ├── buildExperiment.js ├── dev ├── Broadcaster.js ├── Query.js ├── Screenshot.js └── SuperConfig.js ├── experiments ├── index.js ├── particles │ ├── Scene.js │ ├── System.js │ └── shaders │ │ ├── basic.vert │ │ ├── instancing.frag │ │ ├── instancing.vert │ │ └── sim.frag └── spring │ ├── Scene.js │ └── shaders │ ├── basic.vert │ ├── instancing.frag │ ├── instancing.vert │ └── sim.frag ├── gl ├── camera │ ├── Camera.js │ ├── OrthographicCamera.js │ └── PerspectiveCamera.js ├── const │ ├── webglConst.js │ └── webglNumber.js ├── core │ ├── ArrayBuffer.js │ ├── Extension.js │ ├── FrameBuffer.js │ ├── IndexBuffer.js │ ├── Object3D.js │ ├── Program.js │ ├── State.js │ ├── Texture.js │ ├── Texture3D.js │ ├── TextureCube.js │ └── Webgl.js ├── high │ ├── BasicMaterial.js │ ├── Geometry.js │ ├── Mesh.js │ ├── Primitive.js │ └── Shader.js ├── index.js ├── math │ ├── Ray.js │ └── Vector3.js ├── post │ ├── BlendPass.js │ ├── BloomPass.js │ ├── BoxBlurPass.js │ ├── BrightnessContrastPass.js │ ├── Composer.js │ ├── Composerori.js │ ├── DofPass.js │ ├── FXAAPass.js │ ├── FullBoxBlurPass.js │ ├── InvertPass.js │ ├── NoisePass.js │ ├── Pass.js │ ├── TiltPass.js │ ├── ToonPass.js │ └── shaders │ │ ├── blend.frag │ │ ├── boxBlur.frag │ │ ├── boxBlur.vert │ │ ├── brightness-contrast.frag │ │ ├── default.frag │ │ ├── default.vert │ │ ├── dof.frag │ │ ├── fxaa.frag │ │ ├── invert.frag │ │ ├── noise.frag │ │ ├── tilt.frag │ │ └── toon.frag ├── shaders │ ├── basic.frag │ └── basic.vert └── utils │ ├── ArrayUtils.js │ ├── Debug.js │ ├── DeviceOrientationControl.js │ ├── FBOHelper.js │ ├── HitDetect.js │ ├── Loader.js │ ├── ObjParser.js │ ├── OrbitalCameraControl.js │ ├── PingPong.js │ ├── UIID.js │ ├── Utils.js │ └── fallback.js └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = tab 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | max_line_length = 150 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.log 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Webgl tools [![experimental](http://badges.github.io/stability-badges/dist/experimental.svg)](http://github.com/badges/stability-badges) 2 | 3 | ## Doc only for fun 4 | 5 | ## [http://gl.jojo.ninja/doc](http://gl.jojo.ninja/doc) 6 | 7 | ## Instalation 8 | ```bash 9 | git clone https://github.com/JordanMachado/webgl-tool 10 | npm install 11 | ``` 12 | 13 | ## Run it 14 | ```bash 15 | npm start 16 | ``` 17 | 18 | ### Experiments 19 | 20 | ## [http://gl.jojo.ninja/](http://gl.jojo.ninja/) 21 | 22 | * [Particles](http://gl.jojo.ninja/experiments/particles/) 23 | * [Instanced lines](http://gl.jojo.ninja/experiments/instanced-lines/) 24 | * [Shadow particles](http://gl.jojo.ninja/experiments/shadow-particles/) 25 | * [Curly](http://gl.jojo.ninja/experiments/curly/) 26 | 27 | 28 | ![Alt text](http://gl.jojo.ninja/demo.png "demos") 29 | 30 | 31 | 32 | # Inspiration & Ressources 33 | 34 | * [Alfrid](https://github.com/yiwenl/Alfrid) by [@yiwen_lin](https://twitter.com/yiwen_lin?lang=en) 35 | 36 | * [nanoGL](https://github.com/plepers/nanogl) by [@plepers](https://github.com/plepers) 37 | 38 | * [medium](https://github.com/amelierosser/medium) by [@amelierosser](https://twitter.com/ixviii_io?lang=en) 39 | 40 | * [THREE.js](https://github.com/mrdoob/three.js/) by a lot of people ^^ 41 | 42 | * [webglfundamentals](https://webglfundamentals.org/) by [greggman](https://github.com/greggman) 43 | 44 | * [learningwebgl](https://learnopengl.com/) by [JOEY DE VRIES](https://joeydevries.com/#home) 45 | 46 | * [learningwebgl](http://learningwebgl.com/blog/?page_id=1217) 47 | 48 | * [tojicode]( https://blog.tojicode.com/) by [tojiro](https://twitter.com/Tojiro?lang=fr) 49 | -------------------------------------------------------------------------------- /docs/CreateContextWebgl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: CreateContextWebgl 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: CreateContextWebgl

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

CreateContextWebgl(bar)

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new CreateContextWebgl(bar)

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Constructs a new Foo by setting bar to `bar` 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
NameTypeDescription
bar 92 | 93 | 94 | * 95 | 96 | 97 | 98 | Thing representing some data
110 | 111 | 112 | 113 | 114 | 115 | 116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 |
Source:
144 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 |
196 | 197 |
198 | 199 | 200 | 201 | 202 |
203 | 204 | 207 | 208 |
209 | 210 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /docs/Foo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Foo 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Foo

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

Foo()

32 | 33 |
Foo fooing bars
34 | 35 | 36 |
37 | 38 |
39 |
40 | 41 | 42 | 43 | 44 |

Constructor

45 | 46 | 47 | 48 |

new Foo()

49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 |
68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
Source:
95 |
98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 |
106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 |
147 | 148 |
149 | 150 | 151 | 152 | 153 |
154 | 155 | 158 | 159 |
160 | 161 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Semibold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Semibold-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-Semibold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-SemiboldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf -------------------------------------------------------------------------------- /docs/fonts/OpenSans-SemiboldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/fonts/OpenSans-SemiboldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Global 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Global

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
78 | 79 | 80 | 81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |

Methods

100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |

append(containeropt)

108 | 109 | 110 | 111 | 112 | 113 | 114 |
115 | Append the renderer into an htmlElement 116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 |
Parameters:
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 166 | 167 | 168 | 177 | 178 | 179 | 180 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 |
NameTypeAttributesDefaultDescription
container 159 | 160 | 161 | object 162 | 163 | 164 | 165 | 169 | 170 | <optional>
171 | 172 | 173 | 174 | 175 | 176 |
181 | 182 | document.body 183 | 184 | html element to add the canvas
193 | 194 | 195 | 196 | 197 | 198 | 199 |
200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 |
Source:
227 |
230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 |
238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 |
263 | 264 |
265 | 266 | 267 | 268 | 269 |
270 | 271 | 274 | 275 |
276 | 277 | 280 | 281 | 282 | 283 | 284 | -------------------------------------------------------------------------------- /docs/index.clsA.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: clsA 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: clsA

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

clsA()

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new clsA()

45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 |
Source:
91 |
94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 |
122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 |
143 | 144 |
145 | 146 | 147 | 148 | 149 |
150 | 151 | 154 | 155 |
156 | 157 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/docs/screenshot.png -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (function() { 3 | var source = document.getElementsByClassName('prettyprint source linenums'); 4 | var i = 0; 5 | var lineNumber = 0; 6 | var lineId; 7 | var lines; 8 | var totalLines; 9 | var anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = 'line' + lineNumber; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: hsl(104, 100%, 24%); 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: hsl(104, 100%, 24%); } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: hsl(240, 100%, 50%); } 17 | 18 | /* a comment */ 19 | .com { 20 | color: hsl(0, 0%, 60%); } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: hsl(240, 100%, 32%); } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: hsl(240, 100%, 40%); } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #000000; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #000000; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #000000; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webgl-tools", 3 | "version": "1.0.1", 4 | "description": "webgl-tools", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "budo ./src/index.js:main.js --dir ./public --live -- -t babelify -t aliasify -t glslify", 9 | "start:experiment": "budo ./src/buildExperiment.js:main.js --dir ./public --live -- -t babelify -t aliasify -t glslify", 10 | "build:experiment": "browserify -t babelify -t aliasify -g glslify ./src/buildExperiment.js | uglifyjs -o public/main.js", 11 | "build": "browserify -t babelify -t aliasify -g glslify ./src/index.js | uglifyjs -o public/main.js", 12 | "doc": "jsdoc src/gl -r -d docs -t node_modules/loke-jsdoc-theme --readme ./README.md" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/JordanMachado/webgl-tools.git" 17 | }, 18 | "keywords": [ 19 | "webgl", 20 | "webgl2", 21 | "canvas", 22 | "context", 23 | "gl", 24 | "web", 25 | "tools" 26 | ], 27 | "babel": { 28 | "presets": [ 29 | "es2015" 30 | ], 31 | "plugins": [ 32 | "transform-es2015-modules-commonjs" 33 | ] 34 | }, 35 | "aliasify": { 36 | "aliases": { 37 | "gl": "./src/gl", 38 | "experiments": "./src/experiments", 39 | "shaders": "./src/shaders", 40 | "dev": "./src/dev" 41 | } 42 | }, 43 | "author": "Jordan Machado (http://jojo.ninja)", 44 | "license": "ISC", 45 | "bugs": { 46 | "url": "https://github.com/JordanMachado/webgl-tools/issues" 47 | }, 48 | "homepage": "https://github.com/JordanMachado/webgl-tools#readme", 49 | "dependencies": { 50 | "assets-loader": "^0.5.1", 51 | "color-scheme": "^1.0.0", 52 | "domready": "^1.0.8", 53 | "events": "^3.0.0", 54 | "fast-url-parser": "^1.1.3", 55 | "gbo-reader": "^1.0.4", 56 | "gl-matrix": "^2.3.2", 57 | "glsl-film-grain": "^1.0.4", 58 | "glsl-noise": "0.0.0", 59 | "glslify": "^6.0.1", 60 | "gsap": "^1.20.6", 61 | "jsartoolkit": "0.0.0", 62 | "jsdoc": "^3.5.5", 63 | "nice-color-palettes": "^2.0.0", 64 | "parse-obj": "0.0.0", 65 | "primitive-sphere": "^3.0.0", 66 | "querystringparser": "^0.1.1", 67 | "raf": "^3.3.0", 68 | "simplex-noise": "^2.3.0", 69 | "uglify-js": "^3.4.9" 70 | }, 71 | "devDependencies": { 72 | "aliasify": "^2.1.0", 73 | "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", 74 | "babel-preset-es2015": "^6.22.0", 75 | "babelify": "^7.3.0", 76 | "budo": "^9.4.7", 77 | "dat.gui": "^0.6.1", 78 | "loke-jsdoc-theme": "^2.1.0", 79 | "minimist": "^1.2.0", 80 | "ua-device-type": "0.0.4" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /public/assets/img/colors.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/public/assets/img/colors.jpg -------------------------------------------------------------------------------- /public/assets/img/ground_asphalt_05_normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/public/assets/img/ground_asphalt_05_normal.jpg -------------------------------------------------------------------------------- /public/assets/img/height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/public/assets/img/height.png -------------------------------------------------------------------------------- /public/assets/img/normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/public/assets/img/normal.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Loading 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 72 | 73 | 74 |
75 |

All experiments

76 |
77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /snipnet/functions.glsl: -------------------------------------------------------------------------------- 1 | // 2D 2 | vec2 rotate(vec2 v, float a) { 3 | float s = sin(a); 4 | float c = cos(a); 5 | mat2 m = mat2(c, -s, s, c); 6 | return m * v; 7 | } 8 | 9 | // 3D 10 | mat4 rotationMatrix(vec3 axis, float angle) { 11 | axis = normalize(axis); 12 | float s = sin(angle); 13 | float c = cos(angle); 14 | float oc = 1.0 - c; 15 | 16 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 17 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 18 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 19 | 0.0, 0.0, 0.0, 1.0); 20 | } 21 | 22 | vec3 rotate(vec3 v, vec3 axis, float angle) { 23 | mat4 m = rotationMatrix(axis, angle); 24 | return (m * vec4(v, 1.0)).xyz; 25 | } 26 | 27 | 28 | vec2 envMapEquirect(vec3 wcNormal, float flipEnvMap) { 29 | //I assume envMap texture has been flipped the WebGL way (pixel 0,0 is a the bottom) 30 | //therefore we flip wcNorma.y as acos(1) = 0 31 | float phi = acos(-wcNormal.y); 32 | float theta = atan(flipEnvMap * wcNormal.x, wcNormal.z) + PI; 33 | return vec2(theta / TwoPI, phi / PI); 34 | } 35 | 36 | vec2 envMapEquirect(vec3 wcNormal) { 37 | //-1.0 for left handed coordinate system oriented texture (usual case) 38 | return envMapEquirect(wcNormal, -1.0); 39 | } 40 | 41 | float diffuse(vec3 N, vec3 L) { 42 | return max(dot(N, normalize(L)), 0.0); 43 | } 44 | 45 | 46 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 47 | return diffuse(N, L) * C; 48 | } 49 | 50 | 51 | #extension GL_OES_standard_derivatives : enable 52 | // function from three js 53 | vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 54 | 55 | // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 56 | 57 | vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 58 | vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 59 | vec2 st0 = dFdx( vUv.st ); 60 | vec2 st1 = dFdy( vUv.st ); 61 | 62 | vec3 S = normalize( q0 * st1.t - q1 * st0.t ); 63 | vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); 64 | vec3 N = normalize( surf_norm ); 65 | 66 | vec3 mapN = texture2D( uNormalMap, vUv ).xyz * 2.0 - 1.0; 67 | mapN.xy = uNormalScale * mapN.xy; 68 | mat3 tsn = mat3( S, T, N ); 69 | return normalize( tsn * mapN ); 70 | 71 | } 72 | 73 | vec4 getMapColor(sampler2D texture, sampler2D textureDepth, vec4 vShadowCoord, vec3 uPointSource) { 74 | vec4 color = baseColor; 75 | 76 | vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 77 | 78 | vec2 uv = shadowCoord.xy; 79 | float d = texture2D(textureDepth, uv).r; 80 | 81 | float visibility = 1.0; 82 | if(d < shadowCoord.z - uBias) { 83 | visibility = 0.0; 84 | } 85 | 86 | float a = acos(dot(normalize(uPointSource), vNormal)); 87 | if (a > MIN_ANGLE) { 88 | visibility = 0.0; 89 | } 90 | 91 | vec4 colorMap = texture2D(texture, uv); 92 | visibility *= colorMap.a; 93 | 94 | color.rgb = mix(baseColor.rgb, colorMap.rgb, visibility); 95 | // color.a = colorMap.a; 96 | 97 | return color; 98 | } 99 | 100 | mat3 calcLookAtMatrix(vec3 camPosition, vec3 camTarget, float roll) { 101 | vec3 ww = normalize(camTarget - camPosition); 102 | vec3 uu = normalize(cross(ww, vec3(sin(roll), cos(roll), 0.0))); 103 | vec3 vv = normalize(cross(uu, ww)); 104 | 105 | return mat3(uu, vv, ww); 106 | } 107 | mat3 lookat = calcLookAtMatrix(vec3(0.0, 0.0 , 10.0), vec3(0.0), 0.0); 108 | 109 | 110 | float d = distance(vTextureCoord, vec2(.5)); 111 | d = 1.0 - smoothstep(0.0, 0.5, d); 112 | d *= 0.5; 113 | -------------------------------------------------------------------------------- /snipnet/shaders/attractor.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uShadowMap; 4 | 5 | varying vec3 vNormal; 6 | varying vec3 vColor; 7 | varying vec4 vShadowCoord; 8 | 9 | 10 | 11 | void main() { 12 | // 13 | // vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 14 | // vec2 uv = shadowCoord.xy; 15 | // // vec4 shadow = texture2D( uShadowMap, uv.xy ); 16 | // // vec4 shadow = texture2D( uShadowMap, vUv ); 17 | // float visibility = 1.0; 18 | // 19 | // if ( shadow.r < shadowCoord.z - 0.005){ 20 | // visibility = 0.0; 21 | // } 22 | // gl_FragColor = vec4(vec3(visibility) * vec3(1.0), 1.0); 23 | // gl_FragColor = vec4(vec3(shadow.rgb), 1.0); 24 | gl_FragColor = vec4(vColor, 1.0); 25 | } 26 | -------------------------------------------------------------------------------- /snipnet/shaders/attractor.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec2 aUv; 3 | attribute vec3 aColor; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat4 uShadowMatrix; 9 | uniform mat3 normalMatrix; 10 | 11 | 12 | uniform float uPointSize; 13 | uniform sampler2D uPosition; 14 | 15 | varying vec3 vNormal; 16 | varying vec4 vShadowCoord; 17 | varying vec2 vUv; 18 | varying vec3 vColor; 19 | 20 | 21 | void main() { 22 | vec4 p = vec4(aPosition, 1.0); 23 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 24 | gl_PointSize = uPointSize; 25 | vUv = aUv; 26 | vColor = aColor; 27 | vShadowCoord = uShadowMatrix * worldMatrix * p; 28 | } 29 | -------------------------------------------------------------------------------- /snipnet/shaders/base.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | varying vec2 vUv; 3 | varying vec3 vCenter; 4 | varying vec3 vNormal; 5 | varying vec3 vVel; 6 | 7 | float diffuse(vec3 N, vec3 L) { 8 | return max(dot(N, normalize(L)), 0.0); 9 | } 10 | 11 | 12 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 13 | return diffuse(N, L) * C; 14 | } 15 | 16 | 17 | void main() { 18 | vec3 color = vCenter; 19 | vec3 light = diffuse(vNormal, vec3(0.0,1.0,1.0), vec3(1.0)); 20 | 21 | // color = vVel; 22 | gl_FragColor = vec4( vNormal - light + vVel * 0.05, 1.0); 23 | } 24 | -------------------------------------------------------------------------------- /snipnet/shaders/base.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec3 aNormal; 5 | attribute vec2 aUv; 6 | attribute vec2 aOffset; 7 | attribute vec3 aCenter; 8 | attribute vec2 aUvsCenter; 9 | 10 | uniform mat4 projectionMatrix; 11 | uniform mat4 viewMatrix; 12 | uniform mat4 worldMatrix; 13 | uniform mat4 uShadowMatrix; 14 | uniform mat3 normalMatrix; 15 | uniform float uForce; 16 | uniform sampler2D uTexture; 17 | 18 | 19 | varying vec3 vNormal; 20 | varying vec3 vCenter; 21 | varying vec3 vVel; 22 | varying vec2 vUv; 23 | 24 | 25 | 26 | void main() { 27 | vec4 p = vec4(aPosition, 1.0); 28 | vec4 off = texture2D(uTexture, aUv); 29 | p.xyz += off.xyz * uForce; 30 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 31 | gl_PointSize = 10.0; 32 | vUv = aUv; 33 | vNormal = aNormal; 34 | vCenter = vec3(aUvsCenter,1.0); 35 | vVel = vec3(off); 36 | } 37 | -------------------------------------------------------------------------------- /snipnet/shaders/bg.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec3 vNormal; 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | 8 | gl_FragColor = vec4(vec3(0.85, 0.85, 0.85), 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /snipnet/shaders/bg.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | 13 | void main() { 14 | vec4 p = vec4(aPosition, 1.0); 15 | gl_Position = p; 16 | vUv = aUv; 17 | vNormal = normalize(normalMatrix * aNormal); 18 | } 19 | -------------------------------------------------------------------------------- /snipnet/shaders/bg/bg.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | 4 | uniform sampler2D uNormalMap; 5 | uniform sampler2D uHeightMap; 6 | uniform float uTime; 7 | 8 | uniform vec3 uColor; 9 | uniform vec2 uNormalScale; 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | varying vec3 vViewPosition; 13 | 14 | #extension GL_OES_standard_derivatives : enable 15 | // function from three js 16 | // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html 17 | vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 18 | 19 | // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 20 | 21 | vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 22 | vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 23 | vec2 st0 = dFdx( vUv.st ); 24 | vec2 st1 = dFdy( vUv.st ); 25 | 26 | vec3 S = normalize( q0 * st1.t - q1 * st0.t ); 27 | vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); 28 | vec3 N = normalize( surf_norm ); 29 | 30 | vec3 mapN = texture2D( uNormalMap, vUv ).xyz * 2.0 - 1.0; 31 | mapN.xy = uNormalScale * mapN.xy; 32 | mat3 tsn = mat3( S, T, N ); 33 | return normalize( tsn * mapN ); 34 | 35 | } 36 | 37 | 38 | float diffuse(vec3 N, vec3 L) { 39 | return max(dot(N, normalize(L)), 0.0); 40 | } 41 | 42 | 43 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 44 | return diffuse(N, L) * C; 45 | } 46 | 47 | varying float fogFactor; 48 | 49 | const vec3 fogColor = vec3(.01, 0.0, 0.2); 50 | 51 | 52 | #pragma glslify: snoise3 = require(glsl-noise/simplex/2d) 53 | 54 | void main() { 55 | 56 | 57 | vec3 color = uColor; 58 | float d = 1.0 - length(vec2(0.5) - vUv); 59 | d= cos((vUv.x- uTime) * 100. ); 60 | d= cos((vUv.x) * 100. ); 61 | 62 | color = smoothstep(0.5, 0.55, vec3(d)); 63 | color = vec3(0.0,0.0,0.6) * (1.0 - color); 64 | color = mix(color, vec3(0.0), vUv.y); 65 | 66 | gl_FragColor = vec4(color , 1.0); 67 | 68 | } 69 | -------------------------------------------------------------------------------- /snipnet/shaders/bg/bg.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | uniform sampler2D uHeightMap; 10 | 11 | 12 | 13 | varying vec3 vNormal; 14 | varying vec2 vUv; 15 | varying vec3 vViewPosition; 16 | 17 | const float density = 0.03; 18 | const float gradient = 5.1; 19 | varying float fogFactor; 20 | 21 | void main() { 22 | 23 | vec4 p = vec4(aPosition, 1.0); 24 | 25 | vViewPosition = (projectionMatrix * viewMatrix * p).xyz; 26 | gl_Position = p; 27 | vUv = aUv; 28 | float dist = length(vViewPosition.xyz); 29 | 30 | vNormal = normalize(normalMatrix * aNormal); 31 | 32 | fogFactor = exp(-pow(dist*density,gradient)); 33 | fogFactor = clamp(fogFactor, 0.0, 1.0); 34 | } 35 | -------------------------------------------------------------------------------- /snipnet/shaders/debug.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | 13 | void main() { 14 | vec4 p = vec4(aPosition, 1.0); 15 | gl_Position = worldMatrix * p; 16 | vUv = aUv; 17 | vNormal = normalize(normalMatrix * aNormal); 18 | } 19 | -------------------------------------------------------------------------------- /snipnet/shaders/envMap.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform samplerCube uTexture; 4 | uniform samplerCube uTextureFake; 5 | uniform mat4 viewMatrix; 6 | 7 | varying vec3 vNormal; 8 | varying vec3 vUv; 9 | 10 | varying vec3 vViewPosition; 11 | varying vec3 vEye; 12 | 13 | 14 | mat4 inverse(mat4 m) { 15 | float 16 | a00 = m[0][0], a01 = m[0][1], a02 = m[0][2], a03 = m[0][3], 17 | a10 = m[1][0], a11 = m[1][1], a12 = m[1][2], a13 = m[1][3], 18 | a20 = m[2][0], a21 = m[2][1], a22 = m[2][2], a23 = m[2][3], 19 | a30 = m[3][0], a31 = m[3][1], a32 = m[3][2], a33 = m[3][3], 20 | 21 | b00 = a00 * a11 - a01 * a10, 22 | b01 = a00 * a12 - a02 * a10, 23 | b02 = a00 * a13 - a03 * a10, 24 | b03 = a01 * a12 - a02 * a11, 25 | b04 = a01 * a13 - a03 * a11, 26 | b05 = a02 * a13 - a03 * a12, 27 | b06 = a20 * a31 - a21 * a30, 28 | b07 = a20 * a32 - a22 * a30, 29 | b08 = a20 * a33 - a23 * a30, 30 | b09 = a21 * a32 - a22 * a31, 31 | b10 = a21 * a33 - a23 * a31, 32 | b11 = a22 * a33 - a23 * a32, 33 | 34 | det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; 35 | 36 | return mat4( 37 | a11 * b11 - a12 * b10 + a13 * b09, 38 | a02 * b10 - a01 * b11 - a03 * b09, 39 | a31 * b05 - a32 * b04 + a33 * b03, 40 | a22 * b04 - a21 * b05 - a23 * b03, 41 | a12 * b08 - a10 * b11 - a13 * b07, 42 | a00 * b11 - a02 * b08 + a03 * b07, 43 | a32 * b02 - a30 * b05 - a33 * b01, 44 | a20 * b05 - a22 * b02 + a23 * b01, 45 | a10 * b10 - a11 * b08 + a13 * b06, 46 | a01 * b08 - a00 * b10 - a03 * b06, 47 | a30 * b04 - a31 * b02 + a33 * b00, 48 | a21 * b02 - a20 * b04 - a23 * b00, 49 | a11 * b07 - a10 * b09 - a12 * b06, 50 | a00 * b09 - a01 * b07 + a02 * b06, 51 | a31 * b01 - a30 * b03 - a32 * b00, 52 | a20 * b03 - a21 * b01 + a22 * b00) / det; 53 | } 54 | 55 | // #define ENVMAP_MODE_REFLECTION 56 | 57 | void main() { 58 | 59 | 60 | vec3 incident_eye = normalize(vViewPosition); 61 | vec3 normal = normalize(vEye); 62 | 63 | 64 | 65 | // #ifdef ENVMAP_MODE_REFLECTION 66 | vec3 reflected = reflect(incident_eye, normal); 67 | reflected = vec3(inverse(viewMatrix) * vec4(reflected, 0.0)); 68 | // #else 69 | float ratio = 1.0; 70 | vec3 refraction = refract(incident_eye, normal, ratio); 71 | refraction = vec3(inverse(viewMatrix) * vec4(refraction, 0.0)); 72 | // #endif 73 | 74 | 75 | 76 | vec4 r = textureCube(uTexture, reflected); 77 | vec4 rr = textureCube(uTexture, refraction); 78 | 79 | vec4 rf = textureCube(uTextureFake, reflected); 80 | 81 | vec4 colors = mix(r + rf, rr, 0.); 82 | // vec4 colors = rf; 83 | 84 | gl_FragColor = vec4(colors.rgb, 1.0); 85 | } 86 | -------------------------------------------------------------------------------- /snipnet/shaders/envMap.vert: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec3 aNormal; 5 | attribute vec2 aUv; 6 | 7 | uniform mat4 projectionMatrix; 8 | uniform mat4 viewMatrix; 9 | uniform mat4 worldMatrix; 10 | uniform mat3 normalMatrix; 11 | uniform float uTime; 12 | 13 | varying vec3 vNormal; 14 | varying vec3 vUv; 15 | varying vec3 vViewPosition; 16 | varying vec3 vEye; 17 | 18 | 19 | vec3 mod289(vec3 x) 20 | { 21 | return x - floor(x * (1.0 / 289.0)) * 289.0; 22 | } 23 | 24 | vec4 mod289(vec4 x) 25 | { 26 | return x - floor(x * (1.0 / 289.0)) * 289.0; 27 | } 28 | 29 | vec4 permute(vec4 x) 30 | { 31 | return mod289(((x*34.0)+1.0)*x); 32 | } 33 | 34 | vec4 taylorInvSqrt(vec4 r) 35 | { 36 | return 1.79284291400159 - 0.85373472095314 * r; 37 | } 38 | 39 | vec3 fade(vec3 t) { 40 | return t*t*t*(t*(t*6.0-15.0)+10.0); 41 | } 42 | 43 | // Classic Perlin noise, periodic variant 44 | float pnoise(vec3 P, vec3 rep) 45 | { 46 | vec3 Pi0 = mod(floor(P), rep); // Integer part, modulo period 47 | vec3 Pi1 = mod(Pi0 + vec3(1.0), rep); // Integer part + 1, mod period 48 | Pi0 = mod289(Pi0); 49 | Pi1 = mod289(Pi1); 50 | vec3 Pf0 = fract(P); // Fractional part for interpolation 51 | vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0 52 | vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x); 53 | vec4 iy = vec4(Pi0.yy, Pi1.yy); 54 | vec4 iz0 = Pi0.zzzz; 55 | vec4 iz1 = Pi1.zzzz; 56 | 57 | vec4 ixy = permute(permute(ix) + iy); 58 | vec4 ixy0 = permute(ixy + iz0); 59 | vec4 ixy1 = permute(ixy + iz1); 60 | 61 | vec4 gx0 = ixy0 * (1.0 / 7.0); 62 | vec4 gy0 = fract(floor(gx0) * (1.0 / 7.0)) - 0.5; 63 | gx0 = fract(gx0); 64 | vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0); 65 | vec4 sz0 = step(gz0, vec4(0.0)); 66 | gx0 -= sz0 * (step(0.0, gx0) - 0.5); 67 | gy0 -= sz0 * (step(0.0, gy0) - 0.5); 68 | 69 | vec4 gx1 = ixy1 * (1.0 / 7.0); 70 | vec4 gy1 = fract(floor(gx1) * (1.0 / 7.0)) - 0.5; 71 | gx1 = fract(gx1); 72 | vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1); 73 | vec4 sz1 = step(gz1, vec4(0.0)); 74 | gx1 -= sz1 * (step(0.0, gx1) - 0.5); 75 | gy1 -= sz1 * (step(0.0, gy1) - 0.5); 76 | 77 | vec3 g000 = vec3(gx0.x,gy0.x,gz0.x); 78 | vec3 g100 = vec3(gx0.y,gy0.y,gz0.y); 79 | vec3 g010 = vec3(gx0.z,gy0.z,gz0.z); 80 | vec3 g110 = vec3(gx0.w,gy0.w,gz0.w); 81 | vec3 g001 = vec3(gx1.x,gy1.x,gz1.x); 82 | vec3 g101 = vec3(gx1.y,gy1.y,gz1.y); 83 | vec3 g011 = vec3(gx1.z,gy1.z,gz1.z); 84 | vec3 g111 = vec3(gx1.w,gy1.w,gz1.w); 85 | 86 | vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110))); 87 | g000 *= norm0.x; 88 | g010 *= norm0.y; 89 | g100 *= norm0.z; 90 | g110 *= norm0.w; 91 | vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111))); 92 | g001 *= norm1.x; 93 | g011 *= norm1.y; 94 | g101 *= norm1.z; 95 | g111 *= norm1.w; 96 | 97 | float n000 = dot(g000, Pf0); 98 | float n100 = dot(g100, vec3(Pf1.x, Pf0.yz)); 99 | float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z)); 100 | float n110 = dot(g110, vec3(Pf1.xy, Pf0.z)); 101 | float n001 = dot(g001, vec3(Pf0.xy, Pf1.z)); 102 | float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z)); 103 | float n011 = dot(g011, vec3(Pf0.x, Pf1.yz)); 104 | float n111 = dot(g111, Pf1); 105 | 106 | vec3 fade_xyz = fade(Pf0); 107 | vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z); 108 | vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y); 109 | float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 110 | return 2.2 * n_xyz; 111 | } 112 | 113 | 114 | void main() { 115 | vec4 p = vec4(aPosition, 1.0); 116 | float noise = pnoise(p.xyz + vec3(uTime), vec3(10.0, 5.0, 1.0) ); 117 | p.xyz += noise * 0.5 * aNormal; 118 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 119 | vUv = aPosition; 120 | vViewPosition = (viewMatrix * worldMatrix * p).xyz; 121 | vEye = (viewMatrix * worldMatrix * vec4(aNormal, 0.0)).xyz; 122 | vNormal = normalize(normalMatrix * aNormal); 123 | } 124 | -------------------------------------------------------------------------------- /snipnet/shaders/floor.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | uniform sampler2D uShadowMap; 3 | uniform vec3 fogColor; 4 | uniform vec3 floorColor; 5 | 6 | varying vec3 vNormal; 7 | varying vec2 vUv; 8 | varying vec4 vShadowCoord; 9 | varying float fogFactor; 10 | 11 | void main() { 12 | 13 | vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 14 | vec2 uv = shadowCoord.xy; 15 | vec4 shadow = texture2D( uShadowMap, uv.xy ); 16 | float visibility = 1.0; 17 | 18 | if ( shadow.r < shadowCoord.z - 0.005){ 19 | visibility = 0.5; 20 | } 21 | gl_FragColor = vec4(vec3(visibility) * floorColor, 1.0); 22 | // gl_FragColor = vec4(vec3(vUv,1.0), 1.0); 23 | gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fogFactor); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /snipnet/shaders/floor.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | uniform mat4 uShadowMatrix; 11 | 12 | varying vec3 vNormal; 13 | varying vec2 vUv; 14 | varying vec4 vShadowCoord; 15 | 16 | // fog chunk 17 | const float density = 0.007; 18 | const float gradient = 5.1; 19 | varying float fogFactor; 20 | 21 | 22 | void main() { 23 | vec4 p = vec4(aPosition, 1.0); 24 | vUv= aUv; 25 | vec4 wp = worldMatrix * p; 26 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 27 | vShadowCoord = uShadowMatrix * vec4(wp.xyz, 1.0); 28 | 29 | vec4 postoCam = viewMatrix * worldMatrix * p; 30 | // postoCam.z = 5.; 31 | float dist = length(postoCam.xyz); 32 | 33 | 34 | fogFactor = exp(-pow(dist*density,gradient)); 35 | fogFactor = clamp(fogFactor, 0.0, 1.0); 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /snipnet/shaders/floor/floor.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | 4 | uniform sampler2D uNormalMap; 5 | uniform sampler2D uHeightMap; 6 | uniform float uTime; 7 | 8 | uniform vec3 uColor; 9 | uniform vec2 uNormalScale; 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | varying vec3 vViewPosition; 13 | 14 | #extension GL_OES_standard_derivatives : enable 15 | // function from three js 16 | // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html 17 | vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 18 | 19 | // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 20 | 21 | vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 22 | vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 23 | vec2 st0 = dFdx( vUv.st ); 24 | vec2 st1 = dFdy( vUv.st ); 25 | 26 | vec3 S = normalize( q0 * st1.t - q1 * st0.t ); 27 | vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); 28 | vec3 N = normalize( surf_norm ); 29 | 30 | vec3 mapN = texture2D( uNormalMap, vUv ).xyz * 2.0 - 1.0; 31 | mapN.xy = uNormalScale * mapN.xy; 32 | mat3 tsn = mat3( S, T, N ); 33 | return normalize( tsn * mapN ); 34 | 35 | } 36 | 37 | 38 | float diffuse(vec3 N, vec3 L) { 39 | return max(dot(N, normalize(L)), 0.0); 40 | } 41 | 42 | 43 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 44 | return diffuse(N, L) * C; 45 | } 46 | 47 | varying float fogFactor; 48 | 49 | const vec3 fogColor = vec3(.01); 50 | 51 | 52 | #pragma glslify: snoise3 = require(glsl-noise/simplex/2d) 53 | 54 | void main() { 55 | vec3 normal = perturbNormal2Arb(vViewPosition, vNormal); 56 | vec3 light = diffuse(normal, vec3(1.0, 1.0,cos(uTime*20.)), vec3(0.0, 0.0, 1.)); 57 | float height = texture2D(uHeightMap, vUv).r; 58 | vec3 color = uColor - vec3(height) * 0.1; 59 | float d = 1.0 - length(vec2(0.5) - vUv); 60 | d = smoothstep(0.6, .55, d); 61 | // d = 1.0; 62 | float noise = snoise3(vUv + uTime); 63 | color = vec3(cos(vUv.x * (300. * 1.0 - d) * noise)); 64 | color = smoothstep(0.5, 1.0, color); 65 | 66 | gl_FragColor = vec4(color+ light * (1.0 - d), 1.0); 67 | 68 | gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fogFactor); 69 | 70 | } 71 | -------------------------------------------------------------------------------- /snipnet/shaders/floor/floor.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | uniform sampler2D uHeightMap; 10 | 11 | 12 | 13 | varying vec3 vNormal; 14 | varying vec2 vUv; 15 | varying vec3 vViewPosition; 16 | 17 | const float density = 0.02; 18 | const float gradient = 5.1; 19 | varying float fogFactor; 20 | 21 | void main() { 22 | float height = texture2D(uHeightMap, aUv).r; 23 | vec4 p = vec4(aPosition, 1.0); 24 | float d = 1.0 - length(vec2(0.5) -aUv); 25 | p.z += height * 10. * (1.0 -d); 26 | d = smoothstep(0.84, 1.0, d); 27 | 28 | p.z -= d * 10.; 29 | 30 | 31 | vViewPosition = (projectionMatrix * viewMatrix * p).xyz; 32 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 33 | vUv = aUv; 34 | float dist = length(vViewPosition.xyz); 35 | 36 | vNormal = normalize(normalMatrix * aNormal); 37 | 38 | fogFactor = exp(-pow(dist*density,gradient)); 39 | fogFactor = clamp(fogFactor, 0.0, 1.0); 40 | } 41 | -------------------------------------------------------------------------------- /snipnet/shaders/instancing.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform vec3 uLightColor; 4 | uniform vec3 uColor; 5 | uniform vec3 uColor1; 6 | varying vec3 vNormal; 7 | varying vec2 vUv; 8 | varying vec2 vUv2; 9 | varying vec3 vViewPosition; 10 | 11 | uniform sampler2D uBuffer; 12 | 13 | 14 | 15 | float diffuse(vec3 N, vec3 L) { 16 | return max(dot(N, normalize(L)), 0.0); 17 | } 18 | 19 | 20 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 21 | return diffuse(N, L) * C; 22 | } 23 | 24 | varying vec3 vNormal2; 25 | 26 | void main() { 27 | vec3 light = diffuse(vNormal, vec3(0.0,1.0,0.), uLightColor); 28 | vec4 buffer = texture2D(uBuffer, vUv2); 29 | vec3 color = mix(uColor, uColor1, vViewPosition.y + 1.4); 30 | gl_FragColor = vec4(color + light, 1.0); 31 | // gl_FragColor = vec4(vec3(buffer.a), 1.0); 32 | } 33 | -------------------------------------------------------------------------------- /snipnet/shaders/instancing.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aTwouv; 4 | attribute vec2 aUv; 5 | 6 | attribute vec4 aOffset; 7 | 8 | uniform mat4 projectionMatrix; 9 | uniform mat4 viewMatrix; 10 | uniform mat4 worldMatrix; 11 | uniform mat3 normalMatrix; 12 | uniform float uTime; 13 | uniform sampler2D uBuffer; 14 | 15 | varying vec3 vNormal; 16 | varying vec3 vNormal2; 17 | varying vec2 vUv; 18 | varying vec2 vUv2; 19 | varying vec3 vViewPosition; 20 | 21 | mat3 rotationMatrix(vec3 axis, float angle) 22 | { 23 | axis = normalize(axis); 24 | float s = sin(angle); 25 | float c = cos(angle); 26 | float oc = 1.0 - c; 27 | 28 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 29 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 30 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c 31 | ); 32 | } 33 | 34 | 35 | void main() { 36 | vec4 p = vec4(aPosition + aOffset.xyz, 1.0); 37 | 38 | vec2 uv2 = aTwouv; 39 | vec4 buffer = texture2D( uBuffer, uv2); 40 | 41 | mat3 rot = rotationMatrix(vec3(1.0,0.0,0.0), buffer.x * 5.0)* rotationMatrix(vec3(0.0,1.0,0.0),buffer.y * 5.0)* rotationMatrix(vec3(0.0,0.0,1.0),buffer.z * 5.0); 42 | vec4 pos = vec4((aPosition * buffer.a * rot) + buffer.xyz, 1.0); 43 | 44 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * pos; 45 | 46 | vUv = aUv; 47 | // vUv2 = aTwouv; 48 | vViewPosition = -(worldMatrix * pos).xyz; 49 | vNormal = normalMatrix * normalize(aNormal * rot); 50 | vNormal2 = aNormal; 51 | } 52 | -------------------------------------------------------------------------------- /snipnet/shaders/line/base.frag: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordanMachado/webgl-tools/020d987854d0a44255d1d5a0244824b34df44a60/snipnet/shaders/line/base.frag -------------------------------------------------------------------------------- /snipnet/shaders/line/base.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec3 aNormal; 5 | attribute vec2 aUv; 6 | 7 | varying vec2 vUv; 8 | varying vec3 vNormal; 9 | 10 | void main() { 11 | vUv = vec2(aUv.x, aUv.y); 12 | vNormal = aNormal; 13 | gl_Position = vec4(aPosition, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /snipnet/shaders/matcap.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D uTexture; 4 | varying vec3 vNormal; 5 | varying vec2 vUv; 6 | varying float vNoise; 7 | varying vec3 vEye; 8 | 9 | const float PI = 3.141592653589793; 10 | const float TwoPI = PI * 2.0; 11 | 12 | 13 | vec2 matcap(vec3 eye, vec3 normal) { 14 | vec3 reflected = reflect(eye, normal); 15 | float m = 2.8284271247461903 * sqrt( reflected.z+1.0 ); 16 | return reflected.xy / m + 0.5; 17 | } 18 | 19 | void main() { 20 | 21 | if(vNoise < 0.1) { 22 | discard; 23 | } 24 | // vec2 uv = envMapEquirect(vNormal).xy; 25 | 26 | 27 | // vec3 finalNormal = tsb * normalMap; 28 | vec2 uv = matcap(vEye, vNormal).xy; 29 | vec4 color = texture2D(uTexture,uv); 30 | 31 | gl_FragColor = vec4(color.rgb, 1.0); 32 | // gl_FragColor = vec4(vTangent, 1.0); 33 | } 34 | -------------------------------------------------------------------------------- /snipnet/shaders/matcap.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aTangent; 3 | attribute vec3 aBitangent; 4 | attribute vec3 aNormal; 5 | attribute vec3 aColor; 6 | attribute vec2 aUv; 7 | 8 | uniform mat4 projectionMatrix; 9 | uniform mat4 viewMatrix; 10 | uniform mat4 worldMatrix; 11 | uniform mat3 normalMatrix; 12 | 13 | uniform float uTime; 14 | 15 | varying vec3 vColor; 16 | varying vec3 vNormal; 17 | varying vec2 vUv; 18 | varying float vNoise; 19 | varying vec3 vEye; 20 | 21 | #pragma glslify: snoise3 = require(glsl-noise/simplex/3d) 22 | 23 | void main() { 24 | float noise = snoise3(aPosition.xyz/2. + vec3(0.0,uTime, 0.0)); 25 | vec4 p = vec4(aPosition, 1.0); 26 | p.xyz += noise * aNormal * 0.1; 27 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 28 | vUv = aUv; 29 | vNoise = noise; 30 | vEye = normalize( vec3(viewMatrix * worldMatrix * p ) ); 31 | vNormal = normalize(normalMatrix * aNormal); 32 | } 33 | -------------------------------------------------------------------------------- /snipnet/shaders/normal.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D uMap; 4 | uniform sampler2D uNormalMap; 5 | uniform vec2 uNormalScale; 6 | varying vec3 vNormal; 7 | varying vec2 vUv; 8 | varying vec3 vViewPosition; 9 | 10 | #extension GL_OES_standard_derivatives : enable 11 | // function from three js 12 | // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html 13 | vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 14 | 15 | // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 16 | 17 | vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 18 | vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 19 | vec2 st0 = dFdx( vUv.st ); 20 | vec2 st1 = dFdy( vUv.st ); 21 | 22 | vec3 S = normalize( q0 * st1.t - q1 * st0.t ); 23 | vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); 24 | vec3 N = normalize( surf_norm ); 25 | 26 | vec3 mapN = texture2D( uNormalMap, vUv ).xyz * 2.0 - 1.0; 27 | mapN.xy = uNormalScale * mapN.xy; 28 | mat3 tsn = mat3( S, T, N ); 29 | return normalize( tsn * mapN ); 30 | 31 | } 32 | 33 | 34 | float diffuse(vec3 N, vec3 L) { 35 | return max(dot(N, normalize(L)), 0.0); 36 | } 37 | 38 | 39 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 40 | return diffuse(N, L) * C; 41 | } 42 | 43 | 44 | void main() { 45 | vec3 map = texture2D(uMap, vUv).xyz; 46 | vec3 normal = perturbNormal2Arb(vViewPosition, vNormal); 47 | vec3 light = diffuse(normal, vec3(0.0,1.0,1.0), vec3(0.7)); 48 | gl_FragColor = vec4(map +light, 1.0); 49 | } 50 | -------------------------------------------------------------------------------- /snipnet/shaders/particles/particle.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform vec3 uLightColor; 4 | uniform sampler2D uShadowMap; 5 | uniform sampler2D uBuffer; 6 | uniform vec3 fogColor; 7 | 8 | 9 | varying vec3 vNormal; 10 | varying vec2 vUv; 11 | varying vec4 vShadowCoord; 12 | varying vec3 vColor; 13 | 14 | varying float fogFactor; 15 | 16 | float diffuse(vec3 N, vec3 L) { 17 | return max(dot(N, normalize(L)), 0.0); 18 | } 19 | 20 | 21 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 22 | return diffuse(N, L) * C; 23 | } 24 | 25 | void main() { 26 | vec4 buffer = texture2D(uBuffer,vUv); 27 | 28 | vec3 light = diffuse(vNormal, vec3(0.0,1.,.0),uLightColor); 29 | 30 | 31 | vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 32 | vec2 uv = shadowCoord.xy; 33 | vec4 shadow = texture2D( uShadowMap, uv.xy ); 34 | float visibility = 1.0; 35 | 36 | if ( shadow.r < shadowCoord.z - 0.005){ 37 | visibility = 0.5; 38 | } 39 | gl_FragColor = vec4((visibility * light) + (vColor * visibility), 1.0); 40 | 41 | gl_FragColor.rgb = mix(fogColor, gl_FragColor.rgb, fogFactor); 42 | } 43 | -------------------------------------------------------------------------------- /snipnet/shaders/particles/particle.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec4 aOffset; 5 | attribute vec3 aNormal; 6 | attribute vec2 aUv; 7 | attribute vec2 aUv2; 8 | attribute vec3 aColor; 9 | 10 | uniform mat4 projectionMatrix; 11 | uniform mat4 viewMatrix; 12 | uniform mat4 worldMatrix; 13 | uniform mat3 normalMatrix; 14 | uniform sampler2D uBuffer; 15 | uniform sampler2D uBufferVel; 16 | uniform sampler2D uPositions; 17 | uniform vec3 mouse; 18 | 19 | varying vec2 vUv; 20 | varying vec3 vColor; 21 | varying vec3 vNormal; 22 | 23 | 24 | const float density = 0.007; 25 | const float gradient = 5.1; 26 | varying float fogFactor; 27 | 28 | mat3 calcLookAtMatrix(vec3 camPosition, vec3 camTarget, float roll) { 29 | vec3 ww = normalize(camTarget - camPosition); 30 | vec3 uu = normalize(cross(ww, vec3(sin(roll), cos(roll), 0.0))); 31 | vec3 vv = normalize(cross(uu, ww)); 32 | 33 | return mat3(uu, vv, ww); 34 | } 35 | 36 | mat4 rotationMatrix(vec3 axis, float angle) { 37 | axis = normalize(axis); 38 | float s = sin(angle); 39 | float c = cos(angle); 40 | float oc = 1.0 - c; 41 | 42 | return mat4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0, 43 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0, 44 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0, 45 | 0.0, 0.0, 0.0, 1.0); 46 | } 47 | 48 | vec3 rotate(vec3 v, vec3 axis, float angle) { 49 | mat4 m = rotationMatrix(axis, angle); 50 | return (m * vec4(v, 1.0)).xyz; 51 | } 52 | varying vec4 vShadowCoord; 53 | 54 | uniform mat4 uShadowMatrix; 55 | 56 | void main() { 57 | vec4 buffer = texture2D(uBuffer,aUv2); 58 | vec4 velo = texture2D(uBufferVel,aUv2); 59 | vec4 base = texture2D(uPositions,aUv2); 60 | vUv = vec2(aUv2); 61 | mat3 lookAt = calcLookAtMatrix(buffer.xyz + velo.xyz, buffer.xyz, 0.0); 62 | 63 | vNormal = normalize( lookAt*aNormal.xyz); 64 | vec4 p = vec4(aPosition + aOffset.xyz, 1.0); 65 | vColor = aColor; 66 | 67 | p.xyz = (aPosition.xyz * base.a * length(buffer.xyz) * 0.007) * lookAt + buffer.xyz * 0.1; 68 | vec4 postoCam = viewMatrix * worldMatrix * p; 69 | 70 | 71 | float dist = length(postoCam.xyz); 72 | vShadowCoord = uShadowMatrix * vec4(p.xyz, 1.0); 73 | 74 | fogFactor = exp(-pow(dist*density,gradient)); 75 | fogFactor = clamp(fogFactor, 0.0, 1.0); 76 | 77 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 78 | 79 | } 80 | -------------------------------------------------------------------------------- /snipnet/shaders/particles/position.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | varying vec2 vUv; 3 | 4 | uniform sampler2D uTexture; 5 | uniform sampler2D uOrigin; 6 | 7 | uniform vec3 mouse; 8 | uniform sampler2D uVelocity; 9 | 10 | 11 | 12 | 13 | void main() { 14 | vec4 pos = texture2D(uTexture, vUv); 15 | vec4 vel = texture2D(uVelocity, vUv); 16 | 17 | float life = pos.a; 18 | life -= 0.0020; 19 | if(life < 0.1) { 20 | life = 1.0; 21 | } 22 | 23 | pos.xyz += vel.xyz; 24 | 25 | gl_FragColor = vec4(pos.xyz,life); 26 | } 27 | -------------------------------------------------------------------------------- /snipnet/shaders/particles/sim.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | #define GLSLIFY 1 3 | 4 | uniform sampler2D uTexture; 5 | uniform sampler2D uOrigin; 6 | 7 | uniform float uTime; 8 | uniform vec2 mouse; 9 | uniform float width; 10 | uniform float height; 11 | varying vec2 vUv; 12 | 13 | // 14 | // Description : Array and textureless GLSL 2D/3D/4D simplex 15 | // noise functions. 16 | // Author : Ian McEwan, Ashima Arts. 17 | // Maintainer : ijm 18 | // Lastmod : 20110822 (ijm) 19 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 20 | // Distributed under the MIT License. See LICENSE file. 21 | // https://github.com/ashima/webgl-noise 22 | // 23 | 24 | vec3 mod289(vec3 x) { 25 | return x - floor(x * (1.0 / 289.0)) * 289.0; 26 | } 27 | 28 | vec4 mod289(vec4 x) { 29 | return x - floor(x * (1.0 / 289.0)) * 289.0; 30 | } 31 | 32 | vec4 permute(vec4 x) { 33 | return mod289(((x*34.0)+1.0)*x); 34 | } 35 | 36 | vec4 taylorInvSqrt(vec4 r) 37 | { 38 | return 1.79284291400159 - 0.85373472095314 * r; 39 | } 40 | 41 | float snoise(vec3 v) 42 | { 43 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 44 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 45 | 46 | // First corner 47 | vec3 i = floor(v + dot(v, C.yyy) ); 48 | vec3 x0 = v - i + dot(i, C.xxx) ; 49 | 50 | // Other corners 51 | vec3 g = step(x0.yzx, x0.xyz); 52 | vec3 l = 1.0 - g; 53 | vec3 i1 = min( g.xyz, l.zxy ); 54 | vec3 i2 = max( g.xyz, l.zxy ); 55 | 56 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 57 | // x1 = x0 - i1 + 1.0 * C.xxx; 58 | // x2 = x0 - i2 + 2.0 * C.xxx; 59 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 60 | vec3 x1 = x0 - i1 + C.xxx; 61 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 62 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 63 | 64 | // Permutations 65 | i = mod289(i); 66 | vec4 p = permute( permute( permute( 67 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 68 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 69 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 70 | 71 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 72 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 73 | float n_ = 0.142857142857; // 1.0/7.0 74 | vec3 ns = n_ * D.wyz - D.xzx; 75 | 76 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 77 | 78 | vec4 x_ = floor(j * ns.z); 79 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 80 | 81 | vec4 x = x_ *ns.x + ns.yyyy; 82 | vec4 y = y_ *ns.x + ns.yyyy; 83 | vec4 h = 1.0 - abs(x) - abs(y); 84 | 85 | vec4 b0 = vec4( x.xy, y.xy ); 86 | vec4 b1 = vec4( x.zw, y.zw ); 87 | 88 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 89 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 90 | vec4 s0 = floor(b0)*2.0 + 1.0; 91 | vec4 s1 = floor(b1)*2.0 + 1.0; 92 | vec4 sh = -step(h, vec4(0.0)); 93 | 94 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 95 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 96 | 97 | vec3 p0 = vec3(a0.xy,h.x); 98 | vec3 p1 = vec3(a0.zw,h.y); 99 | vec3 p2 = vec3(a1.xy,h.z); 100 | vec3 p3 = vec3(a1.zw,h.w); 101 | 102 | //Normalise gradients 103 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 104 | p0 *= norm.x; 105 | p1 *= norm.y; 106 | p2 *= norm.z; 107 | p3 *= norm.w; 108 | 109 | // Mix final noise value 110 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 111 | m = m * m; 112 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 113 | dot(p2,x2), dot(p3,x3) ) ); 114 | } 115 | 116 | vec3 snoiseVec3( vec3 x ){ 117 | 118 | float s = snoise(vec3( x )); 119 | float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 )); 120 | float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 )); 121 | vec3 c = vec3( s , s1 , s2 ); 122 | return c; 123 | 124 | } 125 | 126 | vec3 curlNoise( vec3 p ){ 127 | 128 | const float e = .1; 129 | vec3 dx = vec3( e , 0.0 , 0.0 ); 130 | vec3 dy = vec3( 0.0 , e , 0.0 ); 131 | vec3 dz = vec3( 0.0 , 0.0 , e ); 132 | 133 | vec3 p_x0 = snoiseVec3( p - dx ); 134 | vec3 p_x1 = snoiseVec3( p + dx ); 135 | vec3 p_y0 = snoiseVec3( p - dy ); 136 | vec3 p_y1 = snoiseVec3( p + dy ); 137 | vec3 p_z0 = snoiseVec3( p - dz ); 138 | vec3 p_z1 = snoiseVec3( p + dz ); 139 | 140 | float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y; 141 | float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z; 142 | float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x; 143 | 144 | const float divisor = 1.0 / ( 2.0 * e ); 145 | return normalize( vec3( x , y , z ) * divisor ); 146 | 147 | } 148 | 149 | float rand(vec2 co){ 150 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 151 | } 152 | 153 | void main() { 154 | vec4 pos = texture2D(uTexture,vUv); 155 | vec4 opos = texture2D(uOrigin,vUv); 156 | vec3 noise = curlNoise(pos.xyz + vec3(0.0, 0.0, uTime)) * 0.01; 157 | pos.xyz += noise; 158 | pos.y += 0.005; 159 | 160 | float life = pos.a; 161 | life -= 0.0020; 162 | if(life < 0.1) { 163 | life = 1.0; 164 | pos.xyz = opos.xyz; 165 | } 166 | if(vUv.x < 1.0/width) { 167 | pos.xyz = vec3(1.0); 168 | 169 | } 170 | 171 | gl_FragColor = vec4(pos.xyz, life); 172 | } 173 | -------------------------------------------------------------------------------- /snipnet/shaders/particles/velocity.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | // simulation 3 | varying vec2 vUv; 4 | 5 | uniform sampler2D uTexture; 6 | uniform sampler2D uPositions; 7 | 8 | uniform vec3 mouse; 9 | 10 | 11 | 12 | void main() { 13 | 14 | 15 | vec4 pos = texture2D(uPositions, vUv); 16 | vec4 vel = texture2D(uTexture, vUv); 17 | 18 | vec3 force = mouse - pos.xyz; 19 | vec3 nForce = normalize(force); 20 | vel.xyz *= 0.99 + (pos.a*0.01); 21 | vel.xyz += nForce * (pos.a * 0.3); 22 | 23 | 24 | gl_FragColor = vec4(vel.xyz,1.0); 25 | } 26 | -------------------------------------------------------------------------------- /snipnet/shaders/sphere.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | varying vec3 vNormal; 4 | varying vec2 vUv; 5 | varying vec4 vDistToLight; 6 | 7 | uniform float uTime; 8 | 9 | 10 | float diffuse(vec3 N, vec3 L) { 11 | return max(dot(N, normalize(L)), 0.0); 12 | } 13 | 14 | 15 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 16 | return diffuse(N, L) * C; 17 | } 18 | 19 | void main() { 20 | vec3 light = diffuse(vNormal, vec3(-1.0,0.0,0.0), vec3(51.0/255.0,255.0/255.0,185.0/255.0 )); 21 | vec3 light2 = diffuse(vNormal, vec3(1.0,0.0,0.0), vec3(255.0/255.0,50.0/255.0,219.0/255.0 )); 22 | vec3 light3 = diffuse(vNormal, vec3(0.0,0.0,10.0), vec3(5.0/255.0,5.0/255.0,219.0/255.0 )); 23 | vec3 lighing = vec3(0.1) + light + light2 + light3; 24 | float color = cos((vUv.y + uTime * 0.1) * 100.0); 25 | color = smoothstep(0.5,0.6, color); 26 | gl_FragColor = vec4( color + lighing, 1.0); 27 | } 28 | -------------------------------------------------------------------------------- /snipnet/shaders/sphere.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | varying vec4 vDistToLight; 13 | 14 | void main() { 15 | vec4 p = vec4(aPosition, 1.0); 16 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 17 | vUv = aUv; 18 | // vDistToLight = ( worldMatrix * p) - vec4(0.0,10.0,-10.0,0.0); 19 | vNormal = normalize(normalMatrix * aNormal); 20 | } 21 | -------------------------------------------------------------------------------- /snipnet/shaders/texture.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D uTexture; 4 | varying vec3 vNormal; 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 color = texture2D(uTexture, vUv); 9 | gl_FragColor = vec4(color); 10 | } 11 | -------------------------------------------------------------------------------- /snipnet/shaders/textureCube.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform samplerCube uTexture; 4 | varying vec3 vNormal; 5 | varying vec3 vUv; 6 | 7 | 8 | 9 | void main() { 10 | vec4 colors = textureCube(uTexture, vUv); 11 | gl_FragColor = vec4(colors, 1.0); 12 | } 13 | -------------------------------------------------------------------------------- /snipnet/shaders/textureCube.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | varying vec3 vNormal; 11 | varying vec3 vUv; 12 | varying vec3 vViewPosition; 13 | 14 | void main() { 15 | vec4 p = vec4(aPosition, 1.0); 16 | gl_Position = projectionMatrix * viewMatrix * worldMatrix * p; 17 | vUv = aPosition; 18 | vViewPosition = -(worldMatrix * p).xyz; 19 | vNormal = normalize(normalMatrix * aNormal); 20 | } 21 | -------------------------------------------------------------------------------- /src/DefaultConfig.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | name: 'Experiment', 3 | controls: true, 4 | 5 | }; 6 | 7 | export default config; 8 | -------------------------------------------------------------------------------- /src/buildExperiment.js: -------------------------------------------------------------------------------- 1 | import raf from 'raf'; 2 | import assetsLoader from 'assets-loader'; 3 | import domready from 'domready'; 4 | import Query from 'dev/Query'; 5 | import SuperConfig from 'dev/SuperConfig'; 6 | import AllExperiments from './Experiments'; 7 | 8 | const experimentName = 'particles'; 9 | 10 | let manifest = []; 11 | 12 | if (experimentName && AllExperiments[experimentName]) 13 | { 14 | if (AllExperiments[experimentName].manifest && AllExperiments[experimentName].manifest.length > 0) 15 | { 16 | manifest = AllExperiments[experimentName].manifest; 17 | } 18 | } 19 | const loader = assetsLoader({ 20 | assets: manifest, 21 | }); 22 | 23 | window.getAsset = function getAsset(id) 24 | { 25 | return loader.get(`assets/${id}`); 26 | }; 27 | 28 | domready(() => 29 | { 30 | if (manifest.length > 0) 31 | { 32 | document.body.classList.add('loading'); 33 | loader.on('complete', function loaded(assets) 34 | { 35 | document.body.classList.remove('loading'); 36 | window.assets = assets; 37 | init(); 38 | if (Query.debug) 39 | { console.table(assets); } 40 | }) 41 | .start(); 42 | } 43 | else 44 | { 45 | init(); 46 | } 47 | }); 48 | 49 | let scene; 50 | 51 | function init() 52 | { 53 | scene = new AllExperiments[experimentName].scene(); 54 | Query.init(AllExperiments[experimentName].config); 55 | SuperConfig.init(AllExperiments[experimentName].config); 56 | document.title = AllExperiments[experimentName].config.name || 'Experiment'; 57 | render(); 58 | window.addEventListener('resize', resize); 59 | } 60 | 61 | function resize() 62 | { 63 | if (scene) 64 | { scene.resize(); } 65 | } 66 | function render() 67 | { 68 | raf(render); 69 | if (scene) 70 | { scene.render(); } 71 | } 72 | -------------------------------------------------------------------------------- /src/dev/Broadcaster.js: -------------------------------------------------------------------------------- 1 | // Broadcaster.js 2 | import { EventEmitter } from 'events'; 3 | import SuperConfig from './SuperConfig'; 4 | 5 | class Broadcaster extends EventEmitter 6 | { 7 | constructor() 8 | { 9 | super(); 10 | window.broadcaster = this; 11 | } 12 | emit(...args) 13 | { 14 | super.emit(...args); 15 | if (SuperConfig.query.debug) 16 | { 17 | console.log('Broadcaster emit:', ...args); 18 | } 19 | } 20 | } 21 | 22 | const instance = new Broadcaster(); 23 | 24 | export default instance; 25 | -------------------------------------------------------------------------------- /src/dev/Query.js: -------------------------------------------------------------------------------- 1 | import url from 'fast-url-parser'; 2 | import defaultConfig from '../DefaultConfig'; 3 | url.queryString = require('querystringparser'); 4 | 5 | class Query 6 | { 7 | constructor() 8 | { 9 | this.parseQuery(); 10 | } 11 | init(config) 12 | { 13 | if (!this.config) 14 | { 15 | this.config = config ? config : defaultConfig; 16 | } 17 | } 18 | parseQuery() 19 | { 20 | const parsed = url.parse(window.location.search, true); 21 | 22 | for (const key in parsed.query) 23 | { 24 | if (parsed.query[key] === 'true') 25 | { 26 | this[key] = true; 27 | } 28 | else if (parsed.query[key] === 'false') 29 | { 30 | this[key] = false; 31 | } 32 | else 33 | { 34 | this[key] = JSON.parse(parsed.query[key]); 35 | } 36 | } 37 | } 38 | } 39 | export default new Query(); 40 | -------------------------------------------------------------------------------- /src/dev/Screenshot.js: -------------------------------------------------------------------------------- 1 | let img; 2 | const btn = document.createElement('a'); 3 | 4 | export default class Screenshot 5 | { 6 | constructor(scene) 7 | { 8 | this.scene = scene; 9 | const debug = document.createElement('div'); 10 | 11 | debug.id = 'debug'; 12 | 13 | btn.id = 'screenshot'; 14 | btn.innerHTML = 'screenshot'; 15 | 16 | img = new Image(); 17 | 18 | debug.appendChild(btn); 19 | document.body.appendChild(debug); 20 | btn.addEventListener('mousedown', () => 21 | { 22 | this.capture(); 23 | }); 24 | btn.addEventListener('mouseup', () => 25 | { 26 | btn.download = 'screen'; 27 | }); 28 | } 29 | capture() 30 | { 31 | this.scene.render(); 32 | img.src = this.scene.webgl.canvas.toDataURL(); 33 | btn.href = img.src; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/experiments/index.js: -------------------------------------------------------------------------------- 1 | import ParticlesScene from './particles/Scene.js'; 2 | import SpringScene from './spring/Scene.js'; 3 | const experiments = { 4 | particles: { 5 | scene: ParticlesScene, 6 | config: { 7 | controls: true, 8 | name: 'Particles', 9 | }, 10 | manifest: [ 11 | 'assets/img/normal.png', 12 | ], 13 | }, 14 | spring: { 15 | scene: SpringScene, 16 | config: {}, 17 | }, 18 | }; 19 | 20 | export default experiments; 21 | -------------------------------------------------------------------------------- /src/experiments/particles/System.js: -------------------------------------------------------------------------------- 1 | import PingPong from 'gl/utils/PingPong'; 2 | import G from 'gl'; 3 | const glslify = require('glslify'); 4 | 5 | export default class System 6 | { 7 | constructor(_size, scene) 8 | { 9 | const width = _size; 10 | const height = _size; 11 | 12 | const dataPos = new Float32Array(width * height * 4); 13 | const pos = new Float32Array(width * height * 3); 14 | const uvs = new Float32Array(width * height * 2); 15 | const colors = new Float32Array(width * height * 3); 16 | const size = new Float32Array(width * height * 1); 17 | 18 | // const _colors = ["#0d543f", "#09424b", "#09424b", "#09424b", "#09424b", "#b0bfc8"]; 19 | const _colors = ['#d3e9ff', '#ffd5d5', '#ffa0ad', '#509be1', '#ff71b2']; 20 | let count = 0; 21 | 22 | for (let i = 0, l = width * height * 4; i < l; i += 4) 23 | { 24 | const u = Math.random(); 25 | const v = Math.random(); 26 | const theta = 2 * Math.PI * u; 27 | const phi = Math.acos(2 * v - 1); 28 | const radius = Math.random() * 0.2; 29 | const x = (radius * Math.sin(phi) * Math.cos(theta)); 30 | const y = (radius * Math.sin(phi) * Math.sin(theta)); 31 | const z = (radius * Math.cos(phi)); 32 | 33 | // dataPos[i] = G.utils.random(-0.1, 0.1); 34 | // dataPos[i + 1] = G.utils.random(-0.1, 0.1); 35 | // dataPos[i + 2] = G.utils.random(-0.2, 0.2); 36 | 37 | dataPos[i] = x; 38 | dataPos[i + 1] = y; 39 | dataPos[i + 2] = z; 40 | dataPos[i + 3] = Math.random(); 41 | 42 | pos[count * 3 + 0] = dataPos[i]; 43 | pos[count * 3 + 1] = dataPos[i + 1]; 44 | pos[count * 3 + 2] = dataPos[i + 2]; 45 | 46 | uvs[count * 2 + 0] = (count % width) / width; 47 | uvs[count * 2 + 1] = Math.floor(count / width) / height; 48 | 49 | const mycolor = G.utils.hexToRgb(_colors[Math.floor(Math.random() * _colors.length)]); 50 | 51 | colors[count * 3 + 0] = mycolor[0]; 52 | colors[count * 3 + 1] = mycolor[1]; 53 | colors[count * 3 + 2] = mycolor[2]; 54 | size[count] = G.utils.random(0.5, 1); 55 | 56 | count++; 57 | } 58 | 59 | const dataText = new G.Texture(gl); 60 | 61 | dataText.format = gl.RGBA; 62 | dataText.type = gl.FLOAT; 63 | dataText.uploadData(dataPos, width, height); 64 | 65 | this.gpu = new PingPong({ 66 | data: dataText, 67 | width, 68 | height, 69 | timeAdd: 0.001, 70 | 71 | renderer: scene.webgl, 72 | camera: new G.OrthographicCamera(-1, 1, -1, 1, 0.1, 100), 73 | vs: glslify('./shaders/basic.vert'), 74 | fs: glslify('./shaders/sim.frag'), 75 | uniforms: { 76 | uMouse: [0, 0, 0], 77 | }, 78 | }); 79 | 80 | const geometry = new G.Geometry(); 81 | 82 | geometry.addAttribute('positions', pos, true); 83 | 84 | geometry.addAttribute('colors', colors, true); 85 | geometry.addAttribute('twouvs', uvs, true); 86 | geometry.addAttribute('sizes', size, true); 87 | 88 | const normal = this.normal = new G.Texture(gl); 89 | 90 | normal.format = gl.RGBA; 91 | normal.upload(window.getAsset('img/normal.png')); 92 | 93 | this.mesh = new G.Mesh( 94 | geometry, 95 | new G.Shader( 96 | glslify('./shaders/instancing.vert'), 97 | glslify('./shaders/instancing.frag'), { 98 | uBuffer: dataText, 99 | normalTexture: normal, 100 | uShadowMap: scene.fbo.depth, 101 | uShadowMatrix: scene.mvpDepth, 102 | toLook: [0, 0, 1], 103 | }, 104 | 'Particles' 105 | ), { 106 | drawType: gl.POINTS, 107 | }); 108 | 109 | scene.fboHelper.attach(this.gpu.fboOut.colors); 110 | scene.fboHelper.attach(this.normal); 111 | } 112 | update(mouse) 113 | { 114 | this.mesh.shader.uniforms.uBuffer = this.gpu.fboOutO.colors; 115 | 116 | this.gpu.quad.shader.uniforms.uMouse = mouse; 117 | 118 | this.mesh.shader.uniforms.uBuffer = this.gpu.fboOutO.colors; 119 | this.gpu.update(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/experiments/particles/shaders/basic.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec3 aNormal; 5 | attribute vec2 aUv; 6 | 7 | varying vec2 vUv; 8 | varying vec3 vNormal; 9 | 10 | void main() { 11 | vUv = vec2(aUv.x, aUv.y); 12 | vNormal = aNormal; 13 | gl_Position = vec4(aPosition, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /src/experiments/particles/shaders/instancing.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D normalTexture; 4 | varying vec2 vUv; 5 | varying vec3 vViewPosition; 6 | 7 | uniform sampler2D uShadowMap; 8 | varying vec4 vShadowCoord; 9 | varying vec3 vColor; 10 | 11 | float diffuse(vec3 N, vec3 L) { 12 | return max(dot(N, normalize(L)), 0.0); 13 | } 14 | 15 | 16 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 17 | return diffuse(N, L) * C; 18 | } 19 | 20 | float sampleShadow(vec3 coord) { 21 | return step(coord.z, texture2D(uShadowMap, coord.xy).r + 0.006); 22 | } 23 | 24 | 25 | 26 | void main() { 27 | 28 | if ( length(vec2(0.5) - gl_PointCoord) > 0.5 ) { 29 | discard; 30 | } 31 | vec4 normals = texture2D(normalTexture,gl_PointCoord); 32 | 33 | vec3 light = diffuse(normals.xyz, normalize(vec3(0.0,20.0,1.0)), vec3(0.2)); 34 | vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 35 | float shadow = 0.0; 36 | float offset = 0.0001; 37 | 38 | shadow += sampleShadow(shadowCoord.xyz); 39 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, -offset, 0.0)); 40 | shadow += sampleShadow(shadowCoord.xyz + vec3(-offset, 0.0, 0.0)); 41 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, 0.0, 0.0)); 42 | shadow += sampleShadow(shadowCoord.xyz + vec3( offset, 0.0, 0.0)); 43 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, offset, 0.0)); 44 | shadow /= 5.0; 45 | 46 | 47 | 48 | gl_FragColor = vec4( vColor*0.9 + light , normals.a); 49 | gl_FragColor.rgb *= vec3(smoothstep(0.0, 1.0, shadow+0.65)); 50 | } 51 | -------------------------------------------------------------------------------- /src/experiments/particles/shaders/instancing.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec2 aTwouv; 3 | attribute vec3 aColor; 4 | attribute float aSize; 5 | 6 | 7 | uniform mat4 projectionMatrix; 8 | uniform mat4 viewMatrix; 9 | uniform mat4 worldMatrix; 10 | uniform mat3 normalMatrix; 11 | uniform float uTime; 12 | uniform sampler2D uBuffer; 13 | uniform vec3 toLook; 14 | 15 | 16 | uniform mat4 uShadowMatrix; 17 | varying vec4 vShadowCoord; 18 | 19 | varying vec2 vUv; 20 | varying vec2 vUv2; 21 | varying vec3 vColor; 22 | varying vec3 vViewPosition; 23 | varying vec4 vOffset; 24 | 25 | uniform sampler2D colorsText; 26 | 27 | 28 | void main() { 29 | vec4 offset = texture2D(uBuffer, aTwouv); 30 | 31 | vec4 p = vec4(aPosition + offset.xyz,1.); 32 | vec4 worldPos = projectionMatrix * viewMatrix * worldMatrix * p; 33 | vViewPosition = worldPos.xyz; 34 | vShadowCoord = uShadowMatrix * worldMatrix * p; 35 | 36 | vec4 cc = texture2D(colorsText, vec2(aPosition.xy )); 37 | 38 | 39 | gl_Position = worldPos; 40 | gl_PointSize = 20. * (aSize * clamp(offset.a,0.2,1.)); 41 | // gl_PointSize = 20.; 42 | vColor = aColor; 43 | // vColor = cc.xyz * 0.2; 44 | 45 | 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/experiments/particles/shaders/sim.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | #define GLSLIFY 1 3 | 4 | uniform sampler2D uTexture; 5 | uniform sampler2D uTextureOld; 6 | uniform sampler2D uOrigin; 7 | 8 | uniform float uTime; 9 | 10 | uniform vec3 uMouse; 11 | uniform float width; 12 | uniform float height; 13 | varying vec2 vUv; 14 | 15 | // 16 | // Description : Array and textureless GLSL 2D/3D/4D simplex 17 | // noise functions. 18 | // Author : Ian McEwan, Ashima Arts. 19 | // Maintainer : ijm 20 | // Lastmod : 20110822 (ijm) 21 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 22 | // Distributed under the MIT License. See LICENSE file. 23 | // https://github.com/ashima/webgl-noise 24 | // 25 | 26 | vec3 mod289(vec3 x) { 27 | return x - floor(x * (1.0 / 289.0)) * 289.0; 28 | } 29 | 30 | vec4 mod289(vec4 x) { 31 | return x - floor(x * (1.0 / 289.0)) * 289.0; 32 | } 33 | 34 | vec4 permute(vec4 x) { 35 | return mod289(((x*34.0)+1.0)*x); 36 | } 37 | 38 | vec4 taylorInvSqrt(vec4 r) 39 | { 40 | return 1.79284291400159 - 0.85373472095314 * r; 41 | } 42 | 43 | float snoise(vec3 v) 44 | { 45 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 46 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 47 | 48 | // First corner 49 | vec3 i = floor(v + dot(v, C.yyy) ); 50 | vec3 x0 = v - i + dot(i, C.xxx) ; 51 | 52 | // Other corners 53 | vec3 g = step(x0.yzx, x0.xyz); 54 | vec3 l = 1.0 - g; 55 | vec3 i1 = min( g.xyz, l.zxy ); 56 | vec3 i2 = max( g.xyz, l.zxy ); 57 | 58 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 59 | // x1 = x0 - i1 + 1.0 * C.xxx; 60 | // x2 = x0 - i2 + 2.0 * C.xxx; 61 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 62 | vec3 x1 = x0 - i1 + C.xxx; 63 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 64 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 65 | 66 | // Permutations 67 | i = mod289(i); 68 | vec4 p = permute( permute( permute( 69 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 70 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 71 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 72 | 73 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 74 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 75 | float n_ = 0.142857142857; // 1.0/7.0 76 | vec3 ns = n_ * D.wyz - D.xzx; 77 | 78 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 79 | 80 | vec4 x_ = floor(j * ns.z); 81 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 82 | 83 | vec4 x = x_ *ns.x + ns.yyyy; 84 | vec4 y = y_ *ns.x + ns.yyyy; 85 | vec4 h = 1.0 - abs(x) - abs(y); 86 | 87 | vec4 b0 = vec4( x.xy, y.xy ); 88 | vec4 b1 = vec4( x.zw, y.zw ); 89 | 90 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 91 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 92 | vec4 s0 = floor(b0)*2.0 + 1.0; 93 | vec4 s1 = floor(b1)*2.0 + 1.0; 94 | vec4 sh = -step(h, vec4(0.0)); 95 | 96 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 97 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 98 | 99 | vec3 p0 = vec3(a0.xy,h.x); 100 | vec3 p1 = vec3(a0.zw,h.y); 101 | vec3 p2 = vec3(a1.xy,h.z); 102 | vec3 p3 = vec3(a1.zw,h.w); 103 | 104 | //Normalise gradients 105 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 106 | p0 *= norm.x; 107 | p1 *= norm.y; 108 | p2 *= norm.z; 109 | p3 *= norm.w; 110 | 111 | // Mix final noise value 112 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 113 | m = m * m; 114 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 115 | dot(p2,x2), dot(p3,x3) ) ); 116 | } 117 | 118 | vec3 snoiseVec3( vec3 x ){ 119 | 120 | float s = snoise(vec3( x )); 121 | float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 )); 122 | float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 )); 123 | vec3 c = vec3( s , s1 , s2 ); 124 | return c; 125 | 126 | } 127 | 128 | vec3 curlNoise( vec3 p ){ 129 | 130 | const float e = .1; 131 | vec3 dx = vec3( e , 0.0 , 0.0 ); 132 | vec3 dy = vec3( 0.0 , e , 0.0 ); 133 | vec3 dz = vec3( 0.0 , 0.0 , e ); 134 | 135 | vec3 p_x0 = snoiseVec3( p - dx ); 136 | vec3 p_x1 = snoiseVec3( p + dx ); 137 | vec3 p_y0 = snoiseVec3( p - dy ); 138 | vec3 p_y1 = snoiseVec3( p + dy ); 139 | vec3 p_z0 = snoiseVec3( p - dz ); 140 | vec3 p_z1 = snoiseVec3( p + dz ); 141 | 142 | float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y; 143 | float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z; 144 | float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x; 145 | 146 | const float divisor = 1.0 / ( 2.0 * e ); 147 | return normalize( vec3( x , y , z ) * divisor ); 148 | 149 | } 150 | 151 | float rand(vec2 co){ 152 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 153 | } 154 | 155 | void main() { 156 | vec4 pos = texture2D(uTexture,vUv); 157 | vec4 opos = texture2D(uOrigin,vUv); 158 | 159 | 160 | 161 | vec3 noise = curlNoise(pos.xyz + vec3(0.0, 0.0, uTime)) * 0.01; 162 | pos.xyz += noise; 163 | pos.x += noise.x + 0.014; 164 | 165 | 166 | vec3 force = uMouse - (pos.xyz); 167 | 168 | float dist = distance(uMouse.xy, pos.xy); 169 | if(dist < 1.) { 170 | float ratio = (0.4 / length(force)) * 0.04 ; 171 | pos.xy -= force.xy * ratio; 172 | pos.z -= force.z * ratio * 0.1; 173 | } 174 | 175 | float life = pos.a; 176 | life -= 0.0020; 177 | if(life < 0.0010) { 178 | life = 1.0; 179 | pos.xyz = opos.xyz; 180 | } 181 | 182 | // vel.xy *= 0.85; 183 | // vel.z *= 0.85; 184 | 185 | // color = vel.xyz; 186 | 187 | 188 | gl_FragColor = vec4(pos.xyz, life); 189 | } 190 | -------------------------------------------------------------------------------- /src/experiments/spring/shaders/basic.vert: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 aPosition; 4 | attribute vec3 aNormal; 5 | attribute vec2 aUv; 6 | 7 | varying vec2 vUv; 8 | varying vec3 vNormal; 9 | 10 | void main() { 11 | vUv = vec2(aUv.x, aUv.y); 12 | vNormal = aNormal; 13 | gl_Position = vec4(aPosition, 1.0); 14 | } 15 | -------------------------------------------------------------------------------- /src/experiments/spring/shaders/instancing.frag: -------------------------------------------------------------------------------- 1 | precision mediump float; 2 | 3 | uniform sampler2D normalTexture; 4 | varying vec2 vUv; 5 | varying vec3 vViewPosition; 6 | 7 | uniform sampler2D uShadowMap; 8 | varying vec4 vShadowCoord; 9 | varying vec3 vColor; 10 | 11 | float diffuse(vec3 N, vec3 L) { 12 | return max(dot(N, normalize(L)), 0.0); 13 | } 14 | 15 | 16 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 17 | return diffuse(N, L) * C; 18 | } 19 | 20 | float sampleShadow(vec3 coord) { 21 | return step(coord.z, texture2D(uShadowMap, coord.xy).r + 0.006); 22 | } 23 | 24 | 25 | 26 | void main() { 27 | 28 | if ( length(vec2(0.5) - gl_PointCoord) > 0.5 ) { 29 | discard; 30 | } 31 | vec4 normals = texture2D(normalTexture,gl_PointCoord); 32 | 33 | vec3 light = diffuse(normals.xyz, normalize(vec3(0.0,20.0,1.0)), vec3(0.2)); 34 | vec4 shadowCoord = vShadowCoord / vShadowCoord.w; 35 | float shadow = 0.0; 36 | float offset = 0.0001; 37 | 38 | shadow += sampleShadow(shadowCoord.xyz); 39 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, -offset, 0.0)); 40 | shadow += sampleShadow(shadowCoord.xyz + vec3(-offset, 0.0, 0.0)); 41 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, 0.0, 0.0)); 42 | shadow += sampleShadow(shadowCoord.xyz + vec3( offset, 0.0, 0.0)); 43 | shadow += sampleShadow(shadowCoord.xyz + vec3( 0.0, offset, 0.0)); 44 | shadow /= 5.0; 45 | 46 | 47 | 48 | gl_FragColor = vec4( vColor*0.9 + light , normals.a); 49 | gl_FragColor.rgb *= vec3(smoothstep(0.0, 1.0, shadow+0.65)); 50 | } 51 | -------------------------------------------------------------------------------- /src/experiments/spring/shaders/instancing.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec2 aTwouv; 3 | attribute vec3 aColor; 4 | attribute float aSize; 5 | 6 | 7 | uniform mat4 projectionMatrix; 8 | uniform mat4 viewMatrix; 9 | uniform mat4 worldMatrix; 10 | uniform mat3 normalMatrix; 11 | uniform float uTime; 12 | uniform sampler2D uBuffer; 13 | uniform vec3 toLook; 14 | 15 | 16 | uniform mat4 uShadowMatrix; 17 | varying vec4 vShadowCoord; 18 | 19 | varying vec2 vUv; 20 | varying vec2 vUv2; 21 | varying vec3 vColor; 22 | varying vec3 vViewPosition; 23 | varying vec4 vOffset; 24 | 25 | uniform sampler2D colorsText; 26 | 27 | 28 | void main() { 29 | vec4 offset = texture2D(uBuffer, aTwouv); 30 | 31 | vec4 p = vec4(aPosition + offset.xyz,1.); 32 | vec4 worldPos = projectionMatrix * viewMatrix * worldMatrix * p; 33 | vViewPosition = worldPos.xyz; 34 | vShadowCoord = uShadowMatrix * worldMatrix * p; 35 | 36 | vec4 cc = texture2D(colorsText, vec2(aPosition.xy )); 37 | 38 | 39 | gl_Position = worldPos; 40 | gl_PointSize = 20. * (aSize * clamp(offset.a,0.2,1.)); 41 | // gl_PointSize = 20.; 42 | vColor = aColor; 43 | // vColor = cc.xyz * 0.2; 44 | 45 | 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/experiments/spring/shaders/sim.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | #define GLSLIFY 1 3 | 4 | uniform sampler2D uTexture; 5 | uniform sampler2D uTextureOld; 6 | uniform sampler2D uOrigin; 7 | 8 | uniform float uTime; 9 | 10 | uniform vec3 uMouse; 11 | uniform float width; 12 | uniform float height; 13 | varying vec2 vUv; 14 | 15 | // 16 | // Description : Array and textureless GLSL 2D/3D/4D simplex 17 | // noise functions. 18 | // Author : Ian McEwan, Ashima Arts. 19 | // Maintainer : ijm 20 | // Lastmod : 20110822 (ijm) 21 | // License : Copyright (C) 2011 Ashima Arts. All rights reserved. 22 | // Distributed under the MIT License. See LICENSE file. 23 | // https://github.com/ashima/webgl-noise 24 | // 25 | 26 | vec3 mod289(vec3 x) { 27 | return x - floor(x * (1.0 / 289.0)) * 289.0; 28 | } 29 | 30 | vec4 mod289(vec4 x) { 31 | return x - floor(x * (1.0 / 289.0)) * 289.0; 32 | } 33 | 34 | vec4 permute(vec4 x) { 35 | return mod289(((x*34.0)+1.0)*x); 36 | } 37 | 38 | vec4 taylorInvSqrt(vec4 r) 39 | { 40 | return 1.79284291400159 - 0.85373472095314 * r; 41 | } 42 | 43 | float snoise(vec3 v) 44 | { 45 | const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 46 | const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 47 | 48 | // First corner 49 | vec3 i = floor(v + dot(v, C.yyy) ); 50 | vec3 x0 = v - i + dot(i, C.xxx) ; 51 | 52 | // Other corners 53 | vec3 g = step(x0.yzx, x0.xyz); 54 | vec3 l = 1.0 - g; 55 | vec3 i1 = min( g.xyz, l.zxy ); 56 | vec3 i2 = max( g.xyz, l.zxy ); 57 | 58 | // x0 = x0 - 0.0 + 0.0 * C.xxx; 59 | // x1 = x0 - i1 + 1.0 * C.xxx; 60 | // x2 = x0 - i2 + 2.0 * C.xxx; 61 | // x3 = x0 - 1.0 + 3.0 * C.xxx; 62 | vec3 x1 = x0 - i1 + C.xxx; 63 | vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 64 | vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y 65 | 66 | // Permutations 67 | i = mod289(i); 68 | vec4 p = permute( permute( permute( 69 | i.z + vec4(0.0, i1.z, i2.z, 1.0 )) 70 | + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 71 | + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); 72 | 73 | // Gradients: 7x7 points over a square, mapped onto an octahedron. 74 | // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 75 | float n_ = 0.142857142857; // 1.0/7.0 76 | vec3 ns = n_ * D.wyz - D.xzx; 77 | 78 | vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 79 | 80 | vec4 x_ = floor(j * ns.z); 81 | vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) 82 | 83 | vec4 x = x_ *ns.x + ns.yyyy; 84 | vec4 y = y_ *ns.x + ns.yyyy; 85 | vec4 h = 1.0 - abs(x) - abs(y); 86 | 87 | vec4 b0 = vec4( x.xy, y.xy ); 88 | vec4 b1 = vec4( x.zw, y.zw ); 89 | 90 | //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 91 | //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 92 | vec4 s0 = floor(b0)*2.0 + 1.0; 93 | vec4 s1 = floor(b1)*2.0 + 1.0; 94 | vec4 sh = -step(h, vec4(0.0)); 95 | 96 | vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 97 | vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 98 | 99 | vec3 p0 = vec3(a0.xy,h.x); 100 | vec3 p1 = vec3(a0.zw,h.y); 101 | vec3 p2 = vec3(a1.xy,h.z); 102 | vec3 p3 = vec3(a1.zw,h.w); 103 | 104 | //Normalise gradients 105 | vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 106 | p0 *= norm.x; 107 | p1 *= norm.y; 108 | p2 *= norm.z; 109 | p3 *= norm.w; 110 | 111 | // Mix final noise value 112 | vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 113 | m = m * m; 114 | return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 115 | dot(p2,x2), dot(p3,x3) ) ); 116 | } 117 | 118 | vec3 snoiseVec3( vec3 x ){ 119 | 120 | float s = snoise(vec3( x )); 121 | float s1 = snoise(vec3( x.y - 19.1 , x.z + 33.4 , x.x + 47.2 )); 122 | float s2 = snoise(vec3( x.z + 74.2 , x.x - 124.5 , x.y + 99.4 )); 123 | vec3 c = vec3( s , s1 , s2 ); 124 | return c; 125 | 126 | } 127 | 128 | vec3 curlNoise( vec3 p ){ 129 | 130 | const float e = .1; 131 | vec3 dx = vec3( e , 0.0 , 0.0 ); 132 | vec3 dy = vec3( 0.0 , e , 0.0 ); 133 | vec3 dz = vec3( 0.0 , 0.0 , e ); 134 | 135 | vec3 p_x0 = snoiseVec3( p - dx ); 136 | vec3 p_x1 = snoiseVec3( p + dx ); 137 | vec3 p_y0 = snoiseVec3( p - dy ); 138 | vec3 p_y1 = snoiseVec3( p + dy ); 139 | vec3 p_z0 = snoiseVec3( p - dz ); 140 | vec3 p_z1 = snoiseVec3( p + dz ); 141 | 142 | float x = p_y1.z - p_y0.z - p_z1.y + p_z0.y; 143 | float y = p_z1.x - p_z0.x - p_x1.z + p_x0.z; 144 | float z = p_x1.y - p_x0.y - p_y1.x + p_y0.x; 145 | 146 | const float divisor = 1.0 / ( 2.0 * e ); 147 | return normalize( vec3( x , y , z ) * divisor ); 148 | 149 | } 150 | 151 | float rand(vec2 co){ 152 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); 153 | } 154 | 155 | void main() { 156 | vec4 pos = texture2D(uTexture,vUv); 157 | vec4 opos = texture2D(uOrigin,vUv); 158 | 159 | 160 | 161 | vec3 noise = curlNoise(pos.xyz + vec3(0.0, 0.0, uTime)) * 0.01; 162 | pos.xyz += noise; 163 | pos.x += noise.x + 0.014; 164 | 165 | 166 | vec3 force = uMouse - (pos.xyz); 167 | 168 | float dist = distance(uMouse.xy, pos.xy); 169 | if(dist < 1.) { 170 | float ratio = (0.4 / length(force)) * 0.04 ; 171 | pos.xy -= force.xy * ratio; 172 | pos.z -= force.z * ratio * 0.1; 173 | } 174 | 175 | float life = pos.a; 176 | life -= 0.0020; 177 | if(life < 0.0010) { 178 | life = 1.0; 179 | pos.xyz = opos.xyz; 180 | } 181 | 182 | // vel.xy *= 0.85; 183 | // vel.z *= 0.85; 184 | 185 | // color = vel.xyz; 186 | 187 | 188 | gl_FragColor = vec4(pos.xyz, life); 189 | } 190 | -------------------------------------------------------------------------------- /src/gl/camera/Camera.js: -------------------------------------------------------------------------------- 1 | import glm from 'gl-matrix'; 2 | 3 | export default class Camera 4 | { 5 | constructor() 6 | { 7 | this.projection = glm.mat4.create(); 8 | this.matrix = glm.mat4.create(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/gl/camera/OrthographicCamera.js: -------------------------------------------------------------------------------- 1 | import glm from 'gl-matrix'; 2 | import Object3D from '../core/Object3D'; 3 | 4 | export default class OrthographicCamera extends Object3D 5 | { 6 | constructor(left, right, bottom, top, zNear, zFar) 7 | { 8 | super(); 9 | 10 | this.left = left; 11 | this.right = right; 12 | this.bottom = bottom; 13 | this.top = top; 14 | this.zNear = zNear; 15 | this.zFar = zFar; 16 | this._projection = glm.mat4.create(); 17 | this._view = glm.mat4.create(); 18 | 19 | this._projection = glm.mat4.ortho(this._projection, 20 | left, 21 | right, 22 | bottom, 23 | top, 24 | zNear, 25 | zFar 26 | ); 27 | } 28 | lookAt(aEye, aCenter, aUp = [0, 1, 0]) 29 | { 30 | glm.vec3.copy(this.position, aEye); 31 | glm.mat4.identity(this._view); 32 | glm.mat4.lookAt(this._view, aEye, aCenter, aUp); 33 | } 34 | updateProjectionMatrix() 35 | { 36 | this._projection = glm.mat4.ortho(this._projection, 37 | this.left, 38 | this.right, 39 | this.bottom, 40 | this.top, 41 | this.zNear, 42 | this.zFar 43 | ); 44 | } 45 | get aspect() 46 | { 47 | return this._apsect; 48 | } 49 | set aspect(value) 50 | { 51 | this._apsect = value; 52 | // this.updateProjectionMatrix(); 53 | } 54 | 55 | get view() { return this._view; } 56 | 57 | get projection() { return this._projection; } 58 | } 59 | -------------------------------------------------------------------------------- /src/gl/camera/PerspectiveCamera.js: -------------------------------------------------------------------------------- 1 | import { vec3, mat4, glMatrix } from 'gl-matrix'; 2 | import Object3D from '../core/Object3D'; 3 | import Ray from '../math/Ray'; 4 | 5 | const mInverseViewProj = mat4.create(); 6 | const cameraDir = vec3.create(); 7 | 8 | export default class PerspectiveCamera extends Object3D 9 | { 10 | constructor(fieldOfViewDegree, aspect, zNear, zFar) 11 | { 12 | super(); 13 | this.fieldOfView = fieldOfViewDegree; 14 | this._apsect = aspect; 15 | this.zNear = zNear; 16 | this.zFar = zFar; 17 | 18 | this._view = mat4.create(); 19 | this._projection = mat4.create(); 20 | this._projection = mat4.perspective(this._projection, 21 | glMatrix.toRadian(fieldOfViewDegree), 22 | aspect, 23 | zNear, 24 | zFar 25 | ); 26 | } 27 | lookAt(aEye, aCenter, aUp = [0, 1, 0]) 28 | { 29 | this.position.x = aEye[0]; 30 | this.position.y = aEye[1]; 31 | this.position.z = aEye[2]; 32 | this.pp = aEye; 33 | mat4.identity(this._view); 34 | mat4.lookAt(this._view, aEye, aCenter, aUp); 35 | } 36 | updateProjectionMatrix() 37 | { 38 | this._projection = mat4.perspective(this._projection, 39 | glMatrix.toRadian(this.fieldOfView), 40 | this._apsect, 41 | this.zNear, 42 | this.zFar 43 | ); 44 | } 45 | get aspect() 46 | { 47 | return this._apsect; 48 | } 49 | set aspect(value) 50 | { 51 | this._apsect = value; 52 | this.updateProjectionMatrix(); 53 | } 54 | generateRay(mScreenPosition, mRay) 55 | { 56 | const proj = this.projection; 57 | const view = this.view; 58 | const camPos = vec3.fromValues(this.position.x, this.position.y, this.position.z); 59 | 60 | mat4.multiply(mInverseViewProj, proj, view); 61 | mat4.invert(mInverseViewProj, mInverseViewProj); 62 | // console.log(this.view); 63 | 64 | vec3.transformMat4(cameraDir, mScreenPosition, mInverseViewProj); 65 | vec3.sub(cameraDir, cameraDir, camPos); 66 | vec3.normalize(cameraDir, cameraDir); 67 | 68 | if (!mRay) 69 | { 70 | mRay = new Ray(camPos, cameraDir); 71 | } 72 | else 73 | { 74 | mRay.origin = camPos; 75 | mRay.direction = cameraDir; 76 | } 77 | 78 | return mRay; 79 | } 80 | 81 | get view() { return this._view; } 82 | 83 | get projection() { return this._projection; } 84 | } 85 | -------------------------------------------------------------------------------- /src/gl/core/ArrayBuffer.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData 2 | import { ARRAY_BUFFER, STATIC_DRAW } from '../const/webglConst'; 3 | 4 | class ArrayBuffer 5 | { 6 | /** 7 | * Constructs a new ArrayBuffer 8 | * @param {object} [params={}] options 9 | * @param {string} params.context context webgl 10 | * @param {object} [params.data=null] data of the buffer 11 | * @param {number} [params.usage=STATIC_DRAW] webgl draw usage 12 | * @param {number} [params.divisor=null] divisor for instancing 13 | */ 14 | constructor({ context, data, usage, divisor }) 15 | { 16 | this.gl = context; 17 | this.buffer = this.gl.createBuffer(); 18 | this.usage = usage || STATIC_DRAW; 19 | this.divisor = divisor; 20 | if (this.divisor) 21 | { 22 | this.instanced = true; 23 | } 24 | 25 | this.length = -1; 26 | this.data(data); 27 | } 28 | /** 29 | * @func bind 30 | * @description Bind the arrayBuffer 31 | * @memberof ArrayBuffer.prototype 32 | */ 33 | bind() 34 | { 35 | this.gl.bindBuffer(ARRAY_BUFFER, this.buffer); 36 | } 37 | /** 38 | * @func unbind 39 | * @description Unbind the arrayBuffer 40 | * @memberof ArrayBuffer.prototype 41 | */ 42 | unbind() 43 | { 44 | this.gl.bindBuffer(ARRAY_BUFFER, this.buffer); 45 | } 46 | /** 47 | * @func data 48 | * @description add data to the arrayBuffer 49 | * @param {Float32Array} data data 50 | * @memberof ArrayBuffer.prototype 51 | */ 52 | data(data) 53 | { 54 | this.bind(); 55 | this.gl.bufferData(ARRAY_BUFFER, new Float32Array(data), this.usage); 56 | this.gl.bindBuffer(ARRAY_BUFFER, null); 57 | this._data = new Float32Array(data); 58 | } 59 | /** 60 | * @func attribPointer 61 | * @description set the attribute pointer 62 | * @param {object} attribute attribute 63 | * @memberof ArrayBuffer.prototype 64 | */ 65 | attribPointer(attribute) 66 | { 67 | if (attribute === undefined) 68 | { 69 | // console.log(arguments); 70 | // Debug.error(`Attribute not used in shader`); 71 | return; 72 | } 73 | if (this.length === -1) 74 | { 75 | this.attribute = attribute; 76 | this.computeLenght(attribute._size); 77 | } 78 | this.bind(); 79 | this.gl.vertexAttribPointer(attribute.location, attribute._size, this.gl.FLOAT, false, 0, 0); 80 | this.gl.enableVertexAttribArray(attribute.location); 81 | } 82 | /** 83 | * @func attribPointerInstanced 84 | * @description set the attribute pointer 85 | * @param {object} attribute attribute 86 | * @param {number} divisor divisor 87 | * @memberof ArrayBuffer.prototype 88 | */ 89 | attribPointerInstanced(attribute, divisor) 90 | { 91 | this.attribPointer(attribute); 92 | const ext = this.gl.getExtension('ANGLE_instanced_arrays'); 93 | // console.log(ext); 94 | 95 | ext.vertexAttribDivisorANGLE(attribute.location, divisor); 96 | } 97 | /** 98 | * @func computeLenght 99 | * @description compute the length of the buffer depending of the data type 100 | * @param {number} attribSize attribSize 101 | * @memberof ArrayBuffer.prototype 102 | */ 103 | computeLenght(attribSize) 104 | { 105 | this.length = Math.floor(this._data.length / attribSize); 106 | } 107 | /** 108 | * @func draw 109 | * @description draw the arrayBuffer 110 | * @param {object} mode webgl mode gl.TRIANGLES... 111 | * @param {number} [offset=0] offset for strided data 112 | * @memberof ArrayBuffer.prototype 113 | */ 114 | draw(mode, offset = 0) 115 | { 116 | this.gl.drawArrays(mode, offset, this.length); 117 | } 118 | } 119 | 120 | export default ArrayBuffer; 121 | -------------------------------------------------------------------------------- /src/gl/core/Extension.js: -------------------------------------------------------------------------------- 1 | import Debug from '../utils/Debug'; 2 | 3 | class Extension 4 | { 5 | /** 6 | * @func setGl 7 | * @description Set the webgl context 8 | * @memberof Extension.prototype 9 | */ 10 | setGl(gl) 11 | { 12 | this.gl = gl; 13 | } 14 | /** 15 | * @func active 16 | * @description Active a webgl extension 17 | * @param {string} name name of the extension 18 | * @memberof Extension.prototype 19 | */ 20 | active(name) 21 | { 22 | Debug.info(`Activing: ${name}`); 23 | 24 | const extension = gl.getExtension(name); 25 | 26 | if (extension) 27 | { 28 | Debug.log(`Actived`); 29 | 30 | for (const key in extension) 31 | { 32 | if (typeof extension[key] === 'function') 33 | { 34 | const keyWithoutSuff = key.replace(/OES|MOZ_OES|WEBKIT_OES/g, ''); 35 | 36 | this.gl[keyWithoutSuff] = extension[key].bind(extension); 37 | // console.log(keyWithoutSuff); 38 | } 39 | } 40 | } 41 | else 42 | { 43 | Debug.error(`Extension: {name} is not available on this device`); 44 | } 45 | } 46 | } 47 | 48 | export default new Extension(); 49 | -------------------------------------------------------------------------------- /src/gl/core/FrameBuffer.js: -------------------------------------------------------------------------------- 1 | import Debug from '../utils/Debug'; 2 | import Texture from './Texture'; 3 | class FrameBuffer 4 | { 5 | /** 6 | * Constructs a new FrameBuffer 7 | * @param {object} gl webgl context 8 | * @param {number} width width 9 | * @param {number} height height 10 | * @param {object} [options={}] options 11 | * @param {boolean} [options.depth=false] using depthTexture 12 | */ 13 | constructor(gl, width, height, options = {}) 14 | { 15 | Debug.info(`FBO created width: ${width} height: ${height}`); 16 | 17 | this.gl = gl; 18 | this.width = width; 19 | this.height = height; 20 | this.fbo = gl.createFramebuffer(); 21 | 22 | this.colors = new Texture(gl); 23 | this.colors.format = gl.RGBA; 24 | this.colors.minFilter = gl.NEAREST; 25 | this.colors.magFilter = gl.NEAREST; 26 | this.colors.wrapT = gl.CLAMP_TO_EDGE; 27 | this.colors.wrapS = gl.CLAMP_TO_EDGE; 28 | this.gl.getExtension('OES_texture_float'); 29 | 30 | this.colors.type = this.gl.FLOAT; 31 | this.colors.uploadData(null, width, height); 32 | 33 | if (options.depth) 34 | { 35 | Debug.info('Use depth texture'); 36 | 37 | this.gl.getExtension('WEBGL_depth_texture'); 38 | 39 | // 40 | // this.renderBuffer = gl.createRenderbuffer(); 41 | this.depth = new Texture(gl, width, height, gl.UNSIGNED_SHORT, gl.DEPTH_COMPONENT); 42 | this.depth.minFilter = gl.NEAREST; 43 | this.depth.magFilter = gl.NEAREST; 44 | this.depth.wrapT = gl.CLAMP_TO_EDGE; 45 | this.depth.wrapS = gl.CLAMP_TO_EDGE; 46 | this.depth.type = gl.UNSIGNED_SHORT; 47 | this.depth.format = gl.DEPTH_COMPONENT; 48 | 49 | this.depth.uploadData(null, width, height, true); 50 | } 51 | 52 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fbo); 53 | this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, this.colors.id, 0); 54 | if (options.depth) 55 | { 56 | this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, 57 | this.gl.TEXTURE_2D, this.depth.id, 0); 58 | } 59 | 60 | this.setSize(width, height); 61 | 62 | this.unbind(); 63 | } 64 | /** 65 | * @func bind 66 | * @description Bind the framebuffer 67 | * @memberof FrameBuffer.prototype 68 | */ 69 | bind() 70 | { 71 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.fbo); 72 | this.gl.viewport(0, 0, this.width, this.height); 73 | } 74 | /** 75 | * @func clear 76 | * @description Clear the framebuffer 77 | * @memberof FrameBuffer.prototype 78 | */ 79 | clear() 80 | { 81 | this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT); 82 | } 83 | /** 84 | * @func unbind 85 | * @description Unbind the framebuffer 86 | * @memberof FrameBuffer.prototype 87 | */ 88 | unbind() 89 | { 90 | this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height); 91 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 92 | this.colors.unbind(); 93 | } 94 | /** 95 | * @func setSize 96 | * @description Set the size of the framebuffer 97 | * @param {number} width width 98 | * @param {number} height height 99 | * @memberof FrameBuffer.prototype 100 | */ 101 | setSize(width, height) 102 | { 103 | this.bind(); 104 | this.fbo.width = width; 105 | this.fbo.height = height; 106 | this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null); 107 | } 108 | } 109 | 110 | export default FrameBuffer; 111 | -------------------------------------------------------------------------------- /src/gl/core/IndexBuffer.js: -------------------------------------------------------------------------------- 1 | // https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData 2 | import { ELEMENT_ARRAY_BUFFER, STATIC_DRAW, UNSIGNED_SHORT } from '../const/webglConst'; 3 | class IndexBuffer 4 | { 5 | /** 6 | * Constructs a new ArrayBuffer 7 | * @param {object} [params={}] options 8 | * @param {string} params.context context webgl 9 | * @param {object} [params.data=null] data of the buffer 10 | * @param {number} [params.usage=STATIC_DRAW] webgl draw usage 11 | * @param {number} [params.divisor=null] divisor for instancing 12 | */ 13 | constructor({ context, data, usage }) 14 | { 15 | this.gl = context; 16 | this.buffer = this.gl.createBuffer(); 17 | this.usage = usage || STATIC_DRAW; 18 | this.length = data.length; 19 | this.data(data); 20 | } 21 | /** 22 | * @func bind 23 | * @description Bind the indexBuffer 24 | * @memberof IndexBuffer.prototype 25 | */ 26 | bind() 27 | { 28 | this.gl.bindBuffer(ELEMENT_ARRAY_BUFFER, this.buffer); 29 | } 30 | /** 31 | * @func unbind 32 | * @description Unbind the indexBuffer 33 | * @memberof IndexBuffer.prototype 34 | */ 35 | unbind() 36 | { 37 | this.gl.bindBuffer(ELEMENT_ARRAY_BUFFER, null); 38 | } 39 | /** 40 | * @func data 41 | * @description add data to the indexBuffer 42 | * @param {Uint16Array} data data 43 | * @memberof IndexBuffer.prototype 44 | */ 45 | data(data) 46 | { 47 | this.bind(); 48 | this.gl.bufferData(ELEMENT_ARRAY_BUFFER, new Uint16Array(data), this.usage); 49 | this.gl.bindBuffer(ELEMENT_ARRAY_BUFFER, null); 50 | this._data = data; 51 | } 52 | /** 53 | * @func draw 54 | * @description draw the indexBuffer 55 | * @param {object} mode webgl mode gl.TRIANGLES... 56 | * @param {offset} offset offset for strided data 57 | * @memberof IndexBuffer.prototype 58 | */ 59 | draw(mode, offset = 0) 60 | { 61 | // console.log(this.length); 62 | this.gl.drawElements(mode, this.length, UNSIGNED_SHORT, offset); 63 | } 64 | /** 65 | * @func drawInstance 66 | * @description draw the indexBuffer 67 | * @param {object} mode webgl mode gl.TRIANGLES... 68 | * @param {number} count number of instances 69 | * @memberof IndexBuffer.prototype 70 | */ 71 | drawInstance(mode, count) 72 | { 73 | // console.log(this.length); 74 | const ext = this.gl.getExtension('ANGLE_instanced_arrays'); 75 | 76 | ext.drawElementsInstancedANGLE(mode, this.length, UNSIGNED_SHORT, 0, count); 77 | } 78 | } 79 | export default IndexBuffer; 80 | -------------------------------------------------------------------------------- /src/gl/core/Object3D.js: -------------------------------------------------------------------------------- 1 | import * as glm from 'gl-matrix'; 2 | import Vector3 from '../math/Vector3'; 3 | import uuid from '../utils/UIID'; 4 | 5 | class Object3D 6 | { 7 | /** 8 | * Constructs a new Object3D 9 | * @property {boolean} visible=true 10 | * @property {string} uuid 11 | * @property {object} position 12 | * @property {object} rotation 13 | * @property {object} scale 14 | * @property {object} parent=null 15 | * @property {array} children 16 | * @property {array} matrix 17 | * @property {array} matrixWorld 18 | * @property {array} positionWorld 19 | */ 20 | constructor() 21 | { 22 | this.visible = true; 23 | this.uuid = uuid(); 24 | 25 | this._needUpdate = true; 26 | 27 | this.position = new Vector3(); 28 | 29 | this.rotation = new Vector3(); 30 | 31 | this.scale = new Vector3(1, 1, 1); 32 | 33 | this.position.onChange(() => 34 | { 35 | this._needUpdate = true; 36 | // console.log('cc'); 37 | }); 38 | this.rotation.onChange(() => 39 | { 40 | this._needUpdate = true; 41 | }); 42 | this.scale.onChange(() => 43 | { 44 | this._needUpdate = true; 45 | }); 46 | 47 | this._matrix = glm.mat4.create(); 48 | this._matrixWorld = glm.mat4.create(); 49 | this._matrixRotation = glm.mat4.create(); 50 | this._matrixScale = glm.mat4.create(); 51 | this._matrixTranslation = glm.mat4.create(); 52 | this._matrixIdentity = glm.mat4.create(); 53 | 54 | this.parent = null; 55 | this.children = []; 56 | } 57 | _updateMatrix() 58 | { 59 | if (!this.visible) 60 | { 61 | return; 62 | } 63 | 64 | glm.mat4.rotateX(this._matrixRotation, this._matrixIdentity, this.rotation.x); 65 | glm.mat4.rotateY(this._matrixRotation, this._matrixRotation, this.rotation.y); 66 | glm.mat4.rotateZ(this._matrixRotation, this._matrixRotation, this.rotation.z); 67 | 68 | glm.mat4.scale(this._matrixScale, this._matrixIdentity, this.scale.get()); 69 | glm.mat4.translate(this._matrixTranslation, this._matrixIdentity, this.position.get()); 70 | 71 | glm.mat4.mul(this._matrix, this._matrixTranslation, this._matrixRotation); 72 | glm.mat4.mul(this._matrix, this._matrix, this._matrixScale); 73 | this._updateMatrixWorld(); 74 | this._needUpdate = false; 75 | } 76 | _updateMatrixWorld() 77 | { 78 | if (!this.visible) 79 | { 80 | return; 81 | } 82 | 83 | if (this.parent) 84 | { 85 | glm.mat4.multiply(this._matrixWorld, this.parent._matrixWorld, this._matrix); 86 | } 87 | else 88 | { 89 | glm.mat4.copy(this._matrixWorld, this._matrix); 90 | } 91 | 92 | for (let i = 0, l = this.children.length; i < l; i += 1) 93 | { 94 | this.children[i]._updateMatrixWorld(); 95 | } 96 | } 97 | get positionWorld() 98 | { 99 | if (!this.parent) return this.position.get(); 100 | 101 | return [this.parent.position.x + this.position.x, 102 | this.parent.position.y + this.position.y, this.parent.position.z + this.position.z]; 103 | } 104 | get matrixWorld() 105 | { 106 | if (this._needUpdate) this._updateMatrix(); 107 | 108 | return this._matrixWorld; 109 | } 110 | get matrix() 111 | { 112 | if (this._needUpdate) this._updateMatrix(); 113 | 114 | return this._matrix; 115 | } 116 | /** 117 | * @func addChild 118 | * @description Add a child to the object 119 | * @param {object} child an Object3D 120 | * @memberof Object3D.prototype 121 | */ 122 | addChild(object) 123 | { 124 | if (object.parent) 125 | { 126 | const ndx = object.parent.children.indexOf(this); 127 | 128 | if (ndx >= 0) 129 | { 130 | object.parent.children.splice(ndx, 1); 131 | } 132 | } 133 | object.parent = this; 134 | this.children.push(object); 135 | } 136 | } 137 | 138 | export default Object3D; 139 | -------------------------------------------------------------------------------- /src/gl/core/State.js: -------------------------------------------------------------------------------- 1 | class State 2 | { 3 | /** 4 | * Instance of the State Mananger 5 | * @property {object} capabilities 6 | */ 7 | constructor() 8 | { 9 | // all state 10 | this.capabilities = {}; 11 | } 12 | /** 13 | * @func enable 14 | * @description Enable gl state 15 | * @param {string} id 16 | * @memberof State.prototype 17 | */ 18 | enable(id) 19 | { 20 | if (this.capabilities[id] !== true) 21 | { 22 | gl.enable(id); 23 | this.capabilities[id] = true; 24 | } 25 | } 26 | /** 27 | * @func disable 28 | * @description Disable gl state 29 | * @param {string} id 30 | * @memberof State.prototype 31 | */ 32 | disable(id) 33 | { 34 | if (this.capabilities[id] !== false) 35 | { 36 | gl.disable(id); 37 | this.capabilities[id] = false; 38 | } 39 | } 40 | } 41 | 42 | const state = new State(); 43 | 44 | export default state; 45 | -------------------------------------------------------------------------------- /src/gl/core/Texture.js: -------------------------------------------------------------------------------- 1 | import Numbers from '../const/webglNumber'; 2 | export default class Texture 3 | { 4 | constructor(context, width, height, format, type) 5 | { 6 | this.gl = context; 7 | this.id = this.gl.createTexture(); 8 | this._bindIndex = 0; 9 | 10 | this.width = width || -1; 11 | this.height = height || -1; 12 | this.format = this.gl.RGB; 13 | this.type = type || this.gl.UNSIGNED_BYTE; 14 | 15 | this.minFilter = this.gl.NEAREST; 16 | this.magFilter = this.gl.NEAREST; 17 | this.wrapS = this.gl.CLAMP_TO_EDGE; 18 | this.wrapT = this.gl.CLAMP_TO_EDGE; 19 | this._bindIndex = null; 20 | } 21 | upload(image) 22 | { 23 | if (this.width !== image.width) 24 | { 25 | this.width = image.width; 26 | } 27 | if (this.height !== image.height) 28 | { 29 | this.height = image.height; 30 | } 31 | 32 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 33 | this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false); 34 | this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this._type, image); 35 | } 36 | uploadData(data, width, height) 37 | { 38 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 39 | 40 | if (data instanceof Float32Array) 41 | { 42 | // get extension check 43 | this.gl.getExtension('OES_texture_float'); 44 | 45 | this.type = this.gl.FLOAT; 46 | } 47 | this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this._format, width, height, 0, this._format, this._type, data || null); 48 | this.unbind(); 49 | } 50 | set magFilter(value) 51 | { 52 | this.bind(); 53 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, value); 54 | this._magFilter = value; 55 | this.unbind(); 56 | } 57 | get magFilter() 58 | { 59 | return Numbers[this._magFilter]; 60 | } 61 | set minFilter(value) 62 | { 63 | this.bind(); 64 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, value); 65 | this._minFilter = value; 66 | this.unbind(); 67 | } 68 | get minFilter() 69 | { 70 | return Numbers[this._minFilter]; 71 | } 72 | set wrapS(value) 73 | { 74 | this.bind(); 75 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, value); 76 | this._wrapS = value; 77 | this.unbind(); 78 | } 79 | get wrapS() 80 | { 81 | return Numbers[this._wrapS]; 82 | } 83 | set wrapT(value) 84 | { 85 | this.bind(); 86 | this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, value); 87 | this._wrapT = value; 88 | this.unbind(); 89 | } 90 | get wrapT() 91 | { 92 | return Numbers[this._wrapT]; 93 | } 94 | set type(value) 95 | { 96 | this._type = value; 97 | } 98 | get type() 99 | { 100 | return Numbers[this._type]; 101 | } 102 | set format(value) 103 | { 104 | this._format = value; 105 | } 106 | get format() 107 | { 108 | return Numbers[this._format]; 109 | } 110 | bindIndex(index) 111 | { 112 | this._bindIndex = index; 113 | } 114 | bind() 115 | { 116 | this.gl.activeTexture(this.gl.TEXTURE0 + this._bindIndex); 117 | this.gl.bindTexture(this.gl.TEXTURE_2D, this.id); 118 | // this.unbind(); 119 | } 120 | unbind() 121 | { 122 | this.gl.bindTexture(this.gl.TEXTURE_2D, null); 123 | } 124 | // shortcuts 125 | nearest() 126 | { 127 | this.minFilter = this.gl.NEAREST; 128 | this.magFilter = this.gl.NEAREST; 129 | } 130 | linear() 131 | { 132 | this.minFilter = this.gl.LINEAR; 133 | this.magFilter = this.gl.LINEAR; 134 | } 135 | repeat() 136 | { 137 | this.wrapS = this.gl.REPEAT; 138 | this.wrapT = this.gl.REPEAT; 139 | } 140 | clamp() 141 | { 142 | this.wrapS = this.gl.CLAMP_TO_EDGE; 143 | this.wrapT = this.gl.CLAMP_TO_EDGE; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/gl/core/Texture3D.js: -------------------------------------------------------------------------------- 1 | import Numbers from '../const/webglNumber'; 2 | 3 | export default class Texture3D 4 | { 5 | constructor(context, width, height, depth) 6 | { 7 | this.gl = context; 8 | this.id = this.gl.createTexture(); 9 | 10 | this.width = width || -1; 11 | this.height = height || -1; 12 | this.depth = depth || -1; 13 | 14 | // this.format = this.gl.RGB; 15 | this.format = this.gl.RED; 16 | // this.internalformat = this.gl.RGB; 17 | this.internalformat = this.gl.R8; 18 | this.type = this.gl.UNSIGNED_BYTE; 19 | 20 | this.minFilter = this.gl.LINEAR; 21 | this.magFilter = this.gl.LINEAR; 22 | this.wrapS = this.gl.CLAMP_TO_EDGE; 23 | this.wrapT = this.gl.CLAMP_TO_EDGE; 24 | } 25 | upload(image, width, height, depth) 26 | { 27 | this.gl.bindTexture(this.gl.TEXTURE_3D, this.id); 28 | 29 | this.gl.texImage3D(this.gl.TEXTURE_3D, 0, this._internalformat, 30 | image.width, image.height, depth, 0, this._format, this._type, image); 31 | } 32 | uploadData(data, width, height, depth) 33 | { 34 | this.width = width; 35 | this.height = height; 36 | this.depth = depth; 37 | this.gl.bindTexture(this.gl.TEXTURE_3D, this.id); 38 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_BASE_LEVEL, 0); 39 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAX_LEVEL, Math.log2(depth)); 40 | 41 | if (data instanceof Float32Array) 42 | { 43 | // get extension check 44 | this.gl.getExtension('OES_texture_float'); 45 | 46 | this.type = this.gl.FLOAT; 47 | } 48 | 49 | this.gl.texImage3D(this.gl.TEXTURE_3D, 0, this._internalformat, 50 | width, height, depth, 0, this._format, this._type, data || null); 51 | 52 | this.unbind(); 53 | } 54 | set magFilter(value) 55 | { 56 | this.bind(); 57 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MAG_FILTER, value); 58 | this._magFilter = value; 59 | } 60 | get magFilter() 61 | { 62 | return Numbers[this._magFilter]; 63 | } 64 | set minFilter(value) 65 | { 66 | this.bind(); 67 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_MIN_FILTER, value); 68 | this._minFilter = value; 69 | } 70 | get minFilter() 71 | { 72 | return Numbers[this._minFilter]; 73 | } 74 | set wrapS(value) 75 | { 76 | this.bind(); 77 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_WRAP_S, value); 78 | 79 | this._wrapS = value; 80 | } 81 | get wrapS() 82 | { 83 | return Numbers[this._wrapS]; 84 | } 85 | set wrapT(value) 86 | { 87 | this.bind(); 88 | this.gl.texParameteri(this.gl.TEXTURE_3D, this.gl.TEXTURE_WRAP_T, value); 89 | 90 | this._wrapT = value; 91 | } 92 | get wrapT() 93 | { 94 | return Numbers[this._wrapT]; 95 | } 96 | set type(value) 97 | { 98 | this._type = value; 99 | } 100 | get type() 101 | { 102 | return Numbers[this._type]; 103 | } 104 | set format(value) 105 | { 106 | this._format = value; 107 | } 108 | get format() 109 | { 110 | return Numbers[this._format]; 111 | } 112 | set internalformat(value) 113 | { 114 | this._internalformat = value; 115 | } 116 | get internalformat() 117 | { 118 | return Numbers[this._internalformat]; 119 | } 120 | bind(unit) 121 | { 122 | if (unit) 123 | { this.gl.activeTexture(this.gl.TEXTURE0 + unit); } 124 | this.gl.bindTexture(this.gl.TEXTURE_3D, this.id); 125 | } 126 | unbind() 127 | { 128 | this.gl.bindTexture(this.gl.TEXTURE_3D, null); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/gl/core/TextureCube.js: -------------------------------------------------------------------------------- 1 | export default class CubeMapTexture 2 | { 3 | constructor(context, textures, type) 4 | { 5 | this.gl = context; 6 | this._bindIndex = 0; 7 | this.type = type || this.gl.UNSIGNED_BYTE; 8 | 9 | this.id = this.gl.createTexture(); 10 | this.bind(); 11 | if (textures.length < 6) 12 | { 13 | console.warn('Need at leat 6 textures'); 14 | } 15 | 16 | for (let i = 0; i < textures.length; i++) 17 | { 18 | this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, false); 19 | this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 20 | this.gl.RGBA, this.gl.RGBA, this.type, textures[i]); 21 | } 22 | this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR); 23 | this.gl.texParameteri(this.gl.TEXTURE_CUBE_MAP, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR); 24 | 25 | this.unbind(); 26 | } 27 | 28 | bind() 29 | { 30 | this.gl.activeTexture(this.gl.TEXTURE0 + this._bindIndex); 31 | this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.id); 32 | } 33 | bindIndex(index) 34 | { 35 | this._bindIndex = index; 36 | } 37 | unbind() 38 | { 39 | this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, null); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/gl/high/BasicMaterial.js: -------------------------------------------------------------------------------- 1 | import Shader from './Shader'; 2 | const glslify = require('glslify'); 3 | 4 | function filterEmptyLine(string) 5 | { 6 | return string !== ''; 7 | } 8 | 9 | export default class Material extends Shader 10 | { 11 | constructor(options = {}) 12 | { 13 | // console.log(glslify('../shaders/basic.vert')); 14 | const vs = glslify('../shaders/basic.vert'); 15 | const fs = glslify('../shaders/basic.frag'); 16 | // console.log(vs); 17 | const definesVs = [ 18 | options.color ? '#define COLOR' : '', 19 | options.normalMap ? '#define NORMAL_MAP' : '', 20 | options.fog ? '#define FOG' : '', 21 | ].filter(filterEmptyLine).join('\n'); 22 | 23 | const definesFs = [ 24 | options.color ? '#define COLOR' : '', 25 | options.texture ? '#define TEXTURE' : '', 26 | options.normalMap ? '#define NORMAL_MAP' : '', 27 | options.fog ? '#define FOG' : '', 28 | 29 | ].filter(filterEmptyLine).join('\n'); 30 | 31 | let vertex = `${definesVs}\n${vs}`; 32 | let fragment = `${definesFs}\n${fs}`; 33 | 34 | if (!options.vertex) options.vertex = {}; 35 | 36 | vertex = vertex.replace(/#HOOK_VERTEX_START/g, options.vertex.start || ''); 37 | vertex = vertex.replace(/#HOOK_VERTEX_MAIN/g, options.vertex.main || ''); 38 | vertex = vertex.replace(/#HOOK_VERTEX_END/g, options.vertex.end || ''); 39 | 40 | if (!options.fragment) options.fragment = {}; 41 | 42 | fragment = fragment.replace(/#HOOK_FRAGMENT_START/g, options.fragment.start || ''); 43 | fragment = fragment.replace(/#HOOK_FRAGMENT_MAIN/g, options.fragment.main || ''); 44 | fragment = fragment.replace(/#HOOK_FRAGMENT_END/g, options.fragment.end || ''); 45 | 46 | // console.log(fragment); 47 | // console.log(vertex); 48 | 49 | if (!options.fog) options.fog = {}; 50 | // if(!options.uniforms) options.uniforms = {}; 51 | 52 | super(vertex, fragment, Object.assign({}, { 53 | uColor: options.color || [0, 0, 0], 54 | uTexture: options.texture || null, 55 | uNormalMap: options.normalMap || null, 56 | uNormalScale: options.normalScale || [1, 1], 57 | uNormalUVRepeat: options.normalUvRepeat || [1, 1], 58 | uDensity: options.fog.density || 0.0, 59 | uGradient: options.fog.gradient || 0.0, 60 | uFogColor: options.fog.color || [0, 0, 0], 61 | }, options.uniforms), 'BasicMaterial'); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/gl/high/Geometry.js: -------------------------------------------------------------------------------- 1 | import IndexBuffer from '../core/IndexBuffer'; 2 | import ArrayBuffer from '../core/ArrayBuffer'; 3 | import ArrayUtils from '../utils/ArrayUtils'; 4 | export default class Geometry 5 | { 6 | constructor(data = {}) 7 | { 8 | this.attributes = {}; 9 | const flat = data.flat || false; 10 | 11 | if (data.positions) 12 | { 13 | this.addAttribute('positions', data.positions, flat); 14 | } 15 | if (data.uvs) 16 | { 17 | this.addAttribute('uvs', data.uvs, flat); 18 | } 19 | if (data.normals) 20 | { 21 | this.addAttribute('normals', data.normals, flat); 22 | } 23 | if (data.indices || data.cells) 24 | { 25 | this.addIndices(data.indices || data.cells, flat); 26 | } 27 | } 28 | addInstancedAttribute(name, data, divisor, flat) 29 | { 30 | this.instanced = true; 31 | this.count = 1; 32 | this.attributes[name] = new ArrayBuffer({ 33 | context: gl, 34 | data: flat ? data : ArrayUtils.flatten(data), 35 | divisor, 36 | }); 37 | this[name] = this.attributes[name]; 38 | 39 | return this; 40 | } 41 | addCount(count) 42 | { 43 | this.count = count; 44 | } 45 | addAttribute(name, data, flat) 46 | { 47 | this.attributes[name] = new ArrayBuffer({ 48 | context: gl, 49 | data: flat ? data : ArrayUtils.flatten(data), 50 | }); 51 | this[name] = this.attributes[name]; 52 | 53 | return this; 54 | } 55 | addIndices(data, flat) 56 | { 57 | this.indices = new IndexBuffer({ 58 | context: gl, 59 | data: flat ? data : ArrayUtils.flatten(data), 60 | }); 61 | 62 | return this; 63 | } 64 | generateFaces() 65 | { 66 | const faces = ArrayUtils.generateFaces(this.positions._data, this.indices._data); 67 | 68 | this.faces = faces; 69 | 70 | return this.faces; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/gl/high/Mesh.js: -------------------------------------------------------------------------------- 1 | import Object3D from '../core/Object3D'; 2 | 3 | export default class Mesh extends Object3D 4 | { 5 | constructor(geometry, shader, options = {}) 6 | { 7 | super(); 8 | // console.log(options); 9 | this.drawType = options.drawType !== undefined ? options.drawType : gl.TRIANGLES; 10 | this.depthTest = options.depthTest !== undefined ? options.depthTest : true; 11 | this.geometry = geometry, 12 | this.shader = shader; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/gl/high/Shader.js: -------------------------------------------------------------------------------- 1 | import Program from '../core/Program'; 2 | 3 | export default class Shader 4 | { 5 | constructor(vs, fs, uniforms = {}, name) 6 | { 7 | this.program = new Program({ 8 | context: gl, 9 | vertexShader: vs, 10 | fragmentShader: fs, 11 | name, 12 | }); 13 | this.uniforms = uniforms; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/gl/index.js: -------------------------------------------------------------------------------- 1 | import ArrayBuffer from './core/ArrayBuffer'; 2 | import IndexBuffer from './core/IndexBuffer'; 3 | import FrameBuffer from './core/FrameBuffer'; 4 | import Object3D from './core/Object3D'; 5 | import Program from './core/Program'; 6 | import Texture from './core/Texture'; 7 | import TextureCube from './core/TextureCube'; 8 | import Webgl from './core/Webgl'; 9 | import State from './core/State'; 10 | 11 | import OrthographicCamera from './camera/OrthographicCamera'; 12 | import PerspectiveCamera from './camera/PerspectiveCamera'; 13 | 14 | import GLNumber from './const/webglNumber'; 15 | import GLConst from './const/webglConst'; 16 | 17 | import Geometry from './high/Geometry'; 18 | import Mesh from './high/Mesh'; 19 | import Shader from './high/Shader'; 20 | import Primitive from './high/Primitive'; 21 | import BasicMaterial from './high/BasicMaterial'; 22 | 23 | import Utils from './utils/Utils'; 24 | import ArrayUtils from './utils/ArrayUtils'; 25 | import ObjParser from './utils/ObjParser'; 26 | import Debug from './utils/Debug'; 27 | import HitDetect from './utils/HitDetect'; 28 | import Vector3 from './math/Vector3'; 29 | 30 | import Composer from './post/Composer'; 31 | import Pass from './post/Pass'; 32 | import NoisePass from './post/NoisePass'; 33 | import BoxBlurPass from './post/BoxBlurPass'; 34 | import FullBoxBlurPass from './post/FullBoxBlurPass'; 35 | import InvertPass from './post/InvertPass'; 36 | import FXAAPass from './post/FXAAPass'; 37 | import ToonPass from './post/ToonPass'; 38 | import BrightnessContrastPass from './post/BrightnessContrastPass'; 39 | import DofPass from './post/DofPass'; 40 | import TiltPass from './post/TiltPass'; 41 | import BlendPass from './post/BlendPass'; 42 | import BloomPass from './post/BloomPass'; 43 | 44 | import FBOHelper from './utils/FBOHelper'; 45 | 46 | import glm from 'gl-matrix'; 47 | const vanilla = { 48 | glm, 49 | // core 50 | Webgl, 51 | Texture, 52 | TextureCube, 53 | Program, 54 | Object3D, 55 | FrameBuffer, 56 | IndexBuffer, 57 | ArrayBuffer, 58 | 59 | // camera 60 | OrthographicCamera, 61 | PerspectiveCamera, 62 | 63 | // const 64 | GLNumber, 65 | GLConst, 66 | 67 | // high api 68 | Geometry, 69 | Mesh, 70 | Shader, 71 | Primitive, 72 | State, 73 | BasicMaterial, 74 | 75 | // Utils 76 | Utils, 77 | utils: Utils, 78 | ArrayUtils, 79 | Debug, 80 | debug: Debug, 81 | 82 | // Math 83 | Vector3, 84 | 85 | // Composer 86 | Composer, 87 | Pass, 88 | NoisePass, 89 | BoxBlurPass, 90 | InvertPass, 91 | FXAAPass, 92 | ToonPass, 93 | BrightnessContrastPass, 94 | DofPass, 95 | BloomPass, 96 | TiltPass, 97 | FullBoxBlurPass, 98 | BlendPass, 99 | FBOHelper, 100 | ObjParser, 101 | HitDetect, 102 | }; 103 | 104 | export default vanilla; 105 | -------------------------------------------------------------------------------- /src/gl/math/Ray.js: -------------------------------------------------------------------------------- 1 | // Ray.js 2 | 3 | import * as glm from 'gl-matrix'; 4 | 5 | const vec3 = glm.vec3; 6 | 7 | const a = vec3.create(); 8 | const b = vec3.create(); 9 | const c = vec3.create(); 10 | const target = vec3.create(); 11 | const edge1 = vec3.create(); 12 | const edge2 = vec3.create(); 13 | const normal = vec3.create(); 14 | const diff = vec3.create(); 15 | 16 | class Ray 17 | { 18 | constructor(mOrigin, mDirection) 19 | { 20 | this.origin = vec3.clone(mOrigin); 21 | this.direction = vec3.clone(mDirection); 22 | } 23 | 24 | at(t) 25 | { 26 | vec3.copy(target, this.direction); 27 | vec3.scale(target, target, t); 28 | vec3.add(target, target, this.origin); 29 | 30 | return target; 31 | } 32 | 33 | lookAt(mTarget) 34 | { 35 | vec3.sub(this.direction, mTarget, this.origin); 36 | vec3.normalize(this.origin, this.origin); 37 | } 38 | 39 | closestPointToPoint(mPoint) 40 | { 41 | const result = vec3.create(); 42 | 43 | vec3.sub(mPoint, this.origin); 44 | const directionDistance = vec3.dot(result, this.direction); 45 | 46 | if (directionDistance < 0) 47 | { 48 | return vec3.clone(this.origin); 49 | } 50 | 51 | vec3.copy(result, this.direction); 52 | vec3.scale(result, result, directionDistance); 53 | vec3.add(result, result, this.origin); 54 | 55 | return result; 56 | } 57 | 58 | distanceToPoint(mPoint) 59 | { 60 | return Math.sqrt(this.distanceSqToPoint(mPoint)); 61 | } 62 | 63 | distanceSqToPoint(mPoint) 64 | { 65 | const v1 = vec3.create(); 66 | 67 | vec3.sub(v1, mPoint, this.origin); 68 | const directionDistance = vec3.dot(v1, this.direction); 69 | 70 | if (directionDistance < 0) 71 | { 72 | return vec3.squaredDistance(this.origin, mPoint); 73 | } 74 | 75 | vec3.copy(v1, this.direction); 76 | vec3.scale(v1, v1, directionDistance); 77 | vec3.add(v1, v1, this.origin); 78 | 79 | return vec3.squaredDistance(v1, mPoint); 80 | } 81 | 82 | intersectsSphere(mCenter, mRadius) 83 | { 84 | return this.distanceToPoint(mCenter) <= mRadius; 85 | } 86 | 87 | intersectSphere(mCenter, mRadius) 88 | { 89 | const v1 = vec3.create(); 90 | 91 | vec3.sub(v1, mCenter, this.origin); 92 | const tca = vec3.dot(v1, this.direction); 93 | const d2 = vec3.dot(v1, v1) - tca * tca; 94 | const radius2 = mRadius * mRadius; 95 | 96 | if (d2 > radius2) return null; 97 | 98 | const thc = Math.sqrt(radius2 - d2); 99 | 100 | const t0 = tca - thc; 101 | 102 | const t1 = tca + thc; 103 | 104 | if (t0 < 0 && t1 < 0) return null; 105 | 106 | if (t0 < 0) return this.at(t1); 107 | 108 | return this.at(t0); 109 | } 110 | 111 | distanceToPlane(mPlaneCenter, mNormal) 112 | { 113 | const denominator = vec3.dot(mNormal, this.direction); 114 | 115 | if (denominator === 0) 116 | { 117 | // 118 | } 119 | } 120 | 121 | intersectTriangle(mPA, mPB, mPC, backfaceCulling = false) 122 | { 123 | vec3.copy(a, mPA); 124 | vec3.copy(b, mPB); 125 | vec3.copy(c, mPC); 126 | 127 | // const edge1 = vec3.create(); 128 | // const edge2 = vec3.create(); 129 | // const normal = vec3.create(); 130 | // const diff = vec3.create(); 131 | 132 | vec3.sub(edge1, b, a); 133 | vec3.sub(edge2, c, a); 134 | vec3.cross(normal, edge1, edge2); 135 | 136 | let DdN = vec3.dot(this.direction, normal); 137 | let sign; 138 | 139 | if (DdN > 0) 140 | { 141 | if (backfaceCulling) { return null; } 142 | sign = 1; 143 | } 144 | else if (DdN < 0) 145 | { 146 | sign = -1; 147 | DdN = -DdN; 148 | } 149 | else 150 | { 151 | return null; 152 | } 153 | 154 | vec3.sub(diff, this.origin, a); 155 | 156 | vec3.cross(edge2, diff, edge2); 157 | const DdQxE2 = sign * vec3.dot(this.direction, edge2); 158 | 159 | if (DdQxE2 < 0) { return null; } 160 | 161 | vec3.cross(edge1, edge1, diff); 162 | const DdE1xQ = sign * vec3.dot(this.direction, edge1); 163 | 164 | if (DdE1xQ < 0) { return null; } 165 | 166 | if (DdQxE2 + DdE1xQ > DdN) { return null; } 167 | 168 | const Qdn = -sign * vec3.dot(diff, normal); 169 | 170 | if (Qdn < 0) { return null; } 171 | 172 | return this.at(Qdn / DdN); 173 | } 174 | } 175 | 176 | export default Ray; 177 | -------------------------------------------------------------------------------- /src/gl/math/Vector3.js: -------------------------------------------------------------------------------- 1 | import * as glm from 'gl-matrix'; 2 | 3 | class Vector3 4 | { 5 | constructor(x = 0, y = 0, z = 0) 6 | { 7 | this._xyz = glm.vec3.fromValues(x, y, z); 8 | // this._x = 9 | } 10 | get() 11 | { 12 | return this._xyz; 13 | } 14 | set(x, y, z) 15 | { 16 | if (arguments.length > 1) 17 | { 18 | this._xyz[0] = x; 19 | this._xyz[1] = y; 20 | this._xyz[2] = z; 21 | } 22 | else 23 | { 24 | this._xyz[0] = x; 25 | this._xyz[1] = x; 26 | this._xyz[2] = x; 27 | } 28 | 29 | this.onChangeCallback(); 30 | 31 | return this; 32 | } 33 | get x() 34 | { 35 | return this._xyz[0]; 36 | } 37 | set x(value) 38 | { 39 | this._xyz[0] = value; 40 | this.onChangeCallback(); 41 | } 42 | get y() 43 | { 44 | return this._xyz[1]; 45 | } 46 | set y(value) 47 | { 48 | this._xyz[1] = value; 49 | this.onChangeCallback(); 50 | } 51 | get z() 52 | { 53 | return this._xyz[2]; 54 | } 55 | set z(value) 56 | { 57 | this._xyz[2] = value; 58 | this.onChangeCallback(); 59 | } 60 | toString() 61 | { 62 | return `x: ${this.x}, y: ${this.y}, z: ${this.z}`; 63 | } 64 | } 65 | 66 | Object.assign(Vector3.prototype, { 67 | onChange(fn) 68 | { 69 | this.onChangeCallback = fn; 70 | }, 71 | onChangeCallback() 72 | { 73 | // 74 | }, 75 | 76 | }); 77 | 78 | export default Vector3; 79 | -------------------------------------------------------------------------------- /src/gl/post/BlendPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class BlendPass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | 10 | uniforms.mode = config.mode || 1; 11 | uniforms.opacity = config.opacity || 1; 12 | uniforms.tInput2 = config.tInput2 || null; 13 | uniforms.sizeMode = config.sizeMode || 1; 14 | uniforms.aspectRatio = config.aspectRatio || 1; 15 | uniforms.aspectRatio2 = config.aspectRatio2 || 1; 16 | 17 | super(glslify('./shaders/blend.frag'), uniforms, 'BlendPass'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/gl/post/BloomPass.js: -------------------------------------------------------------------------------- 1 | import FrameBuffer from '../core/FrameBuffer'; 2 | import FullBoxBlurPass from './FullBoxBlurPass'; 3 | import BlendPass from './BlendPass'; 4 | 5 | const BlendMode = { 6 | Normal: 1, 7 | Dissolve: 2, 8 | Darken: 3, 9 | Multiply: 4, 10 | ColorBurn: 5, 11 | LinearBurn: 6, 12 | DarkerColor: 7, 13 | Lighten: 8, 14 | Screen: 9, 15 | ColorDodge: 10, 16 | LinearDodge: 11, 17 | LighterColor: 12, 18 | Overlay: 13, 19 | SoftLight: 14, 20 | HardLight: 15, 21 | VividLight: 16, 22 | LinearLight: 17, 23 | PinLight: 18, 24 | HardMix: 19, 25 | Difference: 20, 26 | Exclusion: 21, 27 | Substract: 22, 28 | Divide: 23, 29 | }; 30 | 31 | export default class Pass 32 | { 33 | constructor(config = {}) 34 | { 35 | this.amount = config.amount || 2; 36 | } 37 | initialize(composer) 38 | { 39 | if (!this.fbo) 40 | { 41 | this.fbo = new FrameBuffer(gl, composer.width, composer.height); 42 | } 43 | this.composer = composer; 44 | 45 | this.fullBoxBlurPass = new FullBoxBlurPass({ 46 | uAmount: this.amount, 47 | }); 48 | this.fullBoxBlurPass.initialize(composer); 49 | 50 | this.blendPass = new BlendPass(); 51 | this.blendPass.initialize(composer); 52 | } 53 | process(inputTexture, cb) 54 | { 55 | let touput; 56 | 57 | this.fullBoxBlurPass.process(inputTexture, (ouput) => 58 | { 59 | touput = ouput; 60 | }); 61 | 62 | this.blendPass.shader.uniforms.mode = 9; 63 | this.blendPass.shader.uniforms.resolution = [this.composer.width, this.composer.height]; 64 | this.blendPass.shader.uniforms.resolution2 = [this.composer.width, this.composer.height]; 65 | this.blendPass.shader.uniforms.tInput2 = inputTexture; 66 | this.blendPass.process(touput, (ouput) => 67 | { 68 | cb(ouput); 69 | }); 70 | // this.shader.uniforms.uTexture = inputTexture; 71 | // this.composer.pass(this.fbo, this.shader); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/gl/post/BoxBlurPass.js: -------------------------------------------------------------------------------- 1 | import Shader from '../high/Shader'; 2 | import FrameBuffer from '../core/FrameBuffer'; 3 | 4 | const glslify = require('glslify'); 5 | 6 | export default class BoxBlur 7 | { 8 | constructor(config = {}) 9 | { 10 | const uniforms = {}; 11 | 12 | uniforms.uDelta = config.uDelta || [0, 0]; 13 | 14 | this.shader = new Shader(glslify('./shaders/boxBlur.vert'), glslify('./shaders/boxBlur.frag'), uniforms, 'BoxBlurPass'); 15 | this.enable = true; 16 | this.fbo = null; 17 | } 18 | process(composer, cb) 19 | { 20 | if (!this.fbo) 21 | { 22 | this.fbo = new FrameBuffer(gl, composer.width, composer.height); 23 | } 24 | this.fbo.bind(); 25 | this.shader.uniforms.uTexture = composer.outputTexture; 26 | this.shader.uniforms.uResolution = [composer.width, composer.height]; 27 | composer.bigTriangle.shader = this.shader; 28 | composer.renderer.render(composer.bigTriangle, composer.camera); 29 | this.fbo.unbind(); 30 | cb(this.fbo.colors); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/gl/post/BrightnessContrastPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class BrightnessContrastPass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | 10 | uniforms.uBrightness = config.uBrightness || 1; 11 | uniforms.uContrast = config.uContrast || 1; 12 | super(glslify('./shaders/brightness-contrast.frag'), uniforms, 'BrightnessContrastPass'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/gl/post/Composer.js: -------------------------------------------------------------------------------- 1 | import Mesh from '../high/Mesh'; 2 | import Geometry from '../high/Geometry'; 3 | import Shader from '../high/Shader'; 4 | import Primitive from '../high/Primitive'; 5 | import FrameBuffer from '../core/FrameBuffer'; 6 | import FBOHelper from '../utils/FBOHelper'; 7 | const glslify = require('glslify'); 8 | 9 | export default class Composer 10 | { 11 | constructor(renderer, width, height, debug = true) 12 | { 13 | this.renderer = renderer; 14 | this.passes = []; 15 | if (debug) 16 | { this.helper = new FBOHelper(renderer); } 17 | 18 | this.shader = new Shader(glslify('./shaders/default.vert'), glslify('./shaders/default.frag'), {}, 'Composer'); 19 | this.geo = new Geometry(Primitive.bigTriangle(1, 1)); 20 | this.bigTriangle = new Mesh(this.geo, this.shader); 21 | this.setSize(width, height); 22 | } 23 | add(pass) 24 | { 25 | this.passes.push(pass); 26 | pass.initialize(this); 27 | } 28 | render(scene, camera) 29 | { 30 | this.camera = camera; 31 | this.fboIn.bind(); 32 | this.fboIn.clear(); 33 | this.renderer.render(scene, camera); 34 | this.fboIn.unbind(); 35 | 36 | this.outputTexture = this.fboIn.colors; 37 | this.outputTextureDepth = this.fboIn.depth; 38 | let count = 0; 39 | 40 | this.passes.forEach((pass) => 41 | { 42 | if (pass.enable) 43 | { 44 | // TODO check if pass is complex or not for uploading default uniforms 45 | if (pass.shader) 46 | { 47 | if (pass.shader.uniforms) 48 | { 49 | pass.shader.uniforms.uResolution = [this.width, this.height]; 50 | } 51 | } 52 | pass.process(this.outputTexture, (ouput) => 53 | { 54 | this.outputTexture = ouput; 55 | count++; 56 | if (this.helper) 57 | { this.helper.renderImediate(ouput, count); } 58 | }); 59 | } 60 | }); 61 | this.toScreen(); 62 | } 63 | pass(fbo, shader) 64 | { 65 | fbo.bind(); 66 | this.bigTriangle.shader = shader; 67 | this.renderer.render(this.bigTriangle, this.camera); 68 | fbo.unbind(); 69 | } 70 | toScreen() 71 | { 72 | this.bigTriangle.shader = this.shader; 73 | this.shader.uniforms.uTexture = this.outputTexture; 74 | this.renderer.render(this.bigTriangle); 75 | } 76 | swap() 77 | { 78 | const tmp = this.fboIn; 79 | 80 | this.fboIn = this.fboOut; 81 | this.fboOut = tmp; 82 | } 83 | setSize(width, height) 84 | { 85 | this.fboIn = new FrameBuffer(gl, width, height, { depth: true }); 86 | this.fboOut = new FrameBuffer(gl, width, height, { depth: true }); 87 | this.width = width; 88 | this.height = height; 89 | this.outputTexture = this.fboIn.colors; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/gl/post/Composerori.js: -------------------------------------------------------------------------------- 1 | import Mesh from '../high/Mesh'; 2 | import Geometry from '../high/Geometry'; 3 | import Shader from '../high/Shader'; 4 | import Primitive from '../high/Primitive'; 5 | import FrameBuffer from '../core/FrameBuffer'; 6 | import FBOHelper from '../utils/FBOHelper'; 7 | const glslify = require('glslify'); 8 | 9 | export default class Composer 10 | { 11 | constructor(renderer, width, height) 12 | { 13 | this.renderer = renderer; 14 | this.passes = []; 15 | this.helper = new FBOHelper(renderer); 16 | 17 | this.shader = new Shader(glslify('./shaders/default.vert'), glslify('./shaders/default.frag')); 18 | this.geo = new Geometry(Primitive.bigTriangle(1, 1)); 19 | this.bigTriangle = new Mesh(this.geo, this.shader); 20 | this.setSize(width, height); 21 | } 22 | add(pass) 23 | { 24 | this.passes.push(pass); 25 | } 26 | render(scene, camera) 27 | { 28 | // render the scene in the fboIn 29 | this.fboIn.bind(); 30 | this.fboIn.clear(); 31 | this.renderer.render(scene, camera); 32 | this.fboIn.unbind(); 33 | // apply passes 34 | let count = 0; 35 | 36 | this.passes.forEach((pass) => 37 | { 38 | if (pass.enable) 39 | { 40 | this.fboOut.bind(); 41 | this.fboOut.clear(); 42 | pass.uniforms.uTexture = this.fboIn.colors; 43 | pass.uniforms.uDepth = this.fboIn.depth; 44 | pass.uniforms.uTime += 0.0025; 45 | this.bigTriangle.shader = pass; 46 | this.renderer.render(this.bigTriangle, camera); 47 | this.fboOut.unbind(); 48 | this.swap(); 49 | } 50 | count++; 51 | this.outputTexture = this.fboIn.colors; 52 | this.helper.renderImediate(this.outputTexture, count); 53 | }); 54 | } 55 | toScreen() 56 | { 57 | this.bigTriangle.shader = this.shader; 58 | this.shader.uniforms.uTexture = this.outputTexture; 59 | this.renderer.render(this.bigTriangle); 60 | } 61 | swap() 62 | { 63 | const tmp = this.fboIn; 64 | 65 | this.fboIn = this.fboOut; 66 | this.fboOut = tmp; 67 | } 68 | setSize(width, height) 69 | { 70 | this.fboIn = new FrameBuffer(gl, width, height, { depth: true }); 71 | this.fboOut = new FrameBuffer(gl, width, height, { depth: true }); 72 | this.outputTexture = this.fboIn.colors; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/gl/post/DofPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | import FrameBuffer from '../core/FrameBuffer'; 5 | 6 | export default class DofPass extends Pass 7 | { 8 | constructor(config = {}) 9 | { 10 | const uniforms = {}; 11 | 12 | uniforms.uFocalDistance = config.uFocalDistance || 0.01; 13 | uniforms.uAperture = config.uAperture || 0.005; 14 | super(glslify('./shaders/dof.frag'), uniforms, 'DofPass'); 15 | } 16 | process(composer, cb) 17 | { 18 | if (!this.fboX) 19 | { 20 | this.fboX = new FrameBuffer(gl, composer.width, composer.height); 21 | this.fboY = new FrameBuffer(gl, composer.width, composer.height); 22 | } 23 | this.fboX.bind(); 24 | this.shader.uniforms.uTexture = composer.outputTexture; 25 | this.shader.uniforms.uDelta = [1, 0]; 26 | composer.bigTriangle.shader = this.shader; 27 | composer.renderer.render(composer.bigTriangle, composer.camera); 28 | this.fboX.unbind(); 29 | 30 | this.fboY.bind(); 31 | this.shader.uniforms.uTexture = this.fboX.colors; 32 | this.shader.uniforms.uDelta = [0, 1]; 33 | composer.bigTriangle.shader = this.shader; 34 | composer.renderer.render(composer.bigTriangle, composer.camera); 35 | this.fboY.unbind(); 36 | 37 | cb(this.fboY.colors); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/gl/post/FXAAPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class FXAAPass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | // TODO bug here 10 | 11 | uniforms.uResolution = config.uResolution || [1, 1]; 12 | super(glslify('./shaders/fxaa.frag'), uniforms, 'FXAAPass'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/gl/post/FullBoxBlurPass.js: -------------------------------------------------------------------------------- 1 | import Shader from '../high/Shader'; 2 | import FrameBuffer from '../core/FrameBuffer'; 3 | const glslify = require('glslify'); 4 | 5 | export default class Pass 6 | { 7 | constructor(config = {}) 8 | { 9 | const uniforms = {}; 10 | 11 | this.uAmount = config.uAmount || 2; 12 | 13 | this.shader = new Shader(glslify('./shaders/boxBlur.vert'), glslify('./shaders/boxBlur.frag'), uniforms, 'FullBoxBlurPass'); 14 | this.enable = true; 15 | this.fbo = null; 16 | } 17 | initialize(composer) 18 | { 19 | if (!this.fboX) 20 | { 21 | this.fboX = new FrameBuffer(gl, composer.width, composer.height); 22 | this.fboY = new FrameBuffer(gl, composer.width, composer.height); 23 | } 24 | this.composer = composer; 25 | } 26 | process(inputTexture, cb) 27 | { 28 | this.shader.uniforms.uTexture = inputTexture; 29 | this.shader.uniforms.uResolution = [this.composer.width, this.composer.height]; 30 | this.shader.uniforms.uDelta = [this.uAmount, 0]; 31 | this.composer.pass(this.fboX, this.shader); 32 | 33 | this.shader.uniforms.uTexture = this.fboX.colors; 34 | this.shader.uniforms.uResolution = [this.composer.width, this.composer.height]; 35 | this.shader.uniforms.uDelta = [0, this.uAmount]; 36 | this.composer.pass(this.fboY, this.shader); 37 | 38 | cb(this.fboY.colors); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/gl/post/InvertPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class NoisePass extends Pass 5 | { 6 | constructor() 7 | { 8 | super(glslify('./shaders/invert.frag'), {}, 'InvertPass'); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/gl/post/NoisePass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class NoisePass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | 10 | uniforms.uAmount = config.uAmount || 0.3; 11 | uniforms.uSpeed = config.uSpeed || 0; 12 | super(glslify('./shaders/noise.frag'), uniforms, 'NoisePass'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/gl/post/Pass.js: -------------------------------------------------------------------------------- 1 | import Shader from '../high/Shader'; 2 | import FrameBuffer from '../core/FrameBuffer'; 3 | 4 | const glslify = require('glslify'); 5 | 6 | export default class Pass 7 | { 8 | constructor(fs, uniforms = {}, name = 'Postpro pass') 9 | { 10 | this.shader = new Shader(glslify('./shaders/default.vert'), fs, uniforms, name); 11 | this.shader.uniforms.uTime = 0; 12 | this.enable = true; 13 | this.fbo = null; 14 | } 15 | initialize(composer) 16 | { 17 | if (!this.fbo) 18 | { 19 | this.fbo = new FrameBuffer(gl, composer.width, composer.height); 20 | } 21 | this.composer = composer; 22 | } 23 | process(inputTexture, cb) 24 | { 25 | this.shader.uniforms.uTexture = inputTexture; 26 | this.shader.uniforms.uTime += 0.0025; 27 | this.composer.pass(this.fbo, this.shader); 28 | cb(this.fbo.colors); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/gl/post/TiltPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class TiltPass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | 10 | uniforms.uBlurAmount = config.uBlurAmount || 1.0; 11 | uniforms.uCenter = config.uCenter || 1.1; 12 | uniforms.uStepSize = config.uStepSize || 0.0005; 13 | super(glslify('./shaders/tilt.frag'), uniforms, 'TiltPass'); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/gl/post/ToonPass.js: -------------------------------------------------------------------------------- 1 | import Pass from './Pass'; 2 | const glslify = require('glslify'); 3 | 4 | export default class ToonPass extends Pass 5 | { 6 | constructor(config = {}) 7 | { 8 | const uniforms = {}; 9 | 10 | uniforms.uAmount = config.uResolution || [1, 1]; 11 | super(glslify('./shaders/toon.frag'), uniforms, 'ToonPass'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/gl/post/shaders/boxBlur.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uTexture; 4 | varying vec2 blurTexCoords[9]; 5 | 6 | void main() { 7 | 8 | vec4 sum = vec4( 0. ); 9 | 10 | sum += texture2D( uTexture, blurTexCoords[0] ) * 0.051; 11 | sum += texture2D( uTexture, blurTexCoords[1] ) * 0.0918; 12 | sum += texture2D( uTexture, blurTexCoords[2] ) * 0.12245; 13 | sum += texture2D( uTexture, blurTexCoords[3] ) * 0.1531; 14 | sum += texture2D( uTexture, blurTexCoords[4] ) * 0.1633; 15 | sum += texture2D( uTexture, blurTexCoords[5] ) * 0.1531; 16 | sum += texture2D( uTexture, blurTexCoords[6] ) * 0.12245; 17 | sum += texture2D( uTexture, blurTexCoords[7] ) * 0.0918; 18 | sum += texture2D( uTexture, blurTexCoords[8] ) * 0.051; 19 | 20 | gl_FragColor = sum; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/gl/post/shaders/boxBlur.vert: -------------------------------------------------------------------------------- 1 | attribute vec2 aPosition; 2 | attribute vec2 aUv; 3 | 4 | 5 | varying vec2 vUv; 6 | varying vec2 blurTexCoords[9]; 7 | 8 | uniform vec2 uResolution; 9 | uniform vec2 uDelta; 10 | 11 | 12 | void main() { 13 | 14 | vec2 inc = uDelta / uResolution; 15 | 16 | 17 | 18 | vec4 p = vec4(aPosition,0.0, 1.0); 19 | gl_Position = p; 20 | vUv = aPosition * .5 + .5; 21 | 22 | blurTexCoords[ 0 ] = vUv - inc * 4.; 23 | blurTexCoords[ 1 ] = vUv - inc * 3.; 24 | blurTexCoords[ 2 ] = vUv - inc * 2.; 25 | blurTexCoords[ 3 ] = vUv - inc * 1.; 26 | blurTexCoords[ 4 ] = vUv; 27 | blurTexCoords[ 5 ] = vUv + inc * 1.; 28 | blurTexCoords[ 6 ] = vUv + inc * 2.; 29 | blurTexCoords[ 7 ] = vUv + inc * 3.; 30 | blurTexCoords[ 8 ] = vUv + inc * 4.; 31 | } 32 | -------------------------------------------------------------------------------- /src/gl/post/shaders/brightness-contrast.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform float uBrightness; 4 | uniform float uContrast; 5 | uniform sampler2D uTexture; 6 | 7 | varying vec2 vUv; 8 | 9 | void main() { 10 | 11 | vec3 color = texture2D(uTexture, vUv).rgb; 12 | vec3 colorContrasted = (color) * uContrast; 13 | vec3 bright = colorContrasted + vec3(uBrightness,uBrightness,uBrightness); 14 | gl_FragColor.rgb = bright; 15 | gl_FragColor.a = 1.; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/gl/post/shaders/default.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uTexture; 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | vec4 base = texture2D(uTexture,vUv); 8 | gl_FragColor = vec4(base.rgb, 1.0); 9 | } 10 | -------------------------------------------------------------------------------- /src/gl/post/shaders/default.vert: -------------------------------------------------------------------------------- 1 | attribute vec2 aPosition; 2 | attribute vec2 aUv; 3 | 4 | varying vec3 vNormal; 5 | varying vec2 vUv; 6 | 7 | void main() { 8 | vec4 p = vec4(aPosition,0.0, 1.0); 9 | gl_Position = p; 10 | vUv = aPosition * .5 + .5; 11 | } 12 | -------------------------------------------------------------------------------- /src/gl/post/shaders/dof.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec2 vUv; 4 | uniform sampler2D uTexture; 5 | uniform sampler2D uDepth; 6 | uniform float uFocalDistance; 7 | uniform float uAperture; 8 | uniform vec2 uDelta; 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 d = abs( texture2D( uDepth, uv ).r - uFocalDistance ); 18 | return min( d * uAperture, .005 ); 19 | //return unpack_depth( texture2D( uDepth, uv ) ); 20 | } 21 | 22 | void main() { 23 | 24 | vec4 sum = vec4( 0. ); 25 | float bias = sampleBias( vUv ); 26 | 27 | sum += texture2D( uTexture, ( vUv - bias * uDelta * 4. ) ) * 0.051; 28 | sum += texture2D( uTexture, ( vUv - bias * uDelta * 3. ) ) * 0.0918; 29 | sum += texture2D( uTexture, ( vUv - bias * uDelta * 2. ) ) * 0.12245; 30 | sum += texture2D( uTexture, ( vUv - bias * uDelta * 1. ) ) * 0.1531; 31 | sum += texture2D( uTexture, ( vUv + bias * uDelta * 0. ) ) * 0.1633; 32 | sum += texture2D( uTexture, ( vUv + bias * uDelta * 1. ) ) * 0.1531; 33 | sum += texture2D( uTexture, ( vUv + bias * uDelta * 2. ) ) * 0.12245; 34 | sum += texture2D( uTexture, ( vUv + bias * uDelta * 3. ) ) * 0.0918; 35 | sum += texture2D( uTexture, ( vUv + bias * uDelta * 4. ) ) * 0.051; 36 | 37 | gl_FragColor = sum; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/gl/post/shaders/fxaa.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uTexture; 4 | uniform vec2 uResolution; 5 | varying vec2 vUv; 6 | 7 | #define FXAA_REDUCE_MIN (1.0/128.0) 8 | #define FXAA_REDUCE_MUL (1.0/8.0) 9 | #define FXAA_SPAN_MAX 8.0 10 | 11 | void main() { 12 | 13 | vec2 res = 1. / uResolution; 14 | 15 | vec3 rgbNW = texture2D( uTexture, ( vUv.xy + vec2( -1.0, -1.0 ) * res ) ).xyz; 16 | vec3 rgbNE = texture2D( uTexture, ( vUv.xy + vec2( 1.0, -1.0 ) * res ) ).xyz; 17 | vec3 rgbSW = texture2D( uTexture, ( vUv.xy + vec2( -1.0, 1.0 ) * res ) ).xyz; 18 | vec3 rgbSE = texture2D( uTexture, ( vUv.xy + vec2( 1.0, 1.0 ) * res ) ).xyz; 19 | vec4 rgbaM = texture2D( uTexture, vUv.xy * res ); 20 | vec3 rgbM = rgbaM.xyz; 21 | vec3 luma = vec3( 0.299, 0.587, 0.114 ); 22 | 23 | float lumaNW = dot( rgbNW, luma ); 24 | float lumaNE = dot( rgbNE, luma ); 25 | float lumaSW = dot( rgbSW, luma ); 26 | float lumaSE = dot( rgbSE, luma ); 27 | float lumaM = dot( rgbM, luma ); 28 | float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) ); 29 | float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) ); 30 | 31 | vec2 dir; 32 | dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); 33 | dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); 34 | 35 | float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN ); 36 | 37 | float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce ); 38 | dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX), 39 | max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), 40 | dir * rcpDirMin)) * res; 41 | vec4 rgbA = (1.0/2.0) * ( 42 | texture2D(uTexture, vUv.xy + dir * (1.0/3.0 - 0.5)) + 43 | texture2D(uTexture, vUv.xy + dir * (2.0/3.0 - 0.5))); 44 | vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * ( 45 | texture2D(uTexture, vUv.xy + dir * (0.0/3.0 - 0.5)) + 46 | texture2D(uTexture, vUv.xy + dir * (3.0/3.0 - 0.5))); 47 | float lumaB = dot(rgbB, vec4(luma, 0.0)); 48 | 49 | if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) { 50 | gl_FragColor = rgbA; 51 | // gl_FragColor = vec4(1.0,0.0,0.0,1.0); 52 | } else { 53 | gl_FragColor = rgbB; 54 | // gl_FragColor = vec4(0.0,1.0,0.0,1.0); 55 | } 56 | 57 | // gl_FragColor = vec4( texture2D( uTexture,vUv ).xyz, 1. ); 58 | } 59 | -------------------------------------------------------------------------------- /src/gl/post/shaders/invert.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uTexture; 4 | varying vec2 vUv; 5 | 6 | void main() { 7 | vec4 base = texture2D(uTexture,vUv); 8 | gl_FragColor = vec4(base.rgb, 1.0); 9 | gl_FragColor.rgb = 1.0 - gl_FragColor.rgb; 10 | } 11 | -------------------------------------------------------------------------------- /src/gl/post/shaders/noise.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D uTexture; 4 | uniform float uAmount; 5 | uniform float uSpeed; 6 | uniform float uTime; 7 | varying vec2 vUv; 8 | 9 | float random(vec2 n, float offset ){ 10 | return .5 - fract(sin(dot(n.xy + vec2( offset, 0. ), vec2(12.9898, 78.233)))* 43758.5453); 11 | } 12 | 13 | void main() { 14 | 15 | vec4 color = texture2D(uTexture, vUv); 16 | color += vec4( vec3( uAmount * random( vUv, .00001 * uSpeed * uTime ) ), 1. ); 17 | 18 | gl_FragColor = color; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/gl/post/shaders/tilt.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | uniform sampler2D uTexture; 3 | varying vec2 vUv; 4 | 5 | 6 | uniform float uBlurAmount; 7 | uniform float uCenter; 8 | uniform float uStepSize; 9 | 10 | const float steps = 3.0; 11 | 12 | const float minOffs = (float(steps-1.0)) / -2.0; 13 | const float maxOffs = (float(steps-1.0)) / +2.0; 14 | 15 | void main() { 16 | 17 | float amount; 18 | vec4 blurred; 19 | 20 | //Work out how much to blur based on the mid point 21 | amount = pow((vUv.y * uCenter) * 2.0 - 1.0, 2.0) * uBlurAmount; 22 | 23 | //This is the accumulation of color from the surrounding pixels in the texture 24 | blurred = vec4(0.0, 0.0, 0.0, 1.0); 25 | 26 | //From minimum offset to maximum offset 27 | for (float offsX = minOffs; offsX <= maxOffs; ++offsX) { 28 | for (float offsY = minOffs; offsY <= maxOffs; ++offsY) { 29 | 30 | //copy the coord so we can mess with it 31 | vec2 temp_vUv = vUv.xy; 32 | 33 | //work out which uv we want to sample now 34 | temp_vUv.x += offsX * amount * uStepSize; 35 | temp_vUv.y += offsY * amount * uStepSize; 36 | 37 | //accumulate the sample 38 | blurred += texture2D(uTexture, temp_vUv); 39 | 40 | } //for y 41 | } //for x 42 | 43 | blurred /= float(steps * steps); 44 | gl_FragColor = blurred; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/gl/post/shaders/toon.frag: -------------------------------------------------------------------------------- 1 | // Based on http://coding-experiments.blogspot.sg/2011/01/toon-pixel-shader.html 2 | precision highp float; 3 | 4 | uniform vec3 uResolution; 5 | uniform sampler2D uTexture; 6 | varying vec2 vUv; 7 | 8 | #define HueLevCount 6 9 | #define SatLevCount 7 10 | #define ValLevCount 4 11 | float HueLevels[HueLevCount]; 12 | float SatLevels[SatLevCount]; 13 | float ValLevels[ValLevCount]; 14 | 15 | vec3 RGBtoHSV( float r, float g, float b) { 16 | float minv, maxv, delta; 17 | vec3 res; 18 | 19 | minv = min(min(r, g), b); 20 | maxv = max(max(r, g), b); 21 | res.z = maxv; // v 22 | 23 | delta = maxv - minv; 24 | 25 | if( maxv != 0.0 ) 26 | res.y = delta / maxv; // s 27 | else { 28 | // r = g = b = 0 // s = 0, v is undefined 29 | res.y = 0.0; 30 | res.x = -1.0; 31 | return res; 32 | } 33 | 34 | if( r == maxv ) 35 | res.x = ( g - b ) / delta; // between yellow & magenta 36 | else if( g == maxv ) 37 | res.x = 2.0 + ( b - r ) / delta; // between cyan & yellow 38 | else 39 | res.x = 4.0 + ( r - g ) / delta; // between magenta & cyan 40 | 41 | res.x = res.x * 60.0; // degrees 42 | if( res.x < 0.0 ) 43 | res.x = res.x + 360.0; 44 | 45 | return res; 46 | } 47 | 48 | vec3 HSVtoRGB(float h, float s, float v ) { 49 | int i; 50 | float f, p, q, t; 51 | vec3 res; 52 | 53 | if( s == 0.0 ) { 54 | // achromatic (grey) 55 | res.x = v; 56 | res.y = v; 57 | res.z = v; 58 | return res; 59 | } 60 | 61 | h /= 60.0; // sector 0 to 5 62 | i = int(floor( h )); 63 | f = h - float(i); // factorial part of h 64 | p = v * ( 1.0 - s ); 65 | q = v * ( 1.0 - s * f ); 66 | t = v * ( 1.0 - s * ( 1.0 - f ) ); 67 | 68 | if (i==0) { 69 | res.x = v; 70 | res.y = t; 71 | res.z = p; 72 | } else if (i==1) { 73 | res.x = q; 74 | res.y = v; 75 | res.z = p; 76 | } else if (i==2) { 77 | res.x = p; 78 | res.y = v; 79 | res.z = t; 80 | } else if (i==3) { 81 | res.x = p; 82 | res.y = q; 83 | res.z = v; 84 | } else if (i==4) { 85 | res.x = t; 86 | res.y = p; 87 | res.z = v; 88 | } else if (i==5) { 89 | res.x = v; 90 | res.y = p; 91 | res.z = q; 92 | } 93 | 94 | return res; 95 | } 96 | 97 | float nearestLevel(float col, int mode) { 98 | 99 | if (mode==0) { 100 | for (int i =0; i= HueLevels[i] && col <= HueLevels[i+1]) { 102 | return HueLevels[i+1]; 103 | } 104 | } 105 | } 106 | 107 | if (mode==1) { 108 | for (int i =0; i= SatLevels[i] && col <= SatLevels[i+1]) { 110 | return SatLevels[i+1]; 111 | } 112 | } 113 | } 114 | 115 | 116 | if (mode==2) { 117 | for (int i =0; i= ValLevels[i] && col <= ValLevels[i+1]) { 119 | return ValLevels[i+1]; 120 | } 121 | } 122 | } 123 | 124 | 125 | } 126 | 127 | // averaged pixel intensity from 3 color channels 128 | float avg_intensity(vec4 pix) { 129 | return (pix.r + pix.g + pix.b)/3.; 130 | } 131 | 132 | vec4 get_pixel(vec2 coords, float dx, float dy) { 133 | return texture2D(uTexture,coords + vec2(dx, dy)); 134 | } 135 | 136 | // returns pixel color 137 | float IsEdge(in vec2 coords){ 138 | float dxtex = 1.0 / uResolution.x ; 139 | float dytex = 1.0 / uResolution.y ; 140 | 141 | float pix[9]; 142 | 143 | int k = -1; 144 | float delta; 145 | 146 | // read neighboring pixel intensities 147 | float pix0 = avg_intensity(get_pixel(coords,-1.0*dxtex, -1.0*dytex)); 148 | float pix1 = avg_intensity(get_pixel(coords,-1.0*dxtex, 0.0*dytex)); 149 | float pix2 = avg_intensity(get_pixel(coords,-1.0*dxtex, 1.0*dytex)); 150 | float pix3 = avg_intensity(get_pixel(coords,0.0*dxtex, -1.0*dytex)); 151 | float pix4 = avg_intensity(get_pixel(coords,0.0*dxtex, 0.0*dytex)); 152 | float pix5 = avg_intensity(get_pixel(coords,0.0*dxtex, 1.0*dytex)); 153 | float pix6 = avg_intensity(get_pixel(coords,1.0*dxtex, -1.0*dytex)); 154 | float pix7 = avg_intensity(get_pixel(coords,1.0*dxtex, 0.0*dytex)); 155 | float pix8 = avg_intensity(get_pixel(coords,1.0*dxtex, 1.0*dytex)); 156 | // average color differences around neighboring pixels 157 | delta = (abs(pix1-pix7)+ 158 | abs(pix5-pix3) + 159 | abs(pix0-pix8)+ 160 | abs(pix2-pix6) 161 | )/4.; 162 | 163 | return clamp(5.5*delta,0.0,1.0); 164 | } 165 | 166 | void main(void) 167 | { 168 | 169 | HueLevels[0] = 0.0; 170 | HueLevels[1] = 80.0; 171 | HueLevels[2] = 160.0; 172 | HueLevels[3] = 240.0; 173 | HueLevels[4] = 320.0; 174 | HueLevels[5] = 360.0; 175 | 176 | SatLevels[0] = 0.0; 177 | SatLevels[1] = 0.1; 178 | SatLevels[2] = 0.3; 179 | SatLevels[3] = 0.5; 180 | SatLevels[4] = 0.6; 181 | SatLevels[5] = 0.8; 182 | SatLevels[6] = 1.0; 183 | 184 | ValLevels[0] = 0.0; 185 | ValLevels[1] = 0.3; 186 | ValLevels[2] = 0.6; 187 | ValLevels[3] = 1.0; 188 | 189 | vec4 colorOrg = texture2D( uTexture, vUv ); 190 | vec3 vHSV = RGBtoHSV(colorOrg.r,colorOrg.g,colorOrg.b); 191 | vHSV.x = nearestLevel(vHSV.x, 0); 192 | vHSV.y = nearestLevel(vHSV.y, 1); 193 | vHSV.z = nearestLevel(vHSV.z, 2); 194 | float edg = IsEdge(vUv); 195 | vec3 vRGB = (edg >= 0.3)? vec3(0.0,0.0,0.0):HSVtoRGB(vHSV.x,vHSV.y,vHSV.z); 196 | gl_FragColor = vec4(vRGB.x,vRGB.y,vRGB.z,1.0); 197 | } 198 | -------------------------------------------------------------------------------- /src/gl/shaders/basic.frag: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying vec3 vNormal; 4 | varying vec2 vUv; 5 | 6 | 7 | #ifdef COLOR 8 | uniform vec3 uColor; 9 | #endif 10 | 11 | #ifdef TEXTURE 12 | uniform sampler2D uTexture; 13 | #endif 14 | 15 | #ifdef NORMAL_MAP 16 | varying vec3 vViewPosition; 17 | uniform sampler2D uNormalMap; 18 | uniform vec2 uNormalScale; 19 | uniform vec2 uNormalUVRepeat; 20 | 21 | 22 | #extension GL_OES_standard_derivatives : enable 23 | // function from three js 24 | // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html 25 | vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { 26 | 27 | // Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988 28 | 29 | vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) ); 30 | vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) ); 31 | vec2 st0 = dFdx( vUv.xy * uNormalUVRepeat); 32 | vec2 st1 = dFdy( vUv.xy * uNormalUVRepeat); 33 | 34 | vec3 S = normalize( q0 * st1.t - q1 * st0.t ); 35 | vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); 36 | vec3 N = normalize( surf_norm ); 37 | 38 | vec3 mapN = texture2D( uNormalMap, vUv * uNormalUVRepeat).xyz * 2.0 - 1.0; 39 | mapN.xy = uNormalScale * mapN.xy; 40 | mat3 tsn = mat3( S, T, N ); 41 | return normalize( tsn * mapN ); 42 | 43 | } 44 | 45 | 46 | #endif 47 | 48 | 49 | #ifdef FOG 50 | varying float fogFactor; 51 | uniform vec3 uFogColor; 52 | #endif 53 | 54 | float diffuse(vec3 N, vec3 L) { 55 | return max(dot(N, normalize(L)), 0.0); 56 | } 57 | 58 | 59 | vec3 diffuse(vec3 N, vec3 L, vec3 C) { 60 | return diffuse(N, L) * C; 61 | } 62 | 63 | 64 | #HOOK_FRAGMENT_START 65 | 66 | 67 | void main() { 68 | vec4 finalColor = vec4(1.0); 69 | vec3 normal = vNormal; 70 | 71 | #ifdef TEXTURE 72 | finalColor = texture2D(uTexture, vUv); 73 | #endif 74 | 75 | #ifdef COLOR 76 | finalColor.rgb *= uColor; 77 | #endif 78 | 79 | #ifdef NORMAL_MAP 80 | normal = perturbNormal2Arb(vViewPosition, vNormal); 81 | #endif 82 | 83 | vec3 light = diffuse(normal, vec3(0.0,1.0,0.0), vec3(0.1)); 84 | 85 | 86 | #HOOK_FRAGMENT_MAIN 87 | 88 | gl_FragColor = vec4(finalColor.rgb + light, finalColor.a); 89 | 90 | #HOOK_FRAGMENT_END 91 | 92 | 93 | #ifdef FOG 94 | gl_FragColor.rgb = mix(uFogColor, gl_FragColor.rgb, fogFactor); 95 | #endif 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/gl/shaders/basic.vert: -------------------------------------------------------------------------------- 1 | attribute vec3 aPosition; 2 | attribute vec3 aNormal; 3 | attribute vec2 aUv; 4 | 5 | uniform mat4 projectionMatrix; 6 | uniform mat4 viewMatrix; 7 | uniform mat4 worldMatrix; 8 | uniform mat3 normalMatrix; 9 | 10 | varying vec3 vNormal; 11 | varying vec2 vUv; 12 | 13 | // #ifdef NORMAL_MAP 14 | varying vec3 vViewPosition; 15 | // #endif 16 | 17 | #ifdef FOG 18 | uniform float uDensity; 19 | uniform float uGradient; 20 | varying float fogFactor; 21 | #endif 22 | 23 | #HOOK_VERTEX_START 24 | 25 | void main() { 26 | vec4 p = vec4(aPosition, 1.0); 27 | vUv = aUv; 28 | vNormal = normalize(normalMatrix * aNormal); 29 | 30 | 31 | vec4 worldPos = projectionMatrix * viewMatrix * worldMatrix * p; 32 | vViewPosition = worldPos.xyz; 33 | 34 | #HOOK_VERTEX_MAIN 35 | 36 | 37 | gl_Position = worldPos; 38 | 39 | #ifdef FOG 40 | float dist = length(vViewPosition.xyz); 41 | fogFactor = exp(-pow(dist * uDensity, uGradient)); 42 | fogFactor = clamp(fogFactor, 0.0, 1.0); 43 | #endif 44 | 45 | #HOOK_VERTEX_END 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/gl/utils/ArrayUtils.js: -------------------------------------------------------------------------------- 1 | import * as glm from 'gl-matrix'; 2 | 3 | const mat4 = glm.mat4; 4 | const vec3 = glm.vec3; 5 | const vec2 = glm.vec2; 6 | 7 | function flatten(arr) 8 | { 9 | return arr.reduce(function (flat, toFlatten) 10 | { 11 | return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten); 12 | }, []); 13 | } 14 | 15 | function generateFaces(vertices, indices) 16 | { 17 | const _vertices = []; 18 | let index = 0; 19 | 20 | for (let i = 0; i < vertices.length; i += 3) 21 | { 22 | _vertices.push([vertices[i], vertices[i + 1], vertices[i + 2]]); 23 | } 24 | let ia, 25 | ib, 26 | ic; 27 | let a, 28 | b, 29 | c; 30 | const vba = vec3.create(), 31 | vca = vec3.create(); 32 | const faces = []; 33 | 34 | for (let i = 0; i < indices.length; i += 3) 35 | { 36 | if (i % 2 == 0) index += 10; 37 | ia = indices[i]; 38 | ib = indices[i + 1]; 39 | ic = indices[i + 2]; 40 | 41 | a = _vertices[ia]; 42 | b = _vertices[ib]; 43 | c = _vertices[ic]; 44 | 45 | const face = { 46 | indices: [ia, ib, ic], 47 | index, 48 | vertices: [a, b, c], 49 | }; 50 | 51 | faces.push(face); 52 | } 53 | 54 | return faces; 55 | } 56 | 57 | function randomPointInGeometry(geometry, nbPoints) 58 | { 59 | 60 | } 61 | 62 | function generateTangents(vertices, uvs) 63 | { 64 | const tangents = []; 65 | const bitangents = []; 66 | const v0 = vec3.create(); 67 | const v1 = vec3.create(); 68 | const v2 = vec3.create(); 69 | 70 | const uv0 = vec3.create(); 71 | const uv1 = vec3.create(); 72 | const uv2 = vec3.create(); 73 | 74 | const deltaPos1 = vec3.create(); 75 | const deltaPos2 = vec3.create(); 76 | 77 | const deltaUV1 = vec2.create(); 78 | const deltaUV2 = vec2.create(); 79 | 80 | for (let i = 0; i < vertices.length; i += 3) 81 | { 82 | const _v0 = vertices[i]; 83 | const _v1 = vertices[i + 1]; 84 | const _v2 = vertices[i + 2]; 85 | 86 | vec3.set(v0, _v0[0], _v0[1], _v0[2]); 87 | vec3.set(v1, _v1[0], _v1[1], _v1[2]); 88 | vec3.set(v2, _v2[0], _v2[1], _v2[2]); 89 | 90 | const _uv0 = uvs[i]; 91 | const _uv1 = uvs[i + 1]; 92 | const _uv2 = uvs[i + 2]; 93 | 94 | vec2.set(uv0, _uv0[0], _uv0[1]); 95 | vec2.set(uv1, _uv1[0], _uv1[1]); 96 | vec2.set(uv2, _uv2[0], _uv2[1]); 97 | 98 | vec3.subtract(deltaPos1, v1, v0); 99 | vec3.subtract(deltaPos2, v2, v0); 100 | 101 | vec3.subtract(deltaUV1, uv0, uv1); 102 | vec3.subtract(deltaUV2, uv0, uv2); 103 | 104 | const delta = (deltaUV1[0] * deltaUV2[1] - deltaUV1[1] * deltaUV2[0]); 105 | // delta = delta === 0 ? 1: 0.0001; 106 | const r = 1.0 / delta; 107 | // console.log(r); 108 | 109 | const scalePos1x = scalar(deltaPos1, deltaUV2[0]); 110 | const scalePos1y = scalar(deltaPos1, deltaUV2[1]); 111 | 112 | const scalePos2x = scalar(deltaPos2, deltaUV1[0]); 113 | const scalePos2y = scalar(deltaPos2, deltaUV1[1]); 114 | 115 | // console.log(scalePos1x,scalePos1y); 116 | const tangent = scalar(sub(scalePos1y, scalePos2y), r); 117 | const bitangent = scalar(sub(scalePos2x, scalePos1x), r); 118 | 119 | tangents.push(tangent); 120 | tangents.push(tangent); 121 | tangents.push(tangent); 122 | bitangents.push(bitangent); 123 | bitangents.push(bitangent); 124 | bitangents.push(bitangent); 125 | 126 | return { 127 | tangents, 128 | bitangents, 129 | }; 130 | 131 | // vec2.sub(deltaPos1, uv1, uv0) 132 | // console.log(deltaPos1); 133 | } 134 | 135 | return { 136 | tangents, 137 | bitangents, 138 | }; 139 | console.log('tangent'); 140 | } 141 | 142 | function scalar(vec, scalar) 143 | { 144 | const _vec = []; 145 | 146 | for (let i = 0; i < vec.length; i++) 147 | { 148 | _vec[i] = vec[i] * scalar; 149 | } 150 | 151 | return _vec; 152 | } 153 | 154 | function sub(b, a) 155 | { 156 | const _vec = []; 157 | 158 | for (let i = 0; i < a.length; i++) 159 | { 160 | _vec[i] = a[i] - b[i]; 161 | } 162 | 163 | return _vec; 164 | } 165 | 166 | export default { 167 | flatten, 168 | generateFaces, 169 | 170 | generateTangents, 171 | randomPointInGeometry, 172 | }; 173 | -------------------------------------------------------------------------------- /src/gl/utils/Debug.js: -------------------------------------------------------------------------------- 1 | const cache = {}; 2 | 3 | class Debug 4 | { 5 | constructor() 6 | { 7 | this.verbose = false; 8 | } 9 | group(message) 10 | { 11 | if (!this.verbose) return; 12 | console.group(`%c ${message} `, 'color: #262626'); 13 | } 14 | groupEnd() 15 | { 16 | if (!this.verbose) return; 17 | console.groupEnd(); 18 | } 19 | print(message) 20 | { 21 | console.log(`%c ${message} `, 'background: #222; color: #ffffff'); 22 | } 23 | info(message) 24 | { 25 | if (!this.verbose) return; 26 | console.log(`%c ${message} `, 'color: #106bba'); 27 | } 28 | log(message) 29 | { 30 | if (!this.verbose) return; 31 | console.log(`%c ${message} `, 'color: #1ca51c'); 32 | } 33 | error(message, obj = '') 34 | { 35 | // if (!this.verbose) return; 36 | console.log(`%c ${message} `, 'background: #f65959; color: #ffffff', obj); 37 | } 38 | errorOnce(message, obj = '') 39 | { 40 | // if (!this.verbose) return; 41 | const id = message.replace(/ /g, ''); 42 | 43 | if (!cache[id]) 44 | { 45 | cache[id] = true; 46 | console.log(`%c ${message} `, 'background: #f65959; color: #ffffff', obj); 47 | } 48 | } 49 | } 50 | const debug = new Debug(); 51 | 52 | export default debug; 53 | -------------------------------------------------------------------------------- /src/gl/utils/DeviceOrientationControl.js: -------------------------------------------------------------------------------- 1 | // DeviceOrientationControl.js 2 | 3 | import { mat4, quat, vec3 } from 'gl-matrix'; 4 | 5 | function rad(degree) 6 | { 7 | return degree * Math.PI / 180; 8 | } 9 | 10 | class DeviceOrientationControl 11 | { 12 | constructor(mViewMatrix) 13 | { 14 | this._mtxTarget = mViewMatrix; 15 | this._rotation = mat4.create(); 16 | 17 | this._hasSet = false; 18 | this._alpha = 0; 19 | this._beta = 0; 20 | this._gamma = 0; 21 | this.easing = 0.1; 22 | 23 | this._init(); 24 | this.connect(); 25 | } 26 | 27 | _init() 28 | { 29 | this.enabled = true; 30 | 31 | this.deviceOrientation = {}; 32 | this.screenOrientation = 0; 33 | 34 | this.alphaOffsetAngle = 0; 35 | 36 | this.onScreenOrientationChangeBind = (e) => this._onScreenOrientationChange(e); 37 | this.onDeviceOrientationChangeBind = (e) => this._onDeviceOrientationChange(e); 38 | } 39 | 40 | connect() 41 | { 42 | this.onScreenOrientationChangeBind(); 43 | 44 | window.addEventListener('orientationchange', this.onScreenOrientationChangeBind, false); 45 | window.addEventListener('deviceorientation', this.onDeviceOrientationChangeBind, false); 46 | 47 | this.enabled = true; 48 | } 49 | 50 | disconnect() 51 | { 52 | window.removeEventListener('orientationchange', this.onScreenOrientationChangeBind, false); 53 | window.removeEventListener('deviceorientation', this.onDeviceOrientationChangeBind, false); 54 | this.enabled = false; 55 | } 56 | 57 | update() 58 | { 59 | const alpha = this.deviceOrientation.alpha ? rad(this.deviceOrientation.alpha) + this.alphaOffsetAngle : 0; 60 | const beta = this.deviceOrientation.beta ? rad(this.deviceOrientation.beta) : 0; 61 | const gamma = this.deviceOrientation.gamma ? rad(this.deviceOrientation.gamma) : 0; 62 | const orient = this.screenOrientation ? rad(this.screenOrientation) : 0; 63 | 64 | if (!this._hasSet) 65 | { 66 | this._alpha = alpha; 67 | this._beta = beta; 68 | this._gamma = gamma; 69 | } 70 | else 71 | { 72 | this._alpha += (alpha - this._alpha) * this.easing; 73 | this._beta += (beta - this._beta) * this.easing; 74 | this._gamma += (gamma - this._gamma) * this.easing; 75 | } 76 | 77 | this.setObjectQuaternion(this._alpha, this._beta, this._gamma, orient); 78 | } 79 | 80 | setObjectQuaternion(alpha, beta, gamma, orient) 81 | { 82 | const q = quat.create(); 83 | const zee = vec3.create(); 84 | const q0 = quat.create(); 85 | const q1 = quat.create(); 86 | 87 | zee[2] = 1; 88 | 89 | // YXZ 90 | const euler = { 91 | x: beta, 92 | y: alpha, 93 | z: -gamma, 94 | }; 95 | 96 | const c1 = Math.cos(euler.x / 2); 97 | const c2 = Math.cos(euler.y / 2); 98 | const c3 = Math.cos(euler.z / 2); 99 | const s1 = Math.sin(euler.x / 2); 100 | const s2 = Math.sin(euler.y / 2); 101 | const s3 = Math.sin(euler.z / 2); 102 | 103 | const x = s1 * c2 * c3 + c1 * s2 * s3; 104 | const y = c1 * s2 * c3 - s1 * c2 * s3; 105 | const z = c1 * c2 * s3 - s1 * s2 * c3; 106 | const w = c1 * c2 * c3 + s1 * s2 * s3; 107 | 108 | quat.set(q, x, y, z, w); 109 | quat.set(q1, Math.sqrt(0.5), 0, 0, -Math.sqrt(0.5)); 110 | 111 | quat.setAxisAngle(q0, zee, -orient); 112 | 113 | quat.multiply(q, q, q1); 114 | quat.multiply(q, q, q0); 115 | 116 | quat.invert(q, q); 117 | mat4.fromQuat(this._mtxTarget, q); 118 | mat4.fromQuat(this._rotation, q); 119 | } 120 | 121 | // Event handlers 122 | 123 | _onScreenOrientationChange() 124 | { 125 | this.screenOrientation = window.orientation || 0; 126 | } 127 | 128 | _onDeviceOrientationChange() 129 | { 130 | this.deviceOrientation = event; 131 | 132 | this.update(); 133 | } 134 | 135 | get rotation() { return this._rotation; } 136 | } 137 | 138 | export default DeviceOrientationControl; 139 | -------------------------------------------------------------------------------- /src/gl/utils/FBOHelper.js: -------------------------------------------------------------------------------- 1 | import Mesh from '../high/Mesh'; 2 | import Geometry from '../high/Geometry'; 3 | import Shader from '../high/Shader'; 4 | import Primitive from '../high/Primitive'; 5 | import OrthographicCamera from '../camera/OrthographicCamera'; 6 | 7 | export default class FBOHelper 8 | { 9 | constructor(renderer, size = 256) 10 | { 11 | this.renderer = renderer; 12 | this.size = size; 13 | this.camera = new OrthographicCamera(-1, 1, -1, 1, 0.1, 100); 14 | this.textures = []; 15 | 16 | this.shader = new Shader(` 17 | attribute vec2 aPosition; 18 | attribute vec2 aUv; 19 | 20 | varying vec3 vNormal; 21 | varying vec2 vUv; 22 | 23 | void main() { 24 | vec4 p = vec4(aPosition,0.0, 1.0); 25 | gl_Position = p; 26 | vUv = aPosition * .5 + .5; 27 | } 28 | 29 | 30 | `, ` 31 | precision highp float; 32 | 33 | uniform sampler2D uTexture; 34 | varying vec2 vUv; 35 | 36 | void main() { 37 | vec4 base = texture2D(uTexture,vec2(vUv.x, 1.0-vUv.y)); 38 | gl_FragColor = vec4(base.rgb, 1.0); 39 | } 40 | `, {}, 'FBO helper'); 41 | this.geo = new Geometry(Primitive.bigTriangle(1, 1)); 42 | this.mesh = new Mesh(this.geo, this.shader); 43 | } 44 | attach(texture) 45 | { 46 | this.textures.push(texture); 47 | } 48 | render() 49 | { 50 | if (this.textures.length < 1) return; 51 | 52 | for (let i = 0; i < this.textures.length; i++) 53 | { 54 | this.shader.uniforms.uTexture = this.textures[i]; 55 | this.renderer.gl.viewport(0, i * this.size, this.size, this.size); 56 | this.renderer.render(this.mesh, this.camera); 57 | } 58 | 59 | this.renderer.gl.viewport(0, 0, this.renderer.canvas.width, this.renderer.canvas.height); 60 | } 61 | renderImediate(texture, index) 62 | { 63 | this.shader.uniforms.uTexture = texture; 64 | this.renderer.gl.viewport(index * this.size, 0, this.size, this.size); 65 | this.renderer.render(this.mesh, this.camera); 66 | this.renderer.gl.viewport(0, 0, this.renderer.canvas.width, this.renderer.canvas.height); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/gl/utils/HitDetect.js: -------------------------------------------------------------------------------- 1 | // TouchDetect.js 2 | 3 | import Ray from '../math/Ray'; 4 | import { EventEmitter } from 'events'; 5 | import * as glm from 'gl-matrix'; 6 | 7 | const mat4 = glm.mat4; 8 | const vec3 = glm.vec3; 9 | let v0 = vec3.create(), 10 | v1 = vec3.create(), 11 | v2 = vec3.create(); 12 | 13 | function getMouse(e) 14 | { 15 | let x, 16 | y; 17 | 18 | if (e.touches) 19 | { 20 | x = e.touches[0].pageX; 21 | y = e.touches[0].pageY; 22 | } 23 | else 24 | { 25 | x = e.clientX; 26 | y = e.clientY; 27 | } 28 | 29 | return { 30 | x, y, 31 | }; 32 | } 33 | const t = mat4.create(); 34 | const getVector = (target, v, modelMatrix) => 35 | { 36 | vec3.transformMat4(target, v, modelMatrix); 37 | }; 38 | 39 | /* 40 | * Raycasting for one type of object they all have the same geometry like cube / sphere 41 | */ 42 | class HitDetect extends EventEmitter 43 | { 44 | constructor(objects = [], camera) 45 | { 46 | super(); 47 | 48 | this.objects = objects.length ? objects : [objects]; 49 | this.camera = camera; 50 | 51 | this.ray = new Ray([0, 0, 0], [0, 0, 0]); 52 | this.hit = vec3.fromValues(0, 0, 0); 53 | 54 | this.b_onDown = this._onDown.bind(this); 55 | this.b_onUp = this._onUp.bind(this); 56 | this.b_onMove = this._onMove.bind(this); 57 | 58 | this._posDown = { 59 | x: -9999, 60 | y: -9999, 61 | }; 62 | 63 | this._posLast = { 64 | x: -9999, 65 | y: -9999, 66 | }; 67 | 68 | this.connect(); 69 | } 70 | 71 | connect() 72 | { 73 | // if(Device.instance.desktop) { 74 | window.addEventListener('mousedown', this.b_onDown); 75 | window.addEventListener('mouseup', this.b_onUp); 76 | window.addEventListener('mousemove', this.b_onMove); 77 | // } else { 78 | window.addEventListener('touchstart', this.b_onDown); 79 | window.addEventListener('touchend', this.b_onUp); 80 | window.addEventListener('touchmove', this.b_onMove); 81 | // } 82 | } 83 | disconnect() 84 | { 85 | // if(Device.instance.desktop) { 86 | window.removeEventListener('mousedown', this.b_onDown); 87 | window.removeEventListener('mouseup', this.b_onUp); 88 | window.removeEventListener('mousemove', this.b_onMove); 89 | // } else { 90 | window.removeEventListener('touchstart', this.b_onDown); 91 | window.removeEventListener('touchend', this.b_onUp); 92 | window.removeEventListener('touchmove', this.b_onMove); 93 | // } 94 | this._objectHit = null; 95 | this._posDown.x = -999; 96 | this._posDown.y = -999; 97 | 98 | this.objects = []; 99 | } 100 | 101 | _onUp(e) 102 | { 103 | 104 | // 105 | // let dx = this._posLast.x - this._posDown.x; 106 | // let dy = this._posLast.y - this._posDown.y; 107 | // const d = Math.sqrt(dx*dx + dy*dy); 108 | // this._checkHit(); 109 | } 110 | 111 | _onMove(e) 112 | { 113 | const mouse = getMouse(e); 114 | 115 | this._posDown.x = mouse.x; 116 | this._posDown.y = mouse.y; 117 | this._posLast.x = mouse.x; 118 | this._posLast.y = mouse.y; 119 | this._checkHit(); 120 | } 121 | 122 | _onDown(e) 123 | { 124 | const mouse = getMouse(e); 125 | 126 | this._posDown.x = mouse.x; 127 | this._posDown.y = mouse.y; 128 | this._posLast.x = mouse.x; 129 | this._posLast.y = mouse.y; 130 | this._checkHit(); 131 | } 132 | 133 | _checkHit() 134 | { 135 | let mx = 0, 136 | my = 0; 137 | 138 | const { x, y } = this._posLast; 139 | 140 | mx = (x / window.innerWidth) * 2.0 - 1.0; 141 | my = -(y / window.innerHeight) * 2.0 + 1.0; 142 | 143 | this.camera.generateRay([mx, my, 0], this.ray); 144 | 145 | let hit; 146 | 147 | for (let i = 0; i < this.objects.length; i++) 148 | { 149 | let object; 150 | 151 | object = this.objects[i]; 152 | object._needUpdate = true; 153 | if (!object.geometry.faces) 154 | { 155 | object.geometry.generateFaces(); 156 | } 157 | 158 | const faces = object.geometry.faces; 159 | 160 | for (let j = 0; j < faces.length; j++) 161 | { 162 | let vertices; 163 | 164 | vertices = faces[j].vertices; 165 | getVector(v0, vertices[0], object.matrixWorld); 166 | getVector(v1, vertices[1], object.matrixWorld); 167 | getVector(v2, vertices[2], object.matrixWorld); 168 | 169 | hit = this.ray.intersectTriangle(v0, v1, v2); 170 | if (hit) 171 | { 172 | this.hit[0] = hit[0]; 173 | this.hit[1] = hit[1]; 174 | this.hit[2] = hit[2]; 175 | break; 176 | } 177 | } 178 | } 179 | } 180 | } 181 | 182 | export default HitDetect; 183 | -------------------------------------------------------------------------------- /src/gl/utils/Loader.js: -------------------------------------------------------------------------------- 1 | import Texture from './core/Texture'; 2 | 3 | let index = 0; 4 | 5 | export default class TextureLoader 6 | { 7 | constructor(gl) 8 | { 9 | this.gl = gl; 10 | this.textures = {}; 11 | index = 0; 12 | } 13 | load(src, cb) 14 | { 15 | if (typeof src === 'object') 16 | { 17 | const imagesToLoad = src.length; 18 | let imagesLoaded = 0; 19 | 20 | for (let i = 0; i < src.length; i += 1) 21 | { 22 | const img = new Image(); 23 | 24 | img.addEventListener('load', () => 25 | { 26 | const tex = new Texture(this.gl); 27 | 28 | tex.upload(img); 29 | const name = this.getTextureName(src[i]); 30 | 31 | this.textures[name] = tex; 32 | imagesLoaded++; 33 | if (imagesLoaded === imagesToLoad && cb) 34 | { 35 | cb(this.textures); 36 | } 37 | }); 38 | img.src = src[i]; 39 | } 40 | } 41 | else 42 | { 43 | const img = new Image(); 44 | 45 | img.addEventListener('load', () => 46 | { 47 | const tex = new Texture(this.gl); 48 | 49 | tex.upload(img); 50 | const name = this.getTextureName(src); 51 | 52 | this.textures[name] = tex; 53 | if (cb) cb(tex); 54 | }); 55 | img.src = src; 56 | } 57 | } 58 | getTextureName(src) 59 | { 60 | const ary = src.split('/'); 61 | let str = ary[ary.length - 1]; 62 | const lastIndex = str.lastIndexOf('.'); 63 | 64 | str = str.substring(0, lastIndex); 65 | 66 | return str; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/gl/utils/OrbitalCameraControl.js: -------------------------------------------------------------------------------- 1 | import { vec3, mat4, quat } from 'gl-matrix'; 2 | 3 | const getCursorPos = function (e) 4 | { 5 | if (e.touches) 6 | { 7 | return { 8 | x: e.touches[0].pageX, 9 | y: e.touches[0].pageY, 10 | }; 11 | } 12 | 13 | return { 14 | x: e.clientX, 15 | y: e.clientY, 16 | }; 17 | }; 18 | 19 | const UP = vec3.fromValues(0, 1, 0); 20 | const ANGLE_LIMIT = (Math.PI / 2 - 0.01); 21 | 22 | class OrbitalCameraControl 23 | { 24 | constructor(camera, mRadius = 5, mListenerTarget = window) 25 | { 26 | this.camera = camera; 27 | this._mtxTarget = camera.view; 28 | this._radius = mRadius; 29 | this._targetRadius = mRadius; 30 | this._listenerTarget = mListenerTarget; 31 | this._isDown = false; 32 | this._rotation = mat4.create(); 33 | this.center = vec3.create(); 34 | 35 | this.easing = 0.1; 36 | this.senstivity = 1; 37 | this.senstivityRotation = 1; 38 | 39 | this._isLocked = false; 40 | this._isZoomLocked = false; 41 | this._rx = 0; 42 | this._trx = 0; 43 | this._prevx = 0; 44 | this._ry = 0; 45 | this._try = 0; 46 | this._prevy = 0; 47 | 48 | this._quat = quat.create(); 49 | this._vec = vec3.create(); 50 | this._mtx = mat4.create(); 51 | 52 | this._mouseDown = { 53 | x: 0, 54 | y: 0, 55 | }; 56 | 57 | this._mouse = { 58 | x: 0, 59 | y: 0, 60 | }; 61 | 62 | this._init(); 63 | } 64 | 65 | _init() 66 | { 67 | this._listenerTarget.addEventListener('mousedown', (e) => this._onDown(e)); 68 | this._listenerTarget.addEventListener('mouseup', () => this._onUp()); 69 | this._listenerTarget.addEventListener('mousemove', (e) => this._onMove(e)); 70 | 71 | this._listenerTarget.addEventListener('touchstart', (e) => this._onDown(e)); 72 | this._listenerTarget.addEventListener('touchend', () => this._onUp()); 73 | this._listenerTarget.addEventListener('touchmove', (e) => this._onMove(e)); 74 | 75 | this._listenerTarget.addEventListener('mousewheel', (e) => this._onWheel(e)); 76 | this._listenerTarget.addEventListener('DOMMouseScroll', (e) => this._onWheel(e)); 77 | } 78 | 79 | lock(mValue) 80 | { 81 | this._isLocked = mValue; 82 | } 83 | 84 | lockZoom(mValue) 85 | { 86 | this._isZoomLocked = mValue; 87 | } 88 | 89 | _onWheel(e) 90 | { 91 | if (this._isZoomLocked) 92 | { 93 | return; 94 | } 95 | const w = e.wheelDelta; 96 | const d = e.detail; 97 | let value = 0; 98 | 99 | if (d) 100 | { 101 | if (w) 102 | { 103 | value = w / d / 40 * d > 0 ? 1 : -1; // Opera 104 | } 105 | else 106 | { 107 | value = -d / 3; // Firefox; TODO: do not /3 for OS X 108 | } 109 | } 110 | else 111 | { 112 | value = w / 120; 113 | } 114 | 115 | this._targetRadius += (-value * 2 * this.senstivity); 116 | if (this._targetRadius < 0.01) 117 | { 118 | this._targetRadius = 0.01; 119 | } 120 | } 121 | 122 | _onDown(e) 123 | { 124 | if (this._isLocked) { return; } 125 | this._isDown = true; 126 | 127 | this._mouseDown = getCursorPos(e); 128 | this._mouse = getCursorPos(e); 129 | 130 | this._prevx = this._trx = this._rx; 131 | this._prevy = this._try = this._ry; 132 | } 133 | 134 | _onMove(e) 135 | { 136 | if (this._isLocked) { return; } 137 | if (!this._isDown) { return; } 138 | this._mouse = getCursorPos(e); 139 | } 140 | 141 | _onUp() 142 | { 143 | if (this._isLocked) { return; } 144 | this._isDown = false; 145 | } 146 | 147 | update() 148 | { 149 | const dx = this._mouse.x - this._mouseDown.x; 150 | const dy = this._mouse.y - this._mouseDown.y; 151 | 152 | const senstivity = 0.02 * this.senstivityRotation; 153 | 154 | this._try = this._prevy - dx * senstivity; 155 | this._trx = this._prevx - dy * senstivity; 156 | 157 | if (this._trx < -Math.PI / 2 + 0.01) 158 | { 159 | this._trx = -Math.PI / 2 + 0.01; 160 | } 161 | else if (this._trx > Math.PI / 2 - 0.01) 162 | { 163 | this._trx = Math.PI / 2 - 0.01; 164 | } 165 | 166 | this._rx += (this._trx - this._rx) * this.easing; 167 | this._ry += (this._try - this._ry) * this.easing; 168 | this._radius += (this._targetRadius - this._radius) * this.easing; 169 | 170 | quat.identity(this._quat); 171 | quat.rotateY(this._quat, this._quat, this._ry); 172 | quat.rotateX(this._quat, this._quat, this._rx); 173 | 174 | vec3.set(this._vec, 0, 0, this._radius); 175 | vec3.transformQuat(this._vec, this._vec, this._quat); 176 | 177 | mat4.identity(this._mtx); 178 | // mat4.lookAt(this._mtx, this._vec, this.center, UP); 179 | 180 | if (this._mtxTarget) 181 | { 182 | mat4.copy(this._mtxTarget, this._mtx); 183 | } 184 | this.camera.lookAt(this._vec, this.center, UP); 185 | } 186 | } 187 | 188 | export default OrbitalCameraControl; 189 | -------------------------------------------------------------------------------- /src/gl/utils/PingPong.js: -------------------------------------------------------------------------------- 1 | import G from '../'; 2 | 3 | export default class Pingpong 4 | { 5 | constructor({ 6 | data, 7 | width, 8 | height, 9 | renderer, 10 | camera, 11 | fs, 12 | vs, 13 | uniforms, 14 | timeAdd = 0.1, 15 | }) 16 | { 17 | this.renderer = renderer; 18 | this.camera = camera; 19 | this.uniforms = uniforms; 20 | this.uniforms.uTime = 0; 21 | this.timeAdd = timeAdd; 22 | this.uniforms.uTexture = data; 23 | this.uniforms.uOrigin = data; 24 | this.quad = new G.Mesh( 25 | new G.Geometry(G.Primitive.quad(1, 1)), 26 | new G.Shader( 27 | vs, 28 | fs, 29 | this.uniforms, 30 | 'Simulation' 31 | )); 32 | 33 | this.fboIn = new G.FrameBuffer(gl, width, height); 34 | this.fboOut = new G.FrameBuffer(gl, width, height); 35 | this.fboOutO = this.fboOut; 36 | 37 | // this.fboDebug = new G.Mesh( 38 | // new G.Geometry(G.Primitive.quad(0.3, 0.3)), 39 | // new G.Shader( 40 | // glslify('./shaders/debug.vert'), 41 | // glslify('./shaders/texture.frag'), { 42 | // uTexture: this.fboOut.colors 43 | // } 44 | // )); 45 | // this.fboDebug.x = -0.7; 46 | // this.fboDebug.y = -0.7; 47 | 48 | this.fboIn.bind(); 49 | this.renderer.render(this.quad, this.camera); 50 | this.fboIn.unbind(); 51 | // 52 | this.fboOut.bind(); 53 | this.renderer.render(this.quad, this.camera); 54 | this.fboOut.unbind(); 55 | 56 | this.width = width; 57 | this.height = height; 58 | 59 | this.time = 0; 60 | } 61 | update() 62 | { 63 | this.time += this.timeAdd; 64 | this.quad.shader.uniforms.uTime = this.time; 65 | this.quad.shader.uniforms.width = this.width; 66 | this.quad.shader.uniforms.height = this.height; 67 | // this.renderer.render(this.fboDebug, this.camera) 68 | 69 | this.fboOut.bind(); 70 | this.quad.shader.uniforms.uTexture = this.fboIn.colors; 71 | this.quad.shader.uniforms.uTextureOld = this.fboOut.colors; 72 | this.renderer.render(this.quad, this.camera); 73 | this.fboOut.unbind(); 74 | 75 | const temp = this.fboIn; 76 | 77 | this.fboIn = this.fboOut; 78 | this.fboOut = temp; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/gl/utils/UIID.js: -------------------------------------------------------------------------------- 1 | function uuid() 2 | { 3 | function s4() 4 | { 5 | return Math.floor((1 + Math.random()) * 0x10000) 6 | .toString(16) 7 | .substring(1); 8 | } 9 | 10 | return `${s4() + s4()}-${s4()}-${s4()}-${ 11 | s4()}-${s4()}${s4()}${s4()}`; 12 | } 13 | export default uuid; 14 | -------------------------------------------------------------------------------- /src/gl/utils/Utils.js: -------------------------------------------------------------------------------- 1 | function hexToRgb(hex) 2 | { 3 | const result = (/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i).exec(hex); 4 | 5 | return result ? [ 6 | parseInt(result[1], 16) / 255, 7 | parseInt(result[2], 16) / 255, 8 | parseInt(result[3], 16) / 255, 9 | ] : null; 10 | } 11 | function numberToRgb(hex) 12 | { 13 | hex = parseInt(hex); 14 | var hex = Math.floor(hex); 15 | 16 | return hex ? [ 17 | (hex >> 16 & 255) / 255, 18 | (hex >> 8 & 255) / 255, 19 | (hex & 255) / 255, 20 | ] : null; 21 | } 22 | 23 | function random(min, max) 24 | { 25 | return Math.random() * (max - min) + min; 26 | } 27 | 28 | function clamp(value, min, max) 29 | { 30 | return Math.min(Math.max(value, min), max); 31 | } 32 | 33 | const range = (value, inMin, inMax, outMin, outMax) => 34 | ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin; 35 | 36 | export default { 37 | hexToRgb, 38 | numberToRgb, 39 | random, 40 | clamp, 41 | range, 42 | }; 43 | -------------------------------------------------------------------------------- /src/gl/utils/fallback.js: -------------------------------------------------------------------------------- 1 | module.exports = function fallback(message) 2 | { 3 | if (!message) message = 'Webgl 2 not supported by your browser'; 4 | const el = document.createElement('div'); 5 | 6 | el.classList = 'fallback'; 7 | el.style.position = 'absolute'; 8 | el.style.backgroundColor = 'black'; 9 | el.style.top = 0; 10 | el.style.left = 0; 11 | el.style.width = '100%'; 12 | el.style.height = '100%'; 13 | el.style.textAlign = 'center'; 14 | el.style.zIndex = '99'; 15 | 16 | const p = document.createElement('p'); 17 | 18 | p.style.position = 'absolute'; 19 | p.style.top = '50%'; 20 | p.style.left = '50%'; 21 | p.style.color = 'white'; 22 | p.style.transform = 'translate(-50%,-50%)'; 23 | p.style.color = 'white'; 24 | p.innerHTML = message; 25 | el.appendChild(p); 26 | document.body.appendChild(el); 27 | }; 28 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import raf from 'raf'; 2 | import assetsLoader from 'assets-loader'; 3 | import domready from 'domready'; 4 | import Query from 'dev/Query'; 5 | import SuperConfig from 'dev/SuperConfig'; 6 | import AllExperiments from './Experiments'; 7 | 8 | let manifest = []; 9 | 10 | if (Query.experiment && AllExperiments[Query.experiment]) 11 | { 12 | if (AllExperiments[Query.experiment].manifest && AllExperiments[Query.experiment].manifest.length > 0) 13 | { 14 | manifest = AllExperiments[Query.experiment].manifest; 15 | } 16 | } 17 | const loader = assetsLoader({ 18 | assets: manifest, 19 | }); 20 | 21 | window.getAsset = function getAsset(id) 22 | { 23 | return loader.get(`assets/${id}`); 24 | }; 25 | 26 | domready(() => 27 | { 28 | if (manifest.length > 0) 29 | { 30 | document.body.classList.add('loading'); 31 | loader.on('complete', function loaded(assets) 32 | { 33 | document.body.classList.remove('loading'); 34 | window.assets = assets; 35 | init(); 36 | if (Query.debug) 37 | { console.table(assets); } 38 | }) 39 | .start(); 40 | } 41 | else 42 | { 43 | init(); 44 | } 45 | }); 46 | 47 | let scene; 48 | 49 | function init() 50 | { 51 | const container = document.querySelector('#experiments-list'); 52 | 53 | if (Query.experiment) 54 | { 55 | scene = new AllExperiments[Query.experiment].scene(); 56 | container.style.display = 'none'; 57 | SuperConfig.init(AllExperiments[Query.experiment].config); 58 | document.title = AllExperiments[Query.experiment].config.name || 'Experiment'; 59 | } 60 | else 61 | { 62 | console.log('LISTINGS All experiments to not forget those'); 63 | container.style.display = 'block'; 64 | for (const id in AllExperiments) 65 | { 66 | const btn = document.createElement('button'); 67 | 68 | btn.innerHTML = id; 69 | btn.addEventListener('click', () => 70 | { 71 | const params = `?experiment="${id}"`; 72 | 73 | window.history.pushState('experiment', 'Title', 74 | `${window.location.origin + window.location.pathname + params}`); 75 | window.location.reload(); 76 | }); 77 | container.appendChild(btn); 78 | } 79 | } 80 | 81 | render(); 82 | window.addEventListener('resize', resize); 83 | } 84 | 85 | function resize() 86 | { 87 | if (scene) 88 | { scene.resize(); } 89 | } 90 | function render() 91 | { 92 | raf(render); 93 | if (scene) 94 | { scene.render(); } 95 | } 96 | --------------------------------------------------------------------------------