三个js中的纹理没有更新

问题描述 投票:0回答:3

我使用threejs编辑器作为一些三个工作的基础。当用户将鼠标悬停在某些元素上时,我试图显示一些工具提示。为了实现这一点,我使用了一个画布,它在精灵上呈现为纹理。

// create a canvas element
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 20px Arial";
context1.fillStyle = "rgba(0,0,0,0.95)";
context1.fillText('Hello, world!', 0, 20);

// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;

// use the texture as material
var spriteMaterial = new THREE.SpriteMaterial({
    map: texture1,
    useScreenCoordinates: false
});

// create the sprite and add it tho the scene
var sprite1 = new THREE.Sprite(spriteMaterial);
sprite1.scale.set(1000, 500, 1.0);
sprite1.position.set(50, 50, 0);
scene.add(sprite1);

var i = 0;
// change the canvas' content
setInterval(function () {
    context1.clearRect(0, 0, canvas1.width, canvas1.height);
    var message = 'test' + i++;
    context1.fillText(message, 4, 20);
    texture1.needsUpdate = true;
}, 1000)

显示“test0”,但精灵不会更新。如何更新精灵上的文字?我在这里错过了一些缓存失效吗?

enter image description here

javascript canvas three.js textures sprite
3个回答
1
投票

为什么在3D画布上渲染文本框?通过在页面的2D上下文中投影3D对象位置来定位2D html对象会更好。

优点是不会有任何渲染性能下降,您可以使用常规的CSS / HTML样式为您的信息框。

检查a great example on how you can do that here

another one属于这个 stackoverflow answer。工作就像这样简单:

var proj = toScreenPosition(divObj, camera);

divElem.style.left = proj.x + 'px';
divElem.style.top = proj.y + 'px';

但是,如果你做一些谷歌搜索,你可以很容易地找到更多的例子......

Here is a fiddle愚弄。


0
投票

我认为它没有用,因为你没有设置画布的高度和宽度。

canvas1.width = 256;
canvas1.height = 256;

这条线也是一个问题:context1.fillStyle = "rgba(0.0,0,0,0.95)"; 我改为:context1.fillStyle = '#ff0000';我的工作

Here is a fiddle实现了您的代码,只是在画布上添加了高度和宽度,并更改了fillStyle

如果满足您的需求,威尔特的答案可能是更好的选择。


-1
投票

编辑:我是个白痴。这个问题是2岁。

它似乎对我有用......你确定你没有忽略控制台中的一些错误吗?你在setInterval中放了一个断点来确保它被调用吗?

我确实必须将更新移动到renderloop,因为似乎没有为SO片段定义setInterval,但请在此处查看:

var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  45, // Field of view
  w / h, // Aspect ratio
  0.1, // Near
  10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.PointLight(0xFFFF00);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);

var sphereGeom = new THREE.SphereGeometry(5, 16, 16);
for (var i = 0; i < sphereGeom.vertices.length; i++) {
  var v = sphereGeom.vertices[i];
  if (v.y < 0) v.y = 0;
}
sphereGeom.verticesNeedUpdate = true;
sphereGeom.computeFaceNormals();
sphereGeom.computeVertexNormals();

var material = new THREE.MeshLambertMaterial({
  color: 0x808080
});
var mesh = new THREE.Mesh(sphereGeom, material);
scene.add(mesh);
renderer.setClearColor(0xdddddd, 1);

// create a canvas element
var canvas1 = document.createElement('canvas');
var context1 = canvas1.getContext('2d');
context1.font = "Bold 20px Arial";
context1.fillStyle = "rgba(0,0,0,0.95)";
context1.fillText('Hello, world!', 0, 20);

// canvas contents will be used for a texture
var texture1 = new THREE.Texture(canvas1)
texture1.needsUpdate = true;

// use the texture as material
var spriteMaterial = new THREE.SpriteMaterial({
  map: texture1,
  useScreenCoordinates: false
});

// create the sprite and add it tho the scene
var sprite1 = new THREE.Sprite(spriteMaterial);
sprite1.scale.set(40, 20, 1.0);
sprite1.position.set(-5, 0, -5);
scene.add(sprite1);

var i = 0;

(function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);



  context1.clearRect(0, 0, canvas1.width, canvas1.height);
  var message = 'test' + i++;
  context1.fillText(message, 4, 20);
  texture1.needsUpdate = true;

})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.