Opengl 顶点/片段着色器中的坐标

Opengl 顶点/片段着色器中的坐标,opengl,opengl-es,fragment-shader,vertex-shader,Opengl,Opengl Es,Fragment Shader,Vertex Shader,我想对网格的每个实例执行每像素操作。我发现了一个名为gl_FragCoord的变量,但它的坐标似乎是屏幕坐标。我希望能够访问局部坐标,以便能够进行更改,从而独立地影响每个网格。我希望有一些坐标,例如,(0.0,0.0)坐标是片段的左上角,(1.0,1.0)是右下角 可以将视口作为一个统一体传递,并将框架坐标X除以视口W,将Y框架坐标除以视口H使用和附加顶点属性来构造三角形局部坐标系: #include <GL/glew.h> #include <GL/freeglut.h>

我想对网格的每个实例执行每像素操作。我发现了一个名为gl_FragCoord的变量,但它的坐标似乎是屏幕坐标。我希望能够访问局部坐标,以便能够进行更改,从而独立地影响每个网格。我希望有一些坐标,例如,(0.0,0.0)坐标是片段的左上角,(1.0,1.0)是右下角

可以将视口作为一个统一体传递,并将框架坐标X除以视口W,将Y框架坐标除以视口H

使用和附加顶点属性来构造三角形局部坐标系:

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <vector>
using namespace std;

#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp> 
#include <glm/gtx/transform.hpp>
using namespace glm;

void CheckStatus( GLuint obj )
{
    GLint status = GL_FALSE;
    if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
    if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    GLchar log[ 1 << 16 ] = { 0 };
    if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
    if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
    std::cerr << log << std::endl;
    exit( -1 );
}

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

GLuint LoadProgram( const char* vert, const char* geom, const char* frag )
{
    GLuint prog = glCreateProgram();
    if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
    if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
    if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( prog );
    CheckStatus( prog );
    return prog;
}

#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL
(
    120,
    uniform mat4 u_projection;
    uniform mat4 u_modelview;

    attribute vec3 a_pos;
    attribute vec3 a_bc;

    varying vec3 v_bc;

    void main()
    {
        v_bc = a_bc;
        gl_Position = u_projection * u_modelview * vec4( a_pos, 1.0 );
    }
);

const char* frag = GLSL
(
    120,
    varying vec3 v_bc;
    void main()
    {
        gl_FragColor = vec4( v_bc, 1.0 );
    }
);

struct Vertex
{
    Vertex( const vec3& pos, const vec3& bc )
        : pos( pos )
        , bc( bc )
    {}
    vec3 pos;
    vec3 bc;
};

void AddTriangle( const vec3& p1, const vec3& p2, const vec3& p3, vector< Vertex >& verts )
{
    verts.push_back( Vertex( p1, vec3( 1, 0, 0 ) ) );
    verts.push_back( Vertex( p2, vec3( 0, 1, 0 ) ) );
    verts.push_back( Vertex( p3, vec3( 0, 0, 1 ) ) );
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    double ar = w / h;
    mat4 projection = glm::ortho< float >( -2 * ar, 2 * ar, -2.0, 2.0, -1.0, 1.0 );

    mat4 modelview = mat4( 1.0 );

    // prepare to render
    static GLuint prog = LoadProgram( vert, NULL, frag );
    glUseProgram( prog );

    GLint proj = glGetUniformLocation( prog, "u_projection" );
    glUniformMatrix4fv( proj, 1, GL_FALSE, glm::value_ptr( projection ) );

    GLint model = glGetUniformLocation( prog, "u_modelview" );
    glUniformMatrix4fv( model, 1, GL_FALSE, glm::value_ptr( modelview) );

    vector< Vertex > verts;
    AddTriangle
        (
        vec3( 0, 0, 0 ),
        vec3( 1, 0, 0 ),
        vec3( 1, 1, 0 ),
        verts
        );

    GLint pos = glGetAttribLocation( prog, "a_pos" );
    glVertexAttribPointer( pos, 3, GL_FLOAT, GL_FALSE, sizeof( Vertex ), &verts[0].pos );
    glEnableVertexAttribArray( pos );

    GLint bc = glGetAttribLocation( prog, "a_bc" );
    glVertexAttribPointer( bc, 3, GL_FLOAT, GL_FALSE, sizeof( Vertex ), &verts[0].bc );
    glEnableVertexAttribArray( bc );

    glDrawArrays( GL_TRIANGLES, 0, verts.size() );

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );
    glewInit();

    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
#包括
#包括
#包括
使用名称空间glm;
无效检查状态(GLuint obj)
{
闪烁状态=GLU FALSE;
if(glishader(obj))glGetShaderiv(obj、GL\u编译状态和状态);
if(glIsProgram(obj))glGetProgramiv(obj、GL链接状态和状态);
if(status==GL_TRUE)返回;
GLchar日志[1个顶点;
AddTriangle
(
vec3(0,0,0),
vec3(1,0,0),
vec3(1,1,0),
顶点
);
闪烁位置=GLGETARTIBLOCATION(程序,“a_位置”);
glvertexattributepointer(位置,3,GL_浮点,GL_假,sizeof(顶点),&verts[0].pos);
GlenableVertexAttributeArray(pos);
GLint bc=glGetAttribLocation(prog,“a_bc”);
glvertexattributepointer(bc,3,GL_FLOAT,GL_FALSE,sizeof(顶点),&verts[0].bc);
GlenableVertexAttributeArray(bc);
gldrawArray(GL_三角形,0,verts.size());
glutSwapBuffers();
}
int main(int argc,字符**argv)
{
glutInit(&argc,argv);
glutSetOption(GLUT\U操作\U打开\U窗口\U关闭,GLUT\U操作\U GLUTMAINLOOP\U返回);
glutInitDisplayMode(GLUT_RGBA | GLUT_深度| GLUT_双精度);
glutInitWindowSize(600600);
GLUT(GLUT);
glewInit();
glutDisplayFunc(显示器);
glutMainLoop();
返回0;
}
如果
v_bc==(1,0,0)
则片段位于第一个顶点上

如果
v_bc==(0,1,0)
则碎片位于第二个顶点上


如果
v_bc==(0,0,1)
然后你的片段位于第三个顶点上。

感谢你的支持和想法,我需要的是通过顶点着色器将顶点的局部位置传递给片段着色器。我们无需进行任何额外计算,因为这是顶点着色器知道的值。我仍然没有在开始时想要的值但是现在我知道了更多关于如何使用片段着色器来实现我想要的效果:)。

记住OpenGL坐标是从下到上的。所以(0.0,0.0)是左下角。OpenGL中的规范投影矩阵将生成(0.0,0.0)如左下角。如果要使其成为左上角,则需要翻转Y轴,但请注意,这将改变投影的惯用手,并且需要执行其他操作,如补偿缠绕顺序等。要清楚,通过
LOCAL
position,您指的是对象空间?即顶点所在的坐标空间在任何类型的变换之前都处于。通常顶点着色器的作用是从对象空间变换到剪辑空间…紧接着,会发生另一组变换,将这些坐标转换为规范化设备空间,最后是窗口空间。当您了解坐标的协调方式时,局部位置根本不是描述性的e变换在渲染管道中工作。是的,根据局部位置,我指的是对象空间。我真正想要的是访问对象纹理/纹理的每个像素。