2015-03-16 1 views
2

Voici une conversion de 32 bits flottant par canal en "octet non signé" par normalisation de couleur de canal pour économiser de la bande passante pci-express pour d'autres choses. Parfois, il peut y avoir des rayures de couleur et elles ne sont pas naturelles.Comment éviter les bandes de couleur

Comment puis-je éviter cela? Surtout au bord des sphères.

canaux de couleur Float: enter image description here

canaux d'octets non signés: enter image description here

Ici, bord jaune sur la sphère bleu et le bord bleu sur le rouge ne devrait pas exister.

I utilisé Normalization (du noyau OpenCL):

// multiplying with r doesnt help as picture color gets too bright and reddish. 
float r=rsqrt(pixel0.x*pixel0.x+pixel0.y*pixel0.y+pixel0.z*pixel0.z+0.001f); 
unsigned char rgb0=(unsigned char)(pixel0.x*255.0); 
unsigned char rgb1=(unsigned char)(pixel0.y*255.0); 
unsigned char rgb2=(unsigned char)(pixel0.z*255.0); 
rgba_byte[i*4+0]=rgb0>255?255:rgb0; 
rgba_byte[i*4+1]=rgb1>255?255:rgb1; 
rgba_byte[i*4+2]=rgb2>255?255:rgb2; 
rgba_byte[i*4+3]=255; 

Reliure à tampon:

GL11.glEnableClientState(GL11.GL_COLOR_ARRAY); 
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, id); 
GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 4, 0); 

utilisant LWJGL (contexte glfw) dans un environnement java. Comme Andon M. a dit, j'ai serré avant de lancer (je ne pouvais pas voir quand j'ai dormi lourdement) et cela a résolu.

La qualité des couleurs n'est pas excellente, mais l'utilisation d'un tampon de couleur plus petit a amélioré les performances.

enter image description here

+0

Où cette normalisation se produit-elle? Java n'a pas de type de données 'unsigned' et ni GLSL ni Java ne savent ce qu'est un' char'. –

+0

Sortie provenant du contexte opencl.En utilisant un tableau d'octets pour les recevoir, mais n'est pas la même représentation binaire puisque je ne touche pas jusqu'à ce que sening to gl? –

+0

@ AndonM.Coleman java a un caractère mais il s'agit d'une valeur de 16 bits. –

Répondre

3

Votre ensemble de données d'origine contient des valeurs en virgule flottante normalisée en dehors de la [0,0 , 1,0] gamme, qui, après multiplication par 255,0 et de coulée à unsigned char produit trop-plein. La fausse couleur que vous avez rencontrée se produit dans les zones de la scène qui sont exceptionnellement lumineuses dans un ou plusieurs composants de couleur.

Il semble que vous saviez d'attendre ce débordement quand vous avez écrit rgb0>255?255:rgb0, mais cette logique ne fonctionne pas parce que quand un unsigned char déborde, il enroule autour de au lieu d'un plus grand nombre de .

      La solution minimale à ce problème serait de serrer les couleurs en virgule flottante dans l'intervalle [0,0, 1,0]       avant la conversion en virgule fixe 0,8 (8 bits couleur non signée normalisée), pour éviter le débordement. Toutefois, s'il s'agit d'un problème fréquent, il est préférable de mettre en œuvre un post-traitement HDR vers LDR. Vous devez identifier le pixel le plus lumineux dans une région (ou la totalité) de votre scène, puis normaliser toutes les couleurs dans cette plage. Vous étiez en quelque sorte en train de l'implémenter pour commencer (avec r = sqrt (...)), mais il utilisait seulement la magnitude du pixel courant pour normaliser la couleur.