I'm trying to figure out how to do environment mapping onto an object. Here's the setup:
How would I make the teapot's surface reflect it's surroundings? So what I mean by that is, instead of the teapot being that shade of gray, its surface should reflect its environment, so it should have the checkerboard mapped onto its surface.
This is an example of what I'm trying to accomplish, but its using Three.js and I want to do this on my own (this is for a class).
http://aerotwist.com/tutorials/create-your-own-environment-maps/demo/
Does this make sense? How would I get started?
I answered this question after finishing my homework assignment: https://stackoverflow.com/a/10093646/196921. Refer to the answer for links and code :)
I found a good example of this teapot here...
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/google/shiny-teapot/index.html
Looking through the source code, I found what I was looking for:
function loadCubeMap(base, suffix) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
var faces = [["posx.png", gl.TEXTURE_CUBE_MAP_POSITIVE_X],
["negx.png", gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
["posy.png", gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
["negy.png", gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
["posz.png", gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
["negz.png", gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]];
for (var i = 0; i < faces.length; i++) {
var face = faces[i][1];
var image = new Image();
image.onload = function(texture, face, image) {
return function() {
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
}
} (texture, face, image);
image.src = faces[i][0];
}
return texture;
}
... and the example fragment shader (which has more than I need for the environment reflection mapping)...
precision mediump float;
const float bumpHeight = 0.2;
uniform sampler2D normalSampler;
uniform samplerCube envSampler;
varying vec2 texCoord;
varying vec3 worldEyeVec;
varying vec3 worldNormal;
varying vec3 worldTangent;
varying vec3 worldBinorm;
void main() {
vec2 bump = (texture2D(normalSampler texCoord.xy).xy * 2.0 - 1.0) * bumpHeight;
vec3 normal = normalize(worldNormal);
vec3 tangent = normalize(worldTangent);
vec3 binormal = normalize(worldBinorm);
vec3 nb = normal + bump.x * tangent + bump.y * binormal;
nb = normalize(nb);
vec3 worldEye = normalize(worldEyeVec);
vec3 lookup = reflect(worldEye nb);
vec4 color = textureCube(envSampler, lookup); // <--- this was the aha! line
gl_FragColor = color;
}
The result came out to be kinda cool...
Feel free to check it out at http://hristo.oskov.com/projects/cs418/mp3/. The source code is all there in its glory... the code sucks so please don't judge me :) This is the main JS file: http://hristo.oskov.com/projects/cs418/mp3/js/mp3.js. The shaders are in the index.html page so just view source.
The basic approach for rendering a reflective object is:
(I've never actually done this myself, but I've seen tutorials like this one).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With