Chế độ Blend pha trộn bình thường với rắc rối OpenGL


8

Tôi đã gặp rất nhiều khó khăn khi cố gắng để chức năng pha trộn OpenGL hoạt động như tôi mong đợi nó giống như những gì tôi mong đợi (hoặc từ bất kỳ chương trình chỉnh sửa hình ảnh hợp lý nào). Ví dụ: tôi sẽ sử dụng hai hình ảnh này để trộn (hơi khó nhìn trên nền trắng để màu được dán nhãn):

Hình ảnh được pha trộn

Hình ảnh thử nghiệm

Đây là những gì tôi mong đợi sẽ xảy ra (và những gì xảy ra trong paint.net):

Kết quả mong đợi

Kiểm tra hình ảnh Paint.Net

Rõ ràng chức năng pha trộn mặc định của opengl làm cho nó trông như thế này (rất sai):

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

Kiểm tra pha trộn thông thường OpenGL

Sau một tấn thử nghiệm, đây là lần gần nhất tôi có thể tạo ra một hàm pha trộn "tốt":

glBlendFuncSeparate (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)

Kiểm tra pha trộn tùy chỉnh OpenGL

Tuy nhiên, khi nhìn lại kết quả dự kiến ​​ban đầu, bạn sẽ nhận thấy rằng một số màu hơi mờ hơn một chút (phần giữa bên trái). Cụ thể, chúng được xử lý trước một nửa giá trị màu của chúng (vì 0,5 alpha) và dường như tôi không thể tạo ra một chức năng không làm điều này (mà không gây ra sự cố pha trộn kỳ lạ với phần trong suốt màu đỏ hầu như không nhìn thấy).

Có ai biết một giải pháp cho vấn đề này? Một trong những điều mà tôi đã có là sử dụng alpha tiền mã hóa trong các nguồn (trong khi tôi không muốn làm điều này vì nó đòi hỏi thêm công việc để chuyển đổi mọi màu sắc tôi sử dụng trong trò chơi của mình sang chế độ trước hoặc chỉ viết một số nội dung trong mỗi shader) và làm như vậy :

glBlendFuncSeparate (GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) (Không có tiền xử lý)

Kiểm tra pha trộn tùy chỉnh OpenGL

Rõ ràng điều đó cũng sai, nhưng đây thực sự là kết quả chính xác duy nhất tôi đã nhận được cho đến nay:

glBlendFuncSeparate (GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) (đầu vào được xử lý trước)

Kiểm tra pha trộn tùy chỉnh OpenGL

Vấn đề duy nhất là, làm thế nào tôi có thể thoát khỏi sự xuất hiện sớm để hiển thị nó trên màn hình? Có lẽ nó sẽ yêu cầu một chu kỳ kết xuất bổ sung cho từng thứ tôi pha trộn và điều đó dường như quá phức tạp cho vấn đề này, vì vậy tôi vẫn đang tìm kiếm một câu trả lời (thật thú vị khi tôi không thể tìm thấy bất cứ điều gì về điều này, vì OpenGL được sử dụng rộng rãi đến mức Tôi muốn hình ảnh người khác gặp phải vấn đề này).

Nguồn:

Kiểm tra chức năng pha trộn trực tuyến - http://www.andersriggelsen.dk/glblendfunc.php
Hình ảnh lớp dưới cùng - http://i.stack.imgur.com/XjLNW.png
Hình ảnh lớp trên cùng - http: //i.stack.imgur .com / 9CN6w.png


Tất cả các ảnh chụp màn hình đã được lấy từ Công cụ Visual glBlendFunc + glBlendEquation trực tuyến của Anders Riggelsen . Trong tương lai, loại điều đó sẽ hữu ích để đề cập khi yêu cầu giúp đỡ.
Trevor Powell

@TrevorPowell Dang Tôi biết tôi đã quên nói điều gì đó (tôi thực sự có kế hoạch đặt điều đó ở phía dưới). Dù theo cách mà tôi đang sử dụng để dễ dàng kiểm tra các chế độ hòa trộn, thì nó phải là tiêu chuẩn cho bất kỳ loại OpenGL nào khác (mặc dù tôi có thể thấy những người khác muốn sử dụng nó).
Lemon Drop

