2014年11月12日 星期三

QNX graphic path on vmware

整理筆記一下....
QNX® Software Development Platform 6.6 Graphics Patch [Patch ID 3875]

download下來後在pc上
參考
在command line執行下面bat設定環境變數
base_directory\qnx660-env.bat
再apply patch
applypatch -F download_path/patch-660-3875-660-Graphics-GA.tar

vmware上設置

1‧設定環境變數
  export GRAPHICS_ROOT=/usr/lib/graphics/vmware/
  export LD_LIBRARY_PATH=/usr/lib:/lib:/lib/dll:$GRAPHICS_ROOT:$LD_LIBRARY_PATH

2.copy patch的file到vmware。
  我先mount到pc下的share,並把相關的patch檔copy過去。

cp -f etc/system/config/scaling.conf /etc/system/config/scaling.conf
cp -f usr/share/gles/textures/brick_wall.tga /usr/share/gles/textures/brick_wall.tga
cp -f usr/share/gles/textures/bubble.png /usr/share/gles/textures/bubble.png
cp -f usr/share/images/wallpaper.jpg /usr/share/images/wallpaper.jpg
cp -f x86/bin/screeninfo /bin/screeninfo
cp -f x86/lib/dll/libwfdcfg-sample.so /lib/dll/libwfdcfg-sample.so
cp -f x86/lib/dll/screen-gles1.so /lib/dll/screen-gles1.so
cp -f x86/lib/dll/screen-gles2blt.so /lib/dll/screen-gles2blt.so
cp -f x86/lib/dll/screen-gles2.so /lib/dll/screen-gles2.so
cp -f x86/lib/dll/screen-sw.so /lib/dll/screen-sw.so
cp -f x86/lib/libgestures.so.1 /lib/libgestures.so.1
cp -f x86/lib/libinputevents.so.1 /lib/libinputevents.so.1
cp -f x86/lib/libkalman.so.1 /lib/libkalman.so.1
cp -f x86/lib/libmtouch-calib.so.1 /lib/libmtouch-calib.so.1
cp -f x86/lib/libmtouch-devi.so.1 /lib/libmtouch-devi.so.1
cp -f x86/lib/libmtouch-fake.so.1 /lib/libmtouch-fake.so.1
cp -f x86/lib/libmtouch-inject.so.1 /lib/libmtouch-inject.so.1
cp -f x86/sbin/gpu_drv /sbin/gpu_drv
cp -f x86/sbin/screen /sbin/screen
cp -f x86/usr/bin/calib-touch /usr/bin/calib-touch
cp -f x86/usr/bin/display_image /usr/bin/display_image
cp -f x86/usr/bin/egl-configs /usr/bin/egl-configs
cp -f x86/usr/bin/events /usr/bin/events
cp -f x86/usr/bin/font-freetype /usr/bin/font-freetype
cp -f x86/usr/bin/gles1-gears /usr/bin/gles1-gears
cp -f x86/usr/bin/gles2-gears /usr/bin/gles2-gears
cp -f x86/usr/bin/gles2-maze /usr/bin/gles2-maze
cp -f x86/usr/bin/gpudbg /usr/bin/gpudbg
cp -f x86/usr/bin/print-gestures /usr/bin/print-gestures
cp -f x86/usr/bin/screenshot /usr/bin/screenshot
cp -f x86/usr/bin/sw-vsync /usr/bin/sw-vsync
cp -f x86/usr/bin/vkey /usr/bin/vkey
cp -f x86/usr/bin/yuv-test /usr/bin/yuv-test
cp -f x86/usr/lib/graphics/vmware/graphics.conf /usr/lib/graphics/vmware/graphics.conf
cp -f x86/usr/lib/graphics/vmware/libAtcDecompressor.so /usr/lib/graphics/vmware/libAtcDecompressor.so
cp -f x86/usr/lib/graphics/vmware/libAtcDecompressor.so.1 /usr/lib/graphics/vmware/libAtcDecompressor.so.1
cp -f x86/usr/lib/graphics/vmware/libegl_gallium.so /usr/lib/graphics/vmware/libegl_gallium.so
cp -f x86/usr/lib/graphics/vmware/libHwEGL.so /usr/lib/graphics/vmware/libHwEGL.so
cp -f x86/usr/lib/graphics/vmware/libHwglapi.so /usr/lib/graphics/vmware/libHwglapi.so
cp -f x86/usr/lib/graphics/vmware/libHwGLESv1_CM_g.so /usr/lib/graphics/vmware/libHwGLESv1_CM_g.so
cp -f x86/usr/lib/graphics/vmware/libHwGLESv1_CM.so /usr/lib/graphics/vmware/libHwGLESv1_CM.so
cp -f x86/usr/lib/graphics/vmware/libHwGLESv2.so /usr/lib/graphics/vmware/libHwGLESv2.so
cp -f x86/usr/lib/graphics/vmware/libHwGPU.so /usr/lib/graphics/vmware/libHwGPU.so
cp -f x86/usr/lib/graphics/vmware/libHwWFDvmware.so /usr/lib/graphics/vmware/libHwWFDvmware.so
cp -f x86/usr/lib/graphics/vmware/libllvmpipe_drv.so /usr/lib/graphics/vmware/libllvmpipe_drv.so
cp -f x86/usr/lib/graphics/vmware/libmesa_texcompress_atc.so /usr/lib/graphics/vmware/libmesa_texcompress_atc.so
cp -f x86/usr/lib/graphics/vmware/libmesa_texcompress_pvrt.so /usr/lib/graphics/vmware/libmesa_texcompress_pvrt.so
cp -f x86/usr/lib/graphics/vmware/libmesa_texcompress.so /usr/lib/graphics/vmware/libmesa_texcompress.so
cp -f x86/usr/lib/graphics/vmware/libpipe_vmwgfx_drv.so /usr/lib/graphics/vmware/libpipe_vmwgfx_drv.so
cp -f x86/usr/lib/graphics/vmware/libst_HwGL_g.so /usr/lib/graphics/vmware/libst_HwGL_g.so
cp -f x86/usr/lib/graphics/vmware/libst_HwGL.so /usr/lib/graphics/vmware/libst_HwGL.so
cp -f x86/usr/lib/graphics/vmware/libvmwsvga.so /usr/lib/graphics/vmware/libvmwsvga.so
cp -f x86/usr/lib/libEGL.so.1 /usr/lib/libEGL.so.1
cp -f x86/usr/lib/libGLESv1_CL.so.1 /usr/lib/libGLESv1_CL.so.1
cp -f x86/usr/lib/libGLESv1_CM.so.1 /usr/lib/libGLESv1_CM.so.1
cp -f x86/usr/lib/libGLESv2.so.1 /usr/lib/libGLESv2.so.1
cp -f x86/usr/lib/libscreen.so.1 /usr/lib/libscreen.so.1
cp -f x86/usr/lib/libswblit.so.1 /usr/lib/libswblit.so.1
cp -f x86/usr/lib/libWFD.so.1 /usr/lib/libWFD.so.1
cp -f x86/lib/libgestures.so /lib/libgestures.so
cp -f x86/lib/libinputevents.so /lib/libinputevents.so
cp -f x86/lib/libkalman.so /lib/libkalman.so
cp -f x86/lib/libmtouch-calib.so /lib/libmtouch-calib.so
cp -f x86/lib/libmtouch-devi.so /lib/libmtouch-devi.so
cp -f x86/lib/libmtouch-fake.so /lib/libmtouch-fake.so
cp -f x86/lib/libmtouch-inject.so /lib/libmtouch-inject.so
cp -f x86/usr/lib/libEGL.so /usr/lib/libEGL.so
cp -f x86/usr/lib/libGLESv1_CL.so /usr/lib/libGLESv1_CL.so
cp -f x86/usr/lib/libGLESv1_CM.so /usr/lib/libGLESv1_CM.so
cp -f x86/usr/lib/libGLESv2.so /usr/lib/libGLESv2.so
cp -f x86/usr/lib/libscreen.so /usr/lib/libscreen.so
cp -f x86/usr/lib/libswblit.so /usr/lib/libswblit.so
cp -f x86/usr/lib/libWFD.so /usr/lib/libWFD.so
echo "Done!"

