1 điểm bởi GN⁺ 2024-12-19 | 1 bình luận | Chia sẻ qua WhatsApp
  • 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 ^ y bằ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 &| để 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 độ x và tọa độ y củ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 = 0
    • 0 XOR 1 = 1
    • 1 XOR 0 = 1
    • 1 XOR 1 = 0
  • Ví dụ, 5 XOR 13 = 8
    • Ở dạng nhị phân là 0101 XOR 1101 = 1000

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 ^ y
    • r = 255 - c
    • g = c
    • b = 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ằng HSVtoRGB để dùng làm màu pixel

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 = 0
    • 0 AND 1 = 0
    • 1 AND 0 = 0
    • 1 AND 1 = 1
  • OR trả về 1 nếu một trong hai hoặc cả hai bit là 1
    • 0 OR 0 = 0
    • 0 OR 1 = 1
    • 1 OR 0 = 1
    • 1 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 XORtexture 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

 
GN⁺ 2024-12-19
Ý kiến trên Hacker News
  • Hồi học cấp hai, tôi có mày mò lập trình một chút nhưng chỉ biết làm các ứng dụng CLI đơn giản chạy trong terminal. Rồi một ngày tôi tình cờ tìm thấy Lode's Computer Graphics Tutorial và lần đầu tiếp xúc với những ví dụ dễ hiểu về cách mở cửa sổ rồi vẽ đồ họa lên màn hình
    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
  • Trước đây tôi từng viết một chương trình x86 assembly nhỏ tạo ảnh bằng kỹ thuật tương tự, nhưng màu chỉ là 1 bit
    Thay vì x ^ y, tôi dùng parity(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ác
    Lụ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
  • Tôi nhớ đến texture khoảng cách Hamming: https://chalkdustmagazine.com/features/the-hidden-harmonies-...
  • Một sự thật thú vị: mỗi điểm trong texture XOR là số nguyên nhỏ nhất chưa xuất hiện ở phía trên hoặc bên trái của nó
    Tôi thả nhẹ blog của mình rồi lẩn đi: https://nicknash.me/2012/10/26/happy-halloween/
    • Trong ma trận ví dụ, hàng bắt đầu bằng 5 bị sai; đúng ra phải là
      5 4 7 6 1 0 3 2
  • Nếu tạo animation bằng một hàm như color = (y == (x ^ t)) và thay đổi giá trị t, ta sẽ có hiệu ứng tương tự; nó được gọi là munching squares
    Ban đầ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
  • Có một trang có hàng nghìn ví dụ như thế này: https://www.dwitter.net/
    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
  • Tôi từng dùng texture này để làm một tấm quilt
    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
  • Đây là một trang khá hay. Tôi khuyên nên lên một cấp và xem cả các trang khác nữa
    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
  • Gần đây tôi có nghịch mẫu này trong J, có thể biểu diễn như sau
    ~:"1/~&.#:i.2^8
    Có thể xem ở đây: https://jsoftware.github.io/j-playground/bin/html2/#base64=b...
  • Vừa đọc https://news.ycombinator.com/item?id=42414817 xong, nên chắc có thể xem texture XOR cũng là một phát hiện tình cờ