Probleme mit eigenem Shader

Started by Gidy, September 04, 2013, 05:07:48 PM

Previous topic - Next topic

Gidy

Hallo zusammen,

Ich implementiere gerade eine Visualsierung von 3D-Modellen und möchte gerne abhängig vom Lichteinfallswinkel die Farbe eines Polygons verändern. (Rot = senkrechter Einfall , Schwarz = Parallel zum Lichtstrahl) und zwischen Werte dementsprechend mit einer Interpoliertenfarbe darstellen.


1. Mein erster Ansatz war imm die Polygontexturen über den Texturenmanager jeweils einzelen anzupassen. Dazu hab ich die Normalenberechnet (kann man sich auch von JPCT ausgeben lassen) und dan mit dem Richtungsvektor der Lichtquelle den Einfallswinkel berechnet und anschließend die entsprechende Farbe gesetzt. Bei zu großen Objekten war diese Variante sehr langsam. (Hab das immer in meiner update() Methode des Renderthreads gemacht).

2. Als zweiten Ansatz hab ich dan gedacht ich greife auf Shader zurück, da diese ja wesentlich schneller berechnet werden. Im groben und ganzen funktioniert es auch, siehe Darstellung des Flugzeuges. Nur wenn ich nur ein Objekten mit geringer Polygonanzal und Flacheflächen lade geht irgendwas schief (Siehe kleines Bild links oben), im ShaderDesigner (Rechts kleine Bild oben) hingegen wird alles korrekt dargestellt.

Jemand vieleicht eine Idee woran das liegen könnte? Meine Vermutung ist das ich irgendwas mit der Normalenberechnung der Vertex falsch mache.




VertexShader:


  • lightDir - Richtungsvektor der Lichtquelle (ich benutze momentan den Vektor (0,0,1)
  • colors - Liste von Farben zwischen denen Interpoliert wird (Schwarz,Blaui,Cyan,Grün,Gelb,Orange,Rot)
  • interpolation- Mit wievielen zwischenschritten Interpoliert werden soll.  (255)


uniform vec3 lightDir ;
uniform vec3 colors[6] ;
uniform int interpolation;
varying float intensity;
void main()
{
gl_Position = ftransform();
                 
                //Berechnet den Winkel zwischen der Normalen und der lightDir
intensity =degrees(asin(dot(lightDir,gl_NormalMatrix * gl_Normal)))/90.0;

}


FragmentShader:

uniform vec3 lightDir;
uniform vec3 colors[6];
uniform int interpolation;
varying float intensity;

void main()
{
int colorCount=interpolation*colors.length;

float x=float(interpolation)*colors.length*intensity;

                //Berechnen der ersten Farbe
int color1ID=int(x/float(interpolation))-1;
int color2ID=color1ID+1;
               //Berechnnung des Factors für die Interpolation
float factor=fract(x/float(interpolation));

vec3  c0=colors[color1ID];
vec3  c1=colors[color2ID];

gl_FragColor=vec4(mix(c0,c1,factor),1.0);

}



PS: Gib bestimmt noch wesentlich schönere Varianten einen Shader zu programmieren, aber ich denk für meinen ersten ist der bis auf den Fehler doch gelungen :-P

Edit1: Welche glsl Versionen werden eigentlich von jPCT unterstützt?

EgonOlsen

#1
Per Default berechnet jPCT die Normalen selber und zwar basierend auf den Normalen der angrenzenden Flächen. Wenn du das nicht willst, musst du die Normalen von dem 3D-Editor deiner Wahl entsprechend berechnen lassen, als OBJ exportieren, http://www.jpct.net/doc/com/threed/jpct/Config.html#useNormalsFromOBJ auf true setzen und dann das Ding laden. Dann müsste es eigentlich eher so aussehen, wie du es haben willst. Hier steht noch ein bisschen was zu den Hintergründen: http://www.jpct.net/forum2/index.php/topic,2798.0.html

Gidy

Hmm, ich gehe zwar ungern den Umweg mit ein extra Dateiformat, da ich dann ein Converter schreiben muss. Aber es scheint so als ob das obj-Format ziemlich nah an dem Dateiformat dran ist, was ich sowieso habe (Firmen internes Format).

Da werde ich das mal ausprobieren und meine Normalen entsprechend setzen.

Mal schauen ob ich das morgen hinbekomme :-)

