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

Aktuelle Zeit: Do Jul 10, 2025 10:38

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



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Resolution independent rendering
BeitragVerfasst: Di Aug 10, 2010 15:15 
Offline
DGL Member

Registriert: Sa Jul 10, 2010 16:22
Beiträge: 16
Programmiersprache: C++
Wie kann ich denn bei folgendem Fragmentshader noch "Antialiasing" z.B. mit smoothstep hinzufügen?
Code:
void main(void)
{
   vec2 center_point = vec2(200.0, 200.0);
   float mydistance = distance(center_point, gl_FragCoord.xy);

   if (mydistance <= 50.0)
   {
      gl_FragColor = gl_Color;
   }
   else
   {
      discard;
   }
}


Zuletzt geändert von Mountainking am Do Aug 12, 2010 19:20, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Di Aug 10, 2010 18:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Verdeutliche bitte, worauf du hinaus willst…

greetings

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Di Aug 10, 2010 22:05 
Offline
DGL Member

Registriert: Fr Okt 03, 2008 13:32
Beiträge: 367
MSAA wird ja dadurch erreicht, dass man für jeden Bildschirmpixel mehrere Subpixel errechnet und den Durchschnitt bildet. Oder anders: Man rendert das Bild in höherer Auflösung und verkleinert es dann.

Also gibt es mehrere Möglichkeiten:

1. Möglichkeit: für jeden Pixel mehrere berechnen und den Durchschnitt bilden. z.B. so:

Code:
void main(void)
{
   vec2 center_point = vec2(200.0, 200.0);
   float Alpha=0.0;
   for (float i=0.0; i<=0.5; i+=0.5)
   {
      for (float j=0.0; j<=0.5; j+=0.5)
      {
         float mydistance = distance(center_point+vec2(i,j), gl_FragCoord.xy);

         if (mydistance <= 50.0)
         {
            Alpha+=0.25;
         }
      }
   }
   gl_FragColor=vec4(vec3(gl_Color),gl_Color[3]*Alpha);
}

Dafür muss man natürlich Blending anstellen. Da die Farbe auch überall gleich ist reicht es den Alphawert zu bestimmen.
Bei meinem Beispielcode wird der Pixel in 4 Teile geteilt, weshalb beim Alpha auch immer 1/4 drauf addiert wird.
Die Lösung kommt dem richtigen AA wohl am nächsten.

2. Möglichkeit: Man fügt einen kleinen Rand um den Kreis ein.
Code:
void main(void)
{
   vec2 center_point = vec2(200.0, 200.0);
   float mydistance = distance(center_point+vec2(i,j), gl_FragCoord.xy);

   float Alpha=clamp(1.0*(50.0-mydistance),0.0,1.0);
   gl_FragColor=vec4(vec3(gl_Color),gl_Color[3]*Alpha);
}

Der Faktor vor "(50.0-mydistance)" ist 1 dividiert durch die Randbreite. Also wenn die Zahl kleiner wird, wird der Rand breiter.
Auch hierfür muss Blending angeschaltet sein.

Die Multiplikation "gl_Color[3]*Alpha" in beiden Beispielen ist dafür da falls die Farbe schon eine Transparenz besitzt. Wenn nicht kann man da auch nur "Alpha" hinschreiben.

Ich hoffe mal das kommt in etwa an das heran was du erreichen wolltest.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Mi Aug 11, 2010 08:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Was du wohl brauchst ist folgende funktion.
* genType smoothstep (genType edge0, genType edge1, genType x)
* genType smoothstep (float edge0, float edge1, genType x)
Liefert 0.0 zurück, wenn x <= edge und 1.0 wenn x >= edge. Dabei wird eine weiche Hermite Interpolation zwischen 0 und 1 durchgeführt.
Ich benutze es bei meinem cubicbezier curve renderer, damit die kurven ein AA bekommen.
Code:
#version 130
out vec4 gl_FragColor;
void main(void)
{
   float v=pow(gl_TexCoord[0][0],3.0)-gl_TexCoord[0][1]*gl_TexCoord[0][2];
   float l=length(vec2(dFdx(v),dFdy(v)));
   float f=smoothstep(0.5-l,0.5+l,v);
   if (v<l*-0.5) discard;
   gl_FragColor=vec4(0.0,0.0,1.0,f);
}


Wenn du also mit smoothstep benutzt, dann musst du nur kurz vor geometryende anfangen und beim geometryende spätestens ausgefadet haben.
gl_FragColor = smoothstep(49.0,50.0,mydistance);

_________________
"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: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Mi Aug 11, 2010 13:05 
Offline
DGL Member

Registriert: Sa Jul 10, 2010 16:22
Beiträge: 16
Programmiersprache: C++
Danke euch
Code:
void main(void)
{
   vec2 center_point = vec2(325.0, 325.0);
   float mydistance = distance(center_point, gl_FragCoord.xy);

   float alpha = smoothstep(50.0, 49.0, mydistance);
        gl_FragColor=vec4(vec3(gl_Color), gl_Color[3] * alpha);
}


funktioniert prima. Ich habe allerdings nochein paar andere Probleme.

