PixelShader另类常量设置方法

最近遇到一个很囧的问题,

由于各种原因,编译PixelShader后的ConstantTable出错,也就是如需要动态改变一些常量的需求无法实现,

使用了各种方法无法实现,万般无奈,在最后放弃之前又一次拿出了压箱底的DXSDK,

。。。。

慢着,好像通过Device可以直接设置,真是孤陋寡闻了,

ID3DXEffectStateManager::SetPixelShaderConstantF Method

A callback function that must be implemented by a user to set an array of vertex shader floating-point constants.

Syntax
HRESULT SetPixelShaderConstantF(
  [out]  UINT StartRegister,
  [out]  const FLOAT *pConstantData,
  [out]  UINT RegisterCount
);
Parameters
StartRegister [out]
UINT

The zero-based index of the first constant register.

pConstantData [out]
FLOAT

An array of floating-point constants.

RegisterCount [out]
UINT

The number of registers in pConstantData.

Return Value

HRESULT

The user-implemented method should return S_OK. If the callback fails when setting the device state, either of the following will occur:

Requirements

Header

D3DX9Effect.h

Library

D3dx9.lib

。。。

但是这里这个StartRegister如何取得?

首先想到是再建立了一个简单的工程,

直接通过Effect加载Shader:

    D3DXEFFECT_DESC tEffectDesc;
    g_pMotionBlurEffect->GetDesc(&tEffectDesc);
    int iCount=tEffectDesc.Parameters;
    for(int i=0;i<iCount;++i)
    {
        hHand1=g_pMotionBlurEffect->GetParameter(NULL,i);
        g_pMotionBlurEffect->GetParameterDesc(hHand1,&tDesc);

    }

调整了下HLSL代码,如愿以偿地把想要动态改变的Parameter放在了第一位,

但是

pd3dDevice->SetPixelShaderConstantF(0,&m_fTimeSin_X,1 );

结果杯具了,

且再看

IDirect3DDevice9::GetPixelShaderConstantF Method

Gets a floating-point shader constant.

Syntax
HRESULT GetPixelShaderConstantF(
  [in]       UINT StartRegister,
  [in, out]  float *pConstantData,
  [in]       UINT Vector4fCount
);
Parameters
StartRegister [in]
UINT

Register number that will contain the first constant value.

pConstantData [in, out]
float

Pointer to an array of constants.

Vector4fCount [in]
UINT

Number of four float vectors in the array of constants.

好吧,再改,

通过,一批量的参数获得,

m_pd3dDevice->GetPixelShaderConstantF(0,g_fData,100 );

动态修改,通过Watch找到了该死的参数(囧,相当得山寨),原来前段是由Effect做的管理,自己的参数被远远地放在了后面:好吧,这回再改,可是效果神奇得花屏了,

这时终于想起了我还有PIX,

调试,找到指定渲染位置,打开Device,

真相大白:

image

Register无论你的参数是Float,Float2抑或Float3,其实在实际的GPU中都是按Float4放置的,

这点就与CPU的内存对齐是一个道理,

明白了这点问题也就迎刃而解了,

如需通过SetPixelShaderConstantF设置参数,

StartRegister的值就是Float4的跨度,

诶,都是吃了不明白机制的亏,做了很多无用功,吃一堑长一智吧~~

posted @ 2011-12-03 15:12  Zephyroal  阅读(1762)  评论(0编辑  收藏  举报