注意: 如果從window上編輯上面的成為.sh執行的話,記得要改換行字元,不然到QNX上時檔名結尾會多一個^M。在notepad ++ 的檔案格式轉換可改成unix就不會有這問題。

再執行
gpu_drv
screen
即可



2014年9月29日 星期一

Kanzi: Render Transparent Objects


在Kanzi裡畫半透明物件,比想像中麻煩一點,因為它不是你把物件用半透明材質,然後給個Transparent Queue就會幫你排序做好。

首先,必須在Composing > Pipeline 裡,加一個Property is Equal Filter。在Property Type選blendMode,Operation 選Include,Blend Mode選你的半透明物件所在的Mode。(這邊在弄時有發生怪事,Blend Mode怎麼設都不鳥我,preview視窗重開好幾次也沒用,後來不知怎突然可以用了...)

另一個要注意的點是,它是照物件上的Property排,所以你把BlendMode在Material裡設好,以為用了這個Material就會知道這個屬性。別傻了,它會當你是Opaque的物件....

接者同上步驟建一個畫Opaque的Filter。

然後在Composer建2個render pass 第一個畫Opaque物件。第二個畫半透明的Filter。(在Render Pass的Object Source選剛才的Filter)。把Color Buffer :Clear Enable > false, Depth Buffer: Clear Enable > False,Test Enable打開,Write Enable關掉。


發現怪事了嗎?

ZTest、ZWrite、甚至是Back , Front Culling不在Material上,而是在Render Pass上...WTF....Material要是複雜一點,不是要用一堆Render Pass..... 想到頭皮就發麻....

設完後,疑....排序怎是錯的....原來排序要自己再建一個Sorting Filter,Filter的Source選剛才的Transparent objects。同理,如果用到Tag Filter的話...我已經不敢想那個排列組合了.....

2014年9月24日 星期三

Kanzi StateMachine


在Editor中使用StateMachine 發現幾點要注意的地方

一開始想做一個循環的button,循環某一個State Manager

所以使用Toggle Button。

例如我有5個State,讓Toggle Button也有5個State對應。

