OpenGL OpenGL Bump Map -- Texture artifacts ?

This topic is 1503 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello,

I am learning OpenGL (and learning the math behind it) and I'm making a simple OBJ viewer, nothing fancy.
I have diffuse, specular and ambient light/texture working fine and now I am implementing the bump mapping.
I based my code on what I learned with the OpenGL 4.3 Redbook and "Mathematics for 3D game programming and computer graphics" book.

There is probably something I didn't understand correctly, I just hope you will be able to help me :)

Anyway this is the result I get (from a free asset used just for testing -- the results are fine in blender) :

As you can see there is some artifacts but it must be coming from my tangent space.

PS : Yes, this model is not just a plane.

This is the diffuse texture and the bump map :

    void main() {
vec3 normalDirection = normalize(tangenteSpace*(texture2D( bump_tex, f_texcoord ).rgb*2.0 - 1.0));
//vec3 normalDirection = normalize(mat3(invTransp)*vertNormal);
vec3 viewDirection = tangenteSpace*normalize(vec3(invView * vec4(0.0, 0.0, 0.0, 1.0) - position));

float attenuation = 1.0;//none
vec3 vertToLightSource = vec3(light.position - position*light.position.w);
float distance = length(vertToLightSource);
attenuation = mix(1.0,1.0/(light.constantAttenuation +
light.linearAttenuation *distance +
vec3 lightDirection = tangenteSpace*(vertToLightSource/distance);

//spotlight if spotCutoff <= 90
float clampedCosine = max(0.0, dot(-lightDirection, normalize(light.spotDirection)));
float tempMix = mix(attenuation * pow(clampedCosine, light.spotExponent),0.0,clampedCosine < cos(light.spotCutoff * 3.14159 / 180.0));//if outside of spotlight nothing
attenuation = mix(attenuation,tempMix,light.spotCutoff <= 90.0);

//should there be any attenuation ?
attenuation = mix(attenuation,1.0,light.position.w);

//------------------------------ ambiant light
vec3 ambientLight = vec3(ambientScene)*vec3(mat.Ka);

//------------------------------ specular light
//get the reflection
vec4 specularMapPixel = texture2D(spec_tex, f_texcoord).rgba;
vec3 specularColor = specularMapPixel.rgb;
float shininess = specularMapPixel.a;
vec3 specularReflection = mix(
attenuation * vec3(light.specular) * vec3(mat.Ks)* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)),mat.Ns*shininess) *specularColor.rgb,
vec3(0.0, 0.0, 0.0),
dot(normalDirection, lightDirection) < 0.0
);

vec3 diffuseReflection = attenuation*
vec3(light.diffuse)*vec3(mat.Kd)
*max(0.0,dot(normalDirection,lightDirection));

vec4 Color = vec4(vec4(specularReflection,1.0) + vec4(ambientLight,1)*texture2D(amb_tex, f_texcoord) + vec4(diffuseReflection,1.0)*texture2D(dif_tex, f_texcoord));

FragColor = Color;
}

    void main()
{
//comnpute tangent space
tangenteSpace[0] = mat3(mv)*normalize(tangent.xyz);
tangenteSpace[2] = mat3(mv)*normalize(vertNormal);
tangenteSpace[1] = mat3(mv)*normalize(cross(tangenteSpace[0],tangenteSpace[2])*tangent.w);
tangenteSpace = transpose(tangenteSpace);

//position in world space
position = m * vertCoord;
f_texcoord = vec2(texCoord);

gl_Position = mvp * vertCoord;
}

Share on other sites

I'd say that it isn't the bump map what you need - I think that your shader code expects a normal map (which can be derived from the bump map). Typically 3d modelling softwares can work on both (normal map or height map).

You can either use some filter in the shader to produce the surface normal or use an offline tool to convert the height map into a normal map.

Cheers!

 this image shows the difference between height map and a normal map : http://www.3dkingdoms.com/CW3D/Doc/displacement-maps.jpg

