UE5实现PS图层样式投影效果

news2025/6/28 4:18:54

一、PS图层样式投影效果

1、创建材质函数

MF_PS_Style_Shadow

公开到库(可选) 

 

 定义 function input。

 Shadow代码:

/**
PS图层样式投影效果
	@param {UVs}				texture coordinate
	@param {TextureObject}		texture object
	@param {TextureSize}		纹理大小
	@param {ShadowRGBA}			投影颜色与不透明度
	@param {ShadowRotate}		投影角度
	@param {ShadowLength}		投影距离
	@param {ShadowSize}			投影大小
	@param {OpacityThreshold}	纹理透明度阈值
	@param {BorderThreshold}	边界透明度阈值
*/
float4 Shadow(float2 UVs, Texture2D TextureObject, float2 TextureSize, float4 ShadowRGBA, float ShadowRotate, half ShadowLength, half ShadowSize, float OpacityThreshold = 0, float BorderThreshold = 0.0001) {
	const float PI = acos(-1);
	// 单位像素
	float2 TexturePixel = 1 / TextureSize;
	// 角度
	float Angle = 360 * ShadowRotate;
	// 弧度
	float Degrees = Angle / 180 * PI;
	// 阴影反向方位(单位向量)
	float2 Direction = TexturePixel * float2(cos(Degrees), sin(Degrees));
	
	class Function {
		Texture2D TextureObject;
		SamplerState TextureObjectSampler;
		float4 ShadowRGBA;
		float2 Position;
		float OpacityThreshold;
		float BorderThresholdLeftAndTop;
		float BorderThresholdRightAndBottom;
		
		float PI;
		float2 TexturePixel;
		
		float4 GetShadowRGBA(float2 UVs, out half ShadowStep) {
			ShadowStep = 0;
			float4 TextureRGBA = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, UVs, 0).xyzw;
			if (TextureRGBA.w > this.OpacityThreshold) {
				return TextureRGBA;
			}
			ShadowStep = 1;
			// 阴影反向方位 UVs
			float2 PositionUVs = UVs + this.Position;
			// 阴影反向方位 UVs 超出了 0 - 1 的范围则不计算
			if (PositionUVs.x < this.BorderThresholdLeftAndTop || PositionUVs.x > this.BorderThresholdRightAndBottom || PositionUVs.y < this.BorderThresholdLeftAndTop || PositionUVs.y > this.BorderThresholdRightAndBottom) {
				return TextureRGBA;
			}
			ShadowStep = 2;
			// 阴影反向方位像素点不透明度
			float PositionOpacity = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, PositionUVs, 0).w;
			if (PositionOpacity < this.OpacityThreshold) {
				return TextureRGBA;
			}
			ShadowStep = 3;
			// 返回阴影RGBA
			return this.ShadowRGBA;
		}
		
		float4 CalculateGetShadowSizeRGBA(float2 UVs) {
			float4 ShadowSizeRGBA = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, UVs, 0).xyzw;
			return ShadowSizeRGBA.w < this.OpacityThreshold ? ShadowSizeRGBA : this.ShadowRGBA;
		}
		
		float Calculate1DGaussian(float x) {
			return exp(-0.5 * pow(this.PI * x, 2));
		}
		
		float4 GetShadowSizeRGBA(float2 UVs, half ShadowSize) {
			// 投影大小范围内像素颜色累加
			float4 RGBASum = float4(0, 0, 0, 0);
			// 投影大小范围内像素的权重
			float WeightSum = 0;
			for (half x = -ShadowSize; x <= ShadowSize; x++) {
				for (half y = -ShadowSize; y <= ShadowSize; y++) {
					float Weight = this.Calculate1DGaussian(x / ShadowSize) * this.Calculate1DGaussian(y / ShadowSize);
					WeightSum += Weight;
					float2 OffsetUVs = UVs + float2(x, y) * this.TexturePixel + this.Position;
					if (OffsetUVs.x < this.BorderThresholdLeftAndTop || OffsetUVs.x > this.BorderThresholdRightAndBottom || OffsetUVs.y < this.BorderThresholdLeftAndTop || OffsetUVs.y > this.BorderThresholdRightAndBottom) {
						continue;
					}
					float4 RGBA = this.CalculateGetShadowSizeRGBA(OffsetUVs);
					RGBASum += RGBA * Weight;
				}
			}
			return RGBASum / WeightSum;
		}
	};		// 注意要加分号
	
	// func.TextureObject = TextureObject;
	// func.TextureObjectSampler = TextureObjectSampler;
	// func.ShadowRGBA = ShadowRGBA;
	// func.Position = ShadowLength * Direction;
	// func.OpacityThreshold = OpacityThreshold;
	// func.BorderThresholdLeftAndTop = BorderThreshold;
	// func.BorderThresholdRightAndBottom = 1 - BorderThreshold;
	// func.PI = PI;
	// func.TexturePixel = TexturePixel;
	Function func = { TextureObject, TextureObjectSampler, ShadowRGBA, ShadowLength * Direction, OpacityThreshold, BorderThreshold, 1 - BorderThreshold, PI, TexturePixel };

	half ShadowStep;
	// 结果色
	float4 RGBA = func.GetShadowRGBA(UVs, ShadowStep);
	// 如果不是投影区域,则返回当前结果色
	if (ShadowStep <= 1 || ShadowSize < 1) {
		return RGBA;
	}
	
	// 返回计算阴影大小后的结果色
	return func.GetShadowSizeRGBA(UVs, ShadowSize);
}

