shader之threejs应用

shader之threejs应用

 shader用作编写threejs自定义材质的着色器。

 效果:

 代码:

<template>
    <div class="threeModel">
        <div id="modelBox"></div>
    </div>
</template>

<script>
    import * as THREE from 'three'
    import { STLLoader } from 'three/examples/jsm/loaders/STLLoader'
    import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'


    import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';  

    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
    import {
        CSS2DRenderer,
        CSS2DObject
    } from 'three/examples/jsm/renderers/CSS2DRenderer'

    import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass'
    import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass'
    import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'

    //用于轨道控制器
    var orbitControls, clock, delta,scene;
    export default {
        name: 'threeModel',
        data() {
            return {
            }
        },
        mounted() {
            this.initContainer()
        },
        methods:{
            // 创建场景
            initContainer() {
                var that = this;
                //// 场景-----------------------
                scene = new THREE.Scene();
                //// --------------------------

                //// 摄像机---------------------
                var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000);
                camera.position.x = 300;
                camera.position.y = 100;
                camera.position.z = 300
                //// --------------------------

                //// 物体 end ------------------

                 //生成一个坐标轴,辅助线,坐标轴的参数
                var axes=new THREE.AxisHelper(200);

                //// 光源-----------------------
                var ambientLight = new THREE.AmbientLight(0xffffff);
                scene.add( ambientLight );

                //// 渲染器--------------------
                var renderer = new THREE.WebGLRenderer({antialias: true,alpha:true});
                renderer.setSize( window.innerWidth - 300, window.innerHeight );
                document.getElementById("modelBox").appendChild( renderer.domElement );

                // 设置渲染器渲染阴影效果
                renderer.setClearColor(new THREE.Color(0x000000));
                renderer.shadowMap.enabled = true;


                var controls = new OrbitControls(camera,renderer.domElement)
                controls.target = new THREE.Vector3(0, 0, 0);//控制焦点
                controls.autoRotate = false;//将自动旋转关闭
                clock = new THREE.Clock();//用于更新轨道控制器
                let modelState = 0
                function animate() {
                    renderer.render( scene, camera );
                    renderer.setClearColor(0,0,0,0);
                    renderer.shadowMap.enabled = false;
                    delta = clock.getDelta();
                    controls.update(delta);
                    requestAnimationFrame( animate );
                }
                animate();
                this.addCube()
            },
            addCube(){
                //// 物体----------------------
                var geometry = new THREE.BoxGeometry(40, 40, 40);
                var cube = new THREE.Mesh( geometry, this.shaderMaterial() );
                cube.position.x = 0;
                cube.position.y = 20;
                cube.position.z = 0;
                // 设置投影
                cube.castShadow = true;
                scene.add( cube );
            },
            shaderMaterial(){
                let v=`   
                        varying vec3 vNormal;
                            void main() {
                                //将attributes的normal通过varying赋值给了向量vNormal
                            vNormal = normal;
                                //projectionMatrix是投影变换矩阵 modelViewMatrix是相机坐标系的变换矩阵
                            gl_Position = projectionMatrix * modelViewMatrix * vec4( position.x, position.y, position.z, 1.0 );
                        }
                        `
                let f=`
                        //片元着色器同样需要定义varying vec3 vNormal;
                        varying vec3 vNormal;
                        void main() {
                            //vNormal是一个已经归一化的三维向量
                            float pr = (vNormal.x + 1.0) / 2.0; //pr红色通道值范围为0~1
                            float pg = (vNormal.y + 1.0) / 2.0; //pg绿色通道值范围为0~1
                            float pb = (vNormal.z + 1.0) / 2.0; //pb蓝色通道值范围为0~1
                            gl_FragColor=vec4(pr, pg, pb, 1.0); //最后设置顶点颜色,点与点之间会自动插值
                        }
                        `
                  var  meshMaterial= new THREE.ShaderMaterial({
                        vertexShader: v,
                        fragmentShader: f,
                        transparent: true,
                        side:THREE.DoubleSide,//两面可见
                    });
                return meshMaterial

            }


        }
    }
</script>

<style scoped lang="scss">
    .threeModel{
        background-size: 100% 100%;
        width: 100%;
        height: 100%;
        #modelBox{
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            outline: none;
            canvas{
                outline: none;
            }
        }
    }
</style>

合作:@浩

钻研不易,转载请注明出处。。。。。。

原文地址:https://www.cnblogs.com/s313139232/p/14316827.html