three.js自学之旅(7)—— 各种模型探究(2)

 鉴于很多人看姿势博客基本只看个开头(从自己身上发现),所以会把后面的主要内容和重点内容先拎上来概括一下。

 上一章的例子里给的图都是只有线,没有面,要么只有面,没有线,上网查了很多办法,这一章先来解决既有线又有面的问题。然后再来玩一下椎体模型、圆柱体模型和球体模型,球体模型我会重点关注,这跟我的毕设(搭建一个全景图平台)挂钩。最终所学会做成一个毕设网站,至于要不要申请域名,到时候看情况。

 先来看看如何让模型看起来线面结合,更加直观,更加美观。这里要用到一个新的东西(又他喵的藏在官方API的一个犄角旮旯里),SceneUtils,场景工具箱一共包含三个方法,这里只提用到的。.createMultiMaterialObjecet(geometry,material)为材质中定义的每种材质创建一个新的Object3D对象。请注意,这与MultiMaterial不同,它定义了多个网格物料。这对于需要材质和线框实现的对象最为有用。只要注意到这句话就行了,鉴于之前的兰伯特网孔材料在研究魔性的时候展示出来的效果不是很好,顺便替换了材质。下面上代码和实际效果图

1.椎体模型(ConeGeometry)

var material = [
    new THREE.MeshPhongMaterial({color:0x0000ff}),
    new THREE.MeshPhongMaterial({color:0x000000,wireframe:true})
]; //材质,用了两种材质,一个用来描绘图形,一个用来描绘线
var geometry = new THREE.ConeGeometry(2,5,8,8,false,0,6.28);
var cone = new THREE.SceneUtils.createMultiMaterialObject(geometry,material);
cone.rotation.x = -30*Math.PI/180;
cone.rotation.y = -30*Math.PI/180;
cone.rotation.z = -30*Math.PI/180;
console.log(cone);//输出一下生成的对象,看下面的图
cone.children[ 1 ].scale.multiplyScalar( 1.005 );
scene.add(cone);

assistantTool.modifyParameters(cone.children[ 0 ].geometry.parameters,[
    {
        par:"radius",
        max:20,
        min:1,
        every:1
    },{
        par:"height",
        max:30,
        min:3,
        every:1
    },{
        par:"radialSegments",
        max:20,
        min:2,
        every:1
    },{
        par:"heightSegments",
        max:20,
        min:1,
        every:1
    },{
        par:"thetaStart",
        max:6.28,
        min:0,
        every:0.1
    },{
        par:"thetaLength",
        max:6.28,
        min:0,
        every:0.1
    }
],function(){
    var newGeometry = geometry.parameters;
    cone.children[ 0 ].geometry.dispose();
    cone.children[ 0 ].geometry =  new THREE.ConeGeometry(newGeometry.radius,newGeometry.height,newGeometry.radialSegments,newGeometry.heightSegments,false,newGeometry.thetaStart,newGeometry.thetaLength);
    cone.children[ 1 ].geometry.dispose();
    cone.children[ 1 ].geometry =  new THREE.ConeGeometry(newGeometry.radius,newGeometry.height,newGeometry.radialSegments,newGeometry.heightSegments,false,newGeometry.thetaStart,newGeometry.thetaLength);
})



看起来已经跟官网展示的demo差不多了,同时我还更改了光源,用了四个灯泡,看起来效果更好一些

var pointLights = [
    new THREE.PointLight({color:0xffffff}),
    new THREE.PointLight({color:0xffffff}),
    new THREE.PointLight({color:0xffffff}),
    new THREE.PointLight({color:0xffffff}),
]
pointLights [0].position.set(-10,0,0);
pointLights [1].position.set(10,0,0);
pointLights [2].position.set(0,0,10);
pointLights [3].position.set(0,0,-10);
scene.add(pointLights [0]);
scene.add(pointLights [1]);
scene.add(pointLights [2]);
scene.add(pointLights [3]);

2.圆柱体模型(CylinderGeometry)
//圆柱体模型
var geometry = new THREE.CylinderGeometry(2,2,5,8,8,false,0,6.28);
var cylinder = new THREE.SceneUtils.createMultiMaterialObject(geometry,material);
cylinder.rotation.x = -30*Math.PI/180;
cylinder.children[ 1 ].scale.multiplyScalar( 1.005 );
scene.add(cylinder);

