2012-06-13 40 views
7

Tôi có một chương trình tạo bản đồ chiều cao và sau đó hiển thị nó dưới dạng lưới với OpenGL. Khi tôi cố gắng để thêm ánh sáng, nó kết thúc với hình dạng vuông lạ bao gồm lưới. Họ là đáng chú ý hơn ở một số khu vực hơn những người khác, nhưng luôn luôn ở đó.Các đồ tạo tác ánh sáng vuông lạ trong OpenGL

Tôi đã sử dụng lưới tứ giác, nhưng không có gì thay đổi sau khi chuyển sang lưới tam giác. Tôi đã sử dụng ít nhất ba phương pháp khác nhau để tính toán các chỉ tiêu đỉnh, tất cả đều có cùng tác dụng. Tôi đã thực hiện ánh sáng theo cách thủ công bằng các trình đổ bóng, nhưng không có gì thay đổi khi sử dụng hệ thống chiếu sáng OpenGL được tích hợp sẵn.

mã bình thường-tạo mới nhất của tôi (đang phải đối mặt là một mảng của các chỉ số thành Verts, mảng đỉnh):

int i; 
for (i = 0; i < NINDEX; i += 3) { 
    vec v[3]; 
    v[0] = verts[faces[i + 0]]; 
    v[1] = verts[faces[i + 1]]; 
    v[2] = verts[faces[i + 2]]; 

    vec v1 = vec_sub(v[1], v[0]); 
    vec v2 = vec_sub(v[2], v[0]); 

    vec n = vec_norm(vec_cross(v2, v1)); 

    norms[faces[i + 0]] = vec_add(norms[faces[i + 0]], n); 
    norms[faces[i + 1]] = vec_add(norms[faces[i + 1]], n); 
    norms[faces[i + 2]] = vec_add(norms[faces[i + 2]], n); 
} 

for (i = 0; i < NVERTS; i++) { 
    norms[i] = vec_norm(norms[i]); 
} 

Mặc dù đó không phải là mã duy nhất mà tôi đã sử dụng, vì vậy tôi nghi ngờ rằng nó là nguyên nhân của vấn đề.

tôi vẽ lưới với:

Và tôi hiện không sử dụng bất kỳ shaders.

Điều gì có thể gây ra điều này?

EDIT: Một tập hợp toàn diện hơn về ảnh chụp màn hình:

Đối với người cuối cùng, mã shader là

Vertex:

varying vec3 lightvec, normal; 

void main() { 
    vec3 lightpos = vec3(0, 0, 100); 
    vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex); 
    normal = gl_NormalMatrix * gl_Normal; 

    lightvec = normalize(lightpos - v); 

    gl_Position = ftransform(); 
} 

Fragment:

varying vec3 lightvec, normal; 

void main(void) { 
    float l = dot(lightvec, normal); 
    gl_FragColor = vec4(l, l, l, 1); 
} 
+0

Bạn có thể đăng hai ảnh chụp màn hình của cùng một cảnh, một ảnh có khung dây và một ảnh không có khung hình không? –

+0

Có phải 'chỉ số' không được khởi tạo không? Bạn đang tích lũy các vectơ của bạn vào nó mà không cần zeroing nó trước, mặc dù nếu nó được zeroed ở nơi khác trong chương trình mà không phải là một vấn đề. – genpfault

+0

bạn có đang sử dụng nội suy trơn cho các thuộc tính bình thường trong trình đổ bóng không? Có thể chuyển sang 'phẳng' một chút có thể giúp bản địa hóa vấn đề. Ngoài ra, ánh sáng OpenGL có xu hướng rất khó khăn đối với tôi - tôi thường chắc chắn hơn về mã tôi đã tự viết. –

Trả lời

1

Tôi không có một câu trả lời dứt khoát cho các phiên bản không đổ bóng, nhưng tôi muốn thêm rằng nếu bạn đang làm mỗi sáng pixel trong trình đổ bóng phân đoạn của bạn, có lẽ bạn nên chuẩn hóa bình thường và lightvec bên trong trình đổ bóng phân đoạn.

Nếu bạn không làm điều này, chúng không phải là chiều dài đơn vị (một phép nội suy tuyến tính giữa hai vectơ chuẩn hóa không nhất thiết phải được chuẩn hóa). Điều này có thể giải thích một số hiện vật bạn thấy trong phiên bản đổ bóng, vì độ lớn của sản phẩm chấm sẽ thay đổi như một hàm của khoảng cách từ các đỉnh, trông giống như những gì bạn đang thấy.

EDIT: Một suy nghĩ khác, bạn có đang thực hiện bất kỳ tỷ lệ không đồng nhất nào (khác nhau x, y, z) của lưới khi hiển thị phiên bản không đổ bóng không? Nếu bạn mở rộng quy mô, thì bạn cần phải sửa đổi các chỉ tiêu theo hệ số tỷ lệ nghịch đảo hoặc đặt glEnable(GL_NORMALIZE).Xem ở đây để biết thêm: http://www.lighthouse3d.com/tutorials/glsl-tutorial/normalization-issues/

2

Bạn cần phải hoặc chuẩn hóa bình thường trong shader đoạn, như vậy:

varying vec3 lightvec, normal; 

void main(void) { 
    vec3 normalNormed = normalize(normal); 
    float l = dot(lightvec, normalNormed); 
    gl_FragColor = vec4(l, l, l, 1); 
} 

này có thể tốn kém mặc dù. Điều gì cũng sẽ làm việc trong trường hợp này, với ánh sáng định hướng, là sử dụng ánh sáng đỉnh. Vì vậy, tính giá trị ánh sáng trong vertex

varying float lightItensity; 

void main() { 
    vec3 lightpos = vec3(0, 0, 100); 
    vec3 v = vec3(gl_ModelViewMatrix * gl_Vertex); 
    normal = gl_NormalMatrix * gl_Normal; 

    lightvec = normalize(lightpos - v); 

    lightItensity = dot(normal, lightvec); 

    gl_Position = ftransform(); 
} 

và sử dụng nó trong các shader mảnh,

varying float light; 

void main(void) { 
    float l = light; 
    gl_FragColor = vec4(l, l, l, 1); 
} 

Tôi hy vọng điều này sửa chữa nó, cho tôi biết nếu nó không.

EDIT: Heres một sơ đồ nhỏ mà giải thích những gì có thể xảy ra nhất

enter image description here

EDIT2:

Nếu điều đó không giúp đỡ, thêm hình tam giác. Nội suy các giá trị của chiều cao của bạn và thêm một số đỉnh ở giữa.

Cách khác, hãy thử thay đổi sơ đồ tesselation của bạn. Ví dụ một lưới tam giác đều như vậy có thể làm cho các hiện vật ít nổi bật hơn.

enter image description here

Bạn sẽ phải thực hiện một số nội suy trên heightmap của bạn.

Nếu không, tôi không có ý tưởng .. Chúc may mắn!

+0

Cảm ơn, nhưng tiếc là tôi đã thử làm một cái gì đó như thế này. Tôi bắt đầu tự hỏi nếu vấn đề là trong card đồ họa của tôi (chip tích hợp Intel 1.5 năm). – sigill

+0

Tôi rất nghi ngờ điều đó. Mã shader nên thực hiện theo cùng một cách trên bất kỳ card đồ họa hỗ trợ nó. – Hannesh

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