three.js后处理之outline

本文介绍如何在three.js中使用后处理技术提升场景效果,包括EffectComposer、CopyShader、RenderPass等组件的引入与配置,以及通过OutlinePass实现模型高亮边框效果的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

three的后处理接口相较于cesium来说复杂的多,

要引入5个js,这些js具体是干啥的,还没去看,先实现吧

<script src="../../plugins/EffectComposer.js"></script>
<script src="../../plugins/CopyShader.js"></script>
<script src="../../plugins/RenderPass.js"></script>
<script src="../../plugins/ShaderPass.js"></script>
<script src="../../plugins/OutlinePass.js"></script>
function initThree(elid,options) {
    let  scene,camera ,renderer,viewer
    viewer={}
    el =  document.getElementById(elid)
    const  width = el.offsetWidth, height = el.offsetHeight,asp =  width / height
    renderer = new THREE.WebGLRenderer({antialias : true});
    renderer.setSize(width, height);
    el.append(renderer.domElement);
    renderer.setClearColor('#000')
    scene = new THREE.Scene()
    camera = new THREE.PerspectiveCamera(45, asp, 1, 10000)
    camera.position.set(10,10,10)
    camera.lookAt(0,0,0)
    scene.add(camera)
    viewer.scene=scene
    viewer.camera=camera
    viewer.renderer=renderer
    const controls = new THREE.OrbitControls( camera, renderer.domElement );
    // 如果使用animate方法时,将此函数删除
    controls.addEventListener( 'change', ()=>{
        renderer.render( scene, camera );
    });
    viewer.controls=controls
    renderer.render( scene, camera );

    return viewer
}
  
let app=new initThree('box')
    let scene=app.scene
    let renderer=app.renderer
    let camera=app.camera
    let controls=app.controls
    const clock = new THREE.Clock()


    //add light
    const directionalLight = new THREE.DirectionalLight( '#fff' )
    directionalLight.position.set( 30, 30, 30 ).normalize()
    scene.add( directionalLight )
    const ambientLight = new THREE.AmbientLight('#fff',0.3) // obj 唯一 id
    scene.add(ambientLight)
    /*  **** **** ****   ****/

    renderer.setPixelRatio( window.devicePixelRatio )
    renderer.shadowMap.enabled = true


    const box = new THREE.Mesh(new THREE.BoxBufferGeometry(2,2,2) ,new THREE.MeshBasicMaterial({color:'red'}))
    box.position.set(0,1,-2)
    scene.add(box)

    const box2 = new THREE.Mesh(new THREE.BoxBufferGeometry(2,2,2) ,new THREE.MeshBasicMaterial({color:'yellow'}))
    scene.add(box2)
    box2.position.set(0,1,2)

    const group = new THREE.Group()
    group.add(box,box2)
    group.name = 'oneGroup'
    scene.add(group)


    //球
    const sphereGeometry = new THREE.SphereGeometry(4, 20, 20)
    const sphereMaterial = new THREE.MeshLambertMaterial({color: 'red'})
    const sphere = new THREE.Mesh(sphereGeometry, sphereMaterial)
    sphere.position.set(-10,0,-10)
    scene.add(sphere)
    /*  ***********/
    //
    const composer = new THREE.EffectComposer(renderer)
    composer.setSize( el.offsetWidth, el.offsetHeight )

    //

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

    //
    const loader = new THREE.TextureLoader()

    function initOutlinePass(color, url) {
        const outlinePass = new THREE.OutlinePass( new THREE.Vector2( el.offsetWidth, el.offsetHeight ), scene, camera )
        if(url) {
            loader.load( url, texture => {
                outlinePass.patternTexture = texture
                texture.wrapS = THREE.RepeatWrapping
                texture.wrapT = THREE.RepeatWrapping
            });
        }
        outlinePass.edgeStrength = 3 //粗
        outlinePass.edgeGlow = 1 //发光
        outlinePass.edgeThickness = 1 //光晕粗
        outlinePass.pulsePeriod = 1 //闪烁
        outlinePass.usePatternTexture = false //true

        outlinePass.visibleEdgeColor.set( color );
        outlinePass.hiddenEdgeColor.set( '#190a05' );
        composer.addPass( outlinePass )

        return outlinePass
    }
    const outlinePass2 = initOutlinePass('yellow')
    let selectedObjects2 = []

    outlinePass2.selectedObjects = selectedObjects2
    selectedObjects2.push(sphere)



    function render() {
        controls.update(clock.getDelta())
        composer.render()
        requestAnimationFrame(render)

    }
    render()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值