[Shader study] Color control (2014.05.12)

Post on 25-Jun-2015

650 views 5 download

Transcript of [Shader study] Color control (2014.05.12)

해강 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

참고