More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Yelz的江湖PhotosProfileFriendsMore Tools Explore the Spaces community

Yelz的江湖

May 01

Implement Skinned animation (with vertex diffuse, specular and fog) by Vertex Shader

The demands:

1. Implement skinned animation with vertex shader

2. Implement vertex diffuse, specular and fog in the vertex shader.

During the period I am focusing on implementing the above features, I refered different materials, D3DX SDK help, Google, Gamedev.net...such like that. They are helpful, but none of them is really work!

D3DX SDK sample doesn't show the way to do specular and fog. It also failed to emphasize the points new HLSL programmers (like me) need to pay attention. Pages searched by google are too cursory and full with mistake. It tooks me much time to get everything work. Here is the piece of shader code. I am trying to add enough comments so that you can not only know "how" but also know "why".

////// Shader file for skin animation/////////////////////////////////////////////
// hufuzhipeng@hotmail.com

// Matrx used to do camera space transformations. it is worldMatrix * viewMatrix
//Actually, we need the transpose of the inverse of matWorldView to do normal transform. but becuase to transform
//nomal, only 3x3 part of the matrix will be used and the 3x3 part matWorldView is always orthogonal matrix, and
// transpose(inverse(othogonal matrix))) = othogonal matrix, so we can just input matWorldView.
// Attention: If the 3x3 part of your matWorldView is not othogonal, you must input the transpose of the inverse of
// matWorldView.
// Also read: http://www.gamedev.net/community/forums/topic.asp?topic_id=430330 to know why we need
// "transpose of the inverse "
float4x4 matWorldView;

// Lighting constant
float4 globalAmbient = {0.0f, 0.0f, 0.0f, 0.0f}; // Global ambient setting by D3DRS_AMBIENT//light direction in camera space, I use the .w part to store the power of specular
float4 lightDirection = {0.0f, 0.0f, 0.0f, 0.0f};
float4 combinedDiffuse = {0.0f, 0.0f, 0.0f, 0.0f}; // Combined Light & Material Diffuse
float4 combinedSpecular = {0.0f, 0.0f, 0.0f, 0.0f}; // Combined Light & Material Specular

// fogParameter.x > 0.0 means do fog blending, fogParameter.y = start - end, fogParameter.z = end,
float4 fogParameter = {0.0f, 0.0f, 0.0f, 0.0f};

// Matrix Pallette
static const int MAX_MATRICES = 50;  // Check the d3dcaps.MaxVertexShaderConst on your PC to decide the size

float4x3 mWorldMatrixArray[MAX_MATRICES]:WORLDMATRIXARRAY1;

float4x4 mGlobalWorldViewProjMatrix : COMBINEDMATRIX;

///////////////////////////////////////////////////////////
/// Vertex Shader for normal vertex
///////////////////////////////////////////////////////////
struct VS_INPUT
{
    float4 Pos        : POSITION;
    float4 BlendWeights    : BLENDWEIGHT;
    float4 BlendIndices    : BLENDINDICES;
    float3 Normal        : NORMAL;
    float3 Tex0        : TEXCOORD0;
};

struct VS_OUTPUT
{
    float4    Pos    : POSITION;
    float4  Diffuse : COLOR0;
    float4  Specular: COLOR1;
    float2  Tex0    : TEXCOORD0;
    float   fogWeight : FOG; // For vertex fog
};

