【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

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

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

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

相关文章

联想ThinkPad笔记本怎么开启vt_ThinkPad笔记本开启vt虚拟化教程

最近使用联想ThinkPad笔记本的小伙伴们问我&#xff0c;联想ThinkPad笔记本怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术&#xff0c;当CPU支持VT-x虚拟化技术&#xff0c;有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中&#xff0c;手…

Florence-2视觉语言模型简明教程

近年来&#xff0c;计算机视觉领域见证了基础模型的兴起&#xff0c;这些模型无需训练自定义模型即可进行图像注释。我们已经看到了用于分类的 CLIP [2]、用于对象检测的 GroundingDINO [3] 和用于分割的 SAM [4] 等模型——每个模型都在其领域表现出色。但是&#xff0c;如果我…

将VSCode界面的显示语言改为简体中文,切换VScode界面的显示语言

VSCode界面默认的语言为英语&#xff0c;需要安装简体中文语言包&#xff0c;语言包为插件 &#xff08;Extension&#xff09;。 Step1: 点击左侧扩展按钮 Step2: 在搜索栏 &#xff0c;输入chinese Step3: 选择第一个简体中文&#xff0c;点击右下角install 按钮 Step4: 安装…

【K8S系列】Kubernetes node节点NotReady问题及解决方案详解【已解决】

Kubernetes 集群中的每个节点都是运行容器化应用的基础。当节点状态显示为 NotReady 时,意味着该节点无法正常工作,这可能会导致 Pod 无法调度,从而影响整个应用的可用性。本文将深入分析节点不健康的各种原因、详细的排查步骤以及有效的解决方案。 一、节点不健康的原因 节…

小程序视频SDK解决方案,提供个性化开发和特效定制设计

美摄科技作为视频处理技术的领航者&#xff0c;深知在这一变革中&#xff0c;每一个细微的创新都能激发无限可能。因此&#xff0c;我们精心打造了一套小程序视频SDK解决方案&#xff0c;旨在满足不同行业、不同规模客户的多元化需求&#xff0c;携手共创视频内容的璀璨未来。 …

推动AI技术研发与应用,景联文科技提供专业高效图像采集服务

景联文科技提供专业图像采集服务&#xff0c;涵盖多个领域的应用需求。 包含人体图像、人脸图像、手指指纹、手势识别、交通道路、车辆监控等图像数据集&#xff0c;计算机视觉图像数据集超400TB&#xff0c;支持免费试采试标。 高质量人像采集服务&#xff1a;支持不同光线条件…

Java最全面试题->Java基础面试题->JavaWeb面试题->Git/SVN面试题

文章目录 Git/SVN面试题Git和SVN有什么区别&#xff1f;SVN优缺点&#xff1f;Git优缺点&#xff1f;说一下Git创建分支的步骤&#xff1f;说一下Git合并的两种方法以及区别&#xff1f;Git如何查看文件的提交历史和分支的提交历史?什么是 git stash&#xff1f;什么是git sta…

纯前端实现语音合成并输出提示

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>语音合成</title><style>body {max-…

配置nginx服务通过ip访问多网站

1.关闭防火墙 [rootlocalhost wzj]# systemctl stop firewalld [rootlocalhost wzj]# sstenforce 0 bash: sstenforce: command not found... [rootlocalhost wzj]# setenforce 0 2&#xff0c;挂mnt [rootlocalhost wzj]# mount/dev/sr0/mnt bash: mount/dev/sr0/mnt: No suc…

Excel常用操作培训

1 Excel基本操作 1.1 常用快捷键 1.1.1快捷键操作工作簿、工作表 1.1.2快捷键操作 1.1.3单元格操作 1.1.4输入操作 2.1 常见功能描述 2.1.1 窗口功能栏 excel有很多功能可以用&#xff0c;新建文档后&#xff0c;可以最上方&#xff0c;可以看到所有的功能栏目 2.1.2 剪切板…

双链表的增删改查

目录 一、主程序&#xff08;test.c&#xff09; 二、自定义头文件&#xff08;DList.h&#xff09; 三、函数程序&#xff08;DList.c&#xff09; 一、主程序&#xff08;test.c&#xff09; #define _CRT_SECURE_NO_WARNINGS 1 #include "DList.h"int main() {…

思想是花 嘴是大地

思想是花 嘴是大地 作者&#xff1a;楚旺群 把最美丽的花 播种于嘴的田野 ——舌底生华 思想就会展现灿烂之花 做个比喻 思想是花 嘴是田野 世界上最美的是心灵之花 生成心灵之花的是舌底生灿 最慰藉心田的是话语 产生语言的沃土是嘴把思想来展现 语言交流 它就是产生思…

Spring中导致事务传播失效的情况(自调用、方法访问权限、异常处理不当、传播类型选择错误等。在实际开发中,务必确保事务方法正确配置)

文章目录 1. 自调用&#xff08;内部调用&#xff09;导致事务失效示例&#xff1a;解决办法&#xff1a; 2. 事务方法不是 public 修饰示例&#xff1a;解决办法&#xff1a; 3. 未被 Spring 管理的对象示例&#xff1a;解决办法&#xff1a; 4. 异常类型不匹配导致事务回滚失…

Flutter中使用Cookies

Cookie Cookie 是一种在用户的浏览器中存储的小型文本文件&#xff0c;用于保存有关用户和他们的访问信息。它们通常用于以下目的&#xff1a; 主要功能 会话管理&#xff1a;保持用户登录状态&#xff0c;例如识别已登录的用户。个性化设置&#xff1a;保存用户的偏好设置&a…

Xcode真机运行正常,打包报错

1.问题&#xff1a; 老项目Xcode真机运行没问题&#xff0c;但但打包的时候却报了以下错误&#xff1a; some files could not be transferred (code 23) at /AppleInternal/Library/BuildRoots/4ff29661-3588-11ef-9513-e2437461156c/Library/Caches/com.apple.xbs/Sources/r…

基于python智能推荐的丢失物品招领网站的制作,前端vue+django框架,协同过滤算法实现推荐功能

背景 基于 Python 智能推荐的丢失物品招领网站&#xff0c;通过前端 Vue 和后端 Django 框架的结合&#xff0c;为用户提供便捷、个性化的服务。该系统的核心在于实现智能推荐功能&#xff0c;采用协同过滤算法来提高用户体验&#xff0c;帮助用户更快找到合适的失物或招领信息…

爬虫日常实战

爬取美团新闻信息&#xff0c;此处采用两种方法实现&#xff1a; 注意点&#xff1a;因为此处的数据都是动态数据&#xff0c;所以一定要考虑好向下滑动数据包会更新的情况&#xff0c;不然就只能读取当前页即第一页数据&#xff0c;方法一通过更新ajax数据包网址页数&#xf…

代码随想录算法训练营第51天|101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104.建造最大岛屿

文章目录 101. 孤岛的总面积102. 沉没孤岛103. 水流问题104.建造最大岛屿 101. 孤岛的总面积 卡码网 101. 孤岛的总面积 代码随想录 from collections import deque n, m map(int, input().split())matrix []for i in range(n):matrix.append(list(map(int, input().split(…

二叉树展开为链表

二叉树展开为链表 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同…

07 实战:视频捕获

代码如下: import tkinter as tk # 导入tkinter库,用于创建图形用户界面 from tkinter import ttk, filedialog, messagebox # 导入tkinter的额外部件、文件对话框和消息框 import cv2 # 导入OpenCV库,用于图像处理 import numpy as np # 导入NumPy库,用于数值计算 from P…