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

如何在 LWJGL 中使用索引和顶点缓冲区实现平面着色?

富钧
2023-03-14

我目前正在开发一个程序,在Java的LWJGL框架中以3D方式显示建筑物和地形,据我所知,这与OpenGL非常相似。我试图用平面阴影区分建筑物的侧面。例如,我的程序生成的立方体应该如下所示:

为了实现这一点,我尝试在这里实现该方法:https://gamedev.stackexchange.com/questions/152991/how-can-i-calculate-normals-using-a-vertex-and-index-buffer.

这似乎是顶点着色,它以某种梯度对每个像素着色。我的实现目前看起来像这样:

显然这看起来不像我想要的。以下是我的顶点和碎片着色器:

#version 150

in vec3 position;
in vec2 textureCoordinates;
in vec3 normal;

out vec2 pass_textureCoordinates;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

void main(void){

    vec4 worldPosition = transformationMatrix * vec4(position, 1.0);

    gl_Position = projectionMatrix * viewMatrix * worldPosition;
    pass_textureCoordinates = textureCoordinates;

    surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
    toLightVector = lightPosition - worldPosition.xyz;
    toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;

}
#version 150

in vec2 pass_textureCoordinates;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;

out vec4 out_Color;

uniform sampler2D modelTexture;
uniform vec3 lightColour;
uniform float shineDamper;
uniform float reflectivity;

void main(void){

    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitLightVector = normalize(toLightVector);

    float nDotl = dot(unitNormal, unitLightVector);
    float brightness = max(nDotl, 0.7);
    vec3 diffuse = brightness * lightColour;

    vec3 unitVectorToCamera = normalize(toCameraVector);
    vec3 lightDirection = -unitLightVector;
    vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

    float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
    specularFactor = max(specularFactor, 0.0);
    float dampedFactor = pow(specularFactor, shineDamper);
    vec3 finalSpecular = dampedFactor * reflectivity * lightColour;


    out_Color = vec4(diffuse, 1.0) * texture(modelTexture,pass_textureCoordinates) + vec4(finalSpecular, 1.0);

}

我如何以编程方式为平面着色创建法线数组?

共有1个答案

孟茂
2023-03-14

“渐变排序”是由镜面反射高光引起的。如果法向量垂直于立方体的表面,那么朗伯漫射光会给你一个平坦的外观。
您所要做的就是将均匀变量反射率初始化为 0.0。(实际上这是默认值)。

可以通过片段着色器中的偏导数(< code>dFdx,< code>dFdy)或几何着色器中的叉积来计算面法线向量。但是这种选择会导致质量和速度的损失。

请参阅
从片段着色器中如何获取表面-不是顶点-法线
3D对象以看起来像2D对象的方式着色

 类似资料:
  • 我目前正在使用LWJGL / OpenGL创建一个2D,自上而下的游戏,但是在绘制实体之后,在使用顶点缓冲区对象渲染实体后,在让它们四处移动的过程中,我遇到了一些问题。这是渲染线程的 run() 方法,以及设置方法: 实体从抽象超类继承这些方法来设置 VBO 并绘制实体(呈现线程中的 drawEntities 方法仅调用该方法,实体更新方法(见下文),而 setUpEntities 调用 setU

  • 我在Android 3.2上尝试通过OpenGL ES 2.0绘制一个形状。我可以按照预期使用DrawArray和FloatBuffer进行场景渲染,但不能通过glGenBuffers和vbo/ibo。 以下是我使用的一些片段,去掉了不相关的部分 上面是我创建数组的代码。下面是我的渲染代码。 我知道我的顶点浮动缓冲区工作正常,因为如果我用下面的代码替换上面的代码,它会按预期工作: 当我正在调试以找

  • 我正在努力理解这两个,如何使用它们,以及它们是如何联系的。假设我想创建一个简单的地形和一个有纹理的立方体。对于这两个对象,我有三角形、顶点的数组,对于立方体,我有一个包含纹理数据的数组。我的问题是:我如何使用VAOs和VBOs来创建和呈现这两个? null

  • 我正在尝试从ArrayList读取并创建VBO,然后对其进行渲染。问题是我只是渲染了一个空白屏幕。当我立即渲染时,一切都很好;只有现在VBO的才不起作用。 游戏循环如下所示,相机调用glTranslate和glRotate函数。 渲染方法: 阵列列表具有顶点和链接的颜色。每个体素将其顶点添加到ArrayList(而不是立即渲染)。

  • 两者都是序列化库,由谷歌开发人员开发。他们之间有什么大的区别吗?将使用协议缓冲区的代码转换为使用FlatBuffers需要大量工作吗?

  • null null null 在原始OpenGL中这样做虽然简单,但如果为单个缓冲区设置了许多属性,就会失去控制。我想我可以简化调用属性函数的过程,使用具有如下API的可变模板: 然而,这是不可行的,因为模板参数(AFAIK)实际上不是可变的,而是只能使参数可变。我不想使用函数参数的原因是,我希望能够输入C++关键字和,它们不能用作参数。我目前的解决方案是将参数与重复基本类型的枚举一起使用,例如和