【Three.js】shader特效 能量盾
shader特效之能量盾
- 前言
- 效果噪点图
- 主要代码
- index.html
- depth-fs.js
- depth-vs.js
- shield-fs.js
- shield-vs.js
- 相关项目
前言
效果噪点图
为了可以自定义能量球的效果,这里使用外部加载来的噪点图做纹理,省去用代码写特效的过程。
主要代码
index.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8" /><title>Energy shield</title><meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" /><style>body {margin: 0;padding: 0;}</style>
</head><body><script type="module">import * as THREE from '../../build/three.module.js'import * as TWEEN from '../../build/tween.esm.js'import Stats from '../jsm/libs/stats.module.js'import { OrbitControls } from '../jsm/controls/OrbitControls.js'import { shader as depthVertexShader } from './shaders/depth-vs.js'import { shader as depthFragmentShader } from './shaders/depth-fs.js'import { shader as shieldVertexShader } from './shaders/shield-vs.js'import { shader as shieldFragmentShader } from './shaders/shield-fs.js'// rendererconst renderer = new THREE.WebGLRenderer({ antialias: true })renderer.setPixelRatio(window.devicePixelRatio)renderer.shadowMap.enabled = truerenderer.shadowMap.type = THREE.PCFSoftShadowMaprenderer.outputEncoding = THREE.sRGBEncodingrenderer.gammaFactor = 2.2document.body.append(renderer.domElement)// statsconst stats = new Stats()document.body.appendChild(stats.domElement)// sceneconst scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 100)camera.position.set(0, 1, 2)// controlconst controls = new OrbitControls(camera, renderer.domElement)controls.minDistance = 0.5controls.maxDistance = 10controls.enableDamping = truecontrols.dampingFactor = 0.05controls.screenSpacePanning = truecontrols.autoRotate = false// cubeconst cubeGeometry = new THREE.BoxBufferGeometry(0.4, 0.4, 0.4)const cubeMaterial = new THREE.MeshStandardMaterial({color: 'rgb(100, 70, 30)',roughness: 0.4,metalness: 0.0,side: THREE.DoubleSide})const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)cube.castShadow = cube.receiveShadow = truecube.position.set(-0.6, 0.2, -0.6)cube.rotation.set(-Math.PI / 2, 0, 0)scene.add(cube)// groundconst groundGeometry = new THREE.PlaneBufferGeometry(3, 3)const groundMaterial = new THREE.MeshStandardMaterial({color: 'rgb(20, 20, 30)',roughness: 0.4,metalness: 0.0,side: THREE.DoubleSide})const ground = new THREE.Mesh(groundGeometry, groundMaterial)ground.castShadow = ground.receiveShadow = trueground.position.set(0, 0, 0)ground.rotation.set(-Math.PI / 2, 0, 0)scene.add(ground)// light1const light = new THREE.DirectionalLight(0xffffff)light.position.set(-2, 2, 0.5)light.castShadow = truelight.shadow.camera.top = 2light.shadow.camera.bottom = -2light.shadow.camera.right = 2light.shadow.camera.left = -2light.shadow.bias = -0.00001light.shadow.mapSize.set(4096, 4096)scene.add(light)// light2const hemiLight = new THREE.HemisphereLight(0xbbbbbb, 0x080808, 1)scene.add(hemiLight)// light1 helperscene.add(new THREE.DirectionalLightHelper(light, 2, 0xFFFF00))// axis helperscene.add(new THREE.AxesHelper(100))const depthMaterial = new THREE.RawShaderMaterial({uniforms: {},vertexShader: depthVertexShader,fragmentShader: depthFragmentShader,})const depth = new THREE.WebGLRenderTarget(1, 1, {wrapS: THREE.ClampToEdgeWrapping,wrapT: THREE.ClampToEdgeWrapping,minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBAFormat,type: THREE.UnsignedByteType,stencilBuffer: false,depthBuffer: true})const hdr = new THREE.WebGLRenderTarget(1, 1, {wrapS: THREE.ClampToEdgeWrapping,wrapT: THREE.ClampToEdgeWrapping,minFilter: THREE.LinearFilter,magFilter: THREE.LinearFilter,format: THREE.RGBAFormat,type: THREE.UnsignedByteType,stencilBuffer: false,depthBuffer: true})// shieldconst textureLoader = new THREE.TextureLoader()const texture = textureLoader.load('./imgs/noise1.png')texture.wrapS = texture.wrapT = THREE.RepeatWrappingconst shieldGeometry = new THREE.SphereBufferGeometry(0.5, 100, 100)const shieldMaterial = new THREE.RawShaderMaterial({uniforms: {depthBuffer: { value: null },resolution: { value: new THREE.Vector2(1, 1) },bufColor: { value: null },u_tex: { value: null },time: { value: 0 }},vertexShader: shieldVertexShader,fragmentShader: shieldFragmentShader,transparent: true,depthWrite: false,side: THREE.DoubleSide})const shield = new THREE.Mesh(shieldGeometry, shieldMaterial)shield.position.set(0, 0.3, 0)shield.material.uniforms.depthBuffer.value = depth.textureshield.material.uniforms.bufColor.value = depth.textureshield.material.uniforms.u_tex.value = texturescene.add(shield)// tweenfunction moveCube() {const tween = new TWEEN.Tween(cube.position)tween.to({x: 0.6,z: 0.6}, 5000)tween.yoyo(true)tween.repeat(Infinity)tween.start()}// resizefunction resize() {const width = window.innerWidthconst height = window.innerHeightconst dPR = window.devicePixelRatiocamera.aspect = width / heightcamera.updateProjectionMatrix()renderer.setSize(width, height)depth.setSize(width * dPR, height * dPR)hdr.setSize(width * dPR, height * dPR)shield.material.uniforms.resolution.value.set(width * dPR, height * dPR)}// renderfunction render() {shield.visible = falsescene.overrideMaterial = depthMaterialrenderer.setRenderTarget(depth)renderer.render(scene, camera)shield.visible = truescene.overrideMaterial = nullrenderer.setRenderTarget(null)renderer.render(scene, camera)renderer.setAnimationLoop(render)TWEEN.update()stats.update()controls.update()shield.material.uniforms.time.value = performance.now()}window.addEventListener('resize', resize)moveCube()resize()render()</script>
</body></html>
depth-fs.js
const shader = `#version 300 esprecision highp float;#include <packing>in vec2 vUv;
in float vDepth;out vec4 color;void main() {float depth = (vDepth - .1) / ( 10.0 -.1);color = packDepthToRGBA(depth);
}
`;export { shader };
depth-vs.js
const shader = `#version 300 esprecision highp float;in vec3 position;
in vec2 uv;uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;out vec2 vUv;
out float vDepth;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);vDepth = gl_Position.z;
}
`;export { shader };
shield-fs.js
const shader = `#version 300 esprecision highp float;#include <packing>uniform sampler2D depthBuffer;
uniform vec2 resolution;
uniform float time;
uniform sampler2D u_tex;in float vRim;
in vec2 vUv;
in float vDepth;out vec4 color;const vec4 baseColor = vec4(0.0,0.9,0.0,0.1);void main() {// 基础色color = baseColor;// 动态纹理vec4 maskA = texture(u_tex, vUv);maskA.a = maskA.r;color += maskA;// 边界高亮vec2 uv = gl_FragCoord.xy / resolution;vec4 packedDepth = texture(depthBuffer, uv);float sceneDepth = unpackRGBAToDepth(packedDepth);float depth = (vDepth - .1) / ( 10.0 -.1);float diff = abs(depth - sceneDepth);float contact = diff * 20.;contact = 1. - contact;contact = max(contact, 0.);contact = pow(contact, 20.);contact *= diff*1000.;float a = max(contact, vRim);float fade = 1. - pow(vRim, 10.);color += a * fade;
}
`;export { shader };
shield-vs.js
const shader = `#version 300 esprecision highp float;in vec3 position;
in vec3 normal;
in vec2 uv;uniform mat3 normalMatrix;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float time;out vec2 vUv;
out float vRim;
out float vDepth;void main() {vUv = uv;vUv.x += time * 0.0001;vUv.y += time * 0.0006;vec3 n = normalMatrix * normal;vec4 viewPosition = modelViewMatrix * vec4( position, 1. );vec3 eye = normalize(-viewPosition.xyz);vRim = 1.0 - abs(dot(eye,n));vRim = pow(vRim, 5.);vec3 worldPosition = (modelMatrix * vec4(position, 1.)).xyz; gl_Position = projectionMatrix * viewPosition;vDepth = gl_Position.z;
}
`;export { shader };
相关项目
🚩——坦克大战
📦—— 立体库房
🎄—— 圣诞树
✅—— 程序员升职记
🏀—— 投个篮吧
💖——粒子爱心
相关文章:

