Three.js 中挤出形状的奇怪伪影和空纹理 [英] Odd artifacts and Empty texture in extruded shape in three.js

查看:26
本文介绍了Three.js 中挤出形状的奇怪伪影和空纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾尝试通过使用 Three.js 挤压形状来为 SVG 路径(lineto 和 moveto)赋予 3D 感觉,但该过程会导致一些我无法移除的伪影.

什么会导致我渲染的 3D 形状出现奇怪的伪影?有没有办法去除它们?

工件在下面的示例图像中用箭头标记.

现场示例在这里:');var crateTexture = new THREE.ImageUtils.generateDataTexture(10,10,{r:255,g:0,b:0});var materialFront = new THREE.MeshBasicMaterial( { map: crateTexture } );

//http://jsfiddle.net/pHn2B/27/

示例图片来自 Chrome.同样的行为也发生在 Firefox 中.

解决方案

这是由 z 缓冲问题引起的 CanvasRenderer 的已知限制.您的几何体具有许多细长面,这使情况变得更糟.模型使用 WebGLRenderer 正确渲染.

ExtrudeGeometry 最初是为文本编写的,如果您查看它生成的 UV,它只会使用 UV 的顶点位置的 x 和 y 分量,在您的情况下,它会生成范围 [ 0, 1 ] 之外的值.您可以选择在回调函数中提供自己的紫外线发生器.

首先确保您可以成功地将纹理添加到立方体中.

three.js r.58

I have tried to give 3D feeling to SVG paths (lineto and moveto) by extruding shapes using Three.js, but the process causes some artifacts that I cannot remove.

What could cause odd artifacts in my rendered 3D shape? Is there a way to remove them?

The artifacts are marked with arrows in the sample image below.

The live example is here: http://jsfiddle.net/pHn2B/24/

And the code is here:

// Picking with Callback

// three.js r.52
var container,
    info,
    camera,
    scene,
    light,
    geometry,
    mesh,
    projector,
    renderer,
    controls;
    objects = [];

// dom
container = document.createElement( 'div' );
document.body.appendChild( container );

// info
info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = "drag to rotate camera; click to select";
container.appendChild( info );

// renderer
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );

// scene
scene = new THREE.Scene();

// camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.set( 0, 300, 500 );
scene.add( camera );

// controls
controls = new THREE.OrbitControls( camera );

// light
scene.add( new THREE.AmbientLight( 0x222222 ) );

// light
light = new THREE.PointLight( 0xaaaaaa );
light.position = camera.position;
scene.add( light );

// geometry
geometry = new THREE.CubeGeometry( 100, 100, 500 );

// material
material = new THREE.MeshLambertMaterial( { color: 0xff0000, ambient: 0xff0000, overdraw: true } );

// mesh
mesh = new THREE.Mesh( geometry, material );
mesh.position.set( -100, -100, 200 );
mesh.name = "Red Object";
mesh.callback = function() { info.innerHTML = this.name; }
scene.add( mesh );

objects.push( mesh );

// geometry
////////////
    // CUSTOM //
    ////////////

var starPoints2 = new THREE.Shape();

