Files
BlueRoseNote/03-UnrealEngine/卡通渲染相关资料/渲染功能/ARC/Rendering/正交投影混合.md

4.1 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
正交投影混合 2026-05-03 00:00:00 OrthoBlend 透视校正技术,实现动画风格的透视扁平化效果
ARC
Rendering
VertexFactory
Toon

正交投影混合

返回 Rendering

概述

正交投影混合OrthoBlend是 ARC 引擎实现动画风格透视扁平化的核心技术。在动画/格斗游戏中,角色需要减少透视畸变以保持美术控制的外观,这通过在透视投影和正交投影之间进行混合来实现。

引擎提供了两个版本:

  • V1 (USES_ORTHO_BLEND_POSITION):简单的 X 轴正交混合
  • V2 (USES_ORTHO_BLEND_POSITION2):基于物体中心距离的全透视校正("Purse correction"

实现细节

V1X 轴正交混合

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.ush
  • GpuSkinVertexFactory.ush
  • LandscapeVertexFactory.ush
  • MeshParticleVertexFactory.ush
  • 所有 Particle VertexFactory

材质属性

通过 MP_OrthoBlendWeight 材质属性控制每个材质的混合权重:

// MaterialTemplate.ush
float GetMaterialOrthoBlendWeight(FMaterialVertexParameters Parameters)
{
    %s;  // 由材质图生成
}

C++ 端支持

  • SceneRendering.cpp:计算 OrthoBlendParameter 并写入 ViewUniformBuffer
  • SceneTypes.hMP_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