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

Aktuelle Zeit: Fr Jul 04, 2025 00:43

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 32 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
BeitragVerfasst: Di Aug 17, 2010 00:44 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Hallo :twisted:

Verzweifelt musste ich feststellen, dass es leider keine Hilfsmethode wie gluUnproject zur Umwandlung von Mauskoordinaten auf dem Bildschirm in Objektkoordinaten für WebGL gibt. Diese Umwandlung benötige ich, um anschließend einen Point-In-Polygon-Test anzuwenden. Dieser Algorithmus soll mir sagen, ob ich das Objekt angeklickt habe oder nicht. Falls ja, möchte ich das ensprechende Objekt z.B. rotieren lassen oder farbig hervorheben.

Bevor ich jetzt mit komplizierten Berechnungen anfange, die Monate andauern würden, wollte ich fragen, ob es da eine einfache Lösung gibt, um von der Klickposition der Maus zu den ursprünglichen Modell-Koordinaten zu kommen?

Zu den Bildschirmkoordinaten komme ich ja durch die Viewing-Pipeline:
modelviewMatrix*Projektionsmatrix*Modellkoordinaten=Pixelkoordinaten.
Aber wie sieht der umgekehrte Weg aus?

grüße


Zuletzt geändert von m.sirin am Mi Aug 18, 2010 00:49, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 08:22 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
modelviewMatrix*Projektionsmatrix*Modellkoordinaten=Pixelkoordinaten.

Nicht ganz, eher so:
Code:
tmp := Viewport*Projektion*View*Modell * vertex
pixel := tmp / tmp.w


Für die Umkehrung musst du nur die Matrix invertieren:
Code:
tmp := inverse(Viewport*Projektion*View*Modell) * pixel
vertex := tmp / tmp.w


Code zum invertieren einer Matrix findest du in meinen Projekten WGT und CoolMath.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 08:29 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
Zitat:
Dieser Algorithmus soll mir sagen, ob ich das Objekt angeklickt habe oder nicht.
ähm... ich kenn mich jetzt nicht wirklich mit WebGL aus, aber soqwas macht man gewöhnlich mit Color Picking http://wiki.delphigl.com/index.php/Tutorial_ColorPicking_Shader.

Das mit dem UnProject wäre wahrscheinlich ungenau genug, dass der Point in Polygon Test irgendwelchen Mist produziert. Mal abgesehen davon, dass ein Point in Polygon Test in 2D auch nicht schwerer ist, als in 3D.

mfg

sharkman


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 08:36 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
ähm... ich kenn mich jetzt nicht wirklich mit WebGL aus, aber soqwas macht man gewöhnlich mit Color Picking.

Liegt immer daran was man genau machen will. Wenn du nicht nur das Objekt sondern die genaue Position auf dem Objekt benötigst hilft dir Color-Picking alleine nicht viel. Beide Methoden haben ihre Berechtigung.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 12:04 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Coolcat hat geschrieben:
Liegt immer daran was man genau machen will. Wenn du nicht nur das Objekt sondern die genaue Position auf dem Objekt benötigst hilft dir Color-Picking alleine nicht viel. Beide Methoden haben ihre Berechtigung.

In den meisten Fällen werde ich wahrscheinlich nur ungenaue Positionen brauchen, hauptsache das Objekt ist ausgewählt. Es kann aber durchaus vorkommen, dass ich mal genauere Koordinaten brauche, auch jene genaue Position auf dem Objekt. Dann ist dieses manuelle "unproject" mit der inversen Pipeline-Matrix zu ungenau?

sharkman hat geschrieben:
Mal abgesehen davon, dass ein Point in Polygon Test in 2D auch nicht schwerer ist, als in 3D.

Ist das Ironie?



Habe jetzt den Lösungsansatz von Coolcat genommen, weil er auf dem ersten Blick ziemlich einfach scheint. Nachdem ich die Inverse der Gesamtmatrix bilde und sie mit den Pixelkoordinaten multipliziere, sehe ich erstmal vertraute Objekt-Koordinaten. Es scheint halbwegs funktioniert zu haben, trotz dem, dass die Koordinaten noch große Ungenauigkeiten haben. Was mich zudem irritiert: Wenn ich das Objekt nach links verschiebe, werden die berechneten Koordinaten des Objekt größer, obwohl sie hätten kleiner werden müssen. Das Gleiche gilt für die y-Richtung.

