쉐이더 로 색수차 효과를 어떻게 구현 하시겠습니까?
각 색상에 대해 서로 다른 초점 거리를 가진 세계를 렌더링하면 문제가 해결됩니까 (심도 렌더링 패스가 하나만 사용되는 경우)?
쉐이더 로 색수차 효과를 어떻게 구현 하시겠습니까?
각 색상에 대해 서로 다른 초점 거리를 가진 세계를 렌더링하면 문제가 해결됩니까 (심도 렌더링 패스가 하나만 사용되는 경우)?
답변:
색수차는 렌즈가 모든 초점을 동일한 초점에 맞출 수 없을 때 발생합니다. 이 효과를 위조하여 빠른 전체 화면 포스트 프로세스로 렌더링하는 간단한 방법은 프래그먼트 셰이더의 각 색상 채널에 오프셋을 적용하는 것입니다.
각 채널에 대해 다른 오프셋을 사용하면 원하는 효과의 합리적인 팩시밀리를 얻을 수 있습니다. 이 기술의 예는 여기 에서 찾을 수 있습니다 . 프래그먼트 셰이더는 다음과 같습니다.
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 을 사용할 수 있으며 기본 반사 및 굴절 효과의 예와 색수차 효과의 예를 포함합니다.