Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 30, 2025 23:18

Foren-Übersicht » Programmierung » Shader
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Realtime S3TC kompressor
BeitragVerfasst: Mo Jul 31, 2006 17:56 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Man hat immer zu wenig Vram. Selbst wenn man ein GB hätte wäre es zu wenig. Irgend wie kam in einem IRC channel die Frage auf, ob es nicht möglich wäre Framebufferobjekte zu komprimieren. Nach einigem überlegen war mir klar, das es zumindest über umwege möglich wäre eine Textur im S3TC format per shader zu komprimieren. Beim Suchen fand ich dann diese Seite:
http://graphics.cs.lth.se/research/papers/gputc2006/
Nach dem ich das Paper gelesn hatte, sind mir noch ein paar Verbesserungen eingefallen, mit denen die kompression noch effektiver ablaufen kann (die 4x float16 ausgabe lässt sich nuten, wenn die float werte aus Texturen gelesen werden) Dazu könnte man die Qualität von S3TC noch deutlich verbessern, wenn die helligkeit gegen über den Farben beforzugt werden. Halt so ähnlich wie bei Jpeg, wo die Farbe nur die halbe Auflösung der Helligkeit hat. Mit einem angepasstem algoritmuss würden die Blockartefakte von S3TC wesendlich geringer werden...

Das größte problem dabei wäre der Texture cast. Deren lösung besteht darin die Textur herunter und wieder hochzuladen....

Was haltet ihr davon? Sinn macht ein solcher shader vorallem bei RGB Framebufferobjekten, der rest kann ja schon voher komprimiert werden...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Aug 01, 2006 10:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ob es was bringt, würde ich erst sagen wenn es mal getestet wurde.
Es kommt ja auf die Zeitverluste an die durch das extra verarbeiten anfallen.
Wenn diese relativ gering sind und eventuell das verschieben von Texturen zwischen VRam und Ram schlagen könnte, dann wäre es eine sehr praktische sache.

Eventuell sollte man auch mal probieren die Texturdaten in Wavelet form zu übergeben und per shader dann zurück zuwandeln.
Einer der Vorteil von Wavelet ist ja das ohne mehr platzverbrauch Mipmaps möglich sind. Wavelet ist auch sehr freundlich gegenüber verlustbehaftetem kompremieren. So kann man einfach alle Werte die z.B. 0.25 unterschreiten auf 0 setzen.

Aber sowas muss man alles ausprobieren um zu sehen ob es sich lohnt.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 03, 2006 15:21 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Hier ist das erste konzept. es könnten noch diverse Fehler drin sein:

