해강
questionname@naver.com
Color Control
Shader Study
어떻게 하면 큰 비용 없이 그래픽을 좋게 만들 수 있을까?
시작
출력되는 화면을 결정하는 것은
Lighting, Shadow, Post-Correction
화면
4
Unity Color3
http://insidious.pt/demos/color3/
5
UDK
언리얼의 경우
6
고민
요즘 엔진들에는 기본적으로 들어가 있는 기능
그러나 엔진 안 쓰면…
당연히 누가 만들어주기 전까지는 없음…
Color Correcting?
Color Grading?
두가지 용어가 비슷하게 사용 차이는 없는가?
들어가며
Color Correction 이란 말은
일반적으로 화이트 밸런스를 바로 잡는다는 의미로 사용
일종의 색보정
‘색조를 일관되게 만드는 과정’
Color Correction
Color Grading은
컨셉에 맞게
색을 맞춰나가는 개념을 지칭
‘색조를 정서에 맞게 만드는 과정’
Color Grading
개념적으로는 서로 다르지만
기술적으로는 비슷
디퓨즈까지 반영된 최종 픽셀 값을 조정하거나,
매핑해서 보여주면 끝
정리
노출값 조절
outPixel =
(pow(((inPixel * 255.0) - inBlack) / (inWhite - inBlack),
inGamma) * (outWhite - outBlack) + outBlack) / 255.0;
Level
포토샵의 커브를 이용, 혹은 그라데이션을 만들어 적용
float3 InColor = tex2D (inSampler, IN.UV) XYZ;.
Float3 OutColor;
OutColor.r = tex1D (ColorCorrMap, InColor.r) R;
OutColor.g = tex1D (ColorCorrMap, InColor.g) G;
OutColor.b = tex1D (ColorCorrMap, InColor.b) B;
Curves
Luminanace 값
{0.222, 0.707, 0.071} 은 국제 산업 색상 표준
Float4 GrayScaleConversion( float4 InSceneColor )
{
float4 gray = dot(InSceneColor.xyz, luminace.xyz);
float4 Color = balance * lerp(gray, InSceneColor, saturation);
color.rgb *= fadeValue;
return color;
}
Grayscale Conversion
float3 CalcLut( sampler InLUT, float3 InColor )
{
// 256 x 16 LUT
float2 Offset = float2(0.5f / 256.0f, 0.5f / 16.0f);
float Scale = 15.0f / 16.0f;
float IntB = floor(InColor.b * 14.9999f) / 16.0f;
float FraceB = InColor.b * 15.0f – IntB * 16.0f
float U = IntB + InColor.r *Scale / 16.0f;
float V = InColor.g * Scale;
float3 RG0 = tex2D( InLUT, Offset + float2(U,V).rgb;
float3 RG1 = tex2D(InLUT, Offset + float2(U + 1.0f /
16.0f, V)).rgb;
Return lerp(RG0, RG1, FracB);
}
Unreal3
Unreal3 16x16x16 3d VolumeTexture
Float3 CalcLUT( sampler InLut, float3 InColor )
{
return tex3D( InLUT, InColor * 15.f / 16.f + 0.5f).rgb;
}
색상 채널을 혼합해 모든 픽셀에 전체 매핑 하는 경우
float3 InColor = tex2D . (inSampler, IN.UV) XYZ, float3
OutColor = tex3D (colorSpaceSampler, inColor);
Unreal3, GpuGems
좀 더 기능들을 제공하면 사용하지 않을까…
포토샵에서 지원하는 기능들
Blend Mode
// Curves Shader
float2 g_fTexcoord;
float4 g_fColour;
uniform sampler2D texCurve;
vec4 curves(float4 inColor, sampler2D texCurve)
{
return float4(texture2D(texCurve, vec2(inColor.r, 0.5)).r,
texture2D(texCurve, vec2(inColor.g, 0.5)).g,
texture2D(texCurve, vec2(inColor.b, 0.5)).b, inColor.a);
}
void main()
{
float4 inColor = (g_fColour * texture2D(gm_BaseTexture, g_fTexcoord));
gl_FragColor = curves(inColor, texCurve);
}
기본 이미지의 휘도 증가, 빛 효과에 유용
// Screen Shader
float2 g_fTexcoord;
float4 g_fColour;
uniform sampler2D texScreen;
void main()
{
float4 inColor = g_fColour * texture2D(gm_BaseTexture, g_fTexcoord);
float4 blend = texture2D(texScreen, g_fTexcoord);
float4 outColor = float4(1.0 - (1.0 - inColor.rgb) * (1.0 - blend.rgb), inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
기본 이미지의 밝기를 낮추는 효과, vignette effects에 유용
// Multiply Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texMultiply;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
vec4 blend = texture2D(texMultiply, v_vTexcoord);
vec4 outColor = vec4(blend.rgb * inColor.rgb, inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
색상 대비증가 빛이 없는 씬 유용
// Overlay Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texOverlay;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture,
v_vTexcoord);
vec4 outColor = vec4(0.0, 0.0, 0.0, inColor.a);
vec4 overlay = texture2D(texOverlay, v_vTexcoord);
if (inColor.r > 0.5)
outColor.r = (1.0 - (1.0 - 2.0 * (inColor.r - 0.5)) * (1.0
- overlay.r));
else
outColor.r = ((2.0 * inColor.r) * overlay.r);
if (inColor.g > 0.5)
outColor.g = (1.0 - (1.0 - 2.0 * (inColor.g - 0.5)) * (1.0
- overlay.g));
else
outColor.g = ((2.0 * inColor.g) * overlay.g);
if (inColor.b > 0.5)
outColor.b = (1.0 - (1.0 - 2.0 * (inColor.b - 0.5)) * (1.0
- overlay.b));
else
outColor.b = ((2.0 * inColor.b) * overlay.b);
gl_FragColor = mix(outColor, inColor,1.0 - overlay.a);
}
포화도(색의 강도) 조절, Point light에 유용
// Color Dodge Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texColorDodge;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
vec4 blend = texture2D(texColorDodge, v_vTexcoord);
vec4 outColor = vec4(inColor.rgb / (1.0 - blend.rgb), inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
채도를 조절
// Color Burn Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texColorBurn;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
vec4 blend = texture2D(texColorBurn, v_vTexcoord);
vec4 outColor = vec4(1.0 - (1.0 - inColor.rgb) / blend.rgb, inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
Multipuly의 반대로 화상을 밝게, 꿈꾸는듯한 효과
// Divide Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texDivide;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
vec4 blend = texture2D(texDivide, v_vTexcoord);
vec4 outColor = vec4(inColor.rgb / blend.rgb, inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
이미지를 반전, 포탈?
// Exclusion Shader
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform sampler2D texExclusion;
void main()
{
vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
vec4 blend = texture2D(texExclusion, v_vTexcoord);
vec4 outColor = vec4((abs(inColor - blend)).rgb,inColor.a);
gl_FragColor = mix(outColor, inColor, 1.0 - blend.a);
}
구현은 그렇다쳐도 사용하려면 툴에서 조절 가능해야 한다
Tool
처음엔 이걸 생각
그러나 이후 드는 생각은 누가 이걸 만들어?
http://www.slideshare.net/noerror/07visual-shader-
editor?qid=b3a04c6d-70a3-4363-9574-
976b739f9a01&v=default&b=&from_search=1
Visual Shader Editor
어차피 쉐이더 지원도 없으니 내 맘대로
http://www.youtube.com/watch?v=utaMQFuwNHw&hl=ko
Tool
하나의 Shader로 모든 기능 구현
전처리기를 이용해 Shader 컨트롤
Define된 명령을 이용해 on/off
Uber Shader
잘 지키면서 만들 수 있을지는 미지수
Uber Shader
Test
시험 삼아 적용
뭔가 깔끔하게 색상이 뽑히는게 아닌것 같은데…
감마
텍스쳐 가져올때 보정
float3 diffuseCol = pow( tex2D( diffTex, texCoord ), 2.2 );
최종 칼라 리턴 보정
return float4( pow(finalCol, 1.0 / 2.2), pixelAlpha);
하드웨어 사용시 옵션
Texture : D3DSAMP_SRGBTEXTURE
RenderTarget write: D3DRS_SRGBWRITEENABLE
이후는 다음에…
타임오버
Color Control
http://http.developer.nvidia.com/GPUGems/gpugems_ch22.html
Conversion Color Space & Filtering
http://www.slideshare.net/cagetu/928501785227148871
유니티 라이팅이 안이뻐요. 딱딱하고 입체감이 없어요. 어떻게해야하나요?
http://www.gamedevforever.com/303
Shader Driven
http://www.slideshare.net/cagetu/341130386455014679
참고

[Shader study] Color control (2014.05.12)

  • 1.
  • 2.
    어떻게 하면 큰비용 없이 그래픽을 좋게 만들 수 있을까? 시작
  • 3.
    출력되는 화면을 결정하는것은 Lighting, Shadow, Post-Correction 화면
  • 4.
  • 5.
  • 6.
    6 고민 요즘 엔진들에는 기본적으로들어가 있는 기능 그러나 엔진 안 쓰면… 당연히 누가 만들어주기 전까지는 없음…
  • 7.
    Color Correcting? Color Grading? 두가지용어가 비슷하게 사용 차이는 없는가? 들어가며
  • 8.
    Color Correction 이란말은 일반적으로 화이트 밸런스를 바로 잡는다는 의미로 사용 일종의 색보정 ‘색조를 일관되게 만드는 과정’ Color Correction
  • 9.
    Color Grading은 컨셉에 맞게 색을맞춰나가는 개념을 지칭 ‘색조를 정서에 맞게 만드는 과정’ Color Grading
  • 10.
    개념적으로는 서로 다르지만 기술적으로는비슷 디퓨즈까지 반영된 최종 픽셀 값을 조정하거나, 매핑해서 보여주면 끝 정리
  • 11.
    노출값 조절 outPixel = (pow(((inPixel* 255.0) - inBlack) / (inWhite - inBlack), inGamma) * (outWhite - outBlack) + outBlack) / 255.0; Level
  • 12.
    포토샵의 커브를 이용,혹은 그라데이션을 만들어 적용 float3 InColor = tex2D (inSampler, IN.UV) XYZ;. Float3 OutColor; OutColor.r = tex1D (ColorCorrMap, InColor.r) R; OutColor.g = tex1D (ColorCorrMap, InColor.g) G; OutColor.b = tex1D (ColorCorrMap, InColor.b) B; Curves
  • 13.
    Luminanace 값 {0.222, 0.707,0.071} 은 국제 산업 색상 표준 Float4 GrayScaleConversion( float4 InSceneColor ) { float4 gray = dot(InSceneColor.xyz, luminace.xyz); float4 Color = balance * lerp(gray, InSceneColor, saturation); color.rgb *= fadeValue; return color; } Grayscale Conversion
  • 14.
    float3 CalcLut( samplerInLUT, float3 InColor ) { // 256 x 16 LUT float2 Offset = float2(0.5f / 256.0f, 0.5f / 16.0f); float Scale = 15.0f / 16.0f; float IntB = floor(InColor.b * 14.9999f) / 16.0f; float FraceB = InColor.b * 15.0f – IntB * 16.0f float U = IntB + InColor.r *Scale / 16.0f; float V = InColor.g * Scale; float3 RG0 = tex2D( InLUT, Offset + float2(U,V).rgb; float3 RG1 = tex2D(InLUT, Offset + float2(U + 1.0f / 16.0f, V)).rgb; Return lerp(RG0, RG1, FracB); } Unreal3
  • 15.
    Unreal3 16x16x16 3dVolumeTexture Float3 CalcLUT( sampler InLut, float3 InColor ) { return tex3D( InLUT, InColor * 15.f / 16.f + 0.5f).rgb; } 색상 채널을 혼합해 모든 픽셀에 전체 매핑 하는 경우 float3 InColor = tex2D . (inSampler, IN.UV) XYZ, float3 OutColor = tex3D (colorSpaceSampler, inColor); Unreal3, GpuGems
  • 16.
    좀 더 기능들을제공하면 사용하지 않을까… 포토샵에서 지원하는 기능들 Blend Mode
  • 17.
    // Curves Shader float2g_fTexcoord; float4 g_fColour; uniform sampler2D texCurve; vec4 curves(float4 inColor, sampler2D texCurve) { return float4(texture2D(texCurve, vec2(inColor.r, 0.5)).r, texture2D(texCurve, vec2(inColor.g, 0.5)).g, texture2D(texCurve, vec2(inColor.b, 0.5)).b, inColor.a); } void main() { float4 inColor = (g_fColour * texture2D(gm_BaseTexture, g_fTexcoord)); gl_FragColor = curves(inColor, texCurve); }
  • 18.
    기본 이미지의 휘도증가, 빛 효과에 유용 // Screen Shader float2 g_fTexcoord; float4 g_fColour; uniform sampler2D texScreen; void main() { float4 inColor = g_fColour * texture2D(gm_BaseTexture, g_fTexcoord); float4 blend = texture2D(texScreen, g_fTexcoord); float4 outColor = float4(1.0 - (1.0 - inColor.rgb) * (1.0 - blend.rgb), inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 19.
    기본 이미지의 밝기를낮추는 효과, vignette effects에 유용 // Multiply Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texMultiply; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 blend = texture2D(texMultiply, v_vTexcoord); vec4 outColor = vec4(blend.rgb * inColor.rgb, inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 20.
    색상 대비증가 빛이없는 씬 유용 // Overlay Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texOverlay; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 outColor = vec4(0.0, 0.0, 0.0, inColor.a); vec4 overlay = texture2D(texOverlay, v_vTexcoord); if (inColor.r > 0.5) outColor.r = (1.0 - (1.0 - 2.0 * (inColor.r - 0.5)) * (1.0 - overlay.r)); else outColor.r = ((2.0 * inColor.r) * overlay.r); if (inColor.g > 0.5) outColor.g = (1.0 - (1.0 - 2.0 * (inColor.g - 0.5)) * (1.0 - overlay.g)); else outColor.g = ((2.0 * inColor.g) * overlay.g); if (inColor.b > 0.5) outColor.b = (1.0 - (1.0 - 2.0 * (inColor.b - 0.5)) * (1.0 - overlay.b)); else outColor.b = ((2.0 * inColor.b) * overlay.b); gl_FragColor = mix(outColor, inColor,1.0 - overlay.a); }
  • 21.
    포화도(색의 강도) 조절,Point light에 유용 // Color Dodge Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texColorDodge; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 blend = texture2D(texColorDodge, v_vTexcoord); vec4 outColor = vec4(inColor.rgb / (1.0 - blend.rgb), inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 22.
    채도를 조절 // ColorBurn Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texColorBurn; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 blend = texture2D(texColorBurn, v_vTexcoord); vec4 outColor = vec4(1.0 - (1.0 - inColor.rgb) / blend.rgb, inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 23.
    Multipuly의 반대로 화상을밝게, 꿈꾸는듯한 효과 // Divide Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texDivide; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 blend = texture2D(texDivide, v_vTexcoord); vec4 outColor = vec4(inColor.rgb / blend.rgb, inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 24.
    이미지를 반전, 포탈? //Exclusion Shader varying vec2 v_vTexcoord; varying vec4 v_vColour; uniform sampler2D texExclusion; void main() { vec4 inColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord); vec4 blend = texture2D(texExclusion, v_vTexcoord); vec4 outColor = vec4((abs(inColor - blend)).rgb,inColor.a); gl_FragColor = mix(outColor, inColor, 1.0 - blend.a); }
  • 25.
    구현은 그렇다쳐도 사용하려면툴에서 조절 가능해야 한다 Tool
  • 26.
    처음엔 이걸 생각 그러나이후 드는 생각은 누가 이걸 만들어? http://www.slideshare.net/noerror/07visual-shader- editor?qid=b3a04c6d-70a3-4363-9574- 976b739f9a01&v=default&b=&from_search=1 Visual Shader Editor
  • 27.
    어차피 쉐이더 지원도없으니 내 맘대로 http://www.youtube.com/watch?v=utaMQFuwNHw&hl=ko Tool
  • 28.
    하나의 Shader로 모든기능 구현 전처리기를 이용해 Shader 컨트롤 Define된 명령을 이용해 on/off Uber Shader
  • 29.
    잘 지키면서 만들수 있을지는 미지수 Uber Shader
  • 30.
    Test 시험 삼아 적용 뭔가깔끔하게 색상이 뽑히는게 아닌것 같은데…
  • 31.
    감마 텍스쳐 가져올때 보정 float3diffuseCol = pow( tex2D( diffTex, texCoord ), 2.2 ); 최종 칼라 리턴 보정 return float4( pow(finalCol, 1.0 / 2.2), pixelAlpha); 하드웨어 사용시 옵션 Texture : D3DSAMP_SRGBTEXTURE RenderTarget write: D3DRS_SRGBWRITEENABLE
  • 32.
  • 33.
    Color Control http://http.developer.nvidia.com/GPUGems/gpugems_ch22.html Conversion ColorSpace & Filtering http://www.slideshare.net/cagetu/928501785227148871 유니티 라이팅이 안이뻐요. 딱딱하고 입체감이 없어요. 어떻게해야하나요? http://www.gamedevforever.com/303 Shader Driven http://www.slideshare.net/cagetu/341130386455014679 참고