libgptjs

所属分类:3D图形编程
开发工具:JavaScript
文件大小:0KB
下载次数:0
上传日期:2023-07-27 17:11:59
上 传 者sh-1993
说明:  使用ThreeJS进行图形编程-图形管道的主要类,计算机图形技术:复杂模型的几何和法线计算,照明和阴影,运行时UV坐标,凹凸贴图,曲面平滑,UI,天空盒,反射,有限状态机,aabb对撞机,粒子系统
(Graphical Programming with ThreeJS - main classes for graphics pipeline, computer graphics techniques: geometry and normals calculation for complex models, lighting and shadows, runtime UV coordinates, bump mapping, surface smoothing, UI, skybox, reflections, finite state machine, aabb colliders, particles system)

文件列表:
LICENSE (1092, 2023-07-27)
core/ (0, 2023-07-27)
core/GPT_App.js (3554, 2023-07-27)
core/GPT_Coords.js (6340, 2023-07-27)
core/GPT_LinkedModel.js (2193, 2023-07-27)
core/GPT_Model.js (1819, 2023-07-27)
core/GPT_ModelCollider.js (3064, 2023-07-27)
core/GPT_Renderer.js (3606, 2023-07-27)
core/GPT_Scene.js (5135, 2023-07-27)
core/_libgptjs.json (328, 2023-07-27)
external-libs/ (0, 2023-07-27)
external-libs/OrbitControls.js (25653, 2023-07-27)
external-libs/three-global.js (594, 2023-07-27)
scene-dragon/ (0, 2023-07-27)
scene-dragon/Common.js (2534, 2023-07-27)
scene-dragon/CoordsDragon.js (106448, 2023-07-27)
scene-dragon/CoordsGripper.js (1480, 2023-07-27)
scene-dragon/DragonFire.js (3870, 2023-07-27)
scene-dragon/DragonFireParticles.json (120741, 2023-07-27)
scene-dragon/FSM_Robot.js (8054, 2023-07-27)
scene-dragon/InputManager.js (8407, 2023-07-27)
scene-dragon/ModelBullet.js (4625, 2023-07-27)
scene-dragon/ModelDragon.js (3557, 2023-07-27)
scene-dragon/ModelGripper.js (2313, 2023-07-27)
scene-dragon/ModelRobot.js (8408, 2023-07-27)
scene-dragon/ModelSkybox.js (1713, 2023-07-27)
scene-dragon/ModelTrajectory.js (7467, 2023-07-27)
scene-dragon/SceneDragon.js (14176, 2023-07-27)
scene-dragon/_smooth-dragon.json (338, 2023-07-27)