Code:
  1. uniform sampler2D Texture0;
  2. uniform sampler2D Lookup2D; //256x256 lookuptable for indizies
  3. uniform sampler3D Lookup3D; //32x64x32 lookuptable for colors
  4.  
  5. #define sz = 1.0 / 4096
  6.  
  7.  
  8. const vec2 texofset[16] = {vec2 (-1.5 * sz,-1.5 * sz), vec2 (-0.5 * sz,-1.5 * sz), vec2 (0.5 * sz,-1.5 * sz), vec2 (1.5 * sz,-1.5 * sz),
  9.                                vec2 (-1.5 * sz,-0.5 * sz), vec2 (-0.5 * sz,-0.5 * sz), vec2 (0.5 * sz,-0.5 * sz), vec2 (1.5 * sz,-0.5 * sz),
  10.                                    vec2 (-1.5 * sz, 0.5 * sz), vec2 (-0.5 * sz, 0.5 * sz), vec2 (0.5 * sz, 0.5 * sz), vec2 (1.5 * sz, 0.5 * sz),
  11.                                            vec2 (-1.5 * sz, 1.5 * sz), vec2 (-0.5 * sz, 1.5 * sz), vec2 (0.5 * sz, 1.5 * sz), vec2 (1.5 * sz, 1.5 * sz)};
  12. const float fac[4] = {1.0,4.0,16.0,64.0};
  13.  
  14. vec4 inputs[16];
  15.  
  16. main(){
  17.  
  18.         vec4 middle=vec3(0.0,0.0,0.0,0.0);
  19.     int i;
  20.         for (i=0;i<16;i++){
  21.         inputs[i].rgb=texture2D(Texture0, vec(gl_TexCoord[0])+texofset[i]);
  22.         inputs[i].a = dot(inputs[i].rgb,vec3(0.299, 0.587, 0.114));
  23.         middle += inputs[i];
  24.         }
  25.     middle /= 16.0;
  26.  
  27.     vec4 delta = vec3(0.0,0.0,0.0,0.0);
  28.     float deltac = 0.0;
  29.         for (i=0;i<16;i++){
  30.         if (inputs[i].a > middle.a){
  31.             delta += inputs[i];
  32.             deltac += 1.0;
  33.             }
  34.         }
  35.     delta = (delta / deltac - middle) * 2.0;
  36.     gl_FragColor.r = texture3D(Lookup3D, middle.rgb + delta.rgb ); //First color
  37.         gl_FragColor.g = texture3D(Lookup3D, middle.rgb - delta.rgb ); //Secondary Color
  38.    
  39.     float B[3];
  40.     B[0]=middle.a + delta.a * 0.6667;
  41.     B[1]=middle.a;
  42.     B[2]=middle.a - delta.a * 0.6667;
  43.     float index[4];
  44.     for (i=0;i<4;i++){
  45.         index[i]=0.0;
  46.         for (int j=0; j<4 ;j++){
  47.                         if (inputs[i*4+j].a > B[0]){  
  48.                 // It's color 0 (ligth) do nothing
  49.                 break;
  50.                 }
  51.             if (inputs[i*4+j].a > B[1]){  
  52.                 index[i] += fac[j] * 2.0; // It's color 2 (lighter)
  53.                 break;
  54.                 }
  55.             if (inputs[i*4+j].a > B[2]){  
  56.                 index[i] += fac[j] * 3.0; // It's color 3 (darker)
  57.                 break;
  58.                 }
  59.             index[i] += fac[j] * 1.0; // It's color 1 (dark)
  60.             }     
  61.         }
  62.     gl_FragColor.b = texture2D(Lookup2D, vec2(index[0],index[1])); //Samples 0 to 7
  63.     gl_FragColor.a = texture2D(Lookup2D, vec2(index[2],index[3])); //Samples 8 to 15
  64.     }


Das Rendertarget mit 16 bit Pro Kanal zur Verfügung stellen, damit die 64 bit für die S3TC kompressionsblöcke ereicht werden. Die 4 zusätzlichen Texturlookups sind nötig um auch float16 als rendertarget zu verwenden, da dies neben 2x float der einziege 64bit Rendermode ist der auf Nvidiakarten läuft. Eventuell ist die interne Organisation von Nvidiakarten anders, so das eine andere Anordnung schneller ist

Weiterhin fehlt erst einmal der Code, der die 4x Float16 Textur in eine S3TC mit der 4x Auflösung casted (16x so viele Pixel)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 04, 2006 14:21 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Inzwischen habe ich einen shader, der sich sogar laden lässt. Mit dem cgc compeliert bringt er es auf ganze 419 Instruktionen. Somit werden zum komprimieren eines Pixels etwa 26 Instrukionen gebraucht. Immerhin kann man sehen, dass sämpliche Forschleifen entrollt wurden und das selbst die 16 vec2 konstanten zu einem einfachem floatvektor umgebaut werden.
Prinzipell sollte GLSL im algeminen keinen nachteil gegenüber einem assembler program haebn, aber man vergisst schnell, das einiges an code 16 x ausgeführt wird...

