【Three.js基础学习】26. Animated galaxy

前言

shaders实现星系

    课程回顾

        使用顶点着色器为每个粒子设置动画

        a属性 , u制服 ,v变化

        像素比:window.devicePixelRatio

        自动从渲染器检索像素比

            renderer.getPixelRatio()

        如何尺寸衰减, 放大缩小视角时,粒子都是同样大小的问题

        gl_Position += (1.0 / - viewPosition);

  

下面是实现的数学解释


一、代码

这个我听的迷迷糊糊的,直接看代码中的注释吧

1.script.js

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import * as dat from 'lil-gui'
import galaxyVertexShader from './shaders/galaxy/vertex.glsl'
import galaxyFragmentShader from './shaders/galaxy/fragment.glsl'/*** Base*/
// Debug
const gui = new dat.GUI()// Canvas
const canvas = document.querySelector('canvas.webgl')// Scene
const scene = new THREE.Scene()/*** Galaxy*/
const parameters = {}
parameters.count = 200000
parameters.size = 0.005
parameters.radius = 6
parameters.branches = 3
parameters.spin = 1
parameters.randomness = 0.2
parameters.randomnessPower = 3
parameters.insideColor = '#ff6030'
parameters.outsideColor = '#1b3984'let geometry = null
let material = null
let points = nullconst generateGalaxy = () =>
{if(points !== null) // 制空{geometry.dispose()material.dispose()scene.remove(points)}/*** Geometry*/geometry = new THREE.BufferGeometry()// 这里为什么*3 因为要向各个方向发展,为什么*1只是在一个方向上拉伸const positions = new Float32Array(parameters.count * 3)const randomness = new Float32Array(parameters.count * 3)const colors = new Float32Array(parameters.count * 3)const scales = new Float32Array(parameters.count * 1)const insideColor = new THREE.Color(parameters.insideColor)const outsideColor = new THREE.Color(parameters.outsideColor)for(let i = 0; i < parameters.count; i++){const i3 = i * 3// Positionconst radius = Math.random() * parameters.radiusconst branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2/*长时间就会发现星系在变薄,像一条丝带 ,应该避免下面代码 创建一个新的Float32Array并且在旋转后使用该属性 不应该在旋转之前添加应用随机性randomZXY*/const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1)  * parameters.randomness * radiusconst randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1)  * parameters.randomness * radiusconst randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : - 1)  * parameters.randomness * radius// 旋转 将数据填充到位置上positions[i3    ] = Math.cos(branchAngle) * radiuspositions[i3 + 1] = 0.0positions[i3 + 2] = Math.sin(branchAngle) * radiusrandomness[i3    ] = randomXrandomness[i3 + 1] = randomYrandomness[i3 + 2] = randomZ// Colorconst mixedColor = insideColor.clone()mixedColor.lerp(outsideColor, radius / parameters.radius)colors[i3    ] = mixedColor.rcolors[i3 + 1] = mixedColor.gcolors[i3 + 2] = mixedColor.b// Scalescales[i] = Math.random()}geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3))geometry.setAttribute('aRandomness', new THREE.BufferAttribute(randomness, 3))geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3))geometry.setAttribute('aScale', new THREE.BufferAttribute(scales, 1))/*** Material*/material = new THREE.ShaderMaterial({depthWrite: false,blending: THREE.AdditiveBlending,vertexColors: true,uniforms:{uTime: { value: 0 },uSize: { value: 30 * renderer.getPixelRatio() }  // 星系顶点尺寸*像素比},    vertexShader: galaxyVertexShader,fragmentShader: galaxyFragmentShader})/*** Points*/points = new THREE.Points(geometry, material)scene.add(points)
}gui.add(parameters, 'count').min(100).max(1000000).step(100).onFinishChange(generateGalaxy).name('数量')
gui.add(parameters, 'radius').min(0.01).max(20).step(0.01).onFinishChange(generateGalaxy).name('半径')
gui.add(parameters, 'branches').min(2).max(20).step(1).onFinishChange(generateGalaxy).name('条数')
gui.add(parameters, 'randomness').min(0).max(2).step(0.001).onFinishChange(generateGalaxy).name('随机')
gui.add(parameters, 'randomnessPower').min(1).max(10).step(0.001).onFinishChange(generateGalaxy).name('随机功率')
gui.addColor(parameters, 'insideColor').onFinishChange(generateGalaxy).name('内部颜色')
gui.addColor(parameters, 'outsideColor').onFinishChange(generateGalaxy).name('外部颜色')/*** Sizes*/
const sizes = {width: window.innerWidth,height: window.innerHeight
}window.addEventListener('resize', () =>
{// Update sizessizes.width = window.innerWidthsizes.height = window.innerHeight// Update cameracamera.aspect = sizes.width / sizes.heightcamera.updateProjectionMatrix()// Update rendererrenderer.setSize(sizes.width, sizes.height)renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
})/*** Camera*/
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
camera.position.x = 3
camera.position.y = 3
camera.position.z = 3
scene.add(camera)// Controls
const controls = new OrbitControls(camera, canvas)
controls.enableDamping = true/*** Renderer*/
const renderer = new THREE.WebGLRenderer({canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))/*** Generate the first galaxy*/
generateGalaxy()/*** Animate*/
const clock = new THREE.Clock()const tick = () =>
{const elapsedTime = clock.getElapsedTime()// Update materialmaterial.uniforms.uTime.value = elapsedTime// Update controlscontrols.update()// Renderrenderer.render(scene, camera)// Call tick again on the next framewindow.requestAnimationFrame(tick)
}tick()