Vielleicht sieht jemand den Fehler, den ich mache?

Code:
mvPushMatrix();
    ...
    mvTranslate([-3489860.0, -5557180.0, -457]);
   ...
    setMatrixUniforms();
    gl.drawElements(gl.TRIANGLES,cylinderIndices.length,gl.UNSIGNED_SHORT,0);
  ...
 
   var v = Vector.create([200,200,0,1]);    //200, 200 = Pixelkoordinaten
   var gesamt=getViewportMatrix(700,530).multiply(pMatrix).multiply(mvMatrix);
   var gesamt_inv=gesamt.inverse().multiply(v);

   //hier gebe ich das Ergebnis, dividiert durch die homogene Komponente, aus.
mvPopMatrix();


die Viewport Matrix sieht so aus, mit w=viewportWidth,h=viewportHeight:

Code:
[w/2, 0, 0, w/2],
[0, h/2, 0, h/2],
[0, 0, 1, 0],
[0, 0, 0, 1];


oder auch
Code:
[w, 0, 0, 0]
[0, −h, 0, h]
[0, 0, 1, 0]
[0, 0, 0, 1]


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 12:45 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Dann ist dieses manuelle "unproject" mit der inversen Pipeline-Matrix zu ungenau?

Das Verfahren ist genauer...das ist das Problem ;)
Beim rendern werden die Pixelkoordinaten nämlich gerundet (*), weil der Framebuffer ja nur ganzzahlige Pixelkoordinaten kennt. Da geht also Information verloren die durch die Rücktransformation nicht wiederherstellen kannst. Beim Color-Picking rechnest du aber vorwärts (nicht rückwärts) daher ist das Ergebnis auch das was der User sieht. Aber um die Position (und nicht nur das Objekt) zu kennen auf die der User geklickt hat musst du halt in irgendeiner Form zurückrechnen.

Zitat:
Was mich zudem irritiert: Wenn ich das Objekt nach links verschiebe, werden die berechneten Koordinaten des Objekt größer, obwohl sie hätten kleiner werden müssen. Das Gleiche gilt für die y-Richtung.

Cursor-Koordinaten spiegeln?


(*) Es gibt da gewisse Regeln die dafür sorgen die Grenzen zwischen Polygonen eindeutig sind. Aber vom Prinzip wird da gerundet. (Für mehr Infos das Stichwort Rasterization)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 14:48 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Zitat:
Cursor-Koordinaten spiegeln?

Lag nicht daran, sondern an einen Denkfehler von mir, d.h. es gab nie ein solches Problem^^

Doch nun habe ich wohl ein Problem, denn die Koordinaten zeigen sich unbeeindruckt von meinen Cursorpositionen: Die angezeigten Koordinaten entsprechen den Werten des letzten translates vor drawElements (siehe meinen Post vor diesem). Wenn ich nun die Mauskoordinaten von sagen 200,200 auf 0,0 verändere, tut sich bei den von mir umgewandelten Koordinaten fast gar nichts (obwohl sich die Werte deutlich ändern müssten!): nur die Nachkommastellen verändern sich signifikant. Doch sobald ich das Objekt rotiere oder verschiebe, sind starke Veränderungen bei den Koordinaten zu sehen. Auch die Viewportmatrix scheint in der Multiplikationskette nahezu nichts zu bewirken.

Ich habe nun schon viel rumprobiert und überlegt, weiß aber nicht woran es liegt.. :?

An sich mache ich es doch richtig, oder?

Noch eine Frage: Lässt sich das von sharkman erwähnte color-picking (mit oder ohne shader) auch für webgl realisieren? Ich habe beim Durchlesen der Tutorials einige Dinge wie displayList gesehen, die es für webgl nicht gibt, deshalb frage ich..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Aug 17, 2010 15:30 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
An sich mache ich es doch richtig, oder?

Eigentlich schon.

@Color-picking: Color-picking heißt einfach nur das du jedes Objekt in einer eindeutigen Farbe renderst. Dann liest du die Farbe des Pixels unter dem Cursor aus und weißt somit welches Objekt angeklickt wurde. Ob du nun Displaylisten oder VBO benutzt ist egal.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 18, 2010 18:30 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Coolcat hat geschrieben:
Zitat:
An sich mache ich es doch richtig, oder?

