Three.js: [EffectComposer] Masalah dengan 2 RenderPass berturut-turut

Dibuat pada 1 Feb 2012  ·  18Komentar  ·  Sumber: mrdoob/three.js

Tautan

http://demo.bkcore.com/threejs/webgl_tron_glow.html

Kode

glowcomposer = new THREE.EffectComposer( renderer, renderTarget );

glowcomposer.addPass( renderModelGlow ); // RenderPass
glowcomposer.addPass( hblur ); // ShaderPass
glowcomposer.addPass( vblur ); // ShaderPass
glowcomposer.addPass( effectSave ); // SavePass

glowcomposer.addPass( renderModel ); // RenderPass
glowcomposer.addPass( finalPass ); // ShaderPass

Isi

Saya mendapat dua pemandangan dengan objek / kamera / cahaya yang sama. Satu dengan tekstur menyebar (http://demo.bkcore.com/threejs/webgl_tron.html) dan satu dengan tekstur bercahaya (area bercahaya berwarna putih di atas hitam).

Pipeline rendering saya adalah sebagai berikut:
Saya pertama-tama merender adegan cahaya dan menerapkan blur H / V padanya, kemudian menyimpan output ke dalam frameBuffer menggunakan SavePass.
Lalu saya ingin membuat pemandangan yang tersebar.
Dan terakhir gabungkan dengan framebuffer berpendar.

Masalah

Glow sampler2D saya diteruskan dengan baik ke shader finalPass saya, tetapi seperti yang Anda lihat di demo, panggilan RenderPass kedua untuk adegan difus tidak berkinerja baik. Itu hanya menghasilkan hitam.

Saya mencoba membuat adegan tersebar dalam satu Render pass dan itu berhasil. Itu ketika saya menggunakannya sebagai RenderPass kedua yang tidak berfungsi.

Ada ide?

Terima kasih.
Thibaut D.

Question

Komentar yang paling membantu

Sepertinya demo asli tidak lagi berfungsi:

FWIW Saya membuat demo yang dipreteli untuk menerapkan FX secara selektif dan menulis melalui Additive Blend (menggunakan Three.js v79) di sini: https://www.airtightinteractive.com/demos/selective-fx/

Semua 18 komentar

Saya pikir itu karena buffer kedalaman dihancurkan, lihat # 1017.

Untuk kasus penggunaan Anda, yang mungkin berhasil adalah menggunakan dua komposer (dan dengan demikian dua target render yang sepenuhnya terpisah, masing-masing dengan buffer kedalaman sendiri).

Sesuatu seperti ini:

glowComposer = new THREE.EffectComposer( renderer, renderTargetGlow );

glowComposer.addPass( renderModelGlow ); // RenderPass
glowComposer.addPass( hblur ); // ShaderPass
glowComposer.addPass( vblur ); // ShaderPass

finalComposer = new THREE.EffectComposer( renderer, renderTargetFinal );
finalComposer.addPass( renderModel ); // RenderPass
finalComposer.addPass( finalPass ); // ShaderPass

Sekarang lapisan menyebar akan tersedia sebagai sampler tekstur tDiffuse di finalComposer dan lapisan cahaya yang akan Anda berikan dari glowComposer .

Ini akan menjadi glowComposer.renderTarget1 atau glowComposer.renderTarget2 tergantung pada jumlah lintasan tertentu dan apakah lintasan beralih ke buffer depan dan belakang, yang paling sederhana adalah mencoba keduanya dan melihat mana yang berhasil.

finalshader.uniforms[ 'tGlow' ].texture = glowComposer.renderTarget1;

Saya mencobanya, tetapi mendapat hasil yang sangat tidak terduga.

Ini, kode yang Anda usulkan:
http://demo.bkcore.com/threejs/webgl_tron_glow_swap.html
TDiffuse dari renderModel masih hitam.

Dan ini, adalah kode yang sama persis, dengan hanya dua render pass yang ditukar (adegan difus ada di komposer cahaya, dan adegan cahaya di komposer akhir):
http://demo.bkcore.com/threejs/webgl_tron_glow_swap2.html
Ini tentu saja bukan efek yang saya cari karena difusnya kabur dan bukan cahaya, tetapi seperti yang Anda lihat, baik sampler tGlow dan tDiffuse bekerja ...

Dan yang saya lakukan hanyalah menukar (baris 130 & 175):
baru THREE.RenderPass (pemandangan, kamera);
dengan
baru THREE.RenderPass (glowscene, glowcamera);

Cukup mengejutkan.

Anda perlu menggunakan format RGBA untuk membuat target jika Anda menggunakan transparansi.

Ya, saya setuju, tapi saya tidak menggunakan transparansi karena glow pass saya berubah menjadi putih di atas hitam dan kartu difus saya dengan baik ... menyebar di hitam. Saya kemudian menyusunnya dengan tambahan sehingga transparansi tidak diperlukan.

Namun, untuk memastikan, saya mengubah format RT ke RGBA, tapi itu tidak mengubah apa pun.

Masalah yang aneh di sini, adalah melakukan RenderPass adegan / kamera saya setelah RenderPass glowscene / glowcamera saya tidak berfungsi, saat melakukan RenderPass adegan / kamera saya sebelum RenderPass glowscene / glowcamera saya melakukannya.

Hmmm, sepertinya masalah berbagi geometri untuk materi yang berbeda (lihat # 1211).

Coba ini:

function createScene( geometry, x, y, z, b ) {

    zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );

    // ...

    var geometryClone = THREE.GeometryUtils.clone( geometry );
    var gmat = new THREE.MeshBasicMaterial( { map: gtex } );
    var gmesh = new THREE.Mesh( geometryClone, gmat );

    // ...
}

Iya ! Itu dia.

Kedua sampler saya sekarang terisi dengan benar. Terima kasih :)

