• HLSL中struct里面的变量在内存中的放置方式


     《Intro to d3d10》里面关于hlslstructure packing有这样一段描述

    struct Light

    {

        Light()

        {

            ZeroMemory(this, sizeof(Light));

        }

        D3DXVECTOR3 pos;

        float pad1;       // not used

        D3DXVECTOR3 dir;

        float pad2;       // not used

        D3DXCOLOR ambient;

        D3DXCOLOR diffuse;

        D3DXCOLOR specular;

        D3DXVECTOR3 att;

        float spotPow;

        float range;

    };

    The issue with the pad” variables is to make the C++ structure match the HLSL structure. In the HLSL, structure padding occurs so that elements are packed into 4D vectors, with the restriction that a single element cannot be split across two 4D vectors. Consider the following example:

    struct S

    {

        float3 pos;

        float3 dir;

    };

    If we have to pack the data into 4D vectors, you might think it is done like this:

    vector 1: (pos.x, pos.y, pos.z, dir.x)

    vector 2: (dir.y, dir.z, empty, empty)

    However, this splits the element dir across two 4D vectors, which is not allowed — an element is not allowed to straddle a 4D vector boundary. Therefore, it has to be packed like this:

    vector 1: (pos.x, pos.y, pos.z, empty)

    vector 2: (dir.x, dir.y, dir.z, empty)

    Thus, the pad” variables in our C++ structure are able to correspond to those empty slots in the padded HLSL structure (since C++ does not follow the same packing rules as HLSL).

        个人感觉with the restriction that a single element cannot be split across two 4D vectors这段的描述是不对的,至少是有歧义。经过几次测试,加之请教了一个大牛,基本确定的是:HLSL的结构体struct其实并不管你是一个变量还是几个变量,它就是按照一次放满一个float4的内存长度,多少变量都往一个float4里面塞,塞满了再接着塞下一个float4

        所以就要小心面对float3float2这样的变量,因为前面有变量的关系已经不能再塞到一个float4里面了,那么就要小心。要放几个填充变量,使得float2float3能够在新的一个float4里面重新开始放置。比如下面的例子:

    struct S

    {

     float3 pos;

     float3 normal;

    }

        应该写为

    struct S

    {

     float3 pos;

    float pad1;

     float3 normal;

    float pad2;

    }

        一个师兄介绍最好采用下面的方式:

    struct S

    {

     Float4 pos;

     Float4 normal;

    }

        当然如果不想packing也可以,比如下面:

    vector a: (pos.x, pos.y, pos.z, dir.x)

    vector b: (dir.y, dir.z, empty, empty)存放的话,在hlsl你得float3 aa=a.xyz;float3 bb=float3(a.w,b.x,b.y)

     

        另外如果不想packing。根据大牛的介绍:hlsl编译的时候开了优化选项和不开packing也不一样,就是可以让hlslpacking,比如在d3d9里面得用Id3DXEffect::setRawValue传递进去,这个偶自己就没有测试过,很少使用Effect框架。

  • 相关阅读:
    HierarchicalDataTemplate
    Prism技巧
    常用Exception
    netcore URL重新路径
    Nintendo Switch相册整理
    交换变量-不借助任何变量
    QCombobox样式stylesheet总结
    Qt新旧Moc方式升级功能
    QSS使用方法总结
    【QRegExp】QLineEdit屏蔽空格
  • 原文地址:https://www.cnblogs.com/bester/p/3255795.html
Copyright © 2020-2023  润新知