# Introduction of WebGL 3.js Learning Notes Normal Vector Mesh Material and Method of Creating 360 Degree Panoramic Skybox

## Simple Mesh Normal Material

Mesh Normal Material is a material that is not affected by the color used in rendering. It is only related to the normal vector from inside to outside of each side of itself. Normal vectors are widely used in webgl. The reflection of light and texture mapping of three-dimensional graphics are related to this. As can be seen from the graph, each side of the mesh is rendered in different colors. If we want to add normal vectors to the surface of the object, we can use THREE.ArrowHelper to represent each normal vector, whose parameters are

** The meaning of the parameters is as follows:
dir: Direction, default normal vector
origin: The starting coordinate position
Length: the length of the auxiliary line
Color: the color of the auxiliary line

For a sphere, to describe the normal vector of each surface, we first need to traverse every surface of the sphere, extract the three vertices of the surface (because the surface of webgl is triangle, so it is three vertices). By calculating the center position of the sphere through the divideScalar(3) function, we can derive an ArrowHelper from inside out at the center point. To simulate normal vectors.

`````` for(let i=0;i<sphereGeometry.faces.length;i++){//Cycle on each surface
let face = sphereGeometry.faces[i];//Get the object for each face
let centroid = new THREE.Vector3();
//First create a vector3 object to use to find the center of each face
// Pass the index of the three vertices on this surface to sphereGeometry.vertices to find the coordinates of their vertices
centroid.divideScalar(3);//The coordinates of the central point of a triangle
let arrow = new THREE.ArrowHelper(
face.normal,//The normal vector of face
centroid,
2,
0xffcc55,
0.5,
0.5);//The arrow auxiliary line is equivalent to the normal vector represented by the arrow.
}``````

Among them, sphereGeometry.vertices in the code of centroid.add(sphereGeometry.vertices[face.a]) contains all vertex information of the geometry body, and one of them can be obtained by [] index. Face.a and the following face.b and C are vertex index numbers of the face, indicating that the face is a triangle composed of three vertices with vertex numbers face.a, face.b and face.c. (The faces of webgl are triangles). Then we calculate the center points of the three vertices.

Set some properties of Mesh Normalmaterial in the menu panel to test some characteristics of this material.
Among them:
** this.visible = meshMaterial.visible; // visible

``````        this.wireframe = meshMaterial.wireframe;//Whether or not to render objects in a wireframe fashion
this.wireframeWidth = meshMaterial.wireframeLinewidth;//Width of Wire Frame
this.transparent = meshMaterial.transparent;//Is it transparent?
this.opacity = meshMaterial.opacity;//Transparency requires transparent to be true to be effective
this.side = "front";//There are three ways to render edges: front, back, and both sides.
this.selectMesh = "sphere";//Currently selected geometry
``````
``````function initDatGUI() {
//Setting the parameters needed in the menu
controls = new function () {
this.rotationSpeed = 0.02;
this.visible = meshMaterial.visible;//Visible
this.wireframe = meshMaterial.wireframe;//Whether or not to render objects in a wireframe fashion
this.wireframeWidth = meshMaterial.wireframeLinewidth;//Width of Wire Frame
this.transparent = meshMaterial.transparent;//Is it transparent?
this.opacity = meshMaterial.opacity;//Transparency requires transparent to be true to be effective
this.side = "front";//There are three ways to render edges: front, back, and both sides.
this.selectMesh = "sphere";//Currently selected geometry
};
let gui = new dat.GUI();
meshMaterial.visible = e;
});
meshMaterial.wireframe = e;
});
meshMaterial.wireframeWidth = e;
});
meshMaterial.transparent = e;
});
meshMaterial.opacity = e;
});
switch (e) {
case "front":
meshMaterial.side = THREE.FrontSide;
break;
case "back":
meshMaterial.side = THREE.BackSide;
break;
case "double":
meshMaterial.side = THREE.DoubleSide;
break;
}
meshMaterial.needsUpdate = true;//To update the material in the program, you need to add this sentence
});
//First remove the objects in the scene, then add them.
scene.remove(cube);
scene.remove(sphere);
scene.remove(plane);
switch (e) {
case "sphere":
break;
case "cube":
break;
case "plane":
break;
}
});
switch (e) {
case "flat":
break;
case "smooth":
break;
}
meshMaterial.needsUpdate = true;//To update the material in the program, you need to add this sentence
});
}``````

** Note that if you want to change the properties of the material in the process of running the program, you need to add a sentence after the modification.
meshMaterial.needsUpdate = true, so that the update is successful. * *

## 360 degree panoramic background

A 360-degree panoramic background gives people a sense of immersion. All the backgrounds here use panoramic backgrounds. If you want to use a panoramic background, you need six pictures in six directions to synthesize a complete background (you can also use one picture in six directions), and then assign these maps to scene background.

`````` let urls =[
'image/posx.jpg',
'image/negx.jpg',
'image/posy.jpg',
'image/negy.jpg',
'image/posz.jpg',
'image/negz.jpg'
];//Introducing 6-Direction Mapping
let cubeMap = THREE.ImageUtils.loadTextureCube( urls );
scene = new  THREE.Scene();
scene.background = cubeMap;``````

These pictures need to be placed in order, right, left, back and forth, otherwise the background will be confused.
Here is a panoramic picture website, there are many 360 degree scenery, are six types, download and decompress can be directly introduced.
http://www.humus.name/index.p...

The complete code for this example is as follows:

