【Three.js基础学习】14.Galaxy Generator

news2024/9/22 11:38:47

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

  课程知识点

        1. 实现星际编辑器

        2. 创建粒子 1000, 在随机位置

        3. 创建材质 PointsMaterial

        4. Points() 接收

        5. 放到gui 中调试  但是会发现调整size 等 属性 页面无变化

            因此有两种方法 onChange() onFinishChange()

        这个时候更改就会 将参数传到 generateGalaxy

        同样有问题 增加可以 ,因为在数值增加 不断生成新的星系

        数值缩小时候,但是没有消减

        因此要在函数外部 创建geometry,position,material 这些变量

        判断是否和之前相等 ,不相等则 dispose()  清除几何体缓存,材质缓存同时

        删除这些点 scene.remove(points)

        // 实现漩涡星系 思路

        首先将所有粒子 放到一条直线上 ,x  position[i3 + 0] = Math.random() * parameters.radius

        要实现分支  %  取余操作

        这样在循环中 就可以得到 branchAngle=0,1,2,0,1,2,0,1,2,0,1,2,

                        对应的       i    =0,1,2,3,4,5,6,7,8,9

        下面主要是数学的应用 通过更改数值 实现星系

一、代码

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import * as lil from 'lil-gui'
import { AdditiveBlending } from 'three'

/* 
    课程知识点
        1. 实现星际编辑器
        2. 创建粒子 1000, 在随机位置
        3. 创建材质 PointsMaterial
        4. Points() 接收
        5. 放到gui 中调试  但是会发现调整size 等 属性 页面无变化
            因此有两种方法 onChange() onFinishChange()
        这个时候更改就会 将参数传到 generateGalaxy
        同样有问题 增加可以 ,因为在数值增加 不断生成新的星系
        数值缩小时候,但是没有消减

        因此要在函数外部 创建geometry,position,material 这些变量
        判断是否和之前相等 ,不相等则 dispose()  清除几何体缓存,材质缓存同时
        删除这些点 scene.remove(points)

        // 实现漩涡星系 思路
        首先将所有粒子 放到一条直线上 ,x  position[i3 + 0] = Math.random() * parameters.radius

        要实现分支  %  取余操作
        这样在循环中 就可以得到 branchAngle=0,1,2,0,1,2,0,1,2,0,1,2,
                        对应的       i    =0,1,2,3,4,5,6,7,8,9

        下面主要是数学的应用 通过更改数值 实现星系
*/

/**
 * Base
 */
// Debug
const gui = new lil.GUI()

// Canvas
const canvas = document.querySelector('canvas.webgl')

// Scene
const scene = new THREE.Scene()

/* 
* Galaxy 星系 Generator 编辑器
*/
const parameters = {}
parameters.count = 100000
parameters.size = 0.01
parameters.color = '#ffffff'
parameters.radius = 5 // 半径
parameters.branches = 3 // 分支
parameters.spin = 1 // 旋转
parameters.randomness = 0.2 // 随机值
parameters.randomnessPower = 3 // 
parameters.insideColor = '#ff6030' // 
parameters.outsideColor = '#1b3984' 

let geometry = null
let points = null
let material = null
const generateGalaxy = () =>{
    /* 
    * Destroy old galaxy
    */
   if(points !== null){
    geometry.dispose()
    material.dispose()
    scene.remove(points)
   }

    // Geometry
    geometry = new THREE.BufferGeometry()
    // 创建粒子 位置参数
    const position = new Float32Array(parameters.count * 3)
    const colors = new Float32Array(parameters.count * 3)

    const colorInside = new THREE.Color(parameters.insideColor)
    const colorOutside = new THREE.Color(parameters.outsideColor)


    // 设置随机位置
    for(let i=0;i<parameters.count;i++){
        const i3 = i * 3
        // position
        const radius = Math.random() * parameters.radius
        const sponAngle = radius * parameters.spin
        const branchAngle = (i % parameters.branches) / parameters.branches * Math.PI * 2

        const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
        const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)
        const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1)

        position[i3 + 0] = Math.cos(branchAngle + sponAngle) * radius + randomX
        position[i3 + 1] = randomY
        position[i3 + 2] = Math.sin(branchAngle + sponAngle) * radius + randomZ


        // position[i3 + 0] = (Math.random() - 0.5) * 10  // x位置
        // position[i3 + 1] = (Math.random() - 0.5) * 10  // y
        // position[i3 + 2] = (Math.random() - 0.5) * 10  // z

        // color
        const mixedColor = colorInside.clone()
        mixedColor.lerp(colorOutside,radius/parameters.radius)
        colors[i3 + 0] = mixedColor.r
        colors[i3 + 1] = mixedColor.g
        colors[i3 + 2] = mixedColor.b
    }
    geometry.setAttribute(
        'position',
        new THREE.BufferAttribute(position,3)
    )
    geometry.setAttribute(
        'color',
        new THREE.BufferAttribute(colors,3)
    )

    // Material
    material = new THREE.PointsMaterial({
        // color:parameters.color,
        size:parameters.size,
        sizeAttenuation:true, // 衰减
        depthWrite:false, // 深度缓冲区
        blending: THREE.AdditiveBlending,
        vertexColors:true
    })
    // material.vertexColors = true
    
    /* 
    *   Points
    */
    points = new THREE.Points(
        geometry,
        material
    )
    scene.add(points)
}
gui.add(parameters, 'count').min(100).max(100000).step(100).onFinishChange(generateGalaxy)
gui.add(parameters, 'size').min(0.001).max(1).step(0.001).onFinishChange(generateGalaxy)
gui.add(parameters, 'radius').min(0.01).max(20).step(0.01).onFinishChange(generateGalaxy)
gui.add(parameters, 'branches').min(2).max(20).step(1).onFinishChange(generateGalaxy)
gui.add(parameters, 'spin').min(-5).max(5).step(0.001).onFinishChange(generateGalaxy)
gui.add(parameters, 'randomness').min(0).max(2).step(0.001).onFinishChange(generateGalaxy)
gui.add(parameters, 'randomnessPower').min(1).max(10).step(0.001).onFinishChange(generateGalaxy)
gui.addColor(parameters, 'insideColor').onFinishChange(generateGalaxy)
gui.addColor(parameters, 'outsideColor').onFinishChange(generateGalaxy)

