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

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】

因为马上就要进入下一个阶段,制作动态编辑体积纹理的模块。

但在这之前,要在这一章做最后一些整理。

  • 首先,我们完成没完成的部分。
  • 其次,最后整理一下图表。
  • 最后,本文附上正在用的贴图

完善Shader

还记得我们之前注释掉了"阶梯纹理修复"的部分吗?
在这里插入图片描述
在这里插入图片描述

在第二章第七节中,我们已经修复了这个阶梯纹理。

CurPos += LocalCamVec * (1 - FinalStepSize);//只留了它

然而,在第三章对Shader进行大幅修改时,我们暂时将其注释掉并未继续处理。现在,我们将重新着手修复这个阶梯纹理问题。

希望你还记得,修复阶梯纹理的原理是将for循环的一步单独再以一个小步FinalStepSize执行一次。
因此,基本上就是将for循环中的内容复制出来,在for之后再运行一次。

//创建变量,从0开始累加沿相机方向步进过程中的总密度
float accumdens = 0;//Shadow部分
//创建变量,透射率和光线的能量
float transmittance =1;
float3 lightenergy = 0;
//基本和相机方向步进一样,但这些都是常量,不需要写进for里
Density *= StepSize;
LightVector *= ShadowStepSize;
ShadowDensity *= ShadowStepSize;
//一个对数来计算阈值,用来判断光线是否还值得计算
float shadowthresh = -log(ShadowThreshold)/ShadowDensity;//使用 MaxSteps 作为最大步数进行循环,每次循环执行以下操作
for (int i = 0; i < MaxSteps; i++)
{float cursample = PseudoVolumeTexture(Tex, TexSampler, saturate(CurPos), XYFrames, NumFrames).r;// 在当前步进位置进行纹理采样//Shadow部分if(cursample > 0.001)//如果采样位置没有密度,则跳过{float3 Lpos = CurPos;//Lpos将作为光线步进的起始位置float shadowdist = 0;//和之前的accumdens一样,积累阴影//自阴影for(int s = 0; s < ShadowSteps; s++){Lpos += LightVector;//移动步进位置float Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;//采样//判断是否在框内,不是则直接break退出forfloat3 shadowboxtest = floor( 0.5+ (abs(0.5-Lpos)));//float exitshadowbox = shadowboxtest.x + shadowboxtest.y + shadowboxtest.z;float exitshadowbox = dot(shadowboxtest,1);//简短的通道相加if(shadowdist > shadowthresh || exitshadowbox >= 1) break;shadowdist += Lsample;//累计}//接收阴影float3 dfpos = 2 * (CurPos -0.5) * LocalObjectBoundsMax;//-0.5 * 2,得到一个居中的Bounddfpos = LWCToFloat(TransformLocalPositionToWorld(Parameters,dfpos)) - CameraPosWS;//将dfpos转换为世界空间,需要LWC精度所以在代码里转换,减去相机位置float dftracedist = 1; //创建四个变量float dfshadow = 1;//这是我们最终要的float curdist = 0;float DistanceAlongTrace = 0;for (int d = 0; d < DFSSteps; d++)//又一次的光线步进{DistanceAlongTrace += curdist;//增加距离curdist = GetDistanceToNearestSurfaceGlobal(dfpos);//采样全局距离场,他和蓝图里`DistanceToNearestSurface`是相同函数float SphereSize = DistanceAlongTrace * LightTangent;//采样距离场软阴影的球形距离dfshadow = min( saturate(curdist/SphereSize),dfshadow);//用小于它的结果来更新变量dfpos.xyz += LightVectorWS * dftracedist * curdist;//继续移动位置dftracedist *= 1.0001;//增加一个很小的因子}//更新样本和光能,算法是BeersLaw函数cursample = 1 -exp(-cursample * Density);lightenergy += exp(-shadowdist * ShadowDensity) * cursample * transmittance * LightColor * dfshadow;//在结果上乘dfshadowtransmittance *= 1-cursample;//环境光照部分shadowdist = 0;//重置一下阴影距离,继续利用它计算光照Lpos = CurPos + float3(0,0,0.025);//新位置float Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;//采样shadowdist += Lsample;Lpos = CurPos + float3(0,0,0.05);Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;//采样shadowdist += Lsample;Lpos = CurPos + float3(0,0,0.15);Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;//采样shadowdist += Lsample;lightenergy += exp(-shadowdist * AmbientDensity) *cursample * SkyColor * transmittance;//累计到光}CurPos += -LocalCamVec;
}CurPos += LocalCamVec * (1 - FinalStepSize);
float cursample = PseudoVolumeTexture(Tex, TexSampler, saturate(CurPos), XYFrames, NumFrames).r;//从上面复制过来,使用 FinalStepSize 结果再 Step 一次,进行阶梯修复if(cursample > 0.001){float3 Lpos = CurPos;float shadowdist = 0;for(int s = 0; s < ShadowSteps; s++){Lpos += LightVector;float Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;float3 shadowboxtest = floor( 0.5+ (abs(0.5-Lpos)));float exitshadowbox = dot(shadowboxtest,1);if(shadowdist > shadowthresh || exitshadowbox >= 1) break;shadowdist += Lsample;}float3 dfpos = 2 * (CurPos -0.5) * LocalObjectBoundsMax;dfpos = LWCToFloat(TransformLocalPositionToWorld(Parameters,dfpos)) - CameraPosWS;float dftracedist = 1; float dfshadow = 1;float curdist = 0;float DistanceAlongTrace = 0;for (int d = 0; d < DFSSteps; d++){DistanceAlongTrace += curdist;curdist = GetDistanceToNearestSurfaceGlobal(dfpos);float SphereSize = DistanceAlongTrace * LightTangent;dfshadow = min( saturate(curdist/SphereSize),dfshadow);dfpos.xyz += LightVectorWS * dftracedist * curdist;dftracedist *= 1.0001;}cursample = 1 -exp(-cursample * Density);lightenergy += exp(-shadowdist * ShadowDensity) * cursample * transmittance * LightColor * dfshadow;transmittance *= 1-cursample;shadowdist = 0;Lpos = CurPos + float3(0,0,0.025);float Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;shadowdist += Lsample;Lpos = CurPos + float3(0,0,0.05);Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;shadowdist += Lsample;Lpos = CurPos + float3(0,0,0.15);Lsample = PseudoVolumeTexture(Tex, TexSampler, saturate(Lpos), XYFrames, NumFrames).r;shadowdist += Lsample;lightenergy += exp(-shadowdist * AmbientDensity) *cursample * SkyColor * transmittance;}return float4(lightenergy, transmittance);

