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>
合作:@浩
鑽研不易,轉載請注明出處。。。。。。
