无法理解THREE.js实例化,乒乓球素材和着色器照明

时间:2018-02-21 05:45:39

标签: three.js glsl webgl shader

我已经创建了一些实验来学习如何创建更好的场景,并且我已经进入了更高级的主题,我可以开始工作,但我并不真正理解为什么。

简化问题:

  • 使用dataTexture在着色器中绘制每个对象的InstancedBufferGeomtry过程是什么? (我的着色器下面的代码)
  • 哪些信息从着色器保存到WebGlRenderTarget?
  • 您可以将THREE.js灯光应用于InstancedBufferGeomtry,还是必须在我的着色器中包含灯光和阴影?

InstancedBufferGeometry

据我所知,如果要创建多个形状实例,可以将index,position,normal和if属性克隆到InstancedBufferGeometry,但我不明白为什么它在我的着色器中有效。

例如,我可以拥有一个DataTexture,它终生位置x,y,z和w。在我的模拟中,我正在ping这个DataTexture和更新我的片段着色器中的数据。接下来,我使用不同的着色器绘制我的InstancedBufferGeometry,我使用模拟DataTextures x,y和z作为每个对象的位置。这是我感到困惑的地方,但它应该如何应用,我想知道为什么。

我的顶点着色器使用我应用于InstancedBufferGeometry的boxbuffergeometry中的position,normal和uv,然后使用我的DataTexture中的x,y,z和w位置。从这里开始我的基本计算,当我到达着色器的gl_position时,我想知道它是如何基于我的DataTextures x,y和z绘制框的。我认为这样做的方式是,当绘制gl_position时,它只会绘制该顶点。我不完全理解为什么它会在那个位置画一个完整的盒子。

    precision highp float;

    uniform mat4 modelMatrix;
    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;
    uniform mat3 normalMatrix;

    attribute vec3 position;
    attribute vec3 normal;
    attribute vec2 uv;
    attribute vec2 lookup; // 0,0 to 1,1 for x amount of objects

    uniform sampler2D curPos; //Data texture x,y,z and w for x amount of objs
    uniform sampler2D prevPos; //Data texture x,y,z and w for x amount of objs


    varying vec2 vUv;

    mat3 calcLookAtMatrix(vec3 origin, vec3 target, float roll) {
        vec3 rr = vec3(sin(roll), cos(roll), 0.0);
        vec3 ww = normalize(target - origin);
        vec3 uu = normalize(cross(ww, rr));
        vec3 vv = normalize(cross(uu, ww));

    return mat3(uu, vv, ww);
    }

    void main() {
        vUv = uv;

        vec2 luv = lookup;
        vec4 i = texture2D( curPos, luv );
        vec4 p = texture2D( prevPos, luv );
        mat3 rot = calcLookAtMatrix( p.xyz, i.xyz, 0. );
        vec3 vPosition = rot * position;
        vPosition += mix(p.xyz, i.xyz, .5);

        gl_Position = projectionMatrix * modelViewMatrix * vec4( vPosition, 1.0 );;

    }

乒乓 - 我使用WebGlRenderTargets在我的数据纹理上打乒乓和第四。如何在WebGlRenderTarget上使用.texture接收我的新数据?每次执行时gl_frag都会保存到缓冲区吗?

在我的模拟中,我有一个存储在数组中的两个渲染目标,这些目标是我的正面和背面,由于你无法同时读写,因此可以恢复ping和第四个。我的网格是一个简单的平面几何体,它使用着色器在片段着色器中更新我的DataTexture。如何将gl drag中的每次执行的值保存到渲染目标纹理缓冲区中?

    precision highp float;

    uniform sampler2D source; // data texture x,y,z, and w 
    uniform sampler2D seed; // Original data texture x,y,z, and w 

    void main() {

        vec4 s = texture2D(source,vUv);

        if( s.w <= 0. ) {
            s = texture2D(seed,vUv);
            if( init == 0. ) s.w = 100.;
        }else{
            s.xyz += Noise here;
            s.w -= decay value here;
        }

        gl_FragColor = s;
    }

渲染乒乓球

public render() {

        this.shader.uniforms.source.value = this.front.texture;

        this.target++;
        this.target %= this.buffersCount;
        this.front = this.targets[this.target];
        let prev = this.target - 1;
        if (prev < 0) prev += this.buffersCount;
        this.back = this.targets[prev];

        this.renderer.render(this.orthoScene, this.orthoCamera, this.front);

    }

照明 - 当我切换到使用自己的InstancedBufferGeometry时,rawshadermaterial有一种方法可以使用提供的three.js光源,或者我是否总是需要将自己的自定义光照和阴影添加到我的着色器中?

1 个答案:

答案 0 :(得分:0)

我发现你的部分问题令人困惑。

  1. 您只需将另一个变量添加到着色器。属性normalpositionuv属于我假设的多维数据集,而您的lookup是特殊类型的实例属性。对于每个实例,lookup属性不同,而前三个属性保持不变。

  2. 这是一次绘制调用,它绑定几何(属性)设置不同的绘制模式并调用一次。它将从您的多维数据集中抽取所​​有顶点乘以实例数。

  3. 使用rawShaderMaterial,您必须编写整个着色器并提供所有内容。这几乎就像是three.js一样。因此,使用该特定着色器,您不能使用任何光照或任何其他效果。您可以使用onBeforeCompile将GLSL注入其他材料或咨询/使用此模块。 https://www.npmjs.com/package/three-instanced-mesh