赞
踩
主要运用TubeGeometry来制作自定义的隧道效果
function init(){ //创建 WebGL renderer var canvas = document.querySelector("canvas"); renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, shadowMapEnabled: true, shadowMapType: THREE.PCFSoftShadowMap }); renderer.setSize(ww, wh); //创建场景 添加雾效果,是场景朦胧些 scene = new THREE.Scene(); scene.fog = new THREE.Fog(0x194794, 0, 100); var clock = new THREE.Clock(); //创建透视类型的相机 cameraRotationProxyX = 3.14159; cameraRotationProxyY = 0; camera = new THREE.PerspectiveCamera(45, ww / wh, 0.001, 200); camera.rotation.y = cameraRotationProxyX; camera.rotation.z = cameraRotationProxyY; group = new THREE.Group(); group.position.z = 400; group.add(camera); scene.add(group); //创建点光源 light = new THREE.PointLight(0xffffff, .35, 4, 0); light.castShadow = true; scene.add(light); }
用连续的空间点创建自定义曲线,然后根据曲线来创建管道 再添加贴图
function createSkyTube(){ //Array of points var points = [ [10, 89, 0],[50, 88, 10],[76, 139, 20], [126, 141, 12],[150, 112, 8],[157, 73, 0], [180, 44, 5],[207, 35, 10],[232, 36, 0]]; var p1, p2; //points转化为 vertices for (var i = 0; i < points.length; i++) { var x = points[i][0]; var y = points[i][2]; var z = points[i][1]; points[i] = new THREE.Vector3(x, y, z); } //根据路径点创建自定义曲线 path = new THREE.CatmullRomCurve3(points); path.tension = .5; //创建TubeGeometry var geometry = new THREE.TubeGeometry(path, 300, 4, 32, false); //贴图 var texture = new THREE.TextureLoader().load('res/3d_space_5.jpg', function (texture) { texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.offset.set(0, 0); texture.repeat.set(15, 2); }); //凹凸贴图,影响光照感知深度 var mapHeight = new THREE.TextureLoader().load('res/waveform-bump3.jpg', function (texture) { texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.offset.set(0, 0); texture.repeat.set(15, 2); }); //创建MeshPhong镜面高光材质 var material = new THREE.MeshPhongMaterial({ side: THREE.BackSide, map: texture, shininess: 20, bumpMap: mapHeight, bumpScale: -.03, specular: 0x0b2349 } ); //Create a mesh var tube = new THREE.Mesh(geometry, material); scene.add(tube); }
此时效果如下,效果很干不够立体,然后我们加上辅助线效果
思路是创建比星空管道半径更小的TubeGeometry,然后用EdgesGeometry来创建
//再创建半径略小的管道,添加几何体辅助线
function createTubeEdges(){
var geometry = new THREE.TubeGeometry(path, 150, 3.4, 32, false);
//创建边缘几何体
var geo = new THREE.EdgesGeometry(geometry);
var mat = new THREE.LineBasicMaterial({
linewidth: 2,
opacity: .2,
transparent: 1 }
);
//创建线段
var wireframe = new THREE.LineSegments(geo, mat);
scene.add(wireframe);
}
此时效果如图,显得更加立体了 但是光线还是太暗,我们再用后期效果处理一下
UnrealBloonPass是three.js后期处理的扩展库,可以用来模拟生活中的泛光或眩光效果,用在星空效果里恰到好处 用法如下
function initRenderPass(){ var params = { exposure: 1.3, bloomStrength: .9, bloomThreshold: 0, bloomRadius: 0 }; //set up render pass var renderScene = new THREE.RenderPass(scene, camera); //创建泛光通道 var bloomPass = new THREE.UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85); bloomPass.renderToScreen = true; bloomPass.threshold = params.bloomThreshold; //阈值 bloomPass.strength = params.bloomStrength; //强度 bloomPass.radius = params.bloomRadius; //半径 composer = new THREE.EffectComposer(renderer); composer.setSize(window.innerWidth, window.innerHeight); composer.addPass(renderScene); composer.addPass(bloomPass); }
此时效果图:
这里以创建一个为例,项目中创建了三个来交叉运动,加上之后就有了文章开头的效果
var particleSystem1,particleSystem2,particleSystem3; function createParticles(){ var lastPlace = 0; var newPlace = 0; //粒子贴图 var spikeyTexture = new THREE.TextureLoader().load('res/spikey.png'); var particleCount = 6800; particles1 = new THREE.Geometry(); //粒子材质 pMaterial = new THREE.ParticleBasicMaterial({ color: 0xFFFFFF, size: .5, map: spikeyTexture, transparent: true, blending: THREE.AdditiveBlending }); for (var p = 0; p < particleCount; p++) { // 随机创建粒子 // 随机值 -250 -> 250 var pX = Math.random() * 500 - 250, pY = Math.random() * 50 - 25, pZ = Math.random() * 500 - 250, particle = new THREE.Vector3(pX, pY, pZ); particles1.vertices.push(particle); } // create the particle system particleSystem1 = new THREE.ParticleSystem(particles1,pMaterial); // add it to the scene scene.add(particleSystem1); }
function render() {
//...
particleSystem1.rotation.y += 0.00002;
particleSystem2.rotation.x += 0.00005;
particleSystem3.rotation.z += 0.00001;
//...
requestAnimationFrame(render);
}
requestAnimationFrame(render);
用gsap的ScrollTrigger插件来关联滚动,用法如下:
//初始化gsap鼠标滚动 function initAction(){ gsap.defaultEase = Linear.easeNone; var tubePerc = {percent: 0 }; //注册ScrollTrigger gsap.registerPlugin(ScrollTrigger); var tl = gsap.timeline({ scrollTrigger: { trigger: ".scrollTarget", start: "top top", end: "bottom 100%", scrub: 5, markers: { color: "white" } } }); tl.to(tubePerc, { percent: .96, ease: Linear.easeNone, duration: 10, onUpdate: function () { cameraTargetPercentage = tubePerc.percent; } }); }
这里根据onupdate的cameraTargetPercentage值可以去更新相机的位置
function updateCameraPercentage(percentage) {
//camera位于p1点看向p2点
p1 = path.getPointAt(percentage);
p2 = path.getPointAt(percentage + 0.03);
group.position.set(p1.x, p1.y, p1.z);
group.lookAt(p2);
light.position.set(p2.x, p2.y, p2.z);
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。