WP2WS Project C – B(I)oom

CONCEPT

This project is a continuation of my Project B concept. I wanted to create a scroll-based interactive narrative about growth, challenge, and rising up from the challenge. It’s also like a life cycle, where there is growth, death, and rebirth. I kept the motif of a flower, which I had in Project B as well. In this project, I wanted to focus more on the interactions and visuals, as well as add more of a narrative.

WORK PROCESS

My first concept was actually to explore digital preservation. However, I felt like this concept wasn’t something I could create with an interesting idea around it, so I decided to go back to my Project B concept and expand on it. So I came up with this concept:

Looking at this, I felt like I wouldn’t be able to accomplish everything that I wanted to do, but after receiving a tremendous amount of help from Professor Moon and searching on the web for references and people who did similar things, I was able to complete everything in this concept development, which was super exciting and satisfying.

To explain my work process, I’ll go over each element chronologically in the order they appear in my project. However, in the actual work process, I often jumped around and worked on different parts sporadically so I never completed one thing all in one moment. But for better explanations, I’ll go through it chronologically.

TITLE TEXT + Background

The title text I actually added in half way while I was working on this project. Initially, I had no particular name set for it, but to make the project more cohesive I decided to add a title. I used the same method I used in the last project where I loaded the text and imported textGeometry. It ended up looking like this after I loaded the text:

I wanted to add a fading effect for when the text shows up. So I changed the opacity of the text in the updateThree() by incrementing the opacity by 0.1. This removed the 3D look of the text, but I feel like the 2D look better suited the visuals of my project anyway.

I also kept getting errors because the textMesh wasn’t defined, but this was solved easily by including an if statement.

As for the background, this was pretty straightforward. I wanted to create a gradient effect, but I wasn’t sure how to do that in three.js. I looked for some references on  how to do this and found that it was way easier to just use CSS and make the background of three.js transparent. In order to make the three.js background transparent, I have to go to the script-three.js file and include these lines:

renderer = new THREE.WebGLRenderer({ alpha: true });

renderer.setClearColor(0x000000, 0);
 
The rest was just playing around with the gradient in CSS.
I also wanted to create a transitioning gradient effect when you scroll, but since I was using CSS, I didn’t know how to trigger or transition the gradient and the three.js elements. When I was searching, most of the examples required different sections in the HTML website, which I didn’t want to do, so the other backgrounds were just one colored. The change based on scroll was done using this line of code:
 
document.body.style.background = color(227, 244, 252);
 
Where it accesses the body of the HTML website where everything is hosted and changed the style of the background.
 
SCROLL EFFECT

For the scroll effect I referred to a Youtube video. This was honestly not the most complicated part of the project, because it is just manipulating the position of the camera on the y-axis and updating that. It also takes the data from the mouse wheel, so I had to include an event listener and function for the event.

window.addEventListener("wheel", onMouseWheel);
let y = 20;
let position = 300;
 
function onMouseWheel(event) {
  y = event.deltaY * 0.07;
}
 

Position is the initial position of the camera, which is where the text is. I purposely set the text to be a lot higher than the flower so I can mimic the scroll effect. y is the amount of scroll. It takes the deltaY of the y position and then is multiplied by 0.07 so it doesn’t keep infinitely scrolling. Then in the animate() function it updates camera position to the variable position.

I also intended to include clicking interactions, but I realized that it was hard to keep track of the clicks and how many times someone would click. So I stuck with just incorporating the scroll interaction and having things trigger based on the scroll.

 Flower

This is where I began my work process, but I kept going back and forth between the flower and other elements. So I had to implement a flower, which was essentially the main character of the scene. I found a gltf model on Sketch Fab and used the loader to upload it onto three.js. The first issue I encountered was not being able to see the flower. The loader showed no errors, but I couldn’t see anything.

I found out there’s a three.js editor where you can test if the gltf model works in your scene, which it did:

But when I looked at my scene it was empty. Then I realized it was because I had no lighting, so I tried adding a spotlight and hemisphere light, which then the model showed up.

The next step was trying to get the animation in the model to play. Again, when I was using the editor the animation worked fine. I tried referring to a video on how to trigger the animation, but since the video I used had multiple animations in one model it was slightly more complicated and different than what I actually had to do. Basically, in the gltf loader, I had to create a mixer for the animation and then get the clip and play. Usually the animation is in the scene of the model, but this model was a little different so I had to call gltfData.animations[0] in order to get the animation playing. After that, I made it loop once because I didn’t want the flower to keep opening.

Since there’s a title and I wanted to base the flower opening based on when you scroll to that point, I couldn’t have the animation playing right from the beginning. So when updating the mixer, I added an if statement and played around with the camera y position until I found the rough point of where I want the flower to appear and start the animation.

The next challenge was getting the flower to close when the rain was falling. I wanted to time is based on the splashes on the flower, but I feel like the final outcome wasn’t really like that. Besides that point, it was really difficult trying to keep the animation looping once but also playing the animation again when the rain was falling. Since I set the animation to LoopOnce, it wouldn’t play again if I just updated the mixer backwards in the rainsplash function.

