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

【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相关项目前言 效果噪点图 为了可以自定义能量球的效果&#xff0c;这里使用外部加载来的噪点图做纹理&#xff0c;省去用代码写特效的过程。 主要代码 index.html <…...

【6000字长文】需求评审总是被怼?强烈推荐你试试这三招

前段时间和一个合作部门的产品新人沟通需求,结束的时候,他问了我一个问题,“你在产品新人阶段,最害怕做的事情是什么”? 我不假思索的回答说,“需求评审,是曾经最不想面对的环节,甚至在评审之前几个小时就开始心跳加速了。当然这也是产品修炼路上的必经之路,其实只要掌…...

Hive介绍及DDL

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

Simulink 自动代码生成电机控制:在某国产ARM0定点MCU上实现自动代码生成无感电机控制

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

MySQL基本查询

文章目录表的增删查改Create&#xff08;创建&#xff09;单行数据 全列插入多行数据 指定列插入插入否则更新替换Retrieve&#xff08;读取&#xff09;SELECT列全列查询指定列查询查询字段为表达式查询结果指定别名结果去重WHERE 条件基本比较BETWEEN AND 条件连接OR 条件连…...

你需要知道的 7 个 Vue3 技巧

VNode 钩子在每个组件或html标签上&#xff0c;我们可以使用一些特殊的&#xff08;文档没写的&#xff09;钩子作为事件监听器。这些钩子有&#xff1a;onVnodeBeforeMountonVnodeMountedonVnodeBeforeUpdateonVnodeUpdatedonVnodeBeforeUnmountonVnodeUnmounted我主要是在组件…...

行政区划获取

行政区划获取一、导入jar包二、代码展示背景&#xff1a;公司的行政区划代码有问题&#xff0c;有的没有街道信息&#xff0c;有的关联信息有误&#xff0c;然后找到了国家的网站国家统计局-行政区划&#xff0c;这个里面是包含了所有的行政信息&#xff0c;但是全是html页面&a…...

让ChatGPT介绍一下ChatGPT

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

【Redis】Redis 主从复制 + 读写分离

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

2023届秋招,鬼知道我经历了什么

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

ChatGPT助力校招----面试问题分享(一)

1 ChatGPT每日一题&#xff1a;期望薪资是多少 问题&#xff1a;面试官问期望薪资是多少&#xff0c;如何回答 ChatGPT&#xff1a;当面试官问及期望薪资时&#xff0c;以下是一些建议的回答方法&#xff1a; 1、调查市场行情&#xff1a;在回答之前&#xff0c;可以先调查一…...

CSS媒体查询@media (prefers-color-scheme:dark)判断系统白天黑夜模式

前言 在最近学习中突然看到了在媒体查询中prefers-color-scheme:dark监听的使用&#xff0c;然后就模仿里边写了个简单例子&#xff0c;代码如下&#xff1a; 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&#xff08;我是python3.8也是可以用的&#xff09; environment with PyTorch>1.7.这是ultralyticsCommand Line Interface命令行接口运行输入参数的格式yolo …...

如何在Linux中优雅的使用 head 命令,用来看日志简直溜的不行

当您在 Linux 的命令行上工作时&#xff0c;有时希望快速查看文件的第一行&#xff0c;例如&#xff0c;有个日志文件不断更新&#xff0c;希望每次都查看日志文件的前 10 行。很多朋友使用文本编辑的命令是vim&#xff0c;但还有个命令head也可以让轻松查看文件的第一行。 在…...

Nginx.conf 配置详解

#安全问题&#xff0c;建议用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里的有监督任务的范式&#xff0c;可以归纳成如下的样子。 输入是字词序列&#xff0c;中间一步关键的是语义表征&#xff0c;有了语义表征之后&#xff0c;然后交给下游的模型学习。所以预训练技术的发展&#xff0c;都是在围绕怎么…...

20个Python使用小技巧,建议收藏~

1、易混淆操作 本节对一些 Python 易混淆的操作进行对比。 1.1 有放回随机采样和无放回随机采样 import random random.choices(seq, k1) # 长度为k的list&#xff0c;有放回采样 random.sample(seq, k) # 长度为k的list&#xff0c;无放回采样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&#x1f3e1; 自然语言理解包括一系列不同的任务&#xff0c;例如文本蕴涵、问答、语义相似度评估和文档分类。尽管大量的未标记文本语料库很充足&#xff0c;但用于学习这些特定任务的标记数据却很稀缺&#xff0c;使得判别式训练模型难以达到良好的表现。我们证明&…...

【Vue.js】全局状态管理模式插件vuex

文章目录全局状态管理模式Vuexvuex是什么&#xff1f;什么是“状态管理模式”&#xff1f;vuex的应用场景Vuex安装开始核心概念一、State1、单一状态树2、在 Vue 组件中获得 Vuex 状态3、mapState辅助函数二、Getter三、Mutation1、提交载荷&#xff08;Payload&#xff09;2、…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

32单片机——基本定时器

STM32F103有众多的定时器&#xff0c;其中包括2个基本定时器&#xff08;TIM6和TIM7&#xff09;、4个通用定时器&#xff08;TIM2~TIM5&#xff09;、2个高级控制定时器&#xff08;TIM1和TIM8&#xff09;&#xff0c;这些定时器彼此完全独立&#xff0c;不共享任何资源 1、定…...

Django RBAC项目后端实战 - 03 DRF权限控制实现

项目背景 在上一篇文章中&#xff0c;我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统&#xff0c;为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...

高效的后台管理系统——可进行二次开发

随着互联网技术的迅猛发展&#xff0c;企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心&#xff0c;成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统&#xff0c;它不仅支持跨平台应用&#xff0c;还能提供丰富…...