2009-08-17 32 views
14

Ok, trong trình đổ bóng đoạn GLSL của tôi, tôi muốn có thể tính toán khoảng cách của đoạn từ một dòng cụ thể trong không gian.Cách tính gl_FragCoord trong glsl

Kết quả của việc này là tôi đang đầu tiên cố gắng sử dụng một bộ vec2 khác nhau trong vertex shader của tôi để phản ánh những gì kết thúc trong gl_FragCoord:

varying vec2 fake_frag_coord; 
//in vertex shader: 
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
fake_frag_coord=(gl_ModelViewProjectionMatrix * gl_Vertex).xy; 

Bây giờ trong shader đoạn tôi mong đợi:

gl_FragCoord.xy==fake_frag_coord 

Nhưng không. Đường ống nào hoạt động theo cách nào trên gl_Position để biến nó thành gl_FragCoord mà tôi đang bỏ qua để thực hiện trên fake_frag_coord?

Trả lời

11

gl_FragCoord là tọa độ màn hình, vì vậy bạn cần có thông tin về kích thước màn hình và như vậy để tạo ra nó dựa trên Vị trí. Các fake_frag_coord bạn đã sản xuất sẽ tương ứng với một điểm trong màn hình trong tọa độ thiết bị chuẩn hóa tôi nghĩ (-1-1). Vì vậy, nếu bạn nhân đôi kích thước của màn hình trong một thứ nguyên cụ thể và sau đó thêm kích thước đó, bạn sẽ nhận được pixel màn hình thực tế.

+1

Tôi đã sai về bạn là sai, nhưng phải về việc sử dụng gl_ModelViewProjectionMatrix * gl_Vertex có khả năng giới thiệu lỗi tính toán. – karx11erx

+2

Nitpick: điều đó thực sự sẽ cung cấp cho bạn tọa độ không gian thay vì tọa độ thiết bị chuẩn hóa, vì bạn không thực hiện phân chia phối cảnh xảy ra trong quá trình rasterisation (giữa đổ bóng đỉnh và đổ bóng). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 Đó không chỉ là một nitpick, nó sẽ dẫn đến các giá trị hoàn toàn khác nhau cho phép chiếu phối cảnh. –

0

Vấn đề bạn có là gl_ModelViewProjectionMatrix * gl_Vertex được tính toán trong trình đổ bóng không phải lúc nào cũng là đường ống chức năng cố định tạo ra. Để có được kết quả giống hệt nhau, hãy làm fake_frag_coord = ftransform().

Chỉnh sửa:

Và sau đó mở rộng quy mô với kích thước màn hình của bạn.

+0

ftransform tạo vị trí, không phải là mảnh vỡ. Câu hỏi không phải là hỏi làm thế nào để có được vị trí. –

+0

Câu trả lời của tôi không hoàn toàn sai. Bạn cần phải scale fake_frag_coord với kích thước màn hình của bạn, nhưng bạn có thể nhận được các kết quả khác nhau tùy thuộc vào việc bạn sử dụng fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex hay = ftransform(). – karx11erx

-2
varying vec2 fake_frag_coord; 
//in vertex shader: 

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

Tôi ước mình có thêm đại diện để tôi cũng có thể nitpick. Đây là những gì tôi biết. OpenGL thực hiện Divide-By-W tự động cho bạn, do đó, vào thời điểm một vị trí đến trong một shader fragment, nó đã ở tọa độ NDC, và sau đó W sẽ là 1.0, thời gian duy nhất bạn cần chia cho W là bạn muốn làm cùng một phép toán ở phía CPU, và nhận được kết quả tương tự, HOẶC, nếu bạn vì một lý do kỳ lạ nào đó, muốn có được tọa độ NDC trong bóng đổ đỉnh của bạn.

+1

'gl_FragCoord' là ** không ** trong NDC. Nó nằm trong các tọa độ cửa sổ. –