Sign in to follow this  
jajcek

Passing an array for each vertex

Recommended Posts

Hello,

 

I'm looking for some flexibility on sending data for each vertex. In my situation I'd like to pass some array for every vertex to specify which texture it should use (the array won't me too big, like 5, 6 maybe 7 values; I cannot send only one value with texture id because I need blending between them), like:

 

[1.0, 0.0, 0.0 ...] - first texture

[0.0, 1.0, 0.0 ...] - second texture and so on

 

Currently I am packing these values into some TEXCOORD etc. but it is not flexible, because when I want to add next texture I need to change the vertex structure and try to pack the value somewhere in the shader.

 

So short question: is it possible to send an array with each vertex in DirectX/HLSL?

 

EDIT:

 

I have such structure (variable t is unused but it works with it):

 

struct TerrainVertex {
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT4 color;
    DirectX::XMFLOAT3 normals;
    DirectX::XMFLOAT2 texture;
    DirectX::XMFLOAT2 t;
};

and changed it to (for testing):

struct TerrainVertex {
    DirectX::XMFLOAT3 position;
    DirectX::XMFLOAT4 color;
    DirectX::XMFLOAT3 normals;
    DirectX::XMFLOAT2 texture;
    float t[2];
};

but my whole terrain disappears and I have random artifacts on the screen (plus Microsoft C++ exception: _com_error at memory location 0x002EF170.)

 

input layout:

 

D3D11_INPUT_ELEMENT_DESC inputLayout[] = 
{
    { "POSITION", 0U, DXGI_FORMAT_R32G32B32_FLOAT,    0U, 0U,                           D3D11_INPUT_PER_VERTEX_DATA, 0U },
    { "COLOR",    0U, DXGI_FORMAT_R32G32B32A32_FLOAT, 0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
    { "NORMAL",   0U, DXGI_FORMAT_R32G32B32_FLOAT,    0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
    { "TEXCOORD", 0U, DXGI_FORMAT_R32G32_FLOAT,       0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
    { "TEXCOORD", 1U, DXGI_FORMAT_R32G32_FLOAT,       0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U }
};

 

Thanks for help!

Edited by jajcek

Share this post


Link to post
Share on other sites

I have changed the input layout as you said:

 

{ "POSITION", 0U, DXGI_FORMAT_R32G32B32_FLOAT,    0U, 0U,                           D3D11_INPUT_PER_VERTEX_DATA, 0U },
{ "COLOR",    0U, DXGI_FORMAT_R32G32B32A32_FLOAT, 0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
{ "NORMAL",   0U, DXGI_FORMAT_R32G32B32_FLOAT,    0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
{ "TEXCOORD", 0U, DXGI_FORMAT_R32G32_FLOAT,       0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U },
{ "TESTCOORD", 0U, DXGI_FORMAT_R32G32_FLOAT,       0U, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0U }

and my vertex shader:

 

cbuffer WVP {
    matrix worldViewProjMatrix;
};




struct VS_INPUT {
    float3 position : POSITION;
    float4 color    : COLOR;
    float3 normal   : NORMAL;
    float2 tex      : TEXCOORD0;
    float t[2]   : TESTCOORD0;
};


struct PS_INPUT {
    float4 position : SV_POSITION;
    float4 color    : COLOR;
    float3 normal   : NORMAL;
    float3 tex      : TEXCOORD0;
};


PS_INPUT main(VS_INPUT input) {
    PS_INPUT output;


    output.position = mul( float4( input.position, 1.0f ), worldViewProjMatrix );
    output.color    = input.color;
    output.normal   = input.normal;


    output.tex = float3( input.tex.x, input.tex.y, input.position.y / 50.0f );


    return output;
}

but still the same effect with the same error.

 

I don't know where to look, it is not even used in the shader, just trying to pass there something for testing.

 

To sum up: when I change the

float t[2]   : TESTCOORD0; to float2 t : TESTCOORD0; in shader

and

float t[2]; to DirectX::XMFLOAT2 t; in vertex structure

 

it is working. But I'd like it to be an array.

Edited by jajcek

Share this post


Link to post
Share on other sites

Vertex attributes cannot be arrays. Attributes can only be one of the known dxgi formats (and even then a few are reserved for texture use only). Any change to a vertex format to add/remove members typically always requires a change to the vertex shaders that refer to it.

If you really want to go down this route, settle on a count thats a multiple of 4 and just use float4 attributes, so they take up entire attribute registers.

Share this post


Link to post
Share on other sites


Currently I am packing these values into some TEXCOORD etc. but it is not flexible, because when I want to add next texture I need to change the vertex structure and try to pack the value somewhere in the shader.
But this is what really should be happening. If you need to lookup a coordinate at a specific coord, you need to pass it. It's the way it's meant to be!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this