3.js - 着色器设置点材质(螺旋星系特效)

上图

在这里插入图片描述



着色器设置点材质时,在顶点着色器中,最好设置gl_PointSize,不然看不到你在页面中添加的点



main.js

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'import gsap from 'gsap'import theVertexShader from './shader/13/vertex.glsl?raw'
import theFragmentShader from './shader/13/fragment.glsl?raw'const scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(75, window.innerHeight / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 5)
camera.aspect = window.innerWidth / window.innerHeight
scene.add(camera)const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)// ---------------------------------------------------------------------------// 加载纹理
const textureLoader = new THREE.TextureLoader()
let texture = textureLoader.load('../public/assets/texture/particles/9.png')
let texture1 = textureLoader.load('../public/assets/texture/particles/10.png')
let texture2 = textureLoader.load('../public/assets/texture/particles/11.png')const params = {count: 1000, // 数量size: 0.1, // 大小radius: 5, // 半径branch: 4, // 分支color: '#ff6030',outColor: '#1b3984'
}let geometry = null
let material = null
let point = null
let galaxyColor = new THREE.Color(params.color)
let outGalaxyColor = new THREE.Color(params.outColor)const generateGalaxy = () => {// 如果已经存在这些顶点,那么先释放内存,在删除顶点数据if (point !== null) {geometry.dispose()material.dispose()scene.remove(point)}geometry = new THREE.BufferGeometry() // 生成顶点const position = new Float32Array(params.count * 3) // 顶点位置const colors = new Float32Array(params.count * 3) // 顶点颜色const imgIndex = new Float32Array(params.count) // 贴图const size_arr = new Float32Array(params.count) // 大小for (let i = 0; i < params.count; i++) {const current = i * 3const branchAngel = (i % params.branch) * ((2 * Math.PI) / params.branch)// 当前点,距离圆心的距离const distance = Math.random() * params.radius// 中心点多,外围的点少const randomX = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5const randomY = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5const randomZ = (Math.pow(Math.random() * 2 - 1, 3) * (params.radius - distance)) / 5position[current] = Math.cos(branchAngel) * distance + randomXposition[current + 1] = 0 + randomYposition[current + 2] = Math.sin(branchAngel) * distance + randomZconst mixColor = galaxyColor.clone()mixColor.lerp(outGalaxyColor, distance / params.radius)// 设置颜色colors[current] = mixColor.rcolors[current + 1] = mixColor.gcolors[current + 2] = mixColor.b// 根据索引值,设置不同的贴图imgIndex[current] = i % 3// 顶点的大小size_arr[current] = Math.random()}geometry.setAttribute('position', new THREE.BufferAttribute(position, 3))geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))geometry.setAttribute('imgIndex', new THREE.BufferAttribute(imgIndex, 1))geometry.setAttribute('asize', new THREE.BufferAttribute(size_arr, 1))//#region 点材质// material = new THREE.PointsMaterial({//   color: new THREE.Color(params.color),//   size: params.size,//   map: texture,//   transparent: true,//   alphaMap: texture,//   depthWrite: false,//   sizeAttenuation: true,//   blending: THREE.AdditiveBlending// })//#endregionmaterial = new THREE.ShaderMaterial({vertexShader: theVertexShader,fragmentShader: theFragmentShader,transparent: true,vertexColors: true,depthWrite: false,blending: THREE.AdditiveBlending,uniforms: {uTime: {value: 0},uTexture: {value: texture},uTexture1: {value: texture1},uTexture2: {value: texture2},uColor: {value: galaxyColor}}})point = new THREE.Points(geometry, material)scene.add(point)
}generateGalaxy()// ---------------------------------------------------------------------------//#regionconst renderer = new THREE.WebGLRenderer()
renderer.shadowMap.enabled = true
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.01const clock = new THREE.Clock()
function animate() {// controls.update()const elapsedTime = clock.getElapsedTime()material.uniforms.uTime.value = elapsedTimerequestAnimationFrame(animate)renderer.render(scene, camera)
}
animate()window.addEventListener('resize', () => {camera.aspect = window.innerWidth / window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth, window.innerHeight)renderer.setPixelRatio(window.devicePixelRatio)
})//#endregion

vertex.glsl