Ansonsten benutz ich wieder den Texturenmanager und ändere meine Polygone einzeln. Wie ich vohin gesehen hab, hast du ja in Version 1.27 die Performance verbessert.

Gidy

Hat wunderbar funktioniert mit dem Konvertieren und benutzen des Formates. Nun sieht alles toll aus :-)



Kann es aber sein das die Funktion object3D.getTransformedCenter() nicht mehr funktioniert, wenn ich dei Objekte als .obj-File lade? Ich habe damit vorher alle meine Objekte in den Ursprung des Koordinatensystems gesetzt, nun bekomm ich nur noch den Vektor(0,0,0) raus und meine Objekte sind nicht im Ursprung :-/

EgonOlsen

Nein, da sehe ich keinen Zusammenhang. Wenn da der Ursprung raus kommt, dann ist das auch der Ursprung. Lass dir mal getCenter und getWorldTransformation ausgeben.

Gidy

Danke für den Tipp...ich hab die Revision mit dem fehler gefunden den ich Commitet habe.

Aktuelle Revision:

Center:(0.0,0.0,0.0)
TransfromdCenter:(0.0,0.0,0.0)
WorldTransformation:(
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
)


Gleiche Datei bei einer Revision von vor 2 Tagen:

Center:(0.0,0.0,25.0)
TransfromdCenter: (0.0,0.0,25.0)
WorldTransformation: (
1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0
)


und der unterschied war....ich hate object3D.build() auskommentiert :-/ Gott sei dank gibts eine Versionskontrolle :-D

Gidy

Rein der Vollständigkeits halber mein fertiger Shader, falls jemand mal was ähnliches benötigt.

Fragment-Shader:

uniform vec3 colors[6];
varying vec3 normalized_normal;
varying vec3 normalized_vertex_to_light_vector;
void main()
{
float intensity =  degrees(asin(dot(normalized_normal, normalized_vertex_to_light_vector)))/90.0;
float x=float(colors.length-1)*intensity;

int color1ID=int(x);
int color2ID=color1ID+1;
float factor=fract(x);
vec3  c0=colors[color1ID];
vec3  c1=colors[color2ID];
float temp=0.0;

gl_FragColor=vec4(mix(c0,c1,temp),1.0);

}


Vertex-Shader:

varying vec3 normalized_normal;
varying vec3 normalized_vertex_to_light_vector;
void main()
{
    // Transforming The Vertex
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

    // Transforming The Normal To ModelView-Space
    vec3 normal = gl_NormalMatrix * gl_Normal;

    // Transforming The Vertex Position To ModelView-Space
    vec4 vertex_in_modelview_space = gl_ModelViewMatrix * gl_Vertex;

    // Calculating The Vector From The Vertex Position To The Light Position
   vec3 vertex_to_light_vector = vec3(gl_LightSource[0].position-vertex_in_modelview_space);
   
    // Scaling The Input Vector To Length 1
    normalized_normal = normalize(normal);
    normalized_vertex_to_light_vector = normalize(vertex_to_light_vector);

}

Gidy

Ich arbeite noch immer an der Software und plötzlich erhalte ich diesen Fehler. Dieser tritt bei großen Objekten auf, aber auch nicht immer (ca. 75%). Kleine Objekte gehen ohne Probleme.
Sobald ich das Objekt nichtmehr compilire oder
Config.setParameterValue("useNormalsFromOBJ", false) mache, tritt der Fehler nicht mehr auf. Mit deaktivirtem Shader tritt der Fehler auch auf :-/ Ich weiß nichtmehr weiter. (getestet auf zwei Systemen)

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006fcc89a0, pid=7564, tid=8688
#
# JRE version: 7.0_25-b16
# Java VM: Java HotSpot(TM) 64-Bit Server VM (23.25-b01 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [nvoglv64.DLL+0xac89a0]  DrvPresentBuffers+0xcd540
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# F:\Users\userX\Dropbox\Arbeit\TestProject-JpctLWJGL\hs_err_pid7564.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#



