利用第三方后期处理材质(PostProcess Material)对物体进行描边【UE4】【C++】
效果图:
第一步,创建C++ Basic Code
第二步,定义键盘和鼠标输入的映射
第三步,修改 Rendering 中的 Custom Depth - Stencil Pass
第四步,找到GlobalPostProcessVolume [如果没有的话自行拖放一个PostProcessVolume组件]
将 unbound 勾选上
再修改 Blendables 为 PPI_OutlineColored
完整代码如下:
MyPlayer.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Character.h"
#include "MyPlayer.generated.h"UCLASS()
class OUTLINECPLUSPLUS_API AMyPlayer : public ACharacter
{GENERATED_BODY()public:// Sets default values for this character's propertiesAMyPlayer();void MoveForward(float val);void MoveRight(float val);void LookYaw(float val);void LookPitch(float val);void Use();class AInteractableActor* FindFocusedActor();void HandleHighlight();// Called when the game starts or when spawnedvirtual void BeginPlay() override;// Called every framevirtual void Tick( float DeltaSeconds ) override;// Called to bind functionality to inputvirtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;private:UPROPERTY(EditDefaultsOnly)float InteractionDistance = 300.f; // 交互的范围class AInteractableActor* FocusedActor;// 用于 LineTraceSingleByChannelFCollisionQueryParams TraceParams;
};
MyPlayer.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "InteractableActor.h"
#include "MyPlayer.h"// Sets default values
AMyPlayer::AMyPlayer()
{// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.PrimaryActorTick.bCanEverTick = true;TraceParams = FCollisionQueryParams(FName(TEXT("TraceParams")), false, this);TraceParams.bTraceComplex = false;TraceParams.bTraceAsyncScene = false;TraceParams.bReturnPhysicalMaterial = false;
}// Called when the game starts or when spawned
void AMyPlayer::BeginPlay()
{Super::BeginPlay();}// Called every frame
void AMyPlayer::Tick( float DeltaTime )
{Super::Tick( DeltaTime );if (Controller && Controller->IsLocalController()){HandleHighlight();}}// Called to bind functionality to input
void AMyPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{Super::SetupPlayerInputComponent(PlayerInputComponent);InputComponent->BindAxis("MoveForward", this, &AMyPlayer::MoveForward);InputComponent->BindAxis("MoveRight", this, &AMyPlayer::MoveRight);InputComponent->BindAxis("LookYaw", this, &AMyPlayer::LookYaw);InputComponent->BindAxis("LookPitch", this, &AMyPlayer::LookPitch);InputComponent->BindAction("Use", IE_Pressed, this, &AMyPlayer::Use);}
// 前后移动
void AMyPlayer::MoveForward(float val)
{FRotator Rotation(0, GetActorRotation().Yaw, 0); // Roll, Yaw, PitchFVector forward = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X);AddMovementInput(forward, val);
}// 左右移动
void AMyPlayer::MoveRight(float val)
{FRotator Rotation(0, GetActorRotation().Yaw, 0); // Roll, Yaw, PitchFVector right = FRotationMatrix(Rotation).GetScaledAxis(EAxis::Y);AddMovementInput(right, val);
}// 左右转向
void AMyPlayer::LookYaw(float val)
{AddControllerYawInput(val);
}// 上下转向
void AMyPlayer::LookPitch(float val)
{// 注意方向相反AddControllerPitchInput(val);
}// 按 E 键与激活对象进行交互
void AMyPlayer::Use()
{AInteractableActor* Interactable = FindFocusedActor();if (Interactable){// OnInteract_ImplementationInteractable->OnInteract(this);}
}AInteractableActor* AMyPlayer::FindFocusedActor()
{if (!Controller){return nullptr;}FVector Location;FRotator Rotation;FHitResult Hit(ForceInit);Controller->GetPlayerViewPoint(Location, Rotation);FVector Start = Location;FVector End = Start + (Rotation.Vector() * InteractionDistance);// 通过 “射线拾取” 选定对象GetWorld()->LineTraceSingleByChannel(Hit, Start, End, ECC_Camera, TraceParams);if (Hit.bBlockingHit) // 击中{// 获取当前被击中的对象的引用AInteractableActor* MyCastActor = Cast<AInteractableActor>(Hit.GetActor());if (MyCastActor){return MyCastActor;}}return nullptr;
}void AMyPlayer::HandleHighlight()
{AInteractableActor* NewHighlight = FindFocusedActor();if (NewHighlight){// 如果当前描边和新激活的对象不是同一个if (FocusedActor != NewHighlight){if (FocusedActor){// 当前描边对象取消描边FocusedActor->OnEndFocus();}// 描边新激活对象NewHighlight->OnBeginFocus();FocusedActor = NewHighlight;}}else{if (FocusedActor){// 取消描边FocusedActor->OnEndFocus();FocusedActor = nullptr;}}
}
InteractableActor.h
// Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "GameFramework/Actor.h"
#include "OutlineCPlusPlus.h"
#include "InteractableActor.generated.h"UCLASS()
class OUTLINECPLUSPLUS_API AInteractableActor : public AActor
{GENERATED_BODY()public: // Sets default values for this actor's propertiesAInteractableActor();// Called when the game starts or when spawnedvirtual void BeginPlay() override;// Called every framevirtual void Tick( float DeltaSeconds ) override;UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = Interaction)void OnInteract(AActor* Caller) ;virtual void OnInteract_Implementation(AActor* Caller);void OnBeginFocus();void OnEndFocus();private:UPROPERTY(EditDefaultsOnly)uint32 bCanInteract : 1;TArray<UMeshComponent*> Meshes;UPROPERTY(EditDefaultsOnly)EStencilColor Color = EStencilColor::SC_Green;};
InteractableActor.cpp
// Fill out your copyright notice in the Description page of Project Settings.#include "MyPlayer.h"
#include "InteractableActor.h"// Sets default values
AInteractableActor::AInteractableActor()
{// 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;}// Called when the game starts or when spawned
void AInteractableActor::BeginPlay()
{Super::BeginPlay();for (UActorComponent* Mesh : GetComponentsByClass(UMeshComponent::StaticClass())){UMeshComponent* thisMesh = Cast<UMeshComponent>(Mesh);if (thisMesh){Meshes.Push(thisMesh);}}}// Called every frame
void AInteractableActor::Tick( float DeltaTime )
{Super::Tick( DeltaTime );}void AInteractableActor::OnInteract_Implementation(AActor* Caller)
{AMyPlayer* Player = Cast<AMyPlayer>(Caller);if (Player){GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Now deleting the interactable actor! "))); // 销毁自己Destroy();}}void AInteractableActor::OnBeginFocus()
{if (bCanInteract){for (UMeshComponent* Mesh : Meshes){Mesh->SetRenderCustomDepth(true);Mesh->SetCustomDepthStencilValue((uint8)Color);}}
}void AInteractableActor::OnEndFocus()
{if (bCanInteract){for (UMeshComponent* Mesh : Meshes){Mesh->SetRenderCustomDepth(false);}}
}
颜色 的 Enum
UENUM(BlueprintType)
enum class EStencilColor : uint8
{SC_Green = 250 UMETA(DisplayName = "Green"),SC_Blue = 251 UMETA(DisplayName = "Blue"),SC_Red = 252 UMETA(DisplayName = "Red"),SC_White = 253 UMETA(DisplayName = "White")
};
第三方材质下载链接
PostProcess 官方文档
利用第三方后期处理材质(PostProcess Material)对物体进行描边【UE4】【C++】相关推荐
- Unreal 后期处理材质范例
from: https://docs.unrealengine.com/latest/CHN/Engine/Rendering/PostProcessEffects/PostProcessMateri ...
- Unreal4 后期处理材质
后期处理材质 本页面的内容: 后期处理图表 使用后期处理材质 制作简单的后期处理材质 后期处理材质的关键设置 在不同材质实例之间进行混合 材质表现"SceneTexture" ...
- opengl地球贴纹理_一文看懂材质/纹理 Material, Texture, Shading, Shader 的区别
在计算机图形学和三维设计中,有几个容易混淆的概念.今天我们来一举拿下. 概念整理 可以这么总结: Material 是表现 Shading 的数据集.其他几个概念都是生成这一数据集的资源或者工具. 这 ...
- UE4后期处理材质:扁平化风格描边
1.利用基础颜色实现扁平化渲染 2.创建多边形描边 3.创建法线描边 4.完善描边效果 后期处理体积:用于应用或修改渲染到屏幕上的视觉效果,自定义后期处理材质通过改动渲染缓冲(在渲染画面上叠加RGB值 ...
- UE4 后期处理材质
1 在利用后期处理材质在视口上显示UI参考图标位置 如图操作 2 在后期盒子中添加后期材质
- 【Unity】11.5 物理材质 (Physics Material)
分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 物理材质 (Physics Material) 用于调整碰撞对象的摩擦力和反弹效果. 二.创建物理材质 要创建物理材质 ...
- 利用第三方浏览器漏洞钓鱼
6.4 利用第三方浏览器漏洞钓鱼 现在各种各样的浏览器导出不穷,然而都是建立在IE内核基础上的,而且在安全方面,这些"扩展"版本浏览器远比IE差了许多,很可能IE正常访问的页面,被 ...
- 如何利用第三方数据进行大数据分析
企业如何避免迷失在数据网络中?通过掌握大数据和第三方数据.但是,掌握第三方数据可能会非常具有挑战性,称其遵守严格的数据隐私规范是不可错过的.数据在增长,可以利用的机会也在增加.为了从第三方数据孤岛中获 ...
- 利用第三方服务平台实现简单的短信验证功能
在本篇文章中,将会利用第三方服务平台实现短信验证功能. 首先,先介绍一下刚才提及的第三方服务平台:mob.com 移动开发者服务平台 该平台呢,主要有以下几点功能: 1.为IOS.Android的AP ...
最新文章
- 关于动态规划,你想知道的都在这里了!
- 在Office 2007 Word文档中插入两种页码方法
- 给Xshell设置舒适的配色方案
- ansible(5)——使用通配符操作ansible命令
- (转)python3 计算字符串、文件md5值
- primefaces_PrimeFaces Mobile入门
- 【转】ORACLE中的子查询 ---OCP--047--46
- 【转】MySQL日期函数与日期转换格式化函数大全
- C语言程序设计实践-C语言应用实践
- 使用Excel生成符合正态分布的随机数
- JS 事件捕获、事件冒泡以及事件委托图文详解
- C++中的常对象和常对象成员
- 火萤视频壁纸(让你的桌面丰富多彩)
- CookGAN Causality based Text-to-Image Synthesis
- 现在做电商晚了吗?电商可以赚零花钱吗?
- K-SVD: An Algorithm for Designing Overcomplete Dictionaries for Sparse Representation
- win10关闭杀毒防护
- 管理跨国虚拟团队的技巧
- mysql触发器的作用及语法
- 机器的思考故事——计算机能学会牛顿第二定律吗?
热门文章
- 解决手机无法连接到电脑的问题
- 【新版阿里云控制台】使用体验与介绍
- ux许可服务器关机或未响应,ug11许可证错误解决方法96 nx许可证错误-96 ug打开错误代码96 ug12安装第二次时出现96错误 ug12提示许可证错误96 ug11许可证96...
- Chrome 96 版本无法发送跨域请求的问题 解决方案
- 信管专业如果考计算机证考什么,信管专业可以考的证书
- 福利应用更新,这几款都是老司机喜欢的
- [luogu1768]天路
- TortoiseSVN环境搭建
- 中南大学计算机技术考研科目,中南大学计算机技术(工程硕士专业学位)研究生考试科目和考研参考书目...
- Busybox 命令大全~~