VS_OUTPUT VShade(VS_INPUT i, uniform int NumBones)
{
    VS_OUTPUT o;
    float3 Pos = 0.0f;
    float3 Normal = 0.0f;
    float LastWeight = 0.0f;

    // Compensate for lack of UBYTE4 on Geforce3
    int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);

    // case the vectors to arrays for use in the for loop below
    float BlendWeightsArray[4] = (float[4])i.BlendWeights;
    int IndexArray[4] = (int[4])IndexVector;

    // caculate the pos/normal using the "normal" weights
    for (int iBone=0; iBone<NumBones-1; iBone++)
    {
        LastWeight = LastWeight + BlendWeightsArray[iBone];

       
        // Attention: i.Pos is a 4 flog vector with .w = 1.0f as a "Point"
        Pos += mul(i.Pos, mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];

        // For 3x3 part of mWorldMatrixArray[i], mWorldMatrixArray[i] = Transpose(Inverse(mWorldMatrixArray[i])),
        // So, we can use mWorldMatrixArray[i] to caculate normal transform
       //  You can also use just Inverse(mWorldMatrixArray[i]), because :
       //  dstVector = mul(srcVector, transpose(inverse(mat))) = mul(inverse(mat), srcVector)
        Normal += mul(i.Normal, (float3x3)mWorldMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];       
    }
    LastWeight = 1.0 - LastWeight;

    // Now that we have the calculated weight, add in the final influence
    Pos += (mul(i.Pos, mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight);
    Normal += (mul(i.Normal, (float3x3)mWorldMatrixArray[IndexArray[NumBones-1]]) * LastWeight);

    // transform position from world space into view and then projection space
    // Becuase Pos is a 3 float vector, we need to add .w part to make it be a "Point"
    o.Pos = mul(float4(Pos.xyz, 1.0f),  mGlobalWorldViewProjMatrix);   
   
     // Compute lighting
    // Also read: http://msdn.microsoft.com/en-us/library/bb172390(VS.85).aspx 
    //  There is a mistake in this article:  "Ldir = -norm(Ldir * wvMatrix)" should be "Ldir = -norm(Ldir * vMatrix)"
    // http://msdn.microsoft.com/en-us/library/bb219656(VS.85).aspx for diffuse
   //  http://msdn.microsoft.com/en-us/library/bb219656(VS.85).aspx for specular
   //  http://msdn.microsoft.com/en-us/library/bb219656(VS.85).aspx for fog
    float specularPower = lightDirection.w;
    lightDirection.w = 0;

    // Compiler don't know Pos is a position, so, we need to add .w item by hand
    float3 PosInCameraSapce = mul(float4(Pos, 1.0f), matWorldView);

    // For 3x3 part of matWorldView, matWorldView = Transpose(Inverse(matWorldView)),
    // So, we can use matWorldView to caculate normal transform
    float3 NormalInpCameraSpace = normalize(mul(Normal.xyz, (float3x3)matWorldView));

    float NLDot = max(0, dot(NormalInpCameraSpace, lightDirection.xyz));
   
    // ViewDir = EyePosInCameraSpace - -PosInCameraSapce, because EyePosInCameraSpace is always zero, so
    // we can just use "-PosInCameraSapce"
    float3 ViewDir = normalize(-PosInCameraSapce);
    float3 HalfWayVec = normalize(ViewDir + lightDirection);
    float4 specular = pow(saturate(dot(NormalInpCameraSpace, HalfWayVec)), specularPower); // R.V^n

    o.Diffuse = globalAmbient + combinedDiffuse * NLDot;
    o.Specular = combinedSpecular * specular;

    if (fogParameter.x > 0.0f)
    {
         o.fogWeight = clamp((fogParameter.z - abs(PosInCameraSapce.z)) / fogParameter.y, 0.0f, 1.0f);
    }

    // Copy the input texture coordinate through
    o.Tex0 = i.Tex0.xy;
    return o;
}

//////////////////////////////////////
// Techniques specs follow
//////////////////////////////////////
int CurNumBones = 2;
VertexShader vsArray[4] = { compile vs_2_0 VShade(1),
                            compile vs_2_0 VShade(2),
                            compile vs_2_0 VShade(3),
                            compile vs_2_0 VShade(4)
                          };
technique DrawObjectHLSL
{
    pass p0
    {
        VertexShader = (vsArray[CurNumBones]);
       }
}

///// C++ Part ////

