Texture XOR (2004)
(lodev.org)- Texture XOR là một procedural texture đơn giản được tạo bằng cách XOR tọa độ x, y của pixel, hữu ích khi cần thử nhanh texture mapper mà không cần file ảnh
- Trong C++, có thể tạo giá trị
x ^ ybằng toán tử^rồi đưa vào RGB để tạo ra mẫu thang độ xám; XOR chỉ trả về 1 khi hai bit khác nhau - Kích thước texture trông đẹp nhất khi là lũy thừa của 2, và với kích thước nhỏ hơn 256 thì dải giá trị hẹp nên sẽ tối hơn, có thể nhân giá trị màu để bù lại
- Texture XOR lớn hơn 256 không tăng chất lượng do bị giới hạn trong dải màu 0~255 của kênh 8 bit; với kích thước lớn hơn cần chia nhỏ giá trị hoặc dùng kênh có nhiều bit hơn
- Cùng cách dựa trên tọa độ đó, có thể áp dụng
&và|để tạo texture AND, OR; AND tối hơn, OR sáng hơn, và tổng của XOR với AND sẽ thành OR
Texture XOR dùng được ở đâu
- Texture XOR rất dễ tạo và cũng là một procedural texture nhìn khá thuyết phục về mặt thị giác
- Trong các bản demo hay intro release, nó đã bị dùng quá thường xuyên nên không phải lựa chọn hay; trong game cũng ít thực dụng nếu không phải để làm những thứ như gạch lát sàn sặc sỡ
- Có thể nhanh chóng kiểm tra một texture mapper mới có hoạt động hay không mà không cần tải file ảnh hoặc viết mã sinh texture phức tạp
Tạo mẫu bằng XOR tọa độ
- Ý tưởng cơ bản là XOR tọa độ
xvà tọa độycủa pixel hiện tại - Trong C++, toán tử XOR là
^ - Đoạn mã ví dụ tính giá trị cho mọi pixel trên màn hình 256×256
Uint8 c = x ^ y- Đặt màu thang độ xám bằng
ColorRGB(c, c, c)
- Kết quả hiển thị là mẫu XOR được tạo từ sự kết hợp các mẫu bit của tọa độ
Ràng buộc về kích thước và dải màu
- Kích thước texture trông đẹp hơn khi là lũy thừa của 2
- Giá trị của các thành phần màu nằm trong khoảng từ 0 đến 255
- Giá trị màu tối đa tạo ra bởi phép XOR sẽ bằng kích thước texture khi kích thước đó là lũy thừa của 2
- Các mẫu như 64, nhỏ hơn 256, sẽ trông quá tối
- Có thể khôi phục độ sáng bằng cách nhân giá trị màu lên 4 lần
- Với kích thước lớn hơn 256 như 512, cần giới hạn màu để không vượt quá 256
- Có thể dùng phép lấy dư với 256, nhưng khi đó sẽ không còn là mẫu XOR thực sự nữa
- Chia cho 2 là lựa chọn tốt hơn
- Với kênh 8 bit, không có đủ mức màu phân biệt được nên chất lượng của texture XOR lớn hơn 256×256 sẽ không cao hơn
- Nếu chế độ màu hỗ trợ nhiều bit hơn, giới hạn của texture lớn có thể sẽ khác
Cách XOR hoạt động ở mức bit
- XOR thực hiện phép toán trên từng cặp bit tương ứng trong biểu diễn nhị phân của hai số nguyên
- Exclusive OR trả về 1 nếu hai bit khác nhau, và 0 nếu giống nhau
- Bảng chân trị như sau
0 XOR 0 = 00 XOR 1 = 11 XOR 0 = 11 XOR 1 = 0
- Ví dụ,
5 XOR 13 = 8- Ở dạng nhị phân là
0101 XOR 1101 = 1000
- Ở dạng nhị phân là
Biến thể màu sắc
- Giá trị XOR có thể được áp dụng khác nhau cho từng kênh RGB chứ không chỉ là thang độ xám
- Trong ví dụ, màu được tạo bằng
c = x ^ yr = 255 - cg = cb = c % 128
- Cũng có thể dùng giá trị XOR làm hue của màu HSV rồi đưa vào hàm
HSVtoRGB- Trong ví dụ,
ColorHSV(c, 255, 255)được chuyển đổi bằngHSVtoRGBđể dùng làm màu pixel
- Trong ví dụ,
Texture AND và OR
- Ngoài XOR, cũng có thể dùng toán tử AND và OR để tạo các texture dựa trên tọa độ tương tự
- Trong C++, toán tử AND là
&, còn OR là| - AND chỉ trả về 1 khi cả hai bit đều là 1
0 AND 0 = 00 AND 1 = 01 AND 0 = 01 AND 1 = 1
- OR trả về 1 nếu một trong hai hoặc cả hai bit là 1
0 OR 0 = 00 OR 1 = 11 OR 0 = 11 OR 1 = 1
- Texture AND tối hơn vì chỉ có một trường hợp trả về 1, còn texture OR sáng hơn vì có nhiều trường hợp trả về 1 hơn
- Tổng của texture XOR và texture AND sẽ tạo thành texture OR
Kết luận và ví dụ ứng dụng
- Texture XOR rất dễ tạo, nên hữu ích để kiểm tra texture renderer có hoạt động hay không
- Nó không phù hợp cho tác phẩm nghệ thuật hay các ứng dụng như game
- Cũng có thể dùng dưới dạng texture 3D kiểu
x ^ y ^ z; trong ví dụ, nó được dùng để kiểm tra texture renderer của hành tinh có hoạt động đúng hay không
1 bình luận
Ý kiến trên Hacker News
Nhờ đó tôi có thể thử làm lại các game retro như Pacman, Snake, Space Invaders, và làm được những thứ không thể thực hiện chỉ bằng terminal
Tôi nghĩ trang này là cơ duyên giúp tôi bắt đầu sự nghiệp phát triển phần mềm từ khi còn khá nhỏ. Hồi đó tôi gần như học thuộc các trang và ví dụ ở https://lodev.org/cgtutor/, còn một phần toán học thì lúc ấy tôi hoàn toàn không hiểu
Thay vì
x ^ y, tôi dùngparity(x ^ y): nếu số bit 1 là chẵn thì tô một màu, nếu lẻ thì tô màu khác. Nhìn nó giống kiểu lát gạch gần như lặp lại nhưng không hoàn toàn lặp, nên khá thú vị về mặt thị giácLục lại file cũ thì thấy tôi viết bằng fasm vào năm 2019 và tạo file XPM2; muốn xem thì phải chuyển thủ công sang XPM3. Ảnh kết quả ở đây: https://i.postimg.cc/FsFhXSHG/xortiles.png
Nếu muốn tôi cũng có thể đăng mã lên, nhưng không chắc có ai quan tâm không
Xor(x,y)thì khoảng cách Hamming có lẽ sẽ làPopCount(Xor(x,y))Chắc vậy?
Tôi thả nhẹ blog của mình rồi lẩn đi: https://nicknash.me/2012/10/26/happy-halloween/
5 4 7 6 1 0 3 2color = (y == (x ^ t))và thay đổi giá trị t, ta sẽ có hiệu ứng tương tự; nó được gọi là munching squaresBan đầu nó được viết cho PDP-1 vào đầu thập niên 1960, và tôi từng thấy nó được trình diễn trên chiếc PDP-1 ở Computer History Museum
Màn hình PDP-1 chỉ có thể chấm điểm và không dùng framebuffer bitmap, nên tôi luôn thắc mắc làm thế nào nó tạo ra được texture XOR đặc trưng
Hóa ra là nhờ tận dụng độ lưu sáng dài của phosphor trên màn hình, trong đó độ sáng của từng điểm giảm dần theo thời gian
CHM có video chạy chương trình, nhưng hiệu ứng lưu sáng phosphor không được ghi lại rõ: https://www.computerhistory.org/collections/catalog/10266415...
Video chạy trên MAME phần nào cho thấy cách độ lưu sáng phosphor tạo ra texture XOR: https://youtu.be/AxJzUiaQ7xM?si=X9K47c4WyD6AisUp
Dwitter giống như Twitter dành cho các ví dụ JavaScript một dòng dùng canvas, và người dùng phải gói tác phẩm của mình trong 140 byte
Cũng có nhiều biến thể dùng các toán tử nhị phân khác để tạo tam giác Sierpinski: https://www.dwitter.net/h/sierpinski
Trông khá giống hình nhờ dùng thang màu cầu vồng giống một trong các hình ở cuối trang, và hiện tôi đang treo nó trên tường như một món trang trí kích thước 6 foot × 6 foot
Tài liệu đã 20 năm tuổi, nhưng đặc biệt nếu bạn làm shader, vẫn còn nhiều nội dung hữu ích trong nhiều trường hợp
~:"1/~&.#:i.2^8Có thể xem ở đây: https://jsoftware.github.io/j-playground/bin/html2/#base64=b...