UE4匹配了影视级的开发过程,使用aces标准等,在意标准化。例如《曼达洛人》、国内的《凡人修仙传》等。在美术流程线上,基础的pbr流程,美术依靠工具流是可以完全跑通的。而且这个跑通是以影视级为标准的,这个非常重要。
Unity在大气和雾缺乏美术层匹配、丰富。预设规范缺乏。缺乏引用关系和数据互通。新版本更新了光照,相机和色彩标准。
Unity这些情况不影响效果,但影响使用工具的人。也就是统一流程下,存在两种结果。ue用原生工具加二级辅助工具完成的pipline。unity这边要程序美术全线定制,最终才能达成一样的开发效率。
在地编,特效,动画,材质每个单模块基本都是如此。unity美术对于单跟程序的需求是极高的。而对于当前大体量游戏的开发。工具决定流程效率,决定开发进度,决定解耦。

因此,在工具链及标准定制上,如项目需要,优先以UE流程标准为依据进行工具的移植

位置

unity 端位于 Colors.hlsl AcesTonemap
UE4 端位于 TonemapCommon.hlsl FilmToneMap

ACES 颜色空间

unity-UE4 变量对应

变量,颜色空间 unity UE4
aces aces ColorAP0
acescg acescg WorkingColor
API1 linearCV ToneColor

可以知道二者都是在 acescg color space 进行亮度映射

增加变量

  1. float FilmSlope;// = 0.91;
  2. float FilmToe;// = 0.53;
  3. float FilmShoulder;// = 0.23;
  4. float FilmBlackClip;// = 0;
  5. float FilmWhiteClip;// = 0.035;

对 unity AcesTonamp 如下字段进行修改

  1. const float a = 278.5085;
  2. const float b = 10.7772;
  3. const float c = 293.6045;
  4. const float d = 88.7122;
  5. const float e = 80.6889;
  6. float3 x = acescg;
  7. float3 rgbPost = (x * (a * x + b)) / (x * (c * x + d) + e);
  8. float3 linearCV = darkSurround_to_dimSurround(rgbPost);
  1. #ifdef UE4_TONEMAP
  2. const half ToeScale = 1 + FilmBlackClip - FilmToe;
  3. const half ShoulderScale = 1 + FilmWhiteClip - FilmShoulder;
  4. const float InMatch = 0.18;
  5. const float OutMatch = 0.18;
  6. float ToeMatch;
  7. if (FilmToe > 0.8)
  8. {
  9. ToeMatch = (1 - FilmToe - OutMatch) / FilmSlope + log10(InMatch);
  10. }
  11. else
  12. {
  13. const float bt = (OutMatch + FilmBlackClip) / ToeScale - 1;
  14. ToeMatch = log10(InMatch) - 0.5 * log((1 + bt) / (1 - bt)) * (ToeScale / FilmSlope);
  15. }
  16. float StraightMatch = (1 - FilmToe) / FilmSlope - ToeMatch;
  17. float ShoulderMatch = FilmShoulder / FilmSlope - StraightMatch;
  18. half3 LogColor = log10(acescg);
  19. half3 StraightColor = FilmSlope * (LogColor + StraightMatch);
  20. half3 ToeColor = (-FilmBlackClip) + (2 * ToeScale) / (1 + exp((-2 * FilmSlope / ToeScale) * (LogColor - ToeMatch)));
  21. half3 ShoulderColor = (1 + FilmWhiteClip) - (2 * ShoulderScale) / (1 + exp((2 * FilmSlope / ShoulderScale) * (LogColor - ShoulderMatch)));
  22. ToeColor = LogColor < ToeMatch ? ToeColor : StraightColor;
  23. ShoulderColor = LogColor > ShoulderMatch ? ShoulderColor : StraightColor;
  24. half3 t = saturate((LogColor - ToeMatch) / (ShoulderMatch - ToeMatch));
  25. t = ShoulderMatch < ToeMatch ? 1 - t : t;
  26. t = (3 - 2 * t)*t*t;
  27. half3 linearCV = lerp(ToeColor, ShoulderColor, t);
  28. linearCV = lerp(dot(float3(linearCV), AP1_RGB2Y), linearCV, 0.93);
  29. linearCV = max(0, linearCV);
  30. #else
  31. const float a = 278.5085;
  32. const float b = 10.7772;
  33. const float c = 293.6045;
  34. const float d = 88.7122;
  35. const float e = 80.6889;
  36. float3 x = acescg;
  37. float3 rgbPost = (x * (a * x + b)) / (x * (c * x + d) + e);
  38. float3 linearCV = darkSurround_to_dimSurround(rgbPost);
  39. #endif

修改 ColorGrading.cs,ColorGradingEditor.cs 将 FilmSlope、FilmToe、FilmShoulder、FilmBlackClip、FilmWhiteClip 暴露出去