D3DXMATRIXA16 combinedMat;
D3DXMatrixMultiply(&combinedMat, &m_WorldMatrix, &m_ViewMatrix);
m_pSkinEffect->SetMatrix("matWorldView", &combinedMat);   

// Set Lighting Parameters
DWORD dwGloablAmbient = 0;                       
pDevice->GetRenderState(D3DRS_AMBIENT, &dwGloablAmbient);
D3DXCOLOR globalAmbient(dwGloablAmbient);                       
m_pSkinEffect->SetVector("globalAmbient", (D3DXVECTOR4*)&globalAmbient);

D3DLIGHT9 light;
pDevice->GetLight(0, &light);

D3DXVECTOR4 lightDirection(light.Direction.x, light.Direction.y, light.Direction.z, 0.0f);
D3DXVec4Transform(&lightDirection, &lightDirection, &m_ViewMatrix);                       
D3DXVec4Normalize(&lightDirection, &lightDirection);
lightDirection = -lightDirection;

// Set light and use the .w to set the power for specular
lightDirection.w = m_Material.Power;

m_pSkinEffect->SetVector("lightDirection", &lightDirection);

D3DXCOLOR combinedDiffuse;                                       
D3DXCOLOR diff1(light.Diffuse);
D3DXCOLOR diff2(m_Material.Diffuse.c);
D3DXColorModulate(&combinedDiffuse, &diff1, &diff2);
m_pSkinEffect->SetVector("combinedDiffuse", (D3DXVECTOR4*)&combinedDiffuse);

D3DXCOLOR combinedSpecular;
D3DXCOLOR spec1(light.Specular);
D3DXCOLOR spec2(m_Material.Specular.c);
D3DXColorModulate(&combinedSpecular, &spec1, &spec2);
m_pSkinEffect->SetVector("combinedSpecular", (D3DXVECTOR4*)&combinedSpecular);

DWORD dwFlogFlag = 0;                   
pDevice->GetRenderState(D3DRS_FOGENABLE, &dwFlogFlag);
// Set Fog parameter to shader, we implement fog effect by ourselves
if (dwFlogFlag)
{   
    FLOAT fStart = 0, fEnd = 0;
    pDevice->GetRenderState(D3DRS_FOGSTART, (DWORD *)&fStart);
    pDevice->GetRenderState(D3DRS_FOGEND, (DWORD *)&fEnd);
    if (fEnd - fStart > 1e-6f)
    {
        D3DXVECTOR4 fogParameter(1.0f, fEnd-fStart, fEnd, 0.0f); // 1.0 means use fog blending
        m_pSkinEffect->SetVector("fogParameter", &fogParameter);                           
    }                   
}

D3DXMatrixMultiply(&combinedMat, &combinedMat, &m_ProjMatrix);               
hr = pDevice->SetVertexDeclaration(pAnimationData->m_pDecl);

DWORD dwDrawnFaceCount = 0;
for (uint32 uFaceGroup=0; uFaceGroup<m_dwFaceGroupCount;uFaceGroup++)
{
    D3DXBONECOMBINATION &faceGroup = m_pFaceGroupTable[uFaceGroup];
    for (uint32 uPalleteEntry=0; uPalleteEntry < m_paletteSize; uPalleteEntry++)
    {
        uint32 uMatrixIndex = faceGroup.BoneId[uPalleteEntry];
        if (uMatrixIndex != MAX_UINT32)
        {

            if (m_MatrixPalette[uPalleteEntry] != m_boneMatrix[uMatrixIndex])
            {
                m_MatrixPalette[uPalleteEntry] = pAnimationData->m_boneMatr[uMatrixIndex];   
            }       
        }
    }

    hr = m_pSkinEffect->SetMatrixArray("mWorldMatrixArray", m_MatrixPalette, pAnimationData->m_paletteSize);

    hr = m_pSkinEffect->SetMatrix("mGlobalWorldViewProjMatrix", &combinedMat);

    hr = m_pSkinEffect->SetInt("CurNumBones", pAnimationData->m_dwMaxVertInfl-1);

    UINT numPasses;
    m_pSkinEffect->Begin(&numPasses, D3DXFX_DONOTSAVESTATE);                       

    for (UINT iPass = 0; iPass < numPasses; iPass++)
    {                           
        m_pSkinEffect->BeginPass(iPass);                                                   

        pDevice->DrawIndexedPrimitive( ... );

        m_pSkinEffect->EndPass();
    }

    m_pSkinEffect->End();
    pDevice->SetVertexShader(NULL);
    pDevice->SetPixelShader(NULL);   

    dwDrawnFaceCount += faceGroup.FaceCount;
}

