通过像素值偏移gl_Position或gl_Vertex [英] Offset gl_Position or gl_Vertex by pixels value

查看:208
本文介绍了通过像素值偏移gl_Position或gl_Vertex的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有包含像素值的属性.而且我想用这个属性值来补偿我的gl_vertex.

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

问题是我的gl_vertex以世界单位为单位,而offset \ attribute以像素为单位.

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

如果我将屏幕尺寸统一发送,然后将像素转换为-1到1的值,然后将其添加到最终的gl_Position中,则可以执行此操作.但是我现在不想管理屏幕大小的事件,无论如何我要在每个绘图,每个着色器中都发送它.

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 ?

为了简化操作,我想将gl_Position设置为像素50,50.

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);
}

此代码仅在2D(正交投影)中有效.但不适用于3D. 现在我遇到了问题.我知道我也需要考虑Z值,但不知道如何.

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.

有人吗?

推荐答案

来自keltars评论:

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);

您已经在另一条评论中说过它完美运行".我认为keltar的一般方法在这里绝对正确,但是此实现存在一些问题,并且至少在一般情况下不会正确运行.

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.

因此,最好修改方法以保持原始w不变,并使用类似以下内容的方法:

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);

这篇关于通过像素值偏移gl_Position或gl_Vertex的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