three.js混合白色模型的智慧城市扫光效果

news2024/12/27 14:40:42

three.js混合白色模型的智慧城市扫光效果

https://threehub.cn/#/codeMirror?navigation=ThreeJS&classify=shader&id=cityBlendLight

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'

const box = document.getElementById('box')

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 100000)

camera.position.set(157, 545, -987)

const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })

renderer.setSize(box.clientWidth, box.clientHeight)

renderer.setClearColor(0x000000, 0)

renderer.setPixelRatio(window.devicePixelRatio * 2)

new OrbitControls(camera, renderer.domElement)

window.onresize = () => {

    renderer.setSize(box.clientWidth, box.clientHeight)

    camera.aspect = box.clientWidth / box.clientHeight

    camera.updateProjectionMatrix()

}

box.appendChild(renderer.domElement)

const dirLight = new THREE.DirectionalLight(0xffffff, 3.8)

dirLight.position.set(83, 61, -183)

dirLight.target.position.set(10, -11, -194)

scene.add(dirLight)

const pointLight = new THREE.PointLight(0xffffff, 2)

pointLight.position.set(-60, 182, -98)

scene.add(pointLight)

let model = null

// 加载模型
new FBXLoader().load(`https://threehub.cn/` + '/files/model/city.FBX', (object3d) => {

    scene.add(object3d)

    object3d.scale.set(0.04, 0.04, 0.04)

    object3d.position.set(224, -9, -49)

    model = object3d

    modelBlendShader(object3d, box)

})

// 渲染
animate()

function animate() {

    model && model.render?.()

    renderer.render(scene, camera)

    requestAnimationFrame(animate)

}

