為什麼《孢子》可以通過.png來保存模型?

玩家可以通過下載別人的.png來玩其他玩家的模型,這裡面的具體原理是什麼?


PNG這種文件格式在內部存儲數據時是分段的。有一些數據段是必須的,比如圖像的像素信息,圖像參數,文件尾等等。還有一些是輔助數據段。按照標準來說,當一個圖像解析軟體遇到這種數據段的時候,如果不認識就可以跳過。可以在這些數據段中保存你想要的數據。

但是Spore不是這麼做的。

因為這些私有數據段在壓縮的時候有可能被其他軟體丟掉。

所以Spore把這些數據藏在像素數據里了。

他們先把模型數據導出來,然後經過幾次壓縮和加密,寫入到像素RGBA四個通道中低位上。整個過程已經被人從模型編輯器的代碼中逆向出來了,但是少了一些過程。最終可以把一個模型的數據導入到不相干的圖像上,甚至全黑圖上。但是不能導入到另一個生物的圖像上去。按照它們的說法,Spore不僅僅用了最低一位(LSB)去存模型數據,在其他位上可能也對其進行了檢查。

有時間自己寫代碼試一下好了。

邊寫邊找資料,發布後發現已經有人提到這個了,就當參考吧。


首先PNG是按照chunk(塊)來存儲的 比如說一個常規的PNG文件會有 一個IHDR塊 若干個IDAT塊 一個IEND塊
根據PNG Specification 4.2節 PNG Specification: Chunk Specifications

All ancillary chunks are optional, in the sense that encoders need not write them and decoders can ignore them.

在PNG文件中放一些非標準的輔助塊是符合標準的 圖片查看器可以忽略這些塊 也就是說 孢子可以將數據放在與PNG本身顯示無關的塊中 基本不會引起問題
意思就是 你可以打開這個PNG查看圖片內容 同時模型也存儲在你看不到的地方

但孢子的情況比較特殊 我檢查了下載到的模型PNG 裡面除了IHDR IDAT IEND 沒有其它塊
reddit網友發現孢子把數據存在了PNG的四個通道(R G B Alpha)里 McHoff be talkin" "bout Prettiest Pony in Spore"s Creature Creator
一個孢子模型的PNG文件是256x256像素的 (這個數據可能不對 reddit上說的是128x128 我去孢子上看到的是256x256的)
每個像素都有四個通道(R G B Alpha) 分別代表紅 綠 藍 透明 通道的值的大小代表對應顏色的強度 (RGB color model)
如果僅僅修改顏色數值的最後一個二進位位(改變顏色強度的256分之1) 對肉眼來說是幾乎沒有影響的
孢子正是利用了這一點 將模型信息存儲在每個通道的最後一位(其它位還做了某種校驗) 可以存儲一共256*256*4 bit = 32KByte的數據


文件後綴其實跟文件內容是沒有關聯的。
只要確保文件內容存儲的是模型數據(頂點位置,法線,紋理坐標,材質,光照等等),載入程序按照正確的內容布局進行載入,那麼模型就可以正常顯示。

後綴名只是關聯了文件打開的程序,並不代表程序可以正常載入數據。就比如說,.png模型關聯了你的圖片查看程序,但是你的圖片查看器卻打不開,因為此.png的數據布局跟圖片是不一致的。

自定義模型文件後綴名,想存成什麼就可以存成什麼。如果想(捂臉),還可以存成.zhihu、.avi、.luoyufeng、.exe、.mht或者.xjp。
-------------------------------------------------------------------------------------------------------------------------------------------
感謝 @sqybi提醒,模型.png格式可以用圖像查看器打開,因此應該是利用格式的特殊性將模型數據部分加在了尾部或其他不影響圖像屬性的地方。
另外感謝 @人笨嫌刀鈍 的回答,然後我用他的方法,把一個立方體的模型附在了一張.png圖片的後邊,寫了個非常簡陋載入程序(實時證明末尾附著模型確實可行,這也許跟.PNG圖片按分段存儲數據的特性有關),程序顯示的是一個旋轉的藍顏色線框立方體,下載鏈接:
final.png_免費高速下載。只下載圖片跟exe,放入同一目錄,運行即可。其中cube.txt是原始立方體的模型數據,用於對照數據,不下載也不影響運行。

