XNA 4.0 beta: EffectPass not a simple wrapper!

  So, the beta is out!

      XNA 4.0进行了大幅更新,大部分改动都不错,不过一直有2点让我非常不爽:1. render target必须和某个depth buffer绑定到一起;2. 没有了SetxxShader和SetShaderConstant等底层函数。前者对deffered shading非常不友好,后者让我写的整个材质系统都不能用了。相比之下,后者更让我担心,因为CTP中的Effect和EffectPass仅仅是DX Effect系统之上的一个简单wrapper众所周知,DirectX中Effect的性能一直是被人诟病的地方。好在Shawn告诉我:

“The Windows EffectPass.Apply implementation in the CTP is not complete, and many optimizations not yet implemented. The CTP implementation is functionally correct, but not from a performance standpoint, so you should not worry too much about Windows performance in the CTP.”

 

     似乎Beta版已经解决了这个问题,4.0中的EffectPass不再是DX Effect上的一个简单wrapper,xna team做了很大的努力减少状态改变,以至于PIX分析xna 4.0的程序时有可能出错,Shawn在blog中说:

"The problem occurs because PIX does not support some crazy tricks that GS4 uses to optimize state management" 。

 

      下面是同一段代码在CTP和beta版下的对比:

// test code //
..... set  parameter  for  first  object
effectPass.Apply();
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 
0 0 ,vertices.Count,  0 , primitiveCount);
// only change world matrix and draw the same object again
effect.World  =  Matrix.CreateTranslation( 1 0 0 );
effectPass.Apply();
graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 
0 0 ,vertices.Count,  0 , primitiveCount);



// Pix data for ctp:
ID3DXEffect::BeginPass( 0 )                          
ID3DXEffect::EndPass()                         
ID3DXEffect::End()                         
IDirect3DDevice9::BeginScene()                         
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 ) // draw the 1 primitive                  
ID3DXEffect::SetMatrix( 0xFF6B4D6B 0x0039E6F0 )                     
ID3DXEffect::SetMatrix(
0xFF6B4E13 0x0039E684 )                     
ID3DXEffect::SetMatrix(
0xFF6B4DBF 0x0039E684 )                     
ID3DXEffect::Begin(
0x0039E7EC 0x00000001 )                 
ID3DXEffect::BeginPass(
0 )                          
 IDirect3DDevice9::SetVertexShader(
0x06487820 )                      // redundance!!!!!!
 IDirect3DDevice9::SetVertexShaderConstantF( 0 0x015851C8 1 )       // redundance!!!!!!!!      
 IDirect3DDevice9::SetVertexShaderConstantF( 14 0x015852A8 1 )      // redundance !!!!!!    
 IDirect3DDevice9::SetVertexShaderConstantF( 15 0x015852B8 4 )             
 IDirect3DDevice9::SetVertexShaderConstantF(
19 0x015852F8 3 )             
 IDirect3DDevice9::SetVertexShaderConstantF(
23 0x01585338 3 )             
 IDirect3DDevice9::SetPixelShader(
0x06486AE8 )    3914655838           // redundance!!!!!
 IDirect3DDevice9::SetPixelShaderConstantF( 0 0x01586D40 15 )       // redundance!!!!!!    
ID3DXEffect::EndPass()                         
ID3DXEffect::End()                     
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 ) //  draw the 2 primitive      


// Pix data for beta with d3dx function call
ID3DXEffect::BeginPass( 0 )                
IDirect3DDevice9::BeginScene()
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 )        
ID3DXEffect::SetMatrix(
0xFF84502B 0x0023E444 )                    
ID3DXEffect::SetMatrix(
0xFF8450D3 0x0023E3D8 )                    
ID3DXEffect::SetMatrix(
0xFF84507F 0x0023E3D8 )                    
ID3DXEffect::CommitChanges()                    
  IDirect3DDevice9::SetVertexShaderConstantF(
15 0x00FB5668 4 )
  IDirect3DDevice9::SetVertexShaderConstantF(
19 0x00FB56A8 3 )
  IDirect3DDevice9::SetVertexShaderConstantF(
23 0x00FB56E8 3 )
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 )

// Pix data for beta without d3dx function:
IDirect3DDevice9::BeginScene()                
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 )
IDirect3DDevice9::SetVertexShaderConstantF(
15 0x007D5660 4 )
IDirect3DDevice9::SetVertexShaderConstantF(
19 0x007D56A0 3 )
IDirect3DDevice9::SetVertexShaderConstantF(
23 0x007D56E0 3 )
IDirect3DDevice9::DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0 0 24 0 12 )                    

 

 

     可以看到beta版中,完全过滤了冗余的状态设置,测试代码中的effect.World会更新world marix,worldViewProjMatrix以及WorldInverseTranspose,因此渲染第二个对象前出现3个参数更新是正确的。测试程序里只渲染了2个图形,因此,BeginScene在第一次DP之前出现也是正确的。

 

   

转载于:https://www.cnblogs.com/clayman/archive/2010/07/13/1776611.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值