Hi, after my per pixel lightning and bump map shaders which work fine I now try to realize parallax mapping, first without occlusion and relief.
I read many tutorials about it and understood the math behind it.
In Vertex Shader my view or eye vector is converted to tangentspace:
I read out the height from the heightmap with and multiply it with the uniforms depthStrength and add bias:
offset_depth = (texture2D(normalMap, texCoord).a) * depthStrength + bias;
this offset gets multiplied with the viewVector which is in tangentspace
offset = offset_depth * viewVector_t.xy;
then I use this offset for my diffuse and normal texture coordinates:
diffuseMap = texture2D(textureDiffuse, texCoord + offset);
normal_t = texture2D(normalMap, texCoord + offset).rgb * 2.0 - 1.0;
here my vertex shader:
<div class=“ubbcode-block”><div class=“ubbcode-header”>Warning, Spoiler: <input type=“button” class=“form-button” value=“Show” onclick=“if (this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display != ‘’) { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘’;this.innerText = ‘’; this.value = ‘Hide’; } else { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘none’; this.innerText = ‘’; this.value = ‘Show’; }” />]<div style=“display: none;”>
//uniforms
uniform float LightSourceconstantAttenuation, LightSourcelinearAttenuation, LightSourcequadraticAttenuation;
uniform vec4 LightSourcePosition;
//varyings
varying float attenuation, nxOL ;
varying vec3 viewVector_t, lightVector_t, viewVector_v, normal_v;
//attributes
attribute vec3 Tangent;
//constants
//functions initialising
vec3 ConvertToTangent(vec3 c_vec, vec3 tangent, vec3 binormal, vec3 normal);
////////////////
//////Main//////
////////////////
void main()
{
////////////////
//initialising//
////////////////
float dist;
vec3 position_v, tangent_v, viewVector_v, binormal_v, v,
normal_v, lightVector_v, lightVector_w;
/////////////////////
//global references//
/////////////////////
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
///////////////
////vectors////
///////////////
///////////////
//viewspace_v//
///////////////
normal_v = normalize(gl_NormalMatrix * gl_Normal);
tangent_v = normalize(gl_NormalMatrix * Tangent);
binormal_v = cross(normal_v, tangent_v);
position_v = vec3(gl_ModelViewMatrix * gl_Vertex);
viewVector_v = normalize(-position_v);
lightVector_v = LightSourcePosition.xyz - position_v;
////////////////
//worldspace_w//
////////////////
lightVector_w = LightSourcePosition.xyz - gl_Vertex.xyz;
//////////////////
//tangentspace_t//
//////////////////
v = ConvertToTangent(lightVector_v, tangent_v, binormal_v, normal_v);
lightVector_t = v;
v = ConvertToTangent(viewVector_v, tangent_v, binormal_v, normal_v);
viewVector_t = v;
////////////////
//calculations//
////////////////
dist = length(lightVector_w);
lightVector_v = normalize(lightVector_v);
attenuation = 1.0 / (LightSourceconstantAttenuation +
LightSourcelinearAttenuation * dist +
LightSourcequadraticAttenuation * pow(dist,2.0));
//parallax offset
nxOL = dot(normal_v, viewVector_v);
}
/////////////////////
//////Functions//////
/////////////////////
//This function converts the incoming vector c_vec to tangent space;
vec3 ConvertToTangent(vec3 c_vec, vec3 t, vec3 b, vec3 n) {
vec3 v;
v.x = dot(c_vec, t);
v.y = dot(c_vec, b);
v.z = dot(c_vec, n);
return v;
}
[/QUOTE]</div>
here the fragment shader:
<div class=“ubbcode-block”><div class=“ubbcode-header”>Warning, Spoiler: <input type=“button” class=“form-button” value=“Show” onclick=“if (this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display != ‘’) { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘’;this.innerText = ‘’; this.value = ‘Hide’; } else { this.parentNode.parentNode.getElementsByTagName(‘div’)[1].getElementsByTagName(‘div’)[0].style.display = ‘none’; this.innerText = ‘’; this.value = ‘Show’; }” />]<div style=“display: none;”>
//uniforms
uniform float FrontMaterialshininess, depthStrength, bias;
uniform vec4 LightSourcediffuse, LightSourceambient, LightSourcespecular;
uniform sampler2D textureDiffuse, normalMap;
//varyings
varying float attenuation, nxOL;
varying vec3 viewVector_t, lightVector_t, viewVector_v;
//attributes
//constants
//functions initialising
////////////////
//////Main//////
////////////////
void main()
{
////////////////
//initialising//
////////////////
vec2 offset, texCoord;
vec3 reflectVector, normal_t;
vec4 diffuse, specular, diffuseMap;
float nxDir, specularPower, nxHalf, offset_depth;
///////////
//vectors//
///////////
//////////////////
//tangentspace_t//
//////////////////
viewVector_t = normalize(viewVector_t);
lightVector_t = normalize(lightVector_t);
////////////
//textures//
////////////
texCoord = vec2(gl_TexCoord[0].s * 12.0, gl_TexCoord[0].t * 3.5);
offset_depth = (texture2D(normalMap, texCoord).a) * depthStrength + bias;
offset = offset_depth * viewVector_t.xy;
diffuseMap = texture2D(textureDiffuse, texCoord + offset);
normal_t = texture2D(normalMap, texCoord + offset).rgb * 2.0 - 1.0;
///////////
//diffuse//
///////////
nxDir = max(0.0, dot(normal_t, lightVector_t));
diffuse = LightSourcediffuse * nxDir * attenuation;
////////////
//Specular//
////////////
specular = vec4 (0.0);
specularPower = 0.0;
if(nxDir != 0.0) {
reflectVector = normalize(reflect(-lightVector_t, normal_t));
reflectVector = normalize(2.0 * dot(normal_t, lightVector_t)* normal_t - lightVector_t);
nxHalf = max(0.0, dot(reflectVector, normal_t));
specularPower = pow(nxHalf, FrontMaterialshininess);
specular = LightSourcespecular * specularPower * attenuation;
}
////////////
//Parallax//
////////////
////////////////
//output color//
////////////////
gl_FragColor = ((diffuse + LightSourceambient) ) * vec4(diffuseMap.rgb, 1.0) +
(specular * diffuseMap.a);
}
[/QUOTE]</div>
At some positions the parallax effect looks fine, if I rotate the cylinder, the offset is wrong (red) and should be like the yellow arrows.
Since hours I try to solve this but I have no idea.
thanks for help in advance