当前位置: 首页 > 知识库问答 >
问题:

opengl 4 中每个顶点照明问题

周墨一
2023-03-14

我有一个由只有 8 个顶点的立方体组成的模型,并且每个顶点定向照明都遇到了问题。不是一次照亮整个模型,而是像这样单独照亮每个立方体。

这是我的顶点着色器:

layout(location = 0)in vec3 vp;
layout(location = 1)in vec3 color;
layout(location = 2)in vec3 normal;

out vec3 fColor;

uniform mat4 model;
uniform mat3 nm;
uniform mat3 partNM;
uniform mat4 modelPart;
uniform mat4 view;
uniform mat4 projection;

void main () {
    gl_Position = modelPart * vec4(vp, 1.0f);
    gl_Position = model * gl_Position;
    gl_Position = view * gl_Position;
    gl_Position = projection * gl_Position;

    mat3 normalMatrix =  partNM*nm;
    vec3 normalDirection = normalize(normalMatrix*normal);
    vec3 lightDirection = normalize(vec3(-1.0, 1.0, -1.0));

    vec3 diffuseReflection = clamp(dot(normalDirection, lightDirection),0.0,1.0);
    fColor = color+diffuseReflection;
}

和我的片段着色器:

in vec3 fColor;
out vec4 frag_colour;

void main () {
    frag_colour = vec4(fColor.xyz,1.0);
}

这是我用来设置普通矩阵的函数:

void Shader::setNormalMatrix(string name,glm::mat4 matrix) {
    glm::mat3 nm = glm::transpose(glm::inverse(glm::mat3(matrix)));
    unsigned int location = glGetUniformLocation(program, name.c_str());
    glUniformMatrix3fv(location, 1, false, &nm[0][0]);
}

以及为我的立方体生成顶点和法线的函数:

std::vector<float> Cube::createCube(float size,float x,float y,float z,float r, float g, float b) {
    VertexType points[8];

    points[0].x = (x*size)+0.0f;
    points[0].y = (y*size)+0.0f;
    points[0].z = (z*size)+size;
    points[0].nx = 0.577350; 
    points[0].ny = 0.577350;
    points[0].nz = -0.577350;
    points[0].r = r;
    points[0].g = g;
    points[0].b = b;

    points[1].x = (x*size)+size;
    points[1].y = (y*size)+0.0f;
    points[1].z = (z*size)+size;
    points[1].nx = -0.577350; 
    points[1].ny = 0.577350;
    points[1].nz = -0.577350;
    points[1].r = r;
    points[1].g = g;
    points[1].b = b;

    points[2].x = (x*size)+size;
    points[2].y = (y*size)+size;
    points[2].z = (z*size)+size;
    points[2].nx = -0.577350;
    points[2].ny = -0.577350;
    points[2].nz = -0.577350;
    points[2].r = r;
    points[2].g = g;
    points[2].b = b;

    points[3].x = (x*size)+0.0f;
    points[3].y = (y*size)+size;
    points[3].z = (z*size)+size;
    points[3].nx = 0.577350; 
    points[3].ny = -0.577350;
    points[3].nz = -0.577350;
    points[3].r = r;
    points[3].g = g;
    points[3].b = b;

    points[4].x = (x*size)+0.0f;
    points[4].y = (y*size)+0.0f;
    points[4].z = (z*size)+0.0f;
    points[4].nx = 0.577350; 
    points[4].ny = 0.577350;
    points[4].nz = 0.577350;
    points[4].r = r;
    points[4].g = g;
    points[4].b = b;

    points[5].x = (x*size)+size;
    points[5].y = (y*size)+0.0f;
    points[5].z = (z*size)+0.0f;
    points[5].nx = -0.577350; 
    points[5].ny = 0.577350;
    points[5].nz = 0.577350;
    points[5].r = r;
    points[5].g = g;
    points[5].b = b;

    points[6].x = (x*size)+size;
    points[6].y = (y*size)+size;
    points[6].z = (z*size)+0.0f;
    points[6].nx = -0.577350; 
    points[6].ny = -0.577350;
    points[6].nz = 0.577350;
    points[6].r = r;
    points[6].g = g;
    points[6].b = b;

    points[7].x = (x*size)+0.0f;
    points[7].y = (y*size)+size;
    points[7].z = (z*size)+0.0f;
    points[7].nx = 0.577350; 
    points[7].ny = -0.577350;
    points[7].nz = 0.577350;
    points[7].r = r;
    points[7].g = g;
    points[7].b = b;
    std::vector<float> rPoint;
    for(VertexType p:points) {
        rPoint.push_back(p.x);
        rPoint.push_back(p.y);
        rPoint.push_back(p.z);
        rPoint.push_back(p.r);
        rPoint.push_back(p.g);
        rPoint.push_back(p.b);
        rPoint.push_back(p.nx);
        rPoint.push_back(p.ny);
        rPoint.push_back(p.nz);
    }
    return rPoint;
}

