three.js 通过着色器实现热力图效果

news/2024/10/4 6:52:20/

three.js 通过着色器实现热力图效果

在这里插入图片描述

在线预览 https://threehub.cn/#/codeMirror?navigation=ThreeJS&classify=shader&id=heatmapShader

在 https://threehub.cn 中还有很多案例

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script type="importmap">
{"imports": {"three": "https://threejs.org/build/three.module.min.js","three/addons/": "https://threejs.org/examples/jsm/","three/examples/jsm/": "https://threejs.org/examples/jsm/","gsap": "https://file.threehub.cn/js/gsap/index.js","postprocessing": "https://threehub.cn/js/postprocessing.js","cannon-es": "https://threehub.cn/js/cannon-es.js","dat.gui": "https://threehub.cn/js/dat.gui.module.js","@tweenjs/tween.js": "https://threehub.cn/js/tween.esm.js"}
}
</script>
<style>body {margin: 0;padding: 1px;box-sizing: border-box;background-color: #1f1f1f;display: flex;flex-direction: column;width: 100vw;height: 100vh;overflow: hidden;}#box {width: 100%;height: 100%;}
</style>
</head>
<body>
<div id="box"></div>
<script type="module">
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { GUI } from "three/addons/libs/lil-gui.module.min.js";const box = document.getElementById('box')const scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)camera.position.set(0, 10, 10)const renderer = new THREE.WebGLRenderer()renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)new OrbitControls(camera, renderer.domElement)animate()function animate() {requestAnimationFrame(animate)renderer.render(scene, camera)}window.onresize = () => {renderer.setSize(box.clientWidth, box.clientHeight)camera.aspect = box.clientWidth / box.clientHeightcamera.updateProjectionMatrix()}scene.add(new THREE.AmbientLight(0xffffff, 2), new THREE.AxesHelper(1000))const arr = [[0., 0., 10.], [.2, .6, 5.], [.25, .7, 8.], [.33, .9, 5.], [.35, .8, 6.], [0.017, 5.311, 6.000], [-.45, .8, 4.], [-.2, -.6, 5.], [-.25, -.7, 8.], [-.33, -.9, 8.], [.35, -.45, 10.], [-.1, -.8, 10.], [.33, -.3, 5.], [-.35, .75, 6.], [.6, .4, 10.], [-.4, -.8, 4.], [.7, -.3, 6.], [.3, -.8, 8.]].map(i => new THREE.Vector3(...i))const uniforms1 = {HEAT_MAX: { value: 10, type: 'number', unit: 'float' },PointRadius: { value: 0.42, type: 'number', unit: 'float' },PointsCount: { value: arr.length, type: 'number-array', unit: 'int' }, // 数量c1: { value: new THREE.Color(0x000000), type: 'color', unit: 'vec3' },c2: { value: new THREE.Color(0x000000), type: 'color', unit: 'vec3' },uvY: { value: 1, type: 'number', unit: 'float' },uvX: { value: 1, type: 'number', unit: 'float' },opacity: { value: 1, type: 'number', unit: 'float' }}const gui = new GUI()gui.add(uniforms1.HEAT_MAX, 'value', 0, 10).name('HEAT_MAX')gui.add(uniforms1.PointRadius, 'value', 0, 1).name('PointRadius')gui.add(uniforms1.uvY, 'value', 0, 1).name('uvY')gui.add(uniforms1.uvX, 'value', 0, 1).name('uvX')gui.add(uniforms1.opacity, 'value', 0, 1).name('opacity')gui.addColor(uniforms1.c1, 'value').name('c1')gui.addColor(uniforms1.c2, 'value').name('c2')const uniforms2 = {Points: { value: arr, type: 'vec3-array', unit: 'vec3' }}const uniforms = {...uniforms1,...uniforms2}const vertexShader = `
varying vec2 vUv;
void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`const fragmentShader = 'precision highp float;\n' + 'varying vec2 vUv; \n' +Object.keys(uniforms1).map(i => 'uniform ' + uniforms1[i].unit + ' ' + i + ';').join('\n')+ '\nuniform vec3 Points['+ uniforms1.PointsCount.value + '];'+`
vec3 gradient(float w, vec2 uv) {w = pow(clamp(w, 0., 1.) * 3.14159 * .5, .9);return vec3(sin(w), sin(w * 2.), cos(w))* 1.1 + mix(c1, c2, w) * 1.1; 
}
void main()
{vec2 uv = vUv;uv.xy *= vec2(uvX, uvY);float d = 0.;for (int i = 0; i < PointsCount; i++) {vec3 v = Points[i];float intensity = v.z / HEAT_MAX;float pd = (1. - length(uv - v.xy) / PointRadius) * intensity;d += pow(max(0., pd), 2.);}gl_FragColor = vec4(gradient(d, uv), opacity);
} `const shaderMaterial = new THREE.ShaderMaterial({uniforms,vertexShader,fragmentShader,transparent: true})const plane = new THREE.Mesh(new THREE.PlaneGeometry(10, 10), shaderMaterial)scene.add(plane)console.log(shaderMaterial)
/*** 名称: 热力图* 来源:优雅永不过时* https://github.com/z2586300277*/</script>
</body>
</html>

http://www.ppmy.cn/news/1534274.html

相关文章

RabbitMQ 界面管理说明

1.RabbitMQ界面访问端口和后端代码连接端口不一样 界面端口是15672 http://localhost:15672/ 后端端口是 5672 默认账户密码登录 guest 2.总览图 3.RabbitMq数据存储位置 4.队列 4.客户端消费者连接状态 5.队列运行状态 6.整体运行状态

基于大数据技术的音乐数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

“衣依”服装销售平台:Spring Boot框架的设计与实现

3系统分析 3.1可行性分析 通过对本“衣依”服装销售平台实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本“衣依”服装销售平台采用JAVA作为开发语言&#xff…

Android Glide(一):源码分析,内存缓存和磁盘缓存的分析,实现流程以及生命周期

目录 一、Android Glide是什么&#xff0c;如何使用&#xff1f; Android Glide是一个由Google维护的快速高效的Android图像加载库&#xff0c;它旨在简化在Android应用程序中加载和显示图像的过程&#xff0c;包括内存缓存、磁盘缓存和网络加载&#xff0c;以确保图像加载的快…

UE4_Niagara基础实例—6、蓝图与粒子系统的通信

效果图&#xff1a; 分析&#xff1a; 通过键盘按键来修改粒子系统粒子的大小。 步骤&#xff1a; 1、粒子系统使用上一个实例的粒子系统&#xff0c;大体参数如下&#xff1a; 参数都是乱调的&#xff0c;自己可以随意设置&#xff0c;只注重方法而不在意好看&#xff0c;汗…

【数一线性代数】021入门

Index 推荐阅读&#xff1a;https://blog.csdn.net/weixin_60702024/article/details/141729949分析实现总结 推荐阅读&#xff1a;https://blog.csdn.net/weixin_60702024/article/details/141729949 给定二叉树的根节点root&#xff0c;计算其叶节点的个数。 分析实现 类似…

Python 中的 os 模块

Python 中的 os 模块 在Python中&#xff0c;os 模块是一个内置的标准库&#xff0c;提供了许多与操作系统交互的功能。它允许你执行一系列操作&#xff0c;如文件和目录操作、环境变量管理等。要在Python脚本中使用os模块&#xff0c;你需要首先导入它。 一些常见的用法&…

需求6:如何写一个后端接口?

这两天一直在对之前做的工作做梳理总结&#xff0c;不过前两天我都是在总结一些bug的问题。尽管有些bug问题我还没写文章&#xff0c;但是&#xff0c;我今天不得不先停下对bug的总结了。因为在国庆之后&#xff0c;我需要自己开发一个IT资产管理的功能&#xff0c;这个功能需要…