Lors de la réduction de la profondeur de couleur et du tramage avec un bruit de 2 bits (avec n =] 0,5,1,5 [et sortie = étage (entrée * (2 ^ bits-1) + n)), les extrémités de la plage de valeurs (entrées 0,0 et 1,0 ) sont bruyants. Il serait souhaitable qu'ils soient de couleur unie.
Exemple: https://www.shadertoy.com/view/llsfz4
(ci-dessus est une capture d'écran du shadertoy, illustrant un dégradé et les deux extrémités qui devraient être respectivement blanches et noires, mais qui sont plutôt bruyantes)
Le problème peut bien sûr être résolu en compressant simplement la plage de valeurs de sorte que les extrémités soient toujours arrondies à des valeurs uniques. Cela semble un peu un hack cependant, et je me demande s'il existe un moyen de mettre en œuvre cela "correctement"?
la source
Réponses:
TL; DR: 2 * 1LSB coupures de tramage triangulaire-pdf dans les boîtiers électroniques à 0 et 1 en raison du serrage. Une solution consiste à lerp à un tramage uniforme 1 bit dans ces edgecases.
J'ajoute une deuxième réponse, car cela s'est avéré un peu plus compliqué que je ne le pensais à l'origine. Il semble que ce problème ait été un "TODO: besoins de serrage?" dans mon code depuis que je suis passé du tramage normalisé au tramage triangulaire ... en 2012. Ça fait du bien de le regarder enfin :) Code complet pour la solution / les images utilisées tout au long du post: https://www.shadertoy.com/view/llXfzS
Tout d'abord, voici le problème que nous examinons, lors de la quantification d'un signal à 3 bits avec un tramage PDF triangulaire 2 * 1LSB:
- essentiellement ce que hotmultimedia a montré.
En augmentant le contraste, l'effet décrit dans la question devient apparent: la sortie ne passe pas en moyenne au noir / blanc dans les boîtiers électroniques (et s'étend en fait bien au-delà de 0/1 avant de le faire).
Regarder un graphique donne un peu plus d'informations:
(les lignes grises marquent 0/1, également en gris le signal que nous essayons d'émettre, la ligne jaune est la moyenne de la sortie tramée / quantifiée, le rouge est l'erreur (moyenne du signal)).
Fait intéressant, non seulement la sortie moyenne n'est pas 0/1 aux limites, mais elle n'est pas non plus linéaire (probablement en raison du pdf triangulaire du bruit). En regardant l'extrémité inférieure, il est logique de comprendre pourquoi la sortie diverge: lorsque le signal tramé commence à inclure des valeurs négatives, le serrage sur la sortie modifie la valeur des parties inférieures tramées de la sortie (c'est-à-dire les valeurs négatives), ce qui augmenter la valeur de la moyenne. Une illustration semble être en ordre (tramage 2LSB uniforme et symétrique, toujours en jaune):
Maintenant, si nous utilisons simplement un tramage normalisé 1LSB, il n'y a aucun problème au niveau des bords-cas, mais bien sûr, nous perdons les belles propriétés du tramage triangulaire (voir par exemple cette présentation ).
Une solution (pragmatique, empirique) (hack) consiste alors à revenir à [-0,5; 0,5 [tramage uniforme pour la casse):
Ce qui corrige les edgecases tout en gardant le tramage triangulaire intact pour la plage restante:
Donc, pour ne pas répondre à votre question: je ne sais pas s'il existe une solution plus solide mathématiquement, et je suis tout aussi désireux de savoir ce que Masters of Past a fait :) Jusque-là, au moins nous avons cet horrible hack pour faire fonctionner notre code.
EDIT
Je devrais probablement couvrir la solution de contournement-suggestion donnée dans la question, sur la compression simple du signal. Étant donné que la moyenne n'est pas linéaire dans les cas particuliers, la simple compression du signal d'entrée ne produit pas un résultat parfait - bien qu'elle fixe les points de terminaison:
Références
la source
dithertri
etdithernorm
au lieu d'un RNG indépendant. Une fois que vous aurez étudié toutes les mathématiques et annulé tous les termes, vous constaterez que vous ne lerpez pas du tout! Au lieu de cela, le code agit comme une coupure strictev < 0.5 / depth || v > 1 - 0.5/depth
, basculant instantanément vers la distribution uniforme. Non pas que cela enlève le joli tramage que vous avez, c'est juste inutilement compliqué. La correction du bug est en fait mauvaise, vous vous retrouverez avec un pire tramage. Utilisez simplement une coupure ferme.Je ne suis pas sûr de pouvoir répondre pleinement à votre question, mais j'ajouterai quelques réflexions et nous pourrons peut-être arriver à une réponse ensemble :)
Premièrement, le fondement de la question n'est pas clair pour moi: pourquoi considérez-vous qu'il est souhaitable d'avoir un noir / blanc propre lorsque toutes les autres couleurs ont du bruit? Le résultat idéal après tramage est votre signal d'origine avec un bruit entièrement uniforme. Si le noir et le blanc sont différents, votre bruit dépend du signal (ce qui pourrait être bien, car il se produit quand les couleurs sont de toute façon bloquées).
Cela dit, il y a des situations où le bruit en blanc ou en noir pose un problème (je ne suis pas au courant des cas où le noir et le blanc doivent être "propres" simultanément): lors du rendu d'une particule mélangée additivement comme un quadruple avec une texture, vous ne voulez pas de bruit ajouté dans tout le quad, car cela s'afficherait également à l'extérieur de la texture. Une solution consiste à compenser le bruit, donc plutôt que d'ajouter [-0,5; 1,5 [vous ajoutez [-2,0; 0,0 [(c'est-à-dire soustrayez 2 bits de bruit). C'est une solution assez empirique, mais je ne suis pas au courant d'une approche plus correcte. En y réfléchissant, vous voudrez probablement également augmenter votre signal pour compenser l'intensité perdue ...
Quelque peu apparenté, Timothy Lottes a fait une présentation au GDC sur la mise en forme du bruit aux parties du spectre là où il est le plus nécessaire, en réduisant le bruit dans la partie brillante du spectre: http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp- contenu / téléchargements / 2016/03 / GdcVdrLottes.pdf
la source
J'ai simplifié l'idée de Mikkel Gjoel de tramage avec bruit triangulaire en une fonction simple qui n'a besoin que d'un seul appel RNG. J'ai supprimé tous les bits inutiles, ce qui devrait être assez lisible et compréhensible:
Pour l'idée et le contexte, je vous renvoie à la réponse de Mikkel Gjoel.
la source
J'ai suivi les liens vers cette excellente question avec l'exemple shadertoy.
J'ai quelques questions sur la solution suggérée:
Bon travail! Je veux voir que j'ai bien compris votre ligne de pensée. Merci!
la source