``````<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<title>Depth Material Test</title>
<script src="../../import/three.js"></script>
<script src="../../import/stats.js"></script>
<script src="../../import/Setting.js"></script>
<script src="../../import/OrbitControls.js"></script>
<script src="../../import/dat.gui.min.js"></script>
<script src="../../import/SceneUtils.js"></script>
<style type="text/css">
div#WebGL-output {
border: none;
cursor: pointer;
width: 100%;
height: 850px;
background-color: #333333;
}
</style>
<div id="WebGL-output"></div>
<script>
let camera, renderer, scene, light;
let controller;
let controls;
let cube, sphere, plane, meshMaterial;

function initThree() {
//Render initialization
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x333333);

//Initialize the camera, using the perspective projection camera here
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 10, 100);
camera.position.set(0, 40, 60);
camera.up.x = 0;//Set the orientation of the camera in which direction, and define the orientation of the Y axis above the camera here.
camera.up.y = 1;
camera.up.z = 0;
camera.lookAt(0, 0, 0);

//Initialization scenario
let urls =[
'image/posx.jpg',
'image/negx.jpg',
'image/posy.jpg',
'image/negy.jpg',
'image/posz.jpg',
'image/negz.jpg'
];//Introducing 6-Direction Mapping
let cubeMap = THREE.ImageUtils.loadTextureCube( urls );
scene = new  THREE.Scene();
scene.background = cubeMap;

//Camera movement
controller = new THREE.OrbitControls(camera, renderer.domElement);
controller.target = new THREE.Vector3(0, 0, 0);

light = new THREE.AmbientLight(0x0c0c0c);

light = new THREE.SpotLight(0xffffff);
light.position.set(0, 30, 30);

}

function initDatGUI() {
//Setting the parameters needed in the menu
controls = new function () {
this.rotationSpeed = 0.02;
this.visible = meshMaterial.visible;//Visible
this.wireframe = meshMaterial.wireframe;//Whether or not to render objects in a wireframe fashion
this.wireframeWidth = meshMaterial.wireframeLinewidth;//Width of Wire Frame
this.transparent = meshMaterial.transparent;//Is it transparent?
this.opacity = meshMaterial.opacity;//Transparency requires transparent to be true to be effective
this.side = "front";//There are three ways to render edges: front, back, and both sides.
this.selectMesh = "sphere";//Currently selected geometry
};
let gui = new dat.GUI();
meshMaterial.visible = e;
});
meshMaterial.wireframe = e;
});
meshMaterial.wireframeWidth = e;
});
meshMaterial.transparent = e;
});
meshMaterial.opacity = e;
});
switch (e) {
case "front":
meshMaterial.side = THREE.FrontSide;
break;
case "back":
meshMaterial.side = THREE.BackSide;
break;
case "double":
meshMaterial.side = THREE.DoubleSide;
break;
}
meshMaterial.needsUpdate = true;//To update the material in the program, you need to add this sentence
});
//First remove the objects in the scene, then add them.
scene.remove(cube);
scene.remove(sphere);
scene.remove(plane);
switch (e) {
case "sphere":
break;
case "cube":
break;
case "plane":
break;
}
});
switch (e) {
case "flat":
break;
case "smooth":
break;
}
meshMaterial.needsUpdate = true;//To update the material in the program, you need to add this sentence
});
}

function initObject() {
//Create Cubes, Geometries of the Earth and the Earth
let cubeGeometry = new THREE.BoxGeometry(10, 10, 10);
let sphereGeometry = new THREE.SphereGeometry(10, 20, 20);
let planeGeometry = new THREE.PlaneGeometry(10, 10, 1, 1);
//Create a Normal Material
meshMaterial = new THREE.MeshNormalMaterial();

cube = new THREE.Mesh(cubeGeometry, meshMaterial);
sphere = new THREE.Mesh(sphereGeometry, meshMaterial);
plane = new THREE.Mesh(planeGeometry, meshMaterial);
//Unify the three positions
cube.position.set(0,0,0);
sphere.position = cube.position;
plane.position = cube.position;

//A normal vector is displayed on each surface of the sphere to facilitate observation of the rendering method of the normal vector material.
for(let i=0;i<sphereGeometry.faces.length;i++){//Cycle on each surface
let face = sphereGeometry.faces[i];//Get the object for each face
let centroid = new THREE.Vector3();//First, create a vector3 object to use to find the center of each face.
// Pass the index of the three vertices on this surface to sphereGeom.vertices to find the coordinates of their vertices and add them to the centroid
centroid.divideScalar(3);//The coordinates of the central point of a triangle
let arrow = new THREE.ArrowHelper(
face.normal,
centroid,
2,
0xffcc55,
0.5,
0.5);//The arrow auxiliary line is equivalent to the normal vector represented by the arrow.
}
}

function rotation() {
scene.traverse(function (e) {
if (e instanceof THREE.Mesh) {
e.rotation.y += controls.rotationSpeed;
}
})
}

//renderer
function render() {
rotation();
stats.update();
renderer.clear();
requestAnimationFrame(render);
renderer.render(scene, camera);
}

//Function function
function setting() {
}

//Running the main function, typing the code is always wrong, so it's more convenient to change the name to Start.
function Start() {
initThree();
initObject();
initDatGUI();
setting();
render();
}
</script>
</body>
</html>``````

Tags: Javascript github

Posted on Thu, 25 Apr 2019 12:06:34 -0400 by HAN!