starPoints2.moveTo(307.94,275.49);
starPoints2.lineTo(296.26,275.23);
starPoints2.lineTo(286.64,272.99);
starPoints2.lineTo(279.78,269.31);
starPoints2.lineTo(274.14,263.55);
starPoints2.lineTo(271.65,260.21);
starPoints2.lineTo(269.2,261.06);
starPoints2.lineTo(254.83,268.51);
starPoints2.lineTo(242.11,272.97);
starPoints2.lineTo(227.59,275.23);
starPoints2.lineTo(209.91,275.48);
starPoints2.lineTo(197.47,273.63);
starPoints2.lineTo(187.91,270.13);
starPoints2.lineTo(180.48,265.09);
starPoints2.lineTo(175.32,258.88);
starPoints2.lineTo(172.2,251.44);
starPoints2.lineTo(171.1,242.23);
starPoints2.lineTo(172.24,233.63);
starPoints2.lineTo(175.49,226.24);
starPoints2.lineTo(181,219.54);
starPoints2.lineTo(189.42,213.3);
starPoints2.lineTo(201.36,207.73);
starPoints2.lineTo(217.23,203.25);
starPoints2.lineTo(238.28,200.1);
starPoints2.lineTo(269.37,198.47);
starPoints2.lineTo(269.98,182.93);
starPoints2.lineTo(268.74,171.32);
starPoints2.lineTo(266.05,163.7);
starPoints2.lineTo(261.58,157.72);
starPoints2.lineTo(255.24,153.24);
starPoints2.lineTo(247.06,150.32);
starPoints2.lineTo(235.44,149.13);
starPoints2.lineTo(224.71,150.05);
starPoints2.lineTo(215.91,153);
starPoints2.lineTo(210.23,156.86);
starPoints2.lineTo(207.64,160.85);
starPoints2.lineTo(207.19,165.28);
starPoints2.lineTo(209.34,169.86);
starPoints2.lineTo(212.01,174.15);
starPoints2.lineTo(212.14,177.99);
starPoints2.lineTo(209.8,181.78);
starPoints2.lineTo(204.22,185.79);
starPoints2.lineTo(197.62,187.68);
starPoints2.lineTo(188.65,187.43);
starPoints2.lineTo(182.41,185.39);
starPoints2.lineTo(178.45,181.77);
starPoints2.lineTo(176.2,176.9);
starPoints2.lineTo(176.03,170.64);
starPoints2.lineTo(178.2,164.13);
starPoints2.lineTo(183.09,157.69);
starPoints2.lineTo(191.04,151.36);
starPoints2.lineTo(202.01,145.82);
starPoints2.lineTo(216.09,141.57);
starPoints2.lineTo(232.08,139.24);
starPoints2.lineTo(250.07,139.18);
starPoints2.lineTo(266.13,141.23);
starPoints2.lineTo(279.05,145.06);
starPoints2.lineTo(289.15,150.3);
starPoints2.lineTo(295.91,156.19);
starPoints2.lineTo(300.73,163.41);
starPoints2.lineTo(303.85,172.47);
starPoints2.lineTo(305.07,183.78);
starPoints2.lineTo(305.07,241.97);
starPoints2.lineTo(306,251.51);
starPoints2.lineTo(308.18,256.39);
starPoints2.lineTo(311.72,259.09);
starPoints2.lineTo(317.31,260.01);
starPoints2.lineTo(324.71,259.01);
starPoints2.lineTo(332.45,255.86);
starPoints2.lineTo(335.57,257.53);
starPoints2.lineTo(337.6,260.44);
starPoints2.lineTo(336.94,262.33);
starPoints2.lineTo(328.27,268.74);
starPoints2.lineTo(317.89,273.41);
starPoints2.lineTo(307.94,275.49);
/*
starPoints2.moveTo(245.79,125.33);
starPoints2.lineTo(232.93,124.53);
starPoints2.lineTo(222.21,121.74);
starPoints2.lineTo(213.14,117.11);
starPoints2.lineTo(207.36,111.92);
starPoints2.lineTo(203.7,105.75);
starPoints2.lineTo(201.94,98.18);
starPoints2.lineTo(202.34,90.12);
starPoints2.lineTo(204.86,83.4);
starPoints2.lineTo(210.01,76.81);
starPoints2.lineTo(217.49,71.33);
starPoints2.lineTo(227.17,67.31);
starPoints2.lineTo(238.35,65.2);
starPoints2.lineTo(243.99,64.95);
starPoints2.lineTo(255.92,66.06);
starPoints2.lineTo(266.21,69.28);
starPoints2.lineTo(274.98,74.44);
starPoints2.lineTo(280.64,80.19);
starPoints2.lineTo(284.02,86.85);
starPoints2.lineTo(285.26,94.52);
starPoints2.lineTo(284.27,102.84);
starPoints2.lineTo(281.24,109.66);
starPoints2.lineTo(276.03,115.43);
starPoints2.lineTo(267.89,120.46);
starPoints2.lineTo(257.68,123.93);
starPoints2.lineTo(245.79,125.33);
*/
var smileyEye1Path = new THREE.Path();

smileyEye1Path.moveTo(221.69,258.13);
smileyEye1Path.lineTo(215.2,255.08);
smileyEye1Path.lineTo(210.86,250.57);
smileyEye1Path.lineTo(208.4,244.49);
smileyEye1Path.lineTo(207.92,237.03);
smileyEye1Path.lineTo(209.69,230.71);
smileyEye1Path.lineTo(213.82,224.85);
smileyEye1Path.lineTo(220.9,219.34);
smileyEye1Path.lineTo(230.95,214.67);
smileyEye1Path.lineTo(245.76,210.86);
smileyEye1Path.lineTo(266.59,208.36);
smileyEye1Path.lineTo(269.48,208.76);
smileyEye1Path.lineTo(269.99,212.88);
smileyEye1Path.lineTo(269.99,244.81);
smileyEye1Path.lineTo(269.34,247.02);
smileyEye1Path.lineTo(266.07,250.04);
smileyEye1Path.lineTo(255.27,255.23);
smileyEye1Path.lineTo(242.52,258.58);
smileyEye1Path.lineTo(230.57,259.43);
smileyEye1Path.lineTo(221.69,258.13);

