惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
雷峰网
雷峰网
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
IT之家
IT之家
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
B
Blog RSS Feed
H
Help Net Security
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
L
LangChain Blog
Vercel News
Vercel News

博客园 - 胡说八道

NVIDIA GDC2006 presentation ATI GDC2006 Presentations GDC 2006 Microsoft Developer Day Presentations 天空的颜色和大气散射 - 胡说八道 - 博客园 引擎渲染截图 -地形 引擎渲染截图 Trapezoidal Shadow Map(2) Trapezoidal Shadow Map(1) Meltdown 2005 Presentations parallax mapping 一张截图 有层次感的草的渲染方法 Texture Space Ligthing with Shadow 海面LOD GeoMipMap和Efficient View Frustum Culling PRT直接光照和间接光照 FFT海面 辐射度 DiffuseCubeMap生成器 ver 0.01
Trapezoidal Shadow Map(3)
胡说八道 · 2005-08-04 · via 博客园 - 胡说八道


上面图中右上角为Shadow Map.

使用TSM做Self-Shadow时需要注意ShadowMap保存和第二步用于比较的Depth不要转换到trapezoidal space中,只转换x和y就行了.

计算trapezoidal和LPPS->trapezoidal space的代码修正后为:
 HRESULT CTrapezoidalShadowMap::ComputeTrapezoidalMatrix(D3DXMATRIX& matrix,D3DXVECTOR3& topl,D3DXVECTOR3& topr,D3DXVECTOR3& bottoml,D3DXVECTOR3& bottomr,D3DXVECTOR3& intersection)
{
 // 平移梯形使得两侧边交点到LightProjectSpace的中点
 D3DXMatrixTranslation(&matrix,-intersection.x,-intersection.y,0);
 
 // 旋转梯形使得TopLine和LightProjectSpace的x轴重合
 D3DXVECTOR3 t_topline=(topl-topr);
 D3DXVec3Normalize(&t_topline,&t_topline);

 float t_angle=D3DXVec3Dot(&t_topline,&D3DXVECTOR3(1,0,0));
 
 D3DXMATRIX t_matrix;
 
 if (t_topline.y>0)
  D3DXMatrixRotationZ(&t_matrix,-acosf(t_angle));
 else
  D3DXMatrixRotationZ(&t_matrix,+acosf(t_angle));

 matrix*=t_matrix;

 // 变换使得成为等边梯形
 D3DXVECTOR3 t_point1,t_point2;
 D3DXVec3TransformCoord(&t_point1,&topl,&matrix);
 D3DXVec3TransformCoord(&t_point2,&topr,&matrix);

 t_point1+=t_point2;

 D3DXMatrixIdentity(&t_matrix);
 t_matrix._21=-t_point1.x/t_point1.y;

 matrix*=t_matrix;

 // 变换使得两侧边成90度,TopLine的两点在[-1,1]和[1,1]上
 D3DXVec3TransformCoord(&t_point1,&topr,&matrix);

 D3DXMatrixScaling(&t_matrix,1.0f/t_point1.x,1.0f/t_point1.y,1.0f);

 matrix*=t_matrix;

 // 变换使得梯形变成矩形
 t_matrix._11=t_matrix._22=t_matrix._33=1.0f;
 t_matrix._12=t_matrix._13=t_matrix._14=t_matrix._21=t_matrix._23=0.0f;
 t_matrix._31=t_matrix._32=t_matrix._34=t_matrix._41=t_matrix._43=t_matrix._44=0.0f;

 t_matrix._42=1.0f;
 t_matrix._24=1.0f;

 matrix*=t_matrix;

 // 平移使得矩形的中心到LightProjectSpace的中点
 D3DXVec3TransformCoord(&t_point1,&topl,&matrix);
 D3DXVec3TransformCoord(&t_point2,&bottomr,&matrix);

 D3DXMatrixTranslation(&t_matrix,0,-(t_point1.y+t_point2.y)/2.0f,0);

 matrix*=t_matrix;

 // 拉伸矩形的Y方向,使得充满整个LightProjectSpace
 D3DXVECTOR4 t_point3;
 D3DXVec3Transform(&t_point3,&topl,&matrix);

 D3DXMatrixIdentity(&t_matrix);

 t_matrix._22=-t_point3.w/t_point3.y;

 matrix*=t_matrix;

 //
 return S_OK;
};

