GLSL:如何获得像素x,y,z世界位置?

Roo*_*kie 25 opengl glsl fragment-shader

我想根据它们在世界上的xyz位置来调整颜色.

我在片段着色器中试过这个:

varying vec4 verpos;

void main(){
    vec4 c;
    c.x = verpos.x;
    c.y = verpos.y;
    c.z = verpos.z;
    c.w = 1.0;

    gl_FragColor = c;
}
Run Code Online (Sandbox Code Playgroud)

但似乎颜色根据我的相机角度/位置而变化,我如何使坐标独立于我的相机位置/角度?

继承人我的顶点着色器:

varying vec4 verpos;

void main(){
    gl_Position = ftransform();
    verpos = gl_ModelViewMatrix*gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)

Edit2:改变标题,所以我想要世界坐标,而不是屏幕坐标!

Edit3:添加了我的完整代码

kyn*_*tto 31

在顶点着色器中,您可以使用gl_Vertex(如果不使用固定管道,则为其他内容),这是模型坐标中顶点的位置.通过gl_Vertex乘以模型矩阵,您将获得世界坐标中的顶点位置.指定这一个变化的变量,然后读取其在片段着色器值和世界坐标,你会得到片段的位置.

现在的问题是,如果使用OpenGL的默认模型视图矩阵,它不一定有任何模型矩阵,OpenGL是模型矩阵和视图矩阵的组合.我通常通过使用两个单独的矩阵而不是一个模型视图矩阵来解决这个问题:

  1. 模型矩阵(将模型坐标映射到世界坐标),和
  2. 视图矩阵(将世界坐标映射到摄像机坐标).

因此,只需将两个不同的矩阵分别传递给顶点着色器.你可以通过定义来做到这一点

uniform mat4 view_matrix;
uniform mat4 model_matrix;
Run Code Online (Sandbox Code Playgroud)

在顶点着色器的开头.然后代替ftransform(),说:

gl_Position = gl_ProjectionMatrix * view_matrix * model_matrix * gl_Vertex;
Run Code Online (Sandbox Code Playgroud)

在主程序中,您必须为这两个新矩阵写入值.首先,要获取视图矩阵,请使用glLoadIdentity(),glTranslate(),glRotate()或gluLookAt()进行相机变换,或者按照您通常的方式进行相机变换,然后调用glGetFloatv(GL_MODELVIEW_MATRIX,&array); 为了将矩阵数据提供给数组.其次,以类似的方式,获取模型矩阵,也调用glLoadIdentity(); 并使用glTranslate(),glRotate(),glScale()等进行对象转换,最后调用glGetFloatv(GL_MODELVIEW_MATRIX,&array); 从OpenGL中获取矩阵数据,以便将其发送到顶点着色器.特别要注意,在开始转换对象之前需要调用glLoadIdentity().通常,您将首先变换相机然后变换对象,这将导致一个矩阵同时执行视图和模型功能.但是因为你正在使用单独的矩阵,你需要在使用glLoadIdentity()进行相机变换后重置矩阵.

gl_FragCoord是像素坐标而不是世界坐标.


uof*_*ofc 11

或者你可以将z坐标除以w坐标,这基本上与透视投影无关; 给你原始的世界坐标.

即.

depth = gl_FragCoord.z / gl_FragCoord.w;
Run Code Online (Sandbox Code Playgroud)

当然,这只适用于非剪裁坐标.

但是谁还关心被剪裁的?