/*
smileyEye1Path.moveTo(238.44,116.65);
smileyEye1Path.lineTo(231.99,114.29);
smileyEye1Path.lineTo(227.23,110.22);
smileyEye1Path.lineTo(223.94,104.53);
smileyEye1Path.lineTo(222.41,96.92);
smileyEye1Path.lineTo(223.05,88.57);
smileyEye1Path.lineTo(225.65,82.21);
smileyEye1Path.lineTo(230.07,77.36);
smileyEye1Path.lineTo(235.93,74.4);
smileyEye1Path.lineTo(243.68,73.34);
smileyEye1Path.lineTo(246.08,73.43);
smileyEye1Path.lineTo(253.37,75.08);
smileyEye1Path.lineTo(258.65,78.43);
smileyEye1Path.lineTo(262.47,83.41);
smileyEye1Path.lineTo(264.59,90.25);
smileyEye1Path.lineTo(264.64,98.93);
smileyEye1Path.lineTo(262.63,106.12);
smileyEye1Path.lineTo(258.87,111.5);
smileyEye1Path.lineTo(253.73,115.1);
smileyEye1Path.lineTo(246.81,116.94);
smileyEye1Path.lineTo(238.44,116.65);
*/
var starShape = starPoints2;

starShape.holes.push( smileyEye1Path );

    var extrusionSettings = {
        //size: 1, height: 1, curveSegments: 100, step = 10,
        // font, weight, style,
        amount:20,
        bevelEnabled: true, 
        bevelThickness: 0.5, 
        bevelSize: 0.5,
        bevelSegments: 8,
        // extrudePath:
        // bendPath:
        material: 0,
        extrudeMaterial: 1
        //,
        //uvGenerator: BoundingUVGenerator
       //uvGenerator: THREE.ExtrudeGeometry.WorldUVGenerator
    };

    var starGeometry = new THREE.ExtrudeGeometry( starShape, extrusionSettings );

    var materialFront = new THREE.MeshLambertMaterial( { color: 0xffff00, ambient: 0xffff00, overdraw: false, transparent:false, opacity: 1.0, side: THREE.DoubleSide } );
    var materialSide = new THREE.MeshLambertMaterial( { color: 0xff8800, ambient: 0xff8800, overdraw: false, transparent:false, opacity: 1.0, side: THREE.DoubleSide } );

//var crateTexture = new THREE.ImageUtils.loadTexture( 'http://www.kahkonen.com/asiakkaat/crate2.gif');
//var crateTexture = new THREE.ImageUtils.generateDataTexture(10,10,{r:255,g:0,b:0});

//var materialFront = new THREE.MeshBasicMaterial( { map: crateTexture } );

var materialArray = [ materialFront, materialSide ];
var materialArray = [ materialFront, materialSide ];

var starMaterial = new THREE.MeshFaceMaterial(materialArray);

    var star = new THREE.Mesh( starGeometry, starMaterial );

    star.position.set(-150,-150,0);
    scene.add(star);
/*  
    // add a wireframe to model
    var wireframeTexture = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: false } ); 
    var star = new THREE.Mesh( starGeometry, wireframeTexture );
    star.position.set(50,10,0);
    scene.add(star);
*/
objects.push( star );

// projector
projector = new THREE.Projector();

// listeners
document.addEventListener( 'mousedown', onDocumentMouseDown, false)

// keyboard handler
function onDocumentMouseDown( event ) {

    event.preventDefault();

    var vector = new THREE.Vector3( 
        ( event.clientX / window.innerWidth ) * 2 - 1, 
        - ( event.clientY / window.innerHeight ) * 2 + 1, 
        0.5 );

    projector.unprojectVector( vector, camera );

    var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );

    var intersects = ray.intersectObjects( objects );    

    if ( intersects.length > 0 ) {

        intersects[0].object.callback();

    }

}

// render
function render() {

    controls.update()

    renderer.render( scene, camera );
}

// animate            
(function animate() {

    requestAnimationFrame( animate );
    render();
}());

I have tried to remove artifacts by appending texture, but texture is not shown at all:

Other problem (that may or may not be related to artifact-problem) is that background can be seen through edges.

Texture is not a must, but removing artifacts is.

The code that I have used to add texture is below and full code in the fiddle (link is after the code):

var crateTexture = new THREE.ImageUtils.loadTexture( 'http://www.kahkonen.com/asiakkaat/crate.gif'); var crateTexture = new THREE.ImageUtils.generateDataTexture(10,10,{r:255,g:0,b:0}); var materialFront = new THREE.MeshBasicMaterial( { map: crateTexture } );

// http://jsfiddle.net/pHn2B/27/

Sample images are from Chrome. The same behavior occurs in Firefox too.

解决方案

This is a know limitation of CanvasRenderer caused by z-buffering problems. It is made worse by your geometry which has many elongated faces. The model renders correctly with WebGLRenderer.

ExtrudeGeometry was originally written for text, and if you look at the UVs it generates, it just uses the x- and y-components of the vertex positions for UVs, which in your case, produces values that are outside the range [ 0, 1 ]. You have the option of providing your own UV-generator in a callback function.

Make sure you can successfully add a texture to a cube first.

three.js r.58

这篇关于Three.js 中挤出形状的奇怪伪影和空纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