GLSL and vertex attributes.

View: New views
4 Messages — Rating Filter:   Alert me  

GLSL and vertex attributes.

by java3d-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Continuing the story from http://forums.java.net/jive/message.jspa?messageID=265403 , I'm having a tough time combining J3D, vertex attributes, and GLSL. Any help appreciated.

I'm (still) trying to multitexture my terrain, and I've moved to shaders.
I pass a number to the vertex shader, which then hands it off to the fragment shader. The fragment shader uses this number to decide which texture to read from. This number varies per-vertex, and changes over time. All textures are the same size, and use the same coordinates.

Here's my vertex shader :

[code]
attribute float terrainIndex;
attribute float light;

varying float textureIndex;

void main()
{
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = ftransform();

        textureIndex = terrainIndex;
}
[/code]


and fragment shader :

[code]
uniform sampler2D grass, sand;
varying float textureIndex;

void main()
{
        vec4 texel;
       
        if (textureIndex == 0.0)
                texel = texture2D(grass, gl_TexCoord[0].st);
        else if (textureIndex == 1.0)
                texel = texture2D(sand, gl_TexCoord[0].st);
        else
                texel = vec4(1.0, 0.0, 0.0, 1.0);
       
        gl_FragColor = texel;
}
[/code]


This is how I define my Quad Array :
[code]
QuadArray qa = new QuadArray(
        /*int vertexCount*/ 4,
        /*int vertexFormat*/ GeometryArray.COORDINATES | GeometryArray.TEXTURE_COORDINATE_2
                | GeometryArray.COLOR_3 | GeometryArray.VERTEX_ATTRIBUTES,
        /*int texCoordSetCount*/ 1,
        /*int[] texCoordSetMap*/ new int[] {0, 0},
        /*int vertexAttrCount*/ 2/*?*/,
        /*int[] vertexAttrSizes*/ new int[] {1, 1}
);
[/code]



And this is how I (attempt to) pass the vertex attributes.
[code]
qa.setVertexAttrs(0, 0, new float[] {0, 1, 0, 1});
qa.setVertexAttrs(1, 0, new float[] {1, 0, 1, 0});
[/code]

Now that I've set the scene, here's the problem : It no worky.

I should be seeing a smoothly blended mishmash of sand and grass, but for some reason, the variables aren't getting to the fragment shader.

If I pass float[] {1,1,1,1} or float[] {0,0,0,0}, then I see a plane of grass or sand respectively. If I mix the values as above, I see nothing.


Am I overlooking something obvious?


The line[code]
qa.setVertexAttrs(0, 0, new float[] {0, 1, 0, 1});[/code]Does this map float[0] -> vertex 0, attribute 0, float[1] -> vertex 1, attribute 0, float[2] -> vertex 2, attribute 0, etc.?

Can I pass per-vertex ints? If so, how?

How can I pass an int from the vertex shader to the fragment shader? If I try 'varying int', Shader Designer complains 'warning C7514: OpenGL does not allow varying of type int'. Floats are fine, but I'd rather be safe and pass an int.

Is there any way I can use the float as a texture array index, rather than the horrible if-else in the fragment shader (there'll eventually be about 10 different textures)?

There was talk about nVidia eating some of my vertex attributes, and getting around that by using GeometryArray.setInitialVertexAttrIndex(). Do I need to worry about that, or is that handled transparently by 1.5.x?
[Message sent by forum member 'morne' (morne)]

http://forums.java.net/jive/thread.jspa?messageID=284552

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: GLSL and vertex attributes.

by java3d-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

[b]varying variables[/b] obtained by a fragment shader are [b]perspective-correct interpolated[/b]:[code]0.0 <= textureIndex <= 1.0[/code]
Give the following fragment shader a try (not tested):

[code]
uniform sampler2D grass, sand;
varying float textureIndex;
 
void main() {
    vec4 texel;
    vec4 texel0;
    vec4 texel1;

    texel0 = texture2D(grass, gl_TexCoord[0].st);
    texel1 = texture2D(sand, gl_TexCoord[0].st);

    // linear blend of grass and sand using the perspective-correct interpolation of textureIndex
    texel = mix(texel0, texel1, textureIndex);

    gl_FragColor = texel;
}
[/code]
August
[Message sent by forum member 'interactivemesh' (interactivemesh)]

http://forums.java.net/jive/thread.jspa?messageID=284582

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: GLSL and vertex attributes.

by java3d-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes, I tried that. Problems happen when texture 0 (eg, grass) abuts texture 2 (rock). as the interpolated value passes from 0 to 2, it will go through 1 (sand).
[Message sent by forum member 'morne' (morne)]

http://forums.java.net/jive/thread.jspa?messageID=284603

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...


Re: GLSL and vertex attributes.

by java3d-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Done! Lots of trial and error, a few silly mistakes, but success in the end.

Just in case anyone should google this up in search of the same answers as me :


> The line[code]
> qa.setVertexAttrs(0, 0, new float[] {0, 1, 0,
> 1});[/code]Does this map float[0] -> vertex 0,
> attribute 0, float[1] -> vertex 1, attribute 0,
> float[2] -> vertex 2, attribute 0, etc.?

No. If i is the index of the float, it maps to each attribute in a vertex, and then each attribute in the next vertex, etc.

So, if you have attribute vec4 in your shader program, and 3 vertices, you'd need to pass float[12], and it would map like so :

float[0] -> vertex0, vec4[0]
float[1] -> vertex0, vec4[1]
float[2] -> vertex0, vec4[2]
float[3] -> vertex0, vec4[3]
float[4] -> vertex1, vec4[0]
float[5] -> vertex1, vec4[1]
float[6] -> vertex1, vec4[2]
etc...



> Can I pass per-vertex ints? If so, how?

As of GLSL 1.20, [b]attribute[/b] can only be used with floats, float vectors and matrices.


> How can I pass an int from the vertex shader to the
> fragment shader? If I try 'varying int', Shader
> Designer complains 'warning C7514: OpenGL does not
> allow varying of type int'. Floats are fine, but I'd
> rather be safe and pass an int.

As of GLSL 1.20, [b]varying[/b] can only be used with floats, float vectors, matrices, or arrays of these.

There is no way (as of 1.20) to pass a constant from the vertex shader to the fragment shader. Everything passed is interpolated, as mentioned nearby, in http://forums.java.net/jive/message.jspa?messageID=284582#284582


> Is there any way I can use the float as a texture
> array index, rather than the horrible if-else in the
> fragment shader (there'll eventually be about 10
> different textures)?

Still not certain about this one...

sampler2D can't be constructed, and can only be passed via [b]uniform[/b]. I got round this by defining tex0 = 0, tex1 = 1 etc, by using ShaderAppearance.setShaderAttributeSet().


> There was talk about nVidia eating some of my vertex
> attributes, and getting around that by using
> GeometryArray.setInitialVertexAttrIndex(). Do I need
> to worry about that, or is that handled transparently
> by 1.5.x?

I think this is now handled transparently (can anyone confirm?).

http://download.java.net/media/java3d/webstart/test/QueryProperties.jnlp reports [i]vertexAttrsMax = 10[/i]. Is this 10 before or after nVidia has eaten some? Would the GLSL compiler throw an error if I exceed this, or silently ignore any extraneous data?

\m/
[Message sent by forum member 'morne' (morne)]

http://forums.java.net/jive/thread.jspa?messageID=284606

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@...
For additional commands, e-mail: interest-help@...

LightInTheBox - Buy quality products at wholesale price