본문으로 바로가기
반응형






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