HRESULT CTrapezoidalShadowMap::ComplteLightPostPerspectiveTrapezoidal(SFrustum& frustum,D3DXMATRIX& lightviewproj,D3DXVECTOR3& topl,D3DXVECTOR3& topr,D3DXVECTOR3& bottoml,D3DXVECTOR3& bottomr,D3DXVECTOR3& intersection)
{
 D3DXVECTOR3 t_frustumvertex[9];
 
 D3DXVec3TransformCoordArray( t_frustumvertex, sizeof(D3DXVECTOR3), frustum.m_Vertexs, sizeof(D3DXVECTOR3), &lightviewproj, sizeof(t_frustumvertex)/sizeof(D3DXVECTOR3) );

 for (int i=0;i<9;++i)
 {
  t_frustumvertex[i].z=0.0f;
 }

 D3DXVECTOR3 t_topcenter  =0.25*(t_frustumvertex[0]+t_frustumvertex[1]+t_frustumvertex[2]+t_frustumvertex[3]);
 D3DXVECTOR3 t_bottomcenter =0.25*(t_frustumvertex[4]+t_frustumvertex[5]+t_frustumvertex[6]+t_frustumvertex[7]);

 D3DXVECTOR3 t_centerline = t_topcenter - t_bottomcenter;
 D3DXVec3Normalize(&t_centerline,&t_centerline);

 D3DXMATRIX t_trans;
 D3DXMatrixTranslation(&t_trans,-0.5f*(t_topcenter.x+t_bottomcenter.x),-0.5f*(t_topcenter.y+t_bottomcenter.y),0);

 D3DXMATRIX t_rotation;
 float t_angle=acosf(D3DXVec3Dot(&t_centerline,&D3DXVECTOR3(0,1,0)));

 if (t_centerline.x>0)
  D3DXMatrixRotationZ(&t_rotation,+t_angle);
 else
  D3DXMatrixRotationZ(&t_rotation,-t_angle);

 t_trans*=t_rotation;

 D3DXVec3TransformCoordArray( t_frustumvertex, sizeof(D3DXVECTOR3), t_frustumvertex, sizeof(D3DXVECTOR3), &t_trans, sizeof(t_frustumvertex)/sizeof(D3DXVECTOR3) );

 BoundingBox frustumAABB2D( t_frustumvertex, (sizeof(t_frustumvertex)/sizeof(D3DXVECTOR3)-1) );

 D3DXVECTOR3 t_topl,t_topr,t_bottoml,t_bottomr;

 D3DXVECTOR3 t_side[4];
 float t_value[4];

 for (int i=0;i<4;++i)
 {
  t_side[i]=t_frustumvertex[i]-t_frustumvertex[i+4];
  D3DXVec3Normalize(&t_side[i],&t_side[i]);
  t_value[i]=D3DXVec3Dot(&t_side[i],&D3DXVECTOR3(0,1,0));
 }

 float t_min=1.0f;
 int t_no;
 for (int i=0;i<4;++i)
 {
  if (t_side[i].x>0)
   continue;

  if (t_value[i]<t_min)
  {
   t_min=t_value[i];
   t_no=i;
  }
 }

 t_topr.y=frustumAABB2D.maxPt.y;
 t_topr.x=(t_frustumvertex[8].y-frustumAABB2D.maxPt.y)*tanf(acosf(t_value[t_no]));
 t_topr.z=0.0f;
 t_bottomr.y=frustumAABB2D.minPt.y;
 t_bottomr.x=(t_frustumvertex[8].y-frustumAABB2D.minPt.y)*tanf(acosf(t_value[t_no]));
 t_bottomr.z=0.0f;

 t_min=1.0f;
 for (int i=0;i<4;++i)
 {
  if (t_side[i].x<0)
   continue;

  if (t_value[i]<t_min)
  {
   t_min=t_value[i];
   t_no=i;
  }
 }

 t_topl.y=frustumAABB2D.maxPt.y;
 t_topl.x=-(t_frustumvertex[8].y-frustumAABB2D.maxPt.y)*tanf(acosf(t_value[t_no]));
 t_topl.z=0.0f;
 t_bottoml.y=frustumAABB2D.minPt.y;
 t_bottoml.x=-(t_frustumvertex[8].y-frustumAABB2D.minPt.y)*tanf(acosf(t_value[t_no]));
 t_bottoml.z=0.0f;

 D3DXMATRIX t_invtrans;
 D3DXMatrixInverse(&t_invtrans,NULL,&t_trans);

 D3DXVec3TransformCoord(&topl,&t_topl,&t_invtrans);
 D3DXVec3TransformCoord(&topr,&t_topr,&t_invtrans);
 D3DXVec3TransformCoord(&bottoml,&t_bottoml,&t_invtrans);
 D3DXVec3TransformCoord(&bottomr,&t_bottomr,&t_invtrans);
 D3DXVec3TransformCoord(&intersection,&t_frustumvertex[8],&t_invtrans);
 
 //
 return S_OK;
};