2012-11-08 28 views
12

Khi tôi sử dụng bóng đổ của tôi, tôi có được kết quả như sau: enter image description hereGLSL gương sáng

enter image description here

Một vấn đề là ánh sáng phản chiếu là loại biến dạng và bạn có thể nhìn thấy hình tam giác hình cầu, khác là, tôi có thể xem specular nơi tôi không nên (hình ảnh thứ hai). Một ánh sáng không gian được thực hiện trong vertex shader, khác trong fragment.

Sau đây là cách đổ bóng ánh sáng đỉnh của tôi trông giống như: Vertex:

// Material data. 
uniform vec3 uAmbient; 
uniform vec3 uDiffuse; 
uniform vec3 uSpecular; 
uniform float uSpecIntensity; 
uniform float uTransparency; 

uniform mat4 uWVP; 
uniform mat3 uN; 
uniform vec3 uSunPos; 
uniform vec3 uEyePos; 
attribute vec4 attrPos; 
attribute vec3 attrNorm; 
varying vec4 varColor; 

void main(void) 
{ 
    vec3 N = uN * attrNorm; 
    vec3 L = normalize(uSunPos); 
    vec3 H = normalize(L + uEyePos); 
    float df = max(0.0, dot(N, L)); 
    float sf = max(0.0, dot(N, H)); 
    sf = pow(sf, uSpecIntensity); 

    vec3 col = uAmbient + uDiffuse * df + uSpecular * sf; 
    varColor = vec4(col, uTransparency); 
    gl_Position = uWVP * attrPos; 
} 

Fragment:

varying vec4 varColor; 

void main(void) 
{ 

    //vec4 col = texture2D(texture_0, varTexCoords); 
    //col.r += uLightDir.x; 
    //col.rgb = vec3(pow(gl_FragCoord.z, 64)); 
    gl_FragColor = varColor; 

} 

Có thể, rằng dữ liệu cung cấp của tôi từ mã là sai. uN là ma trận thế giới (không đảo ngược và không chuyển đổi, mặc dù làm điều đó dường như không làm bất cứ điều gì khác nhau). UWVP - ma trận chiếu trên thế giới.

Bất kỳ ý tưởng nào về vấn đề có thể xảy ra ở đâu, sẽ được đánh giá cao.

[EDIT] Đây là tính toán ánh sáng của tôi thực hiện trong đoạn: Vertex Shader file:

uniform mat4 uWVP; 
uniform mat3 uN; 
attribute vec4 attrPos; 
attribute vec3 attrNorm; 
varying vec3 varEyeNormal; 

void main(void) 
{ 
    varEyeNormal = uN * attrNorm; 
    gl_Position = uWVP * attrPos; 
} 

Fragment tập tin shader:

// Material data. 
uniform vec3 uAmbient; 
uniform vec3 uDiffuse; 
uniform vec3 uSpecular; 
uniform float uSpecIntensity; 
uniform float uTransparency; 

uniform vec3 uSunPos; 
uniform vec3 uEyePos; 
varying vec3 varEyeNormal; 

void main(void) 
{ 
    vec3 N = varEyeNormal; 
    vec3 L = normalize(uSunPos); 
    vec3 H = normalize(L + uEyePos); 

    float df = max(0.0, dot(N, L)); 
    float sf = max(0.0, dot(N, H)); 
    sf = pow(sf, uSpecIntensity); 

    vec3 col = uAmbient + uDiffuse * df + uSpecular * sf; 

    gl_FragColor = vec4(col, uTransparency); 
} 

[EDIT2] Như Joakim chỉ ra, tôi wasn' t bình thường hóa varEyeNormal trong shader fragment. Sau khi sửa lỗi đó, kết quả tốt hơn nhiều trong trình đổ bóng phân đoạn. Tôi cũng đã sử dụng chức năng bình thường hóa trên uEyePos, do đó, hình ảnh không còn đi vào mặt tối. Cảm ơn vì sự giúp đỡ.

enter image description here

+0

tôi tin rằng bạn nên phủ nhận normals của bạn.(các đốm sáng ở mặt tối) –

+0

Như sau: vec3 negNormal = vec3 (-attrNorm.x, -attrNorm.y, -attrNorm.z); vec3 N = uN * không bình thường; ? Với điều này tôi không thấy cái nhìn nào cả. – SMart

+0

Tôi đã nói về bức tranh thứ hai, nơi ánh sáng khuyếch tán sẽ dương nếu gương phản xạ tích cực. Bạn có thể tạo ra một jsfiddle không? –

Trả lời

19

Câu trả lời ngắn: Bạn cần phải bình thường hóa varEyeNormal trong shader đoạn, thay vì trong vertex shader.

Câu trả lời dài hơn: Để có được ánh sáng mượt mà, bạn sẽ cần phải tính toán các chỉ tiêu cho mỗi pixel thay vì mỗi đỉnh. Các thay đổi được tính toán trong bóng đổ đỉnh được nội suy tuyến tính trước khi được chuyển tới trình đổ bóng phân đoạn, hoạt động tốt như một phím tắt trong một số trường hợp nhưng lại tệ hơn ở các trường hợp khác.

Lý do bạn nhìn thấy các cạnh tam giác là do nội suy giữa các tiêu chuẩn dẫn đến ngắn hơn 1.0 normals trong tất cả các pixel giữa các đỉnh.

Để sửa lỗi này, bạn sẽ cần phải bình thường hóa các tiêu chuẩn trong trình đổ bóng phân đoạn thay vì trong trình đổ bóng đỉnh.

Ma trận bình thường nên 3x3 trên của transpose của nghịch đảo của ma trận ModelView, đó là tương đương với 3x3 trên của của ma trận ModelView nếu modelview chỉ chứa phép quay và bản dịch (không gỉ)

để biết thêm về ma trận bình thường, xem: http://www.lighthouse3d.com/tutorials/glsl-tutorial/the-normal-matrix/

(Edited cho đúng đắn theo bình luận dưới đây.)

+5

Bạn chỉ về ma trận bình thường là sai. Nó là nghịch đảo ** và ** transpose của 3x3 trên của ma trận modelview. Vì vậy, nếu ma trận modelview chỉ có phép quay và bản dịch, nó chính xác giống như trên 3x3 của ma trận modelview (bởi vì đảo ngược và chuyển vị hủy bỏ cho phép quay, và bản dịch vẫn được nhập), đó có thể là lý do tại sao nó không ' t thực hiện bất kỳ sự khác biệt cho OP để đảo ngược nó hay không. –

+2

Bạn đã chính xác, tôi đã chỉnh sửa câu trả lời của mình –