为什么我的 "X" 没有通过透明矩形显示?
Why is my "X" not showing through the transparent rectangle?
此代码显示了 2 个矩形,透明矩形后面有 "X"s。最上面的背景是红色的——"X" 显示在前面的矩形中。底部矩形具有默认的透明背景——"X" 没有像我希望的那样通过前面的矩形显示。也许我缺少一个 "alpha.." 参数? TIA.
<!doctype html>
<html>
<head>
<title> threejs texture transparency </title>
<style type="text/css">
canvas { outline:1px dotted black; }
</style>
<script src="http://threejs.org/build/three.js"></script>
<script type="text/javascript">
"use strict";
var renderer, camera, world, geometry, material, mesh;
var js3canvas, js3w, js3h, canvas, ctx, texture;
window.onload = function() {
"use strict";
// the basic 3js
js3canvas = document.getElementById("js3canvas");
renderer = new THREE.WebGLRenderer( { canvas:js3canvas } );
js3w = js3canvas.width;
js3h = js3canvas.height;
camera = new THREE.PerspectiveCamera(50, js3w/js3h, 1, 200);
camera.position.z = 75;
camera.lookAt(0,0,0);
world = new THREE.Scene();
world.background = new THREE.Color(0xaaaaaa);
// a greenish transparent rectangle at z=+1
geometry = new THREE.PlaneGeometry(20, 50);
material = new THREE.MeshBasicMaterial( { color:0x55aa55, transparent:true, opacity:0.5 } );
world.add(new THREE.Mesh(geometry, material));
doRect("top"); // a REDDISH rectangle at z=-1 with a texture of a black "X"
doRect("bot"); // a TRANSPARENT rectangle at z=-1 with a texture of a black "X"
renderer.render( world, camera );
};
function doRect(topbot) { // a rectangle with a texture
// first, the canvas for the texture
if (topbot == "top") canvas = document.getElementById("canvas2"); // top rectangle
else canvas = document.getElementById("canvas3"); // bot rectangle
ctx = canvas.getContext("2d");
if (topbot == "top") { // top only, reddish background
ctx.fillStyle = "#aa5555";
ctx.fillRect(0,0,250,50);
} // bot is left default transparent
ctx.strokeStyle = "#0000000"; // black lines to make "X"
ctx.moveTo(0,0); ctx.lineTo(250,50);
ctx.moveTo(0,50); ctx.lineTo(250,0);
ctx.stroke();
// second, the texture
texture = new THREE.Texture(canvas);
texture.minFilter = THREE.LinearFilter; // eliminates console.log msg
texture.needsUpdate = true; // needed
// third, the rectangle with the texture
geometry = new THREE.PlaneGeometry(50,10);
if (topbot == "top") { // top rectangle with "X" texture, reddish background
geometry.translate(0,10,-1); // move up
material = new THREE.MeshBasicMaterial( { map:texture, transparent:false } );
// If this material is transparent(true) then the "X" doesn't show through.
} else { // bottom rectangle with "X" texture, default(transparent) background
geometry.translate(0,-10,-1); // move down
material = new THREE.MeshBasicMaterial( { map:texture, transparent:true, opacity:1.0 } );
// This material has to be transparent to get a transparent background for the texture.
// But then the "X" doesn't show through.
}
mesh = new THREE.Mesh(geometry, material); // and finally the mesh
world.add(mesh);
}
</script>
</head>
<body>
<canvas id="js3canvas" width="600" height="600"></canvas><br />
<canvas id="canvas2" width="250" height="50"></canvas><br />
<canvas id="canvas3" width="250" height="50"></canvas>
</body>
</html>
编辑 Mugen87:
所有材料加"side:THREE.DoubleSide, ",
在适当的地方添加这两个语句:
mesh.renderOrder = 1;
animate();
并添加此功能:
function animate() {
renderer.render( world, camera );
world.rotation.y += .01;
if (world.rotation.y < 3.1416) requestAnimationFrame(animate);
}
现在底部矩形不是透明的?
我会看看这个。
您看到的是深度排序问题。两个透明对象(绿色平面网格和透明 X)都放置在 3D 中的相同位置 space。因此,它们是根据它们在场景图中的顺序进行渲染的。为了获得正确的结果,您必须确保最后渲染绿色平面。您可以通过定义 Object3D.renderOrder.
来影响渲染器的默认排序
var renderer, camera, world, geometry, material, mesh;
var js3canvas, js3w, js3h, canvas, ctx, texture;
// the basic 3js
js3canvas = document.getElementById("js3canvas");
renderer = new THREE.WebGLRenderer( { canvas:js3canvas } );
js3w = js3canvas.width;
js3h = js3canvas.height;
camera = new THREE.PerspectiveCamera(50, js3w/js3h, 1, 200);
camera.position.z = 75;
camera.lookAt(0,0,0);
world = new THREE.Scene();
world.background = new THREE.Color(0xaaaaaa);
// a greenish transparent rectangle at z=+1
geometry = new THREE.PlaneGeometry(20, 50);
material = new THREE.MeshBasicMaterial( { color:0x55aa55, transparent:true, opacity:0.5 } );
var mesh = new THREE.Mesh(geometry, material);
mesh.renderOrder = 1;
world.add(mesh);
doRect("top"); // a REDDISH rectangle at z=-1 with a texture of a black "X"
doRect("bot"); // a TRANSPARENT rectangle at z=-1 with a texture of a black "X"
renderer.render( world, camera );
function doRect(topbot) { // a rectangle with a texture
// first, the canvas for the texture
if (topbot == "top") canvas = document.getElementById("canvas2"); // top rectangle
else canvas = document.getElementById("canvas3"); // bot rectangle
ctx = canvas.getContext("2d");
if (topbot == "top") { // top only, reddish background
ctx.fillStyle = "#aa5555";
ctx.fillRect(0,0,250,50);
} // bot is left default transparent
ctx.strokeStyle = "#0000000"; // black lines to make "X"
ctx.moveTo(0,0); ctx.lineTo(250,50);
ctx.moveTo(0,50); ctx.lineTo(250,0);
ctx.stroke();
// second, the texture
texture = new THREE.Texture(canvas);
texture.minFilter = THREE.LinearFilter; // eliminates console.log msg
texture.needsUpdate = true; // needed
// third, the rectangle with the texture
geometry = new THREE.PlaneGeometry(50,10);
if (topbot == "top") { // top rectangle with "X" texture, reddish background
geometry.translate(0,10,-1); // move up
material = new THREE.MeshBasicMaterial( { map:texture } );
// If this material is transparent(true) then the "X" doesn't show through.
} else { // bottom rectangle with "X" texture, default(transparent) background
geometry.translate(0,-10,-1); // move down
material = new THREE.MeshBasicMaterial( { map:texture, transparent:true, opacity:1.0 } );
// This material has to be transparent to get a transparent background for the texture.
// But then the "X" doesn't show through.
}
mesh = new THREE.Mesh(geometry, material); // and finally the mesh
world.add(mesh);
}
body {
margin: 0;
}
canvas {
outline: 1px dotted black;
}
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
<canvas id="js3canvas" width="600" height="600"></canvas><br />
<canvas id="canvas2" width="250" height="50"></canvas><br />
<canvas id="canvas3" width="250" height="50"></canvas>
此代码显示了 2 个矩形,透明矩形后面有 "X"s。最上面的背景是红色的——"X" 显示在前面的矩形中。底部矩形具有默认的透明背景——"X" 没有像我希望的那样通过前面的矩形显示。也许我缺少一个 "alpha.." 参数? TIA.
<!doctype html>
<html>
<head>
<title> threejs texture transparency </title>
<style type="text/css">
canvas { outline:1px dotted black; }
</style>
<script src="http://threejs.org/build/three.js"></script>
<script type="text/javascript">
"use strict";
var renderer, camera, world, geometry, material, mesh;
var js3canvas, js3w, js3h, canvas, ctx, texture;
window.onload = function() {
"use strict";
// the basic 3js
js3canvas = document.getElementById("js3canvas");
renderer = new THREE.WebGLRenderer( { canvas:js3canvas } );
js3w = js3canvas.width;
js3h = js3canvas.height;
camera = new THREE.PerspectiveCamera(50, js3w/js3h, 1, 200);
camera.position.z = 75;
camera.lookAt(0,0,0);
world = new THREE.Scene();
world.background = new THREE.Color(0xaaaaaa);
// a greenish transparent rectangle at z=+1
geometry = new THREE.PlaneGeometry(20, 50);
material = new THREE.MeshBasicMaterial( { color:0x55aa55, transparent:true, opacity:0.5 } );
world.add(new THREE.Mesh(geometry, material));
doRect("top"); // a REDDISH rectangle at z=-1 with a texture of a black "X"
doRect("bot"); // a TRANSPARENT rectangle at z=-1 with a texture of a black "X"
renderer.render( world, camera );
};
function doRect(topbot) { // a rectangle with a texture
// first, the canvas for the texture
if (topbot == "top") canvas = document.getElementById("canvas2"); // top rectangle
else canvas = document.getElementById("canvas3"); // bot rectangle
ctx = canvas.getContext("2d");
if (topbot == "top") { // top only, reddish background
ctx.fillStyle = "#aa5555";
ctx.fillRect(0,0,250,50);
} // bot is left default transparent
ctx.strokeStyle = "#0000000"; // black lines to make "X"
ctx.moveTo(0,0); ctx.lineTo(250,50);
ctx.moveTo(0,50); ctx.lineTo(250,0);
ctx.stroke();
// second, the texture
texture = new THREE.Texture(canvas);
texture.minFilter = THREE.LinearFilter; // eliminates console.log msg
texture.needsUpdate = true; // needed
// third, the rectangle with the texture
geometry = new THREE.PlaneGeometry(50,10);
if (topbot == "top") { // top rectangle with "X" texture, reddish background
geometry.translate(0,10,-1); // move up
material = new THREE.MeshBasicMaterial( { map:texture, transparent:false } );
// If this material is transparent(true) then the "X" doesn't show through.
} else { // bottom rectangle with "X" texture, default(transparent) background
geometry.translate(0,-10,-1); // move down
material = new THREE.MeshBasicMaterial( { map:texture, transparent:true, opacity:1.0 } );
// This material has to be transparent to get a transparent background for the texture.
// But then the "X" doesn't show through.
}
mesh = new THREE.Mesh(geometry, material); // and finally the mesh
world.add(mesh);
}
</script>
</head>
<body>
<canvas id="js3canvas" width="600" height="600"></canvas><br />
<canvas id="canvas2" width="250" height="50"></canvas><br />
<canvas id="canvas3" width="250" height="50"></canvas>
</body>
</html>
编辑 Mugen87:
所有材料加"side:THREE.DoubleSide, ",
在适当的地方添加这两个语句:
mesh.renderOrder = 1;
animate();
并添加此功能:
function animate() {
renderer.render( world, camera );
world.rotation.y += .01;
if (world.rotation.y < 3.1416) requestAnimationFrame(animate);
}
现在底部矩形不是透明的? 我会看看这个。
您看到的是深度排序问题。两个透明对象(绿色平面网格和透明 X)都放置在 3D 中的相同位置 space。因此,它们是根据它们在场景图中的顺序进行渲染的。为了获得正确的结果,您必须确保最后渲染绿色平面。您可以通过定义 Object3D.renderOrder.
来影响渲染器的默认排序var renderer, camera, world, geometry, material, mesh;
var js3canvas, js3w, js3h, canvas, ctx, texture;
// the basic 3js
js3canvas = document.getElementById("js3canvas");
renderer = new THREE.WebGLRenderer( { canvas:js3canvas } );
js3w = js3canvas.width;
js3h = js3canvas.height;
camera = new THREE.PerspectiveCamera(50, js3w/js3h, 1, 200);
camera.position.z = 75;
camera.lookAt(0,0,0);
world = new THREE.Scene();
world.background = new THREE.Color(0xaaaaaa);
// a greenish transparent rectangle at z=+1
geometry = new THREE.PlaneGeometry(20, 50);
material = new THREE.MeshBasicMaterial( { color:0x55aa55, transparent:true, opacity:0.5 } );
var mesh = new THREE.Mesh(geometry, material);
mesh.renderOrder = 1;
world.add(mesh);
doRect("top"); // a REDDISH rectangle at z=-1 with a texture of a black "X"
doRect("bot"); // a TRANSPARENT rectangle at z=-1 with a texture of a black "X"
renderer.render( world, camera );
function doRect(topbot) { // a rectangle with a texture
// first, the canvas for the texture
if (topbot == "top") canvas = document.getElementById("canvas2"); // top rectangle
else canvas = document.getElementById("canvas3"); // bot rectangle
ctx = canvas.getContext("2d");
if (topbot == "top") { // top only, reddish background
ctx.fillStyle = "#aa5555";
ctx.fillRect(0,0,250,50);
} // bot is left default transparent
ctx.strokeStyle = "#0000000"; // black lines to make "X"
ctx.moveTo(0,0); ctx.lineTo(250,50);
ctx.moveTo(0,50); ctx.lineTo(250,0);
ctx.stroke();
// second, the texture
texture = new THREE.Texture(canvas);
texture.minFilter = THREE.LinearFilter; // eliminates console.log msg
texture.needsUpdate = true; // needed
// third, the rectangle with the texture
geometry = new THREE.PlaneGeometry(50,10);
if (topbot == "top") { // top rectangle with "X" texture, reddish background
geometry.translate(0,10,-1); // move up
material = new THREE.MeshBasicMaterial( { map:texture } );
// If this material is transparent(true) then the "X" doesn't show through.
} else { // bottom rectangle with "X" texture, default(transparent) background
geometry.translate(0,-10,-1); // move down
material = new THREE.MeshBasicMaterial( { map:texture, transparent:true, opacity:1.0 } );
// This material has to be transparent to get a transparent background for the texture.
// But then the "X" doesn't show through.
}
mesh = new THREE.Mesh(geometry, material); // and finally the mesh
world.add(mesh);
}
body {
margin: 0;
}
canvas {
outline: 1px dotted black;
}
<script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
<canvas id="js3canvas" width="600" height="600"></canvas><br />
<canvas id="canvas2" width="250" height="50"></canvas><br />
<canvas id="canvas3" width="250" height="50"></canvas>