# Getting started This tutorial explains how to build a simple scene with the *3DS* module. The basics are somewhat similar to [Three.js](https://threejs.org/). There are some differences though that we will highlight along the way. Let's start with a basic HTML file `index.html` ```html My first example ``` At each step of the tutorial, we highlight the additional lines of code needed to perform the described action. The complete script can be found at the end of this page. ## Step 0. Declaring required modules / Choosing a geometry. Beside the 3DS module, the application relies on several 3d-party JavaScript modules (Three.js in particular). There are several options to load them. We use here the "importmap" specification. In practice the following should be added in the header ```html ``` ### Remarks - If `importmap` is not supported by your browser, you can add the polyfill provided by `es-module-shims` - In this example we assume that the directories `vendor` and `3ds` are at the same level as the `index.html` file. - The names in the import map (`three`, `three/addons`, and `3ds`) cannot be changed. ### Geometry In the above example, we have chosen a geometry, via the module `3dsEuc.js`. Indeed, all the tools for each geometry are wrapped in a single file with the name `3dsXXX.js` where `XXX` has the following meaning. | XXX | Geometry | |-----|---------------------------------------------------| | Euc | $\mathbb E^3$ (euclidean geometry) | | Hyp | $\mathbb H^3$ (hyperbolic geometry) | | Sph | $S^3$ (spherical geometry) | | S2E | $S^2 \times \mathbb E$ (product geometry) | | H2E | $\mathbb H^2 \times \mathbb E$ (product geometry) | | Nil | Nil | | SL2 | The universal cover of ${\rm SL}(2,\mathbb R)$ | | Sol | Sol | From now on, all the instructions to generate a scene will be added in the `script` tag identify as `main`. ## Step 1. Choosing a discrete group. Next, one need to load a discrete subgroup of isometries. This subgroup corresponds to the fundamental group of the quotient manifold/orbifold we are working in. In this tutorial we will only work in $\mathbb E^3$, hence the discrete subgroup is just the trivial group. It is loaded as follows ```javascript import {trivialSet as set} from "3ds"; ``` ## Step 2. Defining a scene, a camera and a renderer. Before adding object, one needs to define a scene and a camera. Those items are bind together in a renderer whose task is to dynamically create a shader and run it. ```javascript import {SphereCamera, BasicRenderer, Scene} from "3ds"; // ... // initial setup const camera = new SphereCamera({set: set}); const scene = new Scene(); const renderer = new BasicRenderer(camera, scene, {}, { logarithmicDepthBuffer: true }); // adjust the renderer to the size of the screen renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); // add a canvas in the HTML file to display the scene. document.body.appendChild(renderer.domElement); ``` - The camera takes as an argument the discrete subgroup of isometries we loaded. By default, the position of the camera is the origin of the geometry. It points toward the negative z-direction (in a preferred frame in the tangent space at the origin). - The renderer takes as arguments the camera and the scene. ## Step 3 Populating the scene The scene is made of objects which are either solids or lights. Before defining those object, we need to extend our list of imports with the relevant classes. In our examples we will also use {class}`Point` as well as the [Color](https://threejs.org/docs/index.html#api/en/math/Color) implementation from Three.js. ```javascript import { PointLight, PhongMaterial, Ball, Point } from "3ds"; import {Color} from "three"; ``` Then we define all the objects in the scene. Here a single point light, and a ball with a phong material. ```javascript // A light const light = new PointLight( new Point(-1, 1, -2), new Color(0, 1, 1), 0.5, ); // Phong shading material const mat = new PhongMaterial({shininess: 10}); // A ball const ball = new Ball( new Point(-1, -0.5, -2), 0.3, mat ); ``` The light has three arguments here (it can be different for another kind of lights or another geometry): its location, its colors and its intensity The phong material accepts various parameters (see the doc) In general, a solid is a shape with a given material. A solid can be defined using a built-in class (as here). Alternatively, one can define separately a shape and a material and combine them in a {class}`Solid` object. Finally, one adds those objects to the scene ```javascript scene.add(light, ball); ``` ## Step 4 Rendering the scene. Before rendering the scene, we need to build the underlying shader. This is done as follows ```javascript renderer.build(); ``` Note that every object added to the scene after this function has been called will not be taken into account. Then we define a function that is called at each frame. ```javascript function animate() { renderer.render(); } ``` Here we just call the {meth}`Renderer.render` method of our renderer. We can elaborate to animate the scene, handle events, etc. Finally, we define the animation loop ```javascript renderer.setAnimationLoop(animate); ``` A useful command to add when debugging is ````javascript renderer.checkShader(); ```` It displays in the log the shader built by the renderer. ## Step 5. Summary The complete `index.html` file is ```html My first example ```