zoukankan      html  css  js  c++  java
  • three.js一个简单demo学些和讲解

    叉口裁剪球体案例

    二话不说先上效果图:

    叉口裁剪球体案例效果图
    叉口裁剪球体案例效果图

    全部代码带注释

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>clipIntersection</title>
      <style>
      body {
        margin: 0;
        background: #000;
        overflow: hidden;
      }
      </style>
    </head>
    
    <body>
      <script src="../three.js-master/build/three.js"></script>
      <script src="../libs/OrbitControls.js"></script>
      <script>
      var camera, scene, renderer;
      // 定义参数,后面定义材质的时候会用到
      var params = {
        clipIntersection: true
      };
      // 定义裁剪的切面,后面定义材质的时候会用到
      var clipPlanes = [
        new THREE.Plane(new THREE.Vector3(1, 0, 0), 0),
        new THREE.Plane(new THREE.Vector3(0, -1, 0), 0),
        new THREE.Plane(new THREE.Vector3(0, 0, -1), 0)
      ];
    
      init()
      render()
    
      function init() {
        // 定义WebGL渲染器,并且开启抗锯齿
        renderer = new THREE.WebGLRenderer({ antialias: true })
        // 设置设备像素比,通常用于HiDPI(一种高清渲染方式)设备防止模糊输出canvas
        renderer.setPixelRatio(window.devicePixelRatio)
        // 返回一个包含渲染器输出canvas宽高的对象,以像素为单位
        renderer.setSize(window.innerWidth, window.innerHeight)
        // 定义渲染器是否考虑对象级别的裁剪平面
        renderer.localClippingEnabled = true
        // 将输出的canvas添加到body中
        document.body.appendChild(renderer.domElement)
    
        // 定义场景和相机并且设置相机的位置
        scene = new THREE.Scene()
        camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 0.1, 1000)
        camera.position.set(-20, 30, 40)
    
        // 设置鼠标点击拖拽之后旋转和滚动滚轮放大缩小
        var controls = new THREE.OrbitControls(camera, renderer.domElement)
        controls.addEventListener('change', render); // use only if there is no animation loop
        controls.minDistance = 10;
        controls.maxDistance = 100;
        controls.enablePan = false;
    
        // 定义半球光,参数为天空颜色,地面颜色,光的强度
        var light = new THREE.HemisphereLight(0xffffff, 0x080808, 1)
        scene.add(light)
        // 添加环境光
        scene.add(new THREE.AmbientLight(0x505050))
    
        // 这与Object3d几乎是一样的,其目的是使用语法上更清晰的对象组进行工作
        var group = new THREE.Group()
    
        for (var i = 1; i < 25; i++) {
          // 创建球体的缓存几何模型,参数为半径,水平分割面数量,垂直分割面数量
          var geometry = new THREE.SphereBufferGeometry(i / 2, 48, 24);
          // 定义兰伯特网口材料,一种非发光材质
          var material = new THREE.MeshLambertMaterial({
            // 线条的十六进制颜色
            color: new THREE.Color(Math.sin(i * 0.5) * 0.5 + 0.5, Math.cos(i * 1.5) * 0.5 + 0.5, Math.sin(i * 4.5 + 0) * 0.5 + 0.5),
            // 定义表面两侧的哪一个将呈现,默认是前面
            side: THREE.DoubleSide,
            // 用户在全局使用THREE.Plane对象定义的裁剪平面,这些平面应用于该材料所附的对象。
            // 空间中与平面点积为负的点将被裁剪掉。缺省为空 []。
            clippingPlanes: clipPlanes,
            // 改变剪切平面的行为,以便只裁剪他们的交集,而不是剪接
            clipIntersection: params.clipIntersection
          })
          // 三角形布成的网格图形的基类
          group.add(new THREE.Mesh(geometry, material))
        }
    
        scene.add(group)
        window.addEventListener('resize', onWindowResize, false);
      }
    
    
      function onWindowResize() {
        // 设置相机视锥体宽高比
        camera.aspect = window.innerWidth / window.innerHeight;
        // 更新相机投影矩阵
        camera.updateProjectionMatrix();
        // 设置渲染器宽高
        renderer.setSize(window.innerWidth, window.innerHeight);
        render();
      }
    
      function render() {
        renderer.render(scene, camera);
      }
      </script>
    </body>
    
    </html>
    

    代码知识点详解

    1. THREE.Plane
      • 该方法是定义一个在三维空间中无线伸展的平面,Plane( normal, constant )
      • normal -- (Vector3) 定义平面指向原点的法向量,(1, 0, 0)
      • constant -- (Float) 从原点到平面沿法线方向的负距离,默认0
    2. THREE.Vector3
      • 定义一个三维向量,Vector3( x, y, z )
      • x,y,z分别代表向量的x,y,z的值
    3. THREE.WebGLRenderer
      • WebGL渲染器使用WebGL来绘制您的场景,如果您的设备支持的话。使用WebGL将能够利用GPU硬件加速从而提高渲染性能。这个渲染器比 Canvas渲染器(CanvasRenderer) 有更好的性能。
      • WebGLRenderer( parameters ),parameters可以不写,parameters参数介绍:
        • canvas:将要渲染到的canvas对象,如果没有定义将会新创建一个canvas
        • context:所需要的渲染上下文对象
        • precision:着色器的精度,有"highp","mediump","lowp",如果设备支持的话默认为"highp"
        • alpha:这个canvas是否包含alpha(透明度)缓冲区,默认为false
        • premultipliedAlpha:渲染器是否会假设颜色具有预乘透明度
        • antialias:是否抗锯齿,默认为false
        • stencil:绘制缓冲区是否有一个最少8位的模板缓冲区,默认为true
        • preserveDrawingBuffer:是否保留缓冲区,知道手动清除或者覆盖,默认为false
        • depth:绘图缓冲区是否具有至少16位的深度缓冲区,默认为true
        • logarithmicDepthBuffer:是否使用对数深度缓冲区,如果在一个场景中处理巨大的差异可能需要使用它
      • renderer.setPixelRatio(PixelRatio),设置设备像素比,通常用于HiDPI设备放置模糊输出canvas,最好使用新的three.js文件
      • renderer.setSize(width,height,updateStyle),调整输出canvas尺寸,要考虑设备像素比,并且设置视口以匹配改尺寸,如果设置updateStyle为true则显示添加像素到输出canvas的样式中
      • renderer.localClippingEnabled,定义渲染器是否考虑对象级别的裁剪平面
      • 他还有很多的属性和方法,以后在需要的时候再介绍
    4. THREE.Scene
      • 场景允许你设置哪些对象呗three.js渲染并且渲染在哪里,我们在场景中放置物体,灯光和相机,他有三个属性:
        • fog,一个fog实例,定义了场景中雾状北京类型,默认为null
        • overrideMaterial,如果不为空,它将强制场景中的一切对象都是用该材料进行渲染,默认为null
        • autoUpdate:默认为true,如果设置为true,那么每一帧的渲染都要检查场景和对象是否需要矩阵更新,否则你必须自己来维护场景中的所有矩阵
    5. THREE.PerspectiveCamera
      • 进行远景投影的相机,PerspectiveCamera( fov, aspect, near, far )
        • FOV,相机视锥体垂直角度
        • aspect,相机视锥体宽高比
        • near,相机视锥体近裁剪面
        • far,相机视锥体远裁剪面
      • camera.position.set(x,y,z),定义相机的位置
      • camera.updateProjectionMatrix(),更新相机投影矩阵
    6. THREE.HemisphereLight
      • 位于场景正上方的光源,HemisphereLight( skyColor, groundColor, intensity )
        • skyColor,RGB天空颜色值
        • groundColor,RGB地面颜色值
        • intensity,光的强度
    7. THREE.AmbientLight
      • 定义环境光,AmbientLight( color, intensity ),这种光应用到场景中的所有物体
        • color:RGB颜色
        • intensity:光的强度
    8. THREE.SphereBufferGeometry
      • 球体缓存几何模型,SphereBufferGeometry(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
    9. THREE.MeshLambertMaterial
      • 兰伯特网口材质,一种非发光材料,无镜面高光,改材料使用非物理的朗博模型来计算反射率,这可以模拟一些表面(如未经处理的木材或者石头),但是不能模拟具有镜面高光的光泽表面(比如上漆的木头)
      • 阴影使用Gouraud阴影模型计算,这将计算每个顶点的阴影(在顶点着色器中),并在多边形的面上插入结果
      • 由于反射率和照明模型的简单性,性能要比其他几个材质更好,代价是图形的准确行要稍差
      • MeshLambertMaterial( parameters )
        • color,线条的十六进制颜色,默认为0xffffff
        • side,定义表面两侧的哪一个将呈现,前面,后面或者双面,默认值是THREE.Frontside,其他可选为THREE.Backside和THREE.Doubleside
        • map,设置纹理贴图,默认为null
        • lightMap,设置光照贴图,默认为null
        • lightMapIntensity,设置光照贴图强度,默认为1
        • aoMap,设置环境遮挡贴图(ao=ambient occlusion),默认为null
        • aoMapIntensity,设置环境遮挡贴图强度,默认为1
        • specularMap,高光贴图,默认为null
        • alphaMap,透明度贴图,默认为null
        • envMap,环境贴图,默认为null
        • combine,如果有环境贴图,如何组合表面颜色的结果,默认为THREE.Multiply,还有THREE.MixOperation, THREE.AddOperation.如果选择了mix,反射率用于在两种颜色之间进行混合
        • reflectivity,设置反射率,默认为1
        • refractionRatio,设置折射率默认值是0.98
        • fog,定义材质是否受全局雾设置的有影响,默认为true
        • shading,定义着色器,默认为THREE.SmoothShading
        • wireframe,渲染模型为线框,默认为false
        • wireframeLinewidth,线框线宽度,默认为1
        • wireframeLinecap,定义线端的外观,默认值是round
        • vertexColors:定义顶点如何着色,默认值是THREE.NoColors
        • skinning:定义材质是否使用皮肤,默认为false
        • morphTargets:定义是否使用变形目标,默认为false
        • morphNormals:定义材质是否使用morphNormals,如果设置为true的话将morphNormals从geometry传递到着色器,默认为false
        • clippingPlanes,用户定义的裁剪平面,指定为世界空间中的THREE.Plane对象。 这些平面应用于该材料所附的对象。空间中与平面点积为负的点将被裁剪掉。缺省为空 []
        • chipIntersection,改变裁剪平面的行为,一边只是裁剪他们的交集而不是剪接
        • 还有其他许多基础材料的属性就不在继续介绍了,会在后续逐渐介绍
    10. THREE.Mesh
      • 网孔对象的基类,Mesh( geometry, material )
        • geometry,一个几何体的实例
        • 一个材质的实例
  • 相关阅读:
    微信支付收款限制
    手机自动化截图调试工具——PhotoShop
    ZipSecureFile$ThresholdInputStream cannot be cast to java.base/java.util.zip.ZipFile$ZipFileInputStream
    [Leetcode题解]605. 种花问题-贪心算法+卫语句重构
    「问题修复」「cargo」warning: spurious network error (2 tries remaining): [6] Couldn't resolve host name (Could not resolve host: crates)
    久坐程序员,简单高效的保命技巧,以及某人久坐的惨样
    [Leetcode题解]2. 两数相加-链表遍历和重构
    Go语言基础知识01-用Go打个招呼
    【Qt Tips】QLineEdit内容过滤之setValidator和setInputMask浅析
    Ubuntu12.10 使用JLink连接开发板用arm-gdb调试ARM程序
  • 原文地址:https://www.cnblogs.com/ytg-share/p/7675895.html
Copyright © 2011-2022 走看看