threejs开源实例-粒子地球

news2024/11/5 14:58:54

在这里插入图片描述
源码

three.js webgl - geometry - cube
<script type="module">
    import * as THREE from "three";
    import { OrbitControls } from "three/addons/controls/OrbitControls.js";
    import { GUI } from "three/addons/libs/lil-gui.module.min.js";
    let gui = new GUI();
    // 初始化场景、相机和渲染器
    const gl = {
        clearColor: '#122148',
        shadows: false,
        alpha: false,
        outputColorSpace: THREE.SRGBColorSpace,
    };

    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
        75,
        window.innerWidth / window.innerHeight,
        0.1,
        100
    );

    const renderer = new THREE.WebGLRenderer({ alpha: gl.alpha });
    renderer.setClearColor(gl.clearColor);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.target.set(0, 0, 0);
    controls.update();
    // 设置相机位置
    camera.position.z = 2;
    // Shaders
    const vertexShader = `  uniform float size;

uniform sampler2D elevTexture;
uniform sampler2D alphaTexture;
uniform float uTime;
uniform float uWaveHeight;
uniform float uWaveSpeed;

varying vec2 vUv;
varying float vVisible;
varying float vAlpha;
varying float vElevation;
// Function to generate fBm with vec3 input
float random(vec3 st) {
return fract(sin(dot(st.xyz, vec3(12.9898,78.233,45.164))) * 43758.5453123);
}

float noise(vec3 st) {
vec3 i = floor(st);
vec3 f = fract(st);

// Eight corners in 3D of a tile
float a = random(i);
float b = random(i + vec3(1.0, 0.0, 0.0));
float c = random(i + vec3(0.0, 1.0, 0.0));
float d = random(i + vec3(1.0, 1.0, 0.0));
float e = random(i + vec3(0.0, 0.0, 1.0));
float f1 = random(i + vec3(1.0, 0.0, 1.0));
float g = random(i + vec3(0.0, 1.0, 1.0));
float h = random(i + vec3(1.0, 1.0, 1.0));

vec3 u = f * f * (3.0 - 2.0 * f);

return mix(mix(mix(a, b, u.x), mix(c, d, u.x), u.y),
           mix(mix(e, f1, u.x), mix(g, h, u.x), u.y), u.z);

}

float fbm(vec3 st) {
float value = 0.0;
float amplitude = 0.5;

for (int i = 0; i < 5; i++) {
    value += amplitude * noise(st);
    st *= 2.0;
    amplitude *= 0.5;
}
return value;

}

void main() {
vUv = uv;
float alphaLand = 1.0 - texture2D(alphaTexture, vUv).r;
vAlpha = alphaLand;
vec3 newPosition = position;

if(alphaLand < 0.5) {
  // Sea
  // fBm for wave-like displacement
  float waveHeight = uWaveHeight; // Adjust wave height as needed
  float waveSpeed = uWaveSpeed;  // Adjust wave speed as needed
  float displacement = (fbm(newPosition * 5.0 + uTime * waveSpeed) * 2.0 - 1.0) * waveHeight;
  vElevation = displacement;
  newPosition += normal * displacement ;
}

vec4 mvPosition = modelViewMatrix * vec4( newPosition, 1.0 );
float elv = texture2D(elevTexture, vUv).r;
vec3 vNormal = normalMatrix * normal;
vVisible = step(0.0, dot( -normalize(mvPosition.xyz), normalize(vNormal)));
mvPosition.z += 0.45 * elv;

// 求出 mvPosition 距离相机的距离
float dist = length(mvPosition.xyz);
// 根据距离调整 size
float pointSize = size * (1.0 - dist / 10.0);
gl_PointSize = max(pointSize, 1.0);
gl_PointSize = pointSize;
gl_Position = projectionMatrix * mvPosition;

}
; // 将pointsEarth.vert的内容粘贴在这里 const fragmentShader = uniform sampler2D colorTexture;
// uniform sampler2D alphaTexture;
uniform sampler2D earthTexture;
uniform sampler2D starTexture;

varying vec2 vUv;
varying float vVisible;
varying float vAlpha;
varying float vElevation;

void main() {
if (floor(vVisible + 0.1) == 0.0) discard;
vec2 coord = gl_PointCoord;
float alpha = texture2D(starTexture, coord).a;
// 根据 alpha 值来裁剪形状
if (alpha < 0.1) discard;

// float alphaLand = 1.0 - texture2D(alphaTexture, vUv).r;
vec3 color = texture2D(colorTexture, vUv).rgb;
vec3 earth = texture2D(earthTexture, vUv).rgb;
color = mix(color, earth, 0.65);
if(
  vAlpha > 0.5
) {
  gl_FragColor = vec4(color, vAlpha);
}else {
  // 对于海洋部分,根据 vElevation 调整颜色
  float elevationEffect = clamp(vElevation*30.0, -1.0, 1.0); // 将 vElevation 限制在 [-1, 1] 范围内
  vec3 deep_sea_blue = vec3(0.004, 0.227, 0.388);
  vec3 adjustedColor = mix(deep_sea_blue, earth*1.75, (elevationEffect + 1.0) * 0.5); // 根据 vElevation 调整颜色
  gl_FragColor = vec4(adjustedColor, 1.0-vAlpha);
}

}
`; // 将pointsEarth.frag的内容粘贴在这里

    const params = {
        color: '#17c5a9',
        pointSize: 4.0,
    };

    const wireframeMaterial = {
        color: params.color,
        wireframe: true,
        transparent: true,
        opacity: 0.2,
    };

    const textures = {
        earthMap: new THREE.TextureLoader().load(FILE_HOST + 'images/earthSample/pointsEarth/00_earthmap1k.jpg'),
        starSprite: new THREE.TextureLoader().load(FILE_HOST + 'images/earthSample/pointsEarth/circle.png'),
        colorMap: new THREE.TextureLoader().load(FILE_HOST + 'images/earthSample/pointsEarth/04_rainbow1k.jpg'),
        elevMap: new THREE.TextureLoader().load(FILE_HOST + 'images/earthSample/pointsEarth/01_earthbump1k.jpg'),
        alphaMap: new THREE.TextureLoader().load(FILE_HOST + 'images/earthSample/pointsEarth/02_earthspec1k.jpg'),
    };


    const pointsShader = {
        uniforms: {
            size: { type: 'f', value: params.pointSize },
            uTime: { type: 'f', value: 0.0 },
            uWaveHeight: { type: 'f', value: 0.075 },
            uWaveSpeed: { type: 'f', value: 0.2 },
            colorTexture: { type: 't', value: textures.colorMap },
            elevTexture: { type: 't', value: textures.elevMap },
            alphaTexture: { type: 't', value: textures.alphaMap },
            earthTexture: { type: 't', value: textures.earthMap },
            starTexture: { type: 't', value: textures.starSprite },
        },
        vertexShader: vertexShader,
        fragmentShader: fragmentShader,
        transparent: true,
        side: THREE.FrontSide,
    };


    const group = new THREE.Group();
    const wireframeMaterialRef = new THREE.MeshBasicMaterial(wireframeMaterial);
    const pointsMaterial = new THREE.ShaderMaterial(pointsShader);

    const geometry = new THREE.IcosahedronGeometry(1, 4);
    const wireframeMesh = new THREE.Mesh(geometry, wireframeMaterialRef);
    group.add(wireframeMesh);

    const pointsGeometry = new THREE.IcosahedronGeometry(1, 128);
    const pointsMesh = new THREE.Points(pointsGeometry, pointsMaterial);
    group.add(pointsMesh);

    const hemisphereLight = new THREE.HemisphereLight('#ffffff', '#080820', 3);
    scene.add(hemisphereLight);

    scene.add(group);



    // 创建一个名为 'Debug' 的文件夹
    let debugFolder = gui.addFolder('Debug');

    // 添加颜色控制器
    debugFolder.addColor(params, 'color').name('color').onChange((value) => {
        wireframeMaterialRef.color.set(value);
    });

    // 添加粒子大小控制器
    debugFolder.add(params, 'pointSize', 0.1, 10, 0.1).name('粒子大小').onChange((value) => {
        pointsShader.uniforms.size.value = value;
    });

    // 添加海浪高度控制器
    debugFolder.add(pointsShader.uniforms.uWaveHeight, 'value', 0.01, 0.5, 0.01).name('海浪高度').onChange((value) => {
        pointsShader.uniforms.uWaveHeight.value = value;
    });

    // 添加海浪变化速度控制器
    debugFolder.add(pointsShader.uniforms.uWaveSpeed, 'value', 0.01, 1, 0.01).name('海浪变化速度').onChange((value) => {
        pointsShader.uniforms.uWaveSpeed.value = value;
    });


    // 渲染循环
    function animate() {
        pointsShader.uniforms.uTime.value += 10 * 0.016;
        group.rotation.y += 0.002;
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
    }
    animate();