2. 顶点着色器

uniform float uTime;
uniform float uSize;attribute vec3 aRandomness;
attribute float aScale;varying vec3 vColor;/* atan(x) 弧度 反正切函数
*/void main()
{/*** Position*/vec4 modelPosition = modelMatrix * vec4(position, 1.0);// Rotatefloat angle = atan(modelPosition.x, modelPosition.z); // 获取角度 偏移的float distanceToCenter = length(modelPosition.xz); // 到中心的距离float angleOffset = (1.0 / distanceToCenter) * uTime ; // 根据时间应该旋转多少度angle += angleOffset; // 更新角度 并且 角度加上角度偏移modelPosition.x = cos(angle) * distanceToCenter; // 更新到模型上,同时乘以到中心的距离modelPosition.z = sin(angle) * distanceToCenter;// Randomness 随机modelPosition.xyz += aRandomness;vec4 viewPosition = viewMatrix * modelPosition;vec4 projectedPosition = projectionMatrix * viewPosition;gl_Position = projectedPosition;/*** Size*/gl_PointSize = uSize * aScale;gl_PointSize *= (1.0 / - viewPosition.z);/*** Color*/vColor = color;
}

3.片段着色器

varying vec3 vColor;void main()
{// // Disc// float strength = distance(gl_PointCoord, vec2(0.5));// strength = step(0.5, strength);// strength = 1.0 - strength;// // Diffuse point// float strength = distance(gl_PointCoord, vec2(0.5));// strength *= 2.0;// strength = 1.0 - strength;// Light pointfloat strength = distance(gl_PointCoord, vec2(0.5));strength = 1.0 - strength;strength = pow(strength, 10.0);// Final colorvec3 color = mix(vec3(0.0), vColor, strength);gl_FragColor = vec4(color, 1.0);
}

二、效果

shaders - 星系


总结

今天学的迷迷糊糊的,整体代码知道看得懂,思路,如何偏移以及一些数学计算很蒙!

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于Springboot + Vue的旧物置换网站管理系统(源码+lw+部署讲解+PPT)

前言 详细视频演示 论文参考 系统介绍 系统概述 核心功能 具体实现截图 1. 首页功能 2. 旧物信息功能 3. 网站公告功能 4. 用户管理功能&#xff08;管理员端&#xff09; 5. 置换交易管理功能 技术栈 后端框架SpringBoot 前端框架Vue 持久层框架MyBatis-Plus …

新书速览|循序渐进Spark大数据应用开发

《循序渐进Spark大数据应用开发》 本书内容 《循序渐进Spark大数据应用开发》结合作者一线开发实践&#xff0c;循序渐进地介绍了新版Apache Spark 3.x的开发技术。全书共10章&#xff0c;第1章和第2章主要介绍Spark的基本概念、安装&#xff0c;并演示如何编写最简单的Spark程…

一道算法期末应用题及解答

1&#xff0e;印刷电路板布线区划分成为n m 个方格&#xff0c;确定连接方格a 到方格b 的最短布线方案。 在布线时&#xff0c;只能沿直线或者直角布线&#xff0c;为避免交叉&#xff0c;已经布线的方格做了封锁标记&#xff0c;其他线路不允许穿过被封锁的方格&#xff0c;某…

2024内科学综合类科技核心期刊汇总

在已经公布的中国科技核心期刊目录&#xff08;2024年版&#xff09;中&#xff0c;5本内科学综合类期刊入选。常笑医学整理了这5本科技核心期刊的详细参数&#xff0c;以及投稿信息&#xff0c;供大家在论文投稿时参考&#xff0c;有需要的赶紧收藏&#xff01; 1.《临床内科…

【网络】Socket编程TCP/UDP序列化和反序列化理解应用层(C++实现)Json::Value

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;计算机网络原理_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.基于Socket的UDP和TCP编程介绍 1.1 基本TCP客户—服务器程序设计基本框架 ​编辑1.2 基本UDP客户—服务器程序设计基本框…

Spring MVC——针对实习面试

目录 Spring MVC什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f;Spring MVC的优点有哪些&#xff1f;Spring MVC的主要组件有哪些&#xff1f;Spring MVC的工作原理或流程是怎样的&#xff1f;Spring MVC常用注解有哪些&#xff1f; Spring MVC 什么是…

硬件工程师之电子元器件—二极管(10)之可变电容和TVS二极管

