Perhaps the easiest way to achieve offset mapping in OpenGL ES 2.0 is also probably the fastest. You need two textures, one of which contains the color (normal) and the displacement map. If you select the regular texture correctly, your fragment shader will look like this:
uniform sampler2D myTexture; varying vec2 texcoords; void main() { gl_FragColor = texture2D(myTexture, texcoords); }
This is pretty simple stuff. Now to achieve offset mapping you need to:
uniform sampler2D myTexture; uniform sampler2D myDisplacementMap; varying vec2 texcoords; void main() { vec2 displacement = 0.1 * texture2D(myDisplacementMap, texcoords).rg; gl_FragColor = texture2D(myTexture, texcoords + displacement); }
It is also simple. You have another texture where red and green are used as x and y to move. This way you get a static, view-independent move. To get the real offset, you need to generate texture tangents and binagent signals that contain the directions of the texture axes in the space of objects (a complex concept, reading an article). After you get them, all you need is the position of the space object (it can be calculated by multiplying the vertex position by the projection model inverted in the vertex shader) and projecting it onto the tangent / bitagen vectors, you can modulate the offset in order depends on the form:
attribute vec3 position, tangent, bitangent; attribute vec2 texcoord; varying vec2 texcoords; varying vec3 eye_dir, tan, bitan; uniform matrix4f modelviewProjectionMatrix; uniform matrix4f modelviewProjectionMatrixInverse; void main() { gl_Position = modelviewProjectionMatrix * vec4(position, 1.0); tan = tangent; bitan = bitangent; texcoords = texcoord; }
(this is the vertex shader) and the fragment shader here:
uniform sampler2D myTexture; uniform sampler2D myDisplacementMap; varying vec2 texcoords; varying vec3 eye_dir, tan, bitan; void main() { vec2 eyen = normalize(eye_dir); vec2 modulation = vec2(dot(eyen, normalize(tan)), dot(eyen, normalize(bitan))); vec2 displacement = 0.1 * texture2D(myDisplacementMap, texcoords).rg * modulation; gl_FragColor = texture2D(myTexture, texcoords + displacement); }
And that should do the trick ... (note that I wrote it from the head, so if there are any errors, feel free to comment)
EDIT : And there were errors, I changed the order of the arguments to the 2D texture (sampler first).