整理图表

老样子,我们做整理,消除意大利面可以让我们更直观的感受shader中的各种关系

  1. 将这一部分RayMarching的参数折叠为RayMarchingParameter
    在这里插入图片描述
    在这里插入图片描述

  2. 打包环境和常量参数Constant
    在这里插入图片描述
    在这里插入图片描述

  3. 整理自阴影距离场的变量SelfShadow
    在这里插入图片描述
    在这里插入图片描述

  4. 打包投影的参数ShadowRayParameter
    在这里插入图片描述
    在这里插入图片描述

  5. 最后整理一下ShadowRayMarching输入顺序,按功能排序
    在这里插入图片描述


当前Shader

抄抄党注目

模型

在这里插入图片描述

长宽高100cm,轴居中,双面双材质ID的Cube模型

本文附下载

预览贴图

在这里插入图片描述

长宽高100cm,轴居中,双面双材质ID的Cube模型。

本文附下载

材质球

M_VolRayMarching
MI_VolRayMarching
MI_VolRayMarching_Shadow

父子关系
子实例材质
子实例材质
MI_VolRayMarching
M_VolRayMarching
MI_VolRayMarching_Shadow

在这里插入图片描述

M_VolRayMarching

细节

在这里插入图片描述

图表

在这里插入图片描述

