• Introduction to my galaxy engine 3: Local light model


    在deferred shading中,对于局部光源,我们是需要建立一个它的光照范围的模型,然后再通过深度和模板检测来获取受光照影响的物体(类似shadow volumn中用到的方法)。以下是两个常用局部光源的模型:点光源模型的一个球体(也可以用cube或者square近似代替),spot light 是一个cone模型, 平行光模型可以用cube模型。需要注意的是所有模型都是封闭的。如果光源是动态产生的话,例如例子系统中粒子的光源,这些模型也可以在geometirc shader生成。

    以下是模型的截图:

    以下是程序代码:步骤主要分为两步(生成顶点位置,生成顶点的索引)

      1 void CGeomCreator::CreateSphere(float fRadius, size_t iRings, size_t iSegments, const D3DXVECTOR3& Pos)
      2 {
      3     //suppose the sphere is located at coord center
      4     m_iVertexNum = iRings * iSegments + 2;
      5     m_pModel = new ModelType[m_iVertexNum];
      6     size_t iCurVertex = 0;
      7 
      8     float fDeltaRing = PI / (iRings + 1);
      9     float fDeltaSegment = 2 * PI / iSegments;
     10 
     11     //top point
     12     m_pModel[iCurVertex].Pos = D3DXVECTOR3(Pos.x, Pos.y + fRadius, Pos.z);
     13     ++iCurVertex;
     14     //middle points
     15     for (size_t i = 0; i < iRings; ++i)
     16     {
     17         float y = Pos.y + fRadius * cos(fDeltaRing * (i + 1));
     18         float r = fRadius * sin(fDeltaRing * (i + 1));
     19 
     20         for (size_t j = 0; j < iSegments; ++j)
     21         {
     22             float x = Pos.x + r * cos(fDeltaSegment * j);
     23             float z = Pos.z + r * sin(fDeltaSegment * j);
     24 
     25             m_pModel[iCurVertex].Pos = D3DXVECTOR3(x, y, z);
     26             ++iCurVertex;
     27         }
     28     }
     29     //botom point
     30     m_pModel[iCurVertex].Pos = D3DXVECTOR3(Pos.x, Pos.y - fRadius, Pos.z);
     31 
     32     //generate index
     33     m_iIndexNum = iSegments * 3 * 2 + iSegments * 3 * 2 * (iRings - 1);//top + button + middle
     34     m_pIndces = new DWORD[m_iIndexNum];
     35 
     36     size_t iCurIndex = 0;
     37     for (size_t i = 0; i <= iRings; ++i)//<=
     38     {
     39         for (size_t j = 0; j < iSegments; ++j)
     40         {
     41             if(i ==0)//top
     42             {
     43                 m_pIndces[iCurIndex] = 0;    
     44                 ++iCurIndex;
     45                 if(j < iSegments - 1)
     46                     m_pIndces[iCurIndex] = 1 + (j + 1);
     47                 else
     48                     m_pIndces[iCurIndex] = 1;
     49                 ++iCurIndex;
     50                 m_pIndces[iCurIndex] =    1 + j;
     51                 ++iCurIndex;
     52             }
     53             else if(i == iRings)//bottom
     54             {
     55                 size_t iLastVertex = m_iVertexNum - 1;
     56                 size_t iStartVertex = 1 + (iRings - 1) * iSegments + j;
     57 
     58                 m_pIndces[iCurIndex] = iStartVertex;
     59                 ++iCurIndex;
     60                 if(j < iSegments - 1)
     61                     m_pIndces[iCurIndex] = iStartVertex + 1;
     62                 else
     63                     m_pIndces[iCurIndex] = 1 + (iRings - 1) * iSegments;//j back to 0
     64                 ++iCurIndex;
     65                 m_pIndces[iCurIndex] = iLastVertex;
     66                 ++iCurIndex;
     67             }
     68             else//middle of sphere
     69             {
     70                 size_t iStartVertex = 1 + (i - 1) * iSegments + j;
     71 
     72                 m_pIndces[iCurIndex] = iStartVertex;
     73                 ++iCurIndex;
     74                 if(j < iSegments - 1)
     75                     m_pIndces[iCurIndex] = iStartVertex + iSegments + 1;
     76                 else
     77                     m_pIndces[iCurIndex] = iStartVertex + 1;//iSegments back to 0
     78                 ++iCurIndex;
     79                 m_pIndces[iCurIndex] = iStartVertex + iSegments;
     80                 ++iCurIndex;
     81 
     82                 m_pIndces[iCurIndex] = iStartVertex;
     83                 ++iCurIndex;
     84                 if(j < iSegments - 1)
     85                     m_pIndces[iCurIndex] = iStartVertex + 1; 
     86                 else
     87                     m_pIndces[iCurIndex] = 1 + (i - 1) * iSegments;//j back to 0
     88                 ++iCurIndex;
     89                 if(j < iSegments - 1)
     90                     m_pIndces[iCurIndex] = iStartVertex + 1 + iSegments;
     91                 else
     92                     m_pIndces[iCurIndex] = iStartVertex + 1;//iSegments back to 0
     93                 ++iCurIndex;
     94             }
     95         }
     96     }
     97 }
     98 
     99 void CGeomCreator::CreateCone(float fRadius , float fHeight, size_t iSegments, const D3DXVECTOR3& Pos)
    100 {
    101     //suppose the bottom of the sphere is located at xz coord center
    102     m_iVertexNum = iSegments + 2;
    103     m_pModel = new ModelType[m_iVertexNum];
    104     size_t iCurVertex = 0;
    105     float fDeltaSegment = 2 * PI / iSegments;
    106 
    107     //top point
    108     m_pModel[iCurVertex].Pos = D3DXVECTOR3(Pos.x, Pos.y, Pos.z);
    109     ++iCurVertex;
    110     //middle points
    111     for (size_t i = 0; i < iSegments; ++i)
    112     {
    113         float x = cos(fDeltaSegment * i) * fRadius;
    114         float z = sin(fDeltaSegment * i) * fRadius;
    115         m_pModel[iCurVertex].Pos = D3DXVECTOR3(Pos.x + x, Pos.y - fHeight, Pos.z + z);
    116         ++iCurVertex;
    117     }
    118     //bottom point
    119     m_pModel[iCurVertex].Pos = D3DXVECTOR3(Pos.x, Pos.y - fHeight, Pos.z);
    120 
    121     m_iIndexNum = iSegments * 3 * 2;
    122     m_pIndces = new DWORD[m_iIndexNum];
    123     size_t iCurIndex = 0;
    124     //top
    125     for (size_t i = 0; i < iSegments; ++i)
    126     {
    127         m_pIndces[iCurIndex] = 0;
    128         ++iCurIndex;
    129         if(i < iSegments - 1)
    130             m_pIndces[iCurIndex] = 1 + i + 1;
    131         else
    132             m_pIndces[iCurIndex] = 1;
    133         ++iCurIndex;
    134         m_pIndces[iCurIndex] = 1 + i;
    135         ++iCurIndex;
    136     }
    137     //bottom
    138     for (size_t i = 0; i < iSegments; ++i)
    139     {
    140         m_pIndces[iCurIndex] = 1 + i;
    141         ++iCurIndex;
    142         if(i < iSegments - 1)
    143             m_pIndces[iCurIndex] = 1 + i + 1;
    144         else
    145             m_pIndces[iCurIndex] = 1;
    146         ++iCurIndex;
    147         m_pIndces[iCurIndex] = m_iVertexNum -1;
    148         ++iCurIndex;
    149     }
    150 }
  • 相关阅读:
    JAVA实现WEBSERVICE 上传下载
    C# 扩展方法
    C# winform窗体假死
    javascript webstorm用法
    设计模式 单例模式
    c# 浏览器区别
    C# 文件递归
    批处理
    Windows Services Windows Services的操作
    Oracle下载及安装
  • 原文地址:https://www.cnblogs.com/RobinG/p/2515959.html
Copyright © 2020-2023  润新知