WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法

WebGL学习----Three.js学习笔记(5)

点击查看demo演示

Demo地址:https://nsytsqdtn.github.io/d...

简单网格材质 MeshNormalMaterial

MeshNormalMaterial是一种不受渲染时使用的颜色影响的材质,它只与自己每一个面从内到外的法向量有关。法向量在webgl中用处十分广泛,光的反射,以及三维图形的纹理映射都与这个有关。

从图中可以看到,网格的每一面渲染的颜色都是不一样的,如果我们想要在物体表面添加法向量,我们可以使用的THREE.ArrowHelper去表示每一个法向量,它的参数为

THREE.ArrowHelper(dir, origin, length, color, headLength, headWidth)

**其中参数的意义为:
dir:方向,默认是法向量
origin:开始的坐标位置
length:辅助线的长度
color:辅助线的颜色
headLength:头部的长度
headWidth:头部的宽度**

对于一个球体,要描述它每一个面的法向量,首先需要对它的每一个面进行遍历,取出这个面上的三个顶点(因为webgl的面都是三角形,所以是三个顶点),通过divideScalar(3)这个函数计算它的中心位置,我们就可以在这个中心位置点上,从内向外引出一个ArrowHelper,来模拟法向量。

 for(let i=0;i

其中,centroid.add(sphereGeometry.vertices[face.a])这段代码中的sphereGeometry.vertices存有几何体的所有顶点信息,通过[ ]索引可以取得其中的某一个顶点。face.a还有下面的face.b和c都是该面的顶点索引号,表示这个面是由顶点编号为face.a,face.b,face.c的三个顶点所构成的一个三角形(webgl的面都是三角形),然后我们再计算这三个顶点的中心点。

菜单面板的设置

在菜单面板中设置一些MeshNormalmaterial的一些属性,便于去测试这种材质的一些特质
其中:
**this.visible = meshMaterial.visible;//是否可见

        this.wireframe = meshMaterial.wireframe;//是否以线框的方式渲染物体
        this.wireframeWidth = meshMaterial.wireframeLinewidth;//线框的宽度
        this.transparent = meshMaterial.transparent;//是否透明
        this.opacity = meshMaterial.opacity;//透明度,需要transparent为true才有效果
        this.side = "front";//边的渲染方式,有三种,前面,后面,还有双面
        this.selectMesh = "sphere";//当前选择的几何体
        this.shading = "smooth";//着色方式,有平面着色和平滑着色,对一个面很平的几何体几乎看不出区别,如正方体**
    
function initDatGUI() {
        //设置菜单中需要的参数
        controls = new function () {
            this.rotationSpeed = 0.02;
            this.visible = meshMaterial.visible;//是否可见
            this.wireframe = meshMaterial.wireframe;//是否以线框的方式渲染物体
            this.wireframeWidth = meshMaterial.wireframeLinewidth;//线框的宽度
            this.transparent = meshMaterial.transparent;//是否透明
            this.opacity = meshMaterial.opacity;//透明度,需要transparent为true才有效果
            this.side = "front";//边的渲染方式,有三种,前面,后面,还有双面
            this.selectMesh = "sphere";//当前选择的几何体
            this.shading = "smooth";//着色方式,有平面着色和平滑着色,对一个面很平的几何体几乎看不出区别,如正方体
        };
        let gui = new dat.GUI();
        //将刚刚设置的参数添加到菜单中
        let F1 = gui.addFolder("Mesh");
        F1.add(controls, "rotationSpeed", 0, 0.1);
        F1.add(controls, "visible").onChange(function (e) {
            meshMaterial.visible = e;
        });
        F1.add(controls, "wireframe").onChange(function (e) {
            meshMaterial.wireframe = e;
        });
        F1.add(controls, "wireframeWidth",0,10).onChange(function (e) {
            meshMaterial.wireframeWidth = e;
        });
        F1.add(controls, "transparent").onChange(function (e) {
            meshMaterial.transparent = e;
        });
        F1.add(controls, "opacity",0,1).onChange(function (e) {
            meshMaterial.opacity = e;
        });
        F1.add(controls, "side",["front","back","double"]).onChange(function (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;//要在程序中让材质更新需要添加这一句话
        });
        F1.add(controls, "selectMesh",["sphere","cube","plane"]).onChange(function (e) {
            //先把场景的物体清除,再来添加
            scene.remove(cube);
            scene.remove(sphere);
            scene.remove(plane);
            switch (e) {
                case "sphere":
                    scene.add(sphere);
                    break;
                case "cube":
                    scene.add(cube);
                    break;
                case "plane":
                    scene.add(plane);
                    break;
            }
        });
        F1.add(controls, "shading",["flat","smooth"]).onChange(function (e) {
            switch (e) {
                case "flat":
                    meshMaterial.shading = THREE.FlatShading;
                    break;
                case "smooth":
                    meshMaterial.shading = THREE.SmoothShading;
                    break;
            }
            meshMaterial.needsUpdate = true;//要在程序中让材质更新需要添加这一句话
        });
    }

**注意在程序运行过程中想要改变材质的属性,需要在改完以后,添加一句
meshMaterial.needsUpdate = true,这样才能更新成功。**

360度全景背景

360度全景背景能够让人有身临其境的感觉,所有这里的背景使用了全景背景


如果想要使用全景的背景,就需要6张6个方向的图片来合成一个完整的背景(也可以使用1张6方向的图片),然后把这些贴图赋值给 scene.background

 let urls =[
            'image/posx.jpg',
            'image/negx.jpg',
            'image/posy.jpg',
            'image/negy.jpg',
            'image/posz.jpg',
            'image/negz.jpg'
        ];//引入6个方向的贴图
        let cubeMap = THREE.ImageUtils.loadTextureCube( urls );
        scene = new  THREE.Scene();
        scene.background = cubeMap;

这些图片的需要按照顺序摆放,右左上下后前,否则背景会错乱。
这里给一个全景图片的网站,里面有很多的360度风景图,都是6张类型的,下载下来解压后就可以直接引入
http://www.humus.name/index.p...

本例子的完整代码如下:




    
    Depth Material Test
    
    
    
    
    
    
    


你可能感兴趣的:(javascript,webgl,three.js,html5,前端)