precision lowp float;varying vec2 vUv;attribute float asize;
attribute float imgIndex;
varying float vImgIndex;uniform float uTime;varying vec3 vColor;void main() {vUv = uv;vColor = color;vImgIndex = imgIndex;vec4 modelPosition = modelMatrix*vec4(position, 1.0);`获取顶点的角度注:【atan(y, x)】计算两点之间的角度(以弧度为单位)`float angle = atan(modelPosition.x, modelPosition.z);`获取顶点到中心的距离注:按道理得这么写:【length(vec2(modelPosition.x, modelPosition.z))】如果 modelPosition 是一个三维向量,并且,你只需要 x 和 z 分量,length(modelPosition.xz)这样写也可以`float distanceToCenter = length(modelPosition.xz);`角度偏移angleOffset,是基于,顶点到中心距离的倒数,乘以时间uTime来计算的这种方法会导致:当顶点接近中心时,偏移量变得非常大,导致快速旋转`float angleOffset = 1.0/distanceToCenter*uTime;`当前旋转的度数`angle = angle+angleOffset;// modelPosition.x = cos(angle);// modelPosition.z = sin(angle);modelPosition.x = cos(angle)*distanceToCenter;modelPosition.z = sin(angle)*distanceToCenter;vec4 viewPosition = viewMatrix*modelPosition;// 计算顶点在裁剪空间中的位置,`gl_Position`,是GLSL内置的输出变量,用于存储顶点的最终位置gl_Position = projectionMatrix*viewPosition;// gl_Position = projectionMatrix*viewMatrix*modelPosition;`不设置 gl_PointSize 页面上就啥也没有1、GLSL中,`gl_PointSize`是一个特殊的输出变量,用于,设置点渲染时点的大小,2、以【gl_PointSize = 200.0/-viewPosition.z*asize】为例:涉及,视点空间中,顶点的z坐标(viewPosition.z),和一个属性asize的值`// 根据,顶点的深度(即:离视点的距离)和每个顶点可能具有的不同大小(asize)来动态调整点的大小。gl_PointSize = 200.0/-viewPosition.z*asize;// gl_PointSize = 10.0; // 你可以写死试试
}

fragment.glsl

