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

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
WordPress大学
WordPress大学
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
IT之家
IT之家
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
美团技术团队
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
H
Help Net Security
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
博客园_首页
A
About on SuperTechFans
MongoDB | Blog
MongoDB | Blog
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
D
DataBreaches.Net
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
B
Blog
The Register - Security
The Register - Security
I
InfoQ
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
Last Week in AI
Last Week in AI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
有赞技术团队
有赞技术团队
Stack Overflow Blog
Stack Overflow Blog
Jina AI
Jina AI
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News - Newest:
Hacker News - Newest: "LLM"
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
W
WeLiveSecurity
Latest news
Latest news
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 叶小钗
L
Lohrmann on Cybersecurity
博客园 - Franky
Recent Commits to openclaw:main
Recent Commits to openclaw:main
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

博客园 - 胡说八道

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;
};