2012-03-23 28 views
6

Tôi đang viết bóng đổ GLSL mô phỏng quang sai màu cho các đối tượng đơn giản. Tôi đang ở lại OpenGL 2.0 tương thích, vì vậy tôi sử dụng ngăn xếp ma trận OpenGL tích hợp sẵn. Đây là trình đổ bóng đỉnh đơn giản:Phản xạ/khúc xạ với quang sai màu - hiệu chỉnh mắt

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(); 
} 

Đồng nhất là vị trí của máy ảnh trong không gian mô hình, như bạn có thể tưởng tượng. Đây là shader đoạn:

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); 
} 

Các environment là một bản đồ hình khối được trả trực tiếp từ môi trường các hình vẽ tay của.

Trong những trường hợp bình thường, shader cư xử (tôi nghĩ) như mong đợi, năng suất kết quả này:

correct shader behavior

Tuy nhiên, khi các camera có thể xoay 180 độ xung quanh mục tiêu của nó, vì vậy mà nó bây giờ chỉ vào đối tượng từ phía bên kia, những khúc xạ/hình ảnh phản ánh bị biến dạng như vậy (Điều này xảy ra dần dần cho góc giữa 0 và 180 độ, tất nhiên):

incorrect shader behavior

Các hiện vật tương tự xuất hiện khi máy ảnh hạ xuống/nâng lên; nó chỉ có vẻ hoạt động chính xác 100% khi máy ảnh trực tiếp trên đối tượng đích (hướng về phía Z âm, trong trường hợp này).

Tôi đang gặp khó khăn trong việc tìm ra chuyển đổi nào trong trình đổ bóng chịu trách nhiệm cho hình ảnh bị biến dạng này, nhưng cần phải có điều gì đó rõ ràng liên quan đến cách xử lý cameraPos. Điều gì gây ra hình ảnh để làm cong chính nó theo cách này?

Trả lời

2

này trông nghi ngờ với tôi:

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

là bạn cameraPos được xác định trong không gian thế giới? Bạn đang trừ một vector không gian xem (position), từ một không gian được cho là trên thế giới cameraPos vectơ. Bạn cần phải thực hiện phép tính trong không gian thế giới hoặc xem không gian, nhưng bạn không thể trộn chúng.

Để làm điều này một cách chính xác trong không gian thế giới, bạn sẽ phải tải lên ma trận mô hình riêng biệt để có được véc tơ không gian trên thế giới.

+0

Đây là nó! Tôi cũng phải thay thế 'gl_NormalMatrix' bằng' mat3 (modelMatrix) 'vì những lý do rõ ràng. Nó không bao giờ xảy ra với tôi rằng tôi nên xem xét không gian của biến 'vị trí', nó dường như là tầm thường bằng cách nào đó. Cảm ơn! – dflemstr

Các vấn đề liên quan