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

ops/2024/9/30 4:05:02/

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/ops/118737.html

相关文章

C语言编写一个五子棋游戏-代码实例讲解与分析

编写一个完整的五子棋游戏&#xff08;Gomoku 或 Gobang&#xff09;在C语言中是一个相对复杂的任务&#xff0c;因为它涉及到用户界面的处理、游戏逻辑的维护以及可能的AI对手设计。在这里&#xff0c;我将提供一个简化的版本&#xff0c;这个版本将使用控制台来接收用户输入&…

CSS 中的overscroll-behavior属性

overscroll-behavior 是 CSS 中的一个属性&#xff0c;它用于控制元素在发生滚动时&#xff0c;当滚动范围超出其边界时的行为。这个属性对于改善用户体验特别有用&#xff0c;尤其是在移动端设备上&#xff0c;当用户尝试滚动一个已经达到滚动极限的元素时&#xff0c;可以通过…

0926-27,元对象模型,信号和槽函数,connect函数,事件处理的详细过程,widgets模块

0926 QMetaProperty //创建一个支持元对象系统的类 myclass.h #ifndef MYCLASS_H #define MYCLASS_H#include <QObject>class myclass : public QObject {Q_OBJECT//定义了名字位health的动态属性&#xff0c;对应的底层是m_healthQ_PROPERTY(int health MEMBER m_h…

数据库连接池详解

数据库连接池是什么&#xff1f;下文会为你讲解 一、 数据库连接之殇&#xff1a;慢、卡、崩溃 想象一下&#xff0c;你的应用程序就像一家餐厅&#xff0c;数据库就像食材仓库。每次顾客点餐&#xff0c;都需要厨师跑到仓库取食材&#xff0c;做完菜再把食材送回仓库。这种模…

Maya学习笔记:软选择

文章目录 打开软选择调整软选择范围衰减模式 软选择可以很好的进行渐变修改 打开软选择 方法1&#xff1a; 进入点线面模式&#xff0c;按B键进入软选择模式&#xff0c;再按B取消 方法2&#xff1a;双击左侧的选择按钮打开选择面板&#xff0c;勾选软选择 调整软选择范围 …

Flink CDC

全增量一体化架构 自 2.0 版本起&#xff0c;Flink CDC 引入了增量快照框架&#xff0c;实现了数据库全量和增量数据的一体化读取&#xff0c;并可以在全量和增量读取之间进行无缝切换。在读取全量数据时&#xff0c;Flink CDC source 会首先将数据表中的已有数据根据主键分布切…

建立分支提交代码

git分支 git branch 产看当前分支 git branch -a 查看所有分支 git checkout 分支名 切换分支 git checkout -b 分支名 建立分支&#xff08;仅仅是在本地建立了&#xff0c;并没有关联线上&#xff09; git push --set-upstream origin 分支名 把本地分支推到先线上 gti add …

RVC变声器入门

主要参考资料&#xff1a; RVC变声器官方教程&#xff1a;10分钟克隆你的声音&#xff01;一键训练&#xff0c;低配显卡用户福音&#xff01;: https://www.bilibili.com/video/BV1pm4y1z7Gm/?spm_id_from333.337.search-card.all.click&vd_sourcedd284033cd0c4d1f3f59a2…