Câu trả lời:


5

Trong ví dụ đầu tiên của bạn ( glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)), bạn đang bảo nó pha trộn màu sắc dựa trên alpha của hình ảnh được vẽ trên đầu (cái "Tiền cảnh"). Vì vậy, khi bạn pha trộn 50% giữa màu nền trước (38,50,168)và màu nền (38,50,168)ở góc dưới bên trái của hình ảnh, bạn sẽ không ngạc nhiên khi có cùng một màu (38,50,168). Bởi vì sự pha trộn chéo đó chính xác là những gì bạn đã nói với OpenGL.

Đánh giá bằng hình ảnh "mong đợi" của bạn, bạn không muốn pha trộn chéo giữa hai màu - bạn muốn phủ màu nền trước lên màu nền cường độ cao, không pha trộn giữa chúng.

Để làm điều đó, bạn muốn sử dụng glBlendFuncSeparate (vì bạn đang xử lý màu nền khác với màu alpha của nó) và chỉ định rằng trong quá trình trộn, giá trị alpha nền phải được coi là 100%.

đang làm việc

Để dễ xem hơn, đây là các giá trị RGB cuối cùng được xuất ra: RGB

Và đây là giá trị minh bạch cuối cùng là đầu ra. alpha

(Vùng trong suốt '100%' đó thực sự phải được dán nhãn là trong suốt 99,7% và vùng dưới cùng bên phải '50% 'phải được dán nhãn là 49,7% trong suốt, cả hai đều do bit màu đỏ ở bên phải hình ảnh đầu tiên. Ngoài ra, xin lỗi vì đã liệt kê các số sử dụng "độ trong suốt" thay vì độ mờ đục; có thể hơi khó hiểu.)

Nếu có vấn đề cụ thể, vui lòng chỉ ra khu vực của hình ảnh RGB hoặc alpha đang tạo ra các giá trị không chính xác.


Hệ số alpha nguồn có nên không GL_ONE? dest_alpha = src_alpha * src_alpha + 1 * dest_alpha
Mặt

Chà, nếu bạn nhìn vào nó, mảnh ở giữa bên trái vẫn tối hơn rất nhiều so với nó, cũng lật các lớp làm cho nó trông giống như: i.imgur.com/rigBNz6.png (màu đỏ hầu như không nhìn thấy được ở đó để kiểm tra những thứ như đó
Lemon Drop

Bạn đang pha trộn nó ở mức 50% (0,0,0). Tất nhiên, nó tối hơn so với khi bạn trộn nó ở mức 50% (255,255,255).
Trevor Powell

@TrevorPowell Không phải là không có vấn đề gì nếu alpha là 0? Giống như các phương trình Tôi sẽ cho là như sau: finalAlpha = srcAlpha + destAlpha * (1 - srcAlpha)finalColor = ((srcColor * srcAlpha) + (destColor * destAlpha * (1 - srcAlpha))) / finalAlphaCác Color * Alphabit trong việc tính toán màu sắc có thể được thực hiện trong shaders bởi xuất ra giá trị premultiplied, nhưng theres không có cách nào để chia cho finalAlpha để thoát khỏi các premultiplication. (Lấy từ đây )
Lemon Drop

0

Tôi đã có cùng một vấn đề khi tôi muốn kết xuất một tập hợp các đối tượng bộ đệm khung chồng chéo như các lớp. Vấn đề là các hàm trộn GL mở là tuyến tính và nó hoạt động khi nền đích mờ đục. Nhưng phương trình pha trộn thực tế để trộn hai lớp trong suốt không phải là một phương trình tuyến tính và chứa một phần chia.

out_color = {src_color * src_alpha + Dest_color * Dest_alpha * (1-src_alpha)} / out_alpha

Tôi không nghĩ có thể làm điều này với các triển khai OpengGL hiện tại. Vì vậy, như một công việc xung quanh tôi đã phải sử dụng một pixel shader để tính toán thủ công đầu ra của từng pixel.


Vâng, những gì tôi đã làm chỉ là nhân lên alpha trên kết cấu thay vì thực hiện một số cách giải quyết, thật dễ dàng để làm điều đó với một số thư viện (chúng sẽ chỉ là kết cấu sớm khi tải)
Lemon Drop
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.