首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLSL:如何获得像素x,y,z的世界位置?

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

Stack Overflow用户
提问于 2011-02-04 15:13:50
回答 4查看 51.9K关注 0票数 28

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

我在我的碎片着色器里试过这个:

代码语言:javascript
复制
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;
}

但是,似乎颜色的变化取决于我的相机角度/位置,我如何使和弦独立于我的相机位置/角度?

这是我的顶点着色器:

代码语言:javascript
复制
varying vec4 verpos;

void main(){
    gl_Position = ftransform();
    verpos = gl_ModelViewMatrix*gl_Vertex;
}

Edit2:换了标题,所以我想要世界和弦,而不是屏幕和弦!

Edit3:添加了我的完整代码

EN

回答 4

Stack Overflow用户

发布于 2011-02-04 15:18:54

在顶点着色器中,您有gl_Vertex (或者如果您不使用固定的管道),它是一个顶点在模型坐标中的位置。将模型矩阵乘以gl_Vertex,就可以得到世界坐标中的顶点位置。将其赋值给一个可变的变量,然后在片段着色器中读取它的值,您将得到片段在世界坐标中的位置。

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

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

因此,只需将两个不同的矩阵分别传递到顶点着色器。您可以通过定义

代码语言:javascript
复制
uniform mat4 view_matrix;
uniform mat4 model_matrix;

在你的顶点着色器的开头。然后,不要使用ftransform(),比如:

代码语言:javascript
复制
gl_Position = gl_ProjectionMatrix * view_matrix * model_matrix * gl_Vertex;

在主程序中,必须向这两个新矩阵写入值。首先,要获取视图矩阵,可以使用glLoadIdentity()、glTranslate()、glRotate()或gluLookAt()进行相机转换,或者按照通常的方式进行相机转换,然后调用glGetFloatv(GL_MODELVIEW_MATRIX & array );以便将矩阵数据传递到数组中。其次,以类似的方式获取模型矩阵,也调用glLoadIdentity();使用glTranslate()、glRotate()、glScale()等进行对象转换,最后调用glGetFloatv(GL_MODELVIEW_MATRIX &array);从OpenGL中获取矩阵数据,这样就可以将其发送到顶点着色器。特别要注意的是,在开始转换对象之前,需要调用glLoadIdentity()。通常,您会首先转换相机,然后转换对象,这将产生一个矩阵,它同时完成视图和模型功能。但是,由于您使用的是单独的矩阵,所以需要在使用glLoadIdentity()进行相机转换后重置矩阵。

gl_FragCoord是像素坐标,而不是世界坐标。

票数 33
EN

Stack Overflow用户

发布于 2012-02-16 23:36:05

或者,你可以把z坐标除以w坐标,它本质上不做透视投影,给出你原来的世界坐标。

即。

代码语言:javascript
复制
depth = gl_FragCoord.z / gl_FragCoord.w;

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

但谁会在乎剪裁的呢?

票数 13
EN

Stack Overflow用户

发布于 2017-07-28 17:39:16

您需要将World/Model矩阵作为统一的矩阵传递给顶点着色器,然后将其乘以顶点位置,然后将其作为可变值发送到片段着色器:

代码语言:javascript
复制
/*Vertex Shader*/

layout (location = 0) in vec3 Position

uniform mat4 World;
uniform mat4 WVP;

//World FragPos
out vec4 FragPos;

void main()
{
 FragPos = World * vec4(Position, 1.0);
 gl_Position = WVP * vec4(Position, 1.0);
}

/*Fragment Shader*/

layout (location = 0) out vec4 Color;

... 

in vec4 FragPos

void main()
{
 Color = FragPos;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4899555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档