• threejs三角形Geometry的顶点时针顺序会导致三角形看不见


    var scene = new THREE.Scene();

    var camera = new THREE.PerspectiveCamera(75,winSize.width/winSize.height,0.1,1000);
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(winSize.width,winSize.height);
    document.body.appendChild(renderer.domElement);
     
    camera.position.x = -30;
    camera.position.y = 30;
    camera.position.z = 40;
    camera.up.set(0,1,0);
    camera.lookAt(new THREE.Vector3(0,0,0));

    var p1 = new THREE.Vector3(0,10,20);
    var p2 = new THREE.Vector3(0,30,20);
    var p3 = new THREE.Vector3(0,25,40);

    var triangleGeometry = new THREE.Geometry();
    triangleGeometry.vertices.push(p1,p2,p3);

    //3个点投射到camera也就是2d屏幕平面上的时候,在2d平面上这3个点的时针顺序,顺时针如果看不见,就改成逆时针
    triangleGeometry.faces.push(new THREE.Face3(1,0,2));
    // triangleGeometry.faces.push(new THREE.Face3(0,1,2));
    var triangle = new THREE.Mesh(triangleGeometry,
    new THREE.MeshBasicMaterial({ color: 0xff00ff }));
    scene.add(triangle);

    会出现的问题就是,某种情况下,会看不见这个三角形,但是如果把THREE.Geometry对象的vertices数组参数或者faces数组参数里的元素顺序改变一下,三角形就出来了;

    出现这种情况的原因,国外帖子的解释是说跟法线的方向有关系,如果顺序按照顺时针顺序,则曲面的法向量将向下指向,并且由于相机从上面看,所以会看不到三角形,如果顺序是逆时针的,法向量会指向你的相机,就看到三角形了,总是就是要想办法让法向量指向你的摄像机;

    解决问题的一个思路,目前个人理解vertices数组里3个点的顺序,不是问题的关键,关键是在这3个点在faces数组里的顺序,上面代码中vertices数组里的元素的顺序是,p1,p2,p3, faces数组里的元素1,0,2,代表正确的绘图时的顺序是p2,p1,p3,  所以上面代码中,也可以改成这样:

    triangleGeometry.vertices.push(p2,p1,p3);
    triangleGeometry.faces.push(new THREE.Face3(0,1,2));
    var triangle = new THREE.Mesh(triangleGeometry,
    new THREE.MeshBasicMaterial({ color: 0xff00ff }));
    scene.add(triangle);

    既然有3个点的存在,不管在3d世界里是什么朝向,什么角度,投射到摄像机也就是2d屏幕上的时候,总是可以看成是一个2d平面上的3个点,

    如果发现看不到这3个点组成的三角形,如果此时3个点是的指针方向是顺时针,就改成逆时针,反之如果是逆时针,就改成顺时针,就可以看到三角形了。

    正式的3d项目中的模型,如果不带透明度的话,摄像机拍摄不到的模型背面的面,看不到就看不到了,本来不需要看到,但如果是带有透明度材质的模型,如果在模型本身角度偏转或者摄像机大角度围绕模型旋转而造成模型一个面上3个点的指针顺序发生了顺/逆的改变,那是不是就要实时的计算和改变个面的3个顶点的时针顺序。目前3d这快个人理解还很浅陋,希望以后有机会打自己脸。

    参考:https://stackoverflow.com/questions/39398503/draw-a-basic-triangle-with-three-js?rq=1

    ============================================

    opengl右手坐标系,所以是顶点顺序是逆时针的面才可以被看的见。

  • 相关阅读:
    has a / is a 的区别
    Linux头文件作用
    转一篇Decorator模式的讲解文章
    歌手推荐kate st. john
    拷贝构造函数和赋值构造函数声明为私有的作用
    重新认识C++中new的用法
    系统程序员成长计划容器与算法(二)(下)
    深入C++的new
    歌手推荐Cara Dillon
    浅析一道C++设计面试题
  • 原文地址:https://www.cnblogs.com/JD85/p/10114822.html
Copyright © 2020-2023  润新知