4.1 KiB
4.1 KiB
title, date, excerpt, tags, rating
| title | date | excerpt | tags | rating | ||||
|---|---|---|---|---|---|---|---|---|
| 正交投影混合 | 2026-05-03 00:00:00 | OrthoBlend 透视校正技术,实现动画风格的透视扁平化效果 |
|
⭐ |
正交投影混合
返回 Rendering
概述
正交投影混合(OrthoBlend)是 ARC 引擎实现动画风格透视扁平化的核心技术。在动画/格斗游戏中,角色需要减少透视畸变以保持美术控制的外观,这通过在透视投影和正交投影之间进行混合来实现。
引擎提供了两个版本:
- V1 (
USES_ORTHO_BLEND_POSITION):简单的 X 轴正交混合 - V2 (
USES_ORTHO_BLEND_POSITION2):基于物体中心距离的全透视校正("Purse correction")
实现细节
V1:X 轴正交混合
在 Common.ush 中定义:
float4 GetOrthoBlendPosition(
float4 WorldPosition,
float4x4 ViewProjectionMatrix,
float weight)
{
float4 ScreenPosition = mul(WorldPosition, ViewProjectionMatrix);
// 计算正交投影的 X 坐标
float OrthoScreenPositionX = dot(
ResolvedView.OrthoViewProjectionX, WorldPosition);
// 在透视和正交之间混合 X 轴
ScreenPosition.x = lerp(
ScreenPosition.x,
OrthoScreenPositionX * ScreenPosition.w,
weight * ResolvedView.OrthoBlendParameter);
return ScreenPosition;
}
OrthoBlendParameter 从 C++ 端通过 ViewUniformShaderParameters 传入,全局控制混合强度。weight 来自材质属性 MP_OrthoBlendWeight,允许逐材质控制。
V2:全透视校正
float4 GetOrthoBlendPosition2(
float4 WorldPosition,
float4x4 ViewProjectionMatrix,
float weight,
float3 ObjWorldPosition)
{
// 计算顶点相对于物体中心的偏移
float3 offset = WorldPosition.xyz - ObjWorldPosition.xyz;
// 物体中心到相机的距离(沿视线方向)
float dist = abs(dot(
ObjWorldPosition.xyz - ResolvedView.WorldCameraOrigin.xyz,
ResolvedView.ViewForward.xyz));
// 将顶点"拍平"到与物体中心相同距离的平面
float3 origin = ResolvedView.WorldCameraOrigin.xyz
+ ResolvedView.ViewForward.xyz * dist;
WorldPosition.xy = origin.xy + offset.xy;
// ... 后续投影变换
}
V2 的原理:将所有顶点投影到与物体中心等距的平面上,消除了前后肢体因透视导致的大小差异。
全 VertexFactory 覆盖
两个版本均在所有顶点着色器中实现:
| 顶点着色器 | 文件 |
|---|---|
| BasePass | BasePassVertexShader.usf |
| DepthOnly | DepthOnlyVertexShader.usf |
| PositionOnlyDepth | PositionOnlyDepthVertexShader.usf |
| HitProxy | HitProxyVertexShader.usf |
| DebugViewMode | DebugViewModeVertexShader.usf |
覆盖的 VertexFactory:
LocalVertexFactory.ushGpuSkinVertexFactory.ushLandscapeVertexFactory.ushMeshParticleVertexFactory.ush- 所有 Particle VertexFactory
材质属性
通过 MP_OrthoBlendWeight 材质属性控制每个材质的混合权重:
// MaterialTemplate.ush
float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters)
{
%s; // 由材质图生成
}
C++ 端支持
SceneRendering.cpp:计算OrthoBlendParameter并写入 ViewUniformBufferSceneTypes.h:MP_OrthoBlendWeight枚举值HLSLMaterialTranslator.cpp:材质编译支持
关联文档
修改文件列表
| 文件 | 修改类型 |
|---|---|
Shaders/Private/Common.ush |
新增 GetOrthoBlendPosition / GetOrthoBlendPosition2 |
Shaders/Private/BasePassVertexShader.usf |
调用正交混合 |
Shaders/Private/DepthOnlyVertexShader.usf |
调用正交混合 |
Shaders/Private/PositionOnlyDepthVertexShader.usf |
调用正交混合 |
Shaders/Private/HitProxyVertexShader.usf |
调用正交混合 |
Shaders/Private/DebugViewModeVertexShader.usf |
调用正交混合 |
所有 VertexFactory .ush |
提供 ObjWorldPosition |