首先先將Button中 加入一個Number of Toggle Button屬性,設成5

接著,新增Button: Toggle State 這個Trigger。之後,就對文件中的說明看不懂,試了很久才發現:

1.在Trigger Settings中,新增一個Condition,Property > Button Toggle State, Condition > =, Fixed Value > 0

2. Add一個Set property的Action,把State的值設成0。

3. 5個State的話,就要新增5個Button : Toggle State。

如果要有要使用State Manager: State Entered 這個Trigger的話,要加在Target物件(後面測試State Object跟Target都可以),而不是State Group,也不是Button上。同樣地也要在這個Trigger Setting中,設定Condition,不然只要State改變,都會進去。注意: Condition 中的Message Source要改成target物件。不能用預設值  後來發覺跟Message Source無關,是我的property名稱叫State,如果直接在下拉選單key入state 搜尋,會變成MessageArgument.StateManager.State ,但若在選單裡自己找,用選的,就會是我的state。應該是跟內建的名稱衝到,選到第一個是內建的名稱。

如果要用State Manager改變Target物件的屬性,記得要把Target上的對應屬性移掉。例如,在State Object上有Ambient Color這個屬性,要改變Sphere上的Ambient Color的話,要把Sphere上的Ambient Color 移掉。

這個設定成功後,才發現,原來Trigger 裡有一個State Manager: Go to Preview State 這個屬性。但一開始也試不出來,也沒文件。 後來試出,State Group 名稱設成要用的State Manager下的State Group,再把Dispatch Settings中的Routing Target,設成Target物件 (有State Manager那個)

這樣這個就可以做左右的循環State

後記:又出現問題了....用Go to Preview State的方式,沒辦法讓Target物件用它的State Property來判斷現在是在哪個State,前面的方式無法用。目前還找不到對應的值是什麼。後來用了一個蠢方法,在Property Type再增加一個叫State Name的property。在State Object上加入這個屬性,之後在Target物件上的Condition來判斷這個Name,就可以知道是在哪個State......不知正統的解法什麼

經過測試,在State Object上也可以用trigger知道State Enter,但State Left我搞不懂它的邏輯,在同一個State Object上,設Enter跟Left,在進入這個State時,會同時觸發。感覺是別人Left進這個State.....但又不知是誰的State進來呀 X的.... wtf

 用了一個蠢方式,設一個空Node 叫Pre State,上面有個像之前的StateName property。因為Left會發生在Enter之前,所以在Enter時,用Set Property 把空Node的StateName設定Current的名稱,因為left 進入時還沒更改,所以會抓到pre state,這樣就可以知道從哪State出來了..........應該有標準做法吧...但文件沒寫... x的

2014年9月23日 星期二

QNX專案設定

待補充....

剛建好專案,發覺無法Run。
原因是在Documentation中有一段講Communication with the QNX Neutrino RTOS

似乎在PC上debug也一定要有個平台才行

所以我用VMware跑一個評估版的QNX,ip在192.168.6.128

上面說裡面一定要跑一個qconn 的program, 評估版的本來就有

然後在專案裡,Perspective > QNX System Information
在Target Navigator view裡建一個New QNX Target
輸入剛才的ip,然後Finish

這樣IDE中的執行檔就可以Run

此外,如果發覺編完找不到Library,記得在Project Preference裡,加入Extra的library

(libscreen只要打screen就好,前面的lib不用打。)





2014年9月16日 星期二

從vmware的QNX連到 win7的shared folder

試了很久,google了半天,找不到為何連不過去

後來發現原因,原來是電腦名稱和別人衝到.....把名稱改了後就可以....囧 

在vm 裝評估版的QNX 在Windows開一個Shared folder

例如我的分享資料夾叫 Share, QNX的叫 mnt 然後打

 fs-cifs -l -vvvvvv //電腦名稱:電腦ip:/Share /mnt 

-l 是要輸入user name和password
-v 是debug訊息的多寡

 電腦名稱大小寫沒差
 username大小寫也沒差

2014年9月15日 星期一

Create Image form memory

最近在測試從網路上抓 Google map下來,但不知該怎把抓下來的圖轉成Kanzi可用的。

這個軟體目前資源很少呀,用的人不多,不像Unity3D,可以很簡單就做到。

跟網路的溝通我是用POCO這個library



 std::string url = URIinit();
 URI uri(url);
 std::string path(uri.getPathAndQuery());
 if (path.empty()) path = "/";

 HTTPClientSession session(uri.getHost(), uri.getPort());
 HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
 HTTPResponse response;
 session.sendRequest(request);
 std::istream &is = session.receiveResponse( response );


在Kanzi建立需要的資源:

 
 struct KzuResourceManager* resourceManager 
  = kzuUIDomainGetResourceManager(kzaApplicationGetUIDomain(application));

 struct KzcMemoryManager* memoryManager = kzcMemoryGetManager(resourceManager);
 struct KzcImage* image;
 struct KzuImageTexture* texture;

