<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Raluca Nicola</title>
    <description>The latest articles on DEV Community by Raluca Nicola (@ralucanicola).</description>
    <link>https://dev.to/ralucanicola</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F155231%2Fac1e0dcb-09bd-490e-bc37-94b440496c56.jpeg</url>
      <title>DEV Community: Raluca Nicola</title>
      <link>https://dev.to/ralucanicola</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ralucanicola"/>
    <language>en</language>
    <item>
      <title>Learning ThreeJS with a fun project</title>
      <dc:creator>Raluca Nicola</dc:creator>
      <pubDate>Thu, 09 Jan 2020 14:16:59 +0000</pubDate>
      <link>https://dev.to/ralucanicola/learning-threejs-with-a-fun-project-3beb</link>
      <guid>https://dev.to/ralucanicola/learning-threejs-with-a-fun-project-3beb</guid>
      <description>&lt;p&gt;I've been meaning to play around with ThreeJS for a while now and in this holiday I finally had time. When I learn something new, I like to work on a &lt;em&gt;fun&lt;/em&gt;, &lt;em&gt;silly&lt;/em&gt; project where I can use the technology I want to learn. It should be &lt;em&gt;fun&lt;/em&gt; so that I enjoy working on it, but also &lt;em&gt;silly&lt;/em&gt; so that I don't have too much pressure to finish the project...&lt;/p&gt;

&lt;p&gt;In this blog post I'll write about my newly acquired ThreeJS skills, the project I used and some resources that I found super useful.&lt;/p&gt;

&lt;p&gt;So without further ado, the project that I worked on is 🎉 a penguin in a globe 🎉&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa7fgnbmkg9crbtvw5272.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa7fgnbmkg9crbtvw5272.png" alt="Penguin in a globe"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Resources to start learning
&lt;/h2&gt;

&lt;p&gt;I started learning by checking out documentation, blog posts, video tutorials etc. There are many resources out there, so I'll just write the ones that worked really well for me and you might want to check them out (with the disclaimer that they might not work as well for you):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I really enjoyed going through the Getting started section of Lewy Blue's book &lt;a href="https://discoverthreejs.com/book/contents/" rel="noopener noreferrer"&gt;Discover ThreeJS&lt;/a&gt;. Only the first 2 sections are available for now, but it's enough to give you a kick start in the ThreeJS universe.&lt;/li&gt;
&lt;li&gt;If you're more into video tutorials, then CJGammon has an &lt;a href="https://www.youtube.com/watch?v=ABV1mK1CGOY&amp;amp;list=PUFbkyvvsEQn7AmQO6_G5J-A" rel="noopener noreferrer"&gt;Introductory series on youtube&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For explanations on 3D concepts I mostly go to the &lt;a href="https://www.realtimerendering.com/" rel="noopener noreferrer"&gt;Real-Time Rendering&lt;/a&gt; book.&lt;/li&gt;
&lt;li&gt;I wanted to understand how shaders work and write my first shader (be it a dead easy one). It's quite hard to find resources on this topic for beginners... However, I really liked:

&lt;ul&gt;
&lt;li&gt;Surma's Supercharged episode about &lt;a href="https://www.youtube.com/watch?v=_ZQOUQsw_YI" rel="noopener noreferrer"&gt;WebGL shaders for image processing&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Matt DesLauriers' &lt;a href="https://frontendmasters.com/workshops/more-creative-coding/" rel="noopener noreferrer"&gt;Creative coding with WebGL and shaders workshop&lt;/a&gt; on Frontend Masters (this is only available with a paid subscription, but it was really worth it for me). The repo with resources is public on &lt;a href="https://github.com/mattdesl/workshop-webgl-glsl/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When actually starting the project, the best resources turned out to be the &lt;a href="https://threejs.org/docs/index.html#api/en/scenes/Scene" rel="noopener noreferrer"&gt;ThreeJS official documentation&lt;/a&gt; and their &lt;a href="https://threejs.org/examples/" rel="noopener noreferrer"&gt;example apps&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Set up the repo and the app
&lt;/h2&gt;

&lt;p&gt;I wanted to have a simple setup where I could write ES6 JavaScript. Webpack always comes with a ton of configuration which is really useful for big projects, but when all you want to do is put a penguin in a globe, it's so much better if you don't need a ton of configuration. So I tried for the first time &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt; and it was exactly the right tool for the job. It comes with a built-in Babel compiler, so all I needed to do was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// setup the package.json file
npm init -y

// install parcel
npm install --save-dev parcel-bundler

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I added the two script commands for building the project in the &lt;code&gt;package.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parcel index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parcel build index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I installed threejs as well and then I was good to go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save three
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can check out the initial stage of the project &lt;a href="https://github.com/RalucaNicola/learn-threejs/commit/d007d5c311363e5f7bda404a74985bec2357b643" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup the scene
&lt;/h2&gt;

