Reflection/refraction with chromatic aberration - eye correction

匿名 (未验证) 提交于 2019-12-03 02:59:02

问题:

I am writing a GLSL shader that simulates chromatic aberration for simple objects. I am staying OpenGL 2.0 compatible, so I use the built-in OpenGL matrix stack. This is the simple vertex shader:

uniform vec3 cameraPos;  varying vec3 incident; varying vec3 normal;  void main(void) {     vec4 position = gl_ModelViewMatrix * gl_Vertex;     incident = position.xyz / position.w - cameraPos;     normal   = gl_NormalMatrix * gl_Normal;      gl_Position = ftransform(); } 

The cameraPos uniform is the position of the camera in model space, as one might imagine. Here is the fragment shader:

const float etaR = 1.14; const float etaG = 1.12; const float etaB = 1.10; const float fresnelPower = 2.0; const float F = ((1.0 - etaG) * (1.0 - etaG)) / ((1.0 + etaG) * (1.0 + etaG));  uniform samplerCube environment;  varying vec3 incident; varying vec3 normal;  void main(void) {     vec3 i = normalize(incident);     vec3 n = normalize(normal);      float ratio = F + (1.0 - F) * pow(1.0 - dot(-i, n), fresnelPower);      vec3 refractR = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaR), 1.0));     vec3 refractG = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaG), 1.0));     vec3 refractB = vec3(gl_TextureMatrix[0] * vec4(refract(i, n, etaB), 1.0));      vec3 reflectDir = vec3(gl_TextureMatrix[0] * vec4(reflect(i, n), 1.0));      vec4 refractColor;     refractColor.ra = textureCube(environment, refractR).ra;     refractColor.g  = textureCube(environment, refractG).g;     refractColor.b  = textureCube(environment, refractB).b;      vec4 reflectColor;     reflectColor    = textureCube(environment, reflectDir);      vec3 combinedColor = mix(refractColor, reflectColor, ratio);      gl_FragColor = vec4(combinedColor, 1.0); } 

The environment is a cube map that is rendered live from the drawn object's environment.

Under normal circumstances, the shader behaves (I think) like expected, yielding this result:

However, when the camera is rotated 180 degrees around its target, so that it now points at the object from the other side, the refracted/reflected image gets warped like so (This happens gradually for angles between 0 and 180 degrees, of course):

Similar artifacts appear when the camera is lowered/raised; it only seems to behave 100% correctly when the camera is directly over the target object (pointing towards negative Z, in this case).

I am having trouble figuring out which transformation in the shader that is responsible for this warped image, but it should be something obvious related to how cameraPos is handled. What is causing the image to warp itself in this way?

回答1:

This looks suspect to me:

vec4 position = gl_ModelViewMatrix * gl_Vertex; incident = position.xyz / position.w - cameraPos; 

Is your cameraPos defined in world space? You're subtracting a view space vector (position), from a supposedly world space cameraPos vector. You either need to do the calculation in world space or view space, but you can't mix them.

To do this correctly in world space you'll have to upload the model matrix separately to get the world space incident vector.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!