当前位置: 首页 > news >正文

轻量封装WebGPU渲染系统示例<51>- 视差贴图(Parallax Map)(源码)

视差纹理是一种片段着色阶段增强材质表面凹凸细节的技术。

这里在WebGPU的实时渲染材质管线中实现了视差贴图计算,以便增强相关的纹理细节表现力。

当前示例源码github地址:

https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/ParallaxTexTest.ts

当前示例运行效果:

此示例基于此渲染系统实现,当前示例TypeScript源码如下:

export class ParallaxTexTest {private mRscene = new RendererScene();initialize(): void {console.log("ParallaxTexTest::initialize() ...");this.loadImg();}initSys(): void {this.mRscene.initialize({canvasWith: 512,canvasHeight: 512,mtplEnabled: true,rpassparam:{multisampled: true}});this.initScene();this.initEvent();}private mPixels: Uint8ClampedArray;private mPixelsW = 128;private mPixelsH = 128;getRandomColor(s?: number): ColorDataType {if (s === undefined) {s = 1.0;}let i = 5;let j = Math.floor(Math.random() * this.mPixelsW);let k = i * this.mPixelsW + j;let vs = this.mPixels;k *= 4;let cs = [s * vs[k] / 255.0, s * vs[k + 1] / 255.0, s * vs[k + 2] / 255.0];return cs;}private loadImg(): void {let img = new Image();img.onload = evt => {this.mPixelsW = img.width;this.mPixelsH = img.height;let canvas = document.createElement("canvas");canvas.width = img.width;canvas.height = img.height;let ctx = canvas.getContext('2d');ctx.drawImage(img, 0, 0);this.mPixels = ctx.getImageData(0, 0, img.width, img.height).data;this.initSys();}img.src = 'static/assets/colorPalette.jpg';}private mLightData: MtLightDataDescriptor;private createLightData(): MtLightDataDescriptor {let ld = { pointLights: [], directionLights: [], spotLights: [] } as MtLightDataDescriptor;let total = 5;let scale = 3.0;for (let i = 0; i < total; ++i) {for (let j = 0; j < total; ++j) {let position = [-500 + 250 * j, 290 + Math.random() * 30, -500 + 250 * i];position[0] += Math.random() * 60 - 30;position[2] += Math.random() * 60 - 30;let color = this.getRandomColor(scale);let factor1 = 0.00001;let factor2 = 0.00002;let pLight = new PointLight({ color, position, factor1, factor2 });ld.pointLights.push(pLight);if (Math.random() > 0.5) {position = [-500 + 150 * j, 290 + Math.random() * 50, -500 + 150 * i];position[0] += Math.random() * 160 - 80;position[2] += Math.random() * 160 - 80;color = this.getRandomColor(scale);let direction = [(Math.random() - 0.5) * 8, -1, (Math.random() - 0.5) * 8];let degree = Math.random() * 10 + 5;let spLight = new SpotLight({ position, color, direction, degree, factor1, factor2 });ld.spotLights.push(spLight);}}}let dLight = new DirectionLight({ color: [0.5, 0.5, 0.5], direction: [-1, -1, 0] });ld.directionLights.push(dLight);return ld;}private createBillboard(pv: Vector3DataType, c: ColorDataType, type: number): void {let rc = this.mRscene;let diffuseTex0 = { diffuse: { url: "static/assets/flare_core_03.jpg" } };if (type > 1) {diffuseTex0 = { diffuse: { url: "static/assets/circleWave_disp.png" } };}let billboard = new BillboardEntity({ size: 10, textures: [diffuseTex0] });billboard.color = c;billboard.alpha = 1;billboard.transform.setPosition(pv);rc.addEntity(billboard);}private createBillboards(): void {let lightData = this.mLightData;let pls = lightData.pointLights;for (let i = 0; i < pls.length; i++) {let lp = pls[i];this.createBillboard(lp.position, lp.color, 1);}let spls = lightData.spotLights;for (let i = 0; i < spls.length; i++) {let lp = spls[i];this.createBillboard(lp.position, lp.color, 2);}}private initScene(): void {let rc = this.mRscene;let mtpl = rc.renderer.mtpl;this.mLightData = this.createLightData();mtpl.light.lightData = this.mLightData;mtpl.shadow.param.intensity = 0.4;mtpl.shadow.param.radius = 4;let position = [-30, 220, -50];let materials = this.createMaterials(true);let sphere: SphereEntity;let total = 3;let py = 150;for (let i = 0; i < total; ++i) {for (let j = 0; j < total; ++j) {if (total > 2) {position = [-350 + 350 * j, py, -350 + 350 * i];} else {position = [0, py, 0];}let rotation = [0, Math.random() * 360, 0];let materials = this.createMaterials(true);if (sphere) {let sph = new SphereEntity({geometry: sphere.geometry,materials,transform: { position, rotation }});rc.addEntity(sph);} else {sphere = new SphereEntity({radius: 110.0,materials,transform: { position, rotation }});rc.addEntity(sphere);}}}position = [0, 0, 0];materials = this.createMaterials(true, false, 'back');let plane = new PlaneEntity({axisType: 1,materials,extent: [-600, -600, 1200, 1200],transform: { position }});rc.addEntity(plane);this.createBillboards();}private createArmTextures(): WGTextureDataDescriptor[] {const albedoTex = { albedo: { url: `static/assets/pbrtex/rough_plaster_broken_diff_1k.jpg` } };const normalTex = { normal: { url: `static/assets/pbrtex/rough_plaster_broken_nor_1k.jpg` } };const armTex = { arm: { url: `static/assets/pbrtex/rough_plaster_broken_arm_1k.jpg` } };const parallaxTex = { parallax: { url: `static/assets/pbrtex/rough_plaster_broken_disp_1k.jpg` } };let envTex = { specularEnv: {} };let textures = [envTex,albedoTex,normalTex,armTex,parallaxTex] as WGTextureDataDescriptor[];return textures;}private createMaterials(shadowReceived = false, shadow = true, faceCullMode = 'back', uvParam?: number[]): BaseMaterial[] {let textures0 = this.createArmTextures();let material0 = this.createMaterial(textures0, ["solid"], 'less', faceCullMode);this.applyMaterialPPt(material0, shadowReceived, shadow);let list = [material0];if (uvParam) {for (let i = 0; i < list.length; ++i) {list[i].property.uvParam.value = uvParam;}}return list;}private applyMaterialPPt(material: BaseMaterial, shadowReceived = false, shadow = true): void {let ppt = material.property;ppt.ambient.value = [0.2, 0.2, 0.2];ppt.albedo.value = this.getRandomColor(1.0);ppt.arms.roughness = Math.random() * 0.95 + 0.05;ppt.arms.metallic = 0.2;ppt.armsBase.value = [0, 1.0, 0];ppt.specularFactor.value = [0.1, 0.1, 0.1];ppt.shadow = shadow;ppt.lighting = true;ppt.shadowReceived = shadowReceived;}private createMaterial(textures: WGTextureDataDescriptor[], blendModes: string[], depthCompare = 'less', faceCullMode = 'back'): BaseMaterial {let pipelineDefParam = {depthWriteEnabled: true,faceCullMode,blendModes,depthCompare};let material = new BaseMaterial({ pipelineDefParam });material.addTextures(textures);return material;}private initEvent(): void {const rc = this.mRscene;rc.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown);new MouseInteraction().initialize(rc, 0, false).setAutoRunning(true);}private mouseDown = (evt: MouseEvent): void => { };run(): void {this.mRscene.run();}
}

相关文章:

轻量封装WebGPU渲染系统示例<51>- 视差贴图(Parallax Map)(源码)

视差纹理是一种片段着色阶段增强材质表面凹凸细节的技术。 这里在WebGPU的实时渲染材质管线中实现了视差贴图计算&#xff0c;以便增强相关的纹理细节表现力。 当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/Para…...

YOLOv8改进 | 2023主干篇 | 华为最新VanillaNet主干替换Backbone实现大幅度长点

一、本文介绍 本文给大家来的改进机制是华为最新VanillaNet网络&#xff0c;其是今年最新推出的主干网络&#xff0c;VanillaNet是一种注重极简主义和效率的神经网络架构。它的设计简单&#xff0c;层数较少&#xff0c;避免了像深度架构和自注意力这样的复杂操作(需要注意的是…...

Leetcode 376 摆动序列

题意理解&#xff1a; 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 如果是摆动序列&#xff0c;前后差值呈正负交替出现 为保证摆动序列尽可能的长&#xff0c;我们可以尽可能的保留峰值&#xff0c;&#xff0c;删除上下坡的中间值&…...

51单片机控制1602LCD显示屏输出自定义字符二

51单片机控制1602LCD显示屏输出自定义字符二 1.概述 1602LCD除了内置的字符外还提供自定义字符功能&#xff0c;当内置的字符中没有我们想要输出的字符时&#xff0c;我们就可以自己创造字符让他显示&#xff0c;下面介绍1602如何创建自定义字符。 2.1602LCD创建字符原理 自…...