MI_VolRayMarching

父材质为M_VolRayMarching

MI_VolRayMarching_Shadow

父材质为MI_VolRayMarching

  • 细节:
    在这里插入图片描述

相关文章:

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第六篇-阶段总结篇】

因为马上就要进入下一个阶段&#xff0c;制作动态编辑体积纹理的模块。 但在这之前&#xff0c;要在这一章做最后一些整理。 首先&#xff0c;我们完成没完成的部分。其次&#xff0c;最后整理一下图表。最后&#xff0c;本文附上正在用的贴图 完善Shader 还记得我们之前注…...

地球村上一些可能有助于赚钱的20个思维方式

地球村上一些可能有助于赚钱的20个思维方式&#xff1a; 1. 目标导向思维&#xff1a;明确自己的财务目标&#xff0c;并制定详细、可执行的计划来逐步实现。 2. 创新思维&#xff1a;不断寻求新的商业机会和独特的解决方案&#xff0c;以在竞争激烈的市场中脱颖而出。 3. 价值…...

0基础入门matlab

目录 一、命令 二、变量命名 三、数据类型 数字 字符和字符串 矩阵 rand、randi和randn的区别&#xff1f; 元胞数组和结构体 MAGIC 结构体 四、矩阵构造、四则运算、矩阵下标 五、MATLAB逻辑与流程控制 六、MATLAB绘图 二维平面绘图 三维平面绘图 导出图片 内…...

【前端】实操tips集合

1. 关闭vue中组件名字的多词校验 (1) package.json文件中修改eslint配置 "eslintConfig": {"rules": {"vue/multi-word-component-names":"off" }}, &#xff08;2&#xff09;.eslintrc.js或者.eslintrc配置文件中进行配置 modu…...

基于Springboot+Vue 传统文化管理系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取&#xff1a;https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…...

质量漫谈一

我知道很多同学看到这类问题&#xff0c;第一反应想要去寻找的就是作为测试角色&#xff0c;应该要如何如何去做&#xff1f;但是今天这里作为质量第一篇&#xff0c;不打算按照这样单角度去写&#xff0c;这类同学可以就此打住&#xff0c;如果在意的话&#xff0c;可关注后续…...

个体化神经调控 Neurolnavigation介绍

神经调控技术包括DBS, TMS, rTMS, tDCS等等。今天主要说一下TMS。 TMS全程经颅磁刺激&#xff0c;通过对头皮放置磁场线圈&#xff0c;可以定向的往局部头皮发送脉冲信号&#xff0c;抑制局部神经元活动。 TMS的优点是精准刺激&#xff0c;tDCS的优点是刺激范围比较宽泛。近期有…...

02-RT1060 双ADC采样+eDMA传输

RT1060-双ADC+eDMA外设的配合使用 该项目是基于MIMXRT1060-EVKB官方开发板编写的驱动。 一、头文件包含介绍 #include "pin_mux.h" #include "clock_config.h" #include "board.h" #include "fsl_adc.h" #include "fsl_adc_et…...

单值集合总复习

1&#xff1a;Object类的核心方法复习 Object 是所有类【引用数据类型】的 直接 / 间接 父类 toString(): 将一个 引用数据类型的对象 转换成 String 类型 class Object{//Sun //toString()不需要参数&#xff1a;将一个对象转换成字符串 将调用者转换成字符串 public String …...

Pyside6 布局管理器(4)--- QGridLayout的使用

一、QGridLayout的介绍&#xff08;官翻&#xff09; QGridLayout 获得可用的空间&#xff08;由其父布局或 parentWidget() 提供&#xff09;&#xff0c;将其划分为行和列&#xff0c;并将其管理的每个小部件放入正确的单元格中。 列和行的行为是相同的&#xff1b;我们将…...

