I'm pretty new to shaders and I have trouble understanding what can be done what cannot. For example, I have a 3d voxel terrain. Each vertex has 3 info: its position, its color, and its normal. The position is pretty much unique to each vertex, but they are only 6 normals possible, left right up down forward backward, and 256 different colors in my game. So I tried to create a const array in my vertexShader and put the 6 normals in there and then instead of using 3 bytes for each vertex to store the normals only using 1 to store the index to look at. However, this is not working because arrays indices can only be constant. I also tried to test if the normal = 0 then the value is normals[0], etc.. butit didn't work either.
My question is: How can I store recurrent data, and then retrieve it by storing indices in my buffers instead of the said data?
EDIT: I forgot to mention what behavior I have: when passing a "in" variable as an index for the array this is automatically converted to the 0 index, and when testing the value of the "in" and assigning the correct index, I have strange artifacts everywhere.
#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
}
EDIT 2:
So after changing glVertexAttribPointer to glVertexAttribIPointer, I still have big artifacts so I'll post the code and the result:
Method called to create the normals 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);
}
Vertex shader:
#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);
}
Result:
Final Edit: I forgot changing the size of the vertexarray from 3 to 1 so now everything works fine
glVertexAttribPointer
– Rabbid76