Jump to content

[SOLVED] how can I use array in vertex shader's input?


photo

Recommended Posts

in my previous post, I asked how to get the world space camera direction. I'm working on porting speedtree's billboards atlas into unigine and automatically select the correct billboard according to the angle between the tree and camera.
 
This is very important for us, because the ObjectGrass and ObjectMeshClutter won't work in our situation, most of our trees have fixed position, I've successfully make this working now, but I have a shader problem.

In speedtree, a billboards for a tree can have up to 8 images, so it's easy to decide which image and it's uv to use. but here comes a problem. I've modified the D3D11Billboards.cpp to this:
 

    static const D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
        { "POSITION",    0,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    0,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    0,    DXGI_FORMAT_R32G32B32A32_FLOAT,    0,    12,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    1,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    28,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    2,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    36,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    3,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    44,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    4,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    52,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    5,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    60,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    6,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    68,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    7,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    76,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    8,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    84,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    9,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    92,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    10,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    104, D3D11_INPUT_PER_VERTEX_DATA,    0 },
    };

as you can see I'm using up to 8 TEXCOORD, each responding to the billboard uv according to 0-360 degress. so once I've calculated the correct index, I have to use a switch statment in shader to get the the uv.

I also tried to use
 

    static const D3D11_INPUT_ELEMENT_DESC input_element_desc[] = {
        { "POSITION",    0,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    0,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    0,    DXGI_FORMAT_R32G32B32A32_FLOAT,    0,    12,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    1,    DXGI_FORMAT_R16G16B16A16_UNORM,    0,    28,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    2,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    92,    D3D11_INPUT_PER_VERTEX_DATA,    0 },
        { "TEXCOORD",    3,    DXGI_FORMAT_R32G32B32_FLOAT,    0,    104, D3D11_INPUT_PER_VERTEX_DATA,    0 },
    };

to pass the uv as a array, also I've made some modification to D3D11Ext.cpp to write the correct shader declaretion to use this 8 array in TEXCOORD1, because my billboards is the only mesh which use DXGI_FORMAT_R16G16B16A16_UNORM as type. in shader billboards\vertex_base.shader to use
 

struct VERTEX_IN {
    float4 position : POSITION;
    float4 texcoord_0 : TEXCOORD0;
    float4 texcoord_1[8] : TEXCOORD1;
    float3 direction : TEXCOORD2;
    float3 up : TEXCOORD3;
};

but engine keeps reporting that direction has wrong type. Then I think the shader system thinks the direction input are still one of the uv channel. So, here comes the problem, How can I pass this 8 uv as a array in vertex shader instead of use 8 different TEXCOORD and a switch in shader?
 
 
and one more problem in direct3d9:
 

    static const D3DVERTEXELEMENT9 vertex_element[] = {
        { 0, 0,        D3DDECLTYPE_FLOAT3,        D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,    0 },
        { 0, 12,    D3DDECLTYPE_FLOAT4,        D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    0 },
        { 0, 28,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    1 },
        { 0, 36,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    2 },
        { 0, 44,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    3 },
        { 0, 52,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    4 },
        { 0, 60,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    5 },
        { 0, 68,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    6 },
        { 0, 76,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    7 },
        { 0, 84,    D3DDECLTYPE_USHORT4N,    D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    8 },
        { 0, 92,    D3DDECLTYPE_FLOAT3,        D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    9 },
        { 0, 104,    D3DDECLTYPE_FLOAT3,        D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    10 },
        D3DDECL_END()
    };
    
    IDirect3DDevice9 *device = D3D9Ext::getDevice();
    
    HRESULT s = device->CreateVertexDeclaration(vertex_element,&vertex_declaration);

 
then CreateVertexDeclaration will fail, why?

Link to comment

and I think we all know that using switch-case or 8 if-else if in a shader will have much more performance hit than just a one simple IN.texcoord_1[image_index] statement.

 

and I also believe some others want to use ObjectDynamic will also have this kind of problem.

Link to comment

I don't think that "float4 texcoord_1[8] : TEXCOORD1;" construction can map to hardware capabilities. An if/else structure based on 8 different texture coordinates will provide same performance.

 

Direct3D9 runtime have a good debug system. Just switch to the debug runtime in dxcpl.exe and see all errors and warings inside visual studio output attached to the engine process.

Link to comment

strange on dx sdk's dxcpl, it can not enable debug mode for dx9 under windows 8.

 

and I really don't think

 

        [forcecase] switch(image_index)
        {
            case 0: in_texcoord = IN.texcoord_1; break;
            case 1: in_texcoord = IN.texcoord_2; break;
            case 2: in_texcoord = IN.texcoord_3; break;
            case 3: in_texcoord = IN.texcoord_4; break;
            case 4: in_texcoord = IN.texcoord_5; break;
            case 5: in_texcoord = IN.texcoord_6; break;
            case 6: in_texcoord = IN.texcoord_7; break;
            case 7: in_texcoord = IN.texcoord_8; break;
        }

 

will have same performance than

 

in_texcoord = IN.texcoord_1[image_index];

 

:blink:

Link to comment

this is first I've tried, then I have this error, and engine crash:

 

16:01:27 error X8000: D3D11 Internal Compiler Error: Invalid Bytecode: Input signature does not specify component 3 of register 11 which is declared in the shader code.

 

are you sure it's float array[8]; instead of float4 array[8]; they both have error, and I believe it should be float4 array[8]

Link to comment

OK, how stupid I am, the C++ part for dx11 works fine, in vertex input I just use

struct VERTEX_IN {
    float4 position : POSITION;
    float4 texcoord_0 : TEXCOORD0;
    float4 texcoord_1[8] : TEXCOORD1;
    float3 direction : TEXCOORD9;
    float3 up : TEXCOORD10;
};

then there will be no switch no array reassign...

 

but in glsl write this

 

in float4 s_attribute_0;
in float4 s_attribute_1;
in float4 texcoord_1[8];
in float3 direction;
in float3 up;

 

seems will cause engine crash.

Link to comment
  • 3 weeks later...

You can use this kind of vertex shader inputs.

s_attribute_0 - s_attribute_15 are special reserved names for shaders.

The only way to use different names is a strict layout binding:

(layout binding = 2) in texcoord_1;
Link to comment

thanks, but after some digging in glsl's document, it seems glsl don't support to use a variable as array index.

 

So, there is no need for a array in glsl, only use switch.

Link to comment
×
×
  • Create New...