把拿到的stream轉成 char* buffer再轉成Kanzi 的stream格式。

 std::ostringstream oss( std::ios_base::binary);
 oss << is.rdbuf();
 std::string strConst = oss.str();
 int size = strConst.length();
 
 const char* buffer = strConst.c_str();
 

 kzsException error;
 struct KzcInputStream* outstrem;
 error = kzcInputStreamCreateFromMemory(memoryManager, (kzByte*)buffer, size,  KZC_IO_STREAM_ENDIANNESS_UNSPECIFIED, &outstrem);


再用Kanzi的load png的Api: kzcImageLoadPNG,因為我已經知道抓下來是png的格式,若是其它的,要用其它的函式。之前本來想直接用kzuImageTextureCreateFromMemory,這個函式,但發現抓下來的是png,在設定 KZU_TEXTURE_CHANNELS時會有問題,因為png用的是索引色,不是用R8G8B8這種格式,還要把抓下來的raw data做轉換。
 error = kzcImageLoadPNG(memoryManager, outstrem, false, &image);
 /* Create texture from image. */
 result = kzuImageTextureCreateFromImage(resourceManager, "Widget Texture", 
  image, KZU_TEXTURE_FILTER_BILINEAR, 
  KZU_TEXTURE_WRAP_REPEAT, 0.0f, 
  &texture);
 kzsErrorForward(result);
 struct KzuObjectNode* screenNode 
  = kzuScreenToObjectNode(kzaApplicationGetScreen(application));
 
 struct KzuObjectNode* plane = kzuObjectNodeGetRelative(screenNode, "#Plane");
 result = kzuObjectNodeSetResourceIDResourceProperty(plane, KZU_PROPERTY_TYPE_TEXTURE,  kzuImageTextureToResource(texture));
 kzsErrorForward(result);


如果是直接從file中讀取,也可以用這個方式。之前拿來debug用的。把從網路上抓下來的部分改成下面這段就可以
 std::fstream myfile("myfile.png", std::ios::in | std::ios::binary);
 std::filebuf* pbuf = myfile.rdbuf();
 std::size_t size = pbuf->pubseekoff (0,myfile.end,myfile.in);
 pbuf->pubseekpos (0,myfile.in);
 char* buffer=new char[size];
 // get file data
 pbuf->sgetn (buffer,size);
 myfile.close();


Kanzi C++ project

除了在設定中的:
C/C++
 -Advanced: Compiled as -> 改成 Compiled as C++ Code 外

也要把
-Code Generation: Enable C++ Exceptions 設成 /EHsc

參照:http://msdn.microsoft.com/zh-tw/library/1deeycx5.aspx

如果沒改,在編一些第三方函式庫會編不過...




2014年9月4日 星期四

建立Custom Component

1. 建立自已的KzuUiComponentNodeClass

2. 在configuration->onStartup = startup; 時註冊Factory

3. 為了2. 所以要建2個function:
       a. FactoryCreate //用來create component
       b. RegisterToFactory //用來註冊, 如果有要註冊Custom message也可以寫在這
   這會對應到在Editor中,建立的Custom Component name

4. 如果有要處理Message, Handler加在KzuUiComponentNodeClass的initialize function中。

 要在editor preview的話,編GL_21_release版的,ps:要把Editor關掉才能把dll蓋掉。

註冊custom message


 const struct KzuMessageType* MESSAGE_TEXTUREFONT_CHANGRD;
 {
  struct KzcMemoryManager* memoryManager = kzcMemoryGetManager(factory);
  struct KzuMessageType* messageType;
                
  //Message.Custom.FontChange 對應Editor裡的Custom Message Name
  result = kzuMessageRegistryAddMessageType(memoryManager, "Message.Custom.FontChange", KZU_MESSAGE_ROUTING_TUNNELLING_BUBBLING,        &messageType);
  kzsErrorForward(result);

  MESSAGE_TEXTUREFONT_CHANGRD = messageType;
 }

取得/設定 custom property

 {
    struct KzuPropertyType* UV_SET; 
    struct KzcVector4 uvs;

    //get property type
    UV_SET = kzuPropertyRegistryFindPropertyType("uv_modify");
    kzsAssert(kzcIsValidPointer(UV_SET));

    //get property
    uvs = kzuObjectNodeGetVector4PropertyDefault(textrue_font->planeNode, UV_SET);
    uvs.data[0] = (kzFloat)(uv_sets[index].x);
    uvs.data[1] = (kzFloat)(uv_sets[index].y);
    uvs.data[2] = (kzFloat)(uv_sets[index].z);
    uvs.data[3] = (kzFloat)(uv_sets[index].w);

    //set property
    result = kzuObjectNodeSetVector4Property(textrue_font->planeNode, UV_SET, uvs);
    kzsErrorForward(result);
}
在scene node底下的mesh的material,可以從node就直接get property來set,不用去get它的material

2014年8月15日 星期五

linux筆記

ldap.arcade.igs.com.tw

rm -rf 刪資料夾
新系統剛開始用時
vi /etc/ssh/sshd_config

PermitRootLogin yes
PermitEmptyPasswords yes

/etc/init.d/sshd restart


/etc/init.d/ntpd stop          //停止與其它人同步
ntpdate 10.1.1.254             //與server同步

svn co http://rd601/svn/pt/trunk trunk
svn update //要在code2端
chmod -R 777../
Xorg&
xterm&   //& 在背景執行

