2017-09-14 3 views
0

J'essaie de créer un nœud de scène complexe, qui entraînerait plusieurs appels de tirage et un changement d'état entre les deux, lorsqu'il est rencontré dans l'appel WebGLRenderer.render() de trois.Gérer l'état webgl et émettre des appels de tirage séquentiels avec three.js

Spécifiquement je veux travailler avec le tampon stencil, qui n'est pas exposé comme une API de plus haut niveau.

Si je

var mesh = new THREE.Mesh(someGeom, someMaterial) 

je dois avoir cela se avant qu'il ne soit établi:

mesh.onBeforeRender = (renderer , scene , camera)=>{ 
    //because there is no someMaterial.stencilOp = THREE.SomeStencilOp 
    //i need to work with the gl context 

    _gl.enable(_gl.STENCIL_TEST) 
    _gl.clearStencil(0) 
    _gl.clear(_gl.STENCIL_BUFFER_BIT) 
    _gl.stencilFunc(_gl.ALWAYS , 1 , 1) 
    _gl.stencilOp(_gl.REPLACE , _gl.REPLACE , _gl.REPLACE) 
    //... 

} 

Suivi par plus draw appelle:

mesh.onAfterRender = (renderer , scene , camera)=>{ 

    //more state 
    _gl.stencilFunc(_gl.EQUAL , 1 , 1) 
    _gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.INCR) 

    //renderer.render(someOtherMesh , camera) //this doesn't really work 
    renderer.render(anotherSceneWithOtherMesh, camera) //this is nightmarish 

    //more state for yet another call 
    _gl.stencilFunc(_gl.EQUAL, 0 ,1) 
    _gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.KEEP) 

    //renderer.render(mesh , camera) //not a scene so it doesnt work 
    renderer.render(proxySceneForThisMeshWithThisMesh, camera) // :(i need to either bake the transformation, or somehow sync a copy of the scene graph down to this node 

    _gl.disable(_gl.STENCIL_TEST) 

} 

Que pouvais-je faire avec trois, comme c'est, r87 pour y parvenir avec le moins de maux de tête?

Je souhaite que je pourrais appeler une sorte de renderGeometryDirect méthode qui Dessinez la géométrie en utilisant le même nœud que le onBeforeRender ou onAfterRender est appelé, et par la même camera qui est déjà utilisé dans le niveau supérieur render(scene, camera) appel.

Ou s'il est simplement appelé render(myObject3D, camera). Au lieu de cela, je pense à quelque chose qui pourrait gérer la création de ces graphiques fantômes qui fonctionneraient avec render() mais je ne suis pas sûr de ce que la meilleure ligne de conduite est.

+0

je ne vois pas probablement quelque chose ici, mais pourquoi ne pouvez-vous faire juste les trois désamorcent appels au même niveau et le tampon de pochoir contrôle en dehors de cette ? Quelque chose comme 1) pochoir preapre 2) scène de rendu avec des objets écrivant à stencil-buffer 3) render anotherSceneWithOtherMesh 4) render proxySceneForThisMeshWithThisMesh 5) désactiver stencil –

+0

Je ne sais pas comment mieux aborder la création de ces différentes scènes, et comment les synchroniser si je veux déplacer juste le noeud original, si cela a du sens? J'ai besoin d'un système de gestion qui créerait chacune de ces scènes, pour chacun de ces nœuds «multi-passes». – pailhead

+0

Ou un appel de rendu plus pratique. – pailhead

Répondre

1

Juste une idée, peut-être vous pouvez utiliser des couches pour réaliser quelque chose comme ceci (voir here et here)? Cela devrait au moins vous permettre de spécifier des sous-ensembles du graphe de scène à afficher dans un appel de rendu.

donc quelque chose comme ceci:

_gl.enable(_gl.STENCIL_TEST) 
_gl.clearStencil(0) 
_gl.clear(_gl.STENCIL_BUFFER_BIT) 
_gl.stencilFunc(_gl.ALWAYS , 1 , 1) 
_gl.stencilOp(_gl.REPLACE , _gl.REPLACE , _gl.REPLACE) 

camera.layers.set(1);  
renderer.render(scene, camera); 


_gl.stencilFunc(_gl.EQUAL , 1 , 1) 
_gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.INCR) 

camera.layers.set(2); 
renderer.render(scene, camera); 


_gl.stencilFunc(_gl.EQUAL, 0 ,1) 
_gl.stencilOp(_gl.KEEP , _gl.KEEP , _gl.KEEP) 

camera.layers.enable(1); 
camera.layers.enable(2); 
renderer.render(scene, camera); 
+0

J'aime cette idée, mais je suis inquiet que le nombre de canaux puisse être limitant :(Il semble que de cette façon je devrais assigner une couche différente pour chacun de ces nœuds? Peut-être que '.renderOrder' pourrait faire quelque chose de similaire , peut-être avoir chaque parentNode dans une gamme de 1000 à 3000 par exemple, puis chacun de ces autres appels à dessiner à N0 + 1, N0 + 2 ...? – pailhead

+0

Je pensais plus comme un par passe, mais encore une fois je ne suis pas complètement sûr que je sais ce que vous voulez atteindre, quels sont les états intermédiaires du stencil-buffer et ainsi de suite Actuellement, il est limité à 32 couches, mais il peut être possible d'appliquer des patchs de singe si vous en avez vraiment besoin (Il est seulement utilisé via ses méthodes iirc.) –

+0

Mise à jour sur cela.Il fonctionne réellement! Je suis inquiet de la traversée de la scène avec chaque rendu, mais si ne met pas à jour les matrices, je pense qu'il peut être très utile. – pailhead