Three.js-使用贴花将文本添加到平面

时间:2019-01-13 19:24:45

标签: three.js

https://github.com/spite/THREE.DecalGeometry之后, 我试图将文本放置在位于(0,10,0)的简单20X20平面上,如下所示。但是,贴图是在平面下方渲染的:

decal below plane

我简化了吗?

var geometry = new THREE.PlaneGeometry(20, 20);
var material = new THREE.MeshBasicMaterial({color: 0x4a5f70, opacity: 0.8, transparent: true});
var face = new THREE.Mesh(geometry, material);
face.position.setX(0);
face.position.setY(0);
face.position.setZ(10);

var decalGeometry = new THREE.DecalGeometry(
    face, 
    new THREE.Vector3(0,0,10),
    new THREE.Vector3(0,0,1), //z axis
    new THREE.Vector3(20,20,20), 
    new THREE.Vector3(0,0,0)
);

var decalMaterial = new THREE.MeshPhongMaterial({
  color: 0xAAAAAA,
  map: THREE.ImageUtils.loadTexture('/img/images/top.png'),
  side: THREE.FrontSide,
  opacity: 1.0,
  transparent: true,
  depthTest: true,
  depthWrite: false,
  polygonOffset: true,
  polygonOffsetFactor: -4,
});

var mesh = new THREE.Mesh( decalGeometry, decalMaterial );

this.scene.add(face);
this.scene.add(mesh);

1 个答案:

答案 0 :(得分:0)

我认为代码实际上按预期工作,贴花网格不与原始网格重叠,而是制作了新网格。实际上,我尝试将飞机更改为球体,并相应地投影了“ top.png”纹理。

decalGeometry中的参数定义投影网格的位置,但不定义生成的网格(位于(0,0,0)上)的位置。最终结果是您最终渲染了两个网格:原始的一个网格被置换,结果的一个网格(贴花投影)的中心为(0,0,0)。

enter image description here

如果找不到“ top.png”图像,则以下代码不起作用,但是您可以在本地尝试。

var camera, scene, renderer;
var geometry, material, mesh;
var grid;

init();
animate();

function init() {

  // Scene Setup
	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setSize( window.innerWidth*0.993, window.innerHeight*0.993 );
	document.body.appendChild( renderer.domElement );

	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 110 );
  camera.position.set( 50, 50, 0 );

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xcccccc);
  //Cube
	geometry = new THREE.BoxGeometry( 1e-3, 1e-3, 1e-3 );
	material = new THREE.MeshNormalMaterial();
	cube = new THREE.Mesh( geometry, material );
	scene.add( cube );

  //Camera Pivot
  camera.lookAt( cube.position );
  cube.add( camera );

  // Grid
  grid = new THREE.GridHelper( 100, 10 ) 
  scene.add(grid);

  // Geometry
  //var geometry = new THREE.PlaneGeometry(50, 50);
  var geometry = new THREE.SphereGeometry(10,32,32)
  var material = new THREE.MeshBasicMaterial({color: 0x4a5f70, opacity: 0.8, transparent: true, side:THREE.DoubleSide});
  var face = new THREE.Mesh(geometry, material);
  face.position.setX(0);
  face.position.setY(0);
  face.position.setZ(30);

  var decalGeometry = new THREE.DecalGeometry(
      face, 
      new THREE.Vector3(0,0,0),
      new THREE.Vector3(0,1,0), //z axis
      new THREE.Vector3(20,20,20), 
      new THREE.Vector3(0,0,0)
  );

  var decalMaterial = new THREE.MeshPhongMaterial({
    color: 0xAAAAAA,
    map: THREE.ImageUtils.loadTexture('top.png'),
    side: THREE.FrontSide,
    opacity: 1.0,
    transparent: true,
    depthTest: true,
    depthWrite: false,
    polygonOffset: true,
    polygonOffsetFactor: -4,
  });

  var mesh = new THREE.Mesh( decalGeometry, decalMaterial );

  this.scene.add(face);
  this.scene.add(mesh); 
}


function animate() {

	requestAnimationFrame( animate );

  var Y_AXIS = new THREE.Vector3( 0, 1, 0 );
  cube.rotateOnAxis( Y_AXIS, 0.005 );    // radians

	renderer.render( scene, camera );

}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="https://threejs.org/build/three.min.js"></script>
  <script src="https://combinatronics.com/spite/THREE.DecalGeometry/master/src/THREE.DecalGeometry.js"></script>
</head>
<body>
</body>
</html>