drawing an outline on a 3D object with Three.js

时间:2015-07-28 22:58:54

标签: javascript three.js

I have several objects in the scene leaving the outcome of the .mesh of Three.js ... I separate ways but not how.

I want to put a boundary to clearly see the shapes. http://www.subirimagenes.com/imagen-captura-9427322.html

extrude_geometria[i]=new    THREE.ExtrudeGeometry(forma_figura[i],datos_extrusion);
materialFront[i] = new THREE.MeshBasicMaterial( { color: "#FF0000"} );

municipios[i] = new THREE.Mesh( extrude_geometria[i], materialFront[i] );

4 个答案:

答案 0 :(得分:1)

需要Composer和Outline传递。请参阅下面的示例,它是https://threejs.org/examples/?q=out#webgl_postprocessing_outline

上官方示例的简化
<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - post processing - Outline Pass</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="three.js"></script>

<script src="CopyShader.js"></script>
<script src="FXAAShader.js"></script>
<script src="EffectComposer.js"></script>
<script src="RenderPass.js"></script>
<script src="ShaderPass.js"></script>
<script src="OutlinePass.js"></script>


<div id="info">
    <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Outline Pass by <a href="http://eduperiment.com" target="_blank" rel="noopener">Prashant Sharma</a> and <a href="https://clara.io" target="_blank" rel="noopener">Ben Houston</a><br/><br/>
</div>

<script>

    var container, camera, scene, renderer, composer, effectFXAA, outlinePass;

    var raycaster = new THREE.Raycaster();
    var mouse = new THREE.Vector2();

    init();
    animate();

    function init() {
        container = document.createElement('div');
        document.body.appendChild(container);

        var width = window.innerWidth || 1;
        var height = window.innerHeight || 1;

        renderer = new THREE.WebGLRenderer({antialias: false});
        renderer.setSize(width, height);
        document.body.appendChild(renderer.domElement);

        camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 100);
        camera.position.z = 8;
        camera.position.x = 0;

        scene = new THREE.Scene();


        var light = new THREE.DirectionalLight(0xddffdd, 0.4);
        light.position.z = 1;
        light.position.y = 1;
        light.position.x = 1;
        scene.add(light);

        var floorMaterial = new THREE.MeshLambertMaterial();
        floorMaterial.side = THREE.DoubleSide;
        var floorGeometry = new THREE.PlaneBufferGeometry(12, 12);
        var floorMesh = new THREE.Mesh(floorGeometry, floorMaterial);
        floorMesh.rotation.x -= Math.PI * 0.5;
        floorMesh.position.y -= 1.5;
        scene.add(floorMesh);




        // postprocessing
        composer = new THREE.EffectComposer(renderer);

        var renderPass = new THREE.RenderPass(scene, camera);
        composer.addPass(renderPass);

        outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
        composer.addPass(outlinePass);

        effectFXAA = new THREE.ShaderPass(THREE.FXAAShader);
        effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
        effectFXAA.renderToScreen = true;
        composer.addPass(effectFXAA);

        window.addEventListener('mousemove', onTouchMove);
        window.addEventListener('touchmove', onTouchMove);

        function onTouchMove(event) {
            mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
            mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1;

            raycaster.setFromCamera(mouse, camera);

            var intersects = raycaster.intersectObjects([scene], true);

            if (intersects.length > 0) {
                var selectedObject = intersects[0].object;
                outlinePass.selectedObjects = [selectedObject];
            }
        }
    }

    function animate() {
        requestAnimationFrame( animate );
        composer.render();
    }

</script>
</body>
</html>

答案 1 :(得分:0)

查看THREE.js中的内置WireframeHelper和edgesHelper实用程序 - 它们可以添加您描述的内容。

答案 2 :(得分:0)

THREE.BoundingBoxHelper()可以帮到你。它显示了对象的边界框。一个例子是:

# hexadecimal value to define color
var hex  = 0xff0000;
var bbox = new THREE.BoundingBoxHelper( your_mesh, hex );
bbox.update();
scene.add( bbox );

其中 your_mesh 是显示边界框的object3D。

仅渲染网格轮廓的粗略方法是使用正面剔除和沿着法线偏移每个顶点的特定着色器,使用平面颜色渲染网格两次。一个例子是:

var vertexShader = 
"void main(){"+
    "float offset = 2.0;"+
    "vec4 pos = modelViewMatrix * vec4( position + normal * offset, 1.0 );"+
    "gl_Position = projectionMatrix * pos;"+
"}\n";

var fragmentShader =
"void main(){"+
    "gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );"+
"}\n";

答案 3 :(得分:0)

您可以使用EdgesGeometry,在我的情况下效果很好。在添加网格之后插入此代码:

const geometry = new THREE.PlaneBufferGeometry(200, 200) // whatever geometry you use
const line = new THREE.LineSegments(new THREE.EdgesGeometry(geometry), new THREE.LineBasicMaterial({color: 0x00000}))
scene.add(line)

https://threejs.org/docs/#api/en/geometries/EdgesGeometry