Je travaille sur un moteur de rendu d'avant en arrière pour un moteur 2D utilisant une projection orthographique. Je veux utiliser le tampon de profondeur pour éviter le surmenage. J'ai un tampon de profondeur de 16 bits, une caméra à Z = 100 en regardant Z = 0, zNear est 1 et zFar est 1000. Chaque sprite rendu définit ses coordonnées Z à des valeurs de plus en plus éloignées, permettant au test de profondeur d'ignorer le rendu tout ce qui est en dessous.
Cependant, je sais que la façon dont les positions Z se retrouvent avec des valeurs de tampon Z n'est pas linéaire. Je veux utiliser la pleine résolution du tampon de profondeur 16 bits, c'est-à-dire autoriser 65536 valeurs uniques. Donc, pour chaque image-objet rendue, je veux incrémenter la position Z à la position suivante pour la corréler à la prochaine valeur de tampon de profondeur unique.
En d'autres termes, je veux transformer un index d'incrémentation (0, 1, 2, 3 ...) du sprite en cours de dessin vers la position Z appropriée pour que chaque sprite ait une valeur de tampon de profondeur unique. Je ne suis pas sûr des mathématiques derrière cela. Quel est le calcul pour ce faire?
Remarque Je travaille dans WebGL (essentiellement OpenGL ES 2), et j'ai besoin de prendre en charge une large gamme de matériel, donc bien que des extensions comme gl_FragDepth puissent faciliter cela, je ne peux pas l'utiliser pour des raisons de compatibilité.
la source
Réponses:
En effet, les valeurs stockées dans le z-buffer ne sont pas linéaires aux coordonnées z réelles de vos objets, mais à leur réciproque, afin de donner plus de résolution à ce qui est près de l'œil qu'à ce qui est plus proche du plan arrière.
Ce que vous faites, c'est que vous mappez votre
zNear
vers0
et votrezFar
vers1
. PourzNear=1
etzFar=2
, cela devrait ressembler à ceciLa façon de calculer cela est définie par:
Où
... et z_buffer_value est un entier.
L'équation ci-dessus vous est présentée avec l'aimable autorisation de cette page géniale , qui explique les z-buffers d'une très bonne manière.
Donc, afin de trouver le nécessaire
z
pour une donnéez_buffer_value
, nous effaçons simplementz
:la source
z_buffer_value = k * (a + (b / z))
et simplement réorganiser pour résoudrez
, alors je reçois:z = b / ((z_buffer_value / k) - a)
- comment êtes-vous arrivé à la dernière formule différente?(v / k) - a => (v - k * a) / k
et vous vous effondrez(k * b) / (v - (k * a))
. C'est le même résultat.Vous devriez peut-être changer votre approche pour quelque chose de plus simple. Ce que je ferais; Gardez votre profondeur Z, mais gardez une liste de ce que vous rendez. Triez cette liste en fonction de la valeur Profondeur z et affichez les objets dans l'ordre de la liste.
J'espère que cela peut vous aider. Les gens me disent toujours de garder les choses simples.
la source
Puisque vous avez déjà une liste triée de choses à rendre (d'avant en arrière), avez-vous vraiment besoin d'incrémenter l'index Z? Ne pouvez-vous pas utiliser "inférieur ou égal" pour la "fonction de vérification"? De cette façon, il vérifierait si un pixel spécifique a déjà été dessiné ou non.
la source