先上效果吧
shader来源于
https://www.cnblogs.com/eco-just/p/11667713.html ,实现了自定义shader,那么就可以将很多网站上的效果搬过来用了
源代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit|ie-comp|ie-stand">
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
<title>OutlinePass</title>
<style>
#box{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>
</head>
<body>
<div class="ys-absolute-container" id="box" style="overflow: hidden"></div>
</body>
<script src="../../plugins/threeLibrary/three.min.js"></script>
<script src="../../plugins/threeLibrary/js/controls/OrbitControls.js"></script>
<script src="../../plugins/CopyShader.js"></script>
<script src="../../plugins/EffectComposer.js"></script>
<script src="../../plugins/RenderPass.js"></script>
<script src="../../plugins/ShaderPass.js"></script>
<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('#B4D3BA')
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()
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)
const box = new THREE.Mesh(
new THREE.BoxGeometry(1,1,1),
new THREE.MeshBasicMaterial({color:'red'}))
scene.add(box)
//坐标轴辅助
var axes = new THREE.AxesHelper(10); //红x 绿y 蓝z
scene.add(axes);
box.position.set(0,0,0)
let SweepingLightShader = {
uniforms: {
"tDiffuse": {type: "t", value: 0.0},
"time":{type: "f", value: 1.0}
},
vertexShader:`
varying vec2 vUv;
varying vec3 iPosition;
void main(){
vUv = uv;
iPosition = position;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader:`
uniform float time;
uniform sampler2D tDiffuse;
varying vec2 vUv;
varying vec3 iPosition;
void main(){
vec4 texel = texture2D(tDiffuse, vUv);
float x = iPosition.x;
float lighty = x*1.2 + time;
float alpha = abs(iPosition.y - lighty);
if(alpha < 0.1){
float a = 1.0 - alpha / 0.1;
float enda = smoothstep(0.0,1.0,a) + 0.3;
gl_FragColor = texel * enda;
}else{
gl_FragColor = texel * 0.3;
}
}
`
};
// setup effects
var renderPass = new THREE.RenderPass(scene, camera);
var customGrayScale = new THREE.ShaderPass(SweepingLightShader);
customGrayScale.needsUpdate=true
window.customGrayScale=customGrayScale
var effectCopy = new THREE.ShaderPass(THREE.CopyShader);
effectCopy.renderToScreen = true;
var composer = new THREE.EffectComposer(renderer);
composer.addPass(renderPass);
composer.addPass(customGrayScale);
composer.addPass(effectCopy);
var type='add'
function render() {
var time =customGrayScale.uniforms.time.value;
if(time > 2.0){
type = 'reduce'
}else if(time < -2.0){
type = 'add';
}
if(type =='add'){
customGrayScale.uniforms.time.value += 0.01;
}else{
customGrayScale.uniforms.time.value -= 0.01;
}
// console.log(THREE.SweepingLightShader.uniforms[ 'time' ].value)
composer.render()
controls.update(clock.getDelta())
requestAnimationFrame(render)
}
render()
</script>
<!--此脚本与案例无关 可忽略-->
</html>