模型分为几个部分,这就是为什么我有两个正态矩阵和模型矩阵;一个用于整个模型,一个用于模型的单个部分。我的代码是否有问题,或者我是否需要使用每个片段照明来修复此错误?

共有2个答案

邵君植
2023-03-14

原因是您将每个多维数据集呈现为单独的模型。因此,着色器将为每个模型运行一次,在您的情况下,每个多维数据集运行一次。要解决此问题,您需要将整个模型(机器人)渲染为一个模型,具有一组顶点,而不是一组立方体。

臧增
2023-03-14

您的问题是网格的拓扑。在立方体的一角,3张面相遇。这些面孔中的每一个都有不同的正常状态。这会在法线拓扑中造成不连续性。或者用更简单的术语来说。每个角必须使用 3 个顶点,每个面一个顶点,面法线指向正确的方向。

当你在它的时候,你可以删除那些无论如何都不可见的立方体面。

 类似资料:
  • 我怎样才能找到一个有向图中的所有顶点,这样每一个顶点都可以从这个顶点到达呢?现在我只能“发明”O(v^3)ALGO--从每个顶点得到一个DFS/BFS,但我确信,有一个更快的方法来解决这个问题。 谢谢你!

  • 我正在用纯Java创建一个2D自上而下的平铺游戏,现在我正在尝试实现一种实现照明的方法。 首先,关于如何渲染的一些细节:有一个screen类处理所有渲染。像素被放入一个数组中,该数组使用和。 我现在做照明的方法是通过创建第二个数组来保存所有应该从实际像素中减去的亮度。我试着只使用从到的浮点来表示RGB强度。 例如,环境照明为0.3f。我所做的是一个像素到像素的操作,对于将要绘制的每个像素,其RGB

  • 我正在尝试学习如何处理VBO(VertexBufferObjects),但我不能比顶点数组更进一步。我遵循了一些关于这个主题的基本教程,每一个教程都有不同的方式,使我很难理解和执行。 问题:使用进行呈现应该与立即模式下的呈现相同。所以我尝试用songho.ca测试代码,但我得到的只是本机代码中的JVM崩溃。问谷歌一点帮助都没有,因为这种方法的几十个变种。但我假设我的参数是主要问题。 以下是我目前得

  • 前面两节课讲解到了顶点位置坐标数据、顶点颜色数据,这节课讲解第三种顶点数据:顶点法向量。 如果你有初高中物理的光学基础,应该会有漫反射、镜面反射的概念。比如太阳光照在一个物体表面,物体表面与光线夹角位置不同的区域明暗程度不同,WebGL中为了计算光线与物体表面入射角,你首先要计算物体表面每个位置的法线方向,在Threejs中表示物体的网格模型Mesh的曲面是由一个一个三角形构成,所以为了表示物体表

  • 本章介绍如何使用JOGL将光照效果应用于对象。 要设置光照,最初使用glEnable()方法启用光照。 然后使用GLLightingFunc接口的GLLightingFunc glLightfv(int light, int pname, float[] params, int params_offset)方法为GLLightingFunc 。 该方法有四个参数。 下表描述了gllightfv()

  • 下面的堆栈溢出问题 我尝试了在语句中使用两个重复的多个构造,但无法为每个起始顶点获得独立的。我也在使用平台,因此它限制了Gremlin的使用,其中不允许使用循环/脚本。所有gremlin查询必须以并由与链接在一起的命令组成 https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-differences.ht

  • 本文向大家介绍javascript实现了照片拖拽点击置顶的照片墙代码,包括了javascript实现了照片拖拽点击置顶的照片墙代码的使用技巧和注意事项,需要的朋友参考一下 演示图 styles.css drag.js picwall.html 所用到的图片 以上所述就是本文的全部内容了,希望能够对大家熟练掌握javascript有所帮助。

  • 请解释一下算法。 谢了。