GLSL将循环数据存储在常量数组中

问题描述

我对着色器还很陌生,我很难理解可以做什么而不能做什么。例如,我有一个3D体素地形。每个顶点都有3个信息:其位置,颜色和法线。每个顶点的位置几乎都是唯一的,但是在我的游戏中,只能有6个法线,从左到右,从前到后,向后倾斜。因此,我尝试在vertexShader中创建一个const数组,并将6个法线放入其中,而不是为每个顶点使用3个字节来存储法线,而仅使用1个来存储要查看的索引。但是,这不起作用,因为数组索引只能是常量。我还尝试测试normal = 0时的值是否是normals [0]等。但是它也不起作用。

我的问题是:如何存储循环数据,然后通过将索引而不是所述数据存储在缓冲区中来检索它?

编辑: 我忘了提及我的行为: 当将“ in”变量作为数组的索引传递时,该变量将自动转换为0索引,并且当测试“ in”的值并分配正确的索引时,到处都是奇怪的工件。

#version 400

const vec4 normals[6](vec4(1,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);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER,0);
    }

顶点着色器:


#version 400 core

const vec4 normals[] = vec4[6](vec4(1,vec4(0,1,vec4(-1,-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,1.0)).xyz - worldPosition.xyz);
    
    visibility = clamp(exp(-pow(length(positionRelativetoCam.xyz)*fogDensity,fogGradient)),1.0);
}

结果:

Result

最终编辑:我忘了将顶点数组的大小从3更改为1,所以现在一切正常

解决方法

具有整数数据类型的顶点属性可以指定glVertexAttribIPointer(专注于I)而不是glVertexAttribPointer。参见PCA in ML
type 参数未指定属性的类型。 type 参数仅指定源数据数组的类型。由glVertexAttribPointer指定的属性数据将转换为浮点数。