/* 混合着色 */
function modelBlendShader(model) {

    let materials = []

    model.traverse(c => c.isMesh && materials.push(c.material))

    materials = [... new Set(materials)]

    const uniforms = {

        innerCircleWidth: { value: 480, type: 'number', unit: 'float' },

        circleWidth: { value: 160, type: 'number', unit: 'float' },

        circleMax: { value: 940, type: 'number', unit: 'float' },

        circleSpeed: { value: 1.5, type: 'number', unit: 'float' },

        diff: { value: new THREE.Color(0x6edbe8), type: 'color', unit: 'vec3' },

        color3: { value: new THREE.Color(0x1919f9), type: 'color', unit: 'vec3' },

        center: { value: new THREE.Vector3(-1, 0, 0), type: 'position', unit: 'vec3' },

        intensity: { value: 4, type: 'number', unit: 'float' },

        isDisCard: { value: false, type: 'bool', unit: 'bool' },

    }

    const glslProps = {

        vertexHeader: `
            varying vec2 vUv;
            varying vec3 v_position;
            void main() {
                vUv = uv;
                v_position = position;
        `,

        fragHeader: Object.keys(uniforms).map(i => 'uniform ' + uniforms[i].unit + ' ' + i + ';').join('\n') + '\n' + 'varying vec3 v_position; varying vec2 vUv;\n',

        fragBody: `
            float dis = length(v_position - center);
            vec4 diffuseColor;
            if(dis < (innerCircleWidth + circleWidth) && dis > innerCircleWidth) {
                float r = (dis - innerCircleWidth) / circleWidth;
                #ifdef USE_MAP
                    vec3 textureColor = texture2D(map, vUv).rgb;
                    if(isDisCard && textureColor.r < 0.1 && textureColor.g < 0.1  && textureColor.b < 0.1 ) discard;
                #endif
                diffuseColor = vec4( mix(diff, color3, r) * vec3(intensity, intensity, intensity)  , opacity);
            }
            else {
                if(isDisCard)  discard ;
                else diffuseColor = vec4( diffuse, opacity );
            }
        `

    }

    materials.forEach(material => {

        material.onBeforeCompile = (shader) => {

            Object.keys(uniforms).forEach((key) => shader.uniforms[key] = uniforms[key])

            shader.vertexShader = shader.vertexShader.replace(`void main() {`, glslProps.vertexHeader)

            shader.fragmentShader = shader.fragmentShader.replace(/#include <common>/, glslProps.fragHeader + '\n#include <common>\n')

            shader.fragmentShader = shader.fragmentShader.replace('vec4 diffuseColor = vec4( diffuse, opacity );', glslProps.fragBody)

        }

        material.needsUpdate = true

    })

    model.render = () => uniforms.innerCircleWidth.value < uniforms.circleMax.value ? uniforms.innerCircleWidth.value += uniforms.circleSpeed.value : uniforms.innerCircleWidth.value = 0

}


/**
 * 名称: 城市混合扫光
 * 作者: 优雅永不过时 https://github.com/z2586300277
*/

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

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

相关文章

.NET 8.0 项目升级到 .NET 9.0

本文项目从.NETCore3.1开始一直延续到目前&#xff0c;如果您没有升级过&#xff0c;请参考以下文章&#xff1a; .Net Core 2.2 升级到 .Net Core 3.1&#xff1a;https://blog.csdn.net/hefeng_aspnet/article/details/131259537 NetCore3.1或Net6.0项目升级到Net7.0&#x…

第23天:信息收集-APP应用产权渠道服务资产通讯抓包静态提取动态调试测试范围

#知识点 1、信息收集-APP应用-公开信息-知识产权&开发者定位 2、信息收集-APP应用-资产信息-抓包&静态提取&动态调试 一、APP渗透测试的范围->应涵盖APP所有功能和组件&#xff0c;包括但不限于以下几个方面&#xff1a; 1、前端安全&#xff1a;包括界面交互、…

Virtualbox安装ubuntu20虚拟机无法打开终端

用Virtualbox安装ubuntu20系统&#xff0c;安装好之后&#xff0c;无法打开终端&#xff1b; 原因&#xff1a;语言设置导致的问题&#xff1b; 修改方法&#xff1a;将/etc/default/locale里LANG这行的值修改为&#xff1a;en_US.UTF-8即可&#xff1b; 步骤&#xff1a;先在…

PH热榜 | 2024-12-25

1. Assistive24 标语&#xff1a;为残障人士提供的免费辅助技术 介绍&#xff1a;Assistive24 是一款免费的 Chrome 浏览器扩展程序&#xff0c;可以帮助患有注意力缺陷多动障碍 (ADHD)、阅读障碍 (dyslexia) 和低视力等障碍的用户更方便地浏览网页。它提供语音导航、自定义…

Torch.gather

1.官方文档 2.使用要点 输入index的shape等于输出value的shape输入index的索引值仅替换该index中对应dim的index值最终输出为替换index后在原tensor中的值 最终输出的shape和index的shape相同 根据dim的值 选择将index[i,j,k]这个结果替换input[i,j,k]里面对应的i or j or…

Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现马赛克效果,Kotlin(3)

Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现马赛克效果&#xff0c;Kotlin&#xff08;3&#xff09; import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas impor…

音乐极客的新玩具:香橙派Zero3快速搭建Melody个人音乐平台

文章目录 前言1. 添加镜像源2. 本地部署Melody3. 本地访问与使用演示4. 安装内网穿透5. 配置Melody公网地址6. 配置固定公网地址 前言 今天要给喜欢听音乐的朋友们介绍一个超酷的DIY项目&#xff0c;在香橙派Zero3上使用Melody搭建自己的个人在线音乐平台&#xff0c;并且借助…

如何从 0 到 1 ,打造全新一代分布式数据架构

导读&#xff1a;本文从 DIKW&#xff08;数据、信息、知识、智慧&#xff09; 模型视角出发&#xff0c;探讨数字世界中数据的重要性问题。接着站在业务视角&#xff0c;讨论了在不断满足业务诉求&#xff08;特别是 AI 需求&#xff09;的过程中&#xff0c;数据系统是如何一…

elementPlus消息组件多按钮案例

let customClass zsl-el-message-box efb.messageBox({title: 操作提示,showConfirmButton: false,customClass,message: efb.VNode(div, null, [efb.VNode(style, null, .${customClass} .el-message-box__message {width: 100%;}),efb.VNode(div, null, hello world),efb.VN…

MATLAB符号计算-符号表达式基础运算操作

1.1.2符号变量取值域的限定 默认复数域 【例1-1-2】解不等式 1.1.3创建符号表达式 对符号对象进行各种运算&#xff08;算术运算、关系运算、逻辑运算&#xff09;&#xff0c;即可创建符号表达式。 1.算术运算与转置 【例1-1-3】 f5是f4的共轭转置 f6是f4的转置 2.关系…

使用Excel制作通达信自定义外部数据,安排!!!

Excel相信大家电脑上都有这个工具&#xff0c;相比敲编程代码&#xff0c;用这个去做自定义数据对大多数人&#xff0c;应该是比较友好的。自定义数据分为外部序列数据&#xff0c;看了一下内容理解起来比较多&#xff0c;分两期给大家介绍。为了照顾电脑基础薄弱的朋友&#x…

SwiftUI 入门趣谈:在文本框(TextField)内限制数字的输入

概述 虽然 SwiftUI 本身提供了海量内置的原生视图供我们使用&#xff0c;但对于某些情况我们还需要根据实际需求“量体裁衣、专属定制”。 在日常的撸码场景中&#xff0c;我们有时需要限制文本框&#xff08;TextField&#xff09;中数字内容的输入&#xff0c;如何又简单又快…

深入浅出 MyBatis | CRUD 操作、配置解析

3、CRUD 3.1 namespace namespace 中的包名要和 Dao/Mapper 接口的包名一致&#xff01; 比如将 UserDao 改名为 UserMapper 运行发现抱错&#xff0c;这是因为 UserMapper.xml 中没有同步更改 namespace 成功运行 给出 UserMapper 中的所有接口&#xff0c;接下来一一对…

基于c语言的union、字符串、格式化输入输出

结构体之共用体union 共用体也叫联合体&#xff0c;其关键词为union 与结构体不同的是&#xff0c;共用体所开辟的存储空间仅仅为其中最长类型变量的存储空间而不是全部变量的存储空间&#xff0c;由于同一内存单元在同一时间内只能存放其中一种的数据类型&#xff0c;因此在每…

IntelliJ Idea常用快捷键详解

文章目录 IntelliJ Idea常用快捷键详解一、引言二、文本编辑与导航1、文本编辑2、代码折叠与展开 三、运行和调试四、代码编辑1、代码补全 五、重构与优化1、重构 六、使用示例代码注释示例代码补全示例 七、总结 IntelliJ Idea常用快捷键详解 一、引言 在Java开发中&#xff…

AI开发:使用支持向量机(SVM)进行文本情感分析训练 - Python

支持向量机是AI开发中最常见的一种算法。之前我们已经一起初步了解了它的概念和应用&#xff0c;今天我们用它来进行一次文本情感分析训练。 一、概念温习 支持向量机&#xff08;SVM&#xff09;是一种监督学习算法&#xff0c;广泛用于分类和回归问题。 它的核心思想是通过…

Linux-----进程处理(子进程创建)

【尚硅谷嵌入式Linux应用层开发&#xff0c;linux网络编程&#xff0c;linux进程线程&#xff0c;linux文件io】https://www.bilibili.com/video/BV1DJ4m1M77z?p35&vd_source342079de7c07f82982956aad8662b467 main函数 fork创建进程 fork()参数 /*** brief 创建一个子进…

一种寻路的应用

应用背景 利用长途车进行货物转运的寻路计算。例如从深圳到大连。可以走有很多条长途车的路线。需要根据需求计算出最合适路线。不同的路线的总里程数、总价、需要的时间不一样。客户根据需求进行选择。主要有一些细节&#xff1a; 全国的长途车车站的数据的更新&#xff1a; …

2. FPGA基础了解--全局网络

前言 引入扇出的概念介绍FPGA中的全局网络为后续时序优化埋下伏笔 扇出 在FPGA设计中扇出是一个重要的概念&#xff0c;所谓的扇出就是一个控制信号所能控制的数据信号的总个数&#xff0c;比如ctrl信号的扇出就是16 reg ctrl 0; reg [15:0] out 0; always (posedge c…

Excel中一次查询返回多列

使用Excel或wps的时候&#xff0c;有时候需要一次查询返回多列内容&#xff0c;这种情况可以选择多次vlookup或者多次xlookup&#xff0c;但是这种做法费时费力不说&#xff0c;效率还有些低下&#xff0c;特别是要查询的列数过多时。我放了3种查询方法&#xff0c;效果图&…