[shader study] color control (2014.05.12)
Post on 25-Jun-2015
650 views
TRANSCRIPT
어떻게 하면 큰 비용 없이 그래픽을 좋게 만들 수 있을까?
시작
출력되는 화면을 결정하는 것은
Lighting, Shadow, Post-Correction
화면
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
참고