青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

永遠也不完美的程序

不斷學習,不斷實踐,不斷的重構……

常用鏈接

統計

積分與排名

好友鏈接

最新評論

一起學習Shadow mapping

轉自:http://www.cnblogs.com/cxrs/archive/2009/10/17/1585038.html
1、什么是Shadow Maping?
      Shadow Mapping是由Lance Williams于1978年在一篇名為"Casting curved shadows on curved surfaces"的文章中提出的,這篇文章是ShadowMap技術之根源。其實原理很簡單,如果光源和目標點之間的連線沒有任何物體阻擋的話,則目標點沒有在陰影中;如果有物體遮擋,則目標點處在陰影中。而ShadowMap,就是一張記錄了每個象素處用于比較遮擋關系信息的Texture. 
      產生這個ShadowTexture的方法很簡單,以SpotLight為例,把3D Camera放到光源的位置,把DepthTest打開,渲染場景,在PixShader中把每個象素的深度信息或者光源和此象素的距離信息寫到RenderTarget上,由于DepthTest是打開的,保證了最終寫到RenderTarget上的均是物體上未處在陰影中的點的深度值,實質完全可以等效為最終的DepthBuffer。
     得到這個ShowMap之后,如何最終生成陰影呢?在PixShader對每個pixel進行處理時,算出當前象素與燈當的距離Dc,與存在ShdowMap中的引像素的值Dz進行比較,如果Dc > Dz,則在陰影中,反之則被燈光照亮。
2、Shadowmap之HLSL的實現
    在Direct SDk中有ShadowMap的Sample,下面的Shader和Sample里面空全一樣,只是加了一些注釋便于理解。
    (1)生成ShadowMap的VS和PS

//-----------------------------------------------------------------------------
// Vertex Shader: VertShadow
void VertShadow( float4 Pos : POSITION,
                 float3 Normal : NORMAL,
                 out float4 oPos : POSITION,
                 out float2 Depth : TEXCOORD0 )
{
    //從模型坐標系變換到觀察坐標系
    oPos = mul( Pos, g_mWorldView );
   //進行投影變換
   oPos = mul( oPos, g_mProj );
   //把投影坐標系的ZW值賦給Depth,作為PixelShader中的輸出,這里的Z還是齊次坐標,這里不直接輸出Z/W,我的理解是讓Z和W都在Rasterizer中進行線性插
  //值,這樣可以增加最終生成的ShadowMap的精度。
    Depth.xy = oPos.zw;
}
//-----------------------------------------------------------------------------
// Pixel Shader: PixShadow
void PixShadow( float2 Depth : TEXCOORD0,
                out float4 Color : COLOR )
{
    // 把 z / w的值作為Color值輸出,寫到RenderTarget上,此時的RT formate是D3DFMT_R32F
   //把Z/W目的是把齊次坐標Z變換到三維空間的非齊次坐標,范圍則是[-1,1]
    Color = Depth.x / Depth.y;
}

(2)用ShadowMap生成Shadow

//-----------------------------------------------------------------------------
// Vertex Shader: VertScene
// Desc: Process vertex for scene
//-----------------------------------------------------------------------------
void VertScene( float4 iPos : POSITION,
                float3 iNormal : NORMAL,
                float2 iTex : TEXCOORD0,
                out float4 oPos : POSITION,
                out float2 Tex : TEXCOORD0,
                out float4 vPos : TEXCOORD1,
                out float3 vNormal : TEXCOORD2,
                out float4 vPosLight : TEXCOORD3 )
{
    vPos = mul( iPos, g_mWorldView );
    oPos = mul( vPos, g_mProj );
    vNormal = mul( iNormal, (float3x3)g_mWorldView );
    Tex = iTex;
    //把當前頂點位置變換到以光源為Camera的投影空間,
    vPosLight = mul( vPos, g_mViewToLightProj );
}

 