//ssh root@10.3.10.245 -p 412
ssh test@10.1.0.75 -p 412
ssh test@10.3.10.245 -p 22
password : linnet
su  //取得root
mount -t cifs -o username=brianchang,noserverino //10.1.254.52/brianchang /mnt

mount /dev/sdb1 /mnt

find ./ -name .svn -exec rm -rf '{}' \;
find . -type d -name ".svn"|xargs rm -rf

\\10.1.254.52 --> new code2 position

改開機default選項

mongo 筆記

http://docs.mongodb.org/manual/reference/operator/update/rename/
rename:

{
"occupation":"Doctor",
"name": {
   "first":"Jimmy",
   "additional":"Smith"
}

db.foo.update({}, {$rename:{"name.additional":"name.last"}}, false, true);
remap = function (x) {
  if (x.additional){
    db.foo.update({_id:x._id}, {$set:{"name.last":x.name.additional}, $unset:{"name.additional":1}});
  }
}

db.foo.find().forEach(remap);

db.students.update( { _id: 1 }, { $rename: { "nmae": "name" } } )
#rename all field
db.user.update({}, {$rename: {"session.play_data.Attack":"session.play_data.Power"}}, false, true)
#add all field
db.user.update({}, set{"session.play_data.Denfense":0}}, true, true)
[remove]
db.expTable.remove({'_id':ObjectId("52b29b8f5d89c90330cc23ad")})

#remove all documents in collection
db.expTable.remove()
#remove collections
db.expTable.drop()

[backup]
在command line下
mongodump --host 192.168.132.62 --port 27017 --out /backup/mongo-2013-01-17
#會存在 C:/backup/mongo-2013-01-17/
================[pymongo]================
from bson.objectid import ObjectId
#mike is a cursour
mike = testDB['posts'].find({'_id':ObjectId('52b144545d87c91b605dfca9')})

#modify a item
item = testDB['posts'].find({'_id':ObjectId('52b144545d87c91b605dfca9')})
item = item[0]
item['text'] = "haha"
testDB['posts'].save(item)

or

item = testDB['posts'].find_one({'_id':ObjectId('52b144545d87c91b605dfca9')})
testDB['posts'].update({'_id':ObjectId('52b144545d87c91b605dfca9')}, {"$set":{"text":"UCCU"}})

git 筆記

workdirectory --> Stage/Index --> repository --> Server
              add            commit          push

在專案底下使用 git init 開始一個新的 Git repo.

新增遠端儲存庫
git remote add [shortname] [url]
git remote add origin git@bitbucket.org:username/c-practice.git
欲從遠端擷取資料
$ git fetch [remote-name]

$ git push origin master 想要上傳 master 分支到 origin 伺服器

.gitignore
空白列或者以#開頭的列會被忽略
# 不要追蹤檔名為 .a 結尾的檔案
*.a
# 但是要追蹤 lib.a,即使上方已指定忽略所有的 .a 檔案
!lib.a
# 只忽略根目錄下的 TODO 檔案。 不包含子目錄下的 TODO
/TODO
# 忽略build/目錄下所有檔案
build/
# 忽略doc/notes.txt但不包含doc/server/arch.txt
doc/*.txt
# ignore all .txt files in the doc/ directory
doc/**/*.txt
#從repo中移掉某檔但不刪除
git rm --cached mylogfile.log
#add modify files, ingore untracked
git add -u (--update)
#add all files
git add -A
git commit -am  (add modify/delete file. not include untracked file)
同等於
git add -u, git commit -m

#checkout -> 移動Head的位置 到某個branch -b:若沒這個branch就建一個
git checkout -b Brian
#把 那個file revert
git checkout -- Assets/Artworks/Textures/girl.png.meta
同等於
git branch Brian
git checkout Brian
#把stage中某個file移掉
git reset filename

看某個file比較
git diff

2014年7月7日 星期一

GGX BRDF

最近很流行 也來試作一下
float G_Smith(float roughness, float NoV, float NoL)
   {
    //Schlich model
    //G(l,v,h) = G1(l)G1(v)
     float  k = (roughness + 1) * (roughness + 1) /8;
    return  (NoV / (NoV * (1 - k) + k)) *  (NoL / (NoL * (1 - k) + k));
   }
   
   fixed4 GGX_BRDF(float roughness, half3 lightDir, half3 viewDir, float3 Normal, fixed3 specularColor, fixed3 diffuseColor, fixed3 lightColor)
   {
      float pi = 3.14159;
      viewDir = normalize(viewDir);
      lightDir = normalize(lightDir);
      half3 h = normalize (lightDir + viewDir);
      float NdotL = max(0, dot ( Normal, lightDir));
      float NdotH = max (0, dot (Normal, h));
      float NdotV = max(0, dot(Normal, viewDir));
      float LdotH = max(0, dot(lightDir, h));
      float VdotH = max(0 , dot(viewDir, h));
      float3 Kd = 0;
          lightColor.rgb *= NdotL;
          Kd = diffuseColor * _MainColor / pi;
          half4 c;
          c.rgb = Kd * lightColor;
          
          //GGX NDF          
          float alpha =  roughness *  roughness;
          float beta = ((NdotH * NdotH) * (alpha*alpha -1.0) + 1.0);
          float Specular_D =  alpha * alpha/ (pi * beta * beta);
          fixed3 f0 = specularColor;
          float G = G_Smith(roughness, NdotV, NdotL);          
          float Specular_G = G * VdotH / (NdotH , NdotV);
          fixed3 Fschlick =  f0 + (fixed3(1,1,1) - f0)* pow(1 - LdotH, 5);
          c.rgb += Specular_D*Specular_G*Fschlick * lightColor.rgb;
          c.a = 1;
          return c;
   }