2、创建材质

 M_PS_Style_Shadow

修改参数。

 如果之前没有公开到库,则使用 material function call 调用

 

 3、效果预览

一、渲染人物角色

1、创建渲染目标

 命名为 RT_Equipment。

用于 UI 贴图,修改参数,这里大小使用1024。

2、创建 Actor 

 

 命名 BP_Equipment。

添加 场景捕获组件2D。

 根据需要设置参数。

添加 骨骼网络体组件。

 

指定模型与动画。

调整好位置。

3、放入场景。

 将 BP_Equipment 放入 Level,也可以在运行时动态生成。

4、修改材质

由于 A 通道需要反向,所以之前的 Shadow 代码做如下改动:

改动一:

			float4 TextureRGBA = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, UVs, 0).xyzw;
			TextureRGBA = float4(TextureRGBA.rgb, 1 - TextureRGBA.a);
			if (TextureRGBA.w > this.OpacityThreshold) {
				return TextureRGBA;
			}

改动二:

			float PositionOpacity = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, PositionUVs, 0).w;
			if (1 - PositionOpacity < this.OpacityThreshold) {
				return TextureRGBA;
			}

改动三:

			float4 ShadowSizeRGBA = Texture2DSampleLevel(this.TextureObject, this.TextureObjectSampler, UVs, 0).xyzw;
			ShadowSizeRGBA = float4(ShadowSizeRGBA.rgb, 1 - ShadowSizeRGBA.a);
			return ShadowSizeRGBA.w < this.OpacityThreshold ? ShadowSizeRGBA : this.ShadowRGBA;

5、效果预览

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

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

相关文章

十、children的深入用法-React.Children对象上的方法

目标 理解什么是children掌握React.Children对象上的方法 知识点 什么是children上图中我们看到了&#xff0c;我们之前学过的React.createElement方法&#xff0c;现在大家发现jsx的内容&#xff0c;全部都体现在了该方法上&#xff1b;那么React.createElement其实是有三个…

专精特新企业数据集两份数据

专精特新企业数据集 一、三批专精特新上市、非上市公司数据分布 1、时间截止至2021年8月 2、区域范围&#xff1a;上市和非上市公司两大板块&#xff0c;涵盖申万一级行业 3、指标说明&#xff1a; 包含如下内容&#xff1a;专精特新上市公司名单汇总、第一批专精特新上市公…

opencv 入门学习

opencv 演示 输入说明 原图在顶层后然后再去按键&#xff0c;不然会失效&#xff08;未知原因&#xff09; 1.roberts 边缘检测 2.sobel算子 3.Canny算子 4.Laplace算子 5.Canny算子&#xff0c;轮廓显示 空格 人脸检测准备一张图片效果 默认显示原图和灰阶图 roberts 边缘…

MySQL版本号6和7去哪了

问题 MySQL版本号6和7去哪了 详细问题 笔者起初误以为MySQL版本号6和7可能由于存在诟病不受欢迎或由于MySQL版本迭代过快导致未能在市场上流行 但是在浏览MySQL官网注意到 MySQL在2017年发布了新的版本8.0,但是在此之前的上一一个版本是5.7,40&#xff0c;那么中间的6和7去哪…

并发编程永远绕不开的难题,跟着大牛带你Java并发编程从入门到精通

我们知道&#xff0c;很多框架或者自研组件的底层&#xff0c;都或多或少涉及到并发编程方面的技术点。 比如&#xff1a;在一些本地缓存组件中&#xff0c;当本地缓存过期后&#xff0c;需要从数据库加载数据&#xff0c;这个阶段中就会涉及到线程并发请求的处理&#xff1b;在…

微信小程序云开发

概念 小程序云开发&#xff0c;让前端程序员拥有后端的能力云函数 &#xff08;nodejs&#xff09;云数据库 &#xff08;mogodb&#xff09;云存储前端写好云函数 > 上传到云服务器 >实现自定云部署前端去调用云函数>间接通过云函数对数据库的操作前端>全栈 注意…

DSP之寄存器映射和CDM文件

DSP之寄存器映射和CDM文件 RAM&#xff1a;程序运行速度快&#xff0c;关掉电源&#xff0c;程序会丢失。 Flash&#xff1a;程序运行速度慢&#xff0c;关掉电源&#xff0c;程序不会丢失。 所以&#xff0c;程序一般存到Flash中&#xff0c;在运行的时候&#xff0c;由CPU将…

2010-2019年208个地级市城乡收入差距泰尔指数

