├── .gitignore
├── MouseControls.js
├── README.md
├── assets
└── walker
│ └── Walker.js
├── cells.html
├── colors.html
├── composer.js
├── glsl
├── bits
│ ├── draw
│ │ ├── ao.glsl
│ │ ├── environment.glsl
│ │ ├── fog.glsl
│ │ ├── normal.glsl
│ │ ├── raymarch.glsl
│ │ ├── rim.glsl
│ │ └── shadows.glsl
│ ├── geom
│ │ ├── box.glsl
│ │ ├── cylinder.glsl
│ │ ├── madelbulb.glsl
│ │ ├── mandelBox.glsl
│ │ ├── plane.glsl
│ │ ├── platonic_solids_ref.glsl
│ │ ├── sierpinski.glsl
│ │ ├── sphere.glsl
│ │ └── torus.glsl
│ └── util
│ │ ├── lookat.glsl
│ │ ├── noise.glsl
│ │ ├── operations.glsl
│ │ ├── perlin.glsl
│ │ ├── rotation.glsl
│ │ └── squareFrame.glsl
├── cells.glsl
├── colors.glsl
├── fragment.glsl
├── halibut.glsl
├── hulkbuster.glsl
├── interactive.glsl
├── noise_bulb.glsl
├── tmp.glsl
├── toy.glsl
└── walker.glsl
├── halibut.html
├── hulkbuster.html
├── img
├── colors.png
├── cover.jpg
├── cubemap
│ ├── cube03_0.png
│ ├── cube03_1.png
│ ├── cube03_2.png
│ ├── cube03_3.png
│ ├── cube03_4.png
│ └── cube03_5.png
├── env.png
├── halibut.jpg
├── hulkbuster.jpg
├── matcap.png
├── noise_bulb.jpg
└── walker.jpg
├── index.html
├── interactive.html
├── noise_bulb.html
├── raymarcher.js
├── tmp.html
├── vendor
├── controls
│ └── OrbitControls.js
├── postprocessing
│ ├── EffectComposer.js
│ ├── MaskPass.js
│ ├── RenderPass.js
│ └── ShaderPass.js
├── shaders
│ ├── CopyShader.js
│ └── FXAAShader.js
└── three.min.js
└── walker.html
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | /.idea
3 | /vendor/three.js
4 | /glsl/tmp.glsl
5 |
--------------------------------------------------------------------------------
/MouseControls.js:
--------------------------------------------------------------------------------
1 | var MouseControls = function(){
2 |
3 | function MouseControls( rayMarching ){
4 |
5 | this.rm = rayMarching;
6 | this.mouseDown = false;
7 |
8 | rayMarching.renderer.domElement.addEventListener( "mousedown", this.onDown.bind( this ), false );
9 | rayMarching.renderer.domElement.addEventListener( "mousemove", this.onMove.bind( this ), false );
10 | rayMarching.renderer.domElement.addEventListener( "mouseup", this.onUp.bind( this ), false );
11 | rayMarching.renderer.domElement.addEventListener( "mouseleave", this.onUp.bind( this ), false );
12 |
13 | }
14 |
15 | function onDown(e){
16 |
17 | var pos = this.getPosition(e);
18 | this.rm.mouse.x = pos[0];
19 | this.rm.mouse.y = pos[1];
20 | this.mouseDown = true;
21 | }
22 |
23 | function onMove(e){
24 |
25 | if( this.mouseDown ){
26 | var pos = this.getPosition(e);
27 | this.rm.mouse.x = pos[0];
28 | this.rm.mouse.y = pos[1];
29 | }
30 | }
31 |
32 | function onUp(e){
33 | this.mouseDown = false;
34 | }
35 |
36 | function getPosition(e){
37 |
38 | var pos = [0,0];
39 | if( e == null )return [window.innerWidth/2, window.innerHeight/2];
40 |
41 | if( 'ontouchstart' in window )
42 | {
43 | var touch = e.targetTouches[0];
44 | pos[0] = touch.clientX;
45 | pos[1] = touch.clientY;
46 | }else
47 | {
48 | if (!e) e = window.event;
49 | if (e.pageX || e.pageY){
50 | pos[0] = e.pageX;
51 | pos[1] = e.pageY;
52 | }
53 | else if (e.clientX || e.clientY){
54 | pos[0] = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
55 | pos[1] = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
56 | }
57 | }
58 | var r = e.target.getBoundingClientRect();
59 | pos[0] -= r.left;
60 | pos[1] -= r.top;
61 | return pos;
62 | }
63 |
64 | var _p = MouseControls.prototype;
65 |
66 | _p.constructor = MouseControls;
67 | _p.onDown = onDown;
68 | _p.onMove = onMove;
69 | _p.onUp = onUp;
70 | _p.getPosition = getPosition;
71 |
72 | return MouseControls;
73 |
74 | }();
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # raymarching-for-THREE
2 | 
3 |
4 | a "helper" to work with raymarching in THREE.js.
5 | * [basic demo](https://rawgit.com/nicoptere/raymarching-for-THREE/master/index.html)
6 | * [interactive demo](https://rawgit.com/nicoptere/raymarching-for-THREE/master/interactive.html) (mouse controls)
7 | * [color segmentation](https://rawgit.com/nicoptere/raymarching-for-THREE/master/colors.html)
8 | * [halibut](https://rawgit.com/nicoptere/raymarching-for-THREE/master/halibut.html)
9 | * [hulkbuster](https://rawgit.com/nicoptere/raymarching-for-THREE/master/hulkbuster.html)
10 | * [2D cells (not raymarched)](https://rawgit.com/nicoptere/raymarching-for-THREE/master/cells.html)
11 |
12 | it is heavily based on http://stack.gl/ core modules & scripts
13 |
14 | [THREE.js](http://threejs.org/) is a popular WebGL library, Raymarching Distance Fields is trendy nowadays, this is a way to bring them together. most of (all!) the work is done by the fragment shader, do not expect anything even remotely complex on the javascript side :)
15 | THREE makes it easy to upload various data to the shader (cameras, lights, textures for instance), another benefit is to be able to use THREE's post-processing ecosystem ; in the example above, I used a FXAA Pass to smooth the result.
16 | I've just left a small subset of the post processing & shaders folder for the sake of testing but there 's a lot more on THREE's repo.
17 |
18 | I've left the links to the resources I used in the [fragment file](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/fragment.glsl), most of the changes should be done in the "field()" method after the [HAMMER TIME!](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/fragment.glsl#L126)
19 |
20 | # sample script
21 |
22 |
23 |
24 |
49 |
50 | should give you something like this:
51 | 
52 | [noise bulb demo](https://rawgit.com/nicoptere/raymarching-for-THREE/master/noise_bulb.html)
53 |
54 | the loadFragmentShader method, takes the url of the fragment shader (can be plain text), loads it and call the callback method if it was specified
55 |
56 | loadFragmentShader( url, callback );
57 |
58 | passing the animate loop as a callback is a good idea but is not necessary.
59 |
60 | the 2 most important values for the raymarching are the maximum distance and the precision (the minimum step distance under which the raymarching loop bails out).
61 | by default, their values are 50 and 0.01 respectively. you can set them directly like:
62 |
63 | rm.distance = X
64 | rm.precision = Y
65 |
66 | //then call an update to update the uniforms
67 | rm.update();
68 |
69 | a 'good' value for raymarchMaximumDistance is twice the length of the camera's position ; it gives enough depth to render most of the things
70 |
71 | rm.distance = this.camera.position.length() * 2;
72 |
73 | the default raymarchPrecision is 0.01 which is fairly high (= coarse):
74 |
75 | if you need more accurate renders, increase the rm.distance and lower the rm.precision
76 |
77 | also, the raymarching 'steps' count has to be set directly in the shader like [here](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/fragment.glsl#L130)
78 | increasing it will give much more precise results at the cost of more intensive computations.
79 |
80 | for the sake of exhibiting the beauty of Raymarching, the above shape is produced by [this distance estimator](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/noise_bulb.glsl#L171-L186):
81 |
82 | vec2 field( vec3 position ){
83 |
84 | //create a 5 units radius sphere
85 | vec2 sph = sphere( position, 5. );
86 |
87 | //create a 10 units high, 4 units radius cylinder and positions it at Y = -12.5 units
88 | vec2 cyl = cylinder( position, 10.,4., vec3( 0.,-12.5,0.) );
89 |
90 | //stores a copy of the position being evaluated
91 | vec3 nPos = position * .45;
92 |
93 | //adds some delta
94 | nPos.y -= time * .05;
95 |
96 | //creates a transform (time-based rotation about the Y axis)
97 | vec4 quat = vec4( 0., 1., 0., -time * .1 );
98 |
99 | //evaluates a noise field using the transform above (the noise field "rotates")
100 | vec2 noi = vec2( max( -.5, .5-abs( perlin( nPos, quat ) ) ), 0. );
101 |
102 | //combines the shapes:
103 | // 1 - blend the sphere and the cylinder: smin( sph, cyl, .99 )
104 | // 2 - return the intersection of the blended shapes with the noise field
105 | return intersectionAB( smin( sph, cyl, .99 ), noi );
106 |
107 | }
108 |
109 | then some [colors are being computed](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/noise_bulb.glsl#L270-L286) with the result of this evaluation.
110 |
111 |
112 | # differents colors:
113 | 
114 | to assign different colors to the different parts of the shape you can do somethign like:
115 |
116 | //shape composition
117 | float blend = .5 + sin( time * .5 ) * .5;
118 | vec2 _out = unionAB( sce, smin( to0, smin( to1, subtract( sre, box ), blend ), blend ) );
119 |
120 | //color attribution
121 |
122 | //the Y value of the return value will be used to apply a different shading
123 | // _out.y = 1. is the default value, here, it will be attributed to blended areas
124 |
125 | //we can retrieve the elements by depth
126 | //we use the raymarch precision as a threshold
127 | float d = raymarchPrecision;
128 |
129 | //then an object is found like:
130 |
131 | if( _out.x > box.x - d )_out.y = 0.80;
132 | if( _out.x > to1.x - d )_out.y = 0.66;
133 | if( _out.x > to0.x - d )_out.y = 0.25;
134 | if( _out.x > sce.x - d )_out.y = 0.;
135 |
136 | return _out;
137 |
138 | an alternative to remove the conditional branching would be to write it as :
139 |
140 | _out.y = 1.;
141 | _out.y -= step( box.x - d, _out.x ) * .2
142 | + step( to0.x - d, _out.x ) * .35
143 | + step( to1.x - d, _out.x ) * .75
144 | + step( sce.x - d, _out.x ) * 1.0;
145 |
146 | this approach is supposed to be faster, the downside is that it is less legible.
147 |
148 | check out the [live demo for the color selection](https://rawgit.com/nicoptere/raymarching-for-THREE/master/colors.html)
149 | see [the source shader](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/colors.glsl#L161-L181) for the code.
150 |
151 | # using the effectComposer
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
193 | the composer contains whatever filters you can think of and is called after the RayMarcher' render
194 |
195 |
196 |
197 | # tips
198 |
199 | cheap depth (in the main() function) :
200 |
201 | float depth = ( 1./ log( collision.x ) );
202 |
203 | repeat a shape at a given interval (described by a vec3 r ):
204 |
205 | vec3 repeat( vec3 p, vec3 r ) { return mod( p, r ) - .5 * r; }
206 |
207 | //& in the field() function
208 | vec3 p = repeat( position, r );
209 |
210 | //p is a repeated position, use it to place evenly spaced objects
211 |
212 | spherical uvs: (Spherical Environment Mapping)
213 |
214 | texture2D( map, nor.xy / 2. + .5 );
215 |
216 | you can [lookat](https://github.com/nicoptere/raymarching-for-THREE/blob/master/glsl/bits/util/lookat.glsl) the camera to always face it
217 |
218 | #examples
219 | 
220 | [halibut demo](http://barradeau.com/dump/raymarching/halibut.html)
221 | 
222 | [hulkbuster demo](http://barradeau.com/dump/raymarching/hulkbuster.html)
223 | 
224 | [walker demo](http://barradeau.com/dump/raymarching/walker.html)
225 |
226 | #helpful links:
227 |
228 |
229 | WebGL [quick reference](http://www.shaderific.com/glsl/) for types, functions, statements etc.
230 |
231 | [Jaume Sanchez Elias](https://twitter.com/thespite)'s [Shader Editor chrome extension](https://chrome.google.com/webstore/detail/shader-editor/ggeaidddejpbakgafapihjbgdlbbbpob) mandatory tool to work with shaders
232 |
233 | [Íñgo Quílez](http://www.iquilezles.org/) [distance functions](http://iquilezles.org/www/articles/distfunctions/distfunctions.htm) and his live [example / refernce for basically everything](https://www.shadertoy.com/view/Xds3zN)
234 |
235 | [POUET's thread on primitives, noise, AO, SSS & more]( http://www.pouet.net/topic.php?which=7931&page=1)
236 |
237 | [Kevin Roast](https://twitter.com/kevinroast)'s [homepage](http://www.kevs3d.co.uk/dev/shaders/) is full of examples, rendering tricks, shapes and more
238 |
239 | very interesting series of articles about distance estimators & fractals:
240 | * [Distance Estimated 3D Fractals (Part I)](http://blog.hvidtfeldts.net/index.php/2011/06/distance-estimated-3d-fractals-part-i/)
241 | * [Distance Estimated 3D Fractals (II): Lighting and Coloring](http://blog.hvidtfeldts.net/index.php/2011/08/distance-estimated-3d-fractals-ii-lighting-and-coloring/)
242 | * [Distance Estimated 3D Fractals (III): Folding Space](http://blog.hvidtfeldts.net/index.php/2011/08/distance-estimated-3d-fractals-iii-folding-space/)
243 | * [Distance Estimated 3D Fractals (IV): The Holy Grail](http://blog.hvidtfeldts.net/index.php/2011/09/distance-estimated-3d-fractals-iv-the-holy-grail/)
244 | * [Distance Estimated 3D Fractals (V): The Mandelbulb & Different DE Approximations](http://blog.hvidtfeldts.net/index.php/2011/09/distance-estimated-3d-fractals-v-the-mandelbulb-different-de-approximations/)
245 | * [Distance Estimated 3D Fractals (VI): The Mandelbox](http://blog.hvidtfeldts.net/index.php/2011/11/distance-estimated-3d-fractals-vi-the-mandelbox/)
246 | * [Distance Estimated 3D Fractals (VII): Dual Numbers](http://blog.hvidtfeldts.net/index.php/2011/12/distance-estimated-3d-fractals-vii-dual-numbers/)
247 | * [Distance Estimated 3D Fractals (Part VIII): Epilogue](http://blog.hvidtfeldts.net/index.php/2012/05/distance-estimated-3d-fractals-part-viii-epilogue/)
248 |
249 | which incidentally reminded me of [subblue](https://twitter.com/subblue)'s [beautiful works](http://sub.blue/)
250 |
251 | a reminder of how [the blinn-phong shading](https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model) works
252 |
253 |
--------------------------------------------------------------------------------
/assets/walker/Walker.js:
--------------------------------------------------------------------------------
1 | var Walker = function()
2 | {
3 | var meanwalker = [-10.7519383725583, -3.72746649802272, -16.466685709658, -65.2177300475541, 44.661335747837, -16.466685709658, -65.2177300475541, 44.661335747837, 17.7610082741684, 15.8662806749498, 74.7273524036626, -52.4475178141205, 15.8662806749498, 74.7273524036626, -52.4475178141205, 0, 0, 183.820336741237, 220.478676488392, 251.013364295138, -183.820336741237, -220.478676488392, -251.013364295138, 0, 94.4979146895428, 72.7179566209974, 50.9485900809081, -94.4979146895428, -72.7179566209974, -50.9485900809081, 1640.61993723311, 1366.6742993586, 1402.32109635485, 1130.65231705128, 907.447654999956, 1402.32109635485, 1130.65231705128, 907.447654999956, 1015.0295481002, 909.516923870395, 524.108918400734, 162.337873145943, 909.516923870395, 524.108918400734, 162.337873145943, 126.030870377155, -6.93889390390723E-17, -7.63278329429795E-17, 6.01188539660724, 18.6532785884334, 35.168904918911, -6.01188539660724, -18.6532785884334, -35.168904918911, -9.71445146547012E-17, 0.85583935993545, -66.7599801603397, -0.00136779054226829, -0.855839359935451, 66.7599801603397, 0.00136779054226821, 16.7454749227664, 13.6539217228521, 14.4561843900628, 18.2079200377397, 12.2517881770354, 14.4561843900628, 18.2079200377397, 12.2517881770354, 11.0805683180636, 12.7013089491983, -11.6385045948174, -16.8400386203203, 12.7013089491983, -11.6385045948174, -16.8400386203203, -2.42861286636753E-17, -3.46944695195361E-17, -2.74690764163242, -4.12039184625044, 3.90729059644772, 2.74690764163242, 4.12039184625044, -3.90729059644772, -2.77555756156289E-17, 6.0560609647142, -1.14939409468544, -54.9132000272359, -6.0560609647142, 1.14939409468544, 54.9132000272359, 1, 0, 0, -10.5990547628726, -81.6328045581542, -188.021237194147, 10.5990547628726, 81.6328045581542, 188.021237194147, 0, 7.51975855144645, 147.708816974537, 322.46460362452, -7.51975855144645, -147.708816974537, -322.46460362452, 5.16274050080685, -0.398924078714644, 0.682139326943909, -22.724670410904, -2.67261175746871, 0.682139326943909, -22.724670410904, -2.67261175746871, -4.87628414766496, -0.384609053714416, -5.45192419278888, 3.10930244892261, -0.384609053714416, -5.45192419278888, 3.10930244892261, 0, 0, -5.02980895672233, 5.4082726923341, -48.3290365382949, 5.02980895672233, -5.4082726923341, 48.3290365382949, 0, 2.16443515803395, 21.0488520130996, -38.6505735454448, -2.16443515803395, -21.0488520130996, 38.6505735454448, 11.301384163533, 5.04640285684089, 9.71946135141663, 9.21520988370216, 4.20442453473104, 0.0864653905040408, 9.21520988370216, 4.20442453473104, 0.0864653905040406, 14.0190823730271, 14.2108772033409, 24.0899676140367, -51.2214686002918, 14.2108772033409, 24.0899676140367, -51.2214686002918, -2.94902990916057E-17, -2.08166817117217E-17, 0.409655146504848, -2.13770523265812, -0.166911902672378, -0.409655146504848, 2.13770523265812, 0.166911902672378, 0, 0.128126516280133, 3.41361458305222, 1.50135626982485, -0.128126516280133, -3.41361458305222, -1.50135626982485, -2.71924845380677, -3.00211552243835, -3.52015839198105, -5.41544778625127, -11.7893450407488, -3.52015839198105, -5.41544778625127, -11.7893450407488, -3.36532602257169, -4.21217395862763, -13.3552651024839, 29.5052192061985, -4.21217395862763, -13.3552651024839, 29.5052192061985, 0, -0.777824905615586, 0.182070540329546, -0.266938159883533, -1.44755932031152, -2.33835042367754, -0.266938159883533, -1.44755932031152, -2.33835042367754, 0.308319043161397, -0.64475549181795, -31.9081123051583, 10.0432538072851, -0.64475549181795, -31.9081123051583, 10.0432538072851, 0, 1.38777878078145E-17, -0.4651308638072, -1.01059316019605, -3.22047187794453, 0.4651308638072, 1.01059316019605, 3.22047187794453, 1.21430643318377E-17, -0.652057779184334, -5.39933599975214, -2.65932524348569, 0.652057779184334, 5.39933599975214, 2.65932524348569, -20.8947287998807, -20.8939662029067, -20.4660022882249, -13.9663497069928, 3.72651392566029, -20.4660022882249, -13.9663497069928, 3.72651392566029, -20.8148027436241, -19.3607066652156, -12.4747872187268, -12.1435006547985, -19.3607066652156, -12.4747872187268, -12.1435006547985, 0];
4 | var genderaxis = [10.8622752381147, 3.87784584606416, 3.96644411626268, 3.85579242843092, 2.20245821571388, 3.96644411626268, 3.85579242843092, 2.20245821571388, -1.91706656439971, -2.88401118505139, -7.71017967887297, -5.23282986301825, -2.88401118505139, -7.71017967887297, -5.23282986301825, 0, 0, 2.33504968867266, 5.35207779836652, 0.896955890332611, -2.33504968867266, -5.35207779836652, -0.896955890332611, 0, -4.92072625597757, 6.13262704447186, 4.90290566512624, 4.92072625597757, -6.13262704447186, -4.90290566512624, 0.598322945574293, -0.820230066738596, 1.10163845162971, 2.74334260600583, -0.954369366369163, 1.10163845162971, 2.74334260600583, -0.954369366369163, -4.07022663674413, -4.5315810093439, -1.9174147757701, -2.68748748543046, -4.5315810093439, -1.9174147757701, -2.68748748543046, -0.890102321103325, -8.32667268468867E-17, -5.55111512312578E-17, 1.30515160463045, 0.697114232970961, -0.527484841356247, -1.30515160463045, -0.697114232970961, 0.527484841356248, -2.77555756156289E-17, 0.0485813554947454, 1.82721802473303, -0.00338294354078825, -0.0485813554947455, -1.82721802473303, 0.00338294354078825, 5.01816863098923, 3.20435623460813, 3.55019257928635, 1.80610030041737, -1.36322519248119, 3.55019257928635, 1.80610030041738, -1.36322519248119, -0.162180926939796, -1.59859605581916, -2.25377676330274, 0.169346972086787, -1.59859605581916, -2.25377676330274, 0.169346972086787, -6.93889390390723E-18, -3.46944695195361E-18, -1.43489570265418, -1.33939655573188, -2.94792693327534, 1.43489570265418, 1.33939655573188, 2.94792693327534, 0, -1.72218146089708, -2.56033660634584, -0.740142747399359, 1.72218146089708, 2.56033660634584, 0.740142747399359, 0.034207395201156, 0, 0, 0.50895749811239, 10.8092969078574, 17.5970954067276, -0.50895749811239, -10.8092969078574, -17.5970954067276, -2.77555756156289E-17, -0.768659543801708, -3.28343975390831, -4.10636698720229, 0.768659543801708, 3.28343975390831, 4.10636698720229, 3.00122757985203, 0.99540454173169, 1.05848994151511, -0.953610312585894, -2.2087593437931, 1.05848994151511, -0.953610312585894, -2.2087593437931, -0.665648010096331, -1.09272854820708, -0.356435265191952, -0.252999700189796, -1.09272854820708, -0.356435265191952, -0.252999700189796, 6.93889390390723E-18, 0, -1.62054857692189, -4.68841758693348, -1.34999678078504, 1.62054857692189, 4.68841758693348, 1.34999678078504, 3.46944695195361E-18, -0.24203076680066, -2.61872493398542, -1.3140922430098, 0.24203076680066, 2.61872493398542, 1.3140922430098, 0.348889753128268, 0.860562851303457, -0.458459262279532, -0.27592558441124, -0.320091182027612, -0.667765665467602, -0.27592558441124, -0.320091182027612, -0.667765665467603, -1.62704716356786, -1.49325355842263, 2.1374462006464, 1.37280884103637, -1.49325355842263, 2.1374462006464, 1.37280884103637, -2.77555756156289E-17, -1.38777878078145E-17, -0.00400167616055201, -0.0820685931886628, 0.33762561402375, 0.00400167616055198, 0.0820685931886629, -0.33762561402375, -1.38777878078145E-17, 0.00516524711570088, 1.30236325923525, 0.405743234314944, -0.00516524711570093, -1.30236325923525, -0.405743234314944, -0.186397660789509, -0.154535028531196, -0.336599188354126, -0.0999716867334504, 0.217840087631619, -0.336599188354126, -0.0999716867334503, 0.217840087631619, -0.161083943571017, -0.245518701880568, 1.95664779431894, 1.05702171892267, -0.245518701880568, 1.95664779431894, 1.05702171892267, 0, 0.759222556825001, 0.355377914840419, 0.353595133224375, -0.425647703311692, 1.05136089417181, 0.353595133224375, -0.425647703311692, 1.05136089417181, -0.248022688099012, -0.429277241010223, 1.17633656323907, -0.240189659908589, -0.429277241010223, 1.17633656323907, -0.240189659908589, -2.77555756156289E-17, -2.08166817117217E-17, 0.016422717738074, 1.33953448719773, 0.913474371405699, -0.0164227177380741, -1.33953448719773, -0.913474371405699, -1.38777878078145E-17, 0.00970342000951549, -0.279947291858412, 0.889223046696579, -0.00970342000951552, 0.279947291858412, -0.889223046696579, -0.766276468753209, -0.558612770425893, -0.631510924081967, -1.74294715459389, -3.04002900775738, -0.631510924081967, -1.74294715459389, -3.04002900775738, -0.802355169400983, -0.880726423552862, -1.56721947803708, -0.338692149454206, -0.880726423552862, -1.56721947803708, -0.338692149454206, 0];
5 | var weightaxis = [-8.60322982096967, -4.39777268443819, -4.31654137593974, -1.02419968988667, -1.60591703899923, -4.31654137593974, -1.02419968988667, -1.60591703899923, -4.26099331081557, -2.32629930281409, 6.43969549700463, 10.0935693318593, -2.32629930281409, 6.43969549700463, 10.0935693318593, 0, 0, 3.71622029046712, 6.65597759326383, 9.69562192919174, -3.71622029046712, -6.65597759326383, -9.69562192919174, 0, 7.78736639282353, 0.0787433078343267, -1.26556630921202, -7.78736639282353, -0.0787433078343267, 1.26556630921202, 0.0596088709303616, 0.817695654477612, -3.95444231532143, -6.22768530651593, -12.9325434566197, -3.95444231532143, -6.22768530651593, -12.9325434566197, 11.2221263908486, 10.3804686577979, 7.29828647571261, 2.28212360340294, 10.3804686577979, 7.29828647571261, 2.28212360340294, 4.55185600891705, 6.23921190478346E-17, 9.61506336619311E-18, -1.03881331001095, 1.17656495856413, 5.02239268004826, 1.03881331001095, -1.17656495856413, -5.02239268004826, 4.80753168309656E-18, -0.552115811903587, -3.59626076398225, 0.0146124883231591, 0.552115811903588, 3.59626076398225, -0.014612488323159, -0.845208137045764, 0.225742151854656, -0.162288739590334, 0.768519833706678, 1.38266394169628, -0.162288739590334, 0.768519833706659, 1.38266394169628, 2.2338618526944, 2.37246823360433, -2.62595872751184, -0.160888799369168, 2.37246823360433, -2.62595872751184, -0.160888799369168, -3.47752600781346E-17, -4.13723920383398E-17, 0.84983102742614, 0.730621878292606, 3.31882760712525, -0.84983102742614, -0.730621878292606, -3.31882760712525, 0, 0.937032237142068, 1.66858338568437, 0.606406841881119, -0.937032237142068, -1.66858338568437, -0.606406841881119, 0, 0, 0, -2.91479968579839, 1.9908650545833, 14.8457174549164, 2.91479968579839, -1.9908650545833, -14.8457174549164, -4.31619923154484E-17, -1.49629823768662, -4.65169274010743, -3.5699595564498, 1.49629823768662, 4.65169274010743, 3.5699595564498, -0.389314859668211, -0.722941359031102, -1.11155939802322, 1.97896062813978, 2.34449642252038, -1.11155939802322, 1.97896062813978, 2.34449642252038, -0.862357708685933, -1.5548643796591, -1.70314919425028, 1.98849454708394, -1.5548643796591, -1.70314919425028, 1.98849454708394, -6.11637879189553E-17, -4.79695239985449E-17, 0.0313780976365884, -1.41383220880015, 7.79009045809917, -0.0313780976365884, 1.41383220880015, -7.79009045809917, -5.45666559587501E-17, -0.945524264476216, 1.94598558199536, 4.07786448889072, 0.945524264476216, -1.94598558199536, -4.07786448889072, -0.854887153611129, -0.124788851245166, 0.594542218404294, 0.760752724745457, 0.957793598700929, -1.53748528891728, 0.760752724745457, 0.957793598700929, -1.53748528891728, 1.00760066357486, 0.884790964265378, -1.68363749086776, -1.07391675519032, 0.884790964265378, -1.68363749086776, -1.07391675519032, 2.87922936823689E-17, 2.63885278408208E-17, 0.0427992390747824, -0.982282749429476, -0.627035878127249, -0.0427992390747823, 0.982282749429476, 0.627035878127249, 1.7019480184855E-17, -0.00592021574889225, 2.18799810355824, -1.32408123662573, 0.00592021574889231, -2.18799810355824, 1.32408123662573, 1.43566255610034, 1.57932517557856, 1.70940351164603, 1.34079760022902, -0.326156828395397, 1.70940351164603, 1.34079760022902, -0.326156828395397, 1.61550112667063, 1.59438617934391, -0.945301734607545, -1.4507723825316, 1.59438617934391, -0.945301734607528, -1.4507723825316, 0, -1.14199452482802, -0.908274325058428, -1.23592692595839, -0.0488368203386743, 1.78428901641138, -1.23592692595839, -0.0488368203386725, 1.78428901641138, -0.0206058483765944, -0.0498759350552304, -1.9514425427784, -0.975952785179369, -0.0498759350552304, -1.9514425427784, -0.97595278517937, 4.80753168309656E-18, 1.25999345120496E-17, -0.0778248096444307, -1.05713452199503, 0.140159622942414, 0.0778248096444309, 1.05713452199503, -0.140159622942414, 2.63885278408208E-17, 0.0958178614773403, -2.29016183152658, -0.981655940758735, -0.0958178614773402, 2.29016183152658, 0.981655940758735, 0.873163814765254, 0.691630217779826, 0.460659242794834, -1.21243959156637, -4.95415159635425, 0.460659242794834, -1.21243959156637, -4.95415159635425, 0.912366138079486, 1.1111424379197, 0.506354668509017, -0.645344827798356, 1.1111424379197, 0.506354668509017, -0.645344827798356, 0];
6 | var nervousaxis = [1.608, -4.892, -5.1408, -10.2248, 4.3596, -5.1408, -10.2248, 4.3596, -0.4336, 0.817, 1.139, 12.0732, 0.817, 1.139, 12.0732, 0, 0, 12.227, 2.881, -0.9562, -12.227, -2.881, 0.9562, 0, 8.3682, -2.2468, -5.0328, -8.3682, 2.2468, 5.0328, 5.182, 2.5256, -9.0168, -9.2494, -9.1792, -9.0168, -9.2494, -9.1792, 15.8384, 15.6524, 1.5146, 1.9362, 15.6524, 1.5146, 1.9362, 14.974, 0, 0, 1.93498627759188, 8.55163596816083, 15.1677381022684, -1.93498627759188, -8.55163596816083, -15.1677381022684, 0, 0.0238269291828461, -0.244238930292991, 4.39508124233437, -0.0238269291828461, 0.244238930292991, -4.39508124233437, -1.89858387288271, -0.927809352857772, -1.10742752703369, 1.23096755420124, -2.22327591578999, -1.10742752703369, 1.23096755420124, -2.22327591578999, -0.574144540287477, -0.272324131191442, -1.66297412423435, -3.52473328883379, -0.272324131191442, -1.66297412423435, -3.52473328883379, -4.44089209850063E-17, -4.44089209850063E-17, 0.295973921644049, -0.952476234327165, 4.62764712369284, -0.29597392164405, 0.952476234327165, -4.62764712369284, -4.44089209850063E-17, 0.755561531385885, 0.96965704641076, -1.04874475563672, -0.755561531385885, -0.96965704641076, 1.04874475563672, 0, -8.88178419700125E-17, -8.88178419700125E-17, -2.27213865455679, 2.62068190134895, 10.46424956607, 2.27213865455679, -2.62068190134895, -10.46424956607, -1.33226762955019E-16, 0.505149005191256, 9.023283935737, 12.4419154069332, -0.505149005191256, -9.023283935737, -12.4419154069332, 1.31302213143179, -1.56994681589844, -1.6132516828964, -1.93476231111313, 1.24600961564034, -1.6132516828964, -1.93476231111313, 1.24600961564034, -0.916102246945221, -1.15341023385907, 0.0679548535942194, 1.21923750048419, -1.15341023385907, 0.0679548535942194, 1.21923750048419, 4.44089209850063E-17, 4.44089209850063E-17, -0.866748197406053, -2.37620306856168, -1.04181193052172, 0.866748197406053, 2.37620306856168, 1.04181193052172, 4.44089209850063E-17, -0.296525162996019, 1.25545730805391, 3.71906045091021, 0.29652516299602, -1.25545730805391, -3.71906045091021, 0, 2.15229559017491, 2.63997203948315, 2.88310527131121, 1.08475359067976, -1.84315670321758, 2.88310527131121, 1.08475359067976, -1.84315670321758, 1.85591583782068, 1.31826611955976, -4.08303895625175, -6.91689571702907, 1.31826611955976, -4.08303895625175, -6.91689571702907, 0, 0, 0.0988529041750603, 0.0502665499295525, 1.01706930838328, -0.0988529041750603, -0.0502665499295526, -1.01706930838328, 4.44089209850063E-17, 0.0182012962139708, 0.618271764328891, 0.528820419727892, -0.0182012962139707, -0.618271764328891, -0.528820419727892, 1.27953376484632, 1.05464034445745, 1.06849192617536, 1.29477915707343, -1.80131176088519, 1.06849192617536, 1.29477915707343, -1.80131176088519, 1.05127818065678, 1.14328402799826, 0.147983699397682, 0.758893489554762, 1.14328402799826, 0.147983699397682, 0.758893489554763, 0, -0.762854122695589, -0.950093864177193, -0.896770402353652, -1.16680283146184, -1.26709316444533, -0.896770402353652, -1.16680283146184, -1.26709316444533, -1.68350389453852, -1.96917864045415, -1.073952457854, 2.29589238418201, -1.96917864045415, -1.073952457854, 2.29589238418201, -7.7715611723761E-17, -5.55111512312578E-17, 0.0240354599738873, -1.13762060193993, -1.84086075028633, -0.0240354599738874, 1.13762060193993, 1.84086075028633, -5.55111512312578E-17, -0.00731797896493922, -1.00726341412445, -1.67921538930502, 0.00731797896493909, 1.00726341412445, 1.67921538930502, -1.77067835154163, -1.72694930552193, -2.02147369107245, -3.46120440517578, -5.42293017289516, -2.02147369107245, -3.46120440517578, -5.42293017289516, -1.81913811099514, -1.80524552106467, -0.308170447500367, -1.31680547975447, -1.80524552106467, -0.308170447500367, -1.31680547975447, 0];
7 | var happyaxis = [-3.6804, 3.8492, 3.1128, 0.3552, 1.2418, 3.1128, 0.3552, 1.2418, -5.3888, -7.6816, 0.0542000000000002, 4.2798, -7.6816, 0.0542000000000002, 4.2798, 0, 0, -3.5408, 3.0712, 7.0442, 3.5408, -3.0712, -7.0442, 0, 2.1176, 2.575, 2.1302, -2.1176, -2.575, -2.1302, 4.72, -2.9876, 1.291, 1.9114, 3.0876, 1.291, 1.9114, 3.0876, -6.9384, -6.1032, -6.0298, 2.6348, -6.1032, -6.0298, 2.6348, -11.7576, -4.44089209850063E-17, -3.33066907387547E-17, -0.666342789075971, -6.0838299041835, -8.09295988385648, 0.666342789075971, 6.0838299041835, 8.09295988385648, -4.44089209850063E-17, 0.335225594087923, 2.46216812769978, -2.29332046445224, -0.335225594087923, -2.46216812769978, 2.29332046445224, -1.31118412456019, -0.256508018691095, -0.358033814045386, 1.44243860485824, 3.33623660331717, -0.358033814045386, 1.44243860485824, 3.33623660331717, 1.02104033366303, 2.37903282916426, 1.83761034778044, 1.17579017959672, 2.37903282916426, 1.83761034778044, 1.17579017959672, 4.44089209850063E-17, 4.44089209850063E-17, 1.44553490065014, 3.25201037152906, 1.52786297776612, -1.44553490065014, -3.25201037152906, -1.52786297776612, 4.44089209850063E-17, 1.41987741110572, 2.03949815862409, 0.704496177795203, -1.41987741110572, -2.03949815862409, -0.704496177795203, 0, 0, 0, 2.32089005501046, 8.2004699241545, 9.02785264380681, -2.32089005501046, -8.2004699241545, -9.02785264380682, 0, 1.80607391904883, 19.5478576675537, 40.2099356339615, -1.80607391904883, -19.5478576675537, -40.2099356339615, 3.31999492040294, 2.47801758596406, 2.63198730012136, 0.250964203054187, -4.2740278434618, 2.63198730012136, 0.250964203054187, -4.2740278434618, -0.380111558668358, -0.937259386594074, -1.36618028449039, -0.662055959541116, -0.937259386594074, -1.36618028449039, -0.662055959541116, -4.44089209850063E-17, -4.44089209850063E-17, -1.34022486583498, -2.76114288356605, -1.42272873070436, 1.34022486583498, 2.76114288356605, 1.42272873070436, -4.44089209850063E-17, -0.981461694327258, 4.8738444231396, -3.72794395551649, 0.981461694327258, -4.8738444231396, 3.72794395551649, 0, 1.30627261918698, 1.81803679205044, 1.68843663143742, 2.56463742946301, 1.43182649653633, 1.68843663143742, 2.56463742946301, 1.43182649653633, 1.18074184338601, 1.43513171383725, 6.90719763233261, -1.1115336009357, 1.43513171383725, 6.90719763233261, -1.1115336009357, -3.88578058618805E-17, -3.33066907387547E-17, -0.0601636152042345, -0.41317835167411, 0.627694869579082, 0.0601636152042344, 0.41317835167411, -0.627694869579082, -2.77555756156289E-17, 0.00366706940309695, 0.297968425724437, 1.09982632273336, -0.00366706940309698, -0.297968425724437, -1.09982632273336, -1.60810360624062, -1.52910873346637, -1.53785179605942, -0.812853930949932, -0.767842482084008, -1.53785179605942, -0.812853930949932, -0.767842482084008, -1.66422626280928, -1.7494947574052, -1.26111226605018, 3.21392723077718, -1.7494947574052, -1.26111226605018, 3.21392723077718, 0, -0.0833652467301549, 0.372450671567337, 0.387201887418256, 1.10961312870629, 1.03513527802723, 0.387201887418255, 1.10961312870629, 1.03513527802723, 1.44049499106293, 1.53278623556534, 2.20949939757829, -1.11392398932374, 1.53278623556534, 2.20949939757829, -1.11392398932374, 0, 2.22044604925031E-17, 0.0876067315082398, 1.18328003858253, 1.74422204741945, -0.0876067315082397, -1.18328003858253, -1.74422204741945, -2.22044604925031E-17, -0.001718313706187, 0.68205874913478, 0.581814282931261, 0.001718313706187, -0.68205874913478, -0.581814282931261, -6.12734886158736, -6.16231355914618, -6.30453521311102, -6.78278462041507, -7.60669697586982, -6.30453521311102, -6.78278462041507, -7.60669697586982, -6.09902206473922, -6.12172192882131, -2.59588583193055, 3.35944140524417, -6.12172192882131, -2.59588583193055, 3.35944140524417, 0];
8 |
9 |
10 | function Walker( rm ) {
11 |
12 | this.rm = rm;
13 | this.paused = false;
14 |
15 | this.markers = [];
16 | for ( i = 0; i < 46; i++ ) this.markers.push( 0 );
17 |
18 | this.vertices = [];
19 | this.values = [];
20 | for ( i = 0; i < 15; i++ )
21 | {
22 | this.vertices.push( new THREE.Vector3(0,0,0) );
23 | this.values.push( 0,0,0 );
24 | }
25 |
26 | this.rm.setUniform( "anchors", "v3v", this.vertices );
27 |
28 | this.reset();
29 |
30 | }
31 |
32 | function reset() {
33 |
34 | this.speed = 1;
35 | this.gender = 5;
36 | this.nervous = 0;
37 | this.weight = 0;
38 | this.happy = 0;
39 |
40 | this.walkertime = 0;
41 | this.initphase = 0;
42 |
43 | this.starttime =
44 | this.lasttime = Date.now() * .001;
45 |
46 | this.sizes = [
47 | 1.25, //head
48 | 1.25, // neck
49 |
50 | 1, //shoulder L
51 | 1, //elbow L
52 | .5,//hand L
53 |
54 | 1, //shoulder R
55 | 1, //elbow R
56 | .5,//hand R
57 |
58 | 1, //plexus
59 |
60 | .75,//hip L
61 | 1., //knee L
62 | 1.5,//foot L
63 |
64 | .75,//hip R
65 | 1., //knee R
66 | 1.5 //foot R
67 | ];
68 |
69 | }
70 |
71 | function update() {
72 |
73 | var curtime = Date.now() * .0005 - this.starttime;
74 |
75 | var timediff = (curtime - this.lasttime);
76 |
77 | var speed = ((((meanwalker[45]
78 | + (this.gender * genderaxis[45]))
79 | + (this.weight * weightaxis[45]))
80 | + (this.nervous * nervousaxis[45]))
81 | + (this.happy * happyaxis[45]));
82 |
83 | //this.walkertime = this.walkertime + ((((timediff ) * 2) * Math.PI) * (120 / (speed / this.speed)));
84 | this.walkertime = this.walkertime + (( timediff * 2 * Math.PI) * ( 120 / ( speed / this.speed ) ));
85 |
86 | var i = 0;
87 | while (i < 46) {
88 |
89 | this.markers[i] = (
90 | (
91 | (
92 | (
93 | (((meanwalker[i] + (weightaxis[i] * this.weight))
94 | + (genderaxis[i] * this.gender))
95 | + (nervousaxis[i] * this.nervous))
96 | + (happyaxis[i] * this.happy)
97 | )
98 |
99 | +
100 | (((((meanwalker[i + 46] + (genderaxis[i + 46] * this.gender))
101 | + (weightaxis[i + 46] * this.weight))
102 | + (nervousaxis[i + 46] * this.nervous))
103 | + (happyaxis[i + 46] * this.happy)) * Math.sin(this.walkertime + ((this.initphase * Math.PI) / 180)))
104 | )
105 |
106 | + (((((meanwalker[i + 92]
107 | + (genderaxis[i + 92] * this.gender))
108 | + (weightaxis[i + 92] * this.weight))
109 | + (nervousaxis[i + 92] * this.nervous))
110 | + (happyaxis[i + 92] * this.happy)) * Math.cos(this.walkertime + ((this.initphase * Math.PI) / 180)))
111 | )
112 |
113 | + (((((meanwalker[i + 138]
114 | + (genderaxis[i + 138] * this.gender))
115 | + (weightaxis[i + 138] * this.weight))
116 | + (nervousaxis[i + 138] * this.nervous))
117 | + (happyaxis[i + 138] * this.happy)) * Math.sin(2 * (this.walkertime + ((this.initphase * Math.PI) / 180))))
118 | )
119 |
120 | + (((((meanwalker[i + 184]
121 | + (genderaxis[i + 184] * this.gender))
122 | + (weightaxis[i + 184] * this.weight))
123 | + (nervousaxis[i + 184] * this.nervous))
124 | + (happyaxis[i + 184] * this.happy)) * Math.cos(2 * (this.walkertime + ((this.initphase * Math.PI) / 180))));
125 | i++;
126 | }
127 |
128 | i = 0;
129 | this.values = [];
130 | this.sizes = [];
131 | while ( i < 15 )
132 | {
133 | this.vertices[ i ].x = this.markers[i + 15];
134 | this.vertices[ i ].y = this.markers[i + 30];
135 | this.vertices[ i ].z = this.markers[i ];
136 |
137 | var v = this.vertices[i].multiplyScalar( .01 );
138 | this.values.push( v.x, v.y, v.z);
139 |
140 | //this.sizes.push( v.x );
141 |
142 | if( i == 8 )
143 | {
144 | this.rm.target.copy( v );
145 | this.rm.target.y += 2;
146 | }
147 |
148 | i++;
149 | }
150 |
151 | this.rm.material.uniforms.anchors.value = this.vertices;
152 | this.rm.material.uniforms.anchors.needsUpdate = true;
153 | this.lasttime = curtime;
154 |
155 | }
156 |
157 |
158 | var _p = Walker.prototype;
159 | _p.constructor = Walker;
160 | _p.reset = reset;
161 | _p.update = update;
162 | return Walker;
163 |
164 | }();
--------------------------------------------------------------------------------
/cells.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/colors.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/composer.js:
--------------------------------------------------------------------------------
1 | var Composer = function(){
2 |
3 | function Composer( raymarching ){
4 |
5 | this.renderer = raymarching.renderer;
6 | this.scene = raymarching.scene;
7 | this.camera = raymarching.renderCamera;
8 |
9 | this.composer = new THREE.EffectComposer( this.renderer );
10 | this.composer.addPass( new THREE.RenderPass( this.scene, this.camera ) );
11 |
12 | this.fxaa = new THREE.ShaderPass( THREE.FXAAShader );
13 | this.fxaa.renderToScreen = true;
14 | this.composer.addPass( this.fxaa );
15 |
16 | }
17 |
18 | function setSize(width, height) {
19 | this.composer.setSize(width, height);
20 | this.fxaa.uniforms.resolution.value.set( 1 / width, 1 / height );
21 | }
22 |
23 | function render()
24 | {
25 | this.composer.render();
26 | }
27 |
28 | var _p = Composer.prototype;
29 | _p.render = render;
30 | _p.setSize = setSize;
31 | return Composer;
32 |
33 | }();
--------------------------------------------------------------------------------
/glsl/bits/draw/ao.glsl:
--------------------------------------------------------------------------------
1 |
2 | //https://www.shadertoy.com/view/Xds3zN
3 |
4 | float calcAO( in vec3 pos, in vec3 nor )
5 | {
6 | float occ = 0.0;
7 | float sca = 1.0;
8 | for( int i=0; i maximumDistance) break;
12 | vec2 result = field( rayOrigin + rayDir * dist );
13 | latest = result.x;
14 | dist += latest;
15 | type = result.y;
16 | }
17 |
18 | vec2 res = vec2(-1.0, -1.0 );
19 | if (dist < maximumDistance) { res = vec2(dist, type ); }
20 | return res;
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/glsl/bits/draw/rim.glsl:
--------------------------------------------------------------------------------
1 | //http://www.roxlu.com/2014/037/opengl-rim-shader
2 | vec3 rimlight( vec3 pos, vec3 nor )
3 | {
4 | return vec3(smoothstep(0., 1.0, 1.0 - max(dot( normalize(-pos), nor), 0.0) ));
5 | }
6 |
--------------------------------------------------------------------------------
/glsl/bits/draw/shadows.glsl:
--------------------------------------------------------------------------------
1 |
2 | //https://www.shadertoy.com/view/Xds3zN
3 |
4 | float softshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax, in float K )
5 | {
6 | float res = 1.0;
7 | float t = mint;
8 | for( int i=0; itmax ) break;
14 | }
15 | return clamp( res, 0.0, 1.0 );
16 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/box.glsl:
--------------------------------------------------------------------------------
1 |
2 |
3 | //-------- unit box
4 | vec2 box(vec3 p )
5 | {
6 | return vec2( length( max( abs( p )-vec3(1.), 0.0 ) ),1.);
7 | }
8 |
9 | //-------- variable size box
10 |
11 | vec2 box(vec3 p, vec3 size )
12 | {
13 | return vec2( length( max( abs( p )-size, 0.0 ) ),1.);
14 | }
15 | vec2 box(vec3 p, vec3 size, vec3 pos )
16 | {
17 | return box( p-pos, size );
18 | }
19 |
20 |
21 |
22 | //-------- variable size box + rounded corners
23 |
24 | vec2 box(vec3 p, vec3 size, float corner )
25 | {
26 | return vec2( length( max( abs( p-pos )-size, 0.0 ) )-corner,1.);
27 | }
28 | vec2 box(vec3 p, vec3 size, float corner, vec3 pos )
29 | {
30 | return box( p-pos, size, corner );
31 | }
32 |
33 |
34 | //requires glsl/bits/util/rotation.glsl
35 |
36 | //-------- variable size box + rounded corners + transforms
37 |
38 | vec2 box(vec3 p, vec4 quat )
39 | {
40 | return return box( p * rotationMatrix3( quat.xyz, quat.w ) );
41 | }
42 |
43 | vec2 box(vec3 p, vec3 size, vec4 quat )
44 | {
45 | return return box( p * rotationMatrix3( quat.xyz, quat.w ), size );
46 | }
47 |
48 | vec2 box(vec3 p, vec3 size, float corner, vec4 quat )
49 | {
50 | return return box( ( p-pos ) * rotationMatrix3( quat.xyz, quat.w ), size, corner );
51 | }
52 |
53 | vec2 box(vec3 p, vec3 size, float corner, vec3 pos, vec4 quat )
54 | {
55 | return return box( ( p-pos ) * rotationMatrix3( quat.xyz, quat.w ), size, corner );
56 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/cylinder.glsl:
--------------------------------------------------------------------------------
1 |
2 | //requires glsl/bits/util/rotation.glsl
3 |
4 | //http://www.pouet.net/topic.php?post=365312
5 | vec2 cylinder( vec3 p, float h, float r, vec3 pos, vec4 quat ) {
6 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
7 | vec3 pp = (p - pos ) * transform;
8 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
9 | }
10 | vec2 cylinder( vec3 p, float h, float r, vec3 pos ) {
11 | vec3 pp = (p - pos );
12 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
13 | }
14 | vec2 cylinder( vec3 p, float h, float r ) {
15 | return vec2( max(length(p.xz)-r, abs(p.y)-h),1. );
16 | }
17 |
--------------------------------------------------------------------------------
/glsl/bits/geom/madelbulb.glsl:
--------------------------------------------------------------------------------
1 |
2 | //http://www.kevs3d.co.uk/dev/shaders/mandelbulb.html
3 |
4 | vec2 MandelBulb(vec3 pos)
5 | {
6 | const int Iterations = 12;
7 | const float Bailout = 8.0;
8 | float Power = 5.0 + sin(time*0.5)*4.0;
9 |
10 | vec3 z = pos;
11 | float dr = 1.0;
12 | float r = 0.0;
13 | for (int i = 0; i < Iterations; i++)
14 | {
15 | r = length(z);
16 | if (r > Bailout) break; // TODO: test if better to continue loop and if() rather than break?
17 |
18 | // convert to polar coordinates
19 | float theta = acos(z.z/r);
20 | float phi = atan(z.y,z.x);
21 | dr = pow(r, Power-1.0)*Power*dr + 1.0;
22 |
23 | // scale and rotate the point
24 | float zr = pow(r,Power);
25 | theta = theta*Power;
26 | phi = phi*Power;
27 |
28 | // convert back to cartesian coordinates
29 | z = zr*vec3(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta));
30 | z += pos;
31 | }
32 | return vec2( 0.5*log(r)*r/dr, 1. );
33 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/mandelBox.glsl:
--------------------------------------------------------------------------------
1 | //http://www.kevs3d.co.uk/dev/shaders/mandelbox.html
2 | vec2 MandleBox(vec3 pos)
3 | {
4 | const int Iterations = 12;
5 | const float Scale = 3.0;
6 | const float FoldingLimit = 100.0;
7 |
8 | float MinRad2 = 0.15 + abs(sin(time*.25))*.75;
9 | vec4 scale = vec4(Scale, Scale, Scale, abs(Scale)) / MinRad2;
10 | float AbsScalem1 = abs(Scale - 1.0);
11 | float AbsScaleRaisedTo1mIters = pow(abs(Scale), float(1-Iterations));
12 |
13 | vec4 p = vec4(pos,1.0), p0 = p; // p.w is the distance estimate
14 |
15 | for (int i=0; iFoldingLimit) break;
22 | }
23 | return vec2( ((length(p.xyz) - AbsScalem1) / p.w - AbsScaleRaisedTo1mIters), 1. );
24 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/plane.glsl:
--------------------------------------------------------------------------------
1 | //no height
2 | vec2 plane( vec3 p , vec3 n) { return vec2( dot(p, n), 1. ); }
3 | //with height
4 | vec2 plane( vec3 p , vec4 n) { return vec2( dot(p, n.xyz) + n.w, 1. ); }
5 |
--------------------------------------------------------------------------------
/glsl/bits/geom/platonic_solids_ref.glsl:
--------------------------------------------------------------------------------
1 |
2 | vec3 n1 = vec3(1.000,0.000,0.000);
3 | vec3 n2 = vec3(0.000,1.000,0.000);
4 | vec3 n3 = vec3(0.000,0.000,1.000);
5 | vec3 n4 = vec3(0.577,0.577,0.577);
6 | vec3 n5 = vec3(-0.577,0.577,0.577);
7 | vec3 n6 = vec3(0.577,-0.577,0.577);
8 | vec3 n7 = vec3(0.577,0.577,-0.577);
9 | vec3 n8 = vec3(0.000,0.357,0.934);
10 | vec3 n9 = vec3(0.000,-0.357,0.934);
11 | vec3 n10 = vec3(0.934,0.000,0.357);
12 | vec3 n11 = vec3(-0.934,0.000,0.357);
13 | vec3 n12 = vec3(0.357,0.934,0.000);
14 | vec3 n13 = vec3(-0.357,0.934,0.000);
15 | vec3 n14 = vec3(0.000,0.851,0.526);
16 | vec3 n15 = vec3(0.000,-0.851,0.526);
17 | vec3 n16 = vec3(0.526,0.000,0.851);
18 | vec3 n17 = vec3(-0.526,0.000,0.851);
19 | vec3 n18 = vec3(0.851,0.526,0.000);
20 | vec3 n19 = vec3(-0.851,0.526,0.000);
21 |
22 | // p as usual, e exponent (p in the paper), r radius or something like that
23 | float octahedral(vec3 p, float e, float r) {
24 | float s = pow(abs(dot(p,n4)),e);
25 | s += pow(abs(dot(p,n5)),e);
26 | s += pow(abs(dot(p,n6)),e);
27 | s += pow(abs(dot(p,n7)),e);
28 | s = pow(s, 1./e);
29 | return s-r;
30 | }
31 |
32 |
33 | float dodecahedral(vec3 p, float e, float r) {
34 | float s = pow(abs(dot(p,n14)),e);
35 | s += pow(abs(dot(p,n15)),e);
36 | s += pow(abs(dot(p,n16)),e);
37 | s += pow(abs(dot(p,n17)),e);
38 | s += pow(abs(dot(p,n18)),e);
39 | s += pow(abs(dot(p,n19)),e);
40 | s = pow(s, 1./e);
41 | return s-r;
42 | }
43 |
44 | float icosahedral(vec3 p, float e, float r) {
45 | float s = pow(abs(dot(p,n4)),e);
46 | s += pow(abs(dot(p,n5)),e);
47 | s += pow(abs(dot(p,n6)),e);
48 | s += pow(abs(dot(p,n7)),e);
49 | s += pow(abs(dot(p,n8)),e);
50 | s += pow(abs(dot(p,n9)),e);
51 | s += pow(abs(dot(p,n10)),e);
52 | s += pow(abs(dot(p,n11)),e);
53 | s += pow(abs(dot(p,n12)),e);
54 | s += pow(abs(dot(p,n13)),e);
55 | s = pow(s, 1./e);
56 | return s-r;
57 | }
58 |
59 | float toctahedral(vec3 p, float e, float r) {
60 | float s = pow(abs(dot(p,n1)),e);
61 | s += pow(abs(dot(p,n2)),e);
62 | s += pow(abs(dot(p,n3)),e);
63 | s += pow(abs(dot(p,n4)),e);
64 | s += pow(abs(dot(p,n5)),e);
65 | s += pow(abs(dot(p,n6)),e);
66 | s += pow(abs(dot(p,n7)),e);
67 | s = pow(s, 1./e);
68 | return s-r;
69 | }
70 |
71 | float ticosahedral(vec3 p, float e, float r) {
72 | float s = pow(abs(dot(p,n4)),e);
73 | s += pow(abs(dot(p,n5)),e);
74 | s += pow(abs(dot(p,n6)),e);
75 | s += pow(abs(dot(p,n7)),e);
76 | s += pow(abs(dot(p,n8)),e);
77 | s += pow(abs(dot(p,n9)),e);
78 | s += pow(abs(dot(p,n10)),e);
79 | s += pow(abs(dot(p,n11)),e);
80 | s += pow(abs(dot(p,n12)),e);
81 | s += pow(abs(dot(p,n13)),e);
82 | s += pow(abs(dot(p,n14)),e);
83 | s += pow(abs(dot(p,n15)),e);
84 | s += pow(abs(dot(p,n16)),e);
85 | s += pow(abs(dot(p,n17)),e);
86 | s += pow(abs(dot(p,n18)),e);
87 | s += pow(abs(dot(p,n19)),e);
88 | s = pow(s, 1./e);
89 | return s-r;
90 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/sierpinski.glsl:
--------------------------------------------------------------------------------
1 | //http://www.kevs3d.co.uk/dev/shaders/fractal.html
2 | vec2 sierpinski(vec3 pos)
3 | {
4 | const int Iterations = 14;
5 | const float Scale = 1.85;
6 | const float Offset = 2.0;
7 |
8 | vec3 a1 = vec3(1,1,1);
9 | vec3 a2 = vec3(-1,-1,1);
10 | vec3 a3 = vec3(1,-1,-1);
11 | vec3 a4 = vec3(-1,1,-1);
12 | vec3 c;
13 | float dist, d;
14 | for (int n = 0; n < Iterations; n++)
15 | {
16 | if(pos.x+pos.y<0.) pos.xy = -pos.yx; // fold 1
17 | if(pos.x+pos.z<0.) pos.xz = -pos.zx; // fold 2
18 | if(pos.y+pos.z<0.) pos.zy = -pos.yz; // fold 3
19 | pos = pos*Scale - Offset*(Scale-1.0);
20 | }
21 | return vec2( length(pos) * pow(Scale, -float(Iterations)), 1. );
22 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/sphere.glsl:
--------------------------------------------------------------------------------
1 |
2 | //requires glsl/bits/util/rotation.glsl
3 |
4 | vec2 sphere( vec3 p, float radius, vec3 pos, vec4 quat)
5 | {
6 | return vec2(length( ( p-pos ) * rotationMatrix3( quat.xyz, quat.w ) ) - radius,1);
7 | }
8 | vec2 sphere( vec3 p, float radius, vec3 pos )
9 | {
10 | return vec2( length( ( p-pos) ) - radius,1);
11 | }
12 | vec2 sphere( vec3 p, float radius )
13 | {
14 | return vec2(length( p ) - radius,1);
15 | }
--------------------------------------------------------------------------------
/glsl/bits/geom/torus.glsl:
--------------------------------------------------------------------------------
1 |
2 | //requires glsl/bits/util/rotation.glsl
3 |
4 | vec2 torus( vec3 p, vec2 radii, vec3 pos, vec4 quat )
5 | {
6 | vec3 pp = ( p - pos ) * rotationMatrix3( quat.xyz, quat.w );
7 | float d = length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y;
8 | return vec2(d,1.);
9 | }
10 |
11 | vec2 torus( vec3 p, vec2 radii, vec4 quat )
12 | {
13 | vec3 pp = p * rotationMatrix3( quat.xyz, quat.w );
14 | return vec2(length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y,1.);
15 | }
16 |
17 | vec2 torus( vec3 p, vec2 radii, vec3 pos )
18 | {
19 | vec3 pp = ( p - pos );
20 | return vec2(length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y,1.);
21 | }
22 |
23 | vec2 torus( vec3 p, vec2 radii )
24 | {
25 | return vec2(length( vec2( length( p.xz ) - radii.x, p.y ) ) - radii.y,1.);
26 | }
27 |
28 |
29 | vec2 torus( vec3 p, float radius, float section )
30 | {
31 | return torus( p, vec2( radius, section ) );
32 | }
33 | vec2 torus( vec3 p, float radius, float section, vec3 pos )
34 | {
35 | return torus( p, vec2( radius, section ), pos );
36 | }
37 | vec2 torus( vec3 p, float radius, float section, vec4 quat )
38 | {
39 | return torus( p, vec2( radius, section ), quat );
40 | }
41 | vec2 torus( vec3 p, float radius, float section, vec3 pos, vec4 quat )
42 | {
43 | return torus( p, vec2( radius, section ), pos, quat );
44 | }
--------------------------------------------------------------------------------
/glsl/bits/util/lookat.glsl:
--------------------------------------------------------------------------------
1 |
2 | //https://github.com/stackgl/glsl-look-at/blob/gh-pages/index.glsl
3 |
4 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
5 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
6 | vec3 ww = normalize(target - origin);
7 | vec3 uu = normalize(cross(ww, rr));
8 | vec3 vv = normalize(cross(uu, ww));
9 | return mat3(uu, vv, ww);
10 | }
11 |
--------------------------------------------------------------------------------
/glsl/bits/util/noise.glsl:
--------------------------------------------------------------------------------
1 | //http://www.kevs3d.co.uk/dev/shaders/distancefield3.html
2 |
3 | float hash(in float n)
4 | {
5 | return fract(sin(n)*43758.5453123);
6 | }
7 |
8 | float noise(in vec2 x)
9 | {
10 | vec2 p = floor(x);
11 | vec2 f = fract(x);
12 | f = f*f*(3.0-2.0*f);
13 | float n = p.x + p.y*57.0;
14 | float res = mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
15 | mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y);
16 | return res;
17 | }
18 |
19 | float fractalNoise(in vec2 xy)
20 | {
21 | const int octaves = 3;
22 | float w = 0.7;
23 | float f = 0.0;
24 | for (int i = 0; i < octaves; i++)
25 | {
26 | f += Noise(xy) * w;
27 | w *= 0.5;
28 | xy *= 2.333;
29 | }
30 | return f;
31 | }
--------------------------------------------------------------------------------
/glsl/bits/util/operations.glsl:
--------------------------------------------------------------------------------
1 |
2 | //operations
3 |
4 | vec2 unite(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
5 | vec2 intersect(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
6 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
7 |
8 | vec2 blend( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
9 | //http://iquilezles.org/www/articles/smin/smin.htm
10 | vec2 smin( vec2 a, vec2 b, float k )
11 | {
12 | float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 );
13 | return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. );
14 | }
15 | vec2 expBlend( vec2 a, vec2 b, float k )
16 | {
17 | float res = exp( -k*a.x ) + exp( -k*b.x );
18 | return vec2( -log( res )/k, 1. );
19 | }
20 | vec2 powBlend( vec2 a, vec2 b, float k )
21 | {
22 | float a = pow( a.x, k );
23 | float b = pow( b.x, k );
24 | return vec2( pow( (a*b)/(a+b), 1.0/k ), 1. );
25 | }
--------------------------------------------------------------------------------
/glsl/bits/util/perlin.glsl:
--------------------------------------------------------------------------------
1 |
2 |
3 | //http://www.pouet.net/topic.php?post=367360
4 | const vec3 pa = vec3(1., 57., 21.);
5 | const vec4 pb = vec4(0., 57., 21., 78.);
6 | float perlin(vec3 p) {
7 | vec3 i = floor(p);
8 | vec4 a = dot( i, pa ) + pb;
9 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
10 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
11 | a.xy = mix(a.xz, a.yw, f.y);
12 | return mix(a.x, a.y, f.z);
13 | }
14 |
--------------------------------------------------------------------------------
/glsl/bits/util/rotation.glsl:
--------------------------------------------------------------------------------
1 |
2 | mat3 rotationMatrix3(vec3 axis, float angle)
3 | {
4 | axis = normalize(axis);
5 | float s = sin(angle);
6 | float c = cos(angle);
7 | float oc = 1.0 - c;
8 |
9 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
10 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
11 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
12 | }
13 |
--------------------------------------------------------------------------------
/glsl/bits/util/squareFrame.glsl:
--------------------------------------------------------------------------------
1 |
2 | //https://github.com/hughsk/glsl-square-frame
3 |
4 | vec2 squareFrame(vec2 screenSize) {
5 | vec2 position = 2.0 * (gl_FragCoord.xy / screenSize.xy) - 1.0;
6 | position.x *= screenSize.x / screenSize.y;
7 | return position;
8 | }
9 | vec2 squareFrame(vec2 screenSize, vec2 coord) {
10 | vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
11 | position.x *= screenSize.x / screenSize.y;
12 | return position;
13 | }
--------------------------------------------------------------------------------
/glsl/cells.glsl:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | #define PI 3.1415926535897932384626433832795
4 |
5 | float hash(in float n)
6 | {
7 | return fract(sin(n)*43758.5453123);
8 | }
9 |
10 | void main() {
11 |
12 | vec2 xy = ( ( gl_FragCoord.xy / resolution.xy )- .5) * 2.;
13 | xy.x *= resolution.x/resolution.y;
14 |
15 | float length = pow( 2.,53. );
16 | int id = 0;
17 | vec2 p = vec2(0.);
18 | vec3 pp = vec3( 0.,0., .5 );
19 | vec3 lightDir = vec3( sin( time ), 1., cos( time * .5 ) );
20 |
21 | const int count = 200;
22 | for( int i = 0; i < count; i++ )
23 | {
24 | float an = sin( time * PI * .00001 ) - hash( float(i) ) * PI * 2.;
25 |
26 | float ra = sqrt( hash( an ) );
27 |
28 | p.x = lightDir.x + cos( an ) * ra;
29 | p.y = lightDir.z + sin( an ) * ra;
30 |
31 | float di = distance( xy, p );
32 | length = min( length, di );
33 | if( length == di )
34 | {
35 | id = i;
36 | pp.xy = p;
37 | pp.z = float( id )/float( count ) * ( -xy.x * 1.25 );
38 | }
39 | }
40 |
41 | gl_FragColor = vec4( pp + vec3( 1.) * ( 1. - max( 0.0, dot( pp, lightDir)) ), 1. );
42 |
43 | }
--------------------------------------------------------------------------------
/glsl/colors.glsl:
--------------------------------------------------------------------------------
1 |
2 | uniform vec2 resolution;
3 | uniform float time;
4 | uniform float fov;
5 | uniform float raymarchMaximumDistance;
6 | uniform float raymarchPrecision;
7 | uniform vec3 camera;
8 | uniform vec3 target;
9 |
10 |
11 | //uses most of the StackGL methods
12 | //https://github.com/stackgl
13 |
14 | //https://github.com/hughsk/glsl-square-frame
15 |
16 | vec2 squareFrame(vec2 screenSize) {
17 | vec2 position = 2.0 * (gl_FragCoord.xy / screenSize.xy) - 1.0;
18 | position.x *= screenSize.x / screenSize.y;
19 | return position;
20 | }
21 | vec2 squareFrame(vec2 screenSize, vec2 coord) {
22 | vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
23 | position.x *= screenSize.x / screenSize.y;
24 | return position;
25 | }
26 |
27 | //https://github.com/stackgl/glsl-look-at/blob/gh-pages/index.glsl
28 |
29 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
30 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
31 | vec3 ww = normalize(target - origin);
32 | vec3 uu = normalize(cross(ww, rr));
33 | vec3 vv = normalize(cross(uu, ww));
34 | return mat3(uu, vv, ww);
35 | }
36 |
37 | //https://github.com/stackgl/glsl-camera-ray
38 |
39 | vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) {
40 | return normalize(camMat * vec3(screenPos, lensLength));
41 | }
42 | vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) {
43 | mat3 camMat = calcLookAtMatrix(origin, target, 0.0);
44 | return getRay(camMat, screenPos, lensLength);
45 | }
46 |
47 | /////////////////////////////////////////////////////////////////////////
48 |
49 | mat3 rotationMatrix3(vec3 axis, float angle)
50 | {
51 | axis = normalize(axis);
52 | float s = sin(angle);
53 | float c = cos(angle);
54 | float oc = 1.0 - c;
55 |
56 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
57 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
58 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
59 | }
60 |
61 | /////////////////////////////////////////////////////////////////////////
62 |
63 | //primitives
64 |
65 | vec2 sphere( vec3 p, float radius, vec3 pos , vec4 quat)
66 | {
67 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
68 | float d = length( ( p * transform )-pos ) - radius;
69 | return vec2(d,0.);
70 | }
71 |
72 | vec2 roundBox(vec3 p, vec3 size, float corner, vec3 pos, vec4 quat )
73 | {
74 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
75 | return vec2( length( max( abs( ( p-pos ) * transform )-size, 0.0 ) )-corner,1.);
76 | }
77 |
78 | vec2 torus( vec3 p, vec2 radii, vec3 pos, vec4 quat )
79 | {
80 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
81 | vec3 pp = ( p - pos ) * transform;
82 | float d = length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y;
83 | return vec2(d,1.);
84 | }
85 |
86 |
87 | //operations
88 |
89 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
90 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
91 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
92 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
93 |
94 | //http://iquilezles.org/www/articles/smin/smin.htm
95 | vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. ); }
96 |
97 | //utils
98 |
99 | vec3 twist( vec3 pos, float amount )
100 | {
101 | vec3 p = normalize( pos );
102 | float c = cos(amount * p.y);
103 | float s = sin(amount * p.y);
104 | mat2 m = mat2(c,-s,s,c);
105 | vec3 q = vec3(m*pos.xz,pos.y);
106 | return q;
107 | }
108 |
109 | //http://www.pouet.net/topic.php?post=367360
110 |
111 | #define pa vec3(1., 57., 21.)
112 | #define pb vec4(0., 57., 21., 78.)
113 | float perlin(vec3 p) {
114 | vec3 i = floor(p);
115 | vec4 a = dot( i, pa ) + pb;
116 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
117 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
118 | a.xy = mix(a.xz, a.yw, f.y);
119 | return mix(a.x, a.y, f.z);
120 | }
121 |
122 | /////////////////////////////////////////////////////////////////////////
123 |
124 | // STOP ! ! !
125 |
126 | // HAMMER TIME !
127 |
128 | /////////////////////////////////////////////////////////////////////////
129 |
130 | const int raymarchSteps = 200;
131 | #define PI 3.14159
132 | vec2 field( vec3 position )
133 | {
134 |
135 | //position
136 | vec3 zero = vec3(0.);
137 |
138 | //rotation
139 | vec4 quat = vec4( 1., 0.,0.,0. );
140 |
141 | //twist the whole result
142 | position = twist( position, sin( time ) * .5 );
143 |
144 | //box
145 | vec2 box = roundBox( position, vec3(2.0,2.0,2.0), 0.5, zero, quat + vec4( 1., 1., 1., PI / 4. ) );
146 |
147 | //torus
148 | vec2 to0 = torus( position, vec2( 4.0,.15), zero, quat );
149 | vec2 to1 = torus( position, vec2( 4.0,.15), zero, vec4( 0., 0., 1., PI *.5 ) );
150 |
151 | //spheres
152 | vec2 sre = sphere( position, 3.0, zero, quat );
153 | vec2 sce = sphere( position, 1., zero, quat ) + perlin( position + time ) * .25;
154 |
155 | //shape composition
156 | float blend = .5 + sin( time * .5 ) * .5;
157 | vec2 _out = unionAB( sce, smin( to0, smin( to1, subtract( sre, box ), blend ), blend ) );
158 |
159 | //color attribution
160 |
161 | //the Y value of the return value will be used to apply a different shading
162 | // _out.y = 1. is the default value, here, it will be attributed to blended areas
163 | _out.y = 1.;
164 | //we can retrieve the elements by depth
165 | //we use the raymarch precision as a threshold
166 | float d = raymarchPrecision;
167 |
168 | //then an object is found like:
169 |
170 | if( _out.x > box.x - d )_out.y = 0.80;
171 | if( _out.x > to1.x - d )_out.y = 0.66;
172 | if( _out.x > to0.x - d )_out.y = 0.25;
173 | if( _out.x > sce.x - d )_out.y = 0.;
174 |
175 | //or
176 | _out.y = 1.;
177 | _out.y -= step( box.x - d, _out.x ) * .2
178 | + step( to0.x - d, _out.x ) * .35
179 | + step( to1.x - d, _out.x ) * .75
180 | + step( sce.x - d, _out.x ) * 1.0;
181 |
182 | return _out;
183 | }
184 |
185 | /////////////////////////////////////////////////////////////////////////
186 |
187 | // the methods below this need the field function
188 |
189 | /////////////////////////////////////////////////////////////////////////
190 |
191 |
192 | //the actual raymarching from:
193 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
194 |
195 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
196 |
197 | float latest = precis * 2.0;
198 | float dist = 0.0;
199 | float type = -1.0;
200 | for (int i = 0; i < raymarchSteps; i++) {
201 |
202 | if (latest < precis || dist > maxd) break;
203 |
204 | vec2 result = field( rayOrigin + rayDir * dist );
205 | latest = result.x;
206 | dist += latest;
207 |
208 | type = result.y;
209 | }
210 |
211 | vec2 res = vec2(-1.0, -1.0 );
212 | if (dist < maxd) { res = vec2( dist, type ); }
213 | return res;
214 |
215 | }
216 |
217 | void main() {
218 |
219 | vec2 screenPos = squareFrame( resolution );
220 |
221 | vec3 rayDirection = getRay( camera, target, screenPos, fov );
222 |
223 | vec2 collision = raymarching( camera, rayDirection, raymarchMaximumDistance, raymarchPrecision );
224 |
225 | gl_FragColor = vec4( vec3( .25,.25,.5), 1. );
226 |
227 | if ( collision.x > -0.5)
228 | {
229 |
230 | //retrieve the Y value set in the field() method
231 | vec3 col = vec3( collision.y );
232 |
233 | gl_FragColor = vec4( col, 1. );
234 |
235 | }
236 | }
--------------------------------------------------------------------------------
/glsl/fragment.glsl:
--------------------------------------------------------------------------------
1 |
2 | uniform vec2 resolution;
3 | uniform float time;
4 | uniform sampler2D map;
5 |
6 | //uses most of the StackGL methods
7 | //https://github.com/stackgl
8 |
9 | //https://github.com/hughsk/glsl-square-frame
10 |
11 | vec2 squareFrame(vec2 screenSize) {
12 | vec2 position = 2.0 * (gl_FragCoord.xy / screenSize.xy) - 1.0;
13 | position.x *= screenSize.x / screenSize.y;
14 | return position;
15 | }
16 | vec2 squareFrame(vec2 screenSize, vec2 coord) {
17 | vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
18 | position.x *= screenSize.x / screenSize.y;
19 | return position;
20 | }
21 |
22 | //https://github.com/stackgl/glsl-look-at/blob/gh-pages/index.glsl
23 |
24 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
25 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
26 | vec3 ww = normalize(target - origin);
27 | vec3 uu = normalize(cross(ww, rr));
28 | vec3 vv = normalize(cross(uu, ww));
29 | return mat3(uu, vv, ww);
30 | }
31 |
32 | //https://github.com/stackgl/glsl-camera-ray
33 |
34 | vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) {
35 | return normalize(camMat * vec3(screenPos, lensLength));
36 | }
37 | vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) {
38 | mat3 camMat = calcLookAtMatrix(origin, target, 0.0);
39 | return getRay(camMat, screenPos, lensLength);
40 | }
41 |
42 | /////////////////////////////////////////////////////////////////////////
43 |
44 | mat3 rotationMatrix3(vec3 axis, float angle)
45 | {
46 | axis = normalize(axis);
47 | float s = sin(angle);
48 | float c = cos(angle);
49 | float oc = 1.0 - c;
50 |
51 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
52 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
53 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
54 | }
55 |
56 | /////////////////////////////////////////////////////////////////////////
57 |
58 | //primitives
59 |
60 | vec2 sphere( vec3 p, float radius, vec3 pos , vec4 quat)
61 | {
62 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
63 | float d = length( ( p * transform )-pos ) - radius;
64 | return vec2(d,1);
65 | }
66 |
67 | vec2 roundBox(vec3 p, vec3 size, float corner, vec3 pos, vec4 quat )
68 | {
69 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
70 | return vec2( length( max( abs( ( p-pos ) * transform )-size, 0.0 ) )-corner,1.);
71 | }
72 |
73 | vec2 torus( vec3 p, vec2 radii, vec3 pos, vec4 quat )
74 | {
75 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
76 | vec3 pp = ( p - pos ) * transform;
77 | float d = length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y;
78 | return vec2(d,1.);
79 | }
80 |
81 | vec2 cone( vec3 p, vec2 c, vec3 pos, vec4 quat )
82 | {
83 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
84 | vec3 pp = ( p - pos ) * transform;
85 | float q = length(pp.xy);
86 | return vec2( dot(c,vec2(q,pp.z)), 1. );
87 | }
88 |
89 | //http://www.pouet.net/topic.php?post=365312
90 | vec2 cylinder( vec3 p, float h, float r, vec3 pos, vec4 quat ) {
91 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
92 | vec3 pp = (p - pos ) * transform;
93 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
94 | }
95 |
96 |
97 | //operations
98 |
99 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
100 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
101 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
102 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
103 | //http://iquilezles.org/www/articles/smin/smin.htm
104 | vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. ); }
105 |
106 | //utils
107 |
108 |
109 | //http://www.pouet.net/topic.php?post=367360
110 | const vec3 pa = vec3(1., 57., 21.);
111 | const vec4 pb = vec4(0., 57., 21., 78.);
112 | float perlin(vec3 p) {
113 | vec3 i = floor(p);
114 | vec4 a = dot( i, pa ) + pb;
115 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
116 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
117 | a.xy = mix(a.xz, a.yw, f.y);
118 | return mix(a.x, a.y, f.z);
119 | }
120 |
121 | /////////////////////////////////////////////////////////////////////////
122 |
123 | // STOP ! ! !
124 |
125 | // HAMMER TIME !
126 |
127 | /////////////////////////////////////////////////////////////////////////
128 |
129 |
130 | const int steps = 50;
131 | const int shadowSteps = 4;
132 | const int ambienOcclusionSteps = 3;
133 | const float PI = 3.14159;
134 | vec2 field( vec3 position )
135 | {
136 |
137 |
138 | //position
139 | vec3 zero = vec3(0.);
140 |
141 | //rotation
142 | vec4 quat = vec4( 1., sin( time ) *.1 , 0., time * .2 );
143 |
144 | //noise
145 | vec3 noise = position * .25;
146 | //noise += time * .1;
147 | float pnoise = 1. + perlin( noise );
148 |
149 | //box
150 | vec2 rb = roundBox( position, vec3(2.0,2.0,2.0), 0.5, zero, quat + vec4( 1., 1., 1., PI / 4. ) );
151 |
152 | //torus
153 | vec2 to0 = torus( position, vec2( 4.0,.15), zero, vec4( 1., 0., 0., 0. + time * .2 ) );
154 | vec2 to1 = torus( position, vec2( 4.0,.15), zero, vec4( 0., 0., 1., PI *.5 + time * .2 ) );
155 |
156 | //spheres
157 | vec2 sre = sphere( position, 3.0, zero, quat );
158 | vec2 sce = sphere( position, 1., zero, quat ) + perlin( position + time ) * .25;
159 |
160 | //composition
161 | return smin( sce, smin( to0, smin( to1, subtract( sre, rb ), pnoise ), pnoise ), pnoise);
162 |
163 | }
164 |
165 | /////////////////////////////////////////////////////////////////////////
166 |
167 | // the methods below this need the field function
168 |
169 | /////////////////////////////////////////////////////////////////////////
170 |
171 |
172 | //the actual raymarching from:
173 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
174 |
175 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
176 |
177 | float latest = precis * 2.0;
178 | float dist = 0.0;
179 | float type = -1.0;
180 | vec2 res = vec2(-1.0, -1.0);
181 | for (int i = 0; i < steps; i++) {
182 |
183 | if (latest < precis || dist > maxd) break;
184 |
185 | vec2 result = field( rayOrigin + rayDir * dist );
186 | latest = result.x;
187 | type = result.y;
188 | dist += latest;
189 | }
190 |
191 | if (dist < maxd) { res = vec2(dist, type); }
192 | return res;
193 | }
194 |
195 | //https://github.com/stackgl/glsl-sdf-normal
196 |
197 | vec3 calcNormal(vec3 pos, float eps) {
198 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
199 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
200 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
201 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
202 |
203 | return normalize( v1 * field( pos + v1*eps ).x +
204 | v2 * field( pos + v2*eps ).x +
205 | v3 * field( pos + v3*eps ).x +
206 | v4 * field( pos + v4*eps ).x );
207 | }
208 |
209 | vec3 calcNormal(vec3 pos) {
210 | return calcNormal(pos, 0.002);
211 | }
212 |
213 |
214 | //shadows & AO
215 |
216 | //https://www.shadertoy.com/view/Xds3zN
217 |
218 | float softshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax, in float K )
219 | {
220 | float res = 1.0;
221 | float t = mint;
222 | for( int i=0; itmax ) break;
228 | }
229 | return clamp( res, 0.0, 1.0 );
230 | }
231 |
232 | float calcAO( in vec3 pos, in vec3 nor )
233 | {
234 | float occ = 0.0;
235 | float sca = 1.0;
236 | for( int i=0; i -0.5)
281 | {
282 |
283 | //"world" position
284 | vec3 pos = rayOrigin + rayDirection * collision.x;
285 |
286 | //diffuse color
287 | vec3 col = vec3( .8,.8,.8 );
288 |
289 | //normal vector
290 | vec3 nor = calcNormal( pos );
291 |
292 | //reflection (Spherical Environment Mapping)
293 | vec2 uv = nor.xy / 2. + .5;
294 | vec3 tex = texture2D( map, uv ).rgb;
295 | col += tex * .1;
296 |
297 | vec3 lig0 = normalize( vec3(-0.5, 0.75, -0.5) );
298 | vec3 light0 = max( 0.0, dot( lig0, nor) ) * color0;
299 |
300 | vec3 lig1 = normalize( vec3( 0.5, -0.75, 0.5) );
301 | vec3 light1 = max( 0.0, dot( lig1, nor) ) * color1;
302 |
303 | //AO : usually too strong
304 | float occ = calcAO( pos, nor );
305 |
306 | //shadows ...?
307 | //float sha = softshadow( pos, lig0, .025, 2.5, 2. );
308 |
309 | float dep = ( ( collision.x + .5 ) / ( maxDist * .5 ) );
310 | gl_FragColor = vec4( ( col + light0 + light1 ) * occ * dep, 1. );
311 |
312 | }
313 |
314 | }
--------------------------------------------------------------------------------
/glsl/halibut.glsl:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform float fov;
4 | uniform vec3 camera;
5 | uniform vec3 target;
6 | uniform float raymarchMaximumDistance;
7 | uniform float raymarchPrecision;
8 | uniform sampler2D map;
9 |
10 | /////////////////////////////////////////////////////////////////////////
11 |
12 | mat3 rotationMatrix3(vec3 axis, float angle)
13 | {
14 | axis = normalize(axis);
15 | float s = sin(angle);
16 | float c = cos(angle);
17 | float oc = 1.0 - c;
18 |
19 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
20 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
21 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
22 | }
23 |
24 | vec3 getRay(vec3 dir, vec2 pos)
25 | {
26 | pos = pos - 0.5;
27 | pos.x *= resolution.x/resolution.y;
28 |
29 | dir = normalize(dir);
30 | vec3 right = normalize(cross(vec3(0.,1.,0.),dir));
31 | vec3 up = normalize(cross(dir,right));
32 |
33 | return dir + right*pos.x + up*pos.y;
34 | }
35 |
36 | /////////////////////////////////////////////////////////////////////////
37 |
38 | //primitives
39 |
40 | vec2 box(vec3 p, vec3 size, float corner, vec3 pos ) { return vec2( length( max( abs( p-pos )-size, 0.0 ) )-corner,1.); }
41 |
42 | vec2 plane( vec3 p , vec3 n) { return vec2( dot(p, n), 1. ); }
43 | vec2 plane( vec3 p , vec4 n) { return vec2( dot(p, n.xyz) - n.w, 1. ); }
44 |
45 | //operations
46 |
47 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
48 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
49 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
50 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
51 | //http://iquilezles.org/www/articles/smin/smin.htm
52 | vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. ); }
53 |
54 | //utils
55 |
56 | vec3 repeat( vec3 p, vec3 r ) { return mod( p, r ) - .5 * r; }
57 |
58 | float hash(in float n)
59 | {
60 | return fract(sin(n)*43758.5453123);
61 | }
62 |
63 | float noise(in vec2 x)
64 | {
65 | vec2 p = floor(x);
66 | vec2 f = fract(x);
67 | f = f*f*(3.0-2.0*f);
68 | float n = p.x + p.y*57.0;
69 | float res = mix(mix( hash(n+ 0.0), hash(n+ 1.0),f.x),
70 | mix( hash(n+ 57.0), hash(n+ 58.0),f.x),f.y);
71 | return res;
72 | }
73 |
74 | /////////////////////////////////////////////////////////////////////////
75 |
76 | // STOP ! ! !
77 |
78 | // HAMMER TIME !
79 |
80 | /////////////////////////////////////////////////////////////////////////
81 |
82 |
83 | const int raymarchSteps = 30;
84 |
85 | const int shadowSteps = 4;
86 | const int ambienOcclusionSteps = 3;
87 | #define PI 3.14159
88 | float sdSphere( vec3 p, float s )
89 | {
90 | return length(p)-s;
91 | }
92 | vec2 field( vec3 position )
93 | {
94 |
95 | vec3 r = vec3( 3., 0., 3. );
96 | vec3 p = repeat( position, r );
97 |
98 | position.xz += time *.5;
99 | float n = noise( ( .75 * position.xz / r.xz ) );
100 |
101 | float s = max( .5, n * 1.125 );
102 | float h = n * 5.;
103 |
104 | vec2 pl = plane( position, vec4( 0.,1.,0., h * .9 ) );
105 | vec2 rb = box( p, vec3( s, h, s ), .85 + ( .5+sin( time + n )*.5 ) * .1, vec3(0.) );
106 |
107 | vec2 _out = smin( rb, pl, .5 );
108 | _out.y = n;
109 | return _out;
110 |
111 | }
112 |
113 | /////////////////////////////////////////////////////////////////////////
114 |
115 | // the methods below this need the field function
116 |
117 | /////////////////////////////////////////////////////////////////////////
118 |
119 |
120 | //the actual raymarching from:
121 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
122 |
123 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
124 |
125 | float latest = precis * 2.0;
126 | float dist = 0.0;
127 | float type = -1.0;
128 | for (int i = 0; i < raymarchSteps; i++) {
129 |
130 |
131 | vec2 result = field( rayOrigin + rayDir * dist );
132 | if( result.x > precis ) result.x *= .3;
133 | latest = result.x;
134 | dist += latest;
135 | type = result.y;
136 | if (latest < precis || dist > maxd) break;
137 | }
138 |
139 | vec2 res = vec2(-1.0, -1.0 );
140 | if (dist < maxd) { res = vec2( dist, type ); }
141 | return res;
142 |
143 | }
144 |
145 |
146 | //https://github.com/stackgl/glsl-sdf-normal
147 |
148 | vec3 calcNormal(vec3 pos, float eps) {
149 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
150 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
151 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
152 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
153 |
154 | return normalize( v1 * field( pos + v1*eps ).x +
155 | v2 * field( pos + v2*eps ).x +
156 | v3 * field( pos + v3*eps ).x +
157 | v4 * field( pos + v4*eps ).x );
158 | }
159 |
160 | vec3 calcNormal(vec3 pos) {
161 | return calcNormal(pos, 0.002);
162 | }
163 |
164 | vec4 rimlight( vec3 pos, vec3 nor )
165 | {
166 | vec3 v = normalize(-pos);
167 | float vdn = 1.0 - max(dot(v, nor), 0.0);
168 | return vec4( vec3( smoothstep(0., 1.0, vdn) ), 1.);
169 | }
170 |
171 | vec4 shading( vec3 pos, vec3 norm, vec3 rd, vec3 lightDir, vec3 lightColour, vec3 diffuse )
172 | {
173 |
174 | float specularHardness = 128.;
175 | float specular = 4.;
176 | float ambientFactor = 0.0005;
177 |
178 | vec3 light = lightColour * max(0.0, dot(norm, lightDir));
179 |
180 | vec3 heading = normalize(-rd + lightDir);
181 |
182 | float spec = pow(max(0.0, dot( heading, norm )), specularHardness) * specular;
183 |
184 | light = (diffuse * light) + ( spec * lightColour);
185 |
186 | return vec4(light, 1.0);
187 | }
188 |
189 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
190 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
191 | vec3 ww = normalize(target - origin);
192 | vec3 uu = normalize(cross(ww, rr));
193 | vec3 vv = normalize(cross(uu, ww));
194 | return mat3(uu, vv, ww);
195 | }
196 |
197 | void main() {
198 |
199 | vec2 p = gl_FragCoord.xy / resolution.xy;
200 | vec3 rd = normalize( getRay( target-camera, p ) );
201 |
202 | vec2 collision = raymarching( camera, rd, raymarchMaximumDistance, raymarchPrecision );
203 |
204 |
205 | gl_FragColor = vec4( vec3( .25,.25,.5), 1. );
206 |
207 | vec3 color = vec3(0.0, 0.2, 0.8); //blue
208 | if ( collision.x > -0.5 )
209 | {
210 |
211 | //"world" position
212 | vec3 pos = camera + rd * collision.x;
213 |
214 | //normal vector
215 | vec3 nor = calcNormal( pos );
216 |
217 | //diffuse color
218 | vec3 dif = vec3( collision.y );
219 |
220 | //reflection (Spherical Environment Mapping)
221 | vec3 tex = texture2D( map, ( nor * calcLookAtMatrix( pos, camera,0. ) ).xy / 2. + .5 ).rgb;
222 | dif += tex * .5;
223 |
224 | vec3 lig = normalize( camera ) + vec3(-0.5, 0.75, -0.5) ;
225 |
226 | float depth = ( 1. / log( collision.x ) );
227 | gl_FragColor = vec4( collision.y ) + shading( pos, nor, rd, lig, color, dif ) * 1.5 * rimlight( pos, nor ) * depth;
228 |
229 | }
230 | }
--------------------------------------------------------------------------------
/glsl/hulkbuster.glsl:
--------------------------------------------------------------------------------
1 | uniform vec2 resolution;
2 | uniform float time;
3 | uniform float fov;
4 | uniform vec3 camera;
5 | uniform vec3 target;
6 | uniform float raymarchMaximumDistance;
7 | uniform float raymarchPrecision;
8 | uniform sampler2D map;
9 |
10 | /////////////////////////////////////////////////////////////////////////
11 |
12 | mat3 rotationMatrix3(vec3 axis, float angle)
13 | {
14 | axis = normalize(axis);
15 | float s = sin(angle);
16 | float c = cos(angle);
17 | float oc = 1.0 - c;
18 |
19 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
20 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
21 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
22 | }
23 |
24 | vec3 getRay(vec3 dir, vec2 pos)
25 | {
26 | pos = pos - 0.5;
27 | pos.x *= resolution.x/resolution.y;
28 |
29 | dir = normalize(dir);
30 | vec3 right = normalize(cross(vec3(0.,1.,0.),dir));
31 | vec3 up = normalize(cross(dir,right));
32 |
33 | return dir + right*pos.x + up*pos.y;
34 | }
35 |
36 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
37 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
38 | vec3 ww = normalize(target - origin);
39 | vec3 uu = normalize(cross(ww, rr));
40 | vec3 vv = normalize(cross(uu, ww));
41 | return mat3(uu, vv, ww);
42 | }
43 | /////////////////////////////////////////////////////////////////////////
44 |
45 | //primitives
46 |
47 | float voronoiDistribution( in vec3 p )
48 | {
49 | vec3 i = floor(p + dot(p, vec3(0.333333)) ); p -= i - dot(i, vec3(0.166666)) ;
50 | vec3 i1 = step(0., p-p.yzx), i2 = max(i1, 1.0-i1.zxy); i1 = min(i1, 1.0-i1.zxy);
51 | vec3 p1 = p - i1 + 0.166666, p2 = p - i2 + 0.333333, p3 = p - 0.5;
52 | vec3 rnd = vec3(7, 157, 113); // I use this combination to pay homage to Shadertoy.com. :)
53 | vec4 v = max(0.5 - vec4(dot(p, p), dot(p1, p1), dot(p2, p2), dot(p3, p3)), 0.);
54 | vec4 d = vec4( dot(i, rnd), dot(i + i1, rnd), dot(i + i2, rnd), dot(i + 1., rnd) );
55 | d = fract(sin(d)*262144.)*v*2.;
56 | v.x = max(d.x, d.y), v.y = max(d.z, d.w), v.z = max(min(d.x, d.y), min(d.z, d.w)), v.w = min(v.x, v.y);
57 | return max(v.x, v.y) - max(v.z, v.w); // Maximum minus second order, for that beveled Voronoi look. Range [0, 1].
58 | }
59 | #define sphere(p, r) length(p)-r
60 |
61 | //operations
62 |
63 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
64 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
65 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
66 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
67 | //http://iquilezles.org/www/articles/smin/smin.htm
68 | float smin( float a, float b, float k ) { float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); return mix( b, a, h ) - k*h*(1.0-h); }
69 | vec2 smin( vec2 a, vec2 b, float k ) { return vec2( smin( a.x, b.x, k ), 1. ); }
70 |
71 | //utils
72 |
73 | float hash(in float n)
74 | {
75 | return fract(sin(n)*43758.5453123);
76 | }
77 | float zigzag( float x, float m )
78 | {
79 | return abs( mod( x, (2.*m) ) -m);
80 | }
81 |
82 | #define PI 3.1415926
83 |
84 | /////////////////////////////////////////////////////////////////////////
85 |
86 | // STOP ! ! !
87 |
88 | // HAMMER TIME !
89 |
90 | /////////////////////////////////////////////////////////////////////////
91 |
92 |
93 | const int raymarchSteps = 100;
94 | vec2 field( vec3 position )
95 | {
96 |
97 | float e = sin(time*.5) * .5 + .5;
98 | float c = cos(time*.1) * .5 + .5;
99 |
100 | float off0 = zigzag( position.x, .25-c*.1 )+ zigzag( position.x, .15 );
101 | float off1 = zigzag( position.z, .12 )- zigzag( position.z, .35-c*.1 );
102 |
103 | float r = 31.5;
104 | vec3 plp = position;
105 | plp.y += r;
106 | vec2 pl = smin( vec2( sphere( plp, r + 1. )-off0, 1. ),
107 | vec2( sphere( plp, r + 1. )+off1, 1. ), e );
108 |
109 | plp.y -= r + .75;
110 | vec2 sp = vec2( sphere( plp, 2. + abs( c * 2. ) ), 1. );
111 | sp.x += zigzag( sp.x, .25-e*.1 );
112 |
113 | vec2 si = vec2( sp.x - voronoiDistribution( position*.75 ), 1. );
114 | vec2 res = unionAB( pl, smin( sp, si, .1 ));
115 |
116 | //color switch
117 | res.y = 1.;
118 | if( res.x > sp.x - raymarchPrecision )res.y = 0.;
119 | if( res.x > si.x - raymarchPrecision )res.y = 0.;
120 | if( res.x > pl.x - raymarchPrecision )res.y = 0.5;
121 |
122 | return res;
123 | }
124 |
125 | /////////////////////////////////////////////////////////////////////////
126 |
127 | // the methods below this need the field function
128 |
129 | /////////////////////////////////////////////////////////////////////////
130 |
131 |
132 | //the actual raymarching from:
133 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
134 |
135 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
136 |
137 | float latest = precis * 2.0;
138 | float dist = 0.0;
139 | float type = 0.0;
140 | for (int i = 0; i < raymarchSteps; i++) {
141 |
142 | if (latest < precis || dist > maxd ) break;
143 |
144 | vec2 result = field( rayOrigin + rayDir * dist );
145 | if( result.x > precis ) result.x *= .3;
146 | latest = result.x;
147 | dist += latest;
148 | type = result.y;
149 |
150 | }
151 | vec2 res = vec2(-1.0, -1.0 );
152 | if (dist < maxd) { res = vec2( dist, type ); }
153 | return res;
154 |
155 | }
156 |
157 |
158 | //https://github.com/stackgl/glsl-sdf-normal
159 |
160 | vec3 calcNormal(vec3 pos, float eps) {
161 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
162 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
163 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
164 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
165 |
166 | return normalize( v1 * field( pos + v1*eps ).x +
167 | v2 * field( pos + v2*eps ).x +
168 | v3 * field( pos + v3*eps ).x +
169 | v4 * field( pos + v4*eps ).x );
170 | }
171 |
172 | vec3 calcNormal(vec3 pos) {
173 | return calcNormal(pos, 0.002);
174 | }
175 |
176 | vec4 shading( vec3 pos, vec3 norm, vec3 rd, vec3 lightDir, vec3 lightColour, vec3 diffuse )
177 | {
178 | float specularHardness = 32.;
179 | float specular = 2.;
180 |
181 | vec3 light = lightColour * max(0.0, dot(norm, lightDir));
182 |
183 | vec3 heading = normalize(-rd + lightDir);
184 |
185 | float spec = pow(max(0.0, dot( heading, norm )), specularHardness) * specular;
186 |
187 | light = (diffuse * light) + ( spec * lightColour);
188 |
189 | //normal face camera (constant environment lighting)
190 | norm *= calcLookAtMatrix(pos,camera,0.);
191 | light += texture2D( map, norm.xy / 2. + .5 ).rgb * .2;
192 |
193 | return vec4(light, 1.0);
194 | }
195 |
196 | void main() {
197 |
198 | vec2 p = gl_FragCoord.xy / resolution.xy;
199 | //background
200 | gl_FragColor = vec4( mix( vec3( .1 ), vec3( 1. ), vec3( 1.-p.y ) ) , 1. );
201 |
202 | vec3 red = vec3( .9, 0.1, 0.05);
203 | vec3 dark = vec3( .5, 0.1, 0.15);
204 | vec3 color = vec3( 0.9, 0.65, 0.05);
205 |
206 | vec3 rd = normalize( getRay( target-camera, p ) );
207 | vec2 collision = raymarching( camera, rd, raymarchMaximumDistance, raymarchPrecision );
208 | if ( collision.x > -0.5 )
209 | {
210 | vec3 pos = camera + rd * collision.x;
211 | vec3 nor = calcNormal( pos );
212 | vec3 lightDir = normalize( vec3( 1.,1.,0. ) );
213 | vec3 dif = vec3( 1. );//collision.y );
214 |
215 | float depth = ( 1. / log( collision.x ) );
216 | vec4 s0 = shading( pos,nor, rd,lightDir, red , dif * depth );
217 | vec4 s1 = shading( pos,nor, rd,-lightDir, dark, dif);
218 |
219 | gl_FragColor = ( s0 * .5 + s1 * .5 );
220 |
221 | if( collision.y == 1. )gl_FragColor = shading( pos,nor, rd, normalize( camera + vec3( 0.,2.,0. ) ), color, dif * depth );
222 |
223 | if( collision.y == .5 )gl_FragColor = shading( pos,nor, rd, normalize( camera + vec3( 0.,2.,0. ) ), vec3(.1), dif * depth );
224 | }
225 | }
--------------------------------------------------------------------------------
/glsl/interactive.glsl:
--------------------------------------------------------------------------------
1 |
2 | uniform vec2 resolution;
3 | uniform float time;
4 | uniform float fov;
5 | uniform float raymarchMaximumDistance;
6 | uniform float raymarchPrecision;
7 | uniform vec3 camera;
8 | uniform vec3 target;
9 |
10 | uniform vec3 color0;
11 | uniform vec3 color1;
12 |
13 | uniform vec3 light0;
14 | uniform vec3 light1;
15 |
16 |
17 | //uses most of the StackGL methods
18 | //https://github.com/stackgl
19 |
20 | //https://github.com/hughsk/glsl-square-frame
21 |
22 | vec2 squareFrame(vec2 screenSize) {
23 | vec2 position = 2.0 * (gl_FragCoord.xy / screenSize.xy) - 1.0;
24 | position.x *= screenSize.x / screenSize.y;
25 | return position;
26 | }
27 | vec2 squareFrame(vec2 screenSize, vec2 coord) {
28 | vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
29 | position.x *= screenSize.x / screenSize.y;
30 | return position;
31 | }
32 |
33 | //https://github.com/stackgl/glsl-look-at/blob/gh-pages/index.glsl
34 |
35 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
36 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
37 | vec3 ww = normalize(target - origin);
38 | vec3 uu = normalize(cross(ww, rr));
39 | vec3 vv = normalize(cross(uu, ww));
40 | return mat3(uu, vv, ww);
41 | }
42 |
43 | //https://github.com/stackgl/glsl-camera-ray
44 |
45 | vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) {
46 | return normalize(camMat * vec3(screenPos, lensLength));
47 | }
48 | vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) {
49 | mat3 camMat = calcLookAtMatrix(origin, target, 0.0);
50 | return getRay(camMat, screenPos, lensLength);
51 | }
52 |
53 | /////////////////////////////////////////////////////////////////////////
54 |
55 | mat3 rotationMatrix3(vec3 axis, float angle)
56 | {
57 | axis = normalize(axis);
58 | float s = sin(angle);
59 | float c = cos(angle);
60 | float oc = 1.0 - c;
61 |
62 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
63 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
64 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
65 | }
66 |
67 | /////////////////////////////////////////////////////////////////////////
68 |
69 | //primitives
70 |
71 | vec2 sphere( vec3 p, float radius, vec3 pos , vec4 quat)
72 | {
73 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
74 | float d = length( ( p * transform )-pos ) - radius;
75 | return vec2(d,0.);
76 | }
77 |
78 | vec2 roundBox(vec3 p, vec3 size, float corner, vec3 pos, vec4 quat )
79 | {
80 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
81 | return vec2( length( max( abs( ( p-pos ) * transform )-size, 0.0 ) )-corner,1.);
82 | }
83 |
84 | vec2 torus( vec3 p, vec2 radii, vec3 pos, vec4 quat )
85 | {
86 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
87 | vec3 pp = ( p - pos ) * transform;
88 | float d = length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y;
89 | return vec2(d,1.);
90 | }
91 |
92 | vec2 cone( vec3 p, vec2 c, vec3 pos, vec4 quat )
93 | {
94 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
95 | vec3 pp = ( p - pos ) * transform;
96 | float q = length(pp.xy);
97 | return vec2( dot(c,vec2(q,pp.z)), 1. );
98 | }
99 |
100 | //http://www.pouet.net/topic.php?post=365312
101 | vec2 cylinder( vec3 p, float h, float r, vec3 pos, vec4 quat ) {
102 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
103 | vec3 pp = (p - pos ) * transform;
104 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
105 | }
106 |
107 |
108 | //operations
109 |
110 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
111 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
112 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
113 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
114 | //http://iquilezles.org/www/articles/smin/smin.htm
115 | vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. ); }
116 |
117 | //utils
118 |
119 | vec3 twist( vec3 pos, float amount )
120 | {
121 | vec3 p = normalize( pos );
122 | float c = cos(amount * p.y);
123 | float s = sin(amount * p.y);
124 | mat2 m = mat2(c,-s,s,c);
125 | vec3 q = vec3(m*pos.xz,pos.y);
126 | return q;
127 | }
128 | vec3 repeat( vec3 p, vec3 r )
129 | {
130 | return mod( p, r ) - .5 * r;
131 | }
132 |
133 | //http://www.pouet.net/topic.php?post=367360
134 | const vec3 pa = vec3(1., 57., 21.);
135 | const vec4 pb = vec4(0., 57., 21., 78.);
136 | float perlin(vec3 p) {
137 | vec3 i = floor(p);
138 | vec4 a = dot( i, pa ) + pb;
139 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
140 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
141 | a.xy = mix(a.xz, a.yw, f.y);
142 | return mix(a.x, a.y, f.z);
143 | }
144 |
145 | /////////////////////////////////////////////////////////////////////////
146 |
147 | // STOP ! ! !
148 |
149 | // HAMMER TIME !
150 |
151 | /////////////////////////////////////////////////////////////////////////
152 |
153 |
154 | const int raymarchSteps = 50;
155 |
156 | const int shadowSteps = 4;
157 | const int ambienOcclusionSteps = 3;
158 | const float PI = 3.14159;
159 | vec2 field( vec3 position )
160 | {
161 | //repetition
162 | vec3 r = vec3(9.,0.,9.);
163 | //position
164 | vec3 zero = vec3(0.);
165 |
166 | //rotation
167 | vec4 quat = vec4( 1., sin( time ) *.1 , 0., time * .2 );
168 |
169 | //noise
170 | vec3 noise = position * .25;
171 | //noise += time * .1;
172 | float pnoise = 1. + perlin( noise );
173 |
174 | //box
175 | vec2 rb = roundBox( position, vec3(2.0,2.0,2.0), 0.5, zero, quat + vec4( 1., 1., 1., PI / 4. ) );
176 |
177 | //torus
178 | vec2 to0 = torus( twist( position, PI * sin( time ) ), vec2( 4.0,.15), zero, vec4( 1., 0., 0., 0. + time * .2 ) );
179 | vec2 to1 = torus( position, vec2( 4.0,.15), zero, vec4( 0., 0., 1., PI *.5 + time * .2 ) );
180 |
181 | //spheres
182 | vec2 sre = sphere( position, 3.0, zero, quat );
183 | vec2 sce = sphere( position, 1., zero, quat ) + perlin( position + time ) * .25;
184 |
185 | //composition
186 | return smin( sce, smin( to0, smin( to1, subtract( sre, rb ), pnoise ), pnoise ), pnoise);
187 | }
188 |
189 | /////////////////////////////////////////////////////////////////////////
190 |
191 | // the methods below this need the field function
192 |
193 | /////////////////////////////////////////////////////////////////////////
194 |
195 |
196 | //the actual raymarching from:
197 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
198 |
199 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
200 |
201 | float latest = precis * 2.0;
202 | float dist = 0.0;
203 | float type = -1.0;
204 | for (int i = 0; i < raymarchSteps; i++) {
205 |
206 | if (latest < precis || dist > maxd) break;
207 |
208 | vec2 result = field( rayOrigin + rayDir * dist );
209 | latest = result.x;
210 | dist += latest;
211 |
212 | type = result.y;
213 | }
214 |
215 | vec2 res = vec2(-1.0, -1.0 );
216 | if (dist < maxd) { res = vec2( dist, type ); }
217 | return res;
218 |
219 | }
220 |
221 | //https://github.com/stackgl/glsl-sdf-normal
222 |
223 | vec3 calcNormal(vec3 pos, float eps) {
224 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
225 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
226 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
227 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
228 |
229 | return normalize( v1 * field( pos + v1*eps ).x +
230 | v2 * field( pos + v2*eps ).x +
231 | v3 * field( pos + v3*eps ).x +
232 | v4 * field( pos + v4*eps ).x );
233 | }
234 |
235 | vec3 calcNormal(vec3 pos) {
236 | return calcNormal(pos, 0.002);
237 | }
238 |
239 |
240 | //shadows & AO
241 |
242 | //https://www.shadertoy.com/view/Xds3zN
243 |
244 | float softshadow( in vec3 ro, in vec3 rd, in float mint, in float tmax, in float K )
245 | {
246 | float res = 1.0;
247 | float t = mint;
248 | for( int i=0; itmax ) break;
254 | }
255 | return clamp( res, 0.0, 1.0 );
256 | }
257 |
258 | float calcAO( in vec3 pos, in vec3 nor )
259 | {
260 | float occ = 0.0;
261 | float sca = 1.0;
262 | for( int i=0; i -0.5)
293 | {
294 |
295 | //"world" position
296 | vec3 pos = camera + rayDirection * collision.x;
297 |
298 | //diffuse color
299 | vec3 col = vec3( collision.y );
300 |
301 | //normal vector
302 | vec3 nor = calcNormal( pos );
303 |
304 | vec3 lig0 = normalize( light0 );
305 | vec3 lightColor0 = max( 0.0, dot( lig0, nor) ) * color0;
306 |
307 | vec3 lightColor1 = max( 0.0, dot( normalize( light1 ), nor) ) * color1;
308 |
309 | float depth = 1./ log( collision.x );
310 |
311 | gl_FragColor = vec4( ( col + lightColor0 + lightColor1 ) * depth, 1. );
312 |
313 | }
314 |
315 | }
--------------------------------------------------------------------------------
/glsl/noise_bulb.glsl:
--------------------------------------------------------------------------------
1 |
2 | uniform vec2 resolution;
3 | uniform float time;
4 | uniform sampler2D map;
5 |
6 | //uses most of the StackGL methods
7 | //https://github.com/stackgl
8 |
9 | //https://github.com/hughsk/glsl-square-frame
10 |
11 | vec2 squareFrame(vec2 screenSize) {
12 | vec2 position = 2.0 * (gl_FragCoord.xy / screenSize.xy) - 1.0;
13 | position.x *= screenSize.x / screenSize.y;
14 | return position;
15 | }
16 | vec2 squareFrame(vec2 screenSize, vec2 coord) {
17 | vec2 position = 2.0 * (coord.xy / screenSize.xy) - 1.0;
18 | position.x *= screenSize.x / screenSize.y;
19 | return position;
20 | }
21 |
22 | //https://github.com/stackgl/glsl-look-at/blob/gh-pages/index.glsl
23 |
24 | mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
25 | vec3 rr = vec3(sin(roll), cos(roll), 0.0);
26 | vec3 ww = normalize(target - origin);
27 | vec3 uu = normalize(cross(ww, rr));
28 | vec3 vv = normalize(cross(uu, ww));
29 | return mat3(uu, vv, ww);
30 | }
31 |
32 | //https://github.com/stackgl/glsl-camera-ray
33 |
34 | vec3 getRay(mat3 camMat, vec2 screenPos, float lensLength) {
35 | return normalize(camMat * vec3(screenPos, lensLength));
36 | }
37 | vec3 getRay(vec3 origin, vec3 target, vec2 screenPos, float lensLength) {
38 | mat3 camMat = calcLookAtMatrix(origin, target, 0.0);
39 | return getRay(camMat, screenPos, lensLength);
40 | }
41 |
42 | /////////////////////////////////////////////////////////////////////////
43 |
44 | mat3 rotationMatrix3(vec3 axis, float angle)
45 | {
46 | axis = normalize(axis);
47 | float s = sin(angle);
48 | float c = cos(angle);
49 | float oc = 1.0 - c;
50 |
51 | return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
52 | oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
53 | oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c );
54 | }
55 |
56 | /////////////////////////////////////////////////////////////////////////
57 |
58 | //primitives
59 |
60 | vec2 sphere( vec3 p, float radius, vec3 pos , vec4 quat)
61 | {
62 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
63 | float d = length( ( p * transform )-pos ) - radius;
64 | return vec2(d,1);
65 | }
66 | vec2 sphere( vec3 p, float radius, vec3 pos )
67 | {
68 | float d = length( ( p-pos) ) - radius;
69 | return vec2(d,1);
70 | }
71 | vec2 sphere( vec3 p, float radius )
72 | {
73 | float d = length( p ) - radius;
74 | return vec2(d,1);
75 | }
76 |
77 |
78 | vec2 roundBox(vec3 p, vec3 size, float corner, vec3 pos, vec4 quat )
79 | {
80 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
81 | return vec2( length( max( abs( ( p-pos ) * transform )-size, 0.0 ) )-corner,1.);
82 | }
83 | vec2 roundBox(vec3 p, vec3 size, float corner, vec3 pos )
84 | {
85 | return vec2( length( max( abs( p-pos )-size, 0.0 ) )-corner,1.);
86 | }
87 |
88 |
89 | vec2 torus( vec3 p, vec2 radii, vec3 pos, vec4 quat )
90 | {
91 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
92 | vec3 pp = ( p - pos ) * transform;
93 | float d = length( vec2( length( pp.xz ) - radii.x, pp.y ) ) - radii.y;
94 | return vec2(d,1.);
95 | }
96 |
97 | vec2 cone( vec3 p, vec2 c, vec3 pos, vec4 quat )
98 | {
99 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
100 | vec3 pp = ( p - pos ) * transform;
101 | float q = length(pp.xy);
102 | return vec2( dot(c,vec2(q,pp.z)), 1. );
103 | }
104 |
105 | //http://www.pouet.net/topic.php?post=365312
106 | vec2 cylinder( vec3 p, float h, float r, vec3 pos, vec4 quat ) {
107 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
108 | vec3 pp = (p - pos ) * transform;
109 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
110 | }
111 | vec2 cylinder( vec3 p, float h, float r, vec3 pos ) {
112 | vec3 pp = (p - pos );
113 | return vec2( max(length(pp.xz)-r, abs(pp.y)-h),1. );
114 | }
115 | vec2 cylinder( vec3 p, float h, float r ) {
116 | return vec2( max(length(p.xz)-r, abs(p.y)-h),1. );
117 | }
118 |
119 |
120 |
121 |
122 | //operations
123 |
124 | vec2 unionAB(vec2 a, vec2 b){return vec2(min(a.x, b.x),1.);}
125 | vec2 intersectionAB(vec2 a, vec2 b){return vec2(max(a.x, b.x),1.);}
126 | vec2 blendAB( vec2 a, vec2 b, float t ){ return vec2(mix(a.x, b.x, t ),1.);}
127 | vec2 subtract(vec2 a, vec2 b){ return vec2(max(-a.x, b.x),1.); }
128 | //http://iquilezles.org/www/articles/smin/smin.htm
129 | vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5+0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), 1. ); }
130 |
131 | //utils
132 |
133 |
134 | //http://www.pouet.net/topic.php?post=367360
135 | const vec3 pa = vec3(1., 57., 21.);
136 | const vec4 pb = vec4(0., 57., 21., 78.);
137 | float perlin(vec3 pos, vec4 quat ) {
138 | mat3 transform = rotationMatrix3( quat.xyz, quat.w );
139 | vec3 p = pos * transform;
140 | vec3 i = floor(p);
141 | vec4 a = dot( i, pa ) + pb;
142 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
143 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
144 | a.xy = mix(a.xz, a.yw, f.y);
145 | return mix(a.x, a.y, f.z);
146 | }
147 | float perlin(vec3 p ) {
148 | vec3 i = floor(p);
149 | vec4 a = dot( i, pa ) + pb;
150 | vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
151 | a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
152 | a.xy = mix(a.xz, a.yw, f.y);
153 | return mix(a.x, a.y, f.z);
154 | }
155 |
156 |
157 |
158 | /////////////////////////////////////////////////////////////////////////
159 |
160 | // STOP ! ! !
161 |
162 | // HAMMER TIME !
163 |
164 | /////////////////////////////////////////////////////////////////////////
165 |
166 |
167 | const int steps = 80;
168 | const int shadowSteps = 4;
169 | const int ambienOcclusionSteps = 3;
170 | const float PI = 3.14159;
171 | vec2 field( vec3 position )
172 | {
173 |
174 | vec2 sph = sphere( position, 5. );
175 |
176 | vec3 nPos = position * .45;
177 | nPos.y -= time * .05;
178 |
179 | vec4 quat = vec4( 0., 1., 0., -time * .1 );
180 | vec2 noi = vec2( max( -.5, .5-abs( perlin( nPos, quat ) ) ), 0. );
181 |
182 | vec2 cyl = cylinder( position, 10.,4., vec3( 0.,-12.5,0.) );
183 |
184 | return intersectionAB( smin( sph, cyl, .99 ), noi );
185 |
186 | }
187 |
188 | /////////////////////////////////////////////////////////////////////////
189 |
190 | // the methods below this need the field function
191 |
192 | /////////////////////////////////////////////////////////////////////////
193 |
194 |
195 | //the actual raymarching from:
196 | //https://github.com/stackgl/glsl-raytrace/blob/master/index.glsl
197 |
198 | vec2 raymarching( vec3 rayOrigin, vec3 rayDir, float maxd, float precis ) {
199 |
200 | float latest = precis * 2.0;
201 | float dist = 0.0;
202 | float type = -1.0;
203 | vec2 res = vec2(-1.0, -1.0);
204 | for (int i = 0; i < steps; i++) {
205 |
206 | if (latest < precis || dist > maxd) break;
207 |
208 | vec2 result = field( rayOrigin + rayDir * dist );
209 | latest = result.x;
210 | type = result.y;
211 | dist += latest;
212 | }
213 |
214 | if (dist < maxd) { res = vec2(dist, type); }
215 | return res;
216 | }
217 |
218 | //https://github.com/stackgl/glsl-sdf-normal
219 |
220 | vec3 calcNormal(vec3 pos, float eps) {
221 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
222 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
223 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
224 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
225 |
226 | return normalize( v1 * field( pos + v1*eps ).x +
227 | v2 * field( pos + v2*eps ).x +
228 | v3 * field( pos + v3*eps ).x +
229 | v4 * field( pos + v4*eps ).x );
230 | }
231 |
232 | vec3 calcNormal(vec3 pos) {
233 | return calcNormal(pos, 0.002);
234 | }
235 |
236 | vec3 rimlight( vec3 pos, vec3 nor )
237 | {
238 | vec3 v = normalize(-pos);
239 | float vdn = 1.0 - max(dot(v, nor), 0.0);
240 | return vec3(smoothstep(0., 1.0, vdn));
241 | }
242 |
243 |
244 |
245 | void main() {
246 |
247 |
248 | vec3 color = vec3( 0.4, 0.8, 0.99 ); //blue
249 | vec2 screenPos = squareFrame( resolution );
250 | float col = pow( max( 0., 1.- length( screenPos - vec2( 0.,.35 ) ) ), 1.5 );
251 | gl_FragColor = vec4( vec3( col ), 1. );
252 |
253 |
254 | float cameraAngle = 0.2 * time;
255 | float cameraRadius = 20.+sin( time*.1);
256 |
257 | float lensLength = 2.5;
258 | float y = cameraRadius * .38 + ( cameraRadius * .32 * sin(cameraAngle) );
259 | vec3 rayOrigin = vec3( cameraRadius * sin(cameraAngle), y, cameraRadius * cos(cameraAngle));
260 | vec3 rayTarget = vec3(0, 0, 0);
261 | vec3 rayDirection = getRay(rayOrigin, rayTarget, screenPos, lensLength);
262 |
263 |
264 | float maxDist = 50.;
265 | vec2 collision = raymarching( rayOrigin, rayDirection, maxDist, .01 );
266 |
267 | if ( collision.x > -0.5)
268 | {
269 |
270 | //"world" position
271 | vec3 pos = rayOrigin + rayDirection * collision.x;
272 |
273 | //diffuse color
274 | vec3 col = vec3( .8 );
275 |
276 | //normal vector
277 | vec3 nor = calcNormal( pos );
278 |
279 | vec3 lig1 = normalize( vec3( 0.0, 5.0, -0.0) );
280 | vec3 light1 = max( 0.0, dot( lig1, nor) ) * color;
281 |
282 | vec3 rim1 = rimlight( pos, -lig1 );
283 | vec3 rim2 = rimlight( lig1, -nor ) * .25;
284 |
285 | float dep = ( ( collision.x + .5 ) / ( maxDist * .5 ) );
286 | gl_FragColor = vec4( ( col + rim2 + light1 * rim1 ) - rim1 * dep, 1. );
287 |
288 | }
289 |
290 |
291 | }
--------------------------------------------------------------------------------
/glsl/tmp.glsl:
--------------------------------------------------------------------------------
1 | // Created by Stephane Cuillerdier - Aiekick/2015
2 | // License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
3 |
4 | precision highp float;
5 | uniform float time;
6 | uniform vec2 resolution;
7 |
8 | //////2D FUNC TO MODIFY////////////////////
9 | vec3 effect(vec2 v)
10 | {
11 | vec3 col = vec3(0.);
12 |
13 | v/= 1.5;
14 |
15 | float t = time;
16 |
17 | // vars
18 |
19 | const int n = 15;
20 |
21 | vec3 startColor = normalize(vec3(1.,0.,0.));
22 | vec3 endColor = normalize(vec3(1.,1.,0.5));
23 |
24 | float power = 0.5;
25 | float duration = 3.;
26 | //
27 |
28 | float dMax = duration;
29 |
30 | float mb = 0.;
31 | float mbRadius = 0.;
32 | float sum = 0.;
33 | for(int i=0;itmax ) break;
99 | }
100 | return clamp( res, 0.0, 1.0 );
101 | }
102 |
103 | vec3 calcNormal( in vec3 pos )
104 | {
105 | vec3 eps = vec3( 0.1, 0., 0. );
106 | vec3 nor = vec3(
107 | map(pos+eps.xyy).x - map(pos-eps.xyy).x,
108 | map(pos+eps.yxy).x - map(pos-eps.yxy).x,
109 | map(pos+eps.yyx).x - map(pos-eps.yyx).x );
110 | return normalize(nor);
111 | }
112 |
113 | float calcAO( in vec3 pos, in vec3 nor )
114 | {
115 | float occ = 0.0;
116 | float sca = 1.0;
117 | for( int i=0; i<5; i++ )
118 | {
119 | float hr = 0.01 + 0.12*float(i)/4.0;
120 | vec3 aopos = nor * hr + pos;
121 | float dd = map( aopos ).x;
122 | occ += -(dd-hr)*sca;
123 | sca *= 0.95;
124 | }
125 | return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
126 | }
127 |
128 | ///////////////////////////////////////////
129 | float march(vec3 ro, vec3 rd, float rmPrec, float maxd, float mapPrec)
130 | {
131 | float s = rmPrec;
132 | float d = 0.;
133 | for(int i=0;i<40;i++)
134 | {
135 | if (smaxd) break;
136 | s = map(ro+rd*d).x*mapPrec;
137 | d += s;
138 | }
139 | return d;
140 | }
141 |
142 | ////////MAIN///////////////////////////////
143 | void mainImage( out vec4 fragColor, in vec2 fragCoord )
144 | {
145 |
146 | float cam_a = time; // angle z
147 |
148 | float cam_e = 5.52; // elevation
149 | float cam_d = 1.88; // distance to origin axis
150 |
151 | vec3 camUp=vec3(0,1,0);//Change camere up vector here
152 | vec3 camView=vec3(0,0,0); //Change camere view here
153 | float li = 0.6; // light intensity
154 | float prec = 0.00001; // ray marching precision
155 | float maxd = 50.; // ray marching distance max
156 | float refl_i = 0.45; // reflexion intensity
157 | float refr_a = 0.7; // refraction angle
158 | float refr_i = 0.8; // refraction intensity
159 | float bii = 0.35; // bright init intensity
160 | float marchPrecision = 1.; // ray marching tolerance precision
161 |
162 | vec2 uv = fragCoord.xy / resolution.xy * 2. -1.;
163 | uv.x*=resolution.x/resolution.y;
164 |
165 | vec3 col = vec3(0.);
166 |
167 | vec3 ro = vec3(-sin(cam_a)*cam_d, cam_e+1., cos(cam_a)*cam_d); //
168 | vec3 rov = normalize(camView-ro);
169 | vec3 u = normalize(cross(camUp,rov));
170 | vec3 v = cross(rov,u);
171 | vec3 rd = normalize(rov + uv.x*u + uv.y*v);
172 |
173 | float b = bii;
174 |
175 | float d = march(ro, rd, prec, maxd, marchPrecision);
176 |
177 | if (d 6500.) col.y = 352e5 * pow(Temp,(-3. / 2.)) + 184.;
128 | col.z = 194.18 * log(Temp) - 1448.6;
129 | col = clamp(col, 0., 255.)/255.;
130 | if (Temp < 1000.) col *= Temp/1000.;
131 | return col;
132 | }
133 |
134 | const vec3 RockColor = vec3(.2,.4,.58);
135 | const vec3 DeepSpaceColor = vec3(0,.02,.15);
136 |
137 | void main()
138 | {
139 |
140 | vec4 f = gl_FragColor;
141 | vec2 g = gl_FragCoord.xy;
142 |
143 | vec2 si = resolution.xy;
144 | float t = time;
145 |
146 | float ca = t*.2; // angle z
147 | float ce = 2.; // elevation
148 | float cd = 4.; // distance to origin axis
149 |
150 | vec3 cu=vec3(0,1,0);//Change camere up vector here
151 | vec3 cv=vec3(0,0,0); //Change camere view here
152 | vec2 uv = (g+g-si)/min(si.x, si.y);
153 | vec3 ro = vec3(sin(ca)*cd, ce+1., cos(ca)*cd); //
154 | vec3 rd = cam(uv, ro, cu, cv);
155 |
156 | vec3 d = vec3(0.);
157 | vec3 p = ro+rd*d.x;
158 | vec2 s = vec2(DPrec.y, 0.);
159 | for(int i=0;i<200;i++)
160 | {
161 | if(s.xDPrec.y) break;
162 | s = map(p);
163 | s.x *= (s.x>DPrec.x?RMPrec.x:RMPrec.y);
164 | d.x += s.x;
165 | p = ro+rd*d.x;
166 | }
167 | float alpha = 1.;
168 | if (d.x maxd) break;
224 |
225 | vec2 result = field( rayOrigin + rayDir * dist );
226 | latest = result.x;
227 | dist += latest;
228 | type = result.y;
229 | }
230 |
231 | vec2 res = vec2(-1.0, -1.0 );
232 | if (dist < maxd) { res = vec2( dist, type ); }
233 | return res;
234 |
235 | }
236 |
237 | //https://github.com/stackgl/glsl-sdf-normal
238 |
239 | vec3 calcNormal(vec3 pos, float eps) {
240 | const vec3 v1 = vec3( 1.0,-1.0,-1.0);
241 | const vec3 v2 = vec3(-1.0,-1.0, 1.0);
242 | const vec3 v3 = vec3(-1.0, 1.0,-1.0);
243 | const vec3 v4 = vec3( 1.0, 1.0, 1.0);
244 |
245 | return normalize( v1 * field( pos + v1*eps ).x +
246 | v2 * field( pos + v2*eps ).x +
247 | v3 * field( pos + v3*eps ).x +
248 | v4 * field( pos + v4*eps ).x );
249 | }
250 |
251 | vec3 calcNormal(vec3 pos) {
252 | return calcNormal(pos, 0.002);
253 | }
254 |
255 | vec3 rimlight( vec3 pos, vec3 nor )
256 | {
257 | vec3 v = normalize(-pos);
258 | float vdn = 1.0 - max(dot(v, nor), 0.0);
259 | return vec3(smoothstep(0., 1.0, vdn));
260 | }
261 |
262 | void main() {
263 |
264 | vec2 screenPos = squareFrame( resolution );
265 |
266 | vec3 rayDirection = getRay( camera, target, screenPos, fov );
267 |
268 | vec2 collision = raymarching( camera, rayDirection, raymarchMaximumDistance, raymarchPrecision );
269 |
270 | vec3 col = vec3( 0.85 );
271 |
272 | gl_FragColor = vec4(mix( col, vec3(1.), screenPos.y), 1. );
273 | if ( collision.x > -0.5)
274 | {
275 |
276 | vec3 pos = camera + rayDirection * collision.x;
277 |
278 | vec3 nor = calcNormal( pos,.1 );
279 | vec3 tex = textureCube( cubemap, nor ).rgb;
280 |
281 | col = mix( col, tex, collision.y );
282 |
283 | col = col * rimlight( pos, nor ) + tex * .2;
284 |
285 | gl_FragColor = vec4( col, 1. );
286 | }
287 |
288 | }
--------------------------------------------------------------------------------
/halibut.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/hulkbuster.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/img/colors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/colors.png
--------------------------------------------------------------------------------
/img/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cover.jpg
--------------------------------------------------------------------------------
/img/cubemap/cube03_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_0.png
--------------------------------------------------------------------------------
/img/cubemap/cube03_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_1.png
--------------------------------------------------------------------------------
/img/cubemap/cube03_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_2.png
--------------------------------------------------------------------------------
/img/cubemap/cube03_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_3.png
--------------------------------------------------------------------------------
/img/cubemap/cube03_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_4.png
--------------------------------------------------------------------------------
/img/cubemap/cube03_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/cubemap/cube03_5.png
--------------------------------------------------------------------------------
/img/env.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/env.png
--------------------------------------------------------------------------------
/img/halibut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/halibut.jpg
--------------------------------------------------------------------------------
/img/hulkbuster.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/hulkbuster.jpg
--------------------------------------------------------------------------------
/img/matcap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/matcap.png
--------------------------------------------------------------------------------
/img/noise_bulb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/noise_bulb.jpg
--------------------------------------------------------------------------------
/img/walker.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nicoptere/raymarching-for-THREE/b6954fa8fda6c11f64406b0ee54506ea6223361e/img/walker.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/interactive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/noise_bulb.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
66 |
67 |
--------------------------------------------------------------------------------
/raymarcher.js:
--------------------------------------------------------------------------------
1 | var RayMarcher = function(){
2 |
3 | var tl = new THREE.TextureLoader();
4 | var cl = new THREE.CubeTextureLoader();
5 | var rc = new THREE.Raycaster();
6 | var mouse = new THREE.Vector2();
7 | function RayMarcher( distance, precision ){
8 |
9 | this.distance = distance || 50;
10 | this.precision = precision || 0.01;
11 |
12 | //scene setup
13 |
14 | this.scene = new THREE.Scene();
15 |
16 | this.renderer = new THREE.WebGLRenderer();
17 | this.renderer.setSize( window.innerWidth, window.innerHeight );
18 | this.domElement = this.renderer.domElement;
19 |
20 | //used only to render the scene
21 |
22 | this.renderCamera = new THREE.OrthographicCamera(-1,1,1,-1,1/Math.pow( 2, 53 ),1);
23 |
24 | //geometry setup
25 |
26 | this.geom = new THREE.BufferGeometry();
27 | this.geom.addAttribute( 'position', new THREE.BufferAttribute( new Float32Array([ -1,-1,0, 1,-1,0, 1,1,0, -1, -1, 0, 1, 1, 0, -1, 1, 0]), 3 ) );
28 | this.mesh = new THREE.Mesh( this.geom, null );
29 | this.scene.add( this.mesh );
30 |
31 | //some helpers
32 |
33 | this.camera = new THREE.PerspectiveCamera( 60, 1, 0.1,1 );
34 | this.target = new THREE.Vector3();
35 |
36 | return this;
37 |
38 | }
39 |
40 | function loadFragmentShader( fragmentUrl, callback )
41 | {
42 | this.loaded = false;
43 |
44 | var scope = this;
45 | var req = new XMLHttpRequest();
46 | req.open( "GET", fragmentUrl );
47 | req.onload = function (e) {
48 | scope.setFragmentShader( e.target.responseText, callback );
49 | };
50 | req.send();
51 | return this;
52 | }
53 |
54 | function setFragmentShader( fs, cb ){
55 |
56 | this.startTime = Date.now();
57 | this.mesh.material = this.material = new THREE.ShaderMaterial({
58 |
59 | uniforms :{
60 | resolution:{ type:"v2", value:new THREE.Vector2( this.width, this.height ) },
61 | time:{ type:"f", value:0 },
62 | randomSeed:{ type:"f", value:Math.random() },
63 | fov:{ type:"f", value:45 },
64 | camera:{ type:"v3", value:this.camera.position },
65 | target:{ type:"v3", value:this.target },
66 | raymarchMaximumDistance:{ type:"f", value:this.distance },
67 | raymarchPrecision:{ type:"f", value:this.precision}
68 |
69 | },
70 | vertexShader : "void main() {gl_Position = vec4( position, 1.0 );}",
71 | fragmentShader : fs,
72 | transparent:true
73 | });
74 | this.update();
75 |
76 | if( cb != null )cb( this );
77 | this.loaded = true;
78 | return this;
79 | }
80 |
81 | function setTexture( name, url ){
82 |
83 | if( this.material == null )
84 | {
85 | throw new Error("material not initialised, use setFragmentShader() first.");
86 | }
87 | rm.loaded = false;
88 |
89 | var scope = this;
90 | this.material.uniforms[ name ] = {type:'t', value:null };
91 | tl.load( url, function(texture){
92 |
93 | scope.material.uniforms[ name ].value = texture;
94 | scope.material.needsUpdate = true;
95 | scope.loaded = true;
96 | texture.needsUpdate = true;
97 |
98 | });
99 | return this;
100 | }
101 |
102 | function setCubemap( name, urls ){
103 |
104 | if( this.material == null )
105 | {
106 | throw new Error("material not initialised, use setFragmentShader() first.");
107 | }
108 | rm.loaded = false;
109 |
110 | var scope = this;
111 | this.material.uniforms[ name ] = {type:'t', value:null };
112 | cl.load( urls, function(texture) {
113 | scope.material.uniforms[ name ].value = texture;
114 | scope.material.needsUpdate = true;
115 | scope.loaded = true;
116 | texture.needsUpdate = true;
117 | });
118 | }
119 |
120 | function setUniform( name, type, value ){
121 |
122 | if( this.material == null )
123 | {
124 | throw new Error("material not initialised, use setFragmentShader() first.");
125 | }
126 |
127 | this.material.uniforms[ name ] = {type:type, value:value };
128 | return this;
129 |
130 | }
131 |
132 | function getUniform( name ){
133 |
134 |
135 | if( this.material == null )
136 | {
137 | console.warn("raymarcher.getUniform: material not initialised, use setFragmentShader() first.");
138 | return null;
139 | }
140 |
141 | return this.material.uniforms[name];
142 |
143 | }
144 |
145 | function setSize( width, height ){
146 |
147 | this.width = width;
148 | this.height = height;
149 |
150 | this.renderer.setSize( width, height );
151 |
152 | this.camera.aspect = width / height;
153 | this.camera.updateProjectionMatrix();
154 |
155 | if( this.material != null )
156 | {
157 | this.material.uniforms.resolution.value.x = width;
158 | this.material.uniforms.resolution.value.y = height;
159 | }
160 | return this;
161 | }
162 |
163 | function update(){
164 |
165 | if( this.material == null )return;
166 |
167 | this.material.uniforms.time.value = ( Date.now() - this.startTime ) * .001;
168 | this.material.uniforms.randomSeed.value = Math.random();
169 |
170 | this.material.uniforms.fov.value = this.camera.fov * Math.PI / 180;
171 |
172 | this.material.uniforms.raymarchMaximumDistance.value = this.distance;
173 | this.material.uniforms.raymarchPrecision.value = this.precision;
174 |
175 | this.material.uniforms.camera.value = this.camera.position;
176 |
177 | this.material.uniforms.target.value = this.target;
178 | this.camera.lookAt( this.target );
179 |
180 | }
181 |
182 | function render(){
183 |
184 | if( this.loaded )
185 | {
186 | this.update();
187 | this.renderer.render( this.scene, this.renderCamera );
188 | }
189 | }
190 |
191 | var _p = RayMarcher.prototype;
192 | _p.constructor = RayMarcher;
193 |
194 | _p.loadFragmentShader = loadFragmentShader;
195 | _p.setFragmentShader = setFragmentShader;
196 | _p.setTexture = setTexture;
197 | _p.setCubemap = setCubemap;
198 | _p.setUniform = setUniform;
199 | _p.getUniform = getUniform;
200 | _p.setSize = setSize;
201 | _p.update = update;
202 | _p.render = render;
203 |
204 | return RayMarcher;
205 | }();
--------------------------------------------------------------------------------
/tmp.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/vendor/controls/OrbitControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author qiao / https://github.com/qiao
3 | * @author mrdoob / http://mrdoob.com
4 | * @author alteredq / http://alteredqualia.com/
5 | * @author WestLangley / http://github.com/WestLangley
6 | * @author erich666 / http://erichaines.com
7 | */
8 | /*global THREE, console */
9 |
10 | // This set of controls performs orbiting, dollying (zooming), and panning. It maintains
11 | // the "up" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is
12 | // supported.
13 | //
14 | // Orbit - left mouse / touch: one finger move
15 | // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
16 | // Pan - right mouse, or arrow keys / touch: three finter swipe
17 | //
18 | // This is a drop-in replacement for (most) TrackballControls used in examples.
19 | // That is, include this js file and wherever you see:
20 | // controls = new THREE.TrackballControls( camera );
21 | // controls.target.z = 150;
22 | // Simple substitute "OrbitControls" and the control should work as-is.
23 |
24 | THREE.OrbitControls = function ( object, domElement ) {
25 |
26 | this.object = object;
27 | this.domElement = ( domElement !== undefined ) ? domElement : document;
28 |
29 | // API
30 |
31 | // Set to false to disable this control
32 | this.enabled = true;
33 |
34 | // "target" sets the location of focus, where the control orbits around
35 | // and where it pans with respect to.
36 | this.target = new THREE.Vector3();
37 |
38 | // center is old, deprecated; use "target" instead
39 | this.center = this.target;
40 |
41 | // This option actually enables dollying in and out; left as "zoom" for
42 | // backwards compatibility
43 | this.noZoom = false;
44 | this.zoomSpeed = 1.0;
45 |
46 | // Limits to how far you can dolly in and out
47 | this.minDistance = 0;
48 | this.maxDistance = Infinity;
49 |
50 | // Set to true to disable this control
51 | this.noRotate = false;
52 | this.rotateSpeed = 1.0;
53 |
54 | // Set to true to disable this control
55 | this.noPan = false;
56 | this.keyPanSpeed = 7.0; // pixels moved per arrow key push
57 |
58 | // Set to true to automatically rotate around the target
59 | this.autoRotate = false;
60 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
61 |
62 | // How far you can orbit vertically, upper and lower limits.
63 | // Range is 0 to Math.PI radians.
64 | this.minPolarAngle = 0; // radians
65 | this.maxPolarAngle = Math.PI; // radians
66 |
67 | // Set to true to disable use of the keys
68 | this.noKeys = false;
69 |
70 | // The four arrow keys
71 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
72 |
73 | ////////////
74 | // internals
75 |
76 | var scope = this;
77 |
78 | var EPS = 0.000001;
79 |
80 | var rotateStart = new THREE.Vector2();
81 | var rotateEnd = new THREE.Vector2();
82 | var rotateDelta = new THREE.Vector2();
83 |
84 | var panStart = new THREE.Vector2();
85 | var panEnd = new THREE.Vector2();
86 | var panDelta = new THREE.Vector2();
87 | var panOffset = new THREE.Vector3();
88 |
89 | var offset = new THREE.Vector3();
90 |
91 | var dollyStart = new THREE.Vector2();
92 | var dollyEnd = new THREE.Vector2();
93 | var dollyDelta = new THREE.Vector2();
94 |
95 | var phiDelta = 0;
96 | var thetaDelta = 0;
97 | var scale = 1;
98 | var pan = new THREE.Vector3();
99 |
100 | var lastPosition = new THREE.Vector3();
101 | var lastQuaternion = new THREE.Quaternion();
102 |
103 | var STATE = { NONE : -1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };
104 |
105 | var state = STATE.NONE;
106 |
107 | // for reset
108 |
109 | this.target0 = this.target.clone();
110 | this.position0 = this.object.position.clone();
111 |
112 | // so camera.up is the orbit axis
113 |
114 | var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );
115 | var quatInverse = quat.clone().inverse();
116 |
117 | // events
118 |
119 | var changeEvent = { type: 'change' };
120 | var startEvent = { type: 'start'};
121 | var endEvent = { type: 'end'};
122 |
123 |
124 | this.rotateLeft = function ( angle ) {
125 |
126 | if ( angle === undefined ) {
127 |
128 | angle = getAutoRotationAngle();
129 |
130 | }
131 |
132 | thetaDelta -= angle;
133 |
134 | };
135 |
136 | this.rotateUp = function ( angle ) {
137 |
138 | if ( angle === undefined ) {
139 |
140 | angle = getAutoRotationAngle();
141 |
142 | }
143 |
144 | phiDelta -= angle;
145 |
146 | };
147 |
148 | // pass in distance in world space to move left
149 | this.panLeft = function ( distance ) {
150 |
151 | var te = this.object.matrix.elements;
152 |
153 | // get X column of matrix
154 | panOffset.set( te[ 0 ], te[ 1 ], te[ 2 ] );
155 | panOffset.multiplyScalar( - distance );
156 |
157 | pan.add( panOffset );
158 |
159 | };
160 |
161 | // pass in distance in world space to move up
162 | this.panUp = function ( distance ) {
163 |
164 | var te = this.object.matrix.elements;
165 |
166 | // get Y column of matrix
167 | panOffset.set( te[ 4 ], te[ 5 ], te[ 6 ] );
168 | panOffset.multiplyScalar( distance );
169 |
170 | pan.add( panOffset );
171 |
172 | };
173 |
174 | // pass in x,y of change desired in pixel space,
175 | // right and down are positive
176 | this.pan = function ( deltaX, deltaY ) {
177 |
178 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
179 |
180 | if ( scope.object.fov !== undefined ) {
181 |
182 | // perspective
183 | var position = scope.object.position;
184 | var offset = position.clone().sub( scope.target );
185 | var targetDistance = offset.length();
186 |
187 | // half of the fov is center to top of screen
188 | targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );
189 |
190 | // we actually don't use screenWidth, since perspective camera is fixed to screen height
191 | scope.panLeft( 2 * deltaX * targetDistance / element.clientHeight );
192 | scope.panUp( 2 * deltaY * targetDistance / element.clientHeight );
193 |
194 | } else if ( scope.object.top !== undefined ) {
195 |
196 | // orthographic
197 | scope.panLeft( deltaX * (scope.object.right - scope.object.left) / element.clientWidth );
198 | scope.panUp( deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight );
199 |
200 | } else {
201 |
202 | // camera neither orthographic or perspective
203 | console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );
204 |
205 | }
206 |
207 | };
208 |
209 | this.dollyIn = function ( dollyScale ) {
210 |
211 | if ( dollyScale === undefined ) {
212 |
213 | dollyScale = getZoomScale();
214 |
215 | }
216 |
217 | scale /= dollyScale;
218 |
219 | };
220 |
221 | this.dollyOut = function ( dollyScale ) {
222 |
223 | if ( dollyScale === undefined ) {
224 |
225 | dollyScale = getZoomScale();
226 |
227 | }
228 |
229 | scale *= dollyScale;
230 |
231 | };
232 |
233 | this.setAngles = function( theta, phi, radius )
234 | {
235 |
236 | var position = this.object.position;
237 | offset.copy( position ).sub( this.target );
238 | offset.applyQuaternion( quat );
239 |
240 | theta = theta || Math.atan2( offset.x, offset.z );
241 | phi = phi || Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
242 |
243 | // restrict radius to be between desired limits
244 | radius = radius || offset.length() * scale;
245 | radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
246 |
247 | offset.x = radius * Math.sin( phi ) * Math.sin( theta );
248 | offset.y = radius * Math.cos( phi );
249 | offset.z = radius * Math.sin( phi ) * Math.cos( theta );
250 |
251 | // rotate offset back to "camera-up-vector-is-up" space
252 | offset.applyQuaternion( quatInverse );
253 | position.copy( this.target ).add( offset );
254 | this.object.lookAt( this.target );
255 |
256 | if ( lastPosition.distanceToSquared( this.object.position ) > EPS
257 | || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
258 | this.dispatchEvent( changeEvent );
259 | lastPosition.copy( this.object.position );
260 | lastQuaternion.copy (this.object.quaternion );
261 | }
262 | };
263 |
264 | this.getAngles = function()
265 | {
266 | var position = this.object.position;
267 | offset.copy( position ).sub( this.target );
268 | offset.applyQuaternion( quat );
269 | var theta = Math.atan2( offset.x, offset.z );
270 | var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
271 | return { theta:theta, phi:phi };
272 | };
273 |
274 | this.update = function () {
275 |
276 |
277 | var position = this.object.position;
278 |
279 | offset.copy( position ).sub( this.target );
280 |
281 | // rotate offset to "y-axis-is-up" space
282 | offset.applyQuaternion( quat );
283 |
284 | // angle from z-axis around y-axis
285 |
286 | var theta = Math.atan2( offset.x, offset.z );
287 |
288 | // angle from y-axis
289 |
290 | var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
291 |
292 | if ( this.autoRotate ) {
293 |
294 | this.rotateLeft( getAutoRotationAngle() );
295 |
296 | }
297 |
298 | theta += thetaDelta;
299 | phi += phiDelta;
300 |
301 | // restrict phi to be between desired limits
302 | phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
303 |
304 | // restrict phi to be betwee EPS and PI-EPS
305 | phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
306 |
307 | var radius = offset.length() * scale;
308 |
309 | // restrict radius to be between desired limits
310 | radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
311 |
312 | // move target to panned location
313 | this.target.add( pan );
314 |
315 | offset.x = radius * Math.sin( phi ) * Math.sin( theta );
316 | offset.y = radius * Math.cos( phi );
317 | offset.z = radius * Math.sin( phi ) * Math.cos( theta );
318 |
319 | // rotate offset back to "camera-up-vector-is-up" space
320 | offset.applyQuaternion( quatInverse );
321 |
322 | position.copy( this.target ).add( offset );
323 |
324 | //var pos = offset.normalize().multiplyScalar( EARTH_RADIUS );
325 | this.object.lookAt( this.target );
326 |
327 | thetaDelta = 0;
328 | phiDelta = 0;
329 | scale = 1;
330 | pan.set( 0, 0, 0 );
331 |
332 | // update condition is:
333 | // min(camera displacement, camera rotation in radians)^2 > EPS
334 | // using small-angle approximation cos(x/2) = 1 - x^2 / 8
335 |
336 | if ( lastPosition.distanceToSquared( this.object.position ) > EPS
337 | || 8 * (1 - lastQuaternion.dot(this.object.quaternion)) > EPS ) {
338 |
339 | this.dispatchEvent( changeEvent );
340 |
341 | lastPosition.copy( this.object.position );
342 | lastQuaternion.copy (this.object.quaternion );
343 |
344 | }
345 |
346 | };
347 |
348 |
349 | this.reset = function () {
350 |
351 | state = STATE.NONE;
352 |
353 | this.target.copy( this.target0 );
354 | this.object.position.copy( this.position0 );
355 |
356 | this.update();
357 |
358 | };
359 |
360 | function getAutoRotationAngle() {
361 |
362 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
363 |
364 | }
365 |
366 | function getZoomScale() {
367 |
368 | return Math.pow( 0.95, scope.zoomSpeed );
369 |
370 | }
371 |
372 | function onMouseDown( event ) {
373 |
374 | if ( scope.enabled === false ) return;
375 | // event.preventDefault();
376 |
377 | if ( event.button === 0 ) {
378 | if ( scope.noRotate === true ) return;
379 |
380 | state = STATE.ROTATE;
381 |
382 | rotateStart.set( event.clientX, event.clientY );
383 |
384 | } else if ( event.button === 1 ) {
385 | if ( scope.noZoom === true ) return;
386 |
387 | state = STATE.DOLLY;
388 |
389 | dollyStart.set( event.clientX, event.clientY );
390 |
391 | } else if ( event.button === 2 ) {
392 | if ( scope.noPan === true ) return;
393 |
394 | state = STATE.PAN;
395 |
396 | panStart.set( event.clientX, event.clientY );
397 |
398 | }
399 |
400 | document.addEventListener( 'mousemove', onMouseMove, false );
401 | document.addEventListener( 'mouseup', onMouseUp, false );
402 | scope.dispatchEvent( startEvent );
403 |
404 | }
405 |
406 | function onMouseMove( event ) {
407 |
408 | if ( scope.enabled === false )
409 | {
410 | document.removeEventListener( 'mousemove', onMouseMove, false );
411 | return;
412 | }
413 |
414 | // event.preventDefault();
415 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
416 |
417 | if ( state === STATE.ROTATE ) {
418 |
419 | if ( scope.noRotate === true ) return;
420 |
421 | rotateEnd.set( event.clientX, event.clientY );
422 | rotateDelta.subVectors( rotateEnd, rotateStart );
423 |
424 | // rotating across whole screen goes 360 degrees around
425 | scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
426 |
427 | // rotating up and down along whole screen attempts to go 360, but limited to 180
428 | scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
429 |
430 | rotateStart.copy( rotateEnd );
431 |
432 | } else if ( state === STATE.DOLLY ) {
433 |
434 | if ( scope.noZoom === true ) return;
435 |
436 | dollyEnd.set( event.clientX, event.clientY );
437 | dollyDelta.subVectors( dollyEnd, dollyStart );
438 |
439 | if ( dollyDelta.y > 0 ) {
440 |
441 | scope.dollyIn();
442 |
443 | } else {
444 |
445 | scope.dollyOut();
446 |
447 | }
448 |
449 | dollyStart.copy( dollyEnd );
450 |
451 | } else if ( state === STATE.PAN ) {
452 |
453 | if ( scope.noPan === true ) return;
454 |
455 | panEnd.set( event.clientX, event.clientY );
456 | panDelta.subVectors( panEnd, panStart );
457 |
458 | scope.pan( panDelta.x, panDelta.y );
459 |
460 | panStart.copy( panEnd );
461 |
462 | }
463 |
464 | scope.update();
465 |
466 | }
467 |
468 | function onMouseUp( /* event */ ) {
469 |
470 | if ( scope.enabled === false ) return;
471 |
472 | document.removeEventListener( 'mousemove', onMouseMove, false );
473 | document.removeEventListener( 'mouseup', onMouseUp, false );
474 | scope.dispatchEvent( endEvent );
475 | state = STATE.NONE;
476 |
477 | }
478 |
479 | function onMouseWheel( event ) {
480 |
481 | if ( scope.enabled === false || scope.noZoom === true ) return;
482 |
483 | // event.preventDefault();
484 | event.stopPropagation();
485 |
486 | var delta = 0;
487 |
488 | if ( event.wheelDelta !== undefined ) { // WebKit / Opera / Explorer 9
489 |
490 | delta = event.wheelDelta;
491 |
492 | } else if ( event.detail !== undefined ) { // Firefox
493 |
494 | delta = - event.detail;
495 |
496 | }
497 |
498 | if ( delta > 0 ) {
499 |
500 | scope.dollyOut();
501 |
502 | } else {
503 |
504 | scope.dollyIn();
505 |
506 | }
507 |
508 | scope.update();
509 | scope.dispatchEvent( startEvent );
510 | scope.dispatchEvent( endEvent );
511 |
512 | }
513 |
514 | function onKeyDown( event ) {
515 |
516 | if ( scope.enabled === false || scope.noKeys === true || scope.noPan === true ) return;
517 |
518 | switch ( event.keyCode ) {
519 |
520 | case scope.keys.UP:
521 | scope.pan( 0, scope.keyPanSpeed );
522 | scope.update();
523 | break;
524 |
525 | case scope.keys.BOTTOM:
526 | scope.pan( 0, - scope.keyPanSpeed );
527 | scope.update();
528 | break;
529 |
530 | case scope.keys.LEFT:
531 | scope.pan( scope.keyPanSpeed, 0 );
532 | scope.update();
533 | break;
534 |
535 | case scope.keys.RIGHT:
536 | scope.pan( - scope.keyPanSpeed, 0 );
537 | scope.update();
538 | break;
539 |
540 | }
541 |
542 | }
543 |
544 | function touchstart( event ) {
545 |
546 | if ( scope.enabled === false ) return;
547 |
548 | switch ( event.touches.length ) {
549 |
550 | case 1: // one-fingered touch: rotate
551 |
552 | if ( scope.noRotate === true ) return;
553 |
554 | state = STATE.TOUCH_ROTATE;
555 |
556 | rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
557 | break;
558 |
559 | case 2: // two-fingered touch: dolly
560 |
561 | if ( scope.noZoom === true ) return;
562 |
563 | state = STATE.TOUCH_DOLLY;
564 |
565 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
566 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
567 | var distance = Math.sqrt( dx * dx + dy * dy );
568 | dollyStart.set( 0, distance );
569 | break;
570 |
571 | case 3: // three-fingered touch: pan
572 |
573 | if ( scope.noPan === true ) return;
574 |
575 | state = STATE.TOUCH_PAN;
576 |
577 | panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
578 | break;
579 |
580 | default:
581 |
582 | state = STATE.NONE;
583 |
584 | }
585 |
586 | scope.dispatchEvent( startEvent );
587 |
588 | }
589 |
590 | function touchmove( event ) {
591 |
592 | if ( scope.enabled === false ) return;
593 |
594 | event.preventDefault();
595 | event.stopPropagation();
596 |
597 | var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
598 |
599 | switch ( event.touches.length ) {
600 |
601 | case 1: // one-fingered touch: rotate
602 |
603 | if ( scope.noRotate === true ) return;
604 | if ( state !== STATE.TOUCH_ROTATE ) return;
605 |
606 | rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
607 | rotateDelta.subVectors( rotateEnd, rotateStart );
608 |
609 | // rotating across whole screen goes 360 degrees around
610 | scope.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );
611 | // rotating up and down along whole screen attempts to go 360, but limited to 180
612 | scope.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );
613 |
614 | rotateStart.copy( rotateEnd );
615 |
616 | scope.update();
617 | break;
618 |
619 | case 2: // two-fingered touch: dolly
620 |
621 | if ( scope.noZoom === true ) return;
622 | if ( state !== STATE.TOUCH_DOLLY ) return;
623 |
624 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
625 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
626 | var distance = Math.sqrt( dx * dx + dy * dy );
627 |
628 | dollyEnd.set( 0, distance );
629 | dollyDelta.subVectors( dollyEnd, dollyStart );
630 |
631 | if ( dollyDelta.y > 0 ) {
632 |
633 | scope.dollyOut();
634 |
635 | } else {
636 |
637 | scope.dollyIn();
638 |
639 | }
640 |
641 | dollyStart.copy( dollyEnd );
642 |
643 | scope.update();
644 | break;
645 |
646 | case 3: // three-fingered touch: pan
647 |
648 | if ( scope.noPan === true ) return;
649 | if ( state !== STATE.TOUCH_PAN ) return;
650 |
651 | panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
652 | panDelta.subVectors( panEnd, panStart );
653 |
654 | scope.pan( panDelta.x, panDelta.y );
655 |
656 | panStart.copy( panEnd );
657 |
658 | scope.update();
659 | break;
660 |
661 | default:
662 |
663 | state = STATE.NONE;
664 |
665 | }
666 |
667 | }
668 |
669 | function touchend( /* event */ ) {
670 |
671 | if ( scope.enabled === false ) return;
672 |
673 | scope.dispatchEvent( endEvent );
674 | state = STATE.NONE;
675 |
676 | }
677 |
678 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
679 | this.domElement.addEventListener( 'mousedown', onMouseDown, false );
680 | this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
681 | this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
682 |
683 | this.domElement.addEventListener( 'touchstart', touchstart, false );
684 | this.domElement.addEventListener( 'touchend', touchend, false );
685 | this.domElement.addEventListener( 'touchmove', touchmove, false );
686 |
687 | window.addEventListener( 'keydown', onKeyDown, false );
688 | scope.enabled = true;
689 | // force an update at start
690 | this.update();
691 |
692 | };
693 |
694 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
695 |
--------------------------------------------------------------------------------
/vendor/postprocessing/EffectComposer.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.EffectComposer = function ( renderer, renderTarget ) {
6 |
7 | this.renderer = renderer;
8 |
9 | if ( renderTarget === undefined ) {
10 |
11 | var pixelRatio = renderer.getPixelRatio();
12 |
13 | var width = Math.floor( renderer.context.canvas.width / pixelRatio ) || 1;
14 | var height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;
15 | var parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBuffer: false };
16 |
17 | renderTarget = new THREE.WebGLRenderTarget( width, height, parameters );
18 |
19 | }
20 |
21 | this.renderTarget1 = renderTarget;
22 | this.renderTarget2 = renderTarget.clone();
23 |
24 | this.writeBuffer = this.renderTarget1;
25 | this.readBuffer = this.renderTarget2;
26 |
27 | this.passes = [];
28 |
29 | if ( THREE.CopyShader === undefined )
30 | console.error( "THREE.EffectComposer relies on THREE.CopyShader" );
31 |
32 | this.copyPass = new THREE.ShaderPass( THREE.CopyShader );
33 |
34 | };
35 |
36 | THREE.EffectComposer.prototype = {
37 |
38 | swapBuffers: function() {
39 |
40 | var tmp = this.readBuffer;
41 | this.readBuffer = this.writeBuffer;
42 | this.writeBuffer = tmp;
43 |
44 | },
45 |
46 | addPass: function ( pass ) {
47 |
48 | this.passes.push( pass );
49 |
50 | },
51 |
52 | insertPass: function ( pass, index ) {
53 |
54 | this.passes.splice( index, 0, pass );
55 |
56 | },
57 |
58 | render: function ( delta ) {
59 |
60 | this.writeBuffer = this.renderTarget1;
61 | this.readBuffer = this.renderTarget2;
62 |
63 | var maskActive = false;
64 |
65 | var pass, i, il = this.passes.length;
66 |
67 | for ( i = 0; i < il; i ++ ) {
68 |
69 | pass = this.passes[ i ];
70 |
71 | if ( ! pass.enabled ) continue;
72 |
73 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );
74 |
75 | if ( pass.needsSwap ) {
76 |
77 | if ( maskActive ) {
78 |
79 | var context = this.renderer.context;
80 |
81 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
82 |
83 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );
84 |
85 | context.stencilFunc( context.EQUAL, 1, 0xffffffff );
86 |
87 | }
88 |
89 | this.swapBuffers();
90 |
91 | }
92 |
93 | if ( pass instanceof THREE.MaskPass ) {
94 |
95 | maskActive = true;
96 |
97 | } else if ( pass instanceof THREE.ClearMaskPass ) {
98 |
99 | maskActive = false;
100 |
101 | }
102 |
103 | }
104 |
105 | },
106 |
107 | reset: function ( renderTarget ) {
108 |
109 | if ( renderTarget === undefined ) {
110 |
111 | renderTarget = this.renderTarget1.clone();
112 |
113 | var pixelRatio = this.renderer.getPixelRatio();
114 |
115 | renderTarget.width = Math.floor( this.renderer.context.canvas.width / pixelRatio );
116 | renderTarget.height = Math.floor( this.renderer.context.canvas.height / pixelRatio );
117 |
118 | }
119 |
120 | this.renderTarget1.dispose();
121 | this.renderTarget1 = renderTarget;
122 | this.renderTarget2.dispose();
123 | this.renderTarget2 = renderTarget.clone();
124 |
125 | this.writeBuffer = this.renderTarget1;
126 | this.readBuffer = this.renderTarget2;
127 |
128 | },
129 |
130 | setSize: function ( width, height ) {
131 |
132 | this.renderTarget1.setSize( width, height );
133 | this.renderTarget2.setSize( width, height );
134 |
135 | }
136 |
137 | };
138 |
--------------------------------------------------------------------------------
/vendor/postprocessing/MaskPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.MaskPass = function ( scene, camera ) {
6 |
7 | this.scene = scene;
8 | this.camera = camera;
9 |
10 | this.enabled = true;
11 | this.clear = true;
12 | this.needsSwap = false;
13 |
14 | this.inverse = false;
15 |
16 | };
17 |
18 | THREE.MaskPass.prototype = {
19 |
20 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
21 |
22 | var context = renderer.context;
23 |
24 | // don't update color or depth
25 |
26 | context.colorMask( false, false, false, false );
27 | context.depthMask( false );
28 |
29 | // set up stencil
30 |
31 | var writeValue, clearValue;
32 |
33 | if ( this.inverse ) {
34 |
35 | writeValue = 0;
36 | clearValue = 1;
37 |
38 | } else {
39 |
40 | writeValue = 1;
41 | clearValue = 0;
42 |
43 | }
44 |
45 | context.enable( context.STENCIL_TEST );
46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );
47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );
48 | context.clearStencil( clearValue );
49 |
50 | // draw into the stencil buffer
51 |
52 | renderer.render( this.scene, this.camera, readBuffer, this.clear );
53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear );
54 |
55 | // re-enable update of color and depth
56 |
57 | context.colorMask( true, true, true, true );
58 | context.depthMask( true );
59 |
60 | // only render where stencil is set to 1
61 |
62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1
63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP );
64 |
65 | }
66 |
67 | };
68 |
69 |
70 | THREE.ClearMaskPass = function () {
71 |
72 | this.enabled = true;
73 |
74 | };
75 |
76 | THREE.ClearMaskPass.prototype = {
77 |
78 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
79 |
80 | var context = renderer.context;
81 |
82 | context.disable( context.STENCIL_TEST );
83 |
84 | }
85 |
86 | };
87 |
--------------------------------------------------------------------------------
/vendor/postprocessing/RenderPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
6 |
7 | this.scene = scene;
8 | this.camera = camera;
9 |
10 | this.overrideMaterial = overrideMaterial;
11 |
12 | this.clearColor = clearColor;
13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;
14 |
15 | this.oldClearColor = new THREE.Color();
16 | this.oldClearAlpha = 1;
17 |
18 | this.enabled = true;
19 | this.clear = true;
20 | this.needsSwap = false;
21 |
22 | };
23 |
24 | THREE.RenderPass.prototype = {
25 |
26 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
27 |
28 | this.scene.overrideMaterial = this.overrideMaterial;
29 |
30 | if ( this.clearColor ) {
31 |
32 | this.oldClearColor.copy( renderer.getClearColor() );
33 | this.oldClearAlpha = renderer.getClearAlpha();
34 |
35 | renderer.setClearColor( this.clearColor, this.clearAlpha );
36 |
37 | }
38 |
39 | renderer.render( this.scene, this.camera, readBuffer, this.clear );
40 |
41 | if ( this.clearColor ) {
42 |
43 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
44 |
45 | }
46 |
47 | this.scene.overrideMaterial = null;
48 |
49 | }
50 |
51 | };
52 |
--------------------------------------------------------------------------------
/vendor/postprocessing/ShaderPass.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.ShaderPass = function ( shader, textureID ) {
6 |
7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse";
8 |
9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
10 |
11 | this.material = new THREE.ShaderMaterial( {
12 |
13 | defines: shader.defines || {},
14 | uniforms: this.uniforms,
15 | vertexShader: shader.vertexShader,
16 | fragmentShader: shader.fragmentShader
17 |
18 | } );
19 |
20 | this.renderToScreen = false;
21 |
22 | this.enabled = true;
23 | this.needsSwap = true;
24 | this.clear = false;
25 |
26 |
27 | this.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
28 | this.scene = new THREE.Scene();
29 |
30 | this.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );
31 | this.scene.add( this.quad );
32 |
33 | };
34 |
35 | THREE.ShaderPass.prototype = {
36 |
37 | render: function ( renderer, writeBuffer, readBuffer, delta ) {
38 |
39 | if ( this.uniforms[ this.textureID ] ) {
40 |
41 | this.uniforms[ this.textureID ].value = readBuffer;
42 |
43 | }
44 |
45 | this.quad.material = this.material;
46 |
47 | if ( this.renderToScreen ) {
48 |
49 | renderer.render( this.scene, this.camera );
50 |
51 | } else {
52 |
53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear );
54 |
55 | }
56 |
57 | }
58 |
59 | };
60 |
--------------------------------------------------------------------------------
/vendor/shaders/CopyShader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | *
4 | * Full-screen textured quad shader
5 | */
6 |
7 | THREE.CopyShader = {
8 |
9 | uniforms: {
10 |
11 | "tDiffuse": { type: "t", value: null },
12 | "opacity": { type: "f", value: 1.0 }
13 |
14 | },
15 |
16 | vertexShader: [
17 |
18 | "varying vec2 vUv;",
19 |
20 | "void main() {",
21 |
22 | "vUv = uv;",
23 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
24 |
25 | "}"
26 |
27 | ].join( "\n" ),
28 |
29 | fragmentShader: [
30 |
31 | "uniform float opacity;",
32 |
33 | "uniform sampler2D tDiffuse;",
34 |
35 | "varying vec2 vUv;",
36 |
37 | "void main() {",
38 |
39 | "vec4 texel = texture2D( tDiffuse, vUv );",
40 | "gl_FragColor = opacity * texel;",
41 |
42 | "}"
43 |
44 | ].join( "\n" )
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/vendor/shaders/FXAAShader.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | * @author davidedc / http://www.sketchpatch.net/
4 | *
5 | * NVIDIA FXAA by Timothy Lottes
6 | * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html
7 | * - WebGL port by @supereggbert
8 | * http://www.glge.org/demos/fxaa/
9 | */
10 |
11 | THREE.FXAAShader = {
12 |
13 | uniforms: {
14 |
15 | "tDiffuse": { type: "t", value: null },
16 | "resolution": { type: "v2", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) }
17 |
18 | },
19 |
20 | vertexShader: [
21 |
22 | "void main() {",
23 |
24 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
25 |
26 | "}"
27 |
28 | ].join( "\n" ),
29 |
30 | fragmentShader: [
31 |
32 | "uniform sampler2D tDiffuse;",
33 | "uniform vec2 resolution;",
34 |
35 | "#define FXAA_REDUCE_MIN (1.0/128.0)",
36 | "#define FXAA_REDUCE_MUL (1.0/8.0)",
37 | "#define FXAA_SPAN_MAX 8.0",
38 |
39 | "void main() {",
40 |
41 | "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;",
42 | "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;",
43 | "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;",
44 | "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;",
45 | "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );",
46 | "vec3 rgbM = rgbaM.xyz;",
47 | "vec3 luma = vec3( 0.299, 0.587, 0.114 );",
48 |
49 | "float lumaNW = dot( rgbNW, luma );",
50 | "float lumaNE = dot( rgbNE, luma );",
51 | "float lumaSW = dot( rgbSW, luma );",
52 | "float lumaSE = dot( rgbSE, luma );",
53 | "float lumaM = dot( rgbM, luma );",
54 | "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );",
55 | "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );",
56 |
57 | "vec2 dir;",
58 | "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));",
59 | "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));",
60 |
61 | "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );",
62 |
63 | "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );",
64 | "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),",
65 | "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),",
66 | "dir * rcpDirMin)) * resolution;",
67 | "vec4 rgbA = (1.0/2.0) * (",
68 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +",
69 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));",
70 | "vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (",
71 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +",
72 | "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));",
73 | "float lumaB = dot(rgbB, vec4(luma, 0.0));",
74 |
75 | "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {",
76 |
77 | "gl_FragColor = rgbA;",
78 |
79 | "} else {",
80 | "gl_FragColor = rgbB;",
81 |
82 | "}",
83 |
84 | "}"
85 |
86 | ].join( "\n" )
87 |
88 | };
89 |
--------------------------------------------------------------------------------
/walker.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
96 |
97 |
98 |
--------------------------------------------------------------------------------