虚幻引擎 C++ 实现平面阴影
1、平面阴影介绍
平面阴影是一种相对简单的渲染阴影的方式,可以理解为对一个模型渲染两次,一次是渲染模型本身,另一次是渲染模型的投影。渲染投影可以看作是将模型的顶点变换到地面的投影空间再渲染,可以理解为渲染了一个“压扁”的模型。
相对于shadowMap,平面阴影对性能的损耗相对较小。shadowMap相当于对场景做了两次渲染(第一次在光源位置渲染记录深度纹理,第二次正常渲染);而平面阴影只对模型本身做两次渲染。且shadowMap受限于深度纹理的分辨率,渲染出的阴影会出现锯齿;平面阴影由于阴影本身也是模型,故不会出现明显的锯齿。
但是平面阴影不会在模型上产生阴影(如手臂遮住脸,脸上会有手臂的阴影);且只能投影在平面上(如果地面有其他模型,则阴影会被挡住)。
2、虚幻引擎实现平面阴影
2.1、实现思路
图2-1
思路是将模型通过全局位置偏移的方式,变换到投影的位置。如图2-1,在光线light作用下,模型上的一点p投射的阴影为p'。我们要计算的是px到px'、py到py'以及pz到0的偏移。pz到0好处理,偏移为-pz。要计算px到px'、py到py',首先要得到图2-1中的L,设光线方向向量为lightDir(已单位化)。则点p到点p'的向量为K=L*lightDir,则px到px'的偏移为向量K的X分量、py到py'的偏移为向量K的Y分量。
2.1、材质
2.2、C++部分:动态加载模型、材质
创建一个AMyActorShadow(继承AActor),作为平面阴影模型,添加与玩家控制人物相同的骨骼网格体,添加上平面阴影材质。然后在tick函数里获取玩家人物骨骼网格体的TransForm以及姿态,并更新至当前的骨骼网格体。代码如下:
AMyActorShadow(){// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;//skeleMesh 为成员变量if (skeleMesh == nullptr) {// 实例化一个网格体skeleMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("mesh"));skeleMesh->SetupAttachment(RootComponent);static ConstructorHelpers::FObjectFinder<USkeletalMesh> locMesh(TEXT("玩家人物骨骼网格体的引用"));if (locMesh.Succeeded()) {skeleMesh->SetSkeletalMesh(locMesh.Object, false);}// 关闭阴影skeleMesh->SetCastShadow(false);static UMaterialInterface* MiniMapmatInst = LoadObject<UMaterialInterface>(NULL, TEXT("平面阴影材质的引用"));UMaterialInstanceDynamic* MiniMapmatInstDynamic = UMaterialInstanceDynamic::Create(MiniMapmatInst, nullptr);if (MiniMapmatInstDynamic != nullptr) {int matNum = skeleMesh->GetNumMaterials();for (int i = 0; i < matNum; i++) {skeleMesh->SetMaterial(i, MiniMapmatInstDynamic);}}}}
code2-1 构造函数
// Called every frame
void AMyActorShadow::Tick(float DeltaTime)
{Super::Tick(DeltaTime);USkeletalMeshComponent* source = nullptr;for (TActorIterator<AthridPersonCharacter> itr(GetWorld()); itr; ++itr){AthridPersonCharacter* master = *itr;master->GetTransform();source = itr->FindComponentByClass<USkeletalMeshComponent>();break;}if (source){// 同步位置和朝向this->SetActorTransform(source->GetComponentTransform());// 同步骨骼模型姿态skeleMesh->SetMasterPoseComponent(source);}
}
code2-2 tick事件
3、最终效果
相关文章:

虚幻引擎 C++ 实现平面阴影
1、平面阴影介绍 平面阴影是一种相对简单的渲染阴影的方式,可以理解为对一个模型渲染两次,一次是渲染模型本身,另一次是渲染模型的投影。渲染投影可以看作是将模型的顶点变换到地面的投影空间再渲染,可以理解为渲染了一个“压扁”…...
leetcode 67. 二进制求和
二进制求和 已解答 简单 相关标签 相关企业 给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 示例 1: 输入:a “11”, b “1” 输出:“100” 示例 2: 输入:a “1010”, b “1011” 输出&…...
【C++ 面试 - 基础题】每日 3 题(一)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…...

【动态规划】1、不同路径II+2、三角形最小路径和
1、不同路径II(难度中等) 该题对应力扣网址 AC代码 只会写简单的if-else class Solution { public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {//1、定义子问题//2、子问题递推关系//3、确定dp数组的计算顺序…...

JavaEE-多线程编程单例模式
一、等待通知 系统内部,线程之间是抢占式执行的,随即调度,程序可以通过手动干预的方式,能够让线程一定程度的按咱们想要的顺序执行,无法主动让某个线程被调度,但可以主动让某个线程等待。等待通知可以安排…...

RHCA III之路---EX436-6
RHCA III之路---EX436-6 1. 题目2. 解题3. 确认 1. 题目 2. 解题 三台node分别运行 yum install -y device-mapper-multipath mpathconf --enable systemctl enable --now multipathd3. 确认 fdisk -l...

Vuex模块化 深入浅出超详细
Vuex 模块化 为什么需要模块化? 随着项目规模的增长,单一的 store 文件会变得庞大且难以管理; Vuex 的模块化是一种组织和管理应用状态的策略:,它允许将全局的状态管理分解成更小、更可管理的部分; 逻辑清…...
细说MCU检测按键输入的外部中断和修改HAL_GPIO_EXTI_IRQHandler() 的实现方法
目录 一、 硬件板及设计目的 二、建立工程 1.配置GPIO 2.配置时钟源和Debug 3.配置系统时钟 4.配置NVIC 三、代码编写 四、修改HAL_GPIO_EXTI_IRQHandler() 一、 硬件板及设计目的 本文使用的硬件板是ST的开发板NUCLEO-G474RE,板上MCU型号为ST…...

昂科烧录器支持XHSC小华半导体的32位微控制器HC32F005C6P
芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表,其中XHSC小华半导体的32位微控制器HC32F005C6P已经被昂科的通用烧录平台AP8000所支持。 HC32F005C6P是Low Pin Count、宽电压工作范围的MCU,集成12位1Msps高精度SARADC…...

根据 IP 地址配置子网示例(下挂 hub 接不同 vlan 终端)
我们一般根据端口配置子网比较简单,但是如果换接口,就又要到交换机上重新配置端口所属 vlan 了,紧急情况下,还是比较耽误时间的。但如果根据IP地址配置 vlan,则可以插在交换机上任意端口,排障时比较节省时间…...

Flink-DataWorks第四部分:数据同步(第60天)
系列文章目录 2.4.2 DataStudio侧实时同步 2.4.3 数据集成侧同步任务 文章目录 系列文章目录前言2.4.2 DataStudio侧实时同步2.4.3 数据集成侧同步任务 前言 本文主要详解了DataWorks的数据同步,为第四部分: 由于篇幅过长,分章节进行发布。…...
go post请求,参数是raw json格式,response是固定结构。
在Go语言中,使用net/http包可以很方便地发送HTTP请求,包括POST请求。当需要发送raw JSON格式的参数时,通常会使用encoding/json包来将Go的结构体序列化为JSON字符串,然后使用http.NewRequest函数创建请求,并通过http.C…...

国产开源大模型都有哪些?
随着ChatGPT引领的大模型热潮,国内的公司开始相继投入研发自己的人工智能大模型,截止到2023年10月,国产公司的大模型有近百个,包括一些通用大模型,比如百度的文心一言,也有特定领域的专用大模型,…...

基于Hadoop的超市进货推荐系统设计与实现【springboot案例项目】
文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍系统分析系统设计数据表设计表4-1:关于我们表4-2:用户表4-3:管理员表表4-4:token表表4-5:系统简介表4-6:收藏…...

ChatGPT能从这几个方面提升学术论文质量
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 写作和编辑高质量的学术论文是一项具有挑战性的任务。随着人工智能技术的进步,ChatGPT作为一种强大的语言生成工具,正逐渐成为提升论文质量的得力助手。从头脑风…...
Python3的安装及基础指令
Day 20 基础语法 1、环境:python2内置,安装并使用python3,最新版3.12版可以使用源码安装 # 查看python版本号 [rootpython ~]#yum list installed|grep python [rootpython ~]#yum list installed|grep epel [rootpython ~]# yum -y …...
使用Spring与JDK动态代理实现事务管理
使用Spring与JDK动态代理实现事务管理 在现代企业级应用开发中,事务管理是一项关键的技术,它可以保证一系列操作要么全部成功,要么全部失败,从而确保数据的一致性和完整性。Spring框架提供了强大的事务管理能力,但有时…...
服务器硬件及RAID配置
服务器及 RAID 磁盘阵列介绍 RAID0 俗称 “ 条带 ” ,它将两个或多个硬盘组成一个逻辑硬盘,容量是所有硬盘之和,因 为是多个硬盘组合成一个,故可并行写操作,写入速度提高,但此方式硬盘数据没有冗余&#…...

【经验总结】ShardingSphere5.2.1 + Springboot 快速开始
Sharding Sphere 官方文档地址: https://shardingsphere.apache.org/document/current/cn/overview/maven仓库:https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-jdbc 官方的文档写的很详尽到位,这里会截取部分…...

基于Golang实现Kubernetes边车模式
本文介绍了如何基于 Go 语言实现 Kubernetes Sidecar 模式,并通过实际示例演示创建 Golang 实现的微服务服务、Docker 容器化以及在 Kubernetes 上的部署和管理。原文: Sidecar Pattern with Kubernetes and Go[1] 在这篇文章中,我们会介绍 Sidecar 模式…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...

DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...