2014年7月1日 星期二

Get Selected AssetPath


常常寫EditorWindow但又常常忘了怎寫
把寫好的放上來,以後要改比較方便

順便提供一些小工具

當專案比較大時,資料夾結構很深,有時常需要知道asset的path。所以寫了一個小工具可以看Asset的path


using UnityEngine;
using System.Collections;
using UnityEditor;

public class GetSelectedAssetPath : EditorWindow {

 [MenuItem ("Window/GetSelectedAssetPath")]
 static void Init () {
  // Get existing open window or if none, make a new one:
  GetSelectedAssetPath window = (GetSelectedAssetPath)EditorWindow.GetWindow (typeof (GetSelectedAssetPath));
 }
 void OnGUI () {
  if (GUILayout.Button("Select", GUILayout.Width(60)))
  {
   Debug.Log(AssetDatabase.GetAssetPath(Selection.activeObject));
  }
 }

}

2014年6月27日 星期五

2014 mobile 應注意

 GDC 2014 一篇 Unreal講下一代手機繪圖的文章

新的硬體效能大概
300+ GFLOPS
26GB Bandwidth

http://blog.imgtec.com/powervr/graphics-cores-trying-compare-apples-apples

Mobile GPU:
  Tile-Based: ImgTec, Qualcomm...
  Direct: Nvidia, Intel, Qualcomm..

*Qualcomm Adreno 可切換tile-based or direct‧。
    - Extension: GL_QCOM_binning_control

Tile-Based Mobile GPU
- 32x32 pixels (ImgTec) 300x300 (Qualcomm)

ImgTec G6430:
 1 GPU core
 4 USC (Unified Shading Cluster)
   -16 pipeline each
FP16: 2 SOP (Sum of Product) per clock
  - (a*b+c*d)
FP32: 2 MADD per clock
  -(a*b +c)
154 GFLOPS @ 400 MHz
  - 16 bit floating point

改善部分:
 -Support OpenGL ES 3.0
 -Scalar, not Vector 
 -No additional cost for dependent texture reads
   - Pixelshader math on texture coordinates
   - Texture coordinates can be in .zw (swizzle)
   - 上述的意思是在讀貼圖前,對uv做運算不再有額外的cost,swizzle也不會有。
 -Coherent dynamic flow control at full speed (not 1/4th speed)
   -如果 branch是所有pixel 都做  eg.不是透過mask來branch,就不像之前會被降速
-FP16 is the minimun precision ( no more lowp)
   -用lowp不會有額外效能,最低精度就是FP16


Scalar vs  Vector
glsl : vec3 V = A*B + C*D;
Executed on SGX 543 GPU   75% speed , w component is wasted
  vec4 V' = A*B;
  vec4 V = C*D + V';

Executed on G6430 GPU    full speed
 half V.x = A.x*B.x + C.x*D.x;
 half V.y = A.y*B.y + C.y*D.y;
 half V.z = A.z*B.z + C.z*D.z;

ImgTec tip
-Hidden Surface Removal (HSR)
  - For opaque only
  - Don't keep alpha-test enabled all the time
  - Don't keep "discard" keyword in shader source, even if it's not used (不要相信 compiler)
    alpha-test 和 用了discard都會破壞 HSR

-把相同State都group在一起。
-Sort on State, not distant

-Qualcomm 的rendering process
  會有2個vertex shader,其中一個在tile之前,會把face position save in RAM, 等全部triangle 都知道了再做tile。所有tile 結束再flush to RAM

-Qualcomm Snapdragon Rendering Tips
  -Traditional handling of overdraw (via depth test)
    –Cull as much as you can on CPU, to avoid both CPU and GPU cost
    –Sort on distance (front to back) to maximize early z-rejection
The Adreno SIMD is wide
   -效能問題主要是在temp register usage而不是instruction counts
   -Hard optimize in glsl, check in profiler
   -用ALU比Lookup Texture 快。
  - 避免dependent texture fetches

Expensive to switch Frame Buffer Object on Tile-based GPUs
  -避免太多RenderTarget 切換
  -因為driver會把rendertarget save 到ram裡再copy出來。這樣很慢。
  -要用就開新的。

Clear ALL FBO attachments after new frame/rendertarget
–Clear after eglSwapBuffers / glBindFramebuffer
–Avoids reloading FBO from RAM
–NOTE: Do NOT do unnecessary clears on non-tile-based GPUs (e.g. NVIDIA)
  沒有直接的指令告訴api不要copy。只能用hint的,就是clear buffer。