Nehmen wir mal eine Ellipse als Beispiel:
Code:
void main(void)
{
   vec2 center_point = vec2(200.0, 200.0);
   float radiusx = 100.0;
   float radiusy = 50.0;

   float sx = pow(gl_FragCoord.x - center_point.x, 2.0);
   float sy = pow(gl_FragCoord.y - center_point.y, 2.0);

   float equation = sx / pow(radiusx, 2.0) + sy / pow(radiusy, 2.0);

   if ((equation >= 0.9) && (equation <= 1.0))
   //if (equation == 1.0)
   {
      gl_FragColor = gl_Color;
   }
   else
   {
      discard;
   }
}


Der obige Code gibt mir eine schöne Ellipse die gefüllt ist. Wenn ich jetzt allerdings keine gefüllte Ellipse sondern nur den Umriss haben möchte habe ich das Problem das z.B. mit
Code:
if ((equation >= 0.9) && (equation <= 1.0))

Der Umriss der Ellipse nicht über all gleich dick ist. Und auch das Smoothstep funktioniert hier nicht mehr so einfach wie noch bei dem Kreis.

@TAK2004
Wie renderst du denn den cubic Bezier Shader? Bei mir kommen nur Dreiecke oder Quadrate raus?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Mi Aug 11, 2010 16:06 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Dafür brauch es ein recht aufwändigen vorberechnung der UV Koordinaten, da diese die umgerechneten Stützpunkte wiederspiegeln.
Ich hatte auch mal Probiert Kubische Bezierkurven als linien dar zu stellen aber da hat mir die ungenauigkeit ein strich durch die rechnung gemacht und es kamen an einigen stellen verschwommende breitere streifen raus.
Ich würde aus dem stehgreif erstmal mit 2 schritten machen.
float alpha = smoothstep(50.0, 50.5, mydistance)*step(50.0,mydistance);//sollte von 50.5 nach 50.0 rein blenden und alles unter 50.0 und über 50.5 mit 0 setzen
alpha += (1.0-smoothstep(50.0, 49.5, mydistance))*step(49.5,mydistance);//1-smoothstep invertiert das blending(wird zum rand hin sichtbar),step wird 0 wenn kleiner 49.5 und 1 wenn >49.5 und multipliziert sollte es dann von 49.5 bis 50.0 ein einblenden hinzufügen sonnst sollte immer 0 drauf addiert werden
Nicht getestet aber wenn ich keine mathematischen fehler gemacht hab, dann sollte das so gehen.

_________________
"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: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Mi Aug 11, 2010 21:45 
Offline
DGL Member

Registriert: Sa Jul 10, 2010 16:22
Beiträge: 16
Programmiersprache: C++
Ist es überhaupt möglich die Outline/Stroke von z.B. Bezier/B-Splines mit Shadern vernünftig zu rendern? Ich suche schon seit Tagen im Internet und habe noch nichts gefunden. Die Kurve sollte auflösungsunanbhängig sein. Vielleicht kann mal jemand ein Beispiel Shader posten.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Do Aug 12, 2010 10:24 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Wie ich bereits sagte ist die genauigkeit unzureichend, das liegt daran, das die genutzten Formeln eine annäherung sind, welche auf der Funktionslinie exakt ist und von dieser weg immer ungenauer wird. Hoppe von Microsoft Research hat das sehr genau beleuchtet und Lösungen entwickelt. Wenn ich mich recht entsinne ist die Outline ein extra Mesh.

_________________
"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: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Do Aug 12, 2010 11:25 
Offline
DGL Member

Registriert: Sa Jul 10, 2010 16:22
Beiträge: 16
Programmiersprache: C++
Bezog sich dein letzter Post jetzt nur auf die Bezier-Kurve oder generell auf das Rendern von Kurven? Was meinst du mit Funktionslinie. Sind Berechnungen auf der GPU (im Vergleich zur CPU) ungenau? Ist das also der Grund warum der Ellipsen-Shader weiter oben von mir unterschiedliche Liniendicken hat?

Hier hat jemand das gleiche Problem gehabt:
http://www.gamedev.net/community/forums/topic.asp?topic_id=505331

Du meinst wahrscheinlich diesen Artikel http://research.microsoft.com/en-us/um/people/hoppe/pm.pdf?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Smoother Umriss eines Kreises
BeitragVerfasst: Do Aug 12, 2010 13:16 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich meine den Link.
http://research.microsoft.com/en-us/um/people/hoppe/ravg.pdf
Seite 5.

Bei Kubischen und Quadratischen Bezierkurven nutzt man Näherungsformeln, wegen Geschwindigkeit.
Die Rahmen sind keine Ränder, sondern ein neues Mesh.

_________________
"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: Re: Resolution independent rendering
BeitragVerfasst: Do Aug 12, 2010 19:27 
Offline
DGL Member

Registriert: Sa Jul 10, 2010 16:22
Beiträge: 16
Programmiersprache: C++
Also, wenn ich das richtig sehe gehen die einfach hin ind berechnen für jeden Pixel eine Normale die Senkrecht auf der Kurve liegt und entscheiden dann anhand der Entfernung Punkt Kurve ob der Pixel gezeichnet werden soll.


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


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.009s | 16 Queries | GZIP : On ]