Eigentlich schon.

gut, ich leg das Vorhaben erstmal auf Eis, es funktioniert einfach nicht. oder soll ich mal den ganzen code posten?
Zitat:
@Color-picking: Color-picking heißt einfach nur das du jedes Objekt in einer eindeutigen Farbe renderst. Dann liest du die Farbe des Pixels unter dem Cursor aus und weißt somit welches Objekt angeklickt wurde. Ob du nun Displaylisten oder VBO benutzt ist egal.


Dann will ich mal mit colorpicking rummachen.
Meine Hauptfrage hierbei: Wie weise ich dem Objekt eine "Zweitfarbe" im backbuffer zu ? sowas wie Mit readPixels() kann ich das ja wieder herauslesen. Diese Funktion scheint aber ziemlich ungenau zu sein, da ich manchmal sehr weit reinzoomen muss und mehrere Stellen des jeweiligen Objektes anklicken muss, damit er erkennt, dass es ein anderes Objekt ist (habe ein paar blaue Zylinder auf einigen grauen Platten). Oder liegt es daran, dass ich ein translate in z-Richtung um -7000 Einheiten habe?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Aug 18, 2010 19:39 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Dez 11, 2009 08:02
Beiträge: 532
Programmiersprache: pascal (Delphi 7)
Zitat:
Wie weise ich dem Objekt eine "Zweitfarbe" im backbuffer zu ?
Eine Möglichkeit wäre, die Objekte in ein Array zu schreiben, und dann den Index als Farbe zu benutzen. Ich glaube, so ähnlich stand das auch im Tutorial. Wichtig ist halt, dass eine Farbe nicht mehr als ein Objekt hat.
Zitat:
Diese Funktion scheint aber ziemlich ungenau zu sein (...)
Also, keine Ahnung, woran das liegt. Wenn die Farbe so im Framebuffer (oder wo sie halt hinkommt) landet, wie sie festgelegt wurde, sollte das Problem eigentlich nicht auftreten. Beleuchtet wird da nix und so :wink:
Das mit dem Translate sollte eigentlich egal sein. Ändert schließlich nicht die Farbe 8)

Zitat:
Ist das Ironie?
Hast recht. ich sollte mal anfangen, Smilies zu benutzen. Hoffentlich sind die Smilies da oben einigermaßen passend.
Und hoffentlich stimmt das, was ich geschrieben hab, dieses Mal.

mfg

sharkman


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 19, 2010 07:33 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Das mit der ungenauigkeit kann daran liegen, das zwei unterschiedlich gefärbte Flächen sehr nach zusammenrücken (durch die entfernung) und das Pixel im Puffer quasi eine "Mischfarbe" darstellt.

Beim Colorpicking ist außerdem extrem wichig, dass keinerlei effekte aktiv sind, welche die Farbe beeinflussen. Also keine Texturen (klar) aber auch keine Beleuchtung, kein Fog oder der gleichen. Einfach platte farben, mehr nicht. Dann ist die selektion pixelgenau - außer, wie erwähnt in großer entfernung liegen Flächen zu nach zusammen und mischen sich im Pixel..

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 19, 2010 08:58 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
außer, wie erwähnt in großer entfernung liegen Flächen zu nach zusammen und mischen sich im Pixel..

Pixelfarben von verschiedenen Polygonen werden nicht vermischt, zumindest solange nicht Antialias, ein Blue-Filter oder ähnliches aktiv ist.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 19, 2010 11:45 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Danke für eure Antworten!

sharkman hat geschrieben:
Zitat:
Wie weise ich dem Objekt eine "Zweitfarbe" im backbuffer zu ?
Eine Möglichkeit wäre, die Objekte in ein Array zu schreiben, und dann den Index als Farbe zu benutzen. Ich glaube, so ähnlich stand das auch im Tutorial. Wichtig ist halt, dass eine Farbe nicht mehr als ein Objekt hat.