Discard unused attachments before new frame/rendertarget
–Discard before eglSwapBuffers / glBindFramebuffer
–Avoids saving unused FBO attachments to RAM
–glDiscardFramebufferEXT / glInvalidateFramebuffer

Programmable Blending
GL_EXT_shader_framebuffer_fetch (gl_LastFragData)
•Reads current pixel background “for free”
•Potential uses:
–Custom color blending
–Blend by background depth value (depth in alpha)
•E.g. Soft intersection against world geometry for particles
–Deferred shading without resolving GBuffer
•Stay on GPU and avoid expensive round-trip to RAM
最基本的應用是 soft particle。讀background的depth是free的只是一個register

Tips
•Think scalar! Avoid using unnecessary components
–Avoid: (vec4*float)*float (8 MUL)
–Use: vec4*(float*float) (5 MUL)
•Prefer 16-bit floating point operations (mediump)
•Leverage ALU to hide memory fetches
–E.g. ALU can be faster than using lookup-textures

More Tips
•Don’t switch back and forth between mediump/highp
–ImgTec: Requires shader instructions to convert each time
–Qualcomm: Many conversions are free
   精度轉換有額外cost。先做高精度,再做低精度的轉換。
•Branch spatially coherent for many pixels
–Uses predication to ignore invalid path

Core Optimization: Opaque Draw Ordering
•All platforms,
–1. Group draws by material (shader) to reduce state changes
•Then for all platforms except ImgTec,
–2. Skybox last: 5 ms/frame savings (vs drawing skybox first)
–3. Sort groups nearest first : extra 3 ms/frame savings
–4. Sort inside groups nearest first : extra 7 ms/frame savings
排序是必做的!! 對效能影響非常大。

參考:
GDC2014 Next-gen Mobile Rendering

2014年6月19日 星期四

Deferred Rendering 下的特殊需求

這是針對Unity4的Deferred Rendering,因為5的做法會大改,而且也還沒發佈所以不確定。

最近有個特殊需求是,在做PostEffect時,希望能把一些東西排除掉,列如背景去飽和了,但人物想不被受影響。

但這個在Deferred rendering下會有問題,因為Unity的Deferred Rendering的PostEffect只能作用在最後一隻畫的Camera上,因此想了幾個方法。

1.畫人物時同時畫Stencil,PostEffect判斷Stencil,把人物排除。這個缺點是邊緣會有些鋸齒,Stencil應該沒AA。而且半透明物件就沒辦法。

2.人物在PostEffect之後用Forward畫,。缺點是,Camera深度沒共用,人不會被場景遮蔽。

3.人物用Shader tag,用一隻Camera RenderwithShader,輸出mask。但RenderWithShader同上,只能在Forward下使用,Mask也沒深度。而且另外做mask,drawcall也會增加。

4.把場景、特效、人物,用不用的RenderTexture輸出,最後在另一個PostEffect合併。這是個可行的方法,會增加一些Blit的drawcall,但是固定的。只是會用掉很多Vram。一張Full HD的rendertarget還滿大的。

上述方法好像都有缺點。

如果不同render path的Camera能Share Depth buffer就好了。

所以,如果拿Deferred Rendering的Camera深度,寫到Forward那隻Camera不就解決了?
於是2的Modify選項就出現了。

Camera結構如下:
MainCamera <-- Deferred Rendering
   -PlayerCamera  <-  Forward Rendering (clear flag -> don't clear)

在PlayerCamera掛上一個DepthWrite的Script
Cull Mask設定一下

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent(typeof(Camera))]
public class DetphWrite : MonoBehaviour {

 private Material DepthWriteMaterial = null;
 // Use this for initialization
 void Start () {
  DepthWriteMaterial = new Material(Shader.Find("Hidden/DepthWrite"));
 }
 

 void OnPreRender()
 {

  DrawQuad();
 }

 void DrawQuad()
 {
  GL.PushMatrix(); 
  GL.LoadOrtho();
  
  DepthWriteMaterial.SetPass(0);     
  
  //Render the full screen quad manually.  
  GL.Begin(GL.QUADS); 
  GL.TexCoord2(0.0f, 0.0f); GL.Vertex3(0.0f, 0.0f, 0.1f);  
  GL.TexCoord2(1.0f, 0.0f); GL.Vertex3(1.0f, 0.0f, 0.1f);  
  GL.TexCoord2(1.0f, 1.0f); GL.Vertex3(1.0f, 1.0f, 0.1f);  
  GL.TexCoord2(0.0f, 1.0f); GL.Vertex3(0.0f, 1.0f, 0.1f);  
  GL.End();
  
  GL.PopMatrix();
 }
}

Shader如下:
Shader "Hidden/DepthWrite" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "black" {}
    }
