sRGB 색 공간뿐만 아니라 선형 색상 공간에 대응하는 것 같은 쉐이더를 쓰는 경우 쉐이더에서 색 공간 변환을 할 수 있습니다.
PostProcessing의 소스 코드 를보고 있었는데 좋은 느낌의 색 공간 변환 용 코드가 있었기 때문에이 기사에 정리해 둡니다. 원래의 소스 코드는 다음 github를 참조하십시오.
#define FLT_EPSILON 1.192092896e-07 // Using pow often result to a warning like this "pow(f, e) will not work for negative f,
use abs(f) or conditionally handle negative values if you expect them" // PositivePow remove this warning when you know the value is positive and avoid inf/NAN.
// pow를 사용하면 종종 "pow (f, e)가 음수 f에 대해 작동하지 않거나 abs (f)를 사용하거나// 원하는 경우 음수 값을 처리합니다"와 같은 경고가 발생합니다.
// PositivePow 값이 양수인 것을 알고 inf / NAN을 피하면이 경고를 제거하십시오.
float PositivePow(float base, float power) { return pow(max(abs(base), float(FLT_EPSILON)), power); } float2 PositivePow(float2 base, float2 power) { return pow(max(abs(base), float2(FLT_EPSILON, FLT_EPSILON)), power); } float3 PositivePow(float3 base, float3 power) { return pow(max(abs(base), float3(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power); } float4 PositivePow(float4 base, float4 power) { return pow(max(abs(base), float4(FLT_EPSILON, FLT_EPSILON, FLT_EPSILON, FLT_EPSILON)), power); } half SRGBToLinear(half c) { #if USE_VERY_FAST_SRGB return c * c; #elif USE_FAST_SRGB return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); #else half linearRGBLo = c / 12.92; half linearRGBHi = PositivePow((c + 0.055) / 1.055, 2.4); half linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi; return linearRGB; #endif }
half3 SRGBToLinear(half3 c) { #if USE_VERY_FAST_SRGB return c * c; #elif USE_FAST_SRGB return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878); #else half3 linearRGBLo = c / 12.92; half3 linearRGBHi = PositivePow((c + 0.055) / 1.055, half3(2.4, 2.4, 2.4)); half3 linearRGB = (c <= 0.04045) ? linearRGBLo : linearRGBHi; return linearRGB; #endif }
half4 SRGBToLinear(half4 c) { return half4(SRGBToLinear(c.rgb), c.a); }
half LinearToSRGB(half c) { #if USE_VERY_FAST_SRGB return sqrt(c); #elif USE_FAST_SRGB return max(1.055 * PositivePow(c, 0.416666667) - 0.055, 0.0); #else half sRGBLo = c * 12.92; half sRGBHi = (PositivePow(c, 1.0 / 2.4) * 1.055) - 0.055; half sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi; return sRGB; #endif }
half3 LinearToSRGB(half3 c) { #if USE_VERY_FAST_SRGB return sqrt(c); #elif USE_FAST_SRGB return max(1.055 * PositivePow(c, 0.416666667) - 0.055, 0.0); #else half3 sRGBLo = c * 12.92; half3 sRGBHi = (PositivePow(c, half3(1.0 / 2.4, 1.0 / 2.4, 1.0 / 2.4)) * 1.055) - 0.055; half3 sRGB = (c <= 0.0031308) ? sRGBLo : sRGBHi; return sRGB; #endif }
half4 LinearToSRGB(half4 c) { return half4(LinearToSRGB(c.rgb), c.a); }
SRGBToLinear에서 sRGB 값을 선형 값으로 변환하고 LinearToSRGB에서 그 반대의 작업을 수행합니다.
각각 1 차원, 3 차원, 4 차원 값의 입출력에 대응하고 있습니다.
또한 이러한 변환에는 어느 정도의 계산 비용 때문에 두 근사 식을 사용할 수 있습니다.
USE_VERY_FAST_SRGB과 USE_FAST_SRGB를 정의하여 사용하는 식을 선택할 수 있습니다.
'Technical Report > Unity Shader' 카테고리의 다른 글
2D Signed Distance Field Basics (0) | 2021.02.10 |
---|---|
Shader Graph Custom Shader function (0) | 2020.02.15 |
URP Default Unlit Based to Custom Lighting (0) | 2020.01.31 |
LWRP Basic shader code (0) | 2019.09.08 |
Unity PBR Default (0) | 2019.07.10 |