【问题标题】:Three.js - Checkerboard PlaneThree.js - 棋盘平面
【发布时间】:2014-05-06 13:28:08
【问题描述】:

我正在尝试使用 Three.js 为网页 3D 示例创建一个棋盘。但是,我当前的代码分配了三种颜色,我只需要两种颜色(黑/白)。如何重构数学以生成正确的棋盘格?

// Geometry
var cbgeometry = new THREE.PlaneGeometry( 500, 500, 8, 8 );

// Materials
var cbmaterials = []; 

cbmaterials.push( new THREE.MeshBasicMaterial( { color: 0xffffff, side: THREE.DoubleSide }) );
cbmaterials.push( new THREE.MeshBasicMaterial( { color: 0x000000, side: THREE.DoubleSide }) );
cbmaterials.push( new THREE.MeshBasicMaterial( { color: 0x0000ff, side: THREE.DoubleSide }) );

// Assign a material to each face (each face is 2 triangles)
var l = cbgeometry.faces.length / 2;

for( var i = 0; i < l; i ++ ) {
    var j = 2 * i;
    cbgeometry.faces[ j ].materialIndex = i % 3;
    cbgeometry.faces[ j + 1 ].materialIndex = i % 3;
}

// Mesh
cb = new THREE.Mesh( cbgeometry, new THREE.MeshFaceMaterial( cbmaterials ) );
scene.add( cb );

【问题讨论】:

    标签: javascript three.js geometry plane


    【解决方案1】:

    编辑:

    如果我们的开发环境不同,我会建议这个代码修复:

    EDIT-2:

    索引选择部分的'j'应该是'i',我现在刚刚改了。

    试试这个:

    // Geometry
    var cbgeometry = new THREE.PlaneGeometry( 500, 500, 8, 8 );
    
    // Materials
    var cbmaterials = []; 
    
    cbmaterials.push( new THREE.MeshBasicMaterial( { color: 0xffffff, side: THREE.DoubleSide }) );
    cbmaterials.push( new THREE.MeshBasicMaterial( { color: 0x000000, side: THREE.DoubleSide }) );
    
    var l = cbgeometry.faces.length / 2; // <-- Right here. This should still be 8x8 (64)
    
    console.log("This should be 64: " + l);// Just for debugging puporses, make sure this is 64
    
    for( var i = 0; i < l; i ++ ) {
        j = i * 2; // <-- Added this back so we can do every other 'face'
        cbgeometry.faces[ j ].materialIndex = ((i + Math.floor(i/8)) % 2); // The code here is changed, replacing all 'i's with 'j's. KEEP THE 8
        cbgeometry.faces[ j + 1 ].materialIndex = ((i + Math.floor(i/8)) % 2); // Add this line in, the material index should stay the same, we're just doing the other half of the same face
    }
    
    // Mesh
    cb = new THREE.Mesh( cbgeometry, new THREE.MeshFaceMaterial( cbmaterials ) );
    scene.add( cb );
    

    我评论了我在哪里做了换行。

    我将 Math.floor(i/8) 放在材质索引中以抵消其他所有图层。否则,它将只是垂直线。

    此外,第三种材质已被移除,只剩下白色和黑色可供使用。

    感谢这个问题,解决这个问题很有趣!

    【讨论】:

    • 谢谢!但是,我需要为每个具有两个三角形的面调整代码,因为在我的环境中就是这样(?)。我将i/8 更改为i/128,但不确定最后的更改是什么? Current Render
    • 我编辑了我的答案,请查看它并检查它是否有效!很抱歉造成混乱。
    • 快到了!现在一半黑板一半白:Render我在哪里可以自学以更好地理解数学?
    • 抱歉,我洗了个澡才意识到 ((j + Math.floor(j/8)) % 2) 应该有 'i's 而不是 'j's。说到数学,我是自学的,我不知道有什么好的资源。如果您愿意,我将非常乐意详细解释为什么我会做出我所做的每一项更改。我也很乐意教一些技巧和窍门,以便您对正在发生的事情有更清晰和更深入的了解。
    • 成功!我改变了这两行:((j + Math.floor(j/8)) % 2) ...到这个:((i + Math.floor(i/8)) % 2)
    【解决方案2】:

    THREE.ShaderMaterial() 怎么样?

    顶点着色器可以是类似的东西,

    varying vec2 vUv;
    void main(){
    vUv = uv;
    gl_FragPosition = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
    

    然后你的片段是这样的

    varying vec2 vUv;
    void main(){
    vec2 tileUV = vec2(500.0, 500.0);//say you want to repeat it 500 times in both directions
    vec2 repeatedUV = vUv * tileUV ;
    repeatedUV -=floor(repeatedUV);
    

    现在 repeatUV 有一堆 vec2 在 0-1 范围内的图块,它们重复

    repeatedUV.x = floor(repeatedUV.x * 2.0);//should give black or white stripe in U direction
    repeatedUV.y = floor(repeatedUV.y * 2.0);// same in the other way
    

    那么这类似于布尔代数

    float finalMask = repeatedUV.x + repeatedUV.y;//bottom left 0, bottom right 1, top left 1, top right 2
    finalMask *= 1.0 - repeatedUV.x*repeatedUV.y; //all zero except top right
    gl_FragColor = vec4(vec3(finalMask), 1.0);
    
    }
    

    我猜这样做的方法很昂贵,但可以节省您制作 5000 个三角形的时间。程序生成。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多