[OpenGL]Shader初识

Basic
class Basic : public SubTestBed
{
public:
    Basic(const std::string shaderPath) : SubTestBed(shaderPath) { }

    virtual void Render() override
    {
        m_Renderer.Draw(*m_VA, 3, *m_Shader);
    }
};
#Shader Vertex
#version 330 core  
layout(location = 0) in vec4 a_position;  
void main()                                
{                                          
   gl_Position = a_position;               
}

#Shader Fragment
#version 330 core   
out vec4 fragColor;  
void main()                                
{                                          
   fragColor = vec4(0.3, 0.4, 0.5, 1.0);   
};
Uniform
class Uniform : public SubTestBed
{
public:
    Uniform(const std::string shaderPath) : SubTestBed(shaderPath) { }

    virtual void Render() override
    {
        m_Renderer.Draw(*m_VA, 3, *m_Shader);
        double timeValue = glfwGetTime();
        float greenValue = (float)((sin(timeValue) / 2) + 0.5);
        m_Shader->SetUniform4f("u_Color", 0.0f, greenValue, 0.0f, 1.0f);
    }
};
#Shader Vertex
#version 330 core  

layout(location = 0) in vec4 a_position;  

void main()                                
{                                          
   gl_Position = a_position;               
}


#Shader Fragment
#version 330 core   

out vec4 fragColor;  
uniform vec4 u_Color;

void main()                                
{                                          
   fragColor = u_Color;
};

 

顶点颜色插值
class Interpolation : public SubTestBed
{
public:
    Interpolation(const std::string shaderPath) : SubTestBed(shaderPath) { }

    virtual void Setup() override
    {
        float vertices[] = {
            -0.5f, -0.5f, 0,  1.0f, 0.0f, 0.0f,
            +0.5f, -0.5f, 0,  0.0f, 1.0f, 0.0f,
            +0.5f, +0.5f, 0,  0.0f, 0.0f, 1.0f,
            -0.5f, +0.5f, 0,  1.0f, 0.0f, 1.0f
        };

        unsigned int indices[] = {
            0, 1, 2,
            2, 3, 0
        };

        m_VA = new VertexArray();
        m_VB = new VertexBuffer(vertices, sizeof(vertices));
        VertexBufferLayout layout;
        layout.Push<float>(3);
        layout.Push<float>(3);
        m_VA->AddBuffer(*m_VB, layout);

        m_IB = new IndexBuffer(indices, 6);
        m_VB->UnBind();
        m_VA->UnBind();
        m_IB->UnBind();
    }

    virtual void Render() override
    {
        m_Renderer.Draw(*m_VA, *m_IB, *m_Shader);
    }

};
#Shader Vertex
#version 330 core

layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_color;

out vec3 vertexColor;

void main()
{
gl_Position = a_position;
vertexColor = a_color;
}

#Shader Fragment
#version 330 core

out vec4 fragColor;

in vec3 vertexColor;

void main()
{
fragColor = vec4(vertexColor, 1.0);
}

 

练习题1: 修改顶点着色器让三角形上下颠倒

// CPP代码使用Basic的即可

// 使用Basic.shader然后更改这一句代码即可
gl_Position = vec4(a_position.x, -a_position.y, a_position.z, 1.0); // 将y乘以-1即可

 

练习题2: 使用uniform定义一个水平偏移量,在顶点着色器中使用这个偏移量把三角形移动到屏幕右侧

本人对此题做了一个扩展,使用uniform让其移动到右边

class MoveToRight : public SubTestBed
{
    float speed = 0.2f;
public:
    MoveToRight(const std::string shaderPath) : SubTestBed(shaderPath) { }

    virtual void Render() override
    {
        m_Renderer.Draw(*m_VA, 3, *m_Shader);
        double timeValue = glfwGetTime();
        m_Shader->SetUniform1f("f_offsetX", (float)timeValue * speed);
    }

};
#Shader Vertex
#version 330 core

layout(location = 0) in vec4 a_position;

uniform float f_offsetX;

void main()
{
    gl_Position = vec4(a_position.x + f_offsetX, a_position.y, a_position.z, 1.0);
}


#Shader Fragment
#version 330 core

out vec4 fragColor;

void main()
{
    fragColor = vec4(0.3, 0.4, 0.5, 1.0);
};

 

练习题3: 使用out关键字把顶点位置输出到片段着色器,并将片段的颜色设置为与顶点位置相等。做完这些后,尝试回答下面的问题:为什么在三角形的左下角是黑的?

// CPP代码使用Basic的即可

#Shader Vertex
#version 330 core

layout(location = 0) in vec4 a_position;

out vec4 vertexPosition;

void main()
{
    gl_Position = a_position;
    vertexPosition = a_position; // 把顶点位置传递给fragment shader
}


#Shader Fragment
#version 330 core

out vec4 fragColor;

in vec4 vertexPosition;

void main()
{
    fragColor = vertexPosition; // 使用传入的顶点位置作为颜色输出
}

解释:

左下角是(-0.5. -0.5, 0)点 中上角是(0, 0.5, 0)点 右下角是(0.5. -0.5, 0)点
对应颜色(0, 0, 0) 所以是黑色的 对应颜色(0, 0.5, 0) 所以是50%的绿色的 对应颜色(0.5, 0, 0) 所以是50%的红色的

 

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像