Code:
  1.  
  2. uniform sampler2D Texture0;
  3. uniform sampler2D Lookup2D; //256x256 float16 lookuptable for indizies
  4. uniform sampler3D Lookup3D; //32x64x32 float16 lookuptable for colors, both are filled with shorts from 0 to 2^16
  5.  
  6. #define SZ1  0.5 / 4096.0
  7. #define SZ2  1.5 / 4096.0
  8.  
  9.  
  10. const vec2 texofset[16] = {vec2 (-SZ2,-SZ2), vec2 (-SZ1,-SZ2), vec2 (SZ1,-SZ2), vec2 (SZ2,-SZ2),
  11.                vec2 (-SZ2,-SZ1), vec2 (-SZ1,-SZ1), vec2 (SZ1,-SZ1), vec2 (SZ2,-SZ1),
  12.                vec2 (-SZ2, SZ1), vec2 (-SZ1, SZ1), vec2 (SZ1, SZ1), vec2 (SZ2, SZ1),
  13.                            vec2 (-SZ2, SZ2), vec2 (-SZ1, SZ2), vec2 (SZ1, SZ2), vec2 (SZ2, SZ2)};
  14. const float fac[4] = {1.0,4.0,16.0,64.0};
  15.  
  16. vec4 inputs[16];
  17.  
  18. void main(){
  19.  
  20.         vec4 middle=vec4(0.0,0.0,0.0,0.0);
  21.     int i =0;
  22.         for (i=0;i<16;i++){
  23.         inputs[i].rgb=texture2D(Texture0, vec2(gl_TexCoord[0])+texofset[i]).rgb;
  24.         inputs[i].a = dot(inputs[i].rgb,vec3(0.299, 0.587, 0.114)); // caluculate Hue
  25.         middle += inputs[i];
  26.         }
  27.     middle /= 16.0;
  28.  
  29.     vec4 delta = vec4(0.0,0.0,0.0,0.0);
  30.     float deltac = 0.0;
  31.         for (i=0;i<16;i++){
  32.         if (inputs[i].a > middle.a){
  33.             delta += inputs[i];
  34.             deltac += 1.0;
  35.             }
  36.         }
  37.     delta = (delta / deltac - middle) * 2.0;
  38.     gl_FragColor.r = texture3D(Lookup3D, middle.rgb + delta.rgb ).r; //First color
  39.         gl_FragColor.g = texture3D(Lookup3D, middle.rgb - delta.rgb ).r; //Secondary Color
  40.    
  41.     float B[3];
  42.     B[0]=middle.a + delta.a * 0.6667;
  43.     B[1]=middle.a;
  44.     B[2]=middle.a - delta.a * 0.6667;
  45.     float index[4]={0.0,0.0,0.0,0.0};
  46.    
  47.     for ( i=0; i<4 ;i++)
  48.     for (int j=0; j<4 ;j++){
  49.         if (inputs[j+4*i].a > B[1]){  
  50.             if (inputs[j+4*i].a < B[0]){
  51.                 index[i] += fac[j] * 3.0;
  52.                 }
  53.             else{
  54.                 index[i] += fac[j] /** 1.0*/;
  55.                 }
  56.             }
  57.         else{
  58.             if (inputs[j+4*i].a > B[2]){
  59.                 index[i] += fac[j] * 2.0;
  60.                 }
  61.             /*else{
  62.                 index[i] += fac[j] * 0.0;
  63.                 }*/
  64.             }
  65.         }     
  66.    
  67.     gl_FragColor.b = texture2D(Lookup2D, vec2(index[0],index[1])).r; //Samples 0 to 7
  68.     gl_FragColor.a = texture2D(Lookup2D, vec2(index[2],index[3])).r; //Samples 8 to 15
  69.     }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 07, 2006 02:52 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
SO der erste Code läuft http://cpux.de/s3tc.tar.bz2 Es gibt kleine einschränkungen und der Algoritmus ist noch nicht der beste.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Foren-Übersicht » Programmierung » Shader


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 16 Queries | GZIP : On ]