EDIT

Hum ... Namun perilaku aneh lainnya, dua sampler saya bagus, ketika saya melakukannya

gl_FragColor = texel;

Saya mendapatkan difus dengan benar (http://demo.bkcore.com/threejs/webgl_tron_glow_swap2.html)

Ketika saya melakukannya

gl_FragColor = glow;

Saya mendapatkan sinarnya dengan benar.

Tapi saat saya coba melakukan simple additive blend pada keduanya
gl_FragColor = texel + bersinar;
Saya hanya mendapatkan cahaya (http://demo.bkcore.com/threejs/webgl_tron_glow_swap.html).

Maaf telah mengajukan begitu banyak pertanyaan, saya telah mencoba untuk membuat ini berfungsi tetapi tidak berhasil ..

EDIT2

Bahkan tampaknya melakukan itu

gl_FragColor = texel + glow;

Lebih terlihat seperti ini tentang keluaran rendering:

gl_FragColor = glow + glow;

Sepertinya texel vec4 secara tak terduga digantikan oleh glow vec4. Kedengarannya gila.

Anda perlu meletakkan tekstur di unit tekstur yang berbeda:

uniforms: {
    tDiffuse: { type: "t", value: 0, texture: null },
    tGlow:    { type: "t", value: 1, texture: null }
},

Musim panas!

Jika ada yang tertarik pada rendering cahaya selektif dengan Three.js, saya baru saja menerbitkan artikel kecil tentangnya: http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html

Semoga membantu.

Bagus;)

Sebagai alternatif, daripada kloning geometri, pilihan lain yang lebih murah adalah menggunakan material yang lebih mirip (sehingga geometri di kedua lintasan akan membutuhkan buffer yang sama).

Dalam hal ini, daripada menggunakan bahan dasar untuk lulus cahaya, Anda dapat mencoba bahan Lambert dengan pencahayaan tanpa difus, hanya dengan cahaya sekitar.

Sesuatu seperti ini:

glowScene.add( new THREE.AmbientLight( 0xffffff ) );

// ...

var gmat = new THREE.MeshLambertMaterial( { map: gtex, ambient: 0xffffff, color: 0x000000 } );
var gmesh = new THREE.Mesh( geometry, gmat );

Memang, itu bekerja dengan sempurna.

http://demo.bkcore.com/threejs/webgl_tron_glow_seq.html

Saya akan memperbarui artikel saya tentang solusi ini. Terima kasih !

Saya mem-porting kode ini ke r60 dan secara aneh menemukan masalah yang sama dengan merangkai komposer efek. Saya memiliki godray pass yang berfungsi jika saya menampilkannya ke layar. Tapi lintasan terakhir hanya mengeluarkan model. Output oclcomposer ke saluran tekstur "tadd" tampaknya baik-baik saja jika saya tidak menggunakan Effect Composer terpisah !! Saya sudah mencoba dengan renderer.PreserveDrawingBuffer = true tetapi itu juga tidak berhasil. Saya sudah mencoba menyetel autoclear ke false tetapi bukan itu.

Jika saya merender oclcomposer setelah komposer akhir dan membuat keluaran godray pass ke layar, saya dapat melihat godray tetapi tidak ada modelnya.

Alih-alih mengarahkan output oclcomposer ke saluran tadd di lintasan terakhir, jika saya menyalurkannya ke MeshBasicMaterial dan membuat kotak bertekstur dan menambahkannya ke adegan utama, sekarang saya dapat melihat model dan godrays (di pesawat), bukan efek yang saya inginkan tetapi memberi tahu saya bahwa perpipaan tekstur berfungsi.

// COMPOSERS
//-------------------
var renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBufer: false };

renderTargetOcl = new THREE.WebGLRenderTarget( SCREEN_WIDTH/2, SCREEN_HEIGHT/2, renderTargetParameters );

hblur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalBlur" ] );
vblur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalBlur" ] );
var bluriness = 2;

