Raz*_*a O 3 opengl shader pixel vertex
我的属性包含像素值。我想用这个属性值来偏移我的 gl_vertex 。
问题是我的 gl_vertex 以世界单位为单位,而 offset\attribute 以像素为单位。
如果我将屏幕尺寸作为统一发送,然后将像素转换为 -1 到 1 值,并将其添加到最终的 gl_Position 中,我就可以做到这一点。但我现在不想管理屏幕尺寸事件并在每次绘制、我拥有的每个着色器时发送它。
有没有办法通过一些矩阵游戏或它们的逆矩阵来做到这一点?
为了方便起见,我想将 gl_Position 设置为像素 50,50。
vec4 myPixelValue = vec4(50,50,1,1);
gl_Position = <Something> * myPixelValue;
Run Code Online (Sandbox Code Playgroud)
- - 添加 - -
在我了解到如果不向着色器发送窗口大小就不可能做到这一点后,我决定发送该大小。我创建了以下顶点着色器代码
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);
}
Run Code Online (Sandbox Code Playgroud)
此代码仅适用于 2D(正交投影)。但不是 3D。我现在遇到了问题。我知道我还需要考虑 Z 值,但不知道如何。
任何人 ?
来自 keltars 的评论:
尝试在标准化设备坐标而不是剪辑空间中进行计算。例如
Run Code Online (Sandbox Code Playgroud)vec4 clip = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = vec4(clip.xyz / clip.w + vec3(convertexPix, 0.0), 1.0);
您已经在另一条评论中说过它“完美运行”。我认为 keltar 的一般方法在这里是绝对正确的,但是这个实现有一些问题,并且不会正常工作,至少在一般情况下不会。
问题是,这会在着色器中手动进行透视划分,但裁剪(在着色器之后完成)必须在划分之前完成。如果您的图元与近平面相交,或者物体位于相机后面(现在甚至可能出现在您的面前),这尤其会给您带来错误的结果。
这也将破坏透视校正插值。
因此,最好修改方法以保持原始 w 不变,并使用类似以下内容的方法:
Run Code Online (Sandbox Code Playgroud)vec4 clip = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = vec4(clip.xyz + vec3(clip.w * convertexPix, 0.0), clip.w);
| 归档时间: |
|
| 查看次数: |
2230 次 |
| 最近记录: |