至於開發孢子的遊戲工作室是怎麼做的,已經有回復說的很清楚,也很全面了。大家看看其他的答案是怎麼說的,我這個貌似已經嚴重偏題了......


雖然是用PNG圖片格式存儲的模型,但不是因為PNG格式的特性才能存儲模型,其他圖片格式也一樣

png存的是圖片(這個不詳細分析PNG格式存儲的特性,因為這和存儲遊戲模型無關),可以用圖片查看器來看的。

其實要存儲模型根本不需要用png那麼大,你想想哪些都是矢量的數據,就你拖動放置的組件,調整的參數啊,最多幾k就足夠了吧,你還能設計多複雜。

為什麼是PNG呢,一個「圖片」格式,因為EA為了讓你可以通過縮略圖看分辨不同的模型。就像虛擬機的快照那張圖片,虛擬機也沒高級到通過一張圖片存儲虛擬機的狀態。

關鍵是這個文件又完全符合PNG格式的標準,可以用電腦上的圖片查看器查看,可以用ps、美圖秀秀等圖片編輯軟體查看,只不過看不到任何「玄機」。

只不過這個模型「圖片」文件的大部分體積都用來存儲實際對導入數據無用的「縮略圖」,只用了一小部分零頭存儲那些矢量的可以用數字表示的真正「有用」的東西。至於這部分東西在哪,EA知道就行了,你不需要知道,也不需要看懂。

---------------------------下面舉個例子----------------------------------

準備兩個文件,一個PNG圖片,一個記事本的txt文件
png圖片是知乎的logo(包含透明像素的png圖片,看不清的清選中它):

http://static.zhihu.com/static/img/201304_sign/logo.png

txt文本文件有一行文字

這兩個文件時這樣的:

注意文本文件開始有個空格(避免一會兒合併時和圖片結尾的東西拼到一起吞幾個字)

把它們放到一個目錄下,然後運行cmd進到那個目錄下(這個沒看懂的話看下面這行,看懂的跳過下面這行)
把他們放到D盤下面,然後win+r敲cmd進到黑框框里,輸入d: 回車

然後輸入

copy logo.png /b + logo.txt newlogo.png

回車
就會看到這目錄下出現了一個新文件newlogo.png,同樣可以看到圖片,和logo一樣,屬性看似乎大小也一樣

下面把這個圖片拖到記事本里

怎麼樣,厲害吧,記事本也能看圖片了。不過是亂碼,看不懂,有點囧。
把滾動條拖到最下面,就會看到

怎麼樣,看到字了吧。

我保證以上論證過程你可以自己重現。試試吧,還有一些邪惡的用處請自行發揮。

如果我是一個程序可以根據這張圖說出上面的文字,可不是通過什麼圖像識別的高深技術,只是我看了下圖片結尾處的文字。

孢子的模型文件也是一樣的道理,只是「真正有用的東西」不一定在結尾,可能通過校驗的方式來存儲(不猜了)。即使在結尾,你也看不懂,因為你根本不知道哪幾個位元組是幹嘛的,沒法猜。

電腦上人眼能看懂的東西八成就是給人看的,電腦才不會「看懂」那個(圖像識別神馬的除外)。
電腦程序肯定有其他的方式去「看懂」它。

你都看到這了,就不點下贊 O(∩_∩)O~~


突然想起貼吧上的圖片,右鍵另存,改後綴為torrent後具有神奇效果!
我是不是知道的太多了?


我印象中孢子大量使用了metaBall(具體名字待確認),其模型的存儲方式與一般模型應該差別非常大,metaball只需要存儲量相對很少的參數就能在運行時計算生成相應的模型。

還在旅遊,回去有時間查下。


個人觀點
我個人估計是在png文件裡面添加了模型參數(大小,位置,屬性),而png文件只是一張截圖而已,讀取的時候不是讀的圖片而是裡面的參數,就像種子圖一樣。


推薦閱讀:

本世紀以來有哪些廣為人知的圖片?
如何評價Marc Riboud馬克呂布這樣一位攝影師?
求一張圖片,一個人走在路上,但是他的影子是和一頭龍搏鬥?
看「少女老婦圖」的時候,為什麼一次只能看到一個人物?

TAG:藝電EA | 遊戲 | 圖片 | 孢子遊戲|Spore |