Как изменить цвет лица в Three.js
Я пытаюсь изменить цвет на одной грани сетки. Это в контексте 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;
}
}
Я также инициализирую объект, в данном случае куб следующим образом:
// 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 [ну, задавая вопрос, который, надеюсь, мои изменения не путают]
Ответы
Ответ 1
- Обновить библиотеку до r53.
- Добавить
vertexColors: THREE.FaceColors
в
материал.
-
И, наконец, используйте face.color.setRGB( Math.random(),
Math.random(), Math.random())
.
Теперь нет необходимости проходить цикл для 4
стороны (a, b, c, d) для THREE.Face4
или трех сторон (a, b, c) для
THREE.Face3
.
Это работает как в рендеринге WebGL, так и в Canvas.
Пример
three.js r53
Ответ 2
Предполагая, что "myGeometry" - это геометрия, содержащая лицо, которое вы хотели бы изменить цвет, а "faceIndex" - это индекс конкретного лица, которое вы хотите изменить цвет.
// the face 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 } );
Ответ 3
В соответствии с Three JS Geometry Документ, Чтобы сигнализировать об обновлении на этих лицах, Geometry.elementsNeedUpdate
требуется установите значение true.
Следующий фрагмент изменяет цвета всех лиц.
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();
Ответ 4
Я думаю, что метод, указанный выше, работает только в WebGLRenderer
. Если вы собираетесь что-то, что работает как в CanvasRenderer
, так и в 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);
Этот пример адаптирован из рабочего кода, который у меня есть, но я должен признать, что на самом деле я не запустил этот точный блок кода, и у меня нет большого опыта в том, чтобы сначала все было правильно, но, надеюсь, это поможет любому, кто борется
Ответ 5
Я новичок в three.js, но большинство из этих примеров кажутся слишком длинными и сложными. Следующий код, кажется, окрашивает все 12 треугольных граней для куба... (WebGLRenderer r73).
Одна вещь, которую я заметил при этом, заключается в том, что порядок лиц немного странный (по крайней мере, для меня как новичок).
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