Shader: 2D and 3D arrays

Started by
9 comments, last by faculaganymede 19 years, 1 month ago
Shader Experts, Based on what I learn so far, it seems there's no support for uniform variables of 2D or 3D arrays in the OpenGL Shading Language. If I try to do something like this inside my shader program: uniform float tbl[100][100]; The compiler doesn't like it. Am I not doing this correctly or there really isn't a way? Another idea that I have is that maybe I can make tbl a sampler2D variable, as: uniform sampler2D tbl; But in this case, how do I index the elements in tbl (i.e. if I want to get the value of element tbl[5][5])?
Advertisement
define 'doesnt like it'?
if you are trying to define a 100*100 array then its not gonna work, you're just going to blow out the uniform space, as you're asking for 10,000 floats and my X800XT can only do 4096, so you've over shot by around 6000 floats..
Thanks for your reply, Phantom.
Quote:Original post by _the_phantom_
define 'doesnt like it'?

If I have this in the shader program:
uniform float tbl[100][100];

I get the following error:
"Ready for GLSL
ERROR: 0:4: '[' : syntax error parse error
Link failed. All shader objects have not been successfully compiled."

Quote:Original post by _the_phantom_
if you are trying to define a 100*100 array then its not gonna work, you're just going to blow out the uniform space, as you're asking for 10,000 floats and my X800XT can only do 4096, so you've over shot by around 6000 floats..

What are my other options of passing a large 2D or 3D array of data into the shader (in particular the fragment shader)?

What do you think of my idea of passing the array into the shader as a sampler2D or sampler3D variable (that seem to have enough memory, but I don't know how to access the individual element values)?
having had a shifty at the Orange Book, it appears you are correct in that you cant have a 2D array, everything is a 1D array of a type (which does give you a 2D array in the case of vecs and a 3D one in teh case of mats).

As you say, you'll have to use a texture to access it, which means you'll need to know the width and height of the texture and then take your values you would be using to access the array and normalise them into a [0->1] domain in order to get the right texel.

Beware of filtering and other such things when doing this, i think you'll want to use GL_NEAREST as the filtering kernel, otherwise will will do averaging and you'll get odd results.

As for how to store the data, you can do it either as a 1 component texture (something like GL_LUMIANCE for example) or pack the value into the RGBA channels and then expand them again when you need to get the real value back.
Thanks Phantom.

I thought I explain the full story, maybe someone knows a better way than what I have in mind...

The full story is I am trying to implement a fragment shader that converts the texture RGB to intensity using a look-up table:

RGB -> fragment shader (use look-up table) -> intensity

The look-up table needs to be a 3D array for the 3 color components (i.e. tbl[R][G]=intensity). This is what I had in mind of going about it:

1. In application program -> create look-up table -> float tbl[256][256][256]
2. In application program -> call shader programs
3. In fragment shader program -> read look-up table
4. In fragment shader program -> get texture RGB
5. In fragment shader program -> do intensity look-up -> gl_FragColor = intensity

So, that's why I'll need a 3D array. I appreciate any suggestions.

By the way, how do I get the texture RGB values inside the fragment shader program? gl_Color gives texture color + other colors combined (e.g. lighting), right?
Unless you're planning on changing your intensity mapping, it's likely far more efficient to compute the intensity value directly in the pixel shader.

Something along the lines of 0.299 * R + 0.587 * G + 0.114 * B ought to do it.
Thanks for your reply, ReaperSMS.

The intensity values need to be mapped from the look-up table.
Quote:Original post by faculaganymede
By the way, how do I get the texture RGB values inside the fragment shader program? gl_Color gives texture color + other colors combined (e.g. lighting), right?


no, gl_Color give the per-vertex color in a vertex shader, which you then have to pass down to the fragment shader as a varying to get at it there where you will be able to read the interpolated color, to get the texture color you have to perform the texture lookup yourself in the fragment shader and then do whatever you want with that (apply lighting, fog whatever).
Quote:Original post by _the_phantom_
no, gl_Color give the per-vertex color in a vertex shader...

In the vertex shader, gl_Color is the per vertex color. Does this color include the lighting component in it? If it does, how can I make it not include the lighting component (i.e. to have gl_Color include only colors I want - the 3D model's surface color and texture color).

Quote:Original post by _the_phantom_
no, gl_Color give the per-vertex color in a vertex shader, which you then have to pass down to the fragment shader as a varying...

gl_Color is a built-in variable. If I don't pass it from vertex shader to fragment shader as a varying variable and just use it in the fragement shader, now, inside the fragment shader, is gl_Color still the same per vertex color as inside the vertex shader, or is gl_Color now the interpolated color?

If, inside the fragment shader, gl_Color is the interpolated color, does this color include the lighting component in it? I am confused.
Quote:Original post by faculaganymede
In the vertex shader, gl_Color is the per vertex color. Does this color include the lighting component in it?

No, you would have to do the lighting calculations yourself if you wanted to. As it is, you should have the color you want with gl_Color.

Quote:Original post by faculaganymede
gl_Color is a built-in variable. If I don't pass it from vertex shader to fragment shader as a varying variable and just use it in the fragement shader, now, inside the fragment shader, is gl_Color still the same per vertex color as inside the vertex shader, or is gl_Color now the interpolated color?

If, inside the fragment shader, gl_Color is the interpolated color, does this color include the lighting component in it?

gl_Color is interpolated in the fragment shader. Once again, you would have to do the lighting calculations yourself.

I'm afraid I don't know how to do it myself (I'm learning this stuff right now), but I'm sure what you're going to want to do is to use a texture.

This topic is closed to new replies.

Advertisement