2012-06-28 82 views
14

Tôi đang cố thay đổi màu trên một mặt của lưới. Đây là ngữ cảnh WebGL. Tôi có thể thay đổi toàn bộ màu lưới, không chỉ là một khuôn mặt. mã có liên quan dưới đây:Cách thay đổi màu mặt trong Three.js

// 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; 
    } 
} 

Tôi cũng khởi tạo đối tượng, trong trường hợp này một Cube như sau:

// 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); 

Thay đổi vật liệu làm cho các khối lập phương trắng không phụ thuộc vào màu sắc ánh sáng. Logic giao lộ vẫn hoạt động, nghĩa là tôi chọn đúng khuôn mặt, nhưng màu sắc không thay đổi.

Tôi mới đến Stackoverflow [cũng hỏi một câu hỏi có nghĩa là, vì vậy hy vọng sửa của tôi không phải là khó hiểu]

Trả lời

21
  • Cập nhật thư viện thành r53.
  • Thêm vertexColors: THREE.FaceColors trong tài liệu.
  • Và cuối cùng sử dụng face.color.setRGB(Math.random(), Math.random(), Math.random()).

    Bây giờ không cần phải đi qua vòng lặp cho 4 bên (a, b, c, d) cho THREE.Face4 hoặc 3 bên (a, b, c) cho THREE.Face3.

    Điều này hoạt động trong cả WebGL và Canvas rendering.

Example

three.js r53

+0

Làm việc trong r65. –

+6

Điều này đã cho tôi gần gũi, nhưng cần thiết để thêm 'geometry.colorsNeedUpdate = true' – twmulloy

6

Giả sử rằng "myGeometry" là hình học chứa khuôn mặt mà bạn muốn thay đổi màu sắc của và "faceIndex" là chỉ mục của khuôn mặt cụ thể mà bạn muốn thay đổi màu của.

// 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; 
} 

Sau đó, lưới nhu cầu sử dụng các vật liệu sau đây để màu sắc khuôn mặt có nguồn gốc từ các đỉnh:

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

Cảm ơn Lee, tôi cập nhật đoạn mã của tôi mỗi phản hồi của bạn. Alas khuôn mặt không thay đổi màu sắc. Tôi nghĩ rằng tôi có thể thiết lập những thứ không chính xác bên ngoài logic giao lộ của tôi mà ngăn cản sự thay đổi màu sắc dính vào. – adamsch1

1

Tôi nghĩ rằng phương pháp liệt kê ở trên chỉ hoạt động trong các WebGLRenderer. Nếu bạn đang đi cho một cái gì đó mà làm việc trong cả hai CanvasRendererWebGLRenderer nó là một chút phức tạp hơn, nhưng tôi nghi ngờ kết quả cuối cùng là hiệu quả hơn cả về mặt sử dụng bộ nhớ và hiệu suất.

Sau khi đi qua các nguồn Three.js Projector.js, đây là cách tôi đã làm nó:

// 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); 

Ví dụ này được chuyển thể từ đoạn code làm việc tôi có, nhưng tôi phải thừa nhận tôi không có thực sự chạy khối mã chính xác này và tôi không có hồ sơ theo dõi tuyệt vời để nhận mọi thứ ngay trước tiên, nhưng hy vọng nó sẽ giúp bất kỳ ai đang gặp khó khăn

1

Tôi khá mới mẻ để three.js, nhưng hầu hết các ví dụ này dường như quá dài và phức tạp. Đoạn mã sau dường như tô màu tất cả 12 mặt hình tam giác cho một khối lập phương ... (WebGLRenderer r73).

Một điều tôi lưu ý khi làm điều này là thứ tự của các khuôn mặt là một chút lạ (với tôi như là một người mới ít nhất).

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 
+7

Không cần phải nhanh chóng tạo ra một màu mới. Sử dụng 'color.setHex (0xff0000)'; – WestLangley

+0

Cool thx for the hint :) Tôi đã làm điều đó dựa trên một ví dụ tôi đã thấy. – Gus

2

Theo Three JS Geometry Document Để báo hiệu một bản cập nhật trong này đang phải đối mặt, Geometry.elementsNeedUpdate cần phải được thiết lập là true.

Đoạn mã sau thay đổi màu của tất cả các khuôn mặt.

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(); 
+3

KHÔNG khởi tạo một 'THREE.Color' mới nếu các màu mặt đã tồn tại. Thay vào đó làm 'faces [i] .color.setRGB (1, 0, 0);' và sau đó 'mesh.geometry.colorsNeedUpdate = true;'. Đọc lại tài liệu được tham chiếu. – WestLangley

Các vấn đề liên quan