【Three.js】shader特效 能量盾
shader特效之能量盾前言效果噪点图主要代码index.htmldepth-fs.jsdepth-vs.jsshield-fs.jsshield-vs.js相关项目前言 效果噪点图 为了可以自定义能量球的效果,这里使用外部加载来的噪点图做纹理,省去用代码写特效的过程。 主要代码 index.html <…...
【6000字长文】需求评审总是被怼?强烈推荐你试试这三招
前段时间和一个合作部门的产品新人沟通需求,结束的时候,他问了我一个问题,“你在产品新人阶段,最害怕做的事情是什么”? 我不假思索的回答说,“需求评审,是曾经最不想面对的环节,甚至在评审之前几个小时就开始心跳加速了。当然这也是产品修炼路上的必经之路,其实只要掌…...

Hive介绍及DDL
1.OLTP和OLAP OLTP: 联机事务处理系统。在前台接收的用户数据可以立即传送到后台进行处理,并在很短的时间内给出处理结果。关系型数据库是OLTP典型应用,如MySQL OLTP环境开展数据分析是否可行? 为了更好的开展数据分析&#x…...

Simulink 自动代码生成电机控制:在某国产ARM0定点MCU上实现自动代码生成无感电机控制
目录 前言 开发流程 定点化的技巧 代码生成运行演示 总结 前言 这次尝试了在国产arm0内核的MCU上实现Simulink自动代码生成永磁同步电机无传感控制。机缘巧合之下拿到了一块国产MCU的电机控制板和一个5000RPM的小电机。最后实现了无传感控制,在这里总结下一些经…...

