21

メッシュの片面の色を変更しようとしています。これはWebGLコンテキストにあります。単一の面だけでなく、メッシュ全体の色を変更できます。以下の関連コード:

// Updated Per Lee!

var camera = _this.camera;      
var projector = new THREE.Projector();
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1,                                  - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );

var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( kage.scene.children );

if ( intersects.length > 0 ) {
    face = intersects[0].face;
    var faceIndices = ['a', 'b', 'c', 'd'];         
    var numberOfSides = ( face instanceof THREE.Face3 ) ? 3 : 4;
    // assign color to each vertex of current face
    for( var j = 0; j < numberOfSides; j++ )  {
        var vertexIndex = face[ faceIndices[ j ] ];
    // initialize color variable
    var color = new THREE.Color( 0xffffff );
    color.setRGB( Math.random(), 0, 0 );
    face.vertexColors[ j ] = color;
    }
}

また、オブジェクト、この場合は次のようにCubeを初期化します。

// this material causes a mesh to use colors assigned to vertices
var material = new THREE.MeshBasicMaterial( { 
    color: 0xf0f0f0, 
    shading: THREE.FlatShading,
    vertexColors: THREE.VertexColors 
});

var directionalLight = new THREE.DirectionalLight(0xEEEEEE);
directionalLight.position.set(10, 1, 1).normalize();
kage.scene.add(directionalLight);

var cube = new THREE.Mesh(new THREE.CubeGeometry(300, 300, 300,1,1,1), material);
cube.dynamic = true;
kage.scene.add(cube);

マテリアルを変更すると、明るい色に関係なくキューブが白になります。交差ロジックは引き続き機能します。つまり、正しい面を選択しますが、残念ながら色は変わりません。

私はStackoverflowを初めて使用します[よく質問しているので、私の編集が混乱しないことを願っています]

4

5 に答える 5

26
  • ライブラリをr53に更新します。
  • 材料を追加vertexColors: THREE.FaceColorsします。
  • そして最後にを使用しますface.color.setRGB( Math.random(), Math.random(), Math.random())

    THREE.Face4これで、の場合は4辺(a、b、c、d)、またはの場合は3辺(a、b、c)の ループをトラバースする必要はありませんTHREE.Face3

    これは、WebGLレンダリングとCanvasレンダリングの両方で機能します。

three.js r53

于 2012-12-24T08:08:22.633 に答える
7

「myGeometry」が色を変更したい顔を含むジオメトリであり、「faceIndex」が色を変更したい特定の顔のインデックスであると仮定します。

// the face's indices are labeled with these characters 
var faceIndices = ['a', 'b', 'c', 'd'];  

var face = myGeometry.faces[ faceIndex ];   

// determine if face is a tri or a quad
var numberOfSides = ( face instanceof THREE.Face3 ) ? 3 : 4;

// assign color to each vertex of current face
for( var j = 0; j < numberOfSides; j++ )  
{
    var vertexIndex = face[ faceIndices[ j ] ];
    // initialize color variable
    var color = new THREE.Color( 0xffffff );
    color.setRGB( Math.random(), 0, 0 );
    face.vertexColors[ j ] = color;
}

次に、メッシュは次のマテリアルを使用して、面の色が頂点から派生するようにする必要があります。

// this material causes a mesh to use colors assigned to vertices
var cubeMaterial = new THREE.MeshBasicMaterial( 
    { color: 0xffffff, shading: THREE.FlatShading, 
    vertexColors: THREE.VertexColors } );
于 2012-06-29T15:16:07.570 に答える
5

私はthree.jsにかなり慣れていませんが、これらの例のほとんどは長すぎて複雑に見えます。次のコードは、立方体の12個の三角形の面すべてに色を付けているようです...(WebGLRenderer r73)。

これを行うときに私が気づいたことの1つは、顔の順序が少し奇妙であるということです(少なくとも初心者としての私にとって)。

var geometry = new THREE.BoxGeometry( 1, 1, 1 );
console.log(geometry.faces.length); // 12 triangles
geometry.faces[0].color = new THREE.Color(0x000000); //Right 1
geometry.faces[1].color = new THREE.Color(0xFF0000); //Right 2
geometry.faces[2].color = new THREE.Color(0xFF8C08); //Left 1
geometry.faces[3].color = new THREE.Color(0xFFF702); //Left 2
geometry.faces[4].color = new THREE.Color(0x00FF00); //Top 1
geometry.faces[5].color = new THREE.Color(0x0000FF); //Top 2
geometry.faces[6].color = new THREE.Color(0x6F00FF); //Bottom 1
geometry.faces[7].color = new THREE.Color(0x530070); //Bottom 2
geometry.faces[8].color = new THREE.Color(0x3F3F3F); //Front 1
geometry.faces[9].color = new THREE.Color(0x6C6C6C); //Front 2
geometry.faces[10].color = new THREE.Color(0xA7A7A7);//Rear 1
geometry.faces[11].color = new THREE.Color(0xFFFFFF);//Rear 2
于 2016-02-27T17:06:03.983 に答える
3

Three JS Geometry Documentによると、この面で更新を通知するには、Geometry.elementsNeedUpdatetrueに設定する必要があります。

次のスニペットは、すべての面の色を変更します。

mesh.material.vertexColors = THREE.FaceColors

var faces = mesh.geometry.faces;

for(var i = 0 ; i < faces.length; i++){
  var face = faces[i];
  var color = new THREE.Color("rgb(255, 0, 0)");
  face.color = color;
}

mesh.geometry.elementsNeedUpdate = true;

render();
于 2017-06-26T19:13:45.393 に答える
1

上記の方法は、でのみ機能すると思いますWebGLRendererCanvasRendererとの両方で機能するものを探している場合、WebGLRendererそれはもう少し複雑ですが、最終的な結果はメモリ使用量とパフォーマンスの両方の点でより効率的だと思います。

THREE.jS Projector.jsソースを調べた後、これが私が行った方法です。

// create the face materials
var material_1 = new THREE.MeshLambertMaterial(
    {color : 0xff0000, shading: THREE.FlatShading, overdraw : true}
);
var material_2 = new THREE.MeshLambertMaterial(
    {color : 0x00ff00, shading: THREE.FlatShading, overdraw : true}
);

// create a geometry (any should do)
var geom = new THREE.CubeGeometry(1,1,1);

// add the materials directly to the geometry
geom.materials.push(material_1);
geom.materials.push(material_2);

// assign the material to individual faces (note you assign the index in 
// the geometry, not the material)
for( var i in geom.faces ) {
    var face = geom.faces[i];
    face.materialIndex = i%geom.materials.length;
}

// create a special material for your mesh that tells the renderer to use the 
// face materials
var material = new THREE.MeshFaceMaterial();
var mesh = new THREE.Mesh(geom, material);

この例は、私が持っている作業コードを応用したものですが、この正確なコードブロックを実際に実行したわけではなく、すべてを最初に正しく実行したという優れた実績がないことを認める必要がありますが、誰かに役立つことを願っています苦労している人

于 2012-09-23T01:27:34.583 に答える