最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how would I do environment reflection in webgl without using a library like three.js? - Stack Overflow

programmeradmin0浏览0评论

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).

/

Does this make sense? How would I get started?


Follow-Up

I answered this question after finishing my homework assignment: . Refer to the answer for links and code :)

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?


Follow-Up

I answered this question after finishing my homework assignment: https://stackoverflow.com/a/10093646/196921. Refer to the answer for links and code :)

Share Improve this question edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Apr 9, 2012 at 20:25 HristoHristo 46.5k67 gold badges168 silver badges234 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 12

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:

  1. Placing the camera at the center of the object, render the scene onto six textures representing the view out six faces of a cube around that object.
  2. Write a fragment shader that reflects the line of sight across the surface normal and traces out to where that intersects the cube to find the color seen in the reflection.

(I've never actually done this myself, but I've seen tutorials like this one).

发布评论

评论列表(0)

  1. 暂无评论