【问题标题】:how would I do environment reflection in webgl without using a library like three.js?如果不使用像 three.js 这样的库,我将如何在 webgl 中进行环境反射?
【发布时间】:2012-04-22 04:33:05
【问题描述】:

我正在尝试弄清楚如何将环境映射到对象上。这是设置:

如何让茶壶的表面反射周围的环境?所以我的意思是,茶壶不是那种灰色的阴影,它的表面应该反映它的环境,所以它应该把棋盘映射到它的表面上。

这是我正在尝试完成的一个示例,但它使用 Three.js,我想自己完成(这是针对一个班级)。

http://aerotwist.com/tutorials/create-your-own-environment-maps/demo/

这有意义吗?我该如何开始?


跟进

我在完成作业后回答了这个问题:https://stackoverflow.com/a/10093646/196921。链接和代码参考答案:)

【问题讨论】:

    标签: javascript webgl texture-mapping


    【解决方案1】:

    我在这里找到了这个茶壶的一个很好的例子......

    https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/google/shiny-teapot/index.html

    翻阅源代码,找到了我要找的东西:

    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;
    }
    

    ...和示例片段着色器(它比我需要的环境反射映射更多)...

    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;
    }
    

    结果出来有点酷……

    请随时通过http://hristo.oskov.com/projects/cs418/mp3/ 查看。源代码尽在其中......代码很烂所以请不要评判我:) 这是主要的 JS 文件:http://hristo.oskov.com/projects/cs418/mp3/js/mp3.js。着色器位于 index.html 页面中,因此只需查看源代码。

    【讨论】:

    • 还有这个示例,它会进行实时反射。虽然它使用了一个库。但图书馆并没有隐藏太多。 (webglsamples.googlecode.com/hg/dynamic-cubemap/…)
    • 是的,我看到了一个 :) 非常令人印象深刻的东西,但是当我看到它使用库时我就忽略了它:/
    • 能否包含顶点着色器?没有它,所有这些变化都没有多大意义。此外,您发布到 khronos.org 的链接需要登录详细信息,因此无法查看。
    【解决方案2】:

    渲染反射对象的基本方法是:

    1. 将相机放置在对象的中心,将场景渲染到六个纹理上,这些纹理代表该对象周围立方体的六个面的视图。
    2. 编写一个片段着色器,以反射穿过表面法线的视线并追踪到与立方体相交的位置,以找到反射中看到的颜色。

    (我自己从未真正做过,但我看过像this one 这样的教程)。

    【讨论】:

    • 是的...我从概念上理解。我只是无法弄清楚开始使用它的代码。我只是对 WebGL 不太熟悉:P
    • 您可能有兴趣使用 i-am-glow.com 作为样板,以便您可以专注于着色器/FBO 部分。
    猜你喜欢
    • 2014-07-01
    • 1970-01-01
    • 2020-04-17
    • 2017-03-22
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    相关资源
    最近更新 更多