在three.js中使用基本纹理材质时出现异常抗锯齿

5
在以下代码中,我正在使用正交相机和映射为纹理的画布来设置一个非常基本的场景。我将一些白色文本放在透明画布上,如果我使用canvas.toDataURL(),效果并不明显。然而,当我将画布内容应用于材质作为纹理,并在超标准的2D场景中渲染它时,我的文本周围会出现黑色线条,可能是由于奇怪的抗锯齿效果导致的。在此示例中,渲染器清除颜色、材质和文本都是纯白色。以下是屏幕截图:screenshot
var camera = new THREE.OrthographicCamera(window.innerWidth / - 2,
                                          window.innerWidth / 2, 
                                          window.innerHeight / 2, 
                                          window.innerHeight / - 2, 0, 10);

var scene = new THREE.Scene();

canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 300;

var context = canvas.getContext('2d');

context.fillStyle = "white";
context.font = "bold 72px Arial";
context.fillText("Zibri", 50, 100);        

var texture = new THREE.Texture(canvas);
var geometry = new THREE.PlaneGeometry(canvas.width, canvas.height);

texture.needsUpdate = true;

var material = new THREE.MeshBasicMaterial({ color: 0xffffff, map: texture, transparent: true });
var mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

renderer = new THREE.WebGLRenderer({ antialias: false });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor(0xffffff)

document.body.appendChild( renderer.domElement );

camera.lookAt(scene.position);
renderer.render(scene, camera);

此前已有报告,但目前尚未得到答复。我也遇到了同样的问题,但我没有去搜索和尝试,而是使用了稍微高一些的分辨率,并且由于我的文本是黑色的,所以并不会影响太多。但很抱歉,我无法提供帮助。不过我也在寻找解决方法 ;) - GuyGood
我目前最好的答案就是将画布设置为不使用任何抗锯齿或alpha值。此外,如果您将网格和纹理设置为具有相同的宽度和高度,这也可能有所帮助。另外,在Chrome中,您可以在基本画布上使用CSS来设置在使用字体时应使用哪种类型的抗锯齿。您可以参考此处的超长评论以获取有关修复Chrome问题的帮助。https://groups.google.com/a/chromium.org/forum/#!topic/chromium-bugs/dtM7sjgsI20 - Jack Franzen
尝试使用以下代码:texture.magFilter = THREE.NearestFilter; texture.minFilter = THREE.NearestFilter; texture.generateMipmaps = false; - WestLangley
1个回答

6

我也遇到了这个问题,WestLangley的解决方案在一定程度上修复了该问题,但呈现的文本边缘非常模糊。经过深入研究,我想出了一个自己满意的解决方案,下面就进行概述。

在绘制文本之前,用透明度设置为0.01的相同颜色填充画布。

context.fillStyle = 'rgba(255,255,255,0.01)';
context.fillRect(0,0,canvas.width,canvas.height);

然后使用材质的alphaTest属性来丢弃这种不透明度的像素:

var material = new THREE.MeshBasicMaterial({
    color: 0xffffff,
    map: texture,
    transparent: true,
    alphaTest:0.01
});

最后,将纹理映射的premultiplyAlpha值设置为false:
texture.map.premultiplyAlpha = false;
texture.map.needsUpdate = true;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接