简体   繁体   English

如果不使用像 three.js 这样的库,我将如何在 webgl 中进行环境反射?

[英]how would I do environment reflection in webgl without using a library like three.js?

I'm trying to figure out how to do environment mapping onto an object. Here's the setup:我正在尝试弄清楚如何将环境映射到 object。这是设置:

茶壶

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).这是我想要完成的示例,但它使用Three.js ,我想自己完成(这是一个班级)。

http://aerotwist.com/tutorials/create-your-own-environment-maps/demo/ 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 .我在完成作业后回答了这个问题: 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 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/ .欢迎访问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 .源代码就在那里……代码很烂所以请不要评判我:)这是主要的 JS 文件: http://hristo.oskov.com/projects/cs418/mp3/js/mp3 .js The shaders are in the index.html page so just view source.着色器位于 index.html 页面中,因此只需查看源代码即可。

The basic approach for rendering a reflective object is:渲染反射 object 的基本方法是:

  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.将相机放在 object 的中心,将场景渲染到六个纹理上,代表 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 ). (我自己从来没有真正做过这个,但我看过 这样的教程)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM