2012-02-10 35 views
62

Tôi nhìn thấy rất nhiều shaders đoạn khác nhau,Trình đổ bóng phân đoạn biết biến nào để sử dụng cho màu của pixel?

#version 130 

out vec4 flatColor; 

void main(void) 
{ 
    flatColor = vec4(0.0,1.0,0.0,0.5); 
} 

Và tất cả họ đều sử dụng một biến khác nhau cho các "màu out" (trong trường hợp này flatColor). Vậy OpenGL biết bạn đang cố làm gì?

Tôi đoán tính năng này hoạt động vì flatColor là biến duy nhất được xác định là out, nhưng bạn được phép thêm nhiều biến số out không phải là bạn? Hay điều đó sẽ sụp đổ?


Trên thực tế, như một thử nghiệm, tôi chỉ chạy này:

#version 330 

in vec2 TexCoord0; 

uniform sampler2D TexSampler; 

out vec4 x; 
out vec4 y; 

void main() 
{ 
    y = texture2D(TexSampler, TexCoord0.xy); 
} 

Nó hoạt động tốt cho dù tôi đã sử dụng x hoặc y.


Ngoài ra, chúng tôi đã xác định trước gl_FragColor. Sự khác biệt là gì và tại sao mọi người thường nhấn mạnh vào việc sử dụng các biến của riêng họ?

Trả lời

124

Hơn nữa, chúng tôi có một gl_FragColor được xác định trước.

Hãy bắt đầu với điều này. Không, bạn không có số được xác định trước gl_FragColor. Điều đó đã bị xóa khỏi lõi OpenGL 3.1 trở lên. Trừ khi bạn đang sử dụng tính tương thích (trong trường hợp đó, các trình đổ bóng 3.30 của bạn nên nói là #version 330 compatibility ở trên cùng), bạn sẽ không bao giờ sử dụng tính năng này.

Bây giờ, hãy quay lại đầu ra của trình đổ bóng đoạn do người dùng xác định. Nhưng trước tiên, một sự tương tự nhanh chóng.

Hãy nhớ cách thức, trong trình đổ bóng đỉnh, bạn có đầu vào? Và những đầu vào này đại diện cho các chỉ số thuộc tính đỉnh, các số bạn chuyển đến glVertexAttribPointerglEnableVertexAttribArray và v.v. Bạn thiết lập đầu vào nào kéo từ thuộc tính nào. Trong GLSL 3.30, bạn sử dụng cú pháp sau:

layout(location = 2) in color; 

này đặt shader đầu vào color đỉnh đến từ vị trí thuộc tính 2. Trước 3,30 (hoặc không có ARB_explicit_attrib_location), bạn sẽ phải một trong hai thiết lập này một cách rõ ràng với glBindAttrbLocation trước liên kết hoặc truy vấn chương trình cho chỉ mục thuộc tính với glGetAttribLocation. Nếu bạn không cung cấp vị trí thuộc tính một cách rõ ràng, GLSL sẽ chỉ định một vị trí tùy ý (ví dụ: theo cách thức được triển khai).

Đặt thiết bị trong trình đổ bóng hầu như luôn là tùy chọn tốt hơn.

Trong mọi trường hợp, kết quả đầu ra của đoạn đổ bóng hoạt động gần như giống hệt nhau. Trình tạo bóng phân đoạn có thể viết thành multiple output colors, bản thân chúng được ánh xạ tới multiple buffers in the framebuffer. Vì vậy, bạn cần phải chỉ ra đầu ra nào chuyển sang màu đầu ra của đoạn.

Quá trình này bắt đầu với giá trị vị trí đầu ra mảnh.Đó là thiết lập rất giống với địa điểm đầu vào vertex:

layout(location = 1) out secColor; 

Ngoài ra còn có các chức năng API glBindFragDataLocationglGetFragDataLocation, đó là tương tự như glBindAttribLocationglGetAttribLocation.

Nếu bạn không thực hiện bất kỳ nhiệm vụ rõ ràng nào, việc triển khai thường sẽ gán một trong các biến đầu ra của bạn cho vị trí 0. Tuy nhiên, tiêu chuẩn OpenGL không yêu cầu hành vi này, vì vậy bạn cũng không nên phụ thuộc vào nó.

Để công bằng, chương trình của bạn phải có không thành công để liên kết khi bạn sử dụng hai kết quả đầu ra không nhận được vị trí đầu ra khác nhau. Điều gì có thể xảy ra là trình biên dịch của bạn đã tối ưu hóa trình biên dịch mà bạn không viết ra, vì vậy nó đã quên mất nó khi nó đến lúc kiểm tra lỗi liên kết.

+3

Ước gì tôi có thể cung cấp nhiều hơn +1. Câu trả lời ngoạn mục. Tôi đã tự hỏi làm thế nào các vị trí đầu ra mảnh vỡ hoạt động. :) – kevintodisco

+0

Ahh .. vì vậy họ không dùng nữa 'gl_FragColor' có lợi cho bạn linh hoạt hơn để chọn bộ đệm cần ghi vào? Có ý nghĩa. Cảm ơn một lần nữa! – mpen

+3

@Mark: "Ngừng sử dụng" có nghĩa là "bạn vẫn có thể sử dụng nó, nhưng nó có thể bị xóa trong các phiên bản sau." "Đã xóa" có nghĩa là * đã xóa *. Có một sự khác biệt. Điều đó đã được đánh dấu không được chấp nhận trong GL 3.0 đã được ** gỡ bỏ ** trong 3.1 (tiết kiệm cho một vài điều). –

6

Tôi muốn chỉ định này cho OpenGLES 3.1 trong đó sử dụng GLSL_ES_3.10 link:

§4.4.2

Nếu chỉ có một đầu ra duy nhất [trong shader đoạn], các không cần phải chỉ định vị trí, trong trường hợp này, vị trí mặc định là không.

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