Becuase the matrix palette is usually too small for a whole model, we need to use ID3DXSkinInfo::ConvertToIndexedBlendedMesh to devide the whole model into sub-model to render seperatelly. I implemented the same function by myself, not very difficult. If you don't want to use .x format mesh, try to implement the function by yourself.

April 30

谈论 What's the matter with Tibet? – by i.elephant

Written by my friend bill. 

引用

What's the matter with Tibet? – by i.elephant

 

After seeing Mr. Smith' Free Tibet MSN name, after talking to buddies in Austin and read some articles in US, I begun to realized how critical it is for the so called main stream media in US is making anti-China propaganda with the recent Tibet thing, and how successful they are in making our US friends (they are all nice and honest people) to believe what they saw on TV and other type of media…

 

As a "this generation Chinese" and as a honest person speak about the truth, I think I need to compose this message and have as many as people read it, to know what exactly the Tibet thing is.

 

First of all, I'd like to quote an article which is published on China Daily today by By Lisa Carducci, a Canadian writer, sharing her experience talking to Tibetans (Zang) people in China and in Nepal and how surprised she was. http://www.chinadaily.com.cn/cndy/2008-04/22/content_6633878.htm

 

The paragraph I am going to quote from her article is "Finally, I realized that the Tibetans outside Tibet are the victims not only of ignorance but of a well-organized campaign of misinformation. And it struck me that it may be the same for the Dalai Lama." Honestly, it is the first time for me to understand what non-Chinese Tibetans think and believe. As Lisa mentioned in the article, too bad, the information they believe to be true is from "a well-organized campaign of misinformation". Then who is the organizer of this never-ending campaign of misinformation? There is only one on the planet could be the "god father" of this - Dalai Lama.

 

Why? You may wonder. Is it because that he was "forced to flee the country"? Right, partially. To make the judgment, you have to understand why he was fled and why he wants to turn things over so badly even fifty years has gone.

 

Let me quote another line from Lisa's article "I told her that all the Tibetans I had met earlier knew very well what the central government of China had done for them and appreciated it." Yeah, appreciate, that's the word. Ask yourself, when is the last time you truly appreciate something from the bottom of your heart? That's the time your heart was truly touched and that's about something that really matters to you. Okay, back to the question, why Dalai Lama was forced to flee and why Tibetans in China appreciate what the central government has done?

 

It is a long long story, and story always could be told differently. In Dalai Lama's wording, when he was forced to leave, the so called traditional Tibet culture was destroyed. But he never mentions what exactly the so called traditional Tibet culture was. That's how liars speak about things. Let me give you the word – serfdom. If you don't know exactly what it means, google it. , And of course, Dalai Lama was the king and that explains why he wants the old time back so badly. There are some sites you can go for reference about the serfdom age and the development of Tibet in the new China age.

       http://www.chinaembassy.org.il/eng/zt/xzwt/t159564.htm

       http://english.people.com.cn/features/tibetpaper/tibet.html

       http://www.tibet.cn/english/zt/whitebook/index.html

       http://www.dalai-liar.com/

 

Now you understand what's the real matter of Tibet, the history and the motive. Surprisingly, Dalai Lama has worked so desperately in making his propaganda, and this time he even made some of the main stream media buy in his value, and so come the news you saw on TV about the so called March Tibet riot in China.

 

