OpenGL GLFW更改网格面单独颜色

zaq34kh6  于 2022-10-18  发布在  其他
关注(0)|答案(1)|浏览(207)

目前我正在渲染网格三角形,如下所示:

// draw the same polygons again
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            shader.setVec3("objectColor", obj_color);
            glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);

这段代码的问题是,我正在为整个网格设置着色器内部的对象颜色。
渲染一个面具有不同颜色的单个网格的好方法是什么?目前,我只知道如何设置顶点颜色,并将其传递给碎片着色器。
设置个人脸部颜色最常见的方法是什么?我只考虑将网格顶点复制两次,以避免顶点颜色内插。

我当前的着色器如下所示:
顶点明暗器:


# version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out vec3 FragPos;
out vec3 Normal;
out vec3 LightPos;

uniform vec3 lightPos; 

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    FragPos = vec3(view * model * vec4(aPos, 1.0));
    Normal = mat3(transpose(inverse(view * model))) * aNormal;
    LightPos = vec3(vec4(lightPos, 1.0)); // Transform world-space light position to view-space light position
   // FragPos = vec3(model * vec4(aPos, 1.0));
   //Normal = mat3(transpose(inverse(model))) * aNormal;  
   // gl_Position = projection * view * vec4(FragPos, 1.0);
}

片段着色器:


# version 330 core

out vec4 FragColor;

in vec3 FragPos;
in vec3 Normal;
in vec3 LightPos;

// extra in variable, since we need the light position in view space we calculate this in the vertex shader

uniform vec3 lightColor;
uniform vec3 objectColor;
uniform float f;
uniform float transparency;

void main()
{

   //flat shading
//   vec3 x_ = dFdx(FragPos);
//   vec3 y_= dFdy(FragPos);
//   vec3 normal_ = cross(x_, y_);
//   vec3 norm_ = normalize(normal_);

    // ambient
    float ambientStrength = 0.75;
    vec3 ambient = ambientStrength * lightColor;    

     // diffuse 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(LightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);//change "norm_" to "norm" avoid the performance warning and have unwelded view
    vec3 diffuse = diff * lightColor;

    // specular
    float specularStrength = 0.01;
    vec3 viewDir = normalize(-FragPos); // the viewer is always at (0,0,0) in view-space, so viewDir is (0,0,0) - Position => -Position
    vec3 reflectDir = reflect(-lightDir, norm);  
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor; 

    vec3 shading = (ambient + diffuse + specular)*objectColor;
    //float f = 0.75;
    float r_interpolated =  shading[0] + f * (objectColor[0] - shading[0]);
    float g_interpolated =  shading[1] + f * (objectColor[1] - shading[1]);
    float b_interpolated =  shading[2] + f * (objectColor[2] - shading[2]);

    vec3 result = vec3(r_interpolated,g_interpolated,b_interpolated);

    FragColor = vec4(result, transparency);
}
ukxgm1gy

ukxgm1gy1#

您可以使用flat内插限定符:
不会对该值进行内插。为片段着色器指定的值是该基本体的挑衅顶点的值。
顶点着色器

// [...]

layout (location = 0) in vec3 aColor;
flat out vec3 vColor;

void main()
{
    vColor = aColor;

    // [...]
}

片段着色器

// [...]

flat in vec3 vColor;

void main()
{
    FragColor = vec4(vColor, 1.0);
}

在此实现中,整个三角形基元以一种颜色呈现。如果找到用于将颜色属性指定给顶点的智能系统,则可以使用不同的颜色渲染所有三角形。例如具有指数0-1-2和1-2-3的2个转轴。顶点0的颜色属性定义第一个三角形的颜色,顶点1的颜色属性定义第二个三角形的颜色。
另一种方法是为每个三角形基元创建一个颜色数组,并将该颜色数组存储在Shader Storage Buffer Object中。使用gl_VertexID解决顶点着色器中的颜色。

layout(std430, binding = 0) buffer primitiveColors
{
    vec4 colors[];
};

void main()
{
    vColor = colors[gl_VertexID / 3];

    // [...]
}

相关问题