&lt;p&gt;There are a few basic elements that you need to define, whenever you want to create a new scene: the scene itself, the camera, the lights and the renderer. I added the axes helpers to better orient myself while developing and I also added the &lt;a href="https://threejs.org/docs/#examples/en/controls/OrbitControls" rel="noopener noreferrer"&gt;OrbitControls&lt;/a&gt; for navigation. You can read about all of these in detail with some great examples in the &lt;a href="https://discoverthreejs.com/" rel="noopener noreferrer"&gt;Discover ThreeJS book&lt;/a&gt;.&lt;br&gt;
If you want to have a look at all the setup code, you can find it in this &lt;a href="https://github.com/RalucaNicola/learn-threejs/commit/16246ab0605904673ba1410961cc9abe9c70a5dd" rel="noopener noreferrer"&gt;commit&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a triangulated irregular network
&lt;/h2&gt;

&lt;p&gt;I want to create a triangulated surface that looks a bit like low-poly terrain covered with snow. The workflow is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I start with a bunch of random points and then I connect them creating triangles. A fast and good library that I've used for this is called &lt;a href="https://github.com/mapbox/delaunator" rel="noopener noreferrer"&gt;Delaunator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For each of the created vertices I generate a random z value and i also assign a color based on the height of the vertex. High values are white and lower values are blue.&lt;/li&gt;
&lt;li&gt;I then create the geometry by assigning the vertex position and color to the geometry. I also set the triangle face indices that are returned by the Delaunator library.&lt;/li&gt;
&lt;li&gt;In the end I create the material, telling it to take the colors from the vertices and setting the shading to be flat. This gives the low-poly aspect to the terrain.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the code in this &lt;a href="https://github.com/RalucaNicola/learn-threejs/commit/0b3633e12e510ccefa60c317cad7a4b05fdb20fd" rel="noopener noreferrer"&gt;commit&lt;/a&gt;. And this is what the terrain looks like in the end:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbzxh1zlkupt5v4moxg7t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fbzxh1zlkupt5v4moxg7t.png" alt="low poly terrain"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a glass globe
&lt;/h2&gt;

&lt;p&gt;For this part I used the code from a ThreeJS &lt;a href="https://threejs.org/examples/#webgl_materials_physical_transparency" rel="noopener noreferrer"&gt;example of spheres with transparency&lt;/a&gt;. The most interesting part here is exploring different types of materials and playing with properties like roughness, metalness, clearcoat or reflectivity to simulate a reflective glass surface. I also learned about &lt;a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps" rel="noopener noreferrer"&gt;cube map textures&lt;/a&gt; that can be used as an &lt;a href="https://threejs.org/docs/index.html#api/en/materials/MeshStandardMaterial.envMap" rel="noopener noreferrer"&gt;environment map&lt;/a&gt;. I used &lt;a href="https://unsplash.com/photos/ruJm3dBXCqw" rel="noopener noreferrer"&gt;this abstract image&lt;/a&gt; as an environment map for the globe because it gives this bubble soap effect and the colors also match the background. I created the cube map textures using &lt;a href="https://jaxry.github.io/panorama-to-cubemap/" rel="noopener noreferrer"&gt;this online tool&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkv21xkrtzuntq3zonm4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkv21xkrtzuntq3zonm4y.png" alt="adding a glass globe"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The commit for this step is &lt;a href="https://github.com/RalucaNicola/learn-threejs/commit/c6beac3cc960a63c7c13f723726cdeb067b03708" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Peppermint the pengu
&lt;/h2&gt;

&lt;p&gt;I can't create my own 3D models (still something on my to-learn list). So I always search for models online. Two websites that I constantly go to are Google Poly and Sketchfab. They have a built-in converted that will let you download the models in a GLTF format. I found Peppermint on &lt;a href="https://poly.google.com/view/dLdYN_-2dlE" rel="noopener noreferrer"&gt;Google Poly&lt;/a&gt; under a CC-BY license.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fohbpz0sgs0jy3b6joy1a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fohbpz0sgs0jy3b6joy1a.png" alt="Peppermint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Otherwise, there's not much to add at this step. In the ThreeJS book there is a dedicated section on &lt;a href="https://discoverthreejs.com/book/first-steps/load-models/" rel="noopener noreferrer"&gt;how to import external models&lt;/a&gt;. Or just have a look at &lt;a href="https://github.com/RalucaNicola/learn-threejs/commit/83b893625f09c7dadabdb59d458e2b32291e5a5a" rel="noopener noreferrer"&gt;my code&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add a support for the globe
&lt;/h2&gt;

&lt;p&gt;Finally I added the support, which is not more than a cylinder shape with different radiuses for top and bottom. The exciting part in this step is that I played a bit with shaders and created that gradient for the material. &lt;a href="https://dev.to/maniflames/creating-a-custom-shader-in-threejs-3bhi"&gt;Creating a custom shader in threejs&lt;/a&gt; is a blog post that shows exactly how to create a fragment shader that displays a gradient between 2 colors.&lt;/p&gt;

&lt;p&gt;And that was about it. You can check out the live version here: &lt;a href="https://raluca-nicola.net/learn-threejs/" rel="noopener noreferrer"&gt;https://raluca-nicola.net/learn-threejs/&lt;/a&gt;. Also the repository for the project is here: &lt;a href="https://github.com/RalucaNicola/learn-threejs" rel="noopener noreferrer"&gt;https://github.com/RalucaNicola/learn-threejs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This project was a really nice way to learn new technologies, 3D concepts and play around with tools and I hope it will inspire you to also build something or learn something new. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>threejs</category>
    </item>
  </channel>
</rss>