generateGalaxy()

/**
 * Sizes
 */
const sizes = {
    width: window.innerWidth,
    height: window.innerHeight
}

window.addEventListener('resize', () =>
{
    // Update sizes
    sizes.width = window.innerWidth
    sizes.height = window.innerHeight

    // Update camera
    camera.aspect = sizes.width / sizes.height
    camera.updateProjectionMatrix()

    // Update renderer
    renderer.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))

/**
 * Animate
 */
const clock = new THREE.Clock()

const tick = () =>
{
    const elapsedTime = clock.getElapsedTime()

    // Update controls
    controls.update()

    // Render
    renderer.render(scene, camera)

    // Call tick again on the next frame
    window.requestAnimationFrame(tick)
}

tick()

二、知识点

1.思路图

2.效果


总结

五一前看的,全被自己吃进肚子里了,想想怎么实现的一头雾水!还是要看之前代码,很烦...

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

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

相关文章

4.任务创建和删除的API函数

一、简介 二、动态创建任务函数:xTaskCreate() 此函数用于使用动态的方式创建任务&#xff0c;任务的任务控制块以及任务的栈空间所需的内存&#xff0c;均由 FreeRTOS 从 FreeRTOS 管理的堆中分配&#xff0c;若使用此函数&#xff0c;需要在 FreeRTOSConfig.h 文件 中将宏 c…

5.6 qt day1

自由创建一个登录页面 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//设置窗口this->setWindowTitle("");//设置窗口图标this->setWindowIcon(QIcon("C:\\Users\\14123\\Desktop\\b3119313b07eca80842876219…

【go项目01_学习记录05】

学习记录 1 依赖管理 Go Modules1.1 弃用 $GOPATH1.2 Go Modules 日常使用1.2.1 初始化生成go.mod文件1.2.2 Go Proxy代理1.2.3 go.mod文件查看1.2.4 go.sum文件查看1.2.5 indirect 含义1.2.6 go mod tidy 命令1.2.7 清空 Go Modules 缓存1.2.8 下载依赖1.2.9 所有 Go Modules …

知到java笔记(4.1--继承的用法以及this和super的用法)

格式&#xff1a; 例子&#xff1a; get set获取父类的私有变量 private属性 this和super区别&#xff1a; this用法 super用法 例子

从固定到可变:利用Deformable Attention提升模型能力

1. 引言 本文将深入探讨注意力机制的内部细节&#xff0c;这是了解机器如何选择和处理信息的基础。但这还不是全部&#xff0c;我们还将探讨可变形注意力的创新理念&#xff0c;这是一种将适应性放在首位的动态方法。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 注…

重学java 29.经典接口

光阴似箭&#xff0c;我好像跟不上 —— 24.5.6 一、java.lang.Comparable 我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话&#xff0c;直接使用比较运算符即可&#xff0c;但是引用数据类型是不能直接使用比较运算符来比较大小的。那么&#xff0c;如何解决这个…

linux部署java1.8(jdk1.8)

两种方式&#xff1a; 方式一 1.输入查找命令&#xff1a; yum -y list java*2.输入安装命令&#xff1a; yum install -y java-1.8.0-openjdk.x86_643.测试是否已经安装&#xff1a; java -version方式二&#xff1a; 点击链接进入官网&#xff1a;https://www.oracle.com/…

