2012年12月30日 星期日

Terrain Vertex Color

Vertex color如果我們希望有透明水彩的樣子,會透到舊的Vertex color的話,就會用顏色做lerp,會有強度做為參數,調整與舊有的顏色做加總,公式如下:
strength * color + (1 - strength) * last time color = Final Vertex color
其實就是alpha blending的公式。(上面的數值應該都保持0~1之間)

最後跟我們一般的Diffuse做相乘(應該很少會讓地表的vertex color直接覆蓋掉Diffuse)。

那因為做這種乘色的動作,通常都會降低整個顏色的亮度,所以應該還要有個亮度筆刷,其實這種亮度應該要說是最後顏色的強度,也就是在跟Diffuse做相乘時,還會再乘個數值,讓最後的顏色結果整個再提亮。公式如下:
strength * Brightness + (1 - strength) * last time Brightness  = Final Brightness
FinalVertex color * Diffuse *  Final Brightness = Final Diffuse
這邊從公式就看的出來,如果要提亮的話,Brightness一定要是要大於1的,當然小於1的話還是可以把它刷的更暗。
(如果改成FinalVertex color * Diffuse + Final Brightness這樣的話,看起來會有點像是粉筆筆刷的感覺,兩者就差在粉筆筆刷亮度提高後會容易看不到最後Diffuse的顏色)


這邊要注意的是資料儲存的問題,可以看到Color data in shader這篇。因為通常我們使用地表筆刷刷地表的話,一定會有內外圈,內圈和外圈中間通常是做smooth的動作,所以如果我們使用Unsigned integer來儲存資料的話,那經過smooth(如何做Smooth的動作可看到
Circle shape radial blur這篇)的話,一定會卡掉一些資料,那整個刷出來的感覺就會變成一圈一圈的,不會是一個模糊的放射狀。所以最後儲存的結果就要看到底是要存成一個image還是一個自訂binary格式。如果是image,因為最後一定是存成unsigned integer,一定還是有數值誤差的問題。那如果存成自訂binary格式的缺點就是不能編輯,彈性不夠高。




2012年12月29日 星期六

Color data in shader

一般送進shader的color stream,如果要省顯示卡記憶體空間的話,可以考慮使用unsigned integer的方式送進去。通常空間會有三倍的差距。

目前不知道format在DirectX會叫什麼,但是Gamebryo的話,在使用color stream時element format就叫F_NORMUINT8_4,並且在Gamebryo的預設Material class內會有個SetupPackingRequirements這個function,專門用來設定套用這個Material的Mesh有哪些stream可以送到shader內(這樣的好處是不管Mesh有哪些資料,只要套用到自訂的Material就可以決定說我們只要用Mesh的哪些資料,這樣就不用全部送到shader內浪費顯卡記憶體空間),記得在這邊設定Shader declaration的話要使用SPTYPE_UBYTECOLOR。

然後在shader裡面的color register宣告還是可以宣告成float4,shader會自動幫忙正規化到0~1之間。

這邊要注意使用unsigned integer的動作,可能會有數值誤差的問題。如果color資料需要事先在CPU內計算,並且儲存的格式是unsigned integer,而且color資料會在CPU內先用一些浮點數運算,因為要轉成unsigned int而去掉小數點的數值,然後最後送到GPU內,並且在GPU內又要使用color做運算。注意這邊在GPU的時候拿到的數值,就是已經被去掉部分小數,又轉成float的數值了,這樣的值一定會比整個過程都用float資料來做運算處理的值來的有差距,所以最後出來的畫面一定有落差。

2012年12月1日 星期六

C# with Unmanaged c++ debug setting

如果起始專案是C#的話,而用到其他的專案有些是Unmanaged c++的DLL,預設如果想下中斷點在這些Unmanaged c++的專案,是無法使用的。得在起始專案的屬性內設定->Debug頁面->Enabled Unmanaged C++ debugging。