Yes, there was a riot, bad people were organized to destroy the shops on street, etc., the standard riot things in a violent protest (and more than that this time, definitely), to make everything looks true to Dalai Lama's story. The police did their best to protect the residents. However, there were still victims. Please refer to the photos here: http://www.anti-cnn.com/forum/en/thread-649-1-1.html. It is touching, especially the photo at the bottom which is the five shop girls were torched ALIVE by rioters, oldest 24 (Yang Dongmei, right ), yongest 19 (Chen Jia, left). Totally there wer 13 residents were killed by the rioters. For more stories about "the five young women who burned to death", see here: http://www.iht.com/articles/2008/03/28/asia/tibet.php

 

But what the media in US reported? They refuse to acknowledge the victims of Lhasa riot, they five shop girls lost their lives to the rioters either hired by or motivated by the propaganda from Dalai Lama. Instead, they fabricated the stories that the Chinese police pressing peaceful protesters. Yes, fabricated! Surprise, ahha? Yeah, me too, but that's the truth. Actually, you will laugh about how stupid it is. Basically, what CNN did is just copied and pasted its own video tape of the Tibet Protest movement in India and has fabricated it as in Gansu Province/ Lhasa, China "peaceful" protest movement with Chinese cops in khaki British colonial style uniforms. That's really funny a low IQ. For details, check it out here: http://www.globalresearch.ca/index.php?context=va&aid=8697. And if you do a research, you will find other medias, including Washington Post, did same IQ level stupid "imaginary story telling" reporting.

 

The photo of the five victim girls is still vivid in my mind…for those reporters, don't you feel any level of SHAME??? I have no right wording to express my feeling now. The feeling is very complex. I like the democracy in US and the people there. 99.99%+ of the people there are nice an honest, but this time, the 0.01%- bad people manipulated good people's feeling and trust, and made them believe in the pressing of peaceful protest in Tibet story and made them believe the so called Free Tibet is meaningful thing. I felt so bad when I saw my best friend in US mentally joined the so called Free Tibet thing. That motivates me to write this message, to let more nice and honest US people know that it is the so called Free Tibet people torched five shop girls alive in Tibet, and the god father who won Nobel prize of peace was the biggest slave owner in the serfdom age…

 

Last and least question, why US media do so? I think you already have your idea. No matter it is "All western journalists need to sell news and stories. Their livelihood depends on the stories. Sometimes they have to exaggerate" (2008 Olympics, China, Tibet, by ciga), or they are also nice and honest people just stupidly believed what they thought to be true from Dalai Lama, or there is higher priority agenda such as national interest…who knows, who cares. What happened is what happened, let's face it, in an honest manner.

 

Looking forward, be honest like a real man, don't fabricate, don't ruin beautiful things, especially the Olympic, the thing supposed to be the purest, don't ever think about ruining it. Come one, don't tell me you haven't got the idea that the whole Tibet thing is part of the plot of ruining the Beijing Olympic. Anyway, you are adult, you have your judgment. Like them, they have their judgement:

    http://youtube.com/watch?v=Xsoc4-QnplY

    http://www.youtube.com/watch?v=siBqFgwL-lA


 

There is an old saying that for all the bad things you did, you will be punished, sooner or later. Let's just wait and see

 

 

 

======================================================================================

FBEE89F8668090F78397AFB6146564970318_343888

0318_34388604659a184967c08a780dc6e1acb922d2161dd76223bcb825a81d01a7ec1d97574b62621f2d0cdadf708e1d7d0b2e6cfecdb4e18df1eaf3409283e9970817c74a2ab8f14c3f0def80c3d09e62ccc1c8321b21fc2913d2b4b1708ca13a3cbd36319f98b498a99d59314cea06e48105090d8380

 

 

 

March 03

梅花,新天下贰

 

