【发布时间】:2020-09-26 10:49:34
【问题描述】:
我对着色器还很陌生,我很难理解可以做什么不能做什么。例如,我有一个 3d 体素地形。每个顶点有 3 个信息:它的位置、它的颜色和它的法线。每个顶点的位置几乎都是独一无二的,但它们只有 6 个可能的法线,从左到右从前到后,在我的游戏中有 256 种不同的颜色。因此,我尝试在我的 vertexShader 中创建一个 const 数组并将 6 个法线放入其中,而不是使用每个顶点的 3 个字节来存储法线,仅使用 1 来存储要查看的索引。但是,这不起作用,因为数组索引只能是常数。我还尝试测试如果 normal = 0 那么值是 normals[0] 等等。但它也不起作用。
我的问题是:如何存储循环数据,然后通过将索引存储在缓冲区而不是所述数据中来检索它?
编辑: 我忘了提到我有什么行为: 当传递一个“in”变量作为数组的索引时,它会自动转换为 0 索引,并且在测试“in”的值并分配正确的索引时,我到处都有奇怪的工件。
#version 400
const vec4 normals[6](vec4(1,0,0,0),....)
in int normal;
void main(void){
normals[normal] ---> always returning the first element of the array
}
编辑 2:
所以在将 glVertexAttribPointer 更改为 glVertexAttribIPointer 后,我仍然有很大的工件,所以我将发布代码和结果:
调用创建法线 vbo 的方法:
private void storeDataInAttributeList(int attributeNumber, int coordsSize,byte[] data) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,vboID);
ByteBuffer buffer = storeDataInByteBuffer(data);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL30.glVertexAttribIPointer(attributeNumber, coordsSize, GL11.GL_BYTE, 0,0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
顶点着色器:
#version 400 core
const vec4 normals[] = vec4[6](vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(-1,0,0,0),vec4(0,-1,0,0),vec4(0,0,-1,0));
in vec3 position;
in vec3 color;
in int normal;
out vec4 color_out;
out vec3 unitNormal;
out vec3 unitLightVector;
out vec3 unitToCameraVector;
out float visibility;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;
uniform float fogDensity;
uniform float fogGradient;
void main(void){
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
vec4 positionRelativeToCam = viewMatrix * worldPosition;
gl_Position = projectionMatrix * positionRelativeToCam;
color_out = vec4(color,0.0);
unitNormal = normalize((transformationMatrix * normals[normal]).xyz);
unitLightVector = normalize(lightPosition - worldPosition.xyz);
unitToCameraVector = normalize((inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz);
visibility = clamp(exp(-pow(length(positionRelativeToCam.xyz)*fogDensity,fogGradient)),0.0,1.0);
}
结果:
最终编辑:我忘记将顶点数组的大小从 3 更改为 1,所以现在一切正常
【问题讨论】:
-
数组的类型是什么?。 OpenGL Shading Language 4.00 Specification "数组元素使用类型为 int 或 uint 的表达式访问。" - 除了采样器:“在着色器中聚合成数组的采样器(使用方括号 [])只能使用动态统一的积分表达式进行索引”
-
它是一个 vec4 数组,我将法线索引存储在字节缓冲区中,然后在着色器中转换为 int
-
您是否在着色器中指定了版本。你如何指定积分索引属性?您必须显示相关代码。问题可能是您使用了 glVertexAttribPointer 而不是 glVertexAttribIPointer。见
glVertexAttribPointer -
我在将 glVertexAttribPointer 更改为 glVertexAttribIPointer 后编辑了我的帖子
标签: java opengl glsl shader lwjgl