# libgptjs _`This project is being imported as submodule in several other repositories. The hierarchy works as a NodeJS module.`_ Graphical Programming with ThreeJS * Main classes for graphics pipeline * WebGL project using ThreeJS, HTML5 and OOJS (object oriented javasctipt) for exploring several computer-graphics techniques: * Geometry and Normals calculation for complex models * UV coordinates calculation * Surface Smoothing by using Vertices Normals * Lighting and Shadows * Skybox and reflections * User Interface (sliders, toggles, buttons) * Finite State Machine to handle "shooting robot" * Collision detection using AABB * Particles System with Nebula-Threejs ## LIBGPT - Core * [three-global.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./external-libs/three-global.js) * It is used to create a global object `THREE` and add functionalities to it 1. Imports `three.js` library as module from npm 2. Names it `THREE` (following the nomenclature used in other modules) 3. Exports the object `THREE` from this script / module to be imported into the rest (ex: in OrbitControls.js) 4. In [OrbitControls.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./external-libs/OrbitControls.js), or other scripts, new functionality is added to `THREE` object * Graphical Programming with Threejs [libgptjs](https://github.com/GiovannyJTT/libgptjs/blob/master/./) * The classes at `libgptjs/` are importing `three-global.js` * Wrapper / Library to facilitate re-use of code and organize the graphics pipeline * It contains several objects (classes) for wrapping all the logic required for creating an scene with threejs * This allows modularity and we can reuse code creating instances of those clases * [GPT_Coords](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Coords.js) * Gets vertices (Float32Array) and edges array (Uint32Array) * Calculates the normal vector for each triangle * Provides a method for calculating the UV coordinates for each triangle * [GPT_Model](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Model.js) * Simple class to integrate mesh + geometry + material * Provides method for cleaning gl buffers that were reserved * [GPT_LinkedModel](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_LinkedModel.js) * Model formed of joining several `THREE.Object3D` in order to create articulated models like robot arms * Provides method for adding a new link between two Object3D and finally linking all of them in sequence * [GPT_ModelCollider](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_ModelCollider.js) * Attaches an AABB (axis aligned bounding box) to an existign Mesh * Provides a method for detecting collision with another AABB * [GPT_Scene](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Scene.js) * List of `GPT_Model`s and `GPT_Light` * Provides abstract methods for initial configuration and updates in every frame * These methods have to be overriden when creating the instance of the `GPT_Scene` * Provides methods for adding and removing models at runtime * [GPT_Render](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Renderer.js) * It initializes the camera and camera-handler * This is the main object that creates a `webgl-renderer` and invokes methods of `GPT_Scene` * [GPT_App](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_App.js) * Top-level object that configures the `window` and uses `GPT_Render` * It contains the main loop for animation in which the `update` and `render` are being invoked ## SceneDragon scripts * [Common.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/Common.js) * Contains all constants to be re-used in several points in the code * [CoordsDragon.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/CoordsDragon.js) * Stores arrays of dragon model (vertices and edges) * Since it inherits from `GPT_Coords` it provides methods for computing normals and UVs coordinates * [CoordsGripper.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/CoordsGripper.js) * Stores arrays of gripper model (vertices and edges) * Since it inherits from `GPT_Coords` it provides methods for computing normals and UVs coordinates * [ModelSkybox.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelSkybox.js) * Creates a big cube and maps the texture to simulate environment * These skybox images will be reflected on the Dragon surface and Gripper surface * [ModelDragon.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelDragon.js) * Inherits from `GPT_Model` and overrides `get_geometry` and `get_material` methods * Creates and initializes `geometry` and `material` objects to be inserted into a `mesh` * Computes `UV` coordinates per face (triangle) in order to simulate reflections of the skybox onto the dragon surface * Contains a `GPT_ModelCollider` * [ModelGripper.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelGripper.js) * Idem to ModelDragon * [ModelRobot.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelRobot.js) * Inherits from `GPT_LinkedModel` * Creates separately the parts of the robot (base, arm, forearm, hand and gripper). Then links them all in sequence * [ModelTrajectory.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelTrajectory.js) * Given 2 initial points to be used as direction vector * It computes the control points (`p1, p2, p3, peak and end`) to be used later into the spline points calculation * Control points form a triangle with one of the edges following the `p1` and `p2` direction * `Peak` point is in the middle of triangle and is the highest point * `End` point is on the floor * Spline points are calculated using the control points and `catmullrom` with N (30) segments * Final spline points are used to create line geometry to be rendered * [ModelBullet.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelBullet.js) * Creates the geometry, material, mesh, and GPT_ModelCollider * Needs a trajectory and a starting point3D * Provides a method for moving the bullet between 2 consecutive points3D of the trajectory based on time passed since last frame * [InputManager.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/InputManager.js) * Checks if it is running on mobile device or desktop * Creates the UI (sliders, toggles, etc.) and installs the `onChange` callbacks to be executed when a value is updated by the user * Creates html button for "shoot" and attaches the corresponding callback * [FSM_Robot.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/FSM_Robot.js) * Defines a finite state machine for robot shooter * Defines `States`, `Events` and `Transitions` * Defines Transitions as a dictionary of allowed state-event pairs * Provides methods for `transiting` from one state to other depending on the "Event" * Provides method for `updating` the current state based on timers expiration * [SceneDragon.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/SceneDragon.js) * Contains the handling of main interactions: InputManager, animation (update) of objects, etc. * Inherits from `GPT_Scene` and overrides `createObjects`, `createLights`, `updateObjects` and `updateLights` methods * Performs all setting up of models and lights: floor, dragon, skybox, robot, trajectory, etc. * Performs periodic updates of models and lights: translate, rotate, destroy and create new trajectory, etc. * Contains a method where actions are triggered depending on the change of state of `FSM_Robot` * Any change of state is reflected into the UI * `Idle` * Rotate Dragon, update AABB * `loading_bullet` * Rotate shooting arm * Increase power while user keeps clicking and update UI slider * When power increased set shooting arm to red color * `bullet_traveling` * Draw the trajectory * Move the bullet along the trajectory * Rotate while traveling * `hit` * Blink dragon to red * Stop bullet at collision point * Limits the reaction to the incoming "shoot events" by checking if current robot state is `idle` ## Computer Graphics Techniques ### Geometry and Normals calculation for complex models * A triangle is the basic polygone * It is formed of 3 vertices, each vertex has 3 components float (x, y, z) * Its vertices are defined clockwise by default. This is taken into account when computing the face (triangle) normal vector * A `geometry` in threejs is formed of several arrays * `position` * It is a `Float32Array` in which all the coordinates of all vertices of all triangles are packed together * Array lenght is `3 * num vertices` * Example forming the first __2 triangles__ ```javascript CoordsGripper.prototype.getArrayVertices = function () { return new Float32Array([ 0, 0, 0, 0, 20, 0, 19, 20, 0, 19, 0, 0, 0, 20, 4, 0, 0, 4, ``` * `itemSize` 3 because there are 3 components per vertex ```javascript ModelDragon.prototype.get_geometry = function () { const _geom = new THREE.BufferGeometry(); _geom.setAttribute( "position", new THREE.BufferAttribute(this.coords.vertices_coordinates, 3) ); ``` * `normal` * It is a `Float32Array` containing all the normal vectors for all triangles * Array lenght is `3 * num triangles` * It is computed at [GPT_Coords](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Coords.js) `calculateNormals` * Idem to `positions` * `indices` * It is a `UInt32Array` containing all the sequence of indices (of `positions` array) to form triangles * Example forming the first __2 triangles__ ```javascript CoordsGripper.prototype.getArrayEdges = function () { return new Uint32Array([ 2, 0, 1, 3, 0, 2, ``` * `itemSize` 1 because there are 1 component per vertex-index ```javascript _geom.setIndex(new THREE.BufferAttribute(this.coords.edges_indices, 1)); ``` * `uv` * It is a `Float32Array` containing the UV coordinates for all vertices of all triangles * Each vertex will have 2 UV components (texture coordinates) * UV coordinate values are in range [0.0, 1.0] * Array lenght is `6 * num triangles` * It is computed at [GPT_Coords.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Coords.js) `getUVs` * `itemSize` 2 because each vertex has 2 UV componets ```javascript _geom.setAttribute( "uv", new THREE.BufferAttribute(uvs, 2) ); ``` * A `Mesh Phong Material` in threejs is needed to define the rendering of the geometry ```javascript ModelDragon.prototype.get_material = function () { // loading TextureCube as skybox const _mat = new THREE.MeshPhongMaterial( { color: 0xe5ffe5, emissive: 0xb4ef3e, flatShading: true, // initially per-triangle normals specular: 0x003300, shininess: 70, side: THREE.FrontSide, transparent: true, opacity: 0.75, envMap: Common.SKYBOX_CUBE_TEXTURE } ); ``` * A mesh in threejs is formed of a geometry and a material ```javascript this.mesh = new THREE.Mesh(this.geometry, this.material); ``` ### UV coordinates calculation [GPT_Coords.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Coords.js) `getUVs` 1. Calculates UV for planar surface (x, y, z) where z = 0 2. Depends on geometry bounding box 3. Computes the UV values for each face (triangle) 4. Stores UV coordinates for each triangle (6 float components) ### Surface Smoothing by using Vertices Normals 1. First you need to have per-face (triangle) normals * [GPT_Coords.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_Coords.js) `calculateNormals` * Creates `points3D` array by grouping 3 values from `positions` array * Creates triagles array by grouping 3 values from `points3D` array * Computes normals for each triangle clockwise 1. v1 = p2 - p1 2. v2 = p3 - p2 3. cross_product(v1, v2) 4. Applies modulus 5. Stores normal (3 float components) 2. Then you can invoke `computeVertexNormals` in order to make the transition between faces (triangles) smoother when computing the lighting ```javascript SceneDragon.prototype.createDragon = function () { // pre-calculated for surface smoothing this.dragon_model.geometry.computeVertexNormals(); ``` 3. You must update the material to be `smooth shading` ( `flatShading` = false) ```javascript _cbs.on_change_dragon_smoothing = (new_val_) => { const _dragon = this.gpt_models.get("dragon"); // boolean if (new_val_) { _dragon.material.flatShading = false; } else { _dragon.material.flatShading = true; } _dragon.material.needsUpdate = true; }; ``` ### Lighting and Shadows [SceneDragon.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/SceneDragon.js) `createLights` 1. Creates an `ambient light` that will be added when shading the models surface * 5% white * It doesn't need a position into the Scene 2. Creates a `point light` * 75% white * Emits in all directions 3. Creates a `directional light` * 75% white * Emits only in the direction vector provided (-200, 200, 0) 4. Creates a `focal light` * 75% white * Emits light in a cone volume * Direction of the central lighting vector is pointing to the center of the floor (0,0,0) * Defines `angle` and `distance` to make a `fading lighting` from the center of the cone to the exterior * Defines the cone like shape by defining parameters of shador: `near`, `far` and `fov` ### Skybox and reflections 1. [ModelSkyBox.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelSkybox.js) * Creates a `BoxGeometry` * Attaches a texture (material) per face * The texture images must be specifically for a cube texture * They need to be mapped properly ordered * `posx, negx, posy, negy, posz, negz` * Makes the inner of the box visible instead of the outside ```javascript ModelSkybox.prototype.get_material = function () { ... _cubeFacesMaterials.push( new THREE.MeshBasicMaterial({ map: _loader.load(_img_path), color: 0xffffff, // white side: THREE.BackSide // inside the cube }) ... ``` 2. Reflections on [ModelDragon.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelDragon.js) * Sets `transparent`, `opacity`, and `shinines` to simulate "glass" * Sets the `Skybox Textures Array` as `envMap` ```javascript ModelDragon.prototype.get_material = function () { const _mat = new THREE.MeshPhongMaterial( { color: 0xe5ffe5, emissive: 0xb4ef3e, flatShading: true, // initially per-triangle normals specular: 0x003300, shininess: 70, side: THREE.FrontSide, transparent: true, opacity: 0.75, envMap: Common.SKYBOX_CUBE_TEXTURE } ); ``` 3. Idem for hand of the robot [ModelGripper.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/ModelGripper.js) ### User Interface (sliders, toggles, buttons) [InputManager.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/InputManager.js) 1. It creates a `dat.gui` object * dat.gui assumes the GUI type based on the target's initial value type: * boolean: `checkbox` * int / float: `slider` * string: `text input` * function: `button` * When user updates a value with the UI we store the new value in `effect` variables 2. It attaches the corresponding `onChange` callbacks to be executed when a new value is set using the UI 3. Saves references to UI controllers, so we can reflect updates on the UI * Reflects text of `robot_state` * Reflects value of `robot_power` 4. Creates a custom html button for `shoot`, which is separated from the rest of the panel for better usability 5. Creates a `stats` widget at the bottom of the canvas container. This reflects the frames per second ### Finite State Machine to handle "shooting robot" [FSM_Robot.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/FSM_Robot.js) 1. Defines `States`, `Events` and allowed `Transitions` 2. A transition is defined as `destination state` given a pair `State-Event` 3. Updates the current state based on the expiration of timers * `IDLE` --> shoot --> `LOADING_BULLET` * `LOADING_BULLET` --> timer.expired --> `BULLET_TRAVELING` * `BULLET_TRAVELING` --> collision --> `HIT` * `BULLET_TRAVELING` --> timer.expired --> `NO_HIT` * `HIT` / `NO_HIT` --> timer.expired --> `IDLE` ### Collision detection using AABB [GPT_ModelCollider.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./core/GPT_ModelCollider.js) * Main concept can be read at [link](https://github.com/GiovannyJTT/libgptjs/blob/master/https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_collision_detection) 1. Attaches an AABB (axis aligned bounding box) 2. Updates the dimensions of the AABB at runtime 3. Checks if intersects with other AABB (collided) ### Particle System with Nebula-Threejs * Follow tutorial at [three-nebula.org](https://github.com/GiovannyJTT/libgptjs/blob/master/https://three-nebula.org/) * Nebula is a particle system engine that works with threejs * It provides an editor to create manually and save to json file #### Integration with libgptjs [DragonFireParticles.json](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/DragonFireParticles.json) 1. Adapted manually for our SceneDragon scale: ```json { "type": "Radius", "properties": { "width": 20, "height": 80, "isEnabled": true }, { "type": "RadialVelocity", "properties": { "radius": 400, "x": 0, "y": 0, "z": 1, "theta": 10, "isEnabled": true } ``` 2. The rest of values (color, sprite, life cycle, etc.) were edited using the Nebula editor (windows) [DragonFire.js](https://github.com/GiovannyJTT/libgptjs/blob/master/./scene-dragon/DragonFire.js) 1. Loads the particle system from json file and creates an instance of `nebula` that will be used to render * `Nebula.SpriteRenderer` needs the main `THREE.Scene` 2. Provides a method for updating the `dragon fire particles` according to dragon mouth position * `DragonFire.update_to_dragon_mouth` performs a sequence of translations and rotations to place / update properly the particles emitter while dragon is rotating

近期下载者

相关文件


收藏者