【教程】极简Python接入免费语音识别API

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;请不吝给个[点赞、收藏、关注]哦~ 安装库&#xff1a; pip install SpeechRecognition 使用方法&#xff1a; import speech_recognition as srr sr.Recognizer() harvard sr…

idea2023.2.5的控制台动态配置当前环境

一、idea2023.2.5的控制台动态配置当前环境 1.1、idea版本 1.2、配置方式 1.2.1、方式一 1.2.2、方式二 1.3、参考 https://blog.csdn.net/xiaoheihai666/article/details/127757658

使用idea编辑器回退git已经push的代码

直接上结果 选择想要回退的那次/多次提交历史, 右击, 选中 revert commit git自动产生一个Revert记录&#xff0c;然后我们会看到git自动将我第三次错误提交代码回退了&#xff0c;这个其实就相当于git帮我们手动回退了代码。 后续&#xff0c;只需要我们将本次改动push到远…

从零开始的软件测试学习之旅(五)web测试项目

这里写目录标题 功能型测试非功能性测试面试拓展项目与数据库关系 测试用例设计—基于TPshop前台下单流程 功能型测试 一.设计测试 a,需求分析 1.输入分析 分析项目中要求如:输入长度,类型要求,组成规则,是否为空,是否重复 2.交付分析 判断所有数据正确,有错误给出提示(优化…

锂电池SOH估计 | Matlab实现基于ALO-SVR模型的锂电池SOH估计

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 锂电池SOH估计 | Matlab实现基于ALO-SVR模型的锂电池SOH估计 蚁狮优化支持向量机锂电池健康状态SOH估计&#xff1b; 具体流程如下&#xff1b; 1、分析锂离子电池老化数据集&#xff0c;从中选取具有代表电池性能衰减…

2024第2届华东国际宠物用品展(苏州)

第2届华东宠物展&#xff08;苏州&#xff09;2024.06.28-30 苏州国际博览中心 中国宠业新锐品牌展 400海外展商 20000平方展出面积 3000知名品牌 60000优质观众 参展组委会咨询&#xff1a;深宠展邹春宇 关于展会 第2届华东国际宠物用品展览会(苏州)暨中国宠业新锐品牌…

【自用】了解移动存储卡的基本信息

前言 本文是看B站视频做的一个简单笔记&#xff0c;方便日后自己快速回顾&#xff0c;内容主要介绍了存储卡基本参数&#xff0c;了解卡面上的数字、图标代表的含义。对于日后如何挑选判断一张存储卡的好坏、判别一张存储卡是否合格有一定帮助。 视频参考链接&#xff1a;【硬…

嵌入式Linux学习第二天

今天学习linuxC编程。首先要熟悉linux下编写c程序的过程。 编写程序Hello World! 首先创建存放程序的文件夹&#xff0c;如下图所示&#xff1a; 接下来在创建一个文件夹来保存这节要编写的代码。指令&#xff1a;mkdir 3.1 接下来我们要设置VIM编辑器的一些配置&#xff0…

karateclub,一个超酷的 Python 库!

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超酷的 Python 库 - karateclub。 Github地址&#xff1a;https://github.com/benedekrozemberczki/karateclub Python karateclub是一个用于图嵌入和图聚类的库&#xff…

ERP系统电子文件归档和电子档案管理规范

ERP系统电子文件归档和电子档案管理规范 1 范围 本文件描述了企业资源计划&#xff08;ERP&#xff09;系统形成电子文件归档和电子档案管理的方法。 本文件适用于企业资源计划&#xff08;ERP&#xff09;系统&#xff08;含采购、销售、物料、生产计划、质量、设备、项目…

linux学习:线程池

目录 原理 初始线程池 运行中的线程池 相关结构体 api 线程池初始化 投送任务 增加活跃线程 删除活跃线程 销毁线程池 例子 thread_pool.h thread_pool.c test.c 测试程序 原理 一个进程中的线程就好比是一家公司里的员工&#xff0c;员工的数目应该根据公司的…

LangChain 概念篇(喂饭级)

LangChain 介绍 LangChain 是一个用于开发由语言模型驱动的应用程序的框架。 LangChain 框架的设计目标 支持应用程序让其不仅会通过 API 调用语言模型&#xff0c;而且还会数据感知&#xff08;将语言模型连接到其他数据源&#xff09;&#xff0c;Be agentic&#xff08;允…

ncnn 算子操作描述

ncnn 算子操作描述&#xff0c;具体查询见 ncnn/docs/developer-guide/operators.md at master Tencent/ncnn GitHub 都是从上述地方copy过来的&#xff0c;做备份。 具体如下&#xff1a; 1.AbsVal: 计算输入张量中的每个元素的绝对值。 y abs(x)one_blob_only 只支持…