Three.js 三个.js特定的渲染时间

Three.js 三个.js特定的渲染时间,three.js,Three.js,我想基于计算着色器中以前的像素位置来实现每个对象的运动模糊效果 这项技术的第一步是建立运动物体的速度图。该步骤要求将当前帧的投影矩阵和模型视图矩阵以及前一帧的相同矩阵作为统一变量 如何将这些矩阵包含到某些特殊着色器中?我应该以某种方式找到解决方案,比如: uniforms = { some_uniform_var : {type: "m4", value: initialMatrix, getter: function(){ // `this` points to objec

我想基于计算着色器中以前的像素位置来实现每个对象的运动模糊效果

这项技术的第一步是建立运动物体的速度图。该步骤要求将当前帧的投影矩阵和模型视图矩阵以及前一帧的相同矩阵作为统一变量

如何将这些矩阵包含到某些特殊着色器中?我应该以某种方式找到解决方案,比如:

 uniforms = {
   some_uniform_var : {type: "m4", value: initialMatrix, getter: function(){
      // `this` points to object
      return this.worldMatrix
   }}
 }
但是现在在THREE.js中这是不可用的。我们可以做一些猴子修补,但我找不到最好的方法


有什么建议吗?

目前解决这个问题的办法包括几个部分。我正在使用EffectComposer对渲染场景进行多次传递,其中一次是-VelocityPass。它采用当前和以前的模型视图矩阵和投影矩阵,并生成两个位置。这两个参数都用来计算一个点的速度

着色器看起来像这样

    "void main() {",

        "vec2 a = (pos.xy / pos.w) * 0.5 + 0.5;",
        "vec2 b = (prevPos.xy / prevPos.w) * 0.5 + 0.5;",
        "vec2 oVelocity = a - b;",

        "gl_FragColor = vec4(oVelocity, 0.0, 1.);",

    "}"
这个决定有几个问题。 Three.js具有向对象相关着色器注入矩阵的特定点。
SetProgram
闭包的结尾,它位于
WebGLRenderer
中。这就是我获取整个渲染器文件的原因,将渲染器重命名为
THREE.MySuperDuperWebGLRenderer
,并在其中添加了几行代码:

访问在用户空间中定义的闭包的闭包:

function materialPerObjectSetup(material, object){
    if( material.customUniformUpdate ){
        material.customUniformUpdate( object, material, _gl ); // Yes, I  had to pass it...

    }

}
并在
renderBuffer
renderBufferDirect
中调用它

    var program = setProgram( camera, lights, fog, material, object );

    materialPerObjectSetup(material, object);
现在-用户空间部分:

velocityMat = new THREE.ShaderMaterial( THREE.VelocityShader );

velocityMat.customUniformUpdate = function(obj, mat, _gl){

    // console.log("gotcha");
    var new_m = obj.matrixWorld;
    var p_uniforms = mat.program.uniforms;
    var mvMatrix = camera.matrixWorldInverse.clone().multiplyMatrices(camera.matrixWorldInverse, obj._oldMatrix );

    _gl.uniformMatrix4fv( p_uniforms.prevModelViewMatrix, false,  mvMatrix.elements );
    _gl.uniformMatrix4fv( p_uniforms.prevProjectionMatrix, false, camera.projectionMatrix.elements );
    obj._pass_complete = true; // Необходимо сохранять состояние старой матрицы пока не отрисуется этот пасс. 
                               // А то матрицы обновляются каждый рендеринг сцены.
}
\u pass\u complete
需要多次重新渲染场景-每次都重新计算矩阵。这个技巧帮助我们保存以前的矩阵,直到我们使用它

\u gl.uniformMatrix4fv
是必需的,因为在渲染之前,three.js只服务于宇宙一次。无论我们有多少对象-其他方法将传递到上一个方法的着色器
modelViewMatrix
。发生这种情况是因为我想使用
VelocityShader
完全绘制此场景。没有其他方法可以告诉渲染器为对象使用某种替代材质

作为这一解释的最后一点,我在这里提出了一个技巧来管理对象的前一个矩阵:

            THREE.Mesh.prototype._updateMatrixWorld = rotatedObject.updateMatrixWorld;
            THREE.Mesh.prototype._pass_complete = true;

            Object.defineProperty(THREE.Mesh.prototype, "updateMatrixWorld", {get: function(){
                if(this._pass_complete){
                    this._oldMatrix = this.matrixWorld.clone();
                    this._pass_complete = false;
                }

                this._updateMatrixWorld();


                return (function(){
                });


            }})

我相信有更好的解决办法。但有时我需要匆忙行事。这样的事情可能会发生。

是否要传递一个
Matrix4
数组?您可以使用类型
m4v
来执行此操作。只需更新渲染循环中的数组值。是的,我需要。问题是,我想:1-将此矩阵传递给特定材质的制服,该材质将被覆盖。2-必须为场景中的每个对象传递此矩阵。3-我不想在用户空间中有特殊的循环来遍历每个对象,当渲染器本身这样做的时候。我不明白。尝试提供一个工作的实时示例(即使它在每个对象中循环)。然后问一个具体的问题。我会试着在回答中解释这一点。而且,如果你能给出意见,这将是一个nie补丁,还是不是…嗯。。。从代码片段中,很难注释。。。但无论如何,我只能回答关于three.js的问题——否则我将永远无法完成任何事情。:-)“它采用当前和以前的模型视图矩阵和投影矩阵,并生成两个位置。”您能详细说明一下吗?vec4 pos,prevPos是顶点变换吗?我不确定这里的问题是什么。如果您必须在每个对象中克隆这些矩阵,是什么阻止您传递/更新有关着色器的矩阵?第一个障碍-覆盖材质-我们为每个对象获取一种材质。一个制服阵列。渲染序列中的最后一个对象获胜。第二,我们无法控制在最合适的时候将矩阵发送到着色器。普通制服在这一刻之前就已经寄出了,THREE.js已经加入了这一点,并且不给任何回电。你有没有可能摆弄一把小提琴?或者至少是一些截图?我甚至有一个工作演示。这是一堆“我应该扔掉它”的代码。基本上,您希望看到
PerObjectBlurShader.js
VelocityPass.js
VelocityShader.js
customWeGLRenderer.js
,以及
shader develop.html
本身。但在深入研究之前,我会三思而后行……在探索之前——这里有一篇文章将让你理解所有这些的目的。