Als Anfänger in Opengl/Webgl weiß ich leider immer noch nicht wie ich das konkret machen soll. Bisher habe ich jedem VBO so eine Farbe zugewiesen und zum direkten Färben verwendet:
Code:
    shaderProgram.color = gl.getAttribLocation(shaderProgram, "color");
    gl.enableVertexAttribArray(shaderProgram.color);
   
    ...
    var objektBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, objektBuffer);
    var vertices=[...];
    gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
     
    ...
    gl.bindBuffer(gl.ARRAY_BUFFER, cylinderBuffer);
    gl.vertexAttribPointer(shaderProgram.position, 3, gl.FLOAT, false, 9*4, 0*4);
    gl.vertexAttribPointer(shaderProgram.color, 3, gl.FLOAT, false, 9*4, 3*4);
    gl.vertexAttribPointer(shaderProgram.normals, 3, gl.FLOAT, false, 9*4, 6*4);

    ...
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, objektIndicesBuffer);
    gl.drawElements(gl.TRIANGLES, objektIndices.length, gl.UNSIGNED_SHORT, 0);



Wo und wie kann ich hier eine weitere Farbe (oder was auch immer?) mitgeben, die unsichtbar bleibt und die ich dann später abfragen kann?



Flash hat geschrieben:
Beim Colorpicking ist außerdem extrem wichig, dass keinerlei effekte aktiv sind, welche die Farbe beeinflussen. Also keine Texturen (klar) aber auch keine Beleuchtung, kein Fog oder der gleichen. Einfach platte farben, mehr nicht. Dann ist die selektion pixelgenau - außer, wie erwähnt in großer entfernung liegen Flächen zu nach zusammen und mischen sich im Pixel..


Meine Szene hat eine Beleuchtung. Heißt das jetzt, dass ich colorpicking nicht benutzen kann, oder kann ich die Zweitfarbe von den Effekten unberührt lassen?


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 19, 2010 12:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Wo und wie kann ich hier eine weitere Farbe (oder was auch immer?) mitgeben, die unsichtbar bleibt und die ich dann später abfragen kann?

Du benutzt doch WebGL, also auch Shader. Es empfiehlt sich einen extra Color-Picking-Shader zu benutzen. Die Farbe übernimmst du einfach aus einer uniform-Variable. Ein solcher Shader könnte z.B. wie folgt aussehen. Über useVertexColors kannst du wählen ob die Farbe pro Vertex sein soll oder global per uniform-Variable gesetzt wird. Ich nutze Pro-Vertex-Farben wenn z.B. einzelne Vertices selektiert werden sollen und die uniform-Variante wenn ganze Objekte ausgewählt werden.

(Edit: Die folgenden Shader sind natürlich nicht WebGL-geeignet...aber es geht ja nur um die Idee...)

Code:
//vertexshader
uniform vec4 color;
uniform bool useVertexColors;

void main() {
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

   gl_FrontColor = useVertexColors ? gl_Color : color;
   gl_BackColor = gl_FrontColor;
}

Code:
//fragmentshader
void main() {
   gl_FragColor = gl_Color;
}


Zitat:
Meine Szene hat eine Beleuchtung. Heißt das jetzt, dass ich colorpicking nicht benutzen kann, oder kann ich die Zweitfarbe von den Effekten unberührt lassen?

Du musst einfach nur die Effekte beim Color-Picking abschalten und im Anschluss wieder einschalten ;)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Do Aug 19, 2010 15:37 
Offline
DGL Member

Registriert: Fr Jul 16, 2010 18:28
Beiträge: 40
Okay, ich will erstmal nur jedes Objekt mit einer Farbe versehen. Daher übergebe ich die Farbe an eine uniform-Variable im vertexshader.
Und wie sage ich dem Ganzen, dass die Objekte in dieser zusätzlich übergebenen Farbe nicht gezeichnet werden sollen, sonden nur in einem zweiten Buffer (?) landen sollen?


.........vergebt mir mein Unwissen :oops:


sowas habe ich versucht, was aber nicht klappt, da die neue Farbe direkt gerendert wird:

Code:
void main() {
   gl_FrontColor = myColor;
   gl_BackColor = gl_FrontColor;

  if(selection){
      gl_FrontColor = myNewColor;
      gl_BackColor = gl_FrontColor;
  }
}


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 32 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 12 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.010s | 15 Queries | GZIP : On ]