سؤال

I have attribute contains pixels values. And i want to offset my gl_vertex with this attribute value.

The problem is that my gl_vertex is in world units and the offset\attribute is in pixels.

I can do it if i'm sending the screen size as uniforms and then convert the pixels to -1 to 1 values, and add it to the final gl_Position. But i don't want now to manage screen size events and sending it anyway every draw, every shader that i have.

It there any way to do it with some matrix play, or their inverses ?

To make it easier, I want to set the gl_Position to pixel 50,50.

vec4 myPixelValue = vec4(50,50,1,1);
gl_Position = <Something> * myPixelValue;

---- ADDITION ----

After I understood that it is not possible to do it without sending the shader the window size I decided to send the size. And I created this following vertex shader code

attribute vec2 spriteOffset;

uniform vec2 screenSize;

void main() 
{    
    vec2 screenConvert = vec2(2.0 / screenSize.x, -2.0 / screenSize.y);
    vec2 convertedPix = spriteOffset * screenConvert;

    gl_Position = (gl_ModelViewProjectionMatrix * gl_Vertex) + vec4(convertedPix, 0.0, 0.0);
}

This code is working only in 2D (Orthographic projection). but not on 3D. And there i'm having the problem now. I know i need to consider the Z value as well, but don't know how.

Anyone ?

هل كانت مفيدة؟

المحلول

From keltars comment:

Try calculating in normalised device coordinates instead of clip space. E.g.

vec4 clip = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = vec4(clip.xyz / clip.w + vec3(convertexPix, 0.0), 1.0);

You already said that it "works perfectly" in another comment. I think keltar's general approach is absolutely correct here, but this implementation has some issues, and will not work correctly, at least not in the general case.

The problem is that this does the perspective divide manually in the shader, but the clipping (which is done after the shader) has to be done before the divide. This will especially give you wrong results if you have primitives which are intersecting the near plane, or objects which lie behind the camera (which might now even appear in front of you).

What this also will break is the perspective corrected interpolation.

So it is better to modify the approach to keep the original w as it was and use something like:

vec4 clip = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = vec4(clip.xyz + vec3(clip.w * convertexPix, 0.0), clip.w);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top