HarmonyOS自学-Day2(@Builder装饰器)

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;Builder装饰器&#xff1a;自定义构建函数Builder介绍Builder使用说明自定义组件中创建自定义构建函数全局自定义构建函数 Builder参数传递规则按引用传递参数按值传递参数 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程…...

bottom-up-attention-vqa-master 成功复现!!!

代码地址 1、create_dictionary.py 建立词典和使用预训练的glove向量 &#xff08;1&#xff09;create_dictionary() 遍历每个question文件取出所关注的question部分&#xff0c;qs 遍历qs&#xff0c;对每个问题的文本内容进行分词&#xff0c;并将分词结果添加到字典中&…...

BigDecimal中divide方法详解

BigDecimal中divide方法详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;让我们一起深入探讨Java中BigDecimal的divide方法&#xff0c;揭开这个…...

视频推拉流EasyDSS互联网直播/点播平台构建户外无人机航拍直播解决方案

一、背景分析 近几年&#xff0c;国内无人机市场随着航拍等业务走进大众&#xff0c;出现爆发式增长。无人机除了在民用方面的应用越来越多&#xff0c;在其他领域也已经开始广泛应用&#xff0c;比如公共安全、应急搜救、农林、环保、交通 、通信、气象、影视航拍等。无人机使…...

行为型设计模式-策略模式(Strategy Pattern)

策略模式 策略模式&#xff1a;百度百科中引述为&#xff1a;指对象有某个行为&#xff0c;但是在不同的场景中&#xff0c;该行为有不同的实现算法。 策略模式是对算法的包装&#xff0c;是把使用算法的责任和算法本身分割开来&#xff0c;委派给不同的对象管理。策略模式通…...

html中RGB和RGBA颜色表示法

文章目录 RGB什么是RGBRGB颜色模式的取值范围RGB常用颜色对照表 RGBA什么是RGBARGBA颜色模式的取值范围 总结 RGB 什么是RGB RGB是一种颜色空间&#xff0c;其中R代表红色&#xff08;Red&#xff09;、G代表绿色&#xff08;Green&#xff09;、B代表蓝色&#xff08;Blue&a…...

【BEV感知】BEVFormer 融合多视角相机空间特征和时序特征的端到端框架 ECCV 2022

前言 本文分享BEV感知方案中,具有代表性的方法:BEVFormer。 基本思想:使用可学习的查询Queries表示BEV特征,查找图像中的空间特征和先前BEV地图中的时间特征。 它基于Deformable Attention实现了一种融合多视角相机空间特征和时序特征的端到端框架,适用于多种自动驾驶感…...

git拉取hugging face代码失败:443

报错信息&#xff1a;fatal: unable to access http://huggingface.co/THUDM/chatglm2-6b/: OpenSSL SSL_connect: Connection reset by peer in connection to huggingface.co:443 解决方法&#xff1a;&#xff08;127.0.0.1:7890配置为自己的实际代理ip及端口&#xff09; …...

