如何使用glsl改变顶点位置

How to change vertex position using glsl

本文关键字:顶点 位置 改变 glsl 何使用      更新时间:2023-10-16

我正在尝试根据相机位置移动对象。这是我的顶点着色器

uniform mat4 osg_ViewMatrixInverse;
void main(){
vec4 position  = gl_ProjectionMatrix * gl_ModelViewMatrix *gl_Vertex;   
vec3 camPos=osg_ViewMatrixInverse[3].xyz;
if( camPos.z >1000.0 )
  position.z = position.z+1.0;
    if( camPos.z >5000.0 )
  position.z = position.z+10.0;
if (camPos.z< 300.0 )
  position.z = position.z+300.0;
gl_Position =  position;
}

但是当相机的垂直位置小于300或大于1000时,模型就会消失,而在第二种情况下,它应该只移动一个单位。我读到关于内部的着色器坐标与世界坐标不同,这就是为什么我乘以投影和ModelView矩阵,以获得世界坐标。也许我在这一点上是错的?如果这是一个简单的问题,请原谅我,但我找不到答案。

UPDATE: camPos被转换为世界坐标,但位置不是。也许它与我使用osg_ViewMatrixInverse(通过OpenSceneGraph)来获取相机位置和内部gl_ProjectionMatrix和gl_ModelViewMatrix来获取顶点坐标的事实有关?如何将位置转换为世界坐标?

问题是您正在将位置转换为剪辑坐标(通过将gl_Vertex乘以投影和模型视图矩阵),然后对这些剪辑坐标执行世界坐标操作,这不会给出您想要的结果。

在您乘以模型视图和投影矩阵之前,简单地执行您的转换。

uniform mat4 osg_ViewMatrixInverse;
void main() {
    vec4 position = gl_Vertex;   
    vec3 camPos=osg_ViewMatrixInverse[3].xyz;
    if( camPos.z >1000.0 )
        position.z = position.z+1.0;
    if( camPos.z >5000.0 )
        position.z = position.z+10.0;
    if (camPos.z< 300.0 )
        position.z = position.z+300.0;
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * position;
}

gl_Position在clip-space中,您为任何坐标输出的值必须>= - gl_Position.W或<= gl_Position.W,否则它们将被剪切。如果一个原语的所有坐标都在这个范围之外,那么将不会绘制任何内容。这样做的原因是,在顶点着色器完成后,OpenGL将clip-space坐标除以W,生成范围为[-1,1](NDC)的坐标。

你在这里应该做的是将这些坐标添加到你的对象空间位置,然后执行从对象空间到剪辑空间的转换。三十二上校的回答已经很好地说明了如何做到这一点;我只是想解释为什么你不应该把这个偏移量应用到clip-space坐标

figure out:

uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ViewMatrix;
void main(){
    vec3 camPos=osg_ViewMatrixInverse[3].xyz;
    vec4 position_in_view_space = gl_ModelViewMatrix * gl_Vertex;
    vec4 position_in_world_space  = osg_ViewMatrixInverse * position_in_view_space;
    if( camPos.z >1000.0 )
      position_in_world_space.z = position_in_world_space.z+700.0;
    if( camPos.z >5000.0 )
      position_in_world_space.z = position_in_world_space.z+1000.0;
    if (camPos.z< 300.0 )
      position_in_world_space.z = position_in_world_space.z+200;
    position_in_view_space = osg_ViewMatrix * position_in_world_space;
    vec4 position_in_object_space = gl_ModelViewMatrixInverse * position_in_view_space;
    gl_Position = gl_ModelViewProjectionMatrix * position_in_object_space;
}

一个人需要将gl_Vertex(在对象空间坐标中)通过视图空间坐标转换为世界坐标(也许有直接转换我没有看到),然后他可以修改它们并转换回对象空间坐标