</script>

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

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

相关文章

11.1 daimayuan 模拟赛总结

逆天 复盘 7:40 开题 扫了一眼四个题&#xff0c;T1 神秘构造&#xff0c;感觉和以前做过的某道题有点像啊&#xff0c;应该能做&#xff1b;T2 题意很简洁&#xff0c;感觉可做&#xff1b;T3&#xff0c;一眼感觉是什么优化 dp&#xff1b;T4&#xff0c;看上去像是拆期望…

2024年,Rust开发语言,现在怎么样了?

Rust开发语言有着一些其他语言明显的优势&#xff0c;但也充满着争议&#xff0c;难上手、学习陡峭等。 Rust 是由 Mozilla 主导开发的通用、编译型编程语言&#xff0c;2010年首次公开。 在 Stack Overflow 的年度开发者调查报告中&#xff0c;Rust 连续多年被评为“最受喜爱…

Golang | Leetcode Golang题解之第528题按权重随机选择

题目&#xff1a; 题解&#xff1a; type Solution struct {pre []int }func Constructor(w []int) Solution {for i : 1; i < len(w); i {w[i] w[i-1]}return Solution{w} }func (s *Solution) PickIndex() int {x : rand.Intn(s.pre[len(s.pre)-1]) 1return sort.Searc…