【赠书活动】OpenCV4工业缺陷检测的六种方法

文章目录 前言机器视觉缺陷检测工业上常见缺陷检测方法延伸阅读推荐语 赠书活动 前言 随着工业制造的发展&#xff0c;对产品质量的要求越来越高。工业缺陷检测是确保产品质量的重要环节&#xff0c;而计算机视觉技术的应用能够有效提升工业缺陷检测的效率和精度。 OpenCV是一…...

设计模式之创建型设计模式(一):单例模式 原型模式

单例模式 Singleton 1、什么是单例模式 在软件设计中&#xff0c;单例模式是一种创建型设计模式&#xff0c;其主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 这意味着无论何时需要该类的实例&#xff0c;都可以获得相同的实例&#xff0c;而不会创建…...

Amazon CodeWhisperer 在 vscode 的应用

文章作者:旧花阴 CodeWhisperer 是一款可以帮助程序员更快、更安全地编写代码的工具&#xff0c;可以在他们的开发环境中实时提供代码建议和推荐。亚马逊云科技发布的这款代码生成工具 CodeWhisperer 最大的优势就是对于个人用户免费。以在 vscode 为例&#xff0c;演示安装过程…...

【Java】基于fabric8io库操作k8s集群实战(pod、deployment、service、volume)

目录 前言一、基于fabric8io操作pod1.1 yaml创建pod1.2 fabric8io创建pod案例 二、基于fabric8io创建Service&#xff08;含Deployment&#xff09;2.1 yaml创建Service和Deployment2.2 fabric8io创建service案例 三、基于fabric8io操作Volume3.1 yaml配置挂载存储卷3.2 基于fa…...

uniapp微信小程序下载保存图片流到本地,base64

我们在开发时下载图片或文件&#xff0c;地址基本上都是https的格式&#xff0c;下面来说一下后端返回base64的文件流&#xff0c;是如何下载的 必须把返回的流去掉这一部分&#xff1a;data:image/png;base64&#xff0c;否则下载不了 如我自己的流&#xff1a; data:image/…...

华为数通——企业双出口冗余

目标&#xff1a;默认数据全部经过移动上网&#xff0c;联通低带宽。 R1 [ ]ip route-static 0.0.0.0 24 12.1.1.2 目的地址 掩码 下一条 [ ]ip route-static 0.0.0.0 24 13.1.1.3 preference 65 目的地址 掩码 下一条 设置优先级为65 R…...

送奶APP开发:终极指南

您是否有兴趣使用新鲜牛奶和乳制品&#xff0c;但不想每天早上去乳制品店或最近的商店&#xff1f;借助技术&#xff0c;订购日常用品&#xff08;例如杂货和牛奶&#xff09;变得更加简单。 DailyMoo 是最受欢迎的送奶应用&#xff0c;收入达数百万人民币。因此&#xff0c;投…...

Ngnix之反向代理、负载均衡、动静分离

目录 1. Ngnix 1.1 Linux系统Ngnix下载安装 1.2 反向代理 正向代理&#xff08;Forward Proxy&#xff09;&#xff1a; 反向代理&#xff08;Reverse Proxy&#xff09;&#xff1a; 1.3 负载均衡 1.4 动静分离 1. Ngnix Nginx是一个高性能的开源Web服务器&#xff0…...

Habitat-Lab具身AI仿真平台:从核心概念到实战部署全解析

1. 项目概述&#xff1a;从零开始理解Habitat-Lab 如果你正在研究具身智能&#xff0c;或者对如何让AI在三维物理世界里“学会做事”感到好奇&#xff0c;那你大概率已经听说过Habitat-Lab这个名字。它不是一个游戏引擎&#xff0c;也不是一个单纯的机器人仿真器&#xff0c;而…...

基于MCP协议实现AI助手调用本地快捷指令的完整指南

