【问题标题】:Passing an array of vec2 to shader in THREE.js将 vec2 数组传递给 THREE.js 中的着色器
【发布时间】:2014-10-04 15:07:57
【问题描述】:

我已经在网上搜索了一段时间,但还没有找到正确的答案。 找到了 THREE.js 使用的统一类型列表,我认为下面的代码应该是正确的。在最后一行,我定义了一个统一的 Vector2 数组。

uniforms: {
    "center":   { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },
    "aspectRatio": { type: "f", value: null },
    "radius": { type: "f", value: 0.1 },
    "pointList":  { type: "v2v", value: [] },
},

在我的 js 脚本中,我按如下方式传递此数组。我猜这也应该可行:

// Add effects
effect = new THREE.ShaderPass( THREE.MetaBalls2D );
effect.renderToScreen = true;
effect.uniforms[ 'aspectRatio' ].value = window.innerWidth/window.innerHeight;
effect.uniforms[ 'pointList' ].value = pointList //is an array of THREE.Vector2;
composer.addPass( effect );

我现在的问题是,如何从 Fragmentsshader 访问这个统一变量(在本例中为 pointList)?

【问题讨论】:

    标签: javascript arrays three.js glsl shader


    【解决方案1】:

    我会用一些向量来初始化它以防万一:

    "pointList":  { type: "v2v", value: [ new THREE.Vector2(), new THREE.Vector2() ] },
    

    我认为这是您需要添加到着色器的内容:

    uniform vec2 pointList[2];
    

    另外,如果你想避免Vector2s 你可以使用2fv 作为统一类型:

    "pointList":  { type: "2fv", value: [ 1, 0,  0, 1 ] }
    

    【讨论】:

    • 感谢@mrdoob 的回答。所以,如果我理解正确,只有在预先知道大小的情况下才能初始化数组?您能否通过 int 传递点数并像这样初始化它:uniform vec2 pointList[size];?因为那将是我需要的。我想将大小从 javascript 传递给我的着色器。
    • 我认为你可以做类似 "#define maxv2s 10\n" + yourGlslShader;然后统一 vec2 myv2array[maxv2s] 这样你就可以从 js 定义这个着色器。我认为你不能动态缩放数组。
    • 2fv 好像挺有意思的,以前不知道!
    【解决方案2】:

    您应该知道数组的最大大小是多少,所以假设您有一个数组:

    var myVec2Array = [
        new THREE.Vector2(),
        new THREE.Vector2(),
        new THREE.Vector2(),
        ...
    ]
    

    当你初始化一个着色器时,你可以按照这些思路做一些事情:

    var myShader = new THREE.ShaderMaterial({
        uniforms:{
            _myVec2UniformArray:{
                type:'v2v',
                value:myVec2Array
            }
        },
        vertexShader: 
            '#define ARRAYMAX '+ myVec2Array.length +'\n' + myVertexShader
    }
    

    在 myVertexShader 中你会初始化:

    uniform vec2 _myVec2UniformArray[ARRAYMAX];
    

    你不必填充数组,但是你可以在js中暴露ARRAYMAX,用它来管理两端的数组。

    【讨论】:

    • question @pailhead - 使用此设置,是否可以发送具有不同大小数组的更新 _myVec2UniformArray 制服?只要新数组大小小于 ARRAYMAX,它就可以工作吗?
    • 我认为 glsl 不会让你调整大小和排列,不确定这到底有什么影响,但你可以通过另一个制服并在达到 MAX_whatever 之前打破?
    • 非常感谢。这招救了我!只是一个问题,你能用 define 初始化一个数组吗?像这样:#define array '+ myVec2Array +'\n' + myVertexShader ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-02
    • 2021-01-07
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    相关资源
    最近更新 更多