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


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.