Tôi đang làm việc trên một chương trình WebGL thực hiện ánh xạ bóng. Sau khi tính toán các giá trị độ sâu ở từng đoạn, tôi có một câu lệnh if ở cuối để tính toán ánh sáng dựa trên việc liệu đoạn đó có nằm trong bóng hay không.Trình đổ bóng đoạn WebGL không phân nhánh chính xác trên if statement
gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1);
if (light_tex_coord.z - depth <= 0.0) {
gl_FragColor += vec4
(calcLighting(light1, eye_dir, eye_dir_norm, normal)
, 0.0
);
}
nơi depth
là chiều sâu của bản đồ bóng và light_tex_coord
là vị trí của mảnh trong không gian cảnh của light1
. light1
là một điểm sáng xoay quanh mô hình, và light0
là một điểm ánh sáng tĩnh vị trí tại máy ảnh.
Vấn đề ở đây là nếu nhánh không bao giờ được thực hiện, vì vậy cảnh chỉ có light0
áp dụng cho nó. Tôi đã kiểm tra rằng depth
, light_tex_coord
và calculateLighting
hoạt động chính xác.
Đây là điều lạ, tuy nhiên, thay thế ở trên với đoạn mã sau:
if (light_tex_coord.z - depth <= 0.0) {
gl_FragColor = vec4(0,1,0,1);
} else {
gl_FragColor = vec4(1,0,0,1);
}
Nguyên nhân shadowed khu vực được rút ra một cách chính xác màu đỏ, và không bóng tối để được rút ra trong màu xanh lá cây. Tức là, nhánh được đánh giá đúng. Thay thế nó bằng này:
gl_FragColor = vec4(calcLighting(light0, eye_dir, eye_dir_norm, normal), 1);
gl_FragColor += vec4
(calcLighting(light1, eye_dir, eye_dir_norm, normal)
, 0.0
);
Nguyên nhân ánh sáng được tính toán một cách chính xác (sans bóng, mặc dù). Có vẻ như khi tôi gọi hàm calcLighting đắt tiền hơn trong câu lệnh if, nó thậm chí không bận tâm lấy nó.
Hơn nữa, tôi đã thử áp dụng ánh sáng theo nhiều cách, kể cả sử dụng chức năng clamp
; luôn thực hiện việc thêm và sử dụng toán tử terinary để nhân số thứ hai gọi calcLighting
bằng 1 hoặc 0 và sắp xếp câu lệnh if của tôi theo nhiều cách khác nhau. Không có gì có vẻ hiệu quả.
Có điều gì tôi thiếu về cách phân nhánh hoạt động trong webgl không?
Bạn đã thử tích lũy màu thành biến 'vec4' riêng biệt và ** chỉ ** gán' gl_FragColor' giá trị của biến khác này một lần. Việc ghi vào 'gl_FragColor' nhiều lần trong một shader được hỗ trợ như đang đọc giá trị của nó (cần thiết để thực hiện' + = ') nhưng tất cả các tài khoản vấn đề này dường như liên quan đến một hoặc cả hai hành động này cho dòng điều khiển của bạn. –
Tôi đã thử thay thế tất cả các trường hợp 'gl_FragColor' trong các đoạn mã trên bằng một bộ tích lũy' vec4 acc; '. Tôi chỉ được chỉ định ở cuối trình đổ bóng với 'gl_FragColor = acc;' Không thay đổi trong bất kỳ trường hợp nào ở trên. – Cookyt
Bạn có thể cung cấp toàn bộ mã fs không? Ngoài ra, nó sẽ tạo ra sự khác biệt nếu bạn thay đổi mã thành 'gl_FragColor + = vec4 (calcLight (..), 1.0)'? [note 1.0 alpha value] –