实时阴影绘制技术研究

C++博客 首页 新随笔 联系 聚合 管理
  48 Posts :: 20 Stories :: 57 Comments :: 0 Trackbacks
英文原文:http://www.gamedev.net/reference/articles/article2193.asp

在我的前边文章中有这样一篇文章,是转载gameres的文章,一直也没有好好看看。昨天偶然间看到,仔细研究了一下,读了一下代码。

四遍的绘制过程如下:
  • pass 1:从光源看过去,绘制场景深度,写入最后的COLOR,这个COLOR最终被绘制到g_pShadowSurf这个RenderTarget,深度模板表面保存在g_pShadowDepth(这个暂时不知道怎么用)
  • Pass 2:
  1. 不计算光照,利用VS绘制从视点看过去的场景z值深度,输出一个POSITION和一个TEXTURE0,其中TEXTURE0保存了从光源到该点的深度(使用了纹理矩阵来处理从视点可见的点即可得到),此纹理输出给PS使用。
  2. 在PS中,为每一个纹理g_pShadowMap上的像素点,构造它周围的3*3的表示的纹理坐标数组,并遍历该数组取得纹理颜色值(也就是从光源看到的场景深度值),同从视点看到的点的对应深度值,逐一进行比较。使得周围8个点中看到光源的点越多,最后输出的Color的值就越大,最小为0.1,最大为1。
  3. 该pass的颜色输出到纹理g_pSceneSurf,深度模板表面保存在g_pNewDetphSurf中。
  • Pass 3:
  1. 利用高斯函数pass2中得到的shadow mask进行模糊,这一遍做水平模糊
  2. //
    // Gaussian functions(高斯函数)
    //
    float GetGaussianDistribution( float x, float y, float rho ) {
        float g = 1.0f / sqrt( 2.0f * 3.141592654f * rho * rho );
        return g * exp( -(x * x + y * y) / (2 * rho * rho) );
    }

    void GetGaussianOffsets( bool bHorizontal, D3DXVECTOR2 vViewportTexelSize,
                             D3DXVECTOR2* vSampleOffsets, float* fSampleWeights ) {
        // Get the center texel offset and weight
        fSampleWeights[0] = 1.0f * GetGaussianDistribution( 0, 0, 2.0f );
        vSampleOffsets[0] = D3DXVECTOR2( 0.0f, 0.0f );
       
        // Get the offsets and weights for the remaining taps
        if( bHorizontal ) {
            for( int i = 1; i < 15; i += 2 ) {
                vSampleOffsets[i + 0] = D3DXVECTOR2(  i * vViewportTexelSize.x, 0.0f );
                vSampleOffsets[i + 1] = D3DXVECTOR2( -i * vViewportTexelSize.x, 0.0f );

                fSampleWeights[i + 0] = 2.0f * GetGaussianDistribution( float(i + 0), 0.0f, 3.0f );
                fSampleWeights[i + 1] = 2.0f * GetGaussianDistribution( float(i + 1), 0.0f, 3.0f );
            }
        }

        else {
            for( int i = 1; i < 15; i += 2 ) {
                vSampleOffsets[i + 0] = D3DXVECTOR2( 0.0f,  i * vViewportTexelSize.y );
                vSampleOffsets[i + 1] = D3DXVECTOR2( 0.0f, -i * vViewportTexelSize.y );
               
                fSampleWeights[i + 0] = 2.0f * GetGaussianDistribution( 0.0f, float(i + 0), 3.0f );
                fSampleWeights[i + 1] = 2.0f * GetGaussianDistribution( 0.0f, float(i + 1), 3.0f );
            }
        }
    }
    具体的数学公式我没有查,大概看不懂,还望高手指点。
  • Pass4:这二遍做垂直模糊。
  • Pass 5:绘制场景,逐像素的计算光照,并将模糊后的shadow mask信息和聚光灯贴图应用到场景中。

posted on 2006-06-02 14:02 苦行僧 阅读(3413) 评论(1)  编辑 收藏 引用 所属分类: shadow

Feedback

# re: 基于shadow map的软阴影生成过程祥解 2006-12-05 16:46 wu_chung_tang
利用高斯函数pass2中得到的shadow mask进行模糊
you can do this in PS not in C++ code, can be fast  回复  更多评论
  


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理