Passing variable size arrays to shader

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Passing variable size arrays to shader

Post by Abraxas) »

Hello,

If anyone has some insight into the best way to do this, is would be appreciated.

I would like to construct a dynamically sized array with an indeterminate amount of points (anywhere between 0-1000) in the API, then pass this to the shader.

The I thought of is just passing a 1000-big array to the shader and a 'pointcount' int.

Is there a way to dynamically size arrays to do this?

Thanks.
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Passing variable size arrays to shader

Post by Mel »

not in DX9C, in DX10, i guess that the shader resources can have a dynamic size, and in OpenGL it is posible to make something similar. But in DX9c shaders you have to use a fixed size constants table, so, you have to create the largest array posible, and pass it, even if it is not going to be used complete.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Granyte
Posts: 849
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Passing variable size arrays to shader

Post by Granyte »

well you can theoricaly pass only the variable you are using to the shader but you really need to declare the biggest array you will possibly pass to the shader

note that when using array the maximum float4x4 you can ever pass is 63 and the max float 3 and float 4 is 248 but in irrlicht anything over 224 will fail silently without warning sometime even causing crashes
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Passing variable size arrays to shader

Post by Mel »

no, the maximum amount of data you can pass on dx9c is exactly 256 float4. And, all the data you pass will be aligned to 4 dwords, if it is smaller. they are 256 registers of 128 bits each, hence, the alignment
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Granyte
Posts: 849
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Passing variable size arrays to shader

Post by Granyte »

that is tyhe dx9c specification but you need at least 1 matix at least for view projection and from experimentation compilation will fail in irrlicht for anything higer then 224 float4+ 1 matrix
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Passing variable size arrays to shader

Post by Mel »

maybe you can't set more than 225 variables, but in size you may fill up to 256 registers. In fact, a 4x4 matrix gets optimized to a smaller matrix if the shader doesn't use some rows.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Passing variable size arrays to shader

Post by Abraxas) »

224 float4 registers equates to how many float2s? Or should I double embed the points in a single register?

I just organized my code to send the 100 nearest points ( also the 100 first that pass the comparison test).

I'm using it for a radar shader code.
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Passing variable size arrays to shader

Post by hendu »

Think outside the box and send your points as literal points? (vertices)

Maybe post a pic of what you want to do.
Granyte
Posts: 849
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Passing variable size arrays to shader

Post by Granyte »

or use my vertex texture patch and send it as a texture that is if you need the data in the vertex shader
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Passing variable size arrays to shader

Post by Abraxas) »

Hendu wouldn't that involve additional overhead? Creating a new set of vertices every frame?

Anyway this is what my radar shader looks like:

Callback:

Code: Select all

        // Build points
 
            f32 point[50][2];
            for (int i = 0; i< 50; i++)
            for (int j = 0; j< 2; j++)
                point[i][j] = 0;
            
                // get camera direction
            vector3df cam =  vector3df(smgr->getActiveCamera()->getTarget() - smgr->getActiveCamera()->getAbsolutePosition()).normalize();
        
 
            f32 pointcount = 0;
            if (!obj->quad.empty());
                for (int i = 0; i< obj->quad.size(); i++)
                if (obj->quad[i]->active)
                {
                    vector3df dist = (obj->quad[i]->p - obj->plane->p)*.5/inventoryManager->equip.radarrange;
                    
                    dist.rotateXZBy( atan2(cam.X,cam.Z) * RADTODEG );
 
                        if (dist.getLength() < .5)
                        {                       
                            point[(int)pointcount][1] = (-dist.Z + 0.5) ;
                            point[(int)pointcount][0] = (dist.X + 0.5) ;                            
                            pointcount++;
                        }
                    
                }
 
 
 
                services->setPixelShaderConstant("psize", reinterpret_cast<f32*>(&pointcount), 1);
                services->setPixelShaderConstant("p", reinterpret_cast<f32*>(&point), 100);
Shader:

Code: Select all

float psize;
float p[50][2];
 
float4 PS(OUT I) : COLOR
{  
 
    // Sample the pixel color
    float4 color = tex2D(ColorMapSampler, I.L);    
    
    //Process all the points:
 
float mod = 0;
int i = 0;
 
for (i; i<psize; i++)
if (p[i][0] != 0)
{
 
    float xdist = abs(I.L.x - p[i][0]);
    float ydist = abs(I.L.y - p[i][1]);
 
    float dist = saturate(sqrt(xdist*xdist + ydist*ydist));
    
    dist = pow(1 - dist,64);
    
    mod = mod + dist;
}
    
    color = color + mod * float4(1.5,.4,.4,0);
        
 
    if (color.a > .5) return float4(color.r, color.g, color.b, 0.8);
    else return float4(0,0,0,0);
 
}
Basically to put dots on my radar.

I'll need to send more data with every point though, two floats for position, then ultimately size data and behavior data.

The thing I was the most concerned about was overhead about passing so many variables, but I think the textures and vertex information that's passed is much bigger so just defining a large array seems to be a good solution.
Mel
Competition winner
Posts: 2293
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Passing variable size arrays to shader

Post by Mel »

No, It is posible to draw a really large a mount of triangles even if they are dinamically created and destroyed each frame. Things start to go relatively bad when the amount reaches some thousands of triangles. But for few hundreds it is no big deal.

Use a Draw2Batch. Create an array with the 2D positions, and use always the same source rectangle.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Granyte
Posts: 849
Joined: Tue Jan 25, 2011 11:07 pm
Contact:

Re: Passing variable size arrays to shader

Post by Granyte »

ultimately you could mod my instancing patch to pass a custom second vertex buffer with every data you need for each instance if you have a couple thousand unit to put on the radar that could be the most efficient way to do it.

I have in plans to do this with my instancing patch to do this for my own raday but since i have no knowledge of openGL i didn't do it to have an uniform patch acros both drivers
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Passing variable size arrays to shader

Post by hendu »

Still no picture :P

The overhead would be the same, as you're already creating the array every frame.
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Passing variable size arrays to shader

Post by Abraxas) »

hendu the picture is in my project page, quadfighter.

Mel draw2dbatch might be the fastest way but I like to have strong control over how the dots are drawn (size, color/gradient, I could even modify shape with my code. Plus multiple dots add and merge their colors, which is more "realistic")

I think the second vertex buffer is the best way, where I pass a float (or several floats) from the vertex shader telling the pixel shader how to color that point.

Thanks guys!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Passing variable size arrays to shader

Post by hendu »

Oh, I didn't see it in those pictures, because the forum crops the images.

That looks very amenable to sending the points as vertices indeed.
Post Reply