MySQL基本查询
文章目录表的增删查改Create(创建)单行数据 全列插入多行数据 指定列插入插入否则更新替换Retrieve(读取)SELECT列全列查询指定列查询查询字段为表达式查询结果指定别名结果去重WHERE 条件基本比较BETWEEN AND 条件连接OR 条件连…...
你需要知道的 7 个 Vue3 技巧
VNode 钩子在每个组件或html标签上,我们可以使用一些特殊的(文档没写的)钩子作为事件监听器。这些钩子有:onVnodeBeforeMountonVnodeMountedonVnodeBeforeUpdateonVnodeUpdatedonVnodeBeforeUnmountonVnodeUnmounted我主要是在组件…...
行政区划获取
行政区划获取一、导入jar包二、代码展示背景:公司的行政区划代码有问题,有的没有街道信息,有的关联信息有误,然后找到了国家的网站国家统计局-行政区划,这个里面是包含了所有的行政信息,但是全是html页面&a…...

让ChatGPT介绍一下ChatGPT
申请新必应内测通过了,我在New Bing中使用下ChatGPT,让ChatGPT介绍一下ChatGPT 问题1:帮我生成一篇介绍chatGPT的文章,不少于2000字 回答: chatGPT是什么?它有什么特点和用途? chatGPT是一种…...