SubShader {
    Pass {
        ZTest Always Cull Off ZWrite On
      Fog { Mode off }
        
        CGPROGRAM        
            #pragma exclude_renderers gles flash
            #pragma vertex vert
            #pragma fragment frag
            #pragma target 4.0
             #include "UnityCG.cginc" 
            // vertex input: position, UV
            struct appdata {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
            };
           
            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };
           
            v2f vert (appdata v) {
                v2f o;
                o.pos = mul( UNITY_MATRIX_MVP, v.vertex );
                o.uv = v.texcoord.xy;
                return o;
            }
           

            
            sampler2D _MainTex;     
            sampler2D _CameraDepthTexture;
            
            
            struct fragOut
           {
               // half4 color : COLOR;   don't need
               float depth : DEPTH;
            };
          
            fragOut frag( v2f i ) {
           
                fragOut o;
               
                float depth =UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture,i.uv));
              
              // o.color= 0; // 
                o.depth= depth;
                return o;
           }
            
            

        ENDCG
        }
    }
}
本來以為_CameraDepthTexture要自己copy,但發現竟然Get到的是對的,值沒被Clear掉。如果Forward那支Camera,有下Clear flag Depth,就會被清掉。所以如果要自己畫Mask,前面3的方式,應該也可以傳進來自己判斷。

這個方法的缺點是用到Shader Model 4.0,要把Dx11的flag打開。
另外,在PlayerCamera畫的Soft Particle會失效(明明 _CameraDepthTexture抓得到),我把Particle Shader中#ifdef SOFTPARTICLES_ON 註解掉就可以。應該是Unity判斷Camera不同Render Path時,就 define off了。

如果要在d3d9下可以用,另一個想到的方法是在vertex shader讀入depth map,然後事前產生一個plane,它的點數和螢幕pixel一樣多,再寫入depth。可能對點的位置會有點麻煩,但理論上可行。

2014年6月18日 星期三

一堆Forward限定

Unity文件爛到有剩,一堆東西Forward限定的也不清楚

整理一下,日後再補充

1. Shader tag,所以Camera.RenderWithShader也沒用。
2. Camera.targetTexture:  想抓rendertarget 就用blit吧
3. Stencil Buffer

2014年3月28日 星期五

Unity ColorSpace

之前一直沒認真研究

如果是下Linear space 讀貼圖時會用 sRGB read (power(color, 2.2)) 寫出時會用 sRGB write(power(color,1/2.2))

如果是Gamma space 應該是不會對寫入和寫出做什麼
所以在Gamma space選項打開時,對貼圖設Bypass sRGB Sampling 打開和關掉都沒作用,因為預設就是Linear 的讀入

因此,在Linear space時,要注意如果貼圖是Normal map,要選Normal map,它會自動把Bypass sRGB Sampling開啟, 而自己做LUT貼圖時記得手動打開。以此類推~

2014年2月12日 星期三

Shokwave Shader

參考 http://forums.tigsource.com/index.php?topic=34921.msg928012#msg928012
Shader "Custom/Distort" {
 Properties {
  _MainTex ("Base (RGB)", 2D) = "white" {}
  //_strength("Strength", float) = 1.5
  _strength("Strength", Range(-1.1,1.1)) = 0
  _radius("Radius", float) = 5
  _width("Width", float) = 2.5
  _center("Center", Vector) =(0,0,0,0)
 }
 CGINCLUDE

  #include "UnityCG.cginc"
  
  sampler2D _MainTex;
  
  float _strength;
  float _radius;
  float _width;
  float4 _center;
  struct v2f {
   half4 pos : SV_POSITION;
   half4 uv : TEXCOORD0;
   half4 center : TEXCOORD1;
  };
  float2 offsetFnc(float2 _pos, float2 _center)
  {
   //length from the center of the rendered quad;
   float x = distance(_pos , _center);
   //calculate offset stength
   float val = cos((x-_radius)/(_width/3.1415)) * _strength/2 + _strength/2;
   if(abs(x-_radius)>_width)
      val = 0;
   return normalize(_pos- _center)*val;
   
  }
  v2f vert(appdata_full v) {
   v2f o;
   
   o.pos = mul (UNITY_MATRIX_MVP, v.vertex); 
   o.uv = ComputeScreenPos (o.pos);
   //_center = float4(_Object2World[3][0], _Object2World[3][1], _Object2World[3][2], 1);
   _center = float4(_Object2World[0][3], _Object2World[1][3], _Object2World[2][3], 1);
   o.center = ComputeScreenPos(mul(UNITY_MATRIX_VP, _center));
   //o.center = ComputeScreenPos(mul(UNITY_MATRIX_MVP, _center));
   
   return o; 
  }
  
  fixed4 frag( v2f i ) : COLOR { 
   i.uv.xy /= i.uv.w;
   i.center.xy /= i.center.w;
   fixed4 result = tex2D (_MainTex, i.uv.xy + offsetFnc(i.uv.xy, i.center.xy));
   result.a = 1;
   //result = float4(i.uv.x, i.uv.x, i.uv.x,1);
   return result;
  }    
 ENDCG
 
 SubShader {
  Tags { "RenderType" = "Transparent" "Queue" = "Transparent-2" }
  Cull Off
  Lighting Off
  ZWrite Off
  Fog { Mode Off }
  Blend SrcAlpha OneMinusSrcAlpha
  
 Pass {
 
  CGPROGRAM
  
  #pragma vertex vert
  #pragma fragment frag
  #pragma fragmentoption ARB_precision_hint_fastest 
  #pragma target 3.0
  
  ENDCG
   
  }
    
 } 

 FallBack "Diffuse"
}