微服务day02

教学文档&#xff1a; 黑马教学文档 Docker Docker的安装 镜像和容器 命令解读 常见命令 案例 查看DockerHub&#xff0c;拉取Nginx镜像&#xff0c;创建并运行容器 搜索Nginx镜像&#xff1a;在 www.hub.docker.com 网站进行查询 拉取镜像&#xff1a; docker pull ngin…

认证鉴权框架之—sa-token

一、概述 Satoken 是一个 Java 实现的权限认证框架&#xff0c;它主要用于 Web 应用程序的权限控制。Satoken 提供了丰富的功能来简化权限管理的过程&#xff0c;使得开发者可以更加专注于业务逻辑的开发。 二、逻辑流程 1、登录认证 &#xff08;1&#xff09;、创建token …

python爬虫实现自动获取论文GB 7714引用

在写中文论文、本硕博毕业设计的时候要求非常严格的引用格式——GB 7714引用。对于普通学生来说都是在google scholar上获取&#xff0c;一个一个输入点击很麻烦&#xff0c;就想使用python完成这个自动化流程&#xff0c;实现批量的倒入论文标题&#xff0c;导出引用。 正常引…

pycharm中python控制台出现CommandNotFoundError: No command ‘conda run‘.

1、错误现象 pycharm中打开python控制台出现CommandNotFoundError: No command conda run.的错误。 2、背景 conda是4.6版本&#xff0c;在Anaconda Prompt可以正常运行虚拟环境。 3、解决方法 更新conda版本&#xff0c;基本命令&#xff0c;会自动更新到最新版本。 con…

masm汇编字符输入小写转大写演示

从键盘读取一个字符变成大写换行并输出 assume cs:codecode segmentstart:mov ah,1int 21hmov bl,alsub bl,20hmov dl,10mov ah,2int 21hmov dl,blmov ah,2int 21hmov ah,4chint 21hcode ends end start 效果演示&#xff1a;

VisualStudio远程编译调试linux_c++程序(二)

前章讲述了gdb相关&#xff0c;这章主要讲述用VisualStudio调试编译linux_c程序 1&#xff1a;环境 win10 VisualStudio 2022 Community ubuntu22.04 2:安装 1>vs安装时&#xff0c;勾选 使用c进行linux 和嵌入式开发 (这里以vs2022为例) OR VS安装好了&#xff0c; 选择工…

