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;…

EasyExcel相关整理

一、实体类常用注解 1、字段注解ExcelProperty&#xff0c;一般常用value标明表头&#xff0c;index标明列 2、实体类注解&#xff08;导出样式设置&#xff09; 3、导出特殊类型转换 二、导出 1、导出多个sheet 2、导出数据量大导致内存溢出 三、导入 待更新

安装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…

小项目建议用redis替换mq

在简单的、性能要求高的场景下&#xff0c;Redis 可以很好地替代 RabbitMQ&#xff0c;但对于复杂的消息系统需求&#xff0c;RabbitMQ 仍然是更合适的选择。 部署和运维简化 用redis替换mq最大的好处是&#xff1a;部署和运维简化。如果已经在项目中使用 Redis&#xff0c;继…

Linux学习-Ansible(二)

基本配置 #主机清单文件 [rootharbor ansible]# cat hostlist [web] 192.168.29.161 192.168.29.162 [es] 192.168.29.171 192.168.29.172 192.168.29.173 #查看所有被管理的主机 [rootharbor ansible]# ansible all --list-hostshosts (5):192.168.29.161192.168.29.162192.1…

CMS需求文档

CMS需求文档 文章目录 CMS需求文档一、单体(分布式)架构二、技术三、面向用户四、功能列表1.1.用户管理1.2.权限体系1.3.多站点1.4.模板管理1.5.媒体管理(资源库)1.6.内容组织(分类)1.7.内容创作(稿件库)1.8.内容发布1.9.全文检索1.10.内容词汇1.11.性能优化1.12.日志记录1…

华为OD机试真题E卷-计算网络信号(含题目描述+解题思路+代码解析)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 题目描述: 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。注意:网络信号可以绕过阻隔物 array[m][n]的二维数组代表网格地图…

初始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; …

这项新技术让 AI 感知自己的情感——也感知你的情感

今天&#xff0c;位于纽约的新创公司Hume AI推出了一个全新的“共情语音界面”&#xff0c;使得可以在Anthropic、谷歌、Meta、Mistral以及OpenAI的大型语言模型中添加一系列情感表达的声音&#xff0c;以及对情感敏感的耳朵——这预示着一个时代的到来&#xff0c;届时AI助手可…

【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…

nnunetv2系列:2D实例分割数据集转换

nnunetv2系列&#xff1a;自定义2D实例分割数据集转换 这里主要参考官方源文件nnUNet/nnunetv2/dataset_conversion/Dataset120_RoadSegmentation.py&#xff0c;注释了一些不必要的操作。数据集下载链接: massachusetts-roads-dataset 重要提示: nnU-Net只能用于使用无损(或…