precision lowp float;uniform sampler2D uTexture;
uniform sampler2D uTexture1;
uniform sampler2D uTexture2;varying float vImgIndex;varying vec3 vColor;void main() {// 方案- 1// gl_FragColor = vec4(gl_PointCoord, 0.0, 1.0);// 方案- 2 - 设置渐变圆// float strength = distance(gl_PointCoord,vec2(0.5));// strength*=2.0;// strength = 1.0-strength;// gl_FragColor = vec4(strength);// 方案- 3 - 圆形点// float strength = 1.0-distance(gl_PointCoord, vec2(0.5));// strength = step(0.5, strength);// gl_FragColor = vec4(strength);// 方案- 4 - 设置贴图// vec4 textureColor = texture2D(uTexture, gl_PointCoord);// gl_FragColor = vec4(textureColor.rgb, textureColor.r);// 方案- 5 - 设置多种贴图vec4 textureColor;if(vImgIndex==0.0) {textureColor = texture2D(uTexture, gl_PointCoord);} else if(vImgIndex==1.0) {textureColor = texture2D(uTexture1, gl_PointCoord);} else {textureColor = texture2D(uTexture2, gl_PointCoord);}gl_FragColor = vec4(vColor, textureColor.r);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/53738.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【截图服务 +打包】pkg打包 puppeteer

目录 最后结论 windows打包成服务 定制executablePath 用程序来查找chrome.exe 代替上面的写配置文件 服务遇到的问题 使用java开一个线程启动 遇到的问题与解决 版本匹配问题 打出包后的运行报错问题 linux下的安装 安装n 库缺少 程序运行后的报错 制作 运行报…

化工机械如何精准地进行网络营销推广?

合作咨询联系竑图 hongtu201988 化工机械行业该如何做网络推广&#xff0c;让销量和利润都有明显的提升呢&#xff1f;湖南竑图网络来为大家分析分析&#xff1a; 一、产品的用户是谁&#xff1f; 在传统行业中&#xff0c;用户群体的多样性不容忽视。比如机械设备有很多种&am…

Java 后端接口入参 - 联合前端VUE 使用AES完成入参出参加密解密

加密效果&#xff1a; 解密后的数据就是正常数据&#xff1a; 后端&#xff1a;使用的是spring-cloud框架&#xff0c;在gateway模块进行操作 <dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>30…

Kamailio-超强dispatcher负载均衡模块

Kamailio 负载均衡的功能主要依靠 Dispatcher 模块完成&#xff0c;模块官方文档参看 为什么要引入负载均衡&#xff1f;如何使用&#xff1f; 引入和配置功能路由调用命令行指令 为什么要引入负载均衡&#xff1f; Q: 如果单台VOIP服务的性能不能满足业务需求了&#xff0…

C++中的I/O流

本节主要看代码理解 I/O流继承关系 iostream 主要类 cin cout cerr clog while&#xff08;cin>>str&#xff09; &#xff5b; //处理 &#xff5d; 当接收ctrl z 或 ctrl c时&#xff0c;会停止&#xff0c; 原理&#xff1a;重载操作符bool&#xff0c;令指定istr…

Meta:大语言模型可以通过自我批判取得大幅提升!

夕小瑶科技说 原创 作者 | 谢年年 论文的审稿模式想必大家都不会陌生&#xff0c;一篇论文除了分配多个评审&#xff0c;最后还将由PC综合评估各位审稿人的reviews撰写meta-review。 最近&#xff0c;来自Meta的研究团队将这一模式引进到大模型的对齐训练中。模型同时扮演 执…

poker (GuanDan)

poker &#xff08;GuanDan&#xff09; 掼蛋 基础比大小规则: ①单牌 2最小与以往不太一样&#xff08;2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 < 10 < J < Q < K < A < Joker&#xff09; 如果本级打9&#xff0c;那么9就比A大&#xff0c;…

安装Anaconda(过程)

Anaconda是一个开源的Python发行版本&#xff0c;用来管理Python相关的包&#xff0c;安装Anaconda可以很方便的切换不同的环境&#xff0c;使用不同的深度学习框架开发项目&#xff0c;本文将详细介绍Anaconda的安装。 一、安装 1、安装方式 官网&#xff1a;“https://www.…

JVM - GC垃圾回收

文章目录 目录 文章目录 1. 自动垃圾回收 1.1 垃圾回收区域 2. 方法区回收 3. 堆回收 3.1 对象已死&#xff1f; 3.1.1 引用计数算法 3.1.2 可达性分析算法 3.1.3 再谈引用 强引用 软引用 弱引用 虚引用 3.2 垃圾收集算法 3.2.1 分代收集理论 3.2.2 垃圾回收算…

FlinkCDC 3.2.0 新增优点 Pattern Replacement in routing rules

新增优点&#xff1a;Pattern Replacement in routing rules flinkcdc 3.2.0版本相较于3.1.0版本&#xff0c;避免了多表多sink多次写 route 路由的麻烦&#xff0c;类似于统一前后缀的形式多表多sink&#xff0c;通过<>正则&#xff0c;大大减少了书写 官网&#xff1…

初始Linux 和 各种常见指令

目录 Linux背景 1. 发展史 Linux发展历史 1.历史 2. 开源 Linux下基本指令 01. ls 指令 02. pwd命令 03. cd 指令 04. touch指令 05.mkdir指令&#xff08;重要&#xff09;&#xff1a; 06.rmdir指令 && rm 指令&#xff08;重要&#xff09;&#xff1a; …

【Vue3】自动化路由配置:Vue3与unplugin-vue-router的完美结合

引言 在Vue3项目中&#xff0c;路由管理是构建复杂应用不可或缺的一部分。传统上&#xff0c;手动编写路由配置既繁琐又容易出错。本文将介绍如何利用unplugin-vue-router插件&#xff0c;实现Vue3项目的自动化路由配置&#xff0c;从而提升开发效率和准确性。 unplugin-vue-…

基于SpringBoot+Vue+MySQL的考研互助交流平台

系统展示 用户前台界面 管理员后台界面 系统背景 本文设计并实现了一个基于SpringBoot、Vue.js和MySQL的考研互助交流平台。该平台旨在为广大考研学子提供一个集资源共享、学习交流、经验分享、心理辅导等功能于一体的综合性在线社区。通过SpringBoot构建高效稳定的后端服务&am…

轻松实现游戏串流,内网穿透

一、部署Gemini Gemini使用教程 二、部署Moonlight 过程大概说一下&#xff0c;网上有太多太多moonlight的东西了 需要运行游戏的机器上安装GFE&#xff08;GeForce Experience&#xff09;&#xff0c;登录并开启GAMESTREAM&#xff08;游戏串流&#xff09;功能 注&…

网络安全 L2 Introduction to Cryptography 密码学

Definitions 1. crypto - hidden/secret grafia - writing 2. “the science and study of secret writing” 3. Cryptography is the science of protecting data, which provides means of converting data into unreadable form, so that 1. the data cannot be ac…

vue + Element UI table动态合并单元格

一、功能需求 1、根据名称相同的合并工作阶段和主要任务合并这两列&#xff0c;但主要任务内容一样&#xff0c;但要考虑主要任务一样&#xff0c;但工作阶段不一样的情况。&#xff08;枞向合并&#xff09; 2、落实情况里的定量内容和定性内容值一样则合并。&#xff08;横向…

9.11 QT ( Day 4)

一、作业 1.Widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> //定时器类 #include <QTime> #include <QtTextToSpeech> //文本转语音类QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEcl…

杨氏矩阵中查找某个数字是否存在(不能使用遍历)

杨氏矩阵&#xff1a; 有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的 如图所示&#xff1a; i为行&#xff0c;j为列 如果要找9&#xff0c;先从arr【0】【2】处开始找&#xff0c;3<9,i,排除第一行&#xff0c;6<9,i,排除第…

上海亚商投顾:沪指探底回升 华为产业链午后爆发

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日探底回升&#xff0c;深成指、创业板指盘中跌逾1%&#xff0c;午后集体拉升翻红。华为产业链午后走强…

B-树底层原理

一、B-树介绍 定义&#xff1a; B-树&#xff08;B-Tree&#xff09;是一种自平衡的树形数据结构&#xff0c;广泛应用于数据库和操作系统中。它的设计目标是减少搜索、顺序访问、插入和删除操作中比较次数和移动次数&#xff0c;特别适合于磁盘中数据的存储和检索。 性质&a…