색수차를 어떻게 구현 하시겠습니까?


22

쉐이더 로 색수차 효과를 어떻게 구현 하시겠습니까?

각 색상에 대해 서로 다른 초점 거리를 가진 세계를 렌더링하면 문제가 해결됩니까 (심도 렌더링 패스가 하나만 사용되는 경우)?


왜 색수차를 구현하고 싶습니까?
ashes999

3
블룸과 같은 방식으로 진행할 수 있습니다. 일반 장면을 3 가지 희미한 버전과 결합해야합니다. 이 3 가지 텍스처 각각은 주로 3 가지 기본 색상으로 색조를 지정해야합니다. 물론 3 가지 텍스처에 대해 다른 흐림 전략을 사용하는 경우 변형이 가능합니다 (예 : 각도 오프셋이 다른 방향 흐림은 트릭을 수행 할 수 있음).
teodron

3
@ ashes999-사실감있는 터치를 추가하기 위해 저격수 또는 다른 긴 렌즈일까요? 색수차는 많은 복합 렌즈 디자인의 인공물입니다.
KeithS

게임을 보는 렌즈로 인한 수차에 대응하기 위해 색수차를 구현할 수도 있습니다. 예를 들어, 오큘 러스 리프트 (Oculus Rift)를 사용한 게임에서 뷰의 가장자리에 색수차를 두는 것이 좋습니다.
Joseph Mansfield

답변:


22

색수차는 렌즈가 모든 초점을 동일한 초점에 맞출 수 없을 때 발생합니다. 이 효과를 위조하여 빠른 전체 화면 포스트 프로세스로 렌더링하는 간단한 방법은 프래그먼트 셰이더의 각 색상 채널에 오프셋을 적용하는 것입니다.

각 채널에 대해 다른 오프셋을 사용하면 원하는 효과의 합리적인 팩시밀리를 얻을 수 있습니다. 이 기술의 예는 여기 에서 찾을 수 있습니다 . 프래그먼트 셰이더는 다음과 같습니다.

void main () {
    // Previously, you'd have rendered your complete scene into a texture
    // bound to "fullScreenTexture."
    vec4 rValue = texture2D(fullscreenTexture, gl_TexCoords[0] - rOffset);  
    vec4 gValue = texture2D(fullscreenTexture, gl_TexCoords[0] - gOffset);
    vec4 bValue = texture2D(fullscreenTexture, gl_TexCoords[0] - bOffset);  

    // Combine the offset colors.
    gl_FragColor = vec4(rValue.r, gValue.g, bValue.b, 1.0);
}

이 간단한 핵은 색수차가 렌즈 효과라는 사실을 실제로 고려하지 않습니다. 더 나은 시뮬레이션을 얻으려면 실제로 렌즈 역할을 할 무언가를 렌더링하려고합니다. 이것은 반사 또는 굴절 된 객체를 렌더링하는 방법과 유사합니다. 결과적으로, 전형적인 반사 / 굴절 쉐이더는 색수차를 구현하기위한 기초가 될 수있다.

일반적으로, 당신은보기 벡터와 약간의 정의에 따라 하나의 굴절 벡터 계산하는 것 굴절률 GLSL의 사용, 굴절의 정점 셰이더 기능 :

void main () {
    // ...

    // RefractionVector is a varying vec3.
    // 'ratio' is the ratio of the two indices of refraction.
    RefractionVector = refract(incidentVector, normalVector, ratio);

    // ...
}

그런 다음 프래그먼트 셰이더에서 해당 벡터를 사용하여 (환경 맵으로) 큐브 텍스처 조회를 수행합니다. 일반적으로 이것은 반사 효과와 함께 수행되며 계산 된 프레 넬 항을 결합하여 사용합니다 .

그러면 색수차를 시뮬레이션하기 위해 정점 셰이더에서 서로 다른 굴절률을 통해 약간 오프셋되는 세 가지 굴절 벡터 계산을 수행 할 수 있습니다 .

void main () {
    // ...

    // RefractionVector is a varying vec3, as above.
    // 'ratioR,' et cetera, is the ratio of indices of refraction for
    // the red, green and blue components respectively.
    RedRefractionVector = refract(incidentVector, normalVector, ratioR);
    GreenRefractionVector = refract(incidentVector, normalVector, ratioG);
    BlueRefractionVector = refract(incidentVector, normalVector, ratioB);

    // ...
}

이 세 가지 다른 벡터를 사용하여 세 가지 큐브 맵 조회를 수행 할 수 있습니다. 간단한 예에서 색상이 혼합 된 방식과 비슷하게 혼합 될 수 있습니다.

void main () {
    vec3 color;
    color.r = vec3(textureCube(EnvironmentMap, RedRefractionVector)).r;
    color.g = vec3(textureCube(EnvironmentMap, GreenRefractionVector)).g;
    color.b = vec3(textureCube(EnvironmentMap, BlueRefractionVector)).b;

    gl_FragColor = vec4(color, 1.0);
}

자세한 내용은 OpenGL Orange Book 을 사용할 수 있으며 기본 반사 및 굴절 효과의 예와 색수차 효과의 예를 포함합니다.


하나의 텍스쳐 샘플 만 사용하고 색조를 지정하는 접근법이 있습니까? 3 대 1 광선을 추적하는 것이 매우 비싼 광선 추적과 같은 응용 프로그램에 매우 유용합니다.
Tara
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.