Edited by kauna

Share on other sites

Thank you about that I used a software to generate a nice normal I really got the 2 confuses

But now I see why there is so much issues, it seems that only the diffuse texture (the first loaded into the shader) is active. By that I mean that I tried to apply the other textures as a diffuse texture and I always saw the same results : The "normal" diffuse texture.

I made some change recently and without noticing it I put the glActiveTexture ABOVE the glBindTexture. I hope that is my problem.

Edit : now only the spec texture is used. Weird.

Edited by rXpSwiss

Share on other sites

Can you post your code for binding the textures and setting the active texture? Have you specified which texture unit each of the sampler2D uniforms should use?

Share on other sites

Sure I can do that.

void Model::draw(glm::mat4 view, glm::mat4 projection)
{

//texture diffuse
if (_mtl->getDiffuseTextureMap())
{
glBindTexture(GL_TEXTURE_2D, _difTextureID);
glActiveTexture(GL_TEXTURE0);
glUniform1i(myTexture, 0);
}

//texture ambient
if (_mtl->getAmbientTextureMap())
{
glBindTexture(GL_TEXTURE_2D, _ambTextureID);
glActiveTexture(GL_TEXTURE1);
glUniform1i(myTexture, 1);
}

//texture specular
if (_mtl->getSpecularTextureMap())
{
glBindTexture(GL_TEXTURE_2D, _specTextureID);
glActiveTexture(GL_TEXTURE2);
glUniform1i(myTexture, 2);
}

//texture normal
if (_mtl->getBumpTextureMap())
{
glBindTexture(GL_TEXTURE_2D, _bumpTextureID);
glActiveTexture(GL_TEXTURE3);
glUniform1i(myTexture, 3);
}

//model
_modelMat = _translateMat * _scaleMat * _rotateMat * _modelMat;
glm::mat4 mv = view * _modelMat;
glm::mat4 mvp = projection * view * _modelMat ;
glBindBuffer(GL_ARRAY_BUFFER, _vboID);

glUniformMatrix4fv(mID, 1, GL_FALSE, &_modelMat[0][0]);

glUniformMatrix4fv(mvID, 1, GL_FALSE, &mv[0][0]);

glUniformMatrix4fv(mvpID, 1,GL_FALSE, &mvp[0][0]);

glUniformMatrix4fv(itID, 1, GL_FALSE, &glm::transpose(glm::inverse(_modelMat))[0][0]);

glUniformMatrix4fv(ivID, 1, GL_FALSE, &glm::inverse(view)[0][0]);

//send material info
glUniform3fv(matID, 1, &_mtl->getDiffuseColor()[0]);

glUniform3fv(matID, 1, &_mtl->getAmbientColor()[0]);

glUniform3fv(matID, 1, &_mtl->getSpecularColor()[0]);

glUniform1f(matID, _mtl->getSpecularCoeff());

glDrawArrays(GL_TRIANGLES, 0, _vertices.size());

//reset transform matrix
_rotateMat = glm::mat4(1.0f);
_translateMat = glm::mat4(1.0f);
_scaleMat = glm::mat4(1.0f);

}
{
float defaultColor[4] = { 0.5, 0.5, 0.5, 1 };
//setup element array buffer
glGenBuffers(1, &_vboID);
glBindBuffer(GL_ARRAY_BUFFER, _vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*_vertices.size(), &_vertices.front(), GL_STATIC_DRAW);

//pass to shaders -- better to be continious
glEnableVertexAttribArray(_coordID);
glVertexAttribPointer(_coordID, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(_normID);
glVertexAttribPointer(_normID, 3, GL_FLOAT, GL_TRUE, sizeof(vertex), BUFFER_OFFSET(sizeof(glm::vec4)));

glEnableVertexAttribArray(_texCoordID);
glVertexAttribPointer(_texCoordID, 3, GL_FLOAT, GL_TRUE, sizeof(vertex), BUFFER_OFFSET(sizeof(glm::vec4)+sizeof(glm::vec3)));

glEnableVertexAttribArray(_spaceParamID);
glVertexAttribPointer(_spaceParamID, 4, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(sizeof(glm::vec4) + sizeof(glm::vec3) * 2));

//texture diffuse
if (_mtl->getDiffuseTextureMap())
{
glGenTextures(1, &_difTextureID);
glBindTexture(GL_TEXTURE_2D, _difTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
&_mtl->getDiffuseTextureMap()->data.parsedImageData.front()
);
}
else
{
glGenTextures(1, &_difTextureID);
glBindTexture(GL_TEXTURE_2D, _difTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
1,
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
defaultColor
);
}

//texture ambient
if (_mtl->getAmbientTextureMap())
{
glGenTextures(1, &_ambTextureID);
glBindTexture(GL_TEXTURE_2D, _ambTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
&_mtl->getAmbientTextureMap()->data.parsedImageData.front()
);
}
else
{
glGenTextures(1, &_ambTextureID);
glBindTexture(GL_TEXTURE_2D, _ambTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
1,
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
defaultColor
);
}

//texture specular
if (_mtl->getSpecularTextureMap())
{
glGenTextures(1, &_specTextureID);
glBindTexture(GL_TEXTURE_2D, _specTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
&_mtl->getSpecularTextureMap()->data.parsedImageData.front()
);

}
else
{
glGenTextures(1, &_specTextureID);
glBindTexture(GL_TEXTURE_2D, _specTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
1,
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
defaultColor
);
}

//texture bump map
if (_mtl->getBumpTextureMap())
{
glGenTextures(1, &_bumpTextureID);
glBindTexture(GL_TEXTURE_2D, _bumpTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
&_mtl->getBumpTextureMap()->data.parsedImageData.front()
);
}
else
{
glGenTextures(1, &_bumpTextureID);
glBindTexture(GL_TEXTURE_2D, _bumpTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA8,
1,
1,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
defaultColor
);
}

}

Edited by rXpSwiss

Share on other sites

So there's two problems I can see here:

1. glActiveTexture should come before glBindTexture. OpenGL is a massive state machine and calling glBindTexture will bind the texture to the currently active texture unit. If you call glActiveTexture after glBindTexture, it will affect the next call to glBindTexture.
2. Your texture parameter for GL_TEXTURE_MAG_FILTER is invalid. I'm guessing you meant to set GL_TEXTURE_MIN_FILTER to GL_NEAREST_MIPMAP_LINEAR and GL_TEXTURE_MAG_FILTER to GL_LINEAR. The mipmap filters are valid only for min(ification).
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);

