w,a,s,d to move forward, left, backwards and right.
60 |
q,e to roll left/right. up and down arrow to move up and down.
61 |
p to toggle smoke.
62 |
shift to change camera view.
63 |
caps lock to switch to takeoff mode, or landing mode when flying.
64 |
65 |
66 |
67 |
68 |
69 |
71 |
--------------------------------------------------------------------------------
/airshow/notes.txt:
--------------------------------------------------------------------------------
1 | airshow!
2 |
3 | I love airshows and military aircraft. the one featured here is an f-18. hopefully I will build some more military aircraft to assemble
4 | some static displays! :D
5 |
6 |
7 | notes:
8 | - so when the f-18 controlled by the user reaches some vertical angle ( > 90 deg), the camera flips. not a big deal, but interesting.
9 |
10 | looks like the issue is with lookAt()
11 | this might help: https://discourse.threejs.org/t/solved-lookat-flips-cam-rotation-180-degrees-how-do-i-remove-this/2066/3
12 | and this: https://github.com/mrdoob/three.js/issues/688
13 |
14 | this dicussion also looks interesting: https://github.com/mrdoob/three.js/issues/1460
15 |
16 | - a more pressing matter is the way I handle rolls with Q and E. i'm manipulating the actual jet's mesh so the axis can get misaligned relative
17 | to the group object it's a child of, which then makes all my controls inverted. but it does make sense that that should happen but at
18 | the same time I'm not really sure what a proper experience should be like thinking about it more. maybe I'll reinstall BF2 and take a look :)
19 |
20 | - also, when I put the f18 in a group object the rolling behavior is exactly what i want. but when i try using just the f18 mesh itself,
21 | the rotation is not as good, i.e. it feels like there's some offset, rather than rotating the jet as if the z-axis was going through the
22 | middle of it. not really sure why but that's something to look into.
23 | // https://stackoverflow.com/questions/28848863/threejs-how-to-rotate-around-objects-own-center-instead-of-world-center
24 |
25 | todo:
26 | - better lighting + clouds
27 | - basic f-18 animations like:
28 | - flaps
29 | - rudders
30 | - landing gear deploy/retraction on key press
31 | - allow user to switch between aircraft
32 | - more camera modes
33 | - make more planes for static displays!
34 | -ideas: c-17, c-5, f-15, f-14 (even though retired lol), f-22, av-8b, p-8, tanks are good too, helicopters!!
35 |
36 | textures:
37 | http://hoodavirender.blogspot.com/2012/03/seamless-grass-texture.html
38 | borrowed top-view of Andrews Air Force Base from Google Maps
39 | https://www.goodfreephotos.com/united-states/colorado/rocky-mountains-national-park/colorado-rocky-mountains-national-park-mountains-in-the-horizon.jpg.php
40 | https://www.photos-public-domain.com/2011/03/02/blue-sky-with-white-clouds-texture/
41 |
42 | http://www.aerodynamics4students.com/aircraft-performance/take-off-and-landing.php
43 | https://aviation.stackexchange.com/questions/9961/does-acceleration-increase-linearly-on-a-takeoff-roll
--------------------------------------------------------------------------------
/airshow/pictures/airshow_demo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/airshow/pictures/airshow_demo.webp
--------------------------------------------------------------------------------
/airshow/pictures/rotation-example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/airshow/pictures/rotation-example.gif
--------------------------------------------------------------------------------
/airshow/pictures/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/airshow/pictures/screenshot.png
--------------------------------------------------------------------------------
/airshow/readme.md:
--------------------------------------------------------------------------------
1 | # airshow
2 |
3 | For this project I wanted to make and fly some jets!
4 |
5 | ## notes:
6 |
7 | 1. rotating the plane
8 | Had some issues with this. Placing the plane mesh in a THREE.Group object and rotating the mesh got me the current effect, which I think is good.
9 | However, I am unsure why rotating the plane mesh within a THREE.Group is different than rotating the mesh (or the group object) by itself relative to its own axis, as seen below:
10 |
11 | example of not-so-great rotation (imo) when rotating the THREE.Group on its own axis in object space:
12 | 
13 |
14 | One issue though with the current strategy and using the THREE.Group is that during a vertical loop the orientation of the axes change, which changes the direction of motion on key press. Definitely something to investigate further.
15 |
16 | 2. takeoff and landing
17 | For takeoff, the speed of the plane is increased exponentially (ex via Math.exp()), which looks fine to me visually. I also added a landing mode feature in which the plane descends at a constant speed while being parallel to the ground.
18 |
19 | 3. jet engine exhaust/smoke
20 | Used the partykals.js library by RonenNess (https://github.com/RonenNess/partykals)
--------------------------------------------------------------------------------
/audio_visualization/27-05-2022_153744.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/audio_visualization/27-05-2022_153744.webp
--------------------------------------------------------------------------------
/audio_visualization/README.md:
--------------------------------------------------------------------------------
1 | # audio visualization
2 |
3 | 
4 |
5 | This demo utilizes the Web Audio API (in particular the AnalyserNode) to demonstrate how we can use audio data to help create 3D visualizations.
--------------------------------------------------------------------------------
/audio_visualization/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | audio visualization
5 |
6 |
7 |
8 |
9 |
10 |
11 |
29 |
30 |
31 |
32 |
audio visualization
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
audio file name
44 |
45 |
a very basic visualizer for audio! with trackball controls so you can view the visualizer at different angles. :D
46 |
the pink balls correspond to the time domain and the green-yellow cubes correspond to the frequency domain.
press 1 and 2 keys to change camera view and spacebar to add impulse to the ball. press r to reset.
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
49 |
--------------------------------------------------------------------------------
/basketball/readme.md:
--------------------------------------------------------------------------------
1 | # basketball
2 |
3 | This demo utilizes the Cannon.js library (https://schteppe.github.io/cannon.js/) for handling physics!
4 |
5 | 
--------------------------------------------------------------------------------
/basketball/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/basketball/success.png
--------------------------------------------------------------------------------
/basketball/success2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/basketball/success2.png
--------------------------------------------------------------------------------
/battleships/25-09-2023_202551.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/25-09-2023_202551.gif
--------------------------------------------------------------------------------
/battleships/README.md:
--------------------------------------------------------------------------------
1 | # battleships
2 |
3 | A game idea featuring 3d battleships!
4 |
5 | 
6 |
7 | This demo utilizes an orthographic camera for a top-down view of the map, as well as a perspective camera with orbit controls.
--------------------------------------------------------------------------------
/battleships/battleship-edit2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/battleship-edit2.png
--------------------------------------------------------------------------------
/battleships/battleship2-edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/battleship2-edit.png
--------------------------------------------------------------------------------
/battleships/blender/battleship-edit3.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/blender/battleship-edit3.blend
--------------------------------------------------------------------------------
/battleships/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | battleships
5 |
6 |
7 |
8 |
9 |
17 |
18 |
23 |
24 |
69 |
70 |
71 |
72 |
battleships
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
enemy
88 |
89 |
90 |
91 |
92 |
player
93 |
94 |
95 |
96 |
click on the player ship and click anywhere in the yellow circle to move the ship. if you get close enough to another object, you can click on the object to attack it. when attacking, if 'toggle airstrike' is checked, an airstrike will be initiated :)
97 |
98 |
99 |
101 |
--------------------------------------------------------------------------------
/battleships/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/screenshot.png
--------------------------------------------------------------------------------
/battleships/todo.txt:
--------------------------------------------------------------------------------
1 | TODO:
2 |
3 | - prevent movement through obstacles?
4 | - check for collisions within player unit's select area (the yellow circle)?
5 |
6 | - enemy movement
7 |
8 | - ship animation? (e.g. moving cannons, cannon smoke)
9 |
10 | - brighter sky, night sky options?
11 |
12 | - fix perspective camera? (when using orbit control and rotating the camera, the ships sometimes disappear. is that a camera parameter issue?)
13 |
14 | - figure out why sometimes things don't show in orthographic camera until a certain y position is reached?
15 | e.g. the player selectarea needs to be at or past a certain y value to show up in the orthographic camera
16 |
17 | - more ships
--------------------------------------------------------------------------------
/battleships/waternormals.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/battleships/waternormals.jpg
--------------------------------------------------------------------------------
/boombox/28-12-2024_221744.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/boombox/28-12-2024_221744.gif
--------------------------------------------------------------------------------
/boombox/README.md:
--------------------------------------------------------------------------------
1 | # boombox idea
2 |
3 | A 3D boombox :D
4 |
5 | The boombox model utilizes shape keys (morph targets in Three.js) to transform the play/stop buttons of the model, for rotating the dial to change the lowpass filter frequency and for enlarging the meshes of the speakers based on the audio data.
6 | This demo also adds spatial audio and a lowpass filter with the help of the Web Audio API.
7 |
8 | 
--------------------------------------------------------------------------------
/boombox/boombox.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/boombox/boombox.blend
--------------------------------------------------------------------------------
/boombox/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | boombox
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
w,s to move forward and backward. a,d to rotate left and right. q,e to roll left and right. up and down arrows to rotate up and down.
67 |
click on the canvas to add a new marker while the 'add marker' button is active.
68 |
click on any marker when the 'select marker' button is active. (they should change to red when clicked)
69 |
after markers have been selected, press the 'create path' button to connect the markers.
70 |
the 'ride path' button will move the camera along the created path. note that currently there is a 5 second duration for each created path.
71 |
72 |
73 |
74 |
75 |
76 |
78 |
--------------------------------------------------------------------------------
/camerawork/notes.txt:
--------------------------------------------------------------------------------
1 | https://stackoverflow.com/questions/42309715/how-to-correctly-pass-mouse-coordinates-to-webgl
2 | https://stackoverflow.com/questions/57381278/threejs-2d-pixels-to-3d-coordinates-conversion
3 | https://stackoverflow.com/questions/27409074/converting-3d-position-to-2d-screen-position-r69
4 | https://stackoverflow.com/questions/11638883/thickness-of-lines-using-three-linebasicmaterial
5 | https://github.com/mrdoob/three.js/blob/master/examples/webgl_interactive_cubes.html
6 | https://stackoverflow.com/questions/43414174/animate-object-along-a-path-in-three-js
7 | https://stackoverflow.com/questions/29656301/move-a-mesh-on-a-line-three-js
8 | https://sbcode.net/threejs/vector3-lerp/
9 | https://forum.unity.com/threads/lerp-value-reaching-destination-before-lerp-ends.401896/ -> very important!
10 |
11 | todo:
12 | - import/export of marker+path data so we can demonstrate some useful ideas
13 | - make a useful demo
14 | - add some ui components to represent 'scenes'? i.e. 1 path == 1 scene?
15 | - be able to change speed
16 | - make camera movement smoother? that probably has to do with speed...
17 | - smooth turning about angles? bezier curves?
18 |
--------------------------------------------------------------------------------
/camerawork/readme.md:
--------------------------------------------------------------------------------
1 | # camerawork
2 | ### an experiment with moving a camera along a user-created path
3 |
4 | the user can create markers and paths between markers.
5 | 
6 |
7 | camera view when following a path:
8 | 
9 |
10 | For this demo, the camera is made to focus on the blue cube wireframe while it's moving along a path.
--------------------------------------------------------------------------------
/camerawork/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/camerawork/screenshot.png
--------------------------------------------------------------------------------
/camerawork/texture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/camerawork/texture.png
--------------------------------------------------------------------------------
/car_demo/blender/maybeporsche911-final.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/blender/maybeporsche911-final.blend
--------------------------------------------------------------------------------
/car_demo/blender/porschecolor1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/blender/porschecolor1.png
--------------------------------------------------------------------------------
/car_demo/blender/racetrack.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/blender/racetrack.blend
--------------------------------------------------------------------------------
/car_demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | car demo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
still a work-in-progress.
46 |
47 |
48 |
49 |
controls:
50 |
keys 1-4 control different camera views. z for changing to opposite camera view for front and side views.
51 |
w,s for forwards/backwards. a,d for turning left, right. p to toggle car body visibility. t to toggle racetrack visibility.
52 |
x for toggling racetrack wireframe. c for debug mode.
53 |
54 |
55 |
56 |
57 |
58 |
60 |
--------------------------------------------------------------------------------
/car_demo/notes.txt:
--------------------------------------------------------------------------------
1 | for car turning physics later to make things more realistic/complicated:
2 | https://physics.stackexchange.com/questions/182689/what-causes-a-cars-velocity-to-follow-the-front-wheels-direction
3 | https://physics.stackexchange.com/questions/454887/the-dynamics-of-a-cornering-wheel
4 |
5 | What I want to do is to program at least somewhat realistic turning for the car.
6 | I thought to start with I could just rotate the car to match the rotation of the front wheels. this is tricky because
7 | I'm having trouble figuring out how a car's body rotates when turning. it should be independent of the front wheels' rotation I think?
8 |
9 | TODO:
10 | - fix the car rotation thing when turning. if you try turning the wheels from one side to another (i.e. keep alternating between
11 | A and D) after turning, the car's forward vector is stuck at an angle, which influences the forward movement. I think it has
12 | to do with the if condition I set up to determine whether the car should rotate to align with the front wheels. need to investigate
13 | further though.
14 |
15 | - fix lateral rotation. it kind of works but I still don't know what situations trigger the car to flip over, which happens sometimes.
16 | additionally, when you try to move the car along the big sloped turn, the lateral rotation usually looks pretty ok but then it looks
17 | as if the car got rotated about the Z axis where it's tipped forward at an angle. I think this has to do with the track having
18 | a bunch of segments such that the turns are very 'angular' and not smooth. so what might be level on one face is not on the next.
19 |
20 | objective: get car to be parallel with whatever plane it's on. sounds simple but it's so hard ;_;
21 | unity might help: https://answers.unity.com/questions/168097/orient-vehicle-to-ground-normal.html
22 | https://www.google.com/search?biw=2133&bih=1076&ei=jIyfX9PlBJ-oytMP_u6SwA4&q=unity+get+car+to+be+parallel+with+curved+plane&oq=unity+get+car+to+be+parallel+with+curved+plane&gs_lcp=CgZwc3ktYWIQAzIFCCEQoAEyBQghEKABOgQIABBHOgUIIRCrAjoICCEQFhAdEB46BwghEAoQoAFQijVYy1RgxlVoA3ACeACAAWGIAZELkgECMjCYAQCgAQGqAQdnd3Mtd2l6yAEIwAEB&sclient=psy-ab&ved=0ahUKEwjT29GyhOPsAhUflHIEHX63BOgQ4dUDCA0&uact=5
23 |
24 | this too? https://github.com/mrdoob/three.js/issues/1486
25 |
26 | new strategy: try raycast down once, get the normal of the face the raycast hits. do something with that info?
27 | you can definitely adjust the car's y position with that info so I don't need a separate function to adjust height.
28 |
29 | maybe: https://stackoverflow.com/questions/46336560/three-js-how-to-add-an-object-perpendicular-to-a-face-normal
30 | https://stackoverflow.com/questions/16268482/three-js-convert-face-normal-from-local-space-to-world-space
31 | https://stackoverflow.com/questions/23139442/how-to-get-correct-values-for-normals-in-threejs
32 |
33 | hmm this looks similar: https://stackoverflow.com/questions/23592427/rotate-an-object-according-to-a-plane-normal
34 | and this: https://answers.unity.com/questions/27340/rotating-an-object-to-equal-normals-of-object-belo.html
35 |
36 | ok, so now I can get a normal vector for each face of the racetrack that my raycast hits. great! and each normal vector looks like
37 | it's angled properly along the sloped parts of the track. now what I would like to happen is have the car rotate itself about
38 | the x-axis so that it's angled just like the normal for the face below it (i.e. the local y-axis of the car should be parallel
39 | to the normal)
40 | this is helpful! https://stackoverflow.com/questions/9038465/three-js-object3d-cylinder-rotation-to-align-to-a-vector
41 |
42 | cool, using thePlayer.quaternion.setFromUnitVectors seems to get the car to align with the normal vector of the surface it's on.
43 | but now a new problem - this rotation alignment causes issues with movement; it's forcing the car to face a certain way based
44 | on the normal vector.
45 |
46 | ok I'm very dumb lol. I ended up where I was like a couple days ago. I'm pretty sure the initial idea with getting the lateral rotation
47 | is fine (I just changed what I had to use quaternions lol) and is working - the 'tilting' forward of the car is due to the angled
48 | segments of the track and the fact that I'm only checking the angle of the car and the surface it's on in the middle of the car mesh.
49 | I think I should try adding a marker above the front and rear wheels? but then more rotations if the front wheels should be higher
50 | than the rear wheels ughhhhhhhhhhhhhhhhhh ;_;. I just need to get the car more leveled about the z-axis (check z-axis rotations?).
51 |
52 | -----
53 | so it turns out it's pretty easy. just add a couple more height markers (one for the front and one for the rear of the car), just like
54 | what you do for the lateral rotation. and solve the problem the same way, except you're dealing with vectors that go along the x-axis.
55 | yay! :) the result looks pretty good.
56 |
57 | all that's left is to try to figure out how to get my rotations with the car and the front wheels (which rotate separately)
58 | when turning lined up properly.
59 |
60 | other/maybe helpful:
61 | https://stackoverflow.com/questions/25199173/how-to-find-rotation-matrix-between-two-vectors-in-three-js
62 | https://stackoverflow.com/questions/52977759/three-js-how-to-find-out-xyz-rotations-between-two-vectors
63 | https://stackoverflow.com/questions/43606135/split-quaternion-into-axis-rotations
64 |
65 | for turning the car:
66 | https://asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html
--------------------------------------------------------------------------------
/car_demo/pictures/angle-correction.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/angle-correction.png
--------------------------------------------------------------------------------
/car_demo/pictures/angle-correction2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/angle-correction2.png
--------------------------------------------------------------------------------
/car_demo/pictures/car_demo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/car_demo.webp
--------------------------------------------------------------------------------
/car_demo/pictures/debugging.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/debugging.gif
--------------------------------------------------------------------------------
/car_demo/pictures/ideas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/ideas.png
--------------------------------------------------------------------------------
/car_demo/pictures/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/screenshot.png
--------------------------------------------------------------------------------
/car_demo/pictures/tilting_bad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/car_demo/pictures/tilting_bad.png
--------------------------------------------------------------------------------
/car_demo/readme.md:
--------------------------------------------------------------------------------
1 | # car demo
2 |
3 | For this project I originally just wanted to make a car and display it but then I decided to go further and explore car movement on an angled track.
4 |
5 | ## notes:
6 |
7 | 1. getting the car tilted the right way on an angled road
8 | One challenge was getting the car to tilt correctly when it was on a sloped part of the road. I had to adjust the lateral angle of the car (left-to-right) as well as the forward/backward (longitudinal?) tilt angle.
9 | Below is a sketch of my idea to solve this (it shows the lateral angle but the same idea is applied to the forward/backward angle, just on a different axis).
10 |
11 | 
12 |
13 | You can see below some of the lines I drew to help debug. The cyan and red lines are normal vectors of the car model and of the face of the track model that the car was on. I tried to solve the problem using normal vectors but that didn't work out for me, but I left them in because it looks cool :).
14 |
15 | 
16 |
17 | 
18 |
19 | 2. turning the car based on the front wheels' angle
20 | Another fun problem is getting the car model to turn based on the angle of the front wheels. Initially I thought I could just rotate the car model a bit when the front wheels are angled, which sort of works.
21 |
22 | I also found this amazingly helpful page (https://asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html), which I think helped me calculate a better amount to rotate my car when the front wheels are turned.
23 |
24 | One issue that still stands is that when turning the wheels quickly while moving, the car movement is not realistic possibly because I'm rotating the whole car, which includes the front wheels, when the front wheels are already angled.
--------------------------------------------------------------------------------
/character_demo/animation_state_map.json:
--------------------------------------------------------------------------------
1 | {
2 | "states": {
3 | "normal": {
4 | "idle-arms": {
5 | "actionName": "idlearmsonly",
6 | "loop": "repeat",
7 | "top": true
8 | },
9 | "idle-legs": {
10 | "actionName": "idlelegsonly",
11 | "loop": "repeat",
12 | "bottom": true
13 | },
14 | "run-arms": {
15 | "actionName": "runarmsonly",
16 | "loop": "repeat",
17 | "top": true
18 | },
19 | "run-legs": {
20 | "actionName": "runlegsonly",
21 | "loop": "repeat",
22 | "bottom": true
23 | },
24 | "walk-arms": {
25 | "actionName": "walkarmsonly",
26 | "loop": "repeat",
27 | "top": true
28 | },
29 | "walk-legs": {
30 | "actionName": "walklegsonly",
31 | "loop": "repeat",
32 | "bottom": true
33 | },
34 | "jump": {
35 | "actionName": "jump",
36 | "loop": "once"
37 | },
38 | "drawgun": {
39 | "actionName": "drawgunarmsonly",
40 | "loop": "once",
41 | "top": true
42 | },
43 | "leftlean": {
44 | "actionName": "leanleftgunarmsonly",
45 | "loop": "repeat",
46 | "top": true
47 | },
48 | "rightlean": {
49 | "actionName": "leanrightgunarmsonly",
50 | "loop": "repeat",
51 | "top": true
52 | }
53 | },
54 | "equip": {
55 | "idle-arms": {
56 | "actionName": "holdgunarmsonly",
57 | "loop": "repeat",
58 | "top": true
59 | },
60 | "idle-legs": {
61 | "actionName": "idlelegsonly",
62 | "loop": "repeat",
63 | "bottom": true
64 | },
65 | "walk-arms": {
66 | "actionName": "holdgunarmsonly",
67 | "loop": "repeat",
68 | "top": true
69 | },
70 | "walk-legs": {
71 | "actionName": "walklegsonly",
72 | "loop": "repeat",
73 | "bottom": true
74 | },
75 | "run-legs": {
76 | "actionName": "runlegsonly",
77 | "loop": "repeat",
78 | "bottom": true
79 | },
80 | "run-arms": {
81 | "actionName": "holdgunarmsonly",
82 | "loop": "repeat",
83 | "top": true
84 | },
85 | "reload": {
86 | "actionName": "reloadgun",
87 | "loop": "once",
88 | "top": true
89 | },
90 | "drawgun": {
91 | "actionName": "drawgunarmsonly",
92 | "loop": "once",
93 | "top": true
94 | },
95 | "leftlean": {
96 | "actionName": "leanleftgunarmsonly",
97 | "loop": "repeat",
98 | "top": true
99 | },
100 | "rightlean": {
101 | "actionName": "leanrightgunarmsonly",
102 | "loop": "repeat",
103 | "top": true
104 | }
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/character_demo/blender/humanoid-rig-with-gun.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/character_demo/blender/humanoid-rig-with-gun.blend
--------------------------------------------------------------------------------
/character_demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | character animation test
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
controls:
52 |
w, s to move forward/backward. a, d to turn left/right. hold shift to run. g to toggle weapon equip. 1 to toggle first-person view.
53 |
note: the green cube in the location of the character's head serves as a starting point for the raycaster to use when adjusting the vertical position on uneven terrain.
54 |
55 |
56 |
57 |
58 |
59 |
61 |
--------------------------------------------------------------------------------
/character_demo/notes.txt:
--------------------------------------------------------------------------------
1 | testing character animations/movement with a low-poly humanoid
2 |
3 | having trouble with the imported mesh :'(
4 | https://stackoverflow.com/questions/42886821/blender-exported-json-model-shows-wrong-animations-in-three-js
5 |
6 | outdated but maybe still useful: https://unboring.net/workflows/animation.html
7 |
8 | this is so helpful :'): https://gltf-viewer.donmccurdy.com/
9 |
10 | when using animations in threejs, make sure to attach the root bone to the skinned mesh, otherwise everything will be weird.
11 | i.e. if child.type === "SkinnedMesh" -> child.add(child.skeleton.bones[0])
12 |
13 | handling uneven terrain movement (panda3d looks like a good resource to learn a bunch of other things as well):
14 | https://docs.panda3d.org/1.10/python/programming/pandai/pathfinding/uneven-terrain
15 |
16 |
--------------------------------------------------------------------------------
/character_demo/pictures/character_demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/character_demo/pictures/character_demo.gif
--------------------------------------------------------------------------------
/character_demo/pictures/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/character_demo/pictures/screenshot.png
--------------------------------------------------------------------------------
/character_demo/readme.md:
--------------------------------------------------------------------------------
1 | # character demo
2 |
3 | For this project I wanted to explore character movement!
4 |
5 | ## notes:
6 |
7 | 1. terrain adjustment
8 | Based on the character's current elevation relative to "ground" level, the character's y-position will change so it's always on the terrain properly. To do this I assumed an initial height as a baseline value for being leveled with
9 | the ground. I placed a 'dummy' object (a small green cube) placed in the middle of the character at a height around where the head is. In each update call, a raycast is made downwards from the 'dummy' object to the ground mesh and the distance is compared with the initial baseline distance.
10 | If the current distance is lower than the initial distance, then the character is on higher elevation and its y-position needs to be increased and vice-versa if the current distance is greater.
11 | This link is extremely helpful: https://docs.panda3d.org/1.10/python/programming/pandai/pathfinding/uneven-terrain
12 |
13 | 2. weapon attachment
14 | Attaching a weapon is fairly straight-forward. I just attached the weapon mesh to one of the hand bones in my character mesh as a child. It was a bit difficult to position the weapon though in the hand since it seemed
15 | the coordinate system of the weapon was different.
16 |
17 | 3. added an animation controller
18 | Animating with several actions and managing them became a bit difficult quickly without having an additional object to help.
19 |
20 | 4. Player model animations are split into two parts: a top and bottom so that each animation controls a separate set of bones so that we can mix and match different animations that only concern a specifc set of bones. This is useful (or perhaps necessary?) for handling instances like running with a weapon equipped vs. running without a weapon equipped or running while leaning left/right. Initially I had full character model animations but that proved to be too limiting (also it might be a bit less work to do half-body animations instead of full-body ones).
--------------------------------------------------------------------------------
/curves/README.md:
--------------------------------------------------------------------------------
1 | # curves
2 |
3 | playing with curves (just Catmull-Rom though atm) and using them as paths for object movement (e.g. for aircraft :D).
4 |
5 | 
--------------------------------------------------------------------------------
/curves/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/curves/demo.gif
--------------------------------------------------------------------------------
/curves/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | curves
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
w, s to move forward/backward. a, d to turn left/right. hold shift to run. g to toggle weapon equip. 1 to toggle first-person view. when weapon is equipped, click on the canvas to fire a projectile.
51 |
3 to toggle player mesh visibility. 4 to switch weapon (this is a bit buggy right now).
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
67 |
--------------------------------------------------------------------------------
/fps/readme.md:
--------------------------------------------------------------------------------
1 | # fps
2 | ### a small demo to explore some fps game mechanics
3 |
4 | 
5 |
6 | This demo is a bit of an extension/combo of `character_demo` and `basketball`. It uses cannon.js to help with projectile collisions (although for the player character I instead chose to handle collisions manually since I couldn't figure out how to get a rigidbody properly set up for it). It doesn't really do much atm but you can launch cows :).
7 |
8 | TODO:
9 | - improve player model (specifically figure out how to set up model for first-person vs third-person mode)
10 | - be able to import any gltf model to use as projectile?
11 | - get lighting/shadows better
--------------------------------------------------------------------------------
/lava_lamp/README.md:
--------------------------------------------------------------------------------
1 | # lava_lamp
2 |
3 | a 3D lava lamp implementation using metaballs (adapted from https://webglsamples.org/blob/blob.html) for the lava and a lamp I made in Blender.
4 |
5 | 
--------------------------------------------------------------------------------
/lava_lamp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 3D lava lamp
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
35 |
36 |
37 |
38 |
instructions: use a mouse to draw on the canvas below containing the texture of the model! then click the 'update model' button. you can also rotate the model by clicking on the canvas of the model and moving your mouse (it has trackball controls).
67 |
currently kinda buggy but you can also paste in an image via ctrl+v and drag it into place, as well as resize it after pressing the 's' key and moving the mouse around or rotate it after pressing the 'r' key and using the mouse wheel.
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/livery_editor/notes.txt:
--------------------------------------------------------------------------------
1 | https://discoverthreejs.com/book/first-steps/textures-intro/
2 | https://github.com/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_012_TexturesImagesSamplers.md
3 | https://nicedoc.io/KhronosGroup/glTF-Tutorials/blob/master/gltfTutorial/gltfTutorial_002_BasicGltfStructure.md
4 | https://computergraphics.stackexchange.com/questions/3616/how-to-encode-decode-buffer-data-in-gltf
5 | https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings -> exploring the base64 buffer data uri in gltf files
6 | https://discourse.threejs.org/t/how-to-get-texture-file-bytes-embedded-in-glb-after-loading-it-in-the-scene-via-gltfloader/6569
7 | https://discourse.threejs.org/t/set-img-elements-src-from-texture-map-inside-material/9771/3
8 | https://stackoverflow.com/questions/41853580/three-js-export-a-texture-as-an-image
9 | https://discourse.threejs.org/t/solved-get-dimensions-of-material-texture-image-in-traverse/16875 -> the material.map.image got me what I wanted. pretty easy it turns out lol -_-
10 | https://stackoverflow.com/questions/18436431/three-js-update-texture-image
11 | https://discourse.threejs.org/t/updating-material-map/2381/2
12 | https://discourse.threejs.org/t/textures-map-incorrectly-to-gltf-object/11544/2
13 | https://stackoverflow.com/questions/41469623/preventdefault-and-stoppropagation-not-working-with-pointermove
--------------------------------------------------------------------------------
/livery_editor/readme.md:
--------------------------------------------------------------------------------
1 | # livery_editor
2 | ### a small demo that allows the editing of textures and creation of new livery for models
3 |
4 | 
5 |
6 | Features are limited since this is intended to be just a proof-of-concept. This could probably be extended though to include a more complete drawing/paintbrush tool and a smarter and/or easier way of editing textures perhaps.
7 |
8 | some other ideas:
9 | - is it possible to draw on the model itself?
10 | - can we achieve a mirroring effect on the model when drawing on a texture?
11 | - how about pasting images onto the texture like decals for plastic models?
--------------------------------------------------------------------------------
/livery_editor/yuyushiki-itasha-example-lol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/livery_editor/yuyushiki-itasha-example-lol.png
--------------------------------------------------------------------------------
/models/080415pianobgm3popver-edit-steinway.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/080415pianobgm3popver-edit-steinway.ogg
--------------------------------------------------------------------------------
/models/battleship2.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/battleship2.glb
--------------------------------------------------------------------------------
/models/dangerous-capsule-edit-final.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/dangerous-capsule-edit-final.glb
--------------------------------------------------------------------------------
/models/depositphotos_65970561-stock-photo-asphalt-texture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/depositphotos_65970561-stock-photo-asphalt-texture.jpg
--------------------------------------------------------------------------------
/models/f-18.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/f-18.glb
--------------------------------------------------------------------------------
/models/grass2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/grass2.jpg
--------------------------------------------------------------------------------
/models/oceanfloor.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/oceanfloor.glb
--------------------------------------------------------------------------------
/models/submarine1.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/submarine1.glb
--------------------------------------------------------------------------------
/models/whale-shark-camo.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/models/whale-shark-camo.glb
--------------------------------------------------------------------------------
/new_project_template/README.md:
--------------------------------------------------------------------------------
1 | # new_project_template
2 |
3 | Talk about your new project.
4 |
5 | ![show a gif or screenshot here!]()
--------------------------------------------------------------------------------
/new_project_template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | new_project_template
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
click and drag on the canvas to move around and use a mouse clickwheel to zoom in/out
67 |
68 |
69 |
70 |
71 |
72 |
73 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/shaders/notes.txt:
--------------------------------------------------------------------------------
1 | https://aerotwist.com/tutorials/an-introduction-to-shaders-part-1/
2 | http://aerotwist.com/tutorials/an-introduction-to-shaders-part-2/
3 | https://thebookofshaders.com/02/ -> this only concerns the fragment shader
4 | https://threejs.org/docs/#api/en/materials/ShaderMaterial
5 | https://stackoverflow.com/questions/37398013/animating-custom-shader-in-webgl-three-js
6 | https://shader-tutorial.dev/basics/vertex-shader/
7 | https://threejsfundamentals.org/threejs/lessons/threejs-shadertoy.html
8 | https://blog.scottlogic.com/2019/10/17/sculpting-shapes-with-webgl-fragment-shader.html
9 | https://github.com/mrdoob/three.js/blob/master/examples/webgl_buffergeometry_rawshader.html
10 | https://github.com/mrdoob/three.js/blob/master/examples/webgl2_volume_cloud.html
11 | https://stackoverflow.com/questions/66741338/simple-square-using-buffergeometry
12 | http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
13 | https://discourse.threejs.org/t/shader-randomize-point-positions-from-origins/6689/2
14 | https://stackoverflow.com/questions/23899887/passing-pointlight-info-to-a-custom-shader-with-three-js
15 | https://stackoverflow.com/questions/42170992/three-js-change-attributes-value-in-vertex-shader-and-pass-to-buffer -> this is interesting
16 | https://observablehq.com/@camargo/three-js-utah-teapot-with-a-custom-phong-shader-material
17 | https://stackoverflow.com/questions/17537879/in-webgl-what-are-the-differences-between-an-attribute-a-uniform-and-a-varying
18 | https://threejs.org/docs/#api/en/core/Uniform
19 |
20 | notes
21 | might need to grab the uv coords of my imported model and pass them to the shaders? https://jsfiddle.net/f2Lommf5/16541/
22 | -> nope, just needed make sure the texture's flipY was set to false
23 |
24 | colors for rgba channels in shaders range from 0-1, not 0-255!! somehow I didn't notice that even when the alpha channel was set to 1 and I
25 | wasted a ton of time trying to figure out why different colors weren't working -_-.
--------------------------------------------------------------------------------
/shaders/raymarching.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/shaders/raymarching.png
--------------------------------------------------------------------------------
/shaders/readme.md:
--------------------------------------------------------------------------------
1 | ## shaders
2 |
3 | having fun with shaders. there's so much you can do with them! :O
4 |
5 | 1. jet
6 | - the color and position of vertices of the model changes based on time to create a bit of a "morphing" jet
7 |
8 | 2. jet2
9 | - another jet model but this time featuring the Blinn-Phong reflection model
10 |
11 | 3. whale shark
12 | - a colorful, glowing whale shark (the color (plus a bit of noise) changes over time on the white parts of the shark)
13 |
14 | 4. springy shards
15 | - a bunch of rotating squares whose vertices and colors change over time to form a swirling pattern
16 | - the squares are created using BufferGeometry and the shaders are attached to the BufferGeometry
17 |
18 | 5. raymarching
19 | - a basic, minimal raymarching example
--------------------------------------------------------------------------------
/shaders/shaders/glassShader.js:
--------------------------------------------------------------------------------
1 | // "glass" shader derived from my toon shader
2 | // not that great atm but a starting point at least?
3 | // needs refraction
4 | //
5 | // ideas and things to read:
6 | // https://godotshaders.com/shader-tag/glass/
7 | // https://kylehalladay.com/blog/tutorial/2014/02/18/Fresnel-Shaders-From-The-Ground-Up.html
8 | // https://blog.maximeheckel.com/posts/refraction-dispersion-and-other-shader-light-effects/
9 | // https://community.khronos.org/t/refraction-shader/60635
10 |
11 | const glassShader = {
12 | vertexShader: `
13 | varying vec2 vUv;
14 | varying vec3 vNormal;
15 | varying float fresnel; // Fresnel factor
16 |
17 | void main() {
18 | vUv = uv;
19 | vNormal = normal;
20 | gl_Position = projectionMatrix *
21 | modelViewMatrix *
22 | vec4(position, 1.0);
23 |
24 | // calculate Fresnel factor
25 | vec3 I = normalize(gl_Position.xyz - cameraPosition); // we get cameraPosition for free! (https://threejs.org/docs/#api/en/renderers/webgl/WebGLProgram)
26 | fresnel = pow(1.0 + dot(I, normal), 3.5);
27 | }
28 | `,
29 |
30 | fragShader: `
31 | varying vec2 vUv;
32 | varying vec3 vNormal;
33 | varying float fresnel;
34 | uniform sampler2D img;
35 |
36 | vec3 diffuseLightDir = vec3(1, 1, 0); // change?
37 | vec4 diffuseColor = vec4(1, 1, 1, 0.3);
38 | float diffuseIntensity = 1.5;
39 |
40 | void main() {
41 | float intensity = dot(normalize(diffuseLightDir), vNormal);
42 | if(intensity < 0.){
43 | intensity = 0.;
44 | }
45 |
46 | float alpha = 0.82; // for transparency
47 |
48 | vec4 txColor = vec4(1, 1, 1, 1) * diffuseColor * diffuseIntensity; // change color here
49 |
50 | if(intensity > 0.95){
51 | gl_FragColor = vec4(1, 1, 1, alpha) * vec4(txColor.rgba);
52 | }else if(intensity > 0.5){
53 | gl_FragColor = vec4(0.7, 0.7, 0.7, alpha) * vec4(txColor.rgba);
54 | }else if(intensity > 0.05){
55 | gl_FragColor = vec4(0.35, 0.35, 0.35, alpha) * vec4(txColor.rgba);
56 | }else{
57 | gl_FragColor = vec4(0.1, 0.1, 0.1, alpha) * vec4(txColor.rgba);
58 | }
59 |
60 | gl_FragColor = mix(txColor, gl_FragColor, fresnel);
61 | }
62 | `,
63 | };
--------------------------------------------------------------------------------
/shaders/shaders/jetModelShader.js:
--------------------------------------------------------------------------------
1 | const jetModelShader = {
2 | vertexShader: `
3 | varying vec2 vUv;
4 | uniform float u_time;
5 |
6 | // http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
7 | mat4 getRotationMat(vec3 axis, float angle){
8 | float s = sin(angle);
9 | float c = cos(angle);
10 | float oc = 1.0 - c;
11 |
12 | return mat4(
13 | oc*axis.x*axis.x + c, oc*axis.x*axis.y - axis.z*s, oc*axis.z*axis.x + axis.y*s, 0.0,
14 | oc*axis.x*axis.y + axis.z*s, oc*axis.y*axis.y + c, oc*axis.y*axis.z + axis.x*s, 0.0,
15 | oc*axis.x*axis.z - axis.y*s, oc*axis.y*axis.z + axis.x*s, oc*axis.z*axis.z + c, 0.0,
16 | 0.0, 0.0, 0.0, 1.0
17 | );
18 | }
19 |
20 | float rand(vec2 pos){
21 | return fract(sin(dot(pos, vec2(12.9898,78.233)))*43758.5453123);
22 | }
23 |
24 | void main() {
25 | vUv = uv;
26 |
27 | mat4 rotZ = getRotationMat(vec3(0, 0, 1), sin(0.5*u_time));
28 |
29 | float randVal = rand(uv);
30 |
31 | float xDelta = position.x*randVal*sin(0.8*u_time);
32 | float zDelta = position.z*randVal*cos(0.7*u_time);
33 |
34 | gl_Position = projectionMatrix *
35 | modelViewMatrix *
36 | rotZ *
37 | vec4(position.x+xDelta, position.y, position.z+zDelta, 1.0);
38 | }
39 | `,
40 | fragShader: `
41 | varying vec2 vUv;
42 | uniform sampler2D img;
43 | uniform float u_time;
44 | uniform vec2 u_resolution; // dimensions of renderer
45 |
46 | float interpolate(float val){
47 | return clamp(smoothstep(0.2, 1.0, val), 0.3, 1.0); // let lowest possible val be 0.3
48 | }
49 |
50 | void main() {
51 | vec2 pt = gl_FragCoord.xy/u_resolution.xy;
52 |
53 | vec4 txColor = texture2D(img, vUv);
54 |
55 | gl_FragColor = vec4(
56 | interpolate(txColor.r*abs(sin(u_time))),
57 | interpolate(txColor.g*abs(sin(u_time))),
58 | interpolate(txColor.b*abs(sin(u_time))),
59 | 1.0);
60 | }
61 | `,
62 | };
--------------------------------------------------------------------------------
/shaders/shaders/jetModelShader2.js:
--------------------------------------------------------------------------------
1 | // PPBS - per-pixel blinn-phong shading
2 |
3 | const jetModelShader2 = {
4 | vertexShader: `
5 | uniform vec4 lightPosition[1];
6 |
7 | out vec4 direction[1];
8 | out vec4 halfVectors[1];
9 | out vec4 norm;
10 | out vec2 vUv;
11 |
12 | void main() {
13 | vUv = uv;
14 |
15 | vec4 vertexPos = modelViewMatrix * vec4(position, 1.0);
16 | vec4 viewPos = normalize(-vertexPos);
17 |
18 | vec4 dir = normalize(lightPosition[0] - vertexPos);
19 | direction[0] = dir;
20 |
21 | // calculate halfway vector
22 | vec4 halfVector = normalize(dir + viewPos);
23 | halfVectors[0] = halfVector;
24 |
25 | norm = vec4((normalMatrix * normal), 0); // normalMatrix comes for free
26 |
27 | gl_Position = projectionMatrix *
28 | modelViewMatrix *
29 | vec4(position, 1.0);
30 | }
31 | `,
32 |
33 | fragShader: `
34 | uniform sampler2D img;
35 | uniform float u_time;
36 | uniform vec2 u_resolution;
37 | uniform float shininess;
38 | uniform vec3 diffuseLight[1];
39 | uniform vec3 specularLight[1];
40 | uniform vec4 lightIntensity[1];
41 |
42 | // variables passed in from the vertex shader
43 | in vec4 direction[1]; // light direction
44 | in vec4 halfVectors[1];
45 | in vec4 norm;
46 | in vec2 vUv;
47 |
48 | void main() {
49 | vec4 color = texture2D(img, vUv);
50 |
51 | // calculate ndotl (normal dot light direction) here
52 | float ndotl = max(dot(norm, direction[0]), 0.);
53 |
54 | // calculate specular contribution via (halfVector*normal)^shininess
55 | float specular = pow(max(dot(halfVectors[0], norm), 0.), shininess);
56 |
57 | vec4 diff = ndotl * vec4(diffuseLight[0], 0);
58 | vec4 spec = specular * vec4(specularLight[0], 0);
59 | color = (lightIntensity[0] * (diff + spec + color));
60 |
61 | gl_FragColor = color;
62 | }
63 | `,
64 |
65 | };
--------------------------------------------------------------------------------
/shaders/shaders/raymarchShader.js:
--------------------------------------------------------------------------------
1 | // https://stackoverflow.com/questions/50363915/curve-rotation-in-glsl-fragment-shader
2 | // https://riccardoscalco.it/blog/volume-ray-casting/
3 | // https://stackoverflow.com/questions/9066836/opengl-point-sprites-rotation-in-fragment-shader
4 | // https://math.stackexchange.com/questions/3360969/scale-rotate-skew-a-2d-shape-to-look-like-3d
5 | // this one is pretty useful and minimal so it's easy to understand - https://www.shadertoy.com/view/fdB3Rh
6 | // https://adrianb.io/2016/10/01/raymarching.html#fun-with-distance-fields - useful and helps explain stuff like opU()
7 | // and of course Inigo Quilez's sdf primitives demo (but pretty complicated and hard to break down into easy-to-understand parts): https://www.shadertoy.com/view/Xds3zN
8 |
9 | const raymarchShader = {
10 | vertexShader: `
11 | out vec2 vUv;
12 | void main() {
13 | vUv = uv;
14 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
15 | }
16 | `,
17 |
18 | fragShader: `
19 | #define pi 3.141592653
20 |
21 | uniform float u_time;
22 | uniform vec2 u_resolution;
23 |
24 | in vec2 vUv;
25 |
26 | float sdfSphere(vec3 p, float s){
27 | return length(p)-s;
28 | }
29 |
30 | float sdfPlane(vec3 p){
31 | return p.y;
32 | }
33 |
34 | // union function to return the closest position - necessary when raymarching
35 | vec2 opU(vec2 d1, vec2 d2){
36 | return (d1.x < d2.x) ? d1 : d2;
37 | }
38 |
39 | // add all the objects in the scene
40 | vec2 assembleScene(vec3 p){
41 | // put shapes into position
42 |
43 | // sphere 1
44 | vec3 pos1 = p - vec3(-2., 0.3, 8.);
45 | pos1.x += 0.3*cos(u_time);
46 | pos1.z += 0.3*cos(u_time);
47 | pos1.y += sin(u_time);
48 |
49 | vec2 s1 = vec2(sdfSphere(pos1, 0.7), 0.);
50 |
51 | // sphere 2
52 | vec3 pos2 = p - vec3(2.5, 1.2, 20.);
53 | pos2.x += cos(u_time);
54 | pos2.y -= 0.8*sin(u_time);
55 | vec2 s2 = vec2(sdfSphere(pos2, 1.5), 0.);
56 |
57 | // add sphere 1 and 2
58 | vec2 ret = opU(s1, s2);
59 |
60 | // add some more spheres
61 | int numSpheres = 8;
62 | float radSlice = (360. / float(numSpheres)) * (3.14159 / 180.);
63 | for(float i = 0.; i < float(numSpheres); i++){
64 | vec3 pos = p - vec3(cos(i*radSlice), 0.5, 5.+sin(i*radSlice));
65 |
66 | pos.x += cos(i*radSlice+u_time);
67 | pos.z += cos(i*radSlice+u_time);
68 | pos.y += sin(radSlice+u_time);
69 |
70 | vec2 s = vec2(sdfSphere(pos, 0.2), 0.);
71 |
72 | ret = opU(s, ret);
73 | }
74 |
75 | //ret = opU(vec2(sdfPlane(p)), ret);
76 |
77 | return ret;
78 | }
79 |
80 | // https://www.shadertoy.com/view/Xds3zN
81 | vec3 generateNormal(vec3 p){
82 | vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
83 | return normalize( e.xyy*assembleScene( p + e.xyy ).x +
84 | e.yyx*assembleScene( p + e.yyx ).x +
85 | e.yxy*assembleScene( p + e.yxy ).x +
86 | e.xxx*assembleScene( p + e.xxx ).x );
87 | }
88 |
89 | // https://adrianb.io/2016/10/01/raymarching.html#fun-with-distance-fields
90 | // ro = ray origin
91 | // rd = ray direction
92 | vec3 raymarch(vec3 ro, vec3 rd){
93 | vec3 ret = vec3(1.);
94 |
95 | int maxSteps = 60;
96 | float currRayDist = 0.;
97 |
98 | for(int i = 0; i < maxSteps; i++){
99 | vec3 p = ro+rd*currRayDist;
100 | vec2 d = assembleScene(p);
101 |
102 | if(d.x < 0.0001){
103 | vec3 n = generateNormal(p);
104 |
105 | // calculate color here (https://www.shadertoy.com/view/fdB3Rh)
106 | vec3 lightPos = vec3(0.0, 0.0, 1.0);
107 | //lightPos.xy += vec2(sin(u_time), cos(u_time)) * 2.;
108 | vec3 l = normalize(lightPos - p);
109 | float diff = clamp(dot(n, l), 0.0, 1.0);
110 |
111 | return vec3(0.9*abs(cos(u_time)), 0.9*abs(sin(u_time)), 0.9*abs(cos(u_time))) * diff;
112 | }
113 |
114 | currRayDist += d.x;
115 | }
116 |
117 | return ret;
118 | }
119 |
120 |
121 | void main() {
122 | vec2 st = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / u_resolution.y; // TODO: how to get frag coord relative to plane mesh and not canvas?
123 |
124 | vec3 ro = vec3(0, 1, 0);
125 | vec3 rd = normalize(vec3(st.x, st.y, 1));
126 | vec3 d = raymarch(ro, rd);
127 |
128 | gl_FragColor = vec4(d, 1.0);
129 | }
130 | `,
131 |
132 | };
--------------------------------------------------------------------------------
/shaders/shaders/rippleShader.js:
--------------------------------------------------------------------------------
1 | // https://github.com/twostraws/ShaderKit/blob/main/Shaders/SHKCircleWaveBlended.fsh
2 | // https://github.com/syncopika/music-visualizer/commit/e19ef49c5397e2a37332ca93cbff27ea2796d33f#diff-335967cf3a911f85b6f20eaedc439032b6722b9a81b0938d60d0cf6a18f94c7c
3 |
4 | const rippleShader = {
5 | vertexShader: `
6 | out vec2 vUv;
7 |
8 | void main() {
9 | vUv = uv;
10 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
11 | }
12 | `,
13 |
14 | fragShader: `
15 | uniform float u_time;
16 | uniform vec2 u_resolution;
17 |
18 | in vec2 vUv;
19 |
20 | // ripple parameters
21 | uniform vec2 center;
22 | uniform vec4 color;
23 | uniform float speed;
24 | uniform float density;
25 | uniform float strength;
26 | uniform float brightness;
27 |
28 | void main() {
29 | vec2 pt = vUv.xy; //gl_FragCoord.xy/u_resolution.xy; -> this gets a fragment's position relative to viewport and not relative to mesh
30 | vec4 col = color;
31 |
32 | float waveSpeed = -(u_time * speed * 10.0);
33 |
34 | vec3 brightness = vec3(brightness);
35 | float pixelDist = distance(pt, center);
36 |
37 | if(pixelDist > 0.5){
38 | gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
39 | return;
40 | }
41 |
42 | if(color.r == 1.0 && color.g == 1.0 && color.b == 1.0 && color.a == 0.0){
43 | gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);
44 | return;
45 | }
46 |
47 | vec3 gradientColor = vec3(color.r, color.g, color.b) * brightness;
48 |
49 | // we can tune the ripple to audio data! e.g.
50 | // set gradient color to be a function of the freq bin delta
51 | // if (freqBinDelta > 0) gradientColor *= freqBinDelta * 2.0;
52 |
53 | float colorStrength = pow(1.0 - pixelDist, 3.0);
54 | colorStrength *= strength;
55 |
56 | float waveDensity = density * pixelDist;
57 | float cosine = cos(waveSpeed + waveDensity);
58 | float cosAdjust = (0.5 * cosine) + 0.5;
59 |
60 | float lumi = colorStrength * (strength + cosAdjust);
61 | lumi *= 1.0 - (pixelDist * 2.0);
62 | lumi = max(0.0, lumi);
63 |
64 | vec3 newColor = gradientColor * lumi;
65 | vec4 final = vec4(newColor.r, newColor.g, newColor.b, lumi);
66 | vec4 finalColor = mix(col, final, lumi) * col.w;
67 |
68 | // make alpha be a function of distance from center
69 | finalColor.a = pixelDist / 4.0;
70 |
71 | gl_FragColor = finalColor;
72 |
73 | }
74 | `,
75 |
76 | };
--------------------------------------------------------------------------------
/shaders/shaders/springyShardShader.js:
--------------------------------------------------------------------------------
1 | const springyShardShader = {
2 | vertexShader: `
3 | uniform float u_time;
4 |
5 | attribute vec4 color;
6 | varying vec4 vColor;
7 |
8 | // https://thebookofshaders.com/10/
9 | float rand(vec2 pos){
10 | return fract(sin(dot(pos, vec2(12.9898,78.233)))*43758.5453123);
11 | }
12 |
13 | // http://www.neilmendoza.com/glsl-rotation-about-an-arbitrary-axis/
14 | mat4 getRotationMat(vec3 axis, float angle){
15 | float s = sin(angle);
16 | float c = cos(angle);
17 | float oc = 1.0 - c;
18 |
19 | return mat4(
20 | oc*axis.x*axis.x + c, oc*axis.x*axis.y - axis.z*s, oc*axis.z*axis.x + axis.y*s, 0.0,
21 | oc*axis.x*axis.y + axis.z*s, oc*axis.y*axis.y + c, oc*axis.y*axis.z + axis.x*s, 0.0,
22 | oc*axis.x*axis.z - axis.y*s, oc*axis.y*axis.z + axis.x*s, oc*axis.z*axis.z + c, 0.0,
23 | 0.0, 0.0, 0.0, 1.0
24 | );
25 | }
26 |
27 | void main() {
28 | vColor = color;
29 |
30 | float randVal = rand(vec2(position.xy));
31 |
32 | mat4 rotZ = getRotationMat(vec3(0,0,1), randVal*cos(u_time)); // rotate about the z axis
33 |
34 | // rotate and move the squares along the z axis
35 | gl_Position = projectionMatrix * modelViewMatrix * rotZ * vec4(position.x, position.y, (1.+randVal)*position.z*abs(cos(0.3*u_time)), 1.0);
36 | }
37 | `,
38 |
39 | fragShader: `
40 | uniform sampler2D img;
41 | uniform float u_time;
42 | uniform vec2 u_resolution; // dimensions of renderer canvas
43 | varying vec4 vColor;
44 |
45 | void main() {
46 | gl_FragColor = vec4(
47 | vColor.r*abs(cos(u_time))*1.3,
48 | vColor.g*abs(sin(u_time))*1.6,
49 | vColor.b*abs(cos(u_time))*1.2,
50 | 1.0);
51 | }
52 | `,
53 | };
--------------------------------------------------------------------------------
/shaders/shaders/toonShader.js:
--------------------------------------------------------------------------------
1 | // http://rbwhitaker.wikidot.com/toon-shader
2 |
3 | const toonShader = {
4 | vertexShader: `
5 | varying vec2 vUv;
6 | varying vec3 vNormal;
7 |
8 | // toon shader properties
9 | //vec4 lineColor = vec4(0, 0, 0, 1);
10 | //float lineThickness = .03;
11 |
12 | // TODO: need to add outline
13 | // do I need to add a separate pass shader?
14 |
15 | void main() {
16 | vUv = uv;
17 | vNormal = normal;
18 | gl_Position = projectionMatrix *
19 | modelViewMatrix *
20 | vec4(position, 1.0);
21 | }
22 | `,
23 |
24 | fragShader: `
25 | varying vec2 vUv;
26 | varying vec3 vNormal;
27 | uniform sampler2D img;
28 |
29 | vec3 diffuseLightDir = vec3(1, 1, 0); // change?
30 | vec4 diffuseColor = vec4(1, 1, 1, 1);
31 | float diffuseIntensity = 1.5;
32 |
33 | void main() {
34 | float intensity = dot(normalize(diffuseLightDir), vNormal);
35 | if(intensity < 0.){
36 | intensity = 0.;
37 | }
38 |
39 | vec4 txColor = vec4(0, 0, 1, 1.0) * diffuseColor * diffuseIntensity; // some shade of blue
40 |
41 | if(intensity > 0.95){
42 | gl_FragColor = vec4(1, 1, 1, 1.0) * vec4(txColor.rgb, 1.0);
43 | }else if(intensity > 0.5){
44 | gl_FragColor = vec4(0.7, 0.7, 0.7, 1.0) * vec4(txColor.rgb, 1.0);
45 | }else if(intensity > 0.05){
46 | gl_FragColor = vec4(0.35, 0.35, 0.35, 1.0) * vec4(txColor.rgb, 1.0);
47 | }else{
48 | gl_FragColor = vec4(0.1, 0.1, 0.1, 1.0) * vec4(txColor.rgb, 1.0);
49 | }
50 | }
51 | `,
52 | };
--------------------------------------------------------------------------------
/shaders/shaders/whaleSharkShader.js:
--------------------------------------------------------------------------------
1 | const whaleSharkShader = {
2 | vertexShader: `
3 | varying vec2 vUv;
4 | uniform float u_time;
5 |
6 | void main() {
7 | vUv = uv;
8 |
9 | gl_Position = projectionMatrix *
10 | modelViewMatrix *
11 | vec4(position, 1.0);
12 | }
13 | `,
14 |
15 | fragShader: `
16 | varying vec2 vUv;
17 | uniform sampler2D img;
18 | uniform float u_time;
19 | uniform vec2 u_resolution; // dimensions of renderer
20 |
21 | float rand(vec2 pos){
22 | return fract(sin(dot(pos, vec2(12.9898,78.233)))*43758.5453123);
23 | }
24 |
25 | void main() {
26 | vec2 pt = gl_FragCoord.xy/u_resolution.xy;
27 |
28 | vec4 txColor = texture2D(img, vUv);
29 |
30 | // color only certain parts of the shark!
31 | if(txColor.r < 0.5 && txColor.g < 0.5 && txColor.b < 0.5){
32 | gl_FragColor = vec4(txColor.rgb, 1.0);
33 | }else{
34 | gl_FragColor = vec4(
35 | 1.-txColor.r*abs(sin(0.2*u_time))*rand(pt), // rand(pt) adds some noise
36 | 1.-txColor.g*abs(cos(u_time))*rand(pt),
37 | 1.- txColor.b*abs(sin(0.1*u_time)),
38 | 1.0);
39 | }
40 | }
41 | `,
42 | };
--------------------------------------------------------------------------------
/snowboard/08-10-2023_103831.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/snowboard/08-10-2023_103831.gif
--------------------------------------------------------------------------------
/snowboard/093023humanoid.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/snowboard/093023humanoid.blend
--------------------------------------------------------------------------------
/snowboard/AnimationController.js:
--------------------------------------------------------------------------------
1 | // animation controller for snowboard demo. this one is a bit different from the animation controller
2 | // used for the character and fps demos since the snowboarder model utilizes full-body animations
3 | // instead of half-body animations.
4 |
5 | class AnimationController {
6 |
7 | mixer; // animation mixer
8 | clips; // all the clips for animation
9 | currAction; // current animation of character (action name) - rename to currAction
10 | currState; // the state of character e.g. object equip or not
11 | character; // a reference to the mesh that this controller belongs to
12 | timeDivisor; // number to divide the time by when updating (i.e. a smaller num == faster animation)
13 | animationMap; // for knowing which actions correspond to which states
14 |
15 | constructor(character, animMixer, animClips, clock){
16 | this.character = character;
17 | this.mixer = animMixer;
18 | this.clips = animClips;
19 | this.clock = clock;
20 | this.currAction = '';
21 | this.currState = '';
22 | this.currActionTimescale = 1;
23 | this.animationMap = null;
24 |
25 | fetch('animation_state_map.json')
26 | .then(response => response.json())
27 | .then(data => {
28 | this.animationMap = data.states;
29 | // modify some clips as needed according to the animation map
30 | for(const state in data.states){
31 | for(const action in data.states[state]){
32 | const actionParams = data.states[state][action];
33 | if(actionParams.loop === 'once'){
34 | const actionClip = this.mixer.clipAction(this.clips[actionParams.actionName]);
35 | actionClip.paused = false;
36 | actionClip.setLoop(THREE.LoopOnce);
37 | actionClip.clampWhenFinished = true;
38 | }
39 | }
40 | }
41 | });
42 | }
43 |
44 | toggleObjectVisibility(){
45 | for(const obj of this.objects){
46 | obj.visible = !obj.visible;
47 | }
48 | }
49 |
50 | addObject(obj){
51 | this.objects.push(obj);
52 | }
53 |
54 | setUpdateTimeDivisor(num){
55 | this.timeDivisor = num;
56 | }
57 |
58 | changeState(newState){
59 | this.currState = newState;
60 | }
61 |
62 | changeAction(newAction, timeScale=1){
63 | // if a diff state or timescale is different
64 | if(newAction !== this.currAction || timeScale !== this.currActionTimescale){
65 | this.playAnimation(newAction, this.clock.getDelta(), timeScale);
66 | }
67 | }
68 |
69 | // for now, keep it specific until I figure out what I'm doing
70 | // https://stackoverflow.com/questions/57255000/how-to-animate-2-objects-with-2-different-animations-one-after-another-in-3-js
71 | // possibly irrelevant but a good read nonetheless:
72 | // https://stackoverflow.com/questions/25417547/observer-pattern-vs-mediator-pattern
73 | //
74 | // note that actionToPlay should be a generic action name like walk or run.
75 | // the real animation clip name is derived below using this.animationMap and
76 | // the current character state (i.e. normal (no weapon), weapon-equipped, etc.)
77 | playAnimation(actionToPlay, time, timeScale){
78 | if(this.animationMap){
79 | if(this.animationMap[this.currState][actionToPlay] === undefined){
80 | return;
81 | }
82 |
83 | this.currActionTimescale = timeScale;
84 | this.mixer.stopAllAction();
85 |
86 | this.currAction = actionToPlay;
87 | actionToPlay = this.animationMap[this.currState][actionToPlay]['actionName'];
88 |
89 | const action = this.mixer.clipAction(this.clips[actionToPlay]);
90 |
91 | // https://stackoverflow.com/questions/31274674/reverse-keyframe-animation-in-three-js
92 | if(action.time === 0 && timeScale === -1) {
93 | action.time = action.getClip().duration;
94 | }
95 |
96 | action.timeScale = timeScale;
97 | action.play();
98 | }
99 | }
100 |
101 | // https://discourse.threejs.org/t/animations-looks-different-and-wrong-when-i-play-them-on-three-js/55410/2
102 | update(clockDelta){
103 | this.mixer.update((clockDelta ? clockDelta : this.clock.getDelta()) / this.timeDivisor);
104 | }
105 |
106 | }
107 |
108 | export {
109 | AnimationController
110 | };
--------------------------------------------------------------------------------
/snowboard/README.md:
--------------------------------------------------------------------------------
1 | # snowboarding
2 |
3 | This demo attempts to implement a snowboarding game without physics (so no colliders, gravity, etc.)! It extends some concepts from character demo and explores some new ones.
4 |
5 | some notes:
6 | - getting the snowboarder to match the angle of incline/decline when on a sloped surface
7 | assume forward vector is always (0, 0, 1) (so looking straight ahead relative to the snowboarder model) and find the angle needed to match the angle of the vector
8 | formed by the point on the slope that's hit by the raycast.
9 |
10 | I think I've sorta tackled this problem as well in a different way in my car demo.
11 |
12 | 
13 |
14 | - jumping logic was a bit tricky
15 | needed to know if player was still in the air by the time "jumping" should've ended (which means 1 full arc via sin()). for this I used another raycast to determine if the player is within a certain distance to be considered "on the ground".
16 |
17 | 
--------------------------------------------------------------------------------
/snowboard/animation_state_map.json:
--------------------------------------------------------------------------------
1 | {
2 | "states": {
3 | "normal": {
4 | "idle": {
5 | "actionName": "idle",
6 | "loop": "repeat"
7 | },
8 | "moving": {
9 | "actionName": "moving1",
10 | "loop": "repeat"
11 | },
12 | "jump": {
13 | "actionName": "jump",
14 | "loop": "once"
15 | },
16 | "braking": {
17 | "actionName": "braking",
18 | "loop": "repeat"
19 | },
20 | "turnleft": {
21 | "actionName": "turnleft",
22 | "loop": "repeat"
23 | },
24 | "turnright": {
25 | "actionName": "turnright",
26 | "loop": "repeat"
27 | },
28 | "grab": {
29 | "actionName": "grab",
30 | "loop": "repeat"
31 | },
32 | "tailgrab": {
33 | "actionName": "tailgrab",
34 | "loop": "repeat"
35 | }
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/snowboard/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | snowboarding
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 |
28 |
snowboarding
29 |
30 |
31 |
32 |
33 |
34 |
35 |
press W to move, A and D to turn, spacebar to slow down, J to jump, G or T (while jumping) to do a grab, shift to change camera view
36 |
37 |
38 |
39 |
40 |
42 |
--------------------------------------------------------------------------------
/snowboard/player-rotation-on-slope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/snowboard/player-rotation-on-slope.png
--------------------------------------------------------------------------------
/split-flap_display/05-11-2024_210722.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/split-flap_display/05-11-2024_210722.gif
--------------------------------------------------------------------------------
/split-flap_display/README.md:
--------------------------------------------------------------------------------
1 | # split-flap display idea
2 |
3 | This is an implementation of a [split-flap display](https://en.wikipedia.org/wiki/Split-flap_display#) idea I had.
4 |
5 | I'm cheating a bit though in that I only have one animation that rotates the split-flap display about 45 degrees. Running the animation repeatedly though, at least in my opinion, makes it appear that the display is actually rotating all the way around and moving the flaps. Every time the animation ends, I switch the textures of the top and bottom flaps to a new, random letter from the alphabet.
6 |
7 | 
--------------------------------------------------------------------------------
/split-flap_display/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | split-flap display
5 |
6 |
7 |
8 |
9 |
10 |
11 |
24 |
25 |
26 |
27 |
45 | w,a,s,d to move forward, left, backwards and right.
46 | q,e to roll left/right.
47 | up and down arrow to move up and down.
48 | shift to change camera view.
49 | x to turn on a spotlight.
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
--------------------------------------------------------------------------------
/super_submarine/notes.txt:
--------------------------------------------------------------------------------
1 | notes:
2 |
3 | You are a submarine tasked with providing underwater reconnaisance for the mother ship!
4 | Survey the ocean floor beneath the mother ship to find and disarm dangerous things, as well as to find and collect potentially useful things!
5 |
6 | Be careful not to hit anything or else your submarine will get damaged. if you get damaged enough, you shall perish. :(
7 |
8 | W = forward
9 | S = backward
10 | A = turn left
11 | D = turn right
12 | Q = spin left
13 | E = spin right
14 | up arrow key = turn upwards
15 | down arrow key = turn downwards
16 |
17 | references:
18 | if imported models are being difficult to orientate a certain way, just put them in a group object:
19 | https://stackoverflow.com/questions/59446956/how-can-i-change-the-position-of-an-imported-model-in-three-js
20 |
21 | Dr. Stemkoski's work is extremely helpful!
22 | https://github.com/stemkoski/stemkoski.github.com/blob/master/Three.js/Chase-Camera.html
23 | http://stemkoski.github.io/Three.js/Chase-Camera.html
24 |
25 | threex keyboard from Jerome Etienne to help with key bindings is super awesome as well
26 | https://github.com/jeromeetienne/threex.keyboardstate
27 |
28 | loading/progress bar
29 | https://stackoverflow.com/questions/35575065/how-to-make-a-loading-screen-in-three-js
30 |
31 | other stuff ---------------
32 | https://stackoverflow.com/questions/38305408/threejs-get-center-of-object
33 | https://stackoverflow.com/questions/11473755/how-to-detect-collision-in-three-js
34 |
35 | interesting idea:
36 | https://gamedev.stackexchange.com/questions/35013/how-to-handle-3d-collisions-using-raycasting-with-a-reflection-vector
37 |
38 | user a height map for terrain?
39 | https://stackoverflow.com/questions/15687678/issue-with-terrain-collision-using-three-js
40 |
41 | keydown firing multiple times (i.e. for key X) even though I press it only once:
42 | https://stackoverflow.com/questions/23386127/keydown-fires-multiple-times-before-keyup
43 |
44 | oooh good resource:
45 | https://threejsfundamentals.org/threejs/lessons/threejs-scenegraph.html
46 |
47 |
48 | to do ---------------
49 | - item collection
50 | - trackball rotation
51 | - rocks, seaweed, animals (i.e. sharks?)
52 |
--------------------------------------------------------------------------------
/super_submarine/pictures/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/super_submarine/pictures/screenshot.png
--------------------------------------------------------------------------------
/super_submarine/pictures/submarine_demo.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/super_submarine/pictures/submarine_demo.webp
--------------------------------------------------------------------------------
/super_submarine/pictures/whalesharkmotion.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/super_submarine/pictures/whalesharkmotion.png
--------------------------------------------------------------------------------
/super_submarine/readme.md:
--------------------------------------------------------------------------------
1 | # super submarine
2 |
3 | You are a submarine tasked with some important objectives! you must disarm a dangerous capsule and recover some things from a sunken ship.
4 |
5 | ## notes:
6 |
7 | 1. rotating an object on a circular path
8 | I wanted to get the whale shark to swim in a circle while adjusting the direction its facing (currently not perfect but I think close enough).
9 | To do this, during each update call I place the whale shark at the origin, rotate it, then place it at the next point along the path.
10 | However, in terms of matrix multiplication, these steps need to be done backwards.
11 |
12 | 
13 |
14 | 2. togglable submarine spotlight
15 | Turning on/off the submarine's spotlight (via changing its visible property to true/false) is an expensive operation for rendering and causes some noticeable lag when toggled.
--------------------------------------------------------------------------------
/super_submarine/waternormals.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/super_submarine/waternormals.jpg
--------------------------------------------------------------------------------
/trumpet/080623-trpt-sample.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/trumpet/080623-trpt-sample.wav
--------------------------------------------------------------------------------
/trumpet/README.md:
--------------------------------------------------------------------------------
1 | # Bb trumpet
2 |
3 | a 3D Bb trumpet! You can move the valves with the 1, 2 and 3 keyboard keys or play a demo that plays notes according to their fingerings.
4 |
5 | I also explored a bit how to get pitch from audio data and borrowed some of [Chris Wilson's code](https://github.com/cwilso/PitchDetect/blob/main/js/pitchdetect.js), which uses a technique called autocorrelation to determine pitch.
6 |
7 | You can try importing audio and see the trumpet fingerings sync with the calculated pitch on playback. A monophonic audio sample will likely work best. I've provided a .wav sample of me playing an excerpt of the main theme for the game "Medal of Honor: Pacific Assault", composed by Christoper Lennertz. Please don't expect too much :)
8 |
9 | 
--------------------------------------------------------------------------------
/trumpet/blender/trumpet.blend:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/trumpet/blender/trumpet.blend
--------------------------------------------------------------------------------
/trumpet/blender/trumpet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/trumpet/blender/trumpet.png
--------------------------------------------------------------------------------
/trumpet/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/syncopika/threejs-projects/92a4a4db278b14396136eb50a5932acfa38dc048/trumpet/demo.gif
--------------------------------------------------------------------------------
/trumpet/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bb trumpet
5 |
6 |
7 |
8 |
9 |
10 |
31 |
32 |
33 |
34 |
35 |
a Bb trumpet
36 |
use keys 1, 2 and 3 on the keyboard to move the valves of the trumpet! then press 'shift' to play a note that corresponds with the current fingering.
37 |
in this demo I'm using shape keys/morph targets to make the valves 'move'.
click on the black buttons on the right side of the machine to get an item. note that an item corresponds to a code of 1 letter and 1 number (e.g. 'A1').
59 |
use the mouse clickwheel to zoom in and out.
60 |
you can click on the item when it's in the drop area!
61 |
62 |
63 |
64 |
66 |
--------------------------------------------------------------------------------
/vending_machine/readme.md:
--------------------------------------------------------------------------------
1 | # vending-machine
2 |
3 | a vending machine that has clickable buttons! :D
4 | not super exciting but included in this demo is an example of using fonts/creating text with three.js (and more animation!),
5 | as well as using a Bloom effect shader for a "neon glow" effect.
6 |
7 | 
8 | 
--------------------------------------------------------------------------------