//-----------------------------------------------------------------------------
// Pixel Shader: PixScene
// Desc: Process pixel (do per-pixel lighting) for enabled scene
//-----------------------------------------------------------------------------
float4 PixScene( float2 Tex : TEXCOORD0,
                 float4 vPos : TEXCOORD1,
                 float3 vNormal : TEXCOORD2,
                 float4 vPosLight : TEXCOORD3 ) : COLOR
{
    float4 Diffuse;

    // 計算光源到當前象素方向向量并單位化
    float3 vLight = normalize( float3( vPos - g_vLightPos ) );

    //  dot( vLight, g_vLightDir )為光源到當前象素方向向量和光的方向向量之間的夾角余旋值,由于是spotlight,因此必須要在spotlight可照射的范圍內。因為角
    //度越小余旋值越大,因此這里是大于
    if( dot( vLight, g_vLightDir ) > g_fCosTheta ) 
    {
        // Pixel is in lit area. Find out if it's
        // in shadow using 2x2 percentage closest filtering

        //從投影空間坐標轉化為紋理空間坐標,也就是找到投影空間中的點和紋理空間中的點的對應關系
       //除以w,xy坐標便處在(-1,1)的范圍內,乘0.5加0.5,則變換到了(0,1)的范圍,因texture space的u,v坐標是(0,1)的
        float2 ShadowTexC = 0.5 * vPosLight.xy / vPosLight.w + float2( 0.5, 0.5 );
       //在投影坐標系中,Y軸是向上的,而在紋理空間中Y軸向下,因此要作以下處理
        ShadowTexC.y = 1.0f - ShadowTexC.y;

        // 在texel space中對應的象素坐標
        float2 texelpos = SMAP_SIZE * ShadowTexC;
       
        // 取得小數部分         
        float2 lerps = frac( texelpos );

        //這里使用的是2x2 percentage closest filtering,因此是采的鄰近的四個點,判斷它們是否在陰影中,
        float sourcevals[4];
        sourcevals[0] = (tex2D( g_samShadow, ShadowTexC ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f; 
        sourcevals[1] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 0) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f; 
        sourcevals[2] = (tex2D( g_samShadow, ShadowTexC + float2(0, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f; 
        sourcevals[3] = (tex2D( g_samShadow, ShadowTexC + float2(1.0/SMAP_SIZE, 1.0/SMAP_SIZE) ) + SHADOW_EPSILON < vPosLight.z / vPosLight.w)? 0.0f: 1.0f; 
       
        // 用lerps 
        float LightAmount = lerp( lerp( sourcevals[0], sourcevals[1], lerps.x ),
                                  lerp( sourcevals[2], sourcevals[3], lerps.x ),
                                  lerps.y );
        // 計算光照,如果完全在陰影中,則LightAmount為0,這里只計算了Diffuse color,沒有高光
        Diffuse = ( saturate( dot( -vLight, normalize( vNormal ) ) ) * LightAmount * ( 1 - g_vLightAmbient ) + g_vLightAmbient )
                  * g_vMaterial;
    } else
    {
        Diffuse = g_vLightAmbient * g_vMaterial;
    }

    return tex2D( g_samScene, Tex ) * Diffuse;
}


3、ShdowMap的優缺點
    優點:簡單,不需要知道場景中Object的Geometry,不需要Stencil Buffer,每個燈光只需多渲染一個Pass。
    缺點:當ShadowMap分辨率不夠高時,或燈光與物體隔得很近時,在邊緣處會產生Aliasing,鋸齒,因此,很多改進shadowMap的算法都圍繞著如何消除鋸齒作文章。
4、ShadowMap的改進
    關于ShadowMap的改進,又出了很多的paper和技術,比如:Percentage Shadow map,  使用bloom filter對ShadowMap進行模糊處理.以及siggraph 2002 中Marc Stamminger和 George Drettakis提出的Perspective Shadow map.以及Adaptive Shadow Map等等。

posted on 2010-03-21 20:15 狂爛球 閱讀(2027) 評論(0)  編輯 收藏 引用 所屬分類: 圖形編程

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产一区视频| 亚洲大片在线| 亚洲午夜精品一区二区三区他趣 | 亚洲黄网站黄| 欧美国产第一页| 亚洲精品中文字幕在线| 亚洲大片在线| 欧美日韩精品免费观看视频完整| 亚洲三级电影在线观看| 欧美va天堂| 欧美精品99| 在线中文字幕不卡| 亚洲欧美国产另类| 国产欧美一区二区三区在线老狼| 欧美资源在线观看| 久久亚洲精品一区二区| 亚洲人成毛片在线播放女女| 亚洲激情欧美| 国产农村妇女毛片精品久久麻豆| 久久精品国产久精国产爱| 久久在线播放| 国产精品99久久99久久久二8| 一区二区三区**美女毛片| 国产精品一区二区久久精品 | 在线精品高清中文字幕| 亚洲国产老妈| 国产精品一二三| 欧美激情小视频| 国产精品私房写真福利视频| 欧美a级一区| 国产精品三级久久久久久电影| 久久综合九色综合欧美狠狠| 欧美日韩另类一区| 免费久久99精品国产自在现线 | 亚洲视频一区二区在线观看| 黄色成人免费观看| 亚洲视频免费| 亚洲精品一区二区三| 亚洲影院色无极综合| 亚洲卡通欧美制服中文| 欧美影院精品一区| 亚洲影院色无极综合| 嫩草国产精品入口| 久久久久一区二区| 国产精品久久一区主播| 亚洲精品一区二区三区婷婷月| 国产视频不卡| 亚洲尤物在线| 亚洲一区二区三区午夜| 免费久久99精品国产| 久久久久久久综合| 国产精品理论片在线观看| 亚洲国产另类久久久精品极度| 国产又爽又黄的激情精品视频 | 亚洲黄色一区二区三区| 久久亚洲精选| 久久黄色影院| 久久久久99| 欧美国产欧美亚洲国产日韩mv天天看完整 | 精品91在线| 性欧美xxxx视频在线观看| 夜夜精品视频| 欧美精品尤物在线| 亚洲国产日韩美| 亚洲第一视频| 久久影院午夜片一区| 狂野欧美激情性xxxx欧美| 国产麻豆精品视频| 午夜精品免费在线| 欧美怡红院视频| 国产亚洲精品aa| 性欧美激情精品| 久久九九免费| 亚洲大片精品永久免费| 久久久噜噜噜久噜久久| 免费h精品视频在线播放| 在线观看日韩专区| 欧美mv日韩mv国产网站app| 亚洲成人在线免费| 亚洲视频自拍偷拍| 亚洲欧美综合v| 国产亚洲精品bt天堂精选| 亚洲高清成人| 欧美在线三区| 久久久久国产精品一区| 欧美一区二区三区免费观看视频 | 亚洲免费av电影| 亚洲午夜一区二区| 国产嫩草一区二区三区在线观看| 欧美一区亚洲一区| 欧美成人免费在线观看| 日韩亚洲欧美高清| 欧美视频官网| 久久av二区| 亚洲精品久久久久久下一站| 欧美一级大片在线观看| 在线观看视频一区二区欧美日韩| 欧美黄色片免费观看| 在线亚洲成人| 免费看成人av| 亚洲欧美成人一区二区在线电影| 国产色产综合产在线视频| 久久久久久有精品国产| 亚洲三级免费电影| 欧美伊人影院| 亚洲日本黄色| 国产欧美精品一区二区色综合| 久久久国产精彩视频美女艺术照福利| 欧美激情一区二区三区全黄| 亚洲淫性视频| 亚洲福利av| 国产精品亚发布| 欧美电影在线免费观看网站| 午夜欧美电影在线观看| 亚洲人成高清| 美国三级日本三级久久99| 亚洲一区二区影院| 亚洲欧洲一区二区三区| 国产女主播一区| 欧美日韩国产小视频| 久久野战av| 亚洲欧美国产精品专区久久| 最近看过的日韩成人| 狂野欧美性猛交xxxx巴西| 亚洲欧美区自拍先锋| 亚洲理伦电影| 亚洲激情视频| 在线观看国产日韩| 国产一区二区三区电影在线观看 | 欧美成人资源网| 久久成人国产精品| 亚洲欧美在线一区| 亚洲少妇诱惑| 在线亚洲伦理| 在线亚洲观看| 夜夜夜精品看看| 亚洲精选中文字幕| 亚洲日本欧美| 久久婷婷国产麻豆91天堂| 午夜精品区一区二区三| 国产精品美女www爽爽爽| 一本色道88久久加勒比精品| 亚洲国产欧美一区二区三区丁香婷| 久久精品2019中文字幕| 亚洲欧美视频在线观看| 中文av字幕一区| 一区二区久久久久久| 一本一本久久a久久精品综合妖精| 亚洲高清网站| 亚洲日韩视频| 夜夜嗨av一区二区三区四季av| 亚洲美女色禁图| 一本综合精品| 亚洲欧美日韩一区二区在线 | 国产精品va在线| 欧美三级在线| 国产精品美女www爽爽爽| 国产精品一级二级三级| 国产亚洲欧美日韩在线一区 | 欧美一区二区视频在线观看| 亚洲午夜影视影院在线观看| 亚洲欧美日韩国产| 欧美在线视频观看免费网站| 久久日韩粉嫩一区二区三区| 蜜臀av国产精品久久久久| 欧美福利专区| 国产精品高潮粉嫩av| 国产精品手机视频| 在线观看成人小视频| 亚洲日本乱码在线观看| 亚洲一区中文| 蜜桃av噜噜一区| 91久久国产精品91久久性色| 亚洲视频一区| 美日韩精品免费| 国产精品国产三级国产专播品爱网 | 欧美va亚洲va日韩∨a综合色| 欧美日韩精品二区第二页| 亚洲国产成人在线| 蜜桃av一区二区| 欧美激情1区2区3区| 亚洲第一中文字幕在线观看| 久久永久免费| 亚洲精选91| 羞羞色国产精品| 欧美精品不卡| 国产视频一区二区三区在线观看| 亚洲黄色免费网站| 亚洲欧美日本另类| 欧美成人亚洲成人| 亚洲一区二区在线免费观看| 美日韩精品视频免费看| 欧美无乱码久久久免费午夜一区| 国产午夜精品全部视频在线播放| 99精品视频一区二区三区| 久久九九久精品国产免费直播| 亚洲精品1区| 久久综合中文| 国产色视频一区| 亚洲免费在线看|