There was some point where I was able to mimic the closing animation, but it wasn’t quite there. I believe with this code, the animation would keep looping:

I then found out to do the animation, I need to use reset and timeScale. In the gltf loader, I had this chunk of code:

action.reset();
action.clampWhenFinished = true;
action.timeScale = 1;
action.setLoop(THREE.LoopOnce, 1);
action.play();
 
clampWhenFinished makes sure the animation stays at the last frame, which is the flower completely opened. TimeScale scales the factor of time in the animation, so when it is 0 the animation is paused, when it is 1 the animation goes forwards and -1 is backwards. Technically the default is 1, but I included this line anywawy. I also set the loop to once and then played the animation. This worked, where the flower animation wouldn’t keep looping, but the moment of truth was in the rain scene.
In part where I check for splashes, I included these two lines of code:
 
action.timeScale -= 0.01;
action.paused = false;
 
Since timeScale is used, the animation is technically paused on that last frame. So when I set it to false, the animation will play again and the time will decrease, which means the animation goes backwards. The slight unsatisfying part about this is that it doesn’t slowly close based on the raindrop splashes, but it ended working so you win some and you lose some.
 

 

RAIN AND RAIN SPLASH

To create the rain, it was basically me taking what I did for Project B, but modifying the shape, velocity, and acceleration of the rain. I had to change these components since Project B was more mimicking snowflakes where there was wind blowing it in different directions.

There were some slight challenges in terms of the velocity and acceleration, but the biggest challenge was creating the splash effect. I wanted to have something similar to Going Home, where there’s a section of rainfall and there was a splash effect when the rain hit a surface.

To create the splash effect, I had to make a separate class just for splashes. This was just a cube class from the example code and the values were tweaked to better give a splashing effect. I had to fake the splash collision with the flower by creating a test sphere and playing around with the distance between the rain and sphere:

After calling the splashes, I found it was strange because the cubes would only be updated when there were other splashes:

Then I realized it was because the updating of the cubes was in the splash function, which meant it would only animate then. So that part of the code was moved into a different section and the splash looked very cool.

So I intended for the rain to appear in the second scene, which is supposed to represent challenge. However, it kept appearing in the beginning (which was honestly quite beautiful as well because of the lighting and colors) so I had to work around this issue by wrapping the rain for loop in another if statement, even though there was already the same if statement wrapped around it. I’m still not sure why it is like this though, but this method worked.

FLOODING

The main challenge with the flooding effect was getting the texture on it while it was flooding. Again, I took what I did from Project B and incorporated it into this section, since that project also had the water like texture on a plane. Initially, I set the plane to be scaled at 0 so it can grow when the rain appears. However, while it did grow, there was no texture on the plane:

But when I set the scale to be something visible, I’m able to see the texture of the plane (which can be seen in the previous previous image). So to solve this, the texture and plane was grouped together and it worked.

At first I wanted to scale the flooding effect based on the count of rain splashes, but this effect was too choppy looking, so I changed it to be based on the overall rain count. Basically, every time rain drops reach the bottom of the screen, the count increases and the plane scale size is mapped to the count value.

FINAL SCENE

I feel like the final scene was the most different in terms of the other scenes, but it was one where people were surprised, laughing, and enjoyed the most. It was also quite simple to do, since it was just utilizing the camera in p5.js and then using that as a texture on the sphere. It was just a little difficult trying to get the correct position and texture.

LIGHTING

Lastly, I wanted to talk a little bit about the lighting, since scene 1 and scene 2 have different effects. I included fog, spotlight, and hemisphere light to the scene. I feel like the spotlight is most noticeable when the background is dark.

Also, at first when I did the background change, the lighting looked blown out, but after adjusting the near and far value of the fog, the lighting became a lot better. So for lighting it was just a lot of experimentation and changing up the color.

REFLECTION

It was really fun showing people my project at the IMA Show and I even let them try to interact with it. Everyone seemed to like the final scene, which while I intended it to be kind of a deep note to end on, but it ended up being something funny.

There are definitely some things I would like to add and change in this though. For instance, I want to make the scrolling more intuitive so that others can use it without being confused. It would be cool to have the different animations based on the scroll time rather than stopping at each section. Moreover, I would want to add a reversing effect, so when you scroll up the animations would go backwards. I also tried to add background music, but I ran out of time before I could do it correctly, so I want to include that in the future as well.

Overall, I’m honestly quite proud and satisfied with how this final project turned out. I feel like throughout the semester, I struggled a lot with trying to create something of my own in three.js and something that had “cool” elements. I thought I wouldn’t be able to have every single element that I intended to include, so I’m super happy that I was able to check everything off from my initial concept development. Finally, I would like to give a huge shout out to Professor Moon for being the best! He helped me so much when I hit roadblocks and I often saw him still at the lab helping students with their projects at 3am. Cheers to WP2WS and I hope to keep playing around with three.js and create more cool projects in the future 🙂

 

REFERENCES

 

Leave a Reply

Your email address will not be published. Required fields are marked *