我正在尝试将phong材质添加到我的.obj模型以及着色器区域灯,但是我尝试使用使用数组的Meshface材质来加载两种材质但是当我这样做时模型完全消失。
当我使用其中任何一个但不能同时使用时,情况有效,无论如何都要克服这个问题吗?
以下是DEMO:
CODE:
// area light
var lightColor = 0xffffff;
var lightIntensity = 1;
var geometry = new THREE.PlaneGeometry(100, 50);
var material = new THREE.MeshBasicMaterial({
color: lightColor,
transparent: true,
opacity: 0.7,
side: THREE.FrontSide
});
areaLight = new THREE.Mesh(geometry, material);
areaLight.position.set(0, 25, -25);
areaLight.rotation.set(0, 0, 0);
areaLight.scale.set(1, 1, 1);
scene.add(areaLight);
var Black = new THREE.MeshPhongMaterial({
color: 0x000000,
})
// wireframe hack
areaLight.add(new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
wireframe: true
})));
// areaLight verts
var vertices = areaLight.geometry.vertices;
var verts = [];
verts.push(vertices[0]);
verts.push(vertices[1]);
verts.push(vertices[3]);
verts.push(vertices[2]);
// uniforms
var uniforms = {
color: {
type: "c",
value: new THREE.Color(0xaaaadd)
},
lightColor: {
type: "c",
value: areaLight.material.color
},
lightIntensity: {
type: "f",
value: lightIntensity
},
lightverts: {
type: "v3v",
value: verts
},
lightMatrixWorld: {
type: "m4",
value: areaLight.matrixWorld
}
};
// attributes
var attributes = {};
// material
var material = new THREE.ShaderMaterial({
attributes: attributes,
uniforms: uniforms,
vertexShader: document.getElementById('vertex_shader').textContent,
fragmentShader: document.getElementById('fragment_shader').textContent,
shading: THREE.SmoothShading
});
var onError = function(xhr) {};
THREE.Loader.Handlers.add(/\.dds$/i, new THREE.DDSLoader());
var mtl1Loader = new THREE.MTLLoader();
mtl1Loader.setBaseUrl('neavik/newmail/');
mtl1Loader.setPath('neavik/newmail/');
mtl1Loader.load('chandelier.mtl', function(materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('neavik/newmail/');
objLoader.load('chandelier.obj', function(object4) {
object4.castShadow = true;
object4.receiveShadow = true;
object4.updateMatrix();
object4.position.set(40, 28, 40); //(0,-5,0.5);
object4.scale.x = 0.09;
object4.scale.y = 0.05;
object4.scale.z = 0.09
var mats = [];
mats.push(new THREE.MeshPhongMaterial({
color: 0x000000
}));
mats.push(material);
var faceMaterial = new THREE.MeshFaceMaterial(mats);
object4.traverse(function(child) {
if (child instanceof THREE.Mesh) {
if (child.material.name == "chandelier_Outside") {
child.material = Black; // When i use faceMaterial here the object disappears
child.castShadow = true;
child.receiveShadow = true;
}
}
});
scene.add(object4);
});
})
// plane geometry
var geometry = new THREE.PlaneGeometry(200, 200);
geometry.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
// plane
mesh = new THREE.Mesh(geometry, material);
mesh.position.y = -0.1;
scene.add(mesh);
// torus knot
var geometry = new THREE.TorusKnotGeometry(10, 4, 256, 32, 1, 3, 1);
// mesh
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 28, 0);
scene.add(mesh);
}
主要问题部分
var mats = [];
mats.push(new THREE.MeshPhongMaterial({
color: 0x000000
}));
mats.push(material);
var faceMaterial = new THREE.MeshFaceMaterial(mats);
object4.traverse(function(child) {
if (child instanceof THREE.Mesh) {
if (child.material.name == "chandelier_Outside") {
child.material = Black; // When i use faceMaterial here the object disappears
child.castShadow = true;
child.receiveShadow = true;
}
}
});
scene.add(object4);
});
})
区域光线参考:http://jsfiddle.net/hh74z2ft/1/
预期的结果与此图像类似,即使是枝形吊灯也应该像torusknot一样照亮phongness [此图片中没有phongness] [] 2
答案 0 :(得分:0)
不幸的是,如果我理解正确,这将无效。
材料(以及其他内容)定义如何将三角形的给定片段着色。对于任何给定的三角形,总是只能有一种材料。面材用于处理您想要使用不同材质渲染不同面的情况,但每个三角形仍然只有一种材质。
在three.js中有一个名为multiMaterial的概念(看看THREE.SceneUtils.createMultiMaterialObject()
)。但这只会创建具有相同几何和不同材质的多个网格,因此每个三角形都会渲染两次,每种材质都会渲染一次。
现在的问题是,AreaLight实现有它自己如何表示光的概念(通过着色器制服),这与phong材料的工作方式完全不同。因此,即使你以某种方式在物体上添加了一种物质以获得镜面反射,但物质也不知道如何处理区域光源(它甚至不知道场景中有任何光线。)
为了获得您喜欢的行为,您需要将一个镜面术语(表面镜面反射的计算公式)添加到片段着色器中,并且可能需要一些制服来控制它的行为。这是一个非常复杂的事情,特别是对于区域灯(如果它很容易,我们已经在three.js中有它。)
但是,根据该领域的最新研究,有一些工作要做,您可能需要查看this issue和demo here。此here还有一个拉取请求。