Driver is: nvd3dumx,nvwgf2umx,nvwgf2umx/9.18.13.2049 on NVIDIA Corporation / GeForce GT 555M/PCIe/SSE2
GL_ARB_texture_env_combine supported and used!
FBO supported and used!
VBO supported and used!
OpenGL renderer initialized (using 4 texture stages)
Waiting for renderer to initialize...15
Checking for triangle strip...
Not a triangle strip at position 1!
Waiting for renderer to initialize...16
Subobject of object 2/first compiled to indexed data using 7332/6971 vertices in 44ms!
Object 2/first compiled to 1 subobjects in 951ms!
Creating new world processor buffer for thread view1
Waiting for renderer to initialize...17
Driver is: nvd3dumx,nvwgf2umx,nvwgf2umx/9.18.13.2049 on NVIDIA Corporation / GeForce GT 555M/PCIe/SSE2
GL_ARB_texture_env_combine supported and used!

Shader program compiled and linked fine!
Tangent handle not found (tangents needed: false)!
Shader compiled!
VBO created for object 'first'
Compiled 1 VBO!


Shader program compiled and linked fine!
Tangent handle not found (tangents needed: false)!
Shader compiled!
Loading file F:\Users\Philipp\AppData\Local\Temp\obj4674091273484188013.obj
Text file F:\Users\Philipp\AppData\Local\Temp\obj4674091273484188013.obj loaded...7913887 bytes
Processing object from OBJ-file: reload
Object 'reload_jPCT4' created using 81920 polygons and 245760 vertices.
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 66/66 vertices in 1ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 8775/8775 vertices in 3ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 23997/23997 vertices in 35ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 36ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 9ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 8ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 8ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 10ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 9ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 9ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 24000/24000 vertices in 9ms!
Checking for triangle strip...
Not a triangle strip at position 1!
Subobject of object 4/reload compiled to indexed data using 20922/20922 vertices in 7ms!
Object 4/reload compiled to 12 subobjects in 216ms!
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
VBO created for object 'reload'
Compiled 12 VBO!


Datei mit der der Fehler auftritt: https://www.dropbox.com/s/jcuu2akivitatid/obj5045321048087547196.obj

EgonOlsen

Ja, '*!"&"&%!###-Nvidia-Treiber mal wieder. Dabei sollen die ja sooooo toll sein. Ich gucke mir das mal an. Welche Version von jPCT ist das und wie alt ist dein Grafiktreiber?

EgonOlsen

Aaaalso...

0. Ich kann das Problem nicht nachvollziehen, auch auf NVidia-Karten nicht (oder anders: Bei mir geht es... ;))

1. Das ist der AWTGLRenderer, oder?

2. Ich bräuchte auch den mtl-File. Ohne ist die Texturverteilung scheinbar anders und das Ding wird im Ergebnis in 11 statt wie bei dir in 12 Teile compiliert.

3. Deine Logausgabe ist komisch...und zwar dieser Teil:


OpenGL renderer initialized (using 4 texture stages)
Waiting for renderer to initialize...15
Checking for triangle strip...
Not a triangle strip at position 1!
Waiting for renderer to initialize...16
Subobject of object 2/first compiled to indexed data using 7332/6971 vertices in 44ms!
Object 2/first compiled to 1 subobjects in 951ms!
Creating new world processor buffer for thread view1
Waiting for renderer to initialize...17
Driver is: nvd3dumx,nvwgf2umx,nvwgf2umx/9.18.13.2049 on NVIDIA Corporation / GeForce GT 555M/PCIe/SSE2
GL_ARB_texture_env_combine supported and used!


Da sind Meldungen vom ObjectCompiler zwischen Meldungen "Waiting for renderer to initialize...XX"...das kann gar nicht sein, außer da läuft noch ein anderer Thread, der auch sowas tut. Renderst du in mehrere Fenster gleichzeitig?

