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

news2024/9/29 20:12:48

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.clientHeight

    camera.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.coloradmin.cn/o/2177719.html

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

相关文章

RFID标签的前世今生

一、RFID标签发展历程 1.1 技术突破 RFID标签技术自20世纪90年代兴起以来&#xff0c;经历了多次重要的技术突破&#xff0c;这些突破极大地推动了RFID技术的发展和应用。 标签供电方式的革新&#xff1a;早期的RFID标签主要依赖于电磁感应线圈进行短暂供电&#xff0c;而现…

python中的assert语句

1.什么是assert 程序运行过程中,所有变量的当前值组合构成了“状态“; 每执行一段程序,状态就发生变化;如果程序有逻辑错误的bug,必定在处变量值的组合不符合预期,处于错误状态; 将对变量的预期写为断言,可以定位复杂的逻辑错误。 语法: assert <表达式> [, …

transition在vue2和vue3中的差异

背景&#xff1a; 在学习<transition/> 的时候&#xff0c;发现自己跟着视频抄写的代码&#xff0c;实现效果和示例代码不一致。 代码&#xff1a; <template><div id"app"><button id"btn" click"changeShow">切换…

Cholesky分解

Cholesky 应该怎么念&#xff0c;o(╯□╰)o&#xff0c;我感觉比较像‘瞅乐死骑’&#xff0c;毕竟这是 名字&#xff0c;哈哈哈哈 ATA 这个矩阵非常重要&#xff0c;之前在最小二乘法也见过它&#xff0c;如果&#xff1a; Axb 无解&#xff0c;也就是 xA−1b 不成立&…

随笔:创新的路径

最近&#xff0c;中国工业博览会在上海召开了&#xff0c;许多自动化行业的朋友都去参加这一场中国工业的盛会&#xff0c;兴奋地传来了各种新技术和新产品的消息。总的感觉国产产品集中度很高&#xff0c;长的都差不多。同质化现象比较严重。要实现产品的差异化&#xff0c;唯…

英伟达Blackwell系列显卡揭秘:RTX 5090与RTX 5080引领性能新高度

在万众瞩目的期待中&#xff0c;9月27日传来震撼消息&#xff0c;知名硬件信息揭秘者Kopite7kimi再次出手&#xff0c;独家披露了英伟达即将震撼登场的Blackwell系列显卡中的两款旗舰级产品——GeForce RTX 5090与RTX 5080的详细规格。这一爆料不仅揭示了英伟达新一代显卡的卓越…

企业微信:客户联系自带群发工具和聊天工具

前言 上篇博客介绍了一些客户联系的开启和配置&#xff0c;接下来我们来使用客户联系自带群发工具和聊天工具。 突然发现官方的文档已经很详细了&#xff0c;我这里给出一些简单的描述&#xff1a; 企业微信如何使用群发助手&#xff1f;-帮助中心-企业微信 群发工具 群发消息给…

Clipboard.js实现复制文本到剪贴板功能

一、Clipboard.js简介 Clipboard.js是一个轻量级的实现复制文本到剪贴板功能的JavaScript插件&#xff0c;该插件可以将输入框&#xff0c;文本域&#xff0c;DOM节点元素中的文本内容复制到剪贴板中。 官网地址&#xff1a;Clipboard.js 浏览器兼容性&#xff1a;兼容Chrome、…

第100+26步 ChatGPT学习:概率校准 Bayesian Binning into Quantiles

基于Python 3.9版本演示 一、写在前面 最近看了一篇在Lancet子刊《eClinicalMedicine》上发表的机器学习分类的文章&#xff1a;《Development of a novel dementia risk prediction model in the general population: A large, longitudinal, population-based machine-learn…

Kubernetes从零到精通(16-扩展-CRD、Custom Controller)

目录 一、简介 二、CRD 1.CRD介绍 2.CRD工作流程 三、Custom Controller 1.Custom Controller介绍 2.Custom Controller工作流程 四、示例 1.创建CR 2.配置权限RBAC 3.创建Custom Controller 3.1 Go项目初始化 3.2 main.go编写 3.3 构建镜像 3.4 部署Controller…

BaseCTF2024 个人WP

Pwn&#xff1a; [Week1] 签个到吧&#xff1a; 直接nc&#xff0c;ls&#xff0c;cat flag [Week1] echo&#xff1a; 只能使用echo命令 那就用echo *代替ls输出当前目录所有文件 用echo $(<flag)输出flag [Week1] Ret2text&#xff1a; 简单的栈溢出 from pwn impo…

10分钟,AI如何精准写出社会热点文?一篇爆款文章的背后你敢信?

本文背景 很多小伙伴们反馈&#xff0c;用AI输出的文章经常被平台判定为“疑似AI创作”&#xff0c;一但被判定&#xff0c;系统就不会给推荐流量。 到底在这个充斥着AI的大环境下&#xff0c;应该怎样完成AI文章的写作呢&#xff1f;特别是做流量主项目的小伙伴们&#xff0c;…

golang web笔记-3.响应ResponseWriter

简介 从服务器向客户端返回响应需要使用 ResponseWriter&#xff0c;ResponseWriter是一个接口&#xff0c;handler用它来返回响应。 ResponseWriter常用方法 Write&#xff1a;接收一个byte切片作为参数&#xff0c;然后把它写入到响应的body中。如果Write被调用时&a…

linux conda 安装 配置

linux conda 安装 配置 1. 下载2. 安装3. 配置&#xff08;针对非root用户&#xff0c;当前用户&#xff09; 1. 下载 网址&#xff1a;https://docs.anaconda.com/miniconda/ 下载一个.sh文件 2. 安装 命令&#xff1a;sh Miniconda3-latest-Linux-x86_64.sh 按照提示回车/…

【数据结构】什么是平衡二叉搜索树(AVL树)?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f4cc;AVL树的概念 &#x1f4cc;AVL树的操作 &#x1f38f;AVL树的插入操作 ↩️右单旋 ↩️↪️右左双旋 ↪️↩️左右双旋 ↪️左单旋 &#x1f38f;AVL树的删…

利用AI十分钟制作视频,暴涨4.7w粉丝,小白也能月入过万

今天给大家展示的项目是&#xff1a;AI动漫人物封面。 先来看一下教程方的广告&#xff1a; 蓝海赛道、AI翻唱 一周内获得了4.7万个粉丝&#xff0c;小白也可以轻松上手&#xff0c;月入过万手拿把掐。 现在利用AI创作 动漫 IP 翻唱音乐在全网悄然增多&#xff0c;流量也非常…

女性向游戏的新战场:AI陪伴系统

在数字化时代&#xff0c;游戏不再只是简单的娱乐产品&#xff0c;而是成为了人们情感寄托的重要载体。特别是对于女性玩家来说&#xff0c;游戏不仅仅是一种消遣&#xff0c;更是一种情感体验。近年来&#xff0c;女性向游戏市场逐渐崛起&#xff0c;其中“陪伴系统”成为了一…

【LeetCode】动态规划—931. 下降路径最小和(附完整Python/C++代码)

动态规划—931. 下降路径最小和 前言题目描述基本思路1. 问题定义2. 理解问题和递推关系3. 解决方法3.1 动态规划方法3.2 空间优化的动态规划 4. 进一步优化4.1 空间复杂度优化 5. 小总结 代码实现Python3代码实现Python 代码解释C代码实现C 代码解释 总结: 前言 在算法的学习…

985官宣:19名本科生,获国自然项目!

9月24日&#xff0c;据复旦大学教务处消息&#xff0c;国家自然科学基金委公布了2024年国家自然科学基金青年学生基础研究项目&#xff08;本科生&#xff09;立项情况&#xff0c;复旦大学共有19名基础学科专业本科生获得国家自然科学基金委资助。 此前&#xff0c;据武汉大学…

VBA技术资料MF207:右键录入指定范围数据

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…