1. 项目概述&#xff1a;一个为AI助手“开眼”的桥梁最近在折腾AI工作流的朋友&#xff0c;可能都听说过MCP&#xff08;Model Context Protocol&#xff09;这个概念。简单来说&#xff0c;它就像给Claude、Cursor这类AI助手装上了一套“万能遥控器”&#xff0c;让它们能直接…...

无人机图像拼接:算法原理详解与OpenCV实现

前言 无人机航拍因其灵活、高效、覆盖广的优势,在地形测绘、农业监测、大坝巡检、应急救援等领域得到了广泛应用。然而受限于相机视场角与飞行高度,单张航拍图像往往无法覆盖整个目标区域,需要通过**图像拼接(Image Stitching / Mosaicing)**技术,将多张存在重叠区域的图…...

ARM调试接口技术:SWD与JTAG协议切换机制详解

1. ARM调试接口技术深度解析 在嵌入式系统开发领域&#xff0c;调试接口如同工程师的"听诊器"&#xff0c;是连接开发环境与目标芯片的重要通道。作为行业标准&#xff0c;ARM架构提供了两种主流的调试协议&#xff1a;串行线调试(SWD)和JTAG。这两种协议各有特点&am…...

Digg 回归成 AI 新闻聚合器,追踪 1000 位 AI 领域人士关注内容

1. Digg 再次回归今年 1 月&#xff0c;Digg 以类似 Reddit 的社交新闻网站和应用程序的形式重新推出测试版&#xff0c;但仅仅两个月后&#xff0c;由于大量 AI 机器人涌入&#xff0c;Digg 被迫关闭&#xff0c;并进行了裁员。不过&#xff0c;截至周二&#xff0c;Digg 再次…...

pico示波器采集软件SSL1000A在功率器件测试的应用

在新能源汽车电控体系里&#xff0c;IGBT、MOSFET 是电机控制器、OBC、DC-DC 等核心模块的 “功率开关”&#xff0c;它们的开关特性、瞬态响应、稳定可靠性直接影响整车效率与安全。功率器件测试看似简单&#xff0c;实则细节要求极高&#xff0c;因为器件在高频开关中产生的尖…...

COCO数据集实例解析:从JSON结构到YOLO格式的实战转换

1. COCO数据集JSON结构深度解析 第一次打开COCO数据集的JSON文件时&#xff0c;我完全被里面复杂的嵌套结构搞懵了。这个文件就像俄罗斯套娃&#xff0c;一层套着一层。经过多次实战踩坑&#xff0c;终于摸清了它的门道。COCO的标注文件主要包含五个关键部分&#xff0c;每个部…...

不止是多旋翼:用CopterSim玩转固定翼仿真,从模型替换到3D场景飞行全记录

从多旋翼到固定翼&#xff1a;解锁CopterSim的跨机型仿真潜能 当大多数人提起CopterSim时&#xff0c;第一反应往往是多旋翼无人机的仿真利器。但鲜为人知的是&#xff0c;这款工具蕴藏着更广阔的仿真可能性——通过巧妙的模型替换与参数调整&#xff0c;它能够完美模拟固定翼飞…...

Eur J Nucl Med Mol Imaging(IF=7.6)南方医科大学南方医院北京协和医院等团队:基于PET/CT的深度学习预测食管癌PD-L1与免疫疗效

01文献学习今天分享的文献是由南方医科大学南方医院联合西安电子科技大学、北京协和医院等团队于2025年8月在《European Journal of Nuclear Medicine and Molecular Imaging》&#xff08;中科院1区&#xff0c;IF7.6&#xff09;上发表的研究“Deep learning-based non-invas…...

从ZZULIOJ这道题出发,聊聊面试常客:有序数组合并的三种写法与性能对比

从有序数组合并看算法优化&#xff1a;三种解法与百万级数据处理实战 在技术面试中&#xff0c;有序数组合并是一个经典且高频出现的问题。它不仅考察候选人对基础算法的掌握程度&#xff0c;更能检验其在实际问题中的优化思维。本文将以ZZULIOJ平台上的1124题为例&#xff0c;…...