4. Probier doch mal ein paar Dinge aus:


  • Setze mal Config.glUseVBO=false; (ganz am Anfang)
  • Setze mal Config.glBatchSize hoch oder runter (Default ist 8000, probiere mal 4000, 2000, 500, 16000, 32000...)
  • Setze mal Config.nativeBufferSize hoch. Default ist 1024, probier mal Vielfache davon.

Gidy



Quote from: EgonOlsen on September 12, 2013, 09:23:25 PM
Aaaalso...

0. Ich kann das Problem nicht nachvollziehen, auch auf NVidia-Karten nicht (oder anders: Bei mir geht es... ;))

bösen Treiber immer :-D auf meinem Laptop hab ich den aktuellen Treiber und auf meinem Arbeitsrechner 100% nicht. Ich benutz die neuste JPCT-Version 1.27. In meinem eigene PC hab ich eine Geforce 550M und im Arbeitsrechner eine Gefroce 9300 (Bürorechner :-P).

Quote from: EgonOlsen on September 12, 2013, 09:23:25 PM
1. Das ist der AWTGLRenderer, oder?

Jep, da ich das ganze in einer GUI brauche, der Renderer dient als vorab Visualisierung für eine Simulation.

Quote from: EgonOlsen on September 12, 2013, 09:23:25 PM
2. Ich bräuchte auch den mtl-File. Ohne ist die Texturverteilung scheinbar anders und das Ding wird im Ergebnis in 11 statt wie bei dir in 12 Teile compiliert.

Ich benutzt kein mtl-File ich initialisiere die Polygonfarben anhand einer Materialart. Heist ich schaue aus welchem "Material" das Polygon ist und färbe es dementsprechend ein. Das heißt ich setzt eigentlich mit dem TexturManager für jeder Materialart eine Texture z.B. mit new Texture(1,1,Color.Red)

Quote from: EgonOlsen on September 12, 2013, 09:23:25 PM
3. Deine Logausgabe ist komisch...und zwar dieser Teil:


OpenGL renderer initialized (using 4 texture stages)
Waiting for renderer to initialize...15
Checking for triangle strip...
Not a triangle strip at position 1!
Waiting for renderer to initialize...16
Subobject of object 2/first compiled to indexed data using 7332/6971 vertices in 44ms!
Object 2/first compiled to 1 subobjects in 951ms!
Creating new world processor buffer for thread view1
Waiting for renderer to initialize...17
Driver is: nvd3dumx,nvwgf2umx,nvwgf2umx/9.18.13.2049 on NVIDIA Corporation / GeForce GT 555M/PCIe/SSE2
GL_ARB_texture_env_combine supported and used!


Da sind Meldungen vom ObjectCompiler zwischen Meldungen "Waiting for renderer to initialize...XX"...das kann gar nicht sein, außer da läuft noch ein anderer Thread, der auch sowas tut. Renderst du in mehrere Fenster gleichzeitig?

Das ist korrekt nebenher läuft noch ein weiterer Renderer der die ganze Szene aus einer anderen Perspektive + ein Koordinatensystem zeigt. Beide haben aber jeweils ihr eigenes world-Objekt.
Quote from: EgonOlsen on September 12, 2013, 09:23:25 PM
4. Probier doch mal ein paar Dinge aus:


  • Setze mal Config.glUseVBO=false; (ganz am Anfang)
  • Setze mal Config.glBatchSize hoch oder runter (Default ist 8000, probiere mal 4000, 2000, 500, 16000, 32000...)
  • Setze mal Config.nativeBufferSize hoch. Default ist 1024, probier mal Vielfache davon.

1. Hat nichts gebracht
2. glBatchSize auf 500 scheint es zu keinem Fehler mehr zu kommen.
3. nativeBufferSize mit 2048 oder 4096 war jetzt auch kein Fehler mehr produzierbar.

Dan werde ich mal morgen auf dem Produktivsystem schauen, ob das ändern der Konfig hilft.

Schonmal vorab Vielen dank! Best support ever! :)