灵峰、孤山和西溪自古以来就是杭州赏梅的三大胜地。说起来,最为所人知的便是孤山,那个“梅妻鹤子”的林逋和那句“疏影横斜水清浅,暗香浮动月黄昏”虽时隔千年,尤让人心向往之。中国文人向来对梅花青睐有加,说到底是孤芳自赏的心里在作怪,“零落成泥碾做尘,只有香如故”,大概就是文人仕途失意,处江湖之远后的自我安慰。所以文士们赏梅,讲究的是意境:或是在清冷的冬晨,朔风凛冽,天地肃杀;或是在幽冷的晴夜,月色朦朦,文士们踩着厚厚的积雪在小道上踽踽独行,忽一抬头,正看见一朵怒放的梅花在枝头怒放,那便是有意境了。我们老百姓看梅花就没那么多讲究,踏雪寻梅固然别有乐趣,但与其顶风冒雪,还不如等到明媚的春日,去梅园看一看满树盛开的各色梅花:在花丛中拍几张照片,拈过花来嗅一嗅阵阵幽香,即便是和他人摩肩接踵,也是件开心的事。上周末就是这样的天气,所以一大早便去了植物园,一路径直来到灵峰,在梅花的海洋里徜徉了一番。

公司的3D大型网游天下贰再次内测了,从老天下贰回炉到今天重新内测,只有10个月时间,游戏内容,美术风格,收费模式,全都改了,且不说改得是否成功,效率的确够高。老天下贰我玩得不多,只到10多级,印象最深的就是从新手村出来,一不小心掉到山下小河里,游了半天才找到上岸的地方,灰头土脸跑回去,结果没过多久,再次掉到河里......。新天下贰里选了魍魉,也玩到10多级了,渐入佳境。就画面来说,比以前精致了不少,个人还是很喜欢;任务系统做得也不错,新手的上手难度明显降低。从程序上来说,bigworld引擎经过一年多的优化,无论是效率还是表现力,应该都有提高。之前在悉尼的时候到bigworld总部去访问过,其间谈到了地表渲染部分的优化,差不多就是progressive mesh的概念,看起来也很好的运用到新的游戏场景中了。

February 05

今天出来的两则道歉申明

 

陈冠希就艳照门道歉: http://ent.163.com/special/00032I5C/ps_stars.html 

这说明: 真的假不了

陕西林业厅就老虎门道歉: http://news.163.com/08/0205/00/43T82GN00001124J.html

这说明:假的也真不了

February 03

断桥,白堤,楼外楼,西泠印社,雪后

 

早上醒来,终于见到了久违的阳光。匆匆赶到断桥的时候,桥面上的雪已经快化完了。白堤上的雪已经凝结成冰,外西湖还是水光滢滢,岳湖上却结了一层薄冰。

顺着白堤,一路小心翼翼的走过来,感受了一下雪后的西湖。没带相机,只是用随身的手机拍了几张:

                  

 

 

 

 

 

 

 

                               断桥,外湖                                                                      宝石山,内湖

                                             白堤                                                                           湖上的冰

 

 

 

 

 

 

 

 

                                             楼外楼                                                               楼外楼前的雪人

 

                                              西泠印社

February 02

几张杭州雪景

前些天写blog, 还在说杭州的雪不容易积起来。这两天,老天爷就"Give me color see see" 了^_^

092259 20080202 092642 20080202  131036 20080202 092248 20080202

Microsoft’s Letter to Yahoo

http://dealbook.blogs.nytimes.com/2008/02/01/microsofts-letter-to-yahoo/

really a big news. Microsoft leaks this letter purposely in order to give pressure to Yahoo. From the perspective of shareholders and employees of Yahoo, it's really hard to refuse the offer.

If the acquisition transaction is successful, I just wonder how to combine to 2 bands: Yahoo and Live.

View more entries
 
Updated 2/3/2008
Updated 4/26/2007
Updated 12/8/2006
Updated 4/11/2006