【002】基于SpringBoot+thymeleaf实现的蓝天幼儿园管理系统

基于SpringBootthymeleaf实现的蓝天幼儿园管理系统 文章目录 系统说明技术选型成果展示账号地址及其他说明源码获取 系统说明 基于SpringBootthymeleaf实现的蓝天幼儿园管理系统是为幼儿园提供的一套管理平台&#xff0c;可以提高幼儿园信息管理的准确性&#xff0c;系统将信息…

【AIGC】从CoT到BoT:AGI推理能力提升24%的技术变革如何驱动ChatGPT未来发展

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;迈向AGI的新跨越&#x1f4af;BoT与CoT的技术对比技术原理差异推理性能提升应用范围和通用性从错误中学习的能力总结 &#x1f4af;BoT的工作流程和机制初始化过程生成推…

无人机拦截捕获/直接摧毁算法详解!

一、无人机拦截捕获算法 网捕技术 原理&#xff1a;抛撒特殊设计的网具&#xff0c;捕获并固定无人机。 特点&#xff1a; 适用于小型无人机。 对无人机的损害较小&#xff0c;基本不影响其后续使用。 捕获成功率较高&#xff0c;且成本相对较低。 应用实例&#xff1a;…

解码层跑几次取决于输出词汇多少;10个单词,在解码层跑几次transformer

目录 解码层跑几次取决于输出词汇多少 10个单词,在解码层跑几次transformer 解码层跑几次取决于输出词汇多少 10个单词,在解码层跑几次transformer 取决于具体任务和输出要求 在自然语言处理任务中,Transformer 架构的解码器(Decoder)运行次数与你想要生成的输出长度有关…

算法【Java】—— 记忆化搜索

记忆化搜索 在前面我们已经学习了递归回溯等知识&#xff0c;什么是记忆化搜索&#xff0c;其实就是带着备忘录的递归&#xff0c;我们知道在递归过程中如果如果出现大量的重复的相同的子问题的时候&#xff0c;我们可能进行了多次递归&#xff0c;但是这些递归其实可以只用进…

优化EDM邮件营销,送达率与用户体验双赢

EDM邮件营销需选对平台&#xff0c;优化邮件列表&#xff0c;确保内容优质&#xff0c;进行邮件测试&#xff0c;关注用户反馈调整频率&#xff0c;以保高送达率&#xff0c;提升营销效果。 1. 了解电子邮件送达率的重要性 在开始优化邮件送达率之前&#xff0c;首先需要理解电…

Metasploit渗透测试之在云服务器中使用MSF

概述 随着云计算的发展&#xff0c;对基于云的应用程序、服务和基础设施的测试也在不断增加。在对云部署进行渗透测试时&#xff0c;最大的问题之一是共享所有权。过去&#xff0c;在进行渗透测试时&#xff0c;企业会拥有网络上的所有组件&#xff0c;我们可以对它们进行全部…

Qt桌面应用开发 第一天

目录 1.默认代码解析 1.1main.h解析 1.2myWidget.h解析 1.3FirstProject.pro解析&#xff08;FirstProject为创建的Qt项目名&#xff09; 2.命名规范与快捷键 3.按钮控件及窗口设置 3.1按钮控件QPushButton类 3.2窗口常用设计 4.Qt中的对象树 5.Qt中的坐标系 Qt是一个…

简记Vue3(三)—— ref、props、生命周期、hooks

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Mybatis查询数据库,返回List集合,集合元素也是List。

#有时间需求会要求&#xff1a;查询全校的学生数据&#xff0c;且学生数据按班级划分。那么就需要List<List<user>>类型的数据。 SQL语句 SELECT JSON_ARRAYAGG(JSON_OBJECT(name , name ,BJMC, BJMC ,BJBH,BJBH)) as dev_user FROM dev_user WHERE project_id …

Freertos学习日志(1)-基础知识

目录 1.什么是Freertos&#xff1f; 2.为什么要学习RTOS&#xff1f; 3.Freertos多任务处理的原理 1.什么是Freertos&#xff1f; RTOS&#xff0c;即&#xff08;Real Time Operating System 实时操作系统&#xff09;&#xff0c;是一种体积小巧、确定性强的计算机操作系统…