Share on other sites

I checked every operation with GLgetError and I saw the error with GL_TEXTURE_MAG/MIN_FILTER it was a really bad copy paste from me.

But I didn't find the glActiveTexture because OpenGL doesn't say it is an error because it is correct state-wise but just doesn't do what I want...

Anyway, thank you a lot

Do you have any link on the machine state for texture etc. ?

Now I just need to reenable my bump mapping and see if it works.

I am almost there, there must be something not working with my lightDirection in tangentSpace because everything seems correct except the specular lightning cannot be seen anymore.

I think I fixed it :)

Edited by rXpSwiss

Share on other sites

White & black dots can be the result of math that produces errors. 99% of the cases are sqrt(negative number) and ~zero-length vectors.

Flickering is usually uninitialized variables.

Completely white/black is usually missing/empty texture, or missing/uninitialized uniforms etc.

Transfer normal and tangent to pixel shader (interpolated) and show their magnitudes. color = length(vector);

white = good, black = bad

Eventually you will find the issue. It helps alot to know what values certain things should have. For example, directional vectors (normal, tangent, binormal) should all be length == 1 (white).

1. 1
2. 2
3. 3
Rutin
23
4. 4
5. 5
khawk
14

• 9
• 11
• 11
• 23
• 12
• Forum Statistics

• Total Topics
633653
• Total Posts
3013162
×