2026-05-03 20:37:58 +08:00
|
|
|
|
---
|
|
|
|
|
|
title: 局部位置缩放
|
|
|
|
|
|
date: 2026-05-03 00:00:00
|
|
|
|
|
|
excerpt: 逐材质局部空间顶点缩放
|
|
|
|
|
|
tags:
|
|
|
|
|
|
- ARC
|
|
|
|
|
|
- Rendering
|
|
|
|
|
|
- VertexFactory
|
|
|
|
|
|
rating: ⭐
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# 局部位置缩放
|
|
|
|
|
|
|
|
|
|
|
|
返回 [[Rendering]]
|
|
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
|
|
允许通过材质图在局部空间(Local Space)对顶点位置进行缩放,实现不依赖 Actor Transform 的比例调整。
|
|
|
|
|
|
|
|
|
|
|
|
## 实现
|
|
|
|
|
|
|
|
|
|
|
|
在各 VertexFactory 中通过 `VertexFactoryUpdateLocalPositionScale` 函数实现:
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
void VertexFactoryUpdateLocalPositionScale(
|
|
|
|
|
|
inout FVertexFactoryInput Input,
|
|
|
|
|
|
inout FVertexFactoryIntermediates Intermediates,
|
|
|
|
|
|
float3 scale)
|
|
|
|
|
|
{
|
|
|
|
|
|
Input.Position.xyz *= scale;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
由 `USES_LOCAL_POSITION_SCALE` 宏控制启用,在世界变换之前应用。
|
|
|
|
|
|
|
|
|
|
|
|
## 使用场景
|
|
|
|
|
|
|
|
|
|
|
|
- 角色部件的动态缩放(如拳头放大的夸张动画效果)
|
|
|
|
|
|
- 不同 LOD 级别的微调
|
|
|
|
|
|
- 格斗游戏中攻击判定与视觉表现分离时的视觉调整
|
|
|
|
|
|
|
|
|
|
|
|
## 材质属性
|
|
|
|
|
|
|
|
|
|
|
|
`MP_LocalPositionScale`(float3)通过材质图控制。参见 [[自定义材质属性]]。
|
|
|
|
|
|
|
2026-05-03 21:38:46 +08:00
|
|
|
|
## 完整代码解析
|
|
|
|
|
|
|
|
|
|
|
|
### LocalVertexFactory.ush — 缩放函数定义
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
// LocalVertexFactory.ush — 缩放函数定义
|
|
|
|
|
|
// ASW Change : 2016/06/29 17:05:39 Takuro.K
|
|
|
|
|
|
#if USES_LOCAL_POSITION_SCALE
|
|
|
|
|
|
void VertexFactoryUpdateLocalPositionScale(
|
|
|
|
|
|
inout FVertexFactoryInput Input, // 顶点输入(可修改)
|
|
|
|
|
|
inout FVertexFactoryIntermediates Intermediates, // 中间数据
|
|
|
|
|
|
float3 scale) // 缩放系数 (x, y, z)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 直接在局部空间缩放顶点位置
|
|
|
|
|
|
// 在 WorldTransform 之前应用,所以效果与 Actor Scale 类似
|
|
|
|
|
|
// 但由材质图控制,可以做动画
|
|
|
|
|
|
Input.Position.xyz *= scale;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### BasePassVertexShader.usf — 调用流程
|
|
|
|
|
|
|
|
|
|
|
|
```hlsl
|
|
|
|
|
|
// BasePassVertexShader.usf — 调用流程
|
|
|
|
|
|
// ASW Change : 2016/06/29 17:05:39 Takuro.K
|
|
|
|
|
|
#if USES_LOCAL_POSITION_SCALE
|
|
|
|
|
|
{
|
|
|
|
|
|
// 1. 从材质图获取缩放系数
|
|
|
|
|
|
// 2. 应用到顶点的局部坐标
|
|
|
|
|
|
VertexFactoryUpdateLocalPositionScale(Input, VFIntermediates,
|
|
|
|
|
|
GetMaterialLocalPositionScale(VertexParameters));
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 重新计算世界坐标(因为局部坐标已改变)
|
|
|
|
|
|
WorldPositionExcludingWPO = VertexFactoryGetWorldPosition(Input, VFIntermediates);
|
|
|
|
|
|
WorldPosition = WorldPositionExcludingWPO;
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 重新获取切线空间和材质参数
|
|
|
|
|
|
TangentToLocal = VertexFactoryGetTangentToLocal(Input, VFIntermediates);
|
|
|
|
|
|
VertexParameters = GetMaterialVertexParameters(
|
|
|
|
|
|
Input, VFIntermediates, WorldPosition.xyz, TangentToLocal);
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 代码修改情况
|
|
|
|
|
|
|
|
|
|
|
|
| 文件路径 | 行号 | 修改类型 | 修改内容 |
|
|
|
|
|
|
|---------|------|---------|---------|
|
|
|
|
|
|
| `Shaders/Private/BasePassVertexShader.usf` | L64~L76 | 新增 | 调用 `VertexFactoryUpdateLocalPositionScale` + 重算世界坐标 |
|
|
|
|
|
|
| `Shaders/Private/LocalVertexFactory.ush` | L1171~L1179 | 新增 | `VertexFactoryUpdateLocalPositionScale` 函数(`Input.Position.xyz *= scale`) |
|
|
|
|
|
|
| `Shaders/Private/GpuSkinVertexFactory.ush` | L822~L830 | 新增 | 同上(GPU 蒙皮版本) |
|
|
|
|
|
|
| `Shaders/Private/LandscapeVertexFactory.ush` | L948~L958 | 新增 | 同上(Landscape 版本) |
|
|
|
|
|
|
| `Shaders/Private/MeshParticleVertexFactory.ush` | L728~L736 | 新增 | 同上(MeshParticle 版本) |
|
|
|
|
|
|
| `Shaders/Private/ParticleSpriteVertexFactory.ush` | L684~L691 | 新增 | 同上(ParticleSprite 版本) |
|
|
|
|
|
|
| `Shaders/Private/ParticleGPUSpriteVertexFactory.ush` | L698~L706 | 新增 | 同上(ParticleGPUSprite 版本) |
|
|
|
|
|
|
| `Shaders/Private/ParticleBeamTrailVertexFactory.ush` | L246~L253 | 新增 | 同上(ParticleBeamTrail 版本) |
|
|
|
|
|
|
| `Shaders/Private/VectorFieldVisualizationVertexFactory.ush` | L202~L210 | 新增 | 同上(VectorField 版本) |
|
|
|
|
|
|
| `Shaders/Private/MaterialTemplate.ush` | L2263~L2268 | 新增 | `GetMaterialLocalPositionScale` 材质访问函数 |
|