assistantTool.modifyParameters(cylinder.children[ 0 ].geometry.parameters,[
    {
        par:"radiusTop",
        max:20,
        min:0,
        every:1
    },{
        par:"radiusBottom",
        max:20,
        min:1,
        every:1
    },{
        par:"height",
        max:30,
        min:3,
        every:1
    },{
        par:"radialSegments",
        max:20,
        min:2,
        every:1
    },{
        par:"heightSegments",
        max:20,
        min:1,
        every:1
    },{
        par:"thetaStart",
        max:6.28,
        min:0,
        every:0.1
    },{
        par:"thetaLength",
        max:6.28,
        min:0,
        every:0.1
    }
],function(){
    var newGeometry = geometry.parameters;
    cylinder.children[ 0 ].geometry.dispose();
    cylinder.children[ 0 ].geometry =  new THREE.CylinderGeometry(newGeometry.radiusTop,newGeometry.radiusBottom,newGeometry.height,newGeometry.radialSegments,newGeometry.heightSegments,false,newGeometry.thetaStart,newGeometry.thetaLength);
    cylinder.children[ 1 ].geometry.dispose();
    cylinder.children[ 1 ].geometry =  new THREE.CylinderGeometry(newGeometry.radiusTop,newGeometry.radiusBottom,newGeometry.height,newGeometry.radialSegments,newGeometry.heightSegments,false,newGeometry.thetaStart,newGeometry.thetaLength);
})

扫描二维码关注公众号,回复: 2179434 查看本文章


设置radiusTop的值为0,和圆锥是一样的,所以不详细展开了。


3.球体模型(SphereGeometry)

重点介绍一下球体模型,以及球体模型参数好玩的的地方,先来看一下球模型的几个参数

SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength)
radius — 球体半径. 默认值为50.
widthSegments — 水平分割面的数量. 最小值为3, 默认值为8.
heightSegments — 垂直分割面的数量. 最小值为2, 默认值为6.
phiStart — 指定水平起始角度. 默认值为0.
phiLength — 指定水平扫描角度大小. 默认值为 Math.PI * 2.
thetaStart — 指定垂直起始角度. 默认值为0.
thetaLength — 指定垂直扫描角度大小. 默认值为Math.PI.

//球体模型
var geometry  = new THREE.SphereGeometry(2,8,8,0,6.28,0,3.14);
var sphere =  new THREE.SceneUtils.createMultiMaterialObject(geometry,material);
sphere.children[ 1 ].scale.multiplyScalar( 1.005 );
scene.add(sphere);

assistantTool.modifyParameters(sphere.children[ 0 ].geometry.parameters,[
    {
        par:"radius",
        max:20,
        min:1,
        every:1
    },{
        par:"widthSegments",
        max:20,
        min:3,
        every:1
    },{
        par:"heightSegments",
        max:20,
        min:3,
        every:1
    },{
        par:"phiStart",
        max:6.28,
        min:0,
        every:0.1
    },{
        par:"phiLength",
        max:6.28,
        min:0,
        every:0.1
    },{
        par:"thetaStart",
        max:6.28,
        min:0,
        every:0.1
    },{
        par:"thetaLength",
        max:6.28,
        min:0,
        every:0.1
    }
],function(){
    var newGeometry = geometry.parameters;
    sphere.children[ 0 ].geometry.dispose();
    sphere.children[ 0 ].geometry =  new THREE.SphereGeometry(newGeometry.radius,newGeometry.widthSegments,newGeometry.heightSegments,newGeometry.phiStart,newGeometry.phiLength,newGeometry.thetaStart,newGeometry.thetaLength);
    sphere.children[ 1 ].geometry.dispose();
    sphere.children[ 1 ].geometry =  new THREE.SphereGeometry(newGeometry.radius,newGeometry.widthSegments,newGeometry.heightSegments,newGeometry.phiStart,newGeometry.phiLength,newGeometry.thetaStart,newGeometry.thetaLength);
})


重点讲一下有意思的两个参数

phiLength — 指定水平扫描角度大小. 默认值为 Math.PI * 2.

thetaLength — 指定垂直扫描角度大小. 默认值为Math.PI.

关于这两个参数,我在本地的显示效果不是很好,建议大家去官网的demo玩一下会比较清楚

http://techbrood.com/threejs/docs/scenes/geometry-browser.html#SphereGeometry

第一个参数其实很好理解,只要稍作调整,使得他<2*PI,你就会发现,你的模型破了一个洞


第二个参数跟第一个参数差不多,但他的默认值是PI,当你设置他<PI的时候

当这两个参数>默认值的时候,情况会比较复杂,你可以想象是再生成一个新的球,具体效果看官网的demo就能明白。

模型探究就到这儿,下一章会讲一下纹理,加快一下毕设的进度。

关于毕设的终极效果,是一个VR的看房网站。继续学习吧,不想太多


 

 












猜你喜欢

转载自blog.csdn.net/dkr380205984/article/details/79112158