2

ここにデモがあります: http://percentcer.github.io/poi3d/

ある種の「光の軌跡」効果を与えたい黒い背景に図形が描かれています。これは、前のフレームバッファを保持し、各フレームで「暗くする」ことで実現できると考えました(つまり、最終的に色が vec4(0.0, 0.0, 0.0, a) ) に近い値になると仮定して、各フラグメント ベクトルを 1 未満の値でスケーリングするフラグメント シェーダー。

各フレームで、前のフレームのフラグメント * を再描画し、some_scalarその上にオブジェクトを描画してから、コピー シェーダーを介して画面に送信します。これらはすべて、次のように使用される EffectComposer を介して行います。

初期化:

composer  = new THREE.EffectComposer( renderer );

shDim = new THREE.ShaderPass( THREE.DimShader );
composer.addPass( shDim );

var scenePass  = new THREE.RenderPass( scene, camera );
composer.addPass( scenePass );

var shCopy = new THREE.ShaderPass( THREE.CopyShader );
composer.addPass( shCopy );

そしてアニメーションループ:

shDim.uniforms[ 'prevTDiffuse' ].value = composer.writeBuffer;
composer.render();

( https://github.com/percentcer/poi3d/blob/master/js/logic.js#L61 )

DimShader自体もそれほど複雑ではありません。

fragmentShader: [

        "varying vec2 vUv;",

        "uniform sampler2D tDiffuse;",
        "uniform sampler2D prevTDiffuse;",
        "uniform float scaleRate;",

        "void main() {",

            "vec4 texel = texture2D( prevTDiffuse, vUv );",
            "gl_FragColor = vec4( texel.rgb * scaleRate, texel.a );",

        "}"

    ].join("\n")

つまり、値に 1 未満の値を繰り返し掛けると、0 に近づくはずですよね? ただし、デモを実行すると、暗くなりますが、中間調のグレー値で停止する ことがわかります。

デフォルトの倍率は 0.995 で、これはページアップとページダウンで変更できます。より速い速度 (0.95、既定の状態から 1 ページ ダウン) にすると、フェード アウトは黒にかなり近づきますが、実際には黒に達することはなく、(非常に暗い) グレーでハングします。私の友人の何人かは、これは float 精度の問題の兆候だと考えています。また、これはアルファ値が 0.0 にスケーリングされているため、ある時点で新しいピクセルの色が表示されなくなるブレンドの問題である可能性があると考えましたが、これはアルファも 1.0 に強制すると発生します。

three.jsとGLSLの両方が初めてです。私はいくつかのopenGLの経験がありますが、自分自身も初心者だと考えています。ありがとう!

ああ、ここにも完全なレポがあります: https://github.com/percentcer/poi3d/

4

1 に答える 1

4

これは、カラー バッファが離散値を格納するためです。ある時点で

texel.rgb * scaleRate

丸めると、元の値になります。つまり、値が下がることはありません。

実際、おおよその色を予測できます。color0 ~ 255 の場合は、

scaleRate * color = ( color - 0.5 )

scaleRate= 0.995, color= 100. 私はあなたのデモで 96 を観察します。

于 2013-09-19T22:04:01.857 に答える