2010-2019年208个地级市城乡收入差距泰尔指数 1、数据来源&#xff1a;各省的统计NJ以及部分地级市的NJ&#xff08;主要是地级市的城镇化率&#xff09; 城镇化率为常驻人口城镇化率而非户籍人口城镇化率。附件中也包含各个地级市的城镇化率&#xff0c;农村人均可支配收入2…

Linux开发工具(1)——yum

文章目录软件包管理器 —— yum安装软件的三个问题Linux开源生态yum查找软件yum下载软件yum删除软件配置yum源Linux下的工具本质也是指令 , 下面我会介绍几个常用的工具 , 分别是yum(相当于是手机上的应用商店 , 可以在里面下载工具 ) vim&#xff08;多模式编辑器&#xff09;…

【毕业设计】深度学习行人车辆流量计数系统 - 目标检测 python

文章目录0 前言1. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段2. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程3 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff…

机器学习-SVM算法

文章目录支持向量机1. 间隔与支持向量1.1. 点到超平面的距离1.2. 去掉绝对值1.3. 最大间隔2. 对偶问题2.1. 引入拉格朗日乘子2.2. 求偏导2.3. 得到对偶问题2.4. 求解内层函数 minw,bL(w,b,α)min_{w,b} L(w,b,\alpha)minw,b​L(w,b,α)2.5. 求解外层函数 maxαminw,bL(w,b,α)m…

.ko 加载报错 “unknown symbol in module or invalid parameter” 排查解决方法

.ko 加载报错 “unknown symbol in module or invalid parameter” 排查解决方法 问题来源 今天参照Sigmastar的文档&#xff0c;修改config重新编译kernel&#xff0c;打开板上RNDIS虚拟网口。 按照步骤重编后&#xff0c;在demo.sh加入insmod指令&#xff0c;按顺序在启动…

【计算机网络】—网络编程(socket)02

目录 一、网络编程的概念 二、UDP数据报套接字编程 2.1 回显服务器代码 2.2 翻译程序&#xff08;英译汉&#xff09; 三、TCP数据报套接字编程 3.1回显服务器 3.2 翻译服务器 一、网络编程的概念 网络编程&#xff1a;指网络上的主机&#xff0c;通过不同的进程&#x…

openlayer+ol-ext 裁剪 天地图 中国或者其他省份 范围进行展示

地图未裁剪或遮盖效果&#xff08;天地图&#xff09; 效果1.crop: 1.1裁剪天地图里面效果 参数&#xff1a; inner: true 1.2裁剪天地图外面 参数&#xff1a; inner: false 核心代码&#xff1a; let crop new Crop({feature: feature[0],inner: false,});vecLayer.addF…

【保姆级】新机器部署JDKTomcat

1、登录服务器&#xff0c;如果非root用户则切root用户 sudo su - 2、在/usr/tmp目录上传JDK、Tomcat安装包 3、将安装包移到/usr/lib目录 mv xxx /usr/lib 4、解压 & 重命名 tar -xzvf xxx mv xxx jdk、mv xxx tomcat 5、配置环境变量 vim /etc/profile JAVA_HOME/u…

引用参考文献[1,2]或者[1-3]

目录准备参考视频引用参考文献[1,2]引用参考文献[1-3]准备 word 2021 参考视频 word中同一位置引用多篇参考文献角标设置 引用参考文献[1,2] 把参考文献交叉引用到文章中&#xff0c;如下图所示 选中标签[1][2] &#xff0c;点击切换域代码&#xff1a; 然后如下图所示 …

递归经典例题 --- 青蛙跳台阶(图文详解)

目录 一、介绍 二、解题思路 介绍动态规划法 三、代码实现 一、介绍 所谓的青蛙跳台阶问题&#xff0c;就是指一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级&#xff08;最多只能跳2级&#xff09;。求该青蛙跳上一个n级的台阶总共有多少种跳法。 二、解题思路 首…

Spring核心解析—Resource与ResourceLoader接口

Resource你不得不知的事情前言Resource内容继承结构DOC解释提供的功能重要的内置Resource实现UrlResourceClassPathResourceFileSystemResourceServletContextResourceInputStreamResourceByteArrayResourceResourceLoader内容结构体系源码分析ResourcePatternResolver内容容器…

gdb调试插件的安装——gef/gdbinit/peda(记录向)

源地址&#xff1a;https://github.com/hugsy/ 根据上面的要求&#xff1a; gdb必须得8.0以上&#xff0c;python得3.6以上&#xff0c;但是一般裸机的gdb都是7.2&#xff0c;python是2.7。我们需要下载更高版本的gdb和python 先将系统自带的gdb删除&#xff1a; sudo yum r…

HMS Core手语服务荣获2022中国互联网大会“特别推荐案例”:助力建设数字社会

11月15日&#xff0c;HMS Core手语服务在2022&#xff08;第二十一届&#xff09;中国互联网大会 “互联网助力经济社会数字化转型”案例评选活动中&#xff0c;荣获“特别推荐案例”。 经过一年多的技术迭代和经验积累&#xff0c;HMS Core手语服务已与多个行业的开发者合作&a…