从GPT定制到Turbo升级再到Assistants API,未来AI世界,你准备好了吗?

引言 在OpenAI DevDay发布会上&#xff0c;OpenAI再次震撼整个人工智能行业&#xff0c;为AI领域带来了重大的更新。CEO Sam Altman宣布推出了定制版本的ChatGPT&#xff0c;这意味着用户现在可以根据自己的需求打造个性化的GPT&#xff0c;并分享至GPT Store。这一消息对于受…...

「漏洞复现」BladeX企业级开发平台 tenant/list SQL 注入漏洞复现(CVE-2024-33332)

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…...

基于SSM的消防物资存储系统【附源码】

基于SSM的消防物资存储系统 效果如下&#xff1a; 用户功能界面 仓库管理界面 物资入库管理界面 物资出库管理界面 物资详情管理界面 报警通知管理界面 安全检查提醒管理界面 管理员功能界面 研究背景 21世纪&#xff0c;我国早在上世纪就已普及互联网信息&#xff0c;互联网…...

Pseudo Multi-Camera Editing 数据集:通过常规视频生成的伪标记多摄像机推荐数据集,显著提升模型在未知领域的准确性。

2024-10-19&#xff0c;由伊利诺伊大学厄巴纳-香槟分校和香港城市大学的研究团队提出了一种创新方法&#xff0c;通过将常规视频转换成伪标记的多摄像机视角推荐数据集&#xff0c;有效解决了在未知领域中模型泛化能力差的问题。数据集的创建&#xff0c;为电影、电视和其他媒体…...

认识一下 Mochi-1--最新的免费开源人工智能视频模型

Genmo 是一家专注于视频生成的人工智能公司&#xff0c;该公司宣布发布 Mochi 1 的研究预览版。Mochi 1 是一种新的开源模型&#xff0c;可根据文本提示生成高质量视频&#xff0c;其性能可与 Runway 的 Gen-3 Alpha、Luma AI 的 Dream Machine、Kuaishou 的 Kling、Minimax 的…...

Spring 的事务传播机制

Spring 的事务传播机制定义了一个事务方法在遇到已经存在的事务时如何处理。事务传播属性&#xff08;Propagation&#xff09;提供了七种机制&#xff0c;以适应不同的业务需求和事务边界管理。 1. Spring 的事务传播机制的类型 &#xff08;1&#xff09;REQUIRED&#xff…...

线性代数(1)——线性方程组的几何意义

线性代数的基本问题是求解个未知数的个线性方程&#xff1b; 例如&#xff1a;&#xff08;方程1&#xff09;。 在线性代数的第一讲中&#xff0c;我们从Row Picture、Column Picture、Matrix Picture三个角度来看这个问题。 上面的系统是二维的。通过添加第三个变量&#…...

写给自己的一些心得体会

为什么是CSDN??? 最近跑实验跑得绝望&#xff0c;感觉自己兜兜转转走了太多太多的弯路&#xff0c;我不知道这样的弯路什么时候是个尽头&#xff0c;就像在USJ排队&#xff0c;看似好像要到入口了&#xff0c;实则一转头还是无尽绵延的队伍。走了这么多弯路&#xff0c;总要…...

论文阅读(二十九):Multi-scale Interactive Network for Salient Object Detection

文章目录 Abstract1.Introduction2.Scale VariationProposed Method3.1Network Overview3.2Aggregate Interaction Module3.3 Self-Interaction Module3.4Consistency-Enhanced Loss 4.Experiments4.1Implementation Details4.2 Comparison with State-of-the-arts4.3Ablation …...

常见存储器及其特点

&#xff1a; 一、只读存储器&#xff08;ROM&#xff09;及其类型 1. ROM 特点&#xff1a;存储的数据固定不变&#xff0c;只能读出不能写入&#xff0c;且断电后数据不丢失。应用&#xff1a;通常用于存储系统程序&#xff0c;如BIOS等。 2. PROM&#xff08;可编程只读…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...