72 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
---
 | 
						||
title: 使用Curve进行深度适配的Outline
 | 
						||
date: 2023-07-18 14:47:24
 | 
						||
excerpt: 
 | 
						||
tags: 
 | 
						||
rating: ⭐
 | 
						||
---
 | 
						||
 | 
						||
# 前言
 | 
						||
在UE5.1发现了若干新节点感觉对后处理描边有很大的作用。
 | 
						||
![[MultiDraw_OutlineMaterial.png]]
 | 
						||
 | 
						||
 | 
						||
# ControlCurve
 | 
						||
<iframe src="https://www.desmos.com/calculator/z9o3k0luyb?embed" width="500" height="500" style="border: 1px solid #ccc" frameborder=0></iframe>
 | 
						||
UE单位为cm,理论上描边宽度控制范围为10cm~10000cm(1000m)。假设标准的角色身高为180cm(110~200cm变化比较轻微)并以此定义一个标准数StandardCharacterHeight,经过观察`10~ ControlWidthRangeMax`范围适合使用CurveTexture。而超过ControlWidthRangeMax = StandardCharacterHeight * 2的区域基本是一个线性区间,所以可以使用一个线性函数来控制。
 | 
						||
 | 
						||
以下为原始数据:
 | 
						||
 | 
						||
|     |     |     |      |     |      |     |      |
 | 
						||
| --- | --- | --- | ---- | --- | ---- | --- | ---- |
 | 
						||
| x轴 | 15  | 20  | 25   | 30  | 40   | 60  | 100  |
 | 
						||
| y轴 | -12 | -9  | -7.2 | -6  | -4.5 | -3  | -1.8 |
 | 
						||
 | 
						||
经过重映射后:
 | 
						||
 | 
						||
|     |       |      |      |        |       |         |      |
 | 
						||
| --- | ----- | ---- | ---- | ------ | ----- | ------- | ---- |
 | 
						||
| x轴 | 0.15  | 0.2  | 0.25 | 0.3    | 0.4   | 0.6     | 1    |
 | 
						||
| y轴 | 0.667 | 0.75 | 0.8  | 0.8333 | 0.875 | 0.91666 | 0.95 |
 | 
						||
 | 
						||
考虑需要让描边变得平滑以及让效果更好的考虑,所以以此为基础数据进行了调节(平移曲线并且调整了几个点),以下去本人设置的曲线:![[MultiDraw_OutlineCurve.png|800]]
 | 
						||
 | 
						||
### 线性函数斜率k的计算 
 | 
						||
取得ControlWidthRangeMax上一点(360 0.5)与最大范围x=10000的一点(10000 0.018),即可取得斜率 k = 0.0005/1cm。
 | 
						||
 | 
						||
实际使用0.0005的效果不佳,经过调整最终斜率使用0.002。
 | 
						||
 | 
						||
### Remap
 | 
						||
```c++
 | 
						||
half invLerp(half from, half to, half value) 
 | 
						||
{
 | 
						||
    return (value - from) / (to - from);
 | 
						||
}
 | 
						||
half invLerpClamp(half from, half to, half value)
 | 
						||
{
 | 
						||
    return saturate(invLerp(from,to,value));
 | 
						||
}
 | 
						||
// full control remap, but slower
 | 
						||
half remap(half origFrom, half origTo, half targetFrom, half targetTo, half value)
 | 
						||
{
 | 
						||
    half rel = invLerp(origFrom, origTo, value);
 | 
						||
    return lerp(targetFrom, targetTo, rel);
 | 
						||
}
 | 
						||
```
 | 
						||
 | 
						||
## FOV
 | 
						||
首先确定一下摄像机的FOV范围,CineCamera 默认Current Focal Length 为35,Current Horizontal FOV为37.497356,材质Fov显示为0.6544528(弧度制);编辑器Camera 默认 FOV:90 材质FOV显示1.5707976(弧度制)
 | 
						||
- CineCamera
 | 
						||
	- Current Horizontal FOV范围       1.375033 ~ 143.130096
 | 
						||
	- 材质 FOV 范围                                     0.024~2.4
 | 
						||
- Camera
 | 
						||
	- FOV范围                                               5~170
 | 
						||
	- 材质 FOV 范围                                     0.08~2.967
 | 
						||
 | 
						||
经过观察FOV<90需要使用曲线进行控制,大致和Depth曲线差不多,再调整一下就好。90 < FOV < 170 时OutlineWidth大致呈线性,所以大致计算出斜率k=3:
 | 
						||
 | 
						||
|              |     |     |     |
 | 
						||
| ------------ | --- | --- | --- |
 | 
						||
| FOV          | 90  | 130 | 170 |
 | 
						||
| OutlineWidth | 1   | 3   | 8   |
 |