当前位置: 首页 > news >正文

实现一个漂亮的Three.js 扫光地面 圆形贴图扫光

实现一个漂亮的Three.js 扫光地面 圆形贴图扫光
https://threehub.cn/#/codeMirror?navigation=ThreeJS&classify=shader&id=circleWave
在这里插入图片描述

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from 'dat.gui'const box = document.getElementById('box')const scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(50, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(0, 1, 2)const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)const controls = new OrbitControls(camera, renderer.domElement)controls.enableDamping = truewindow.onresize = () => {renderer.setSize(box.clientWidth, box.clientHeight)camera.aspect = box.clientWidth / box.clientHeightcamera.updateProjectionMatrix()}// 创建平面几何体
const geometry = new THREE.PlaneGeometry(2, 2);const texture = new THREE.TextureLoader().load(`https://file.threehub.cn/` + 'images/channels/wave.png') 
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping// 创建材质
const material = new THREE.ShaderMaterial({side: THREE.DoubleSide,transparent: true,blending: THREE.AdditiveBlending, // 添加混合模式让效果更亮uniforms: {uTime: { value: 0.0 },uScanTex: { value:texture },uScanColor: { value: new THREE.Color(0x00ffff) },    // 主要扫描颜色uScanColorDark: { value: new THREE.Color(0x0088ff) } // 暗部扫描颜色},vertexShader: `varying vec2 vUv;varying vec3 vPosition;void main() {vUv = uv;vPosition = position;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `#define uScanOrigin vec3(0.0, 0.0, 0.0)#define uScanWaveRatio1 3.2#define uScanWaveRatio2 2.8uniform float uTime;uniform sampler2D uScanTex;uniform vec3 uScanColor;uniform vec3 uScanColorDark;varying vec2 vUv;varying vec3 vPosition;float circleWave(vec3 p, vec3 origin, float distRatio) {float t = uTime;float dist = distance(p, origin) * distRatio;float radialMove = fract(dist - t);float fadeOutMask = 1.0 - smoothstep(1.0, 3.0, dist);radialMove *= fadeOutMask;float cutInitialMask = 1.0 - step(t, dist);return radialMove * cutInitialMask;}vec3 getScanColor(vec3 worldPos, vec2 uv, vec3 col) {// 纹理采样float scanMask = texture2D(uScanTex, uv).r;// 波浪效果float cw = circleWave(worldPos, uScanOrigin, uScanWaveRatio1);float cw2 = circleWave(worldPos, uScanOrigin, uScanWaveRatio2);// 扫描遮罩float mask1 = smoothstep(0.3, 0.0, 1.0 - cw);mask1 *= (1.0 + scanMask * 0.7);float mask2 = smoothstep(0.07, 0.0, 1.0 - cw2) * 0.8;mask1 += mask2;float mask3 = smoothstep(0.09, 0.0, 1.0 - cw) * 1.5;mask1 += mask3;// 颜色混合vec3 scanCol = mix(uScanColorDark, uScanColor, mask1);return scanCol * mask1; // 只返回扫描区域的颜色}void main() {vec3 col = vec3(0.0);col = getScanColor(vPosition, vUv * 10.0, col);// 计算alpha通道float alpha = length(col);  // 根据颜色强度计算透明度gl_FragColor = vec4(col, alpha);}`
});// 创建网格并添加到场景
const mesh = new THREE.Mesh(geometry, material);
mesh.rotation.x = Math.PI / 2
scene.add(mesh);// 创建dat.GUI
const gui = new GUI()
const params = {uScanColor: '#00ffff',uScanColorDark: '#0088ff'
}gui.addColor(params, 'uScanColor').onChange((value) => {material.uniforms.uScanColor.value.set(value)
})gui.addColor(params, 'uScanColorDark').onChange((value) => {material.uniforms.uScanColorDark.value.set(value)
})animate()function animate() {requestAnimationFrame(animate)controls.update()renderer.render(scene, camera)material.uniforms.uTime.value += 0.005;}/*** title: Circle Wave* author: Elegant https://z2586300277.github.io/* refer:https://shadertoy-playground.netlify.app/entries/#circle-wave */

相关文章:

  • LeetCode106_从中序与后序遍历序列构造二叉树
  • LeetCode第190题_颠倒二进制位
  • BUUCTF——杂项渗透之神秘的文件
  • 信创生态核心技术栈:国产芯片架构适配详解
  • OpenCV计算机视觉实战(3)——计算机图像处理基础
  • VUE+ElementUI 使用el-input类型type=“number” 时,取消右边的上下箭头
  • Pdf转Word案例(java)
  • Carlink 技术:搭建汽车与手机的智能桥梁
  • react+ts中函数组件父子通信方式
  • React Fiber
  • Canal mysql to mysql 增加 online 库同步配置指南
  • 【基础】Python包管理工具uv使用全教程
  • 13前端项目----购物车修改
  • MySQL初阶:基础增删改查(CRUD)
  • vue3使用轮播图组件swiper
  • 2.Redis高阶实战
  • On the Biology of a Large Language Model——论文学习笔记——拒答和越狱
  • 点分治解析
  • Python __new__ 一个特殊的静态方法
  • 使用Windows+Linux实现mysql的主从复制
  • “浦东时刻”在京展出:沉浸式体验海派风情
  • 竞彩湃|霍芬海姆看到保级曙光,AC米兰专注于意大利杯
  • 蔡达峰:推动食品安全法全面有效实施,为维护人民群众身体健康提供有力法治保障
  • 总奖池超百万!第五届七猫现实题材征文大赛颁奖在即
  • 悬疑推理联合书单|虫神山事件
  • 国家税务总局泰安市税务局:山东泰山啤酒公司欠税超536万元