Three.js 渲染普通几何体的白色部分
Three.js render white part of plain geometry
我正在尝试转动 this plainGeometry
, into this(某种面具)。
此代码有效:(总而言之,创建两个 material,将平面划分为多个段,并为每个段决定哪个 material 与 MeshFaceMaterial
)
Button.onClick(function () {
var obj = editor.selected;
var material = obj.material;
var tex = material.map;
var objHeight = obj.geometry.parameters.height;
var objWidth = obj.geometry.parameters.width;
var texHeight = tex.image.height;
var texWidth = tex.image.width;
var geometry = new THREE.PlaneGeometry(objWidth, objHeight, objWidth, objHeight);
var facesNum = objHeight * objWidth * 2;
var facesX = objWidth * 2;
var facesInX = texWidth * 2;
var materials = [];
materials.push(material);
materials.push(new THREE.MeshBasicMaterial({ }));
for (var i = 0; i < facesNum; i++) {
if ((i % facesX >= objWidth - texWidth) &&
(i % facesX <= (facesInX + objWidth - texWidth - 1)) &&
(i <= (texHeight * objWidth * 2) - 1)) {
geometry.faces[i].materialIndex = 0;
}
else {
geometry.faces[i].materialIndex = 1;
}
}
obj.geometry = geometry;
obj.material = new THREE.MeshFaceMaterial(materials);
editor.signals.materialChanged.dispatch(obj);
});
但我想知道是否有更简单的方法。有什么建议吗?
另一种方法是在纹理上使用 alpha 通道。您可以使用 Gimp 或 Photoshop 执行此操作。
然后您复制网格并将其推到 material 上带有 polygonOffsetFactor 的轴上一点点。将背景 material 应用到第一个网格,将带 alpha 纹理的前景 material 应用到第二个。
看到这个 fiddle alphaTest。 (你 可能 需要禁用跨域访问安全性以便纹理可以加载到此 fiddle,如果你 运行 chrome 将允许这样做使用 --disable-web-security 标志)
这种方法的优点是图像可以是任何形状和位置,并且不需要适合几何体面。
另一种方法,如果您使用的几何形状很复杂,则使用 Three.DecalGeometry 切出一个网格块,然后使用 material 上的 polygonOffsetFactor 稍微移动一下。请参阅 three.js decals example。
示例 fiddle 的来源如下:
var renderer;
var pointLight;
var scene;
var plane1;
var plane2;
function addPlane()
{
var material1 = new THREE.MeshPhongMaterial({ color: 0xFFFFFF });
var material2;
var loader = new THREE.TextureLoader();
loader.load('http://i.imgur.com/ETdl4De.png',
function ( texture ) {
var material2 = new THREE.MeshPhongMaterial({
color: 0xFFFFFF,
map: texture,
alphaTest: 0.7,
polygonOffset: true,
polygonOffsetFactor: - 4,
});
var geometry1 = new THREE.PlaneGeometry(12, 12, 12, 12);
var geometry2 = geometry1.clone();
plane1 = new THREE.Mesh(geometry1,material1);
plane2 = new THREE.Mesh(geometry2,material2);
scene.add(plane2);
scene.add(plane1);
}
);
}
(function() {
'use strict';
scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 10000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
addPlane();
camera.position.z = 52;
pointLight = new THREE.DirectionalLight(0xffffff,1);
pointLight.position.x = 11;
pointLight.position.y = 5;
pointLight.position.z = 25;
scene.add(pointLight);
var reqAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
var render = function() {
reqAnimFrame(render);
renderer.render(scene, camera);
};
render();
}());
最终做到了:
var obj = editor.selected;
var tex = obj.material.map.;
var materials = [];
materials.push(new THREE.MeshBasicMaterial({ map: tex }));
materials.push(new THREE.MeshBasicMaterial({}));
var material = new THREE.MeshFaceMaterial(materials);
var objHeight = obj.geometry.parameters.height;
var objWidth = obj.geometry.parameters.width;
var texHeight = tex.image.height;
var texWidth = tex.image.width;
tex.repeat = new THREE.Vector2(3, 3);
tex.offset = new THREE.Vector2(0, 0);
var geometry = new THREE.PlaneGeometry(objWidth, objHeight, 3, 3);
var v = geometry.vertices;
var facesNum = geometry.faces.length;
v[1] = new THREE.Vector3(-texWidth / 2, objHeight / 2, 0);
v[2] = new THREE.Vector3(texWidth / 2, objHeight / 2, 0);
v[5] = new THREE.Vector3(-texWidth / 2, (objHeight / 2) - texHeight, 0);
v[6] = new THREE.Vector3(texWidth / 2, (objHeight / 2) - texHeight, 0);
v[9] = v[13];
v[10] = v[14];
v[4] = v[8] = v[12];
v[7] = v[11] = v[15];
for (var i = 0; i < facesNum; i++) {
if (i !== 2 && i !== 3) geometry.faces[i].materialIndex = 1;
}
obj.material = material;
obj.geometry = geometry;
editor.signals.materialChanged.dispatch(obj);
我正在尝试转动 this plainGeometry
, into this(某种面具)。
此代码有效:(总而言之,创建两个 material,将平面划分为多个段,并为每个段决定哪个 material 与 MeshFaceMaterial
)
Button.onClick(function () {
var obj = editor.selected;
var material = obj.material;
var tex = material.map;
var objHeight = obj.geometry.parameters.height;
var objWidth = obj.geometry.parameters.width;
var texHeight = tex.image.height;
var texWidth = tex.image.width;
var geometry = new THREE.PlaneGeometry(objWidth, objHeight, objWidth, objHeight);
var facesNum = objHeight * objWidth * 2;
var facesX = objWidth * 2;
var facesInX = texWidth * 2;
var materials = [];
materials.push(material);
materials.push(new THREE.MeshBasicMaterial({ }));
for (var i = 0; i < facesNum; i++) {
if ((i % facesX >= objWidth - texWidth) &&
(i % facesX <= (facesInX + objWidth - texWidth - 1)) &&
(i <= (texHeight * objWidth * 2) - 1)) {
geometry.faces[i].materialIndex = 0;
}
else {
geometry.faces[i].materialIndex = 1;
}
}
obj.geometry = geometry;
obj.material = new THREE.MeshFaceMaterial(materials);
editor.signals.materialChanged.dispatch(obj);
});
但我想知道是否有更简单的方法。有什么建议吗?
另一种方法是在纹理上使用 alpha 通道。您可以使用 Gimp 或 Photoshop 执行此操作。
然后您复制网格并将其推到 material 上带有 polygonOffsetFactor 的轴上一点点。将背景 material 应用到第一个网格,将带 alpha 纹理的前景 material 应用到第二个。 看到这个 fiddle alphaTest。 (你 可能 需要禁用跨域访问安全性以便纹理可以加载到此 fiddle,如果你 运行 chrome 将允许这样做使用 --disable-web-security 标志) 这种方法的优点是图像可以是任何形状和位置,并且不需要适合几何体面。
另一种方法,如果您使用的几何形状很复杂,则使用 Three.DecalGeometry 切出一个网格块,然后使用 material 上的 polygonOffsetFactor 稍微移动一下。请参阅 three.js decals example。
示例 fiddle 的来源如下:
var renderer;
var pointLight;
var scene;
var plane1;
var plane2;
function addPlane()
{
var material1 = new THREE.MeshPhongMaterial({ color: 0xFFFFFF });
var material2;
var loader = new THREE.TextureLoader();
loader.load('http://i.imgur.com/ETdl4De.png',
function ( texture ) {
var material2 = new THREE.MeshPhongMaterial({
color: 0xFFFFFF,
map: texture,
alphaTest: 0.7,
polygonOffset: true,
polygonOffsetFactor: - 4,
});
var geometry1 = new THREE.PlaneGeometry(12, 12, 12, 12);
var geometry2 = geometry1.clone();
plane1 = new THREE.Mesh(geometry1,material1);
plane2 = new THREE.Mesh(geometry2,material2);
scene.add(plane2);
scene.add(plane1);
}
);
}
(function() {
'use strict';
scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 10000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
addPlane();
camera.position.z = 52;
pointLight = new THREE.DirectionalLight(0xffffff,1);
pointLight.position.x = 11;
pointLight.position.y = 5;
pointLight.position.z = 25;
scene.add(pointLight);
var reqAnimFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
var render = function() {
reqAnimFrame(render);
renderer.render(scene, camera);
};
render();
}());
最终做到了:
var obj = editor.selected;
var tex = obj.material.map.;
var materials = [];
materials.push(new THREE.MeshBasicMaterial({ map: tex }));
materials.push(new THREE.MeshBasicMaterial({}));
var material = new THREE.MeshFaceMaterial(materials);
var objHeight = obj.geometry.parameters.height;
var objWidth = obj.geometry.parameters.width;
var texHeight = tex.image.height;
var texWidth = tex.image.width;
tex.repeat = new THREE.Vector2(3, 3);
tex.offset = new THREE.Vector2(0, 0);
var geometry = new THREE.PlaneGeometry(objWidth, objHeight, 3, 3);
var v = geometry.vertices;
var facesNum = geometry.faces.length;
v[1] = new THREE.Vector3(-texWidth / 2, objHeight / 2, 0);
v[2] = new THREE.Vector3(texWidth / 2, objHeight / 2, 0);
v[5] = new THREE.Vector3(-texWidth / 2, (objHeight / 2) - texHeight, 0);
v[6] = new THREE.Vector3(texWidth / 2, (objHeight / 2) - texHeight, 0);
v[9] = v[13];
v[10] = v[14];
v[4] = v[8] = v[12];
v[7] = v[11] = v[15];
for (var i = 0; i < facesNum; i++) {
if (i !== 2 && i !== 3) geometry.faces[i].materialIndex = 1;
}
obj.material = material;
obj.geometry = geometry;
editor.signals.materialChanged.dispatch(obj);