参考网是合法网站吗?,免费app制作平台下载,unity网站后台怎么做,网站静态模板下载前言 three.js 通过着色器如何实现全息影像#xff0c;以及一些动态的效果。 一些难点的思维#xff0c;代码目录 下面图是摄像机视角观看影响上的时候#xff0c;如何实现光影的渐变#xff0c;透视以及叠加等。 一、代码
1.index.html
!DOCTYPE html
html …
前言 three.js 通过着色器如何实现全息影像以及一些动态的效果。 一些难点的思维代码目录 下面图是摄像机视角观看影响上的时候如何实现光影的渐变透视以及叠加等。 一、代码
1.index.html
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleHolographic/titlelink relstylesheet href./style.css
/head
bodycanvas classwebgl/canvasscript typemodule src./script.js/script
/body
/html
2.style.css
*
{margin: 0;padding: 0;
}html,
body
{overflow: hidden;
}.webgl
{position: fixed;top: 0;left: 0;outline: none;
}3.script.js
import * as THREE from three
import { OrbitControls } from three/addons/controls/OrbitControls.js
import GUI from lil-gui
import { GLTFLoader } from three/addons/loaders/GLTFLoader.js
import holographicVertexShader from ./shaders/holographic/vertex.glsl
import holographicFragmentShader from ./shaders/holographic/fragment.glsl/*** Base*/
// Debug
const gui new GUI()// Canvas
const canvas document.querySelector(canvas.webgl)// Scene
const scene new THREE.Scene()// Loaders
const gltfLoader new GLTFLoader()/*** Sizes*/
const sizes {width: window.innerWidth,height: window.innerHeight
}window.addEventListener(resize, ()
{// Update sizessizes.width window.innerWidthsizes.height window.innerHeight// Update cameracamera.aspect sizes.width / sizes.heightcamera.updateProjectionMatrix()// Update rendererrenderer.setSize(sizes.width, sizes.height)renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})/*** Camera*/
// Base camera
const camera new THREE.PerspectiveCamera(25, sizes.width / sizes.height, 0.1, 100)
camera.position.set(7, 7, 7)
scene.add(camera)// Controls
const controls new OrbitControls(camera, canvas)
controls.enableDamping true/*** Renderer*/
const rendererParameters {}
rendererParameters.clearColor #1d1f2aconst renderer new THREE.WebGLRenderer({canvas: canvas,antialias: true
})
renderer.setClearColor(rendererParameters.clearColor)
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))gui.addColor(rendererParameters, clearColor).onChange(() {renderer.setClearColor(rendererParameters.clearColor)})/*** Material*/
const materialParameters {}
materialParameters.color #70c1ffgui.addColor(materialParameters,color).onChange((){material.uniforms.uColor.value.set(materialParameters.color)})const material new THREE.ShaderMaterial({vertexShader:holographicVertexShader,fragmentShader:holographicFragmentShader,uniforms:{uTime:new THREE.Uniform(0),uColor:new THREE.Uniform(new THREE.Color(materialParameters.color))},transparent:true, // 设置透明材质side:THREE.DoubleSide,depthWrite:false, // 停止深度写入blending:THREE.AdditiveBlending, // 混合叠加 叠加起来的颜色更亮})/*** Objects*/
// Torus knot
const torusKnot new THREE.Mesh(new THREE.TorusKnotGeometry(0.6, 0.25, 128, 32),material
)
torusKnot.position.x 3
scene.add(torusKnot)// Sphere
const sphere new THREE.Mesh(new THREE.SphereGeometry(),material
)
sphere.position.x - 3
scene.add(sphere)// Suzanne
let suzanne null
gltfLoader.load(./suzanne.glb,(gltf) {suzanne gltf.scenesuzanne.traverse((child) {if(child.isMesh)child.material material})scene.add(suzanne)}
)/*** Animate*/
const clock new THREE.Clock()const tick ()
{const elapsedTime clock.getElapsedTime()// Update material.uniforms.uTime.value elapsedTime;// Rotate objectsif(suzanne){suzanne.rotation.x - elapsedTime * 0.1suzanne.rotation.y elapsedTime * 0.2}sphere.rotation.x - elapsedTime * 0.1sphere.rotation.y elapsedTime * 0.2torusKnot.rotation.x - elapsedTime * 0.1torusKnot.rotation.y elapsedTime * 0.2// Update controlscontrols.update()// Renderrenderer.render(scene, camera)// Call tick again on the next framewindow.requestAnimationFrame(tick)
}tick()
4.fragment.glsl 顶点着色器 uniform float uTime;
uniform vec3 uColor;varying vec3 vPosition;
varying vec3 vNormal;/* mod(X, Y)函数返回X对Y取模的结果。如果X和Y都是数组mod函数会对数组的每个元素分别进行取模运算对上一步的结果取模 1.0即计算该值除以 1.0 的余数。由于取模 1.0 的效果是将值限制在 0 到 1 之间不包括1这个操作实际上是在做一个周期性变换使得 vUv.x 在 0 到 10 之间变化时结果会在 0 到 1 之间循环pow(x,y)x的y次方。如果x小于0结果是未定义的。同样如果x0并且y0,结果也是未定义的normalize 标准化向量返回一个方向和x相同但长度为1的向量dot 向量xy之间的点积Fresnel 根据相机角度进行判断相同方向1直角0 相反 1同样法线应该渲染vertex.glsl
*/void main(){// Normal 法线标准值重新定义为1vec3 normal normalize(vNormal); // 两个角度大的法线之间的法线长度不是标准重新初始化1if(!gl_FrontFacing)normal * - 1.0;// Stripes 条纹 float stripes mod((vPosition.y - uTime * 0.02) * 20.0, 1.0);stripes pow(stripes, 3.0);// Fresnel 菲涅尔效果 全息vec3 viewDirection normalize(vPosition - cameraPosition) ; // 模型位置 - 相机位置得到视图位置float fresnel dot(viewDirection,normal) 1.0; // 这里加上一原本的0变成1-1变成0fresnel pow(fresnel,2.0);// Falloff 平滑重映射 想要实现边界处 1-0转变 逐渐消失的效果float falloff smoothstep(0.8,0.0,fresnel);// Holographic 全息float holographic stripes * fresnel;holographic fresnel * 1.25;holographic * falloff;// Final Colorgl_FragColor vec4(uColor,holographic);#include tonemapping_fragment#include colorspace_fragment
}
5.vertex.glsl 片段着色器
uniform float uTime; varying vec3 vPosition;
varying vec3 vNormal;/* smoothstep(edge0, edge1, x) 如果x edge0返回0.0 如果x edge1 返回1.0如果edge0 x edge1则执行0~1之间的平滑埃尔米特差值。如果edge0 edge1结果是未定义的。
*/#include ../includes/random2D.glslvoid main(){// Positionvec4 modelPosition modelMatrix * vec4(position,1.0);// Glitch random2D函数会给我0-1的数据减去0.5 相机的中心位置就不会偏移float glitchTime uTime - modelPosition.y; // 设置故障时间float glitchStrength sin(glitchTime) sin(glitchTime * 3.45) sin(glitchTime * 8.76); // 改变频率glitchStrength / 3.0;glitchStrength smoothstep(0.3,1.0,glitchStrength);glitchStrength * 0.25;modelPosition.x (random2D(modelPosition.xz uTime) - 0.5) * glitchStrength;modelPosition.z (random2D(modelPosition.zx uTime) - 0.5) * glitchStrength;gl_Position projectionMatrix * viewMatrix * modelPosition;// Model normal/* 当第四个值为1.0时向量为“同质”所有3个变换(翻译、旋转、比例)都将被应用。当第四个值为0.0时向量不是“同质的”因此不会应用转换在正常情况下是理想的因为正常不是一个职位而是一个*/vec4 modelNormal modelMatrix * vec4(normal,0.0); // 为什么设置0.0 就是不希望正常保持法线向上vPosition modelPosition.xyz;vNormal modelNormal.xyz;
}
6.random2D.glsl 随机数方法
float random2D(vec2 value)
{return fract(sin(dot(value.xy, vec2(12.9898,78.233))) * 43758.5453123);
} 二、效果 Hologram Shader 总结
全息影像显示可以加到自己个人的项目中。感觉还不错