hblur.uniforms[ 'h' ].value = bluriness / SCREEN_WIDTH*2;
vblur.uniforms[ 'v' ].value = bluriness / SCREEN_HEIGHT*2;

var renderModel = new THREE.RenderPass( scene, camera );
var renderModelOcl = new THREE.RenderPass( oclscene, oclcamera );

grPass = new THREE.ShaderPass( THREE.Extras.Shaders.Godrays );
grPass.needsSwap = true;
grPass.renderToScreen = false;

oclcomposer = new THREE.EffectComposer( renderer, renderTargetOcl );

oclcomposer.addPass( renderModelOcl );
oclcomposer.addPass( hblur );
oclcomposer.addPass( vblur );
oclcomposer.addPass( grPass );

var finalPass = new THREE.ShaderPass( THREE.Extras.Shaders.Additive );
finalPass.needsSwap = true;
finalPass.renderToScreen = true;
finalPass.uniforms[ 'tAdd' ].texture = oclcomposer.renderTarget1;

renderTarget = new THREE.WebGLRenderTarget( SCREEN_WIDTH, SCREEN_HEIGHT, renderTargetParameters );
finalcomposer = new THREE.EffectComposer( renderer, renderTarget );

finalcomposer.addPass( renderModel );
finalcomposer.addPass( finalPass );

//RENDER
//-----------
oclcomposer.render(0.1);
finalcomposer.render( 0.1 );

@bbiswas Saya memiliki masalah yang sama dengan versi terbaru. Apa kamu sudah menemukan sesuatu?

Ya, saya berhasil melakukannya - Ini kodenya

var renderTargetOcl = new THREE.WebGLRenderTarget( webGL_window_width/4, webGL_window_height/4, renderTargetParameters );

            hblur = new THREE.ShaderPass( THREE.ShaderExtras[ "horizontalBlur" ] );
            vblur = new THREE.ShaderPass( THREE.ShaderExtras[ "verticalBlur" ] );

            var bluriness = 3;

            hblur.uniforms[ 'h' ].value = bluriness / webGL_window_width*2;
            vblur.uniforms[ 'v' ].value = bluriness / webGL_window_height*2;

            var renderModel = new THREE.RenderPass( scene, camera );
            var renderModelOcl = new THREE.RenderPass( g_occlusion_buffer, g_occlusion_camera );

            grPass = new THREE.ShaderPass( THREE.Extras.Shaders.Godrays );
            grPass.needsSwap = true;
            grPass.renderToScreen = false;

            g_volumetric_light_composer = new THREE.EffectComposer( webGLRenderer, renderTargetOcl );

            g_volumetric_light_composer.addPass( renderModelOcl );
            g_volumetric_light_composer.addPass( hblur );
            g_volumetric_light_composer.addPass( vblur );
            g_volumetric_light_composer.addPass( hblur );
            g_volumetric_light_composer.addPass( vblur );
            g_volumetric_light_composer.addPass( grPass );

            var finalPass = new THREE.ShaderPass( THREE.Extras.Shaders.Additive );
            finalPass.needsSwap = true;
            finalPass.renderToScreen = true;
            finalPass.uniforms[ 'tAdd' ].value = g_volumetric_light_composer.renderTarget1;

            finalcomposer.addPass( renderModel );
            finalcomposer.addPass( finalPass );

//in Render Loop



                g_occlusion_camera.position = camera.position;

                g_occlusion_camera.lookAt( new THREE.Vector3(0,0,0) );
                camera.lookAt( new THREE.Vector3(0,0,0)  );

                vlight.position = pointLight1.position;
                vlight.updateMatrixWorld();

                var lPos = THREE.Extras.Utils.projectOnScreen(pointLight1, camera);
                grPass.uniforms["fX"].value = lPos.x;
                grPass.uniforms["fY"].value = lPos.y;

                g_volumetric_light_composer.render(0.1);
                finalcomposer.render( 0.1 );

Terima kasih banyak!
Itu adalah baris dengan finalPass.uniforms[ 'tAdd' ].value . Saya memiliki finalPass.uniforms[ 'tAdd' ].texture sebelumnya.

Hai bbiswas, dapatkah Anda menambahkan tempat Anda membuat g_occlusion_buffer untuk bagian ini:

var renderModelOcl = new THREE.RenderPass (g_occlusion_buffer, g_occlusion_camera);

Sepertinya demo asli tidak lagi berfungsi:

FWIW Saya membuat demo yang dipreteli untuk menerapkan FX secara selektif dan menulis melalui Additive Blend (menggunakan Three.js v79) di sini: https://www.airtightinteractive.com/demos/selective-fx/

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

mrdoob picture mrdoob  ·  84Komentar

qornflex picture qornflex  ·  113Komentar

kdilayer picture kdilayer  ·  62Komentar

fernandojsg picture fernandojsg  ·  85Komentar

Mugen87 picture Mugen87  ·  68Komentar