写在前面 本系列文章主要讲解二极管的相关知识&#xff0c;希望能帮助更多的同学认识和了解二极管。 若有相关问题&#xff0c;欢迎评论沟通&#xff0c;共同进步。(*^▽^*) 二极管 25. 齐纳二极管的动态阻抗 齐纳阻抗是齐纳二极管在传导电流时的等效串联电阻&#xff08;E…

2024-11-19 树与二叉树

一、树的定义和基本语术 1.基本概念&#xff1a;从根节点出发&#xff0c;依次长出各个分支&#xff0c;各个分支也能长出下级分支。&#xff08;根节点无前驱&#xff0c;叶无后继&#xff09;除根节点外&#xff0c;任何一个结点有且仅有一个前驱。 2.树的基本概念&#xff…

【金融风控项目-08】:特征构造

文章目录 1.数据准备1.1 风控建模特征数据1.2 人行征信数据1.3 据之间的内在逻辑 2 样本设计和特征框架2.1 定义观察期样本2.2 数据EDA(Explore Data Analysis)2.3 梳理特征框架 3 特征构造3.1 静态信息和时间截面特征3.2 未来信息问题3.2.1 未来信息案例3.2.2 时间序列特征的未…

docker基础

一 docker整体架构 docker镜像&#xff08;image&#xff09; docker hub类似于maven远程仓库地址&#xff1a; https://hub.docker.com/ 该地址用于搜索并下载地址。 镜像下载命令&#xff1a; docker pull imagename 比如&#xff1a;docker pull to…

Qt 元对象系统

Qt 元对象系统 Qt 元对象系统1. 元对象的概念2. 元对象系统的核心组件2.1 QObject2.2 Q_OBJECT 宏2.3 Meta-Object Compiler (MOC) 3. 信号与槽3.1 基本概念信号与槽的本质信号和槽的关键特征 3.2 绑定信号与槽参数解析断开连接 3.3 标准信号与槽查找标准信号与槽使用示例规则与…

Lua如何连接MySQL数据库?

大家好&#xff0c;我是袁庭新。使用Lua语言如何来连接数据库呢&#xff1f;新哥这篇文章给你安排上。 1 LuaSQL概述 LuaSQL是一个轻量级的Lua到数据库管理系统&#xff08;DBMS&#xff09;的接口库&#xff0c;由Kepler Project维护&#xff0c;且是开源的。它提供了一个简…

高级指南:全面解析线上服务器CPU占用过高问题及其解决方案

文章目录 拿到CPU占用高的进程ID通过进程ID拿到CPU占用高的线程ID将线程ID转换为十六进制jstack分析线程栈信息 CPU占用过高的时候要先找出到底是哪个进程下的线程占用内存过高了。 我在线上预先写了一个Java程序&#xff0c;Test.java用于本篇文章实验所用。模拟CPU占用过高时…

单片机智能家居火灾环境安全检测-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 传统的火灾报警系统大多依赖于简单的烟雾探测器或温度传感器&#xff0c;…

打造网页版Ubuntu环境:群晖NAS部署docker-webtop与远程访问指南

文章目录 前言1. 下载Docker-Webtop镜像2. 运行Docker-Webtop镜像3. 本地访问网页版Linux系统4. 群晖NAS安装Cpolar工具5. 配置异地访问Linux系统6. 异地远程访问Linux系统7. 固定异地访问的公网地址 前言 本文旨在详细介绍如何在群晖NAS部署docker-webtop&#xff0c;并结合c…

Python轴承故障诊断 (19)基于Transformer-BiLSTM的创新诊断模型

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Pytorch-LSTM轴承故障一维信号分类(一)-CSDN博客 Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客 Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客 三十多个开源…

STM32设计学生宿舍监测控制系统-分享

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 本项目旨在利用STM32单片机为核心&#xff0c;结合传感器技术、无线通信技…

英伟达 Isaac Sim仿真平台体验

一、产品名称及版本 Isaac Sim 是由 NVIDIA 开发的一款基于物理模拟的机器人仿真平台&#xff0c;旨在为机器人开发者和研究人员提供一个高效、真实的仿真环境。Isaac Sim 基于 NVIDIA 的 Omniverse 平台&#xff0c;结合了强大的图形渲染、物理引擎和深度学习能力&#xff0c;…

利用寄存器方式,点亮led3最小板

作业:利用寄存器方式,点亮led3小灯 1.通过观察原理图, led3, 是PA8, 一段接3.3v, 一端接io口, 所以PA8端口输出低电平, 就可以让小灯点亮了 2.利用keil创建最小工程 点击跳转博客 3.按照库函数的配置方式 #include "stdint.h" #include "stm32f10x.h" …

Helius:从数据出发,衡量 Solana 的真实去中心化程度

撰文&#xff1a;Lostin&#xff0c;Helius 编译&#xff1a;Yangz&#xff0c;Techub News 摘要 截至 Epoch 685&#xff0c;Solana 有 4514 个节点&#xff0c;包括 1414 个验证者和 3100 个 RPC。没有哪个验证者控制的质押份额超过 3.2%。 中本聪系数&#xff08;NC&#…