【Redis】Redis 主从复制 + 读写分离
Redis 主从复制 读写分离1. Redis 主从复制 读写分离介绍1.1 从数据持久化到服务高可用1.2 主从复制1.3 如何保证主从数据一致性?1.4 为何采用读写分离模式?2. 一主两从环境准备2.1 配置文件2.2 启动 Redis3. 主从复制原理3.1 全量同步3.1.1 建立连接3…...

2023届秋招,鬼知道我经历了什么
仅记录个人经历,充满主观感受,甚至纯属虚构,仅供参考,杠就是你对 本想毕业再写,但是考虑到等毕业了,24秋招的提前批就快开始了,大概就来不及了,正好现在有点时间,陆陆续…...

ChatGPT助力校招----面试问题分享(一)
1 ChatGPT每日一题:期望薪资是多少 问题:面试官问期望薪资是多少,如何回答 ChatGPT:当面试官问及期望薪资时,以下是一些建议的回答方法: 1、调查市场行情:在回答之前,可以先调查一…...

CSS媒体查询@media (prefers-color-scheme:dark)判断系统白天黑夜模式
前言 在最近学习中突然看到了在媒体查询中prefers-color-scheme:dark监听的使用,然后就模仿里边写了个简单例子,代码如下: body {background-color: #f5f5f5;}media (prefers-color-scheme: dark) {body {background-color: #666;}}然后通过…...

运行YOLOv8实现识别
https://github.com/ultralytics/ultralyticshttps://docs.ultralytics.com/环境配置官方环境要求Python>3.7(我是python3.8也是可以用的) environment with PyTorch>1.7.这是ultralyticsCommand Line Interface命令行接口运行输入参数的格式yolo …...

如何在Linux中优雅的使用 head 命令,用来看日志简直溜的不行
当您在 Linux 的命令行上工作时,有时希望快速查看文件的第一行,例如,有个日志文件不断更新,希望每次都查看日志文件的前 10 行。很多朋友使用文本编辑的命令是vim,但还有个命令head也可以让轻松查看文件的第一行。 在…...
Nginx.conf 配置详解
#安全问题,建议用nobody,不要用root. #user nobody; #worker数和服务器的cpu数相等是最为适宜 worker_processes 2; #work绑定cpu(4 work绑定4cpu) worker_cpu_affinity 0001 0010 0100 1000 #error_log path(存放路径) level(日志等级) path表示日志路径&…...

剖析NLP历史,看chatGPT的发展
1、NLP历史演进 1.1 NLP有监督范式 NLP里的有监督任务的范式,可以归纳成如下的样子。 输入是字词序列,中间一步关键的是语义表征,有了语义表征之后,然后交给下游的模型学习。所以预训练技术的发展,都是在围绕怎么…...
20个Python使用小技巧,建议收藏~
1、易混淆操作 本节对一些 Python 易混淆的操作进行对比。 1.1 有放回随机采样和无放回随机采样 import random random.choices(seq, k1) # 长度为k的list,有放回采样 random.sample(seq, k) # 长度为k的list,无放回采样1.2 lambda 函数的参数 …...
Kafka 主题管理
Kafka 主题管理创建主题查看主题修改主题内部主题异常主题删除失败创建主题 创建 Kafka 主题 create : 创建主题partitions : 主题的分区数replication-factor : 每个分区下的副本数 bin/kafka-topics.sh \ --bootstrap-server broker_host:port \ --create --topic my_topi…...

【深度学习】GPT系列模型:语言理解能力的革新
GPT-1🏡 自然语言理解包括一系列不同的任务,例如文本蕴涵、问答、语义相似度评估和文档分类。尽管大量的未标记文本语料库很充足,但用于学习这些特定任务的标记数据却很稀缺,使得判别式训练模型难以达到良好的表现。我们证明&…...
【Vue.js】全局状态管理模式插件vuex
文章目录全局状态管理模式Vuexvuex是什么?什么是“状态管理模式”?vuex的应用场景Vuex安装开始核心概念一、State1、单一状态树2、在 Vue 组件中获得 Vuex 状态3、mapState辅助函数二、Getter三、Mutation1、提交载荷(Payload)2、…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...