[OpenGL-Projekt] Alles auf Anfang [Update 4]

AW: [update 2] Bloom-Effekt erzeugen

so, ich häng auch mal wieder bissl an meinem projekt, nachdem das ja nu funzt ^^ -> daher [update 2]

joa, das ganze in nen framebuffer zu packen soll ja nich nur schön aussehen, sondern mir auch was bringen: posteffects. als erstes mal bloom probieren - kommt grad im buch dran ^^ joa, also die theorie sieht so aus:
- die szene "normal" rendern, über nen framebuffer in eine textur
- allerdings wird hierbei noch ne 2. textur zeitgleich erstellt, welche alle hellen bereiche der szene enthält (wie das genau funzt sieht für mich auch noch sehr magisch aus xD )
- nachdem man die beiden hat, wird diese "brightTexture" mehrmals geschrumpft (mit nem kernel und gaussfilter bla irgendwie). die schrumpfung simuliert hier immer größer werdende kernel*, welche aktuelle hardware sprengen würden (kleineres bild bei gleichem kernel geblurt und wieder auf ursprungsgröße gebastelt = annäherungsweise das selbe wie originaltextur mit größerem kernel)
-> kann man ganz gut mit ner mipmap lösen, die im grunde ja die originaltextur mit kleineren abbildern ihrer selbst is ^^
- jut, hat man nun den ganzen spaß geblurt, erfolgt im dritten durchgang die kombination der normalen farbausgabe mit dem geblurten gedöhnse und zack peng puff, is die szene schön bloomig :ugly:

jo, soweit zur theorie. nu stellt sich mir aber eine essentielle frage. wenn ich die texturen, wo reingerendert wird (im ertsen schritt), ans fbo häng, dann sag ich dabei, zu welchem colorattachment die gehören:
Code:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, [B]GL_COLOR_ATTACHMENT0[/B], GL_TEXTURE_2D, this->colorTexture, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, [B]GL_COLOR_ATTACHMENT1[/B], GL_TEXTURE_2D, this->bloomTexture, 0);
heisst also, dass alles, was ins color attachment 0 gemalt wird, in der colorTexture landet, und alles in die 1 landet in der bloomTexture. im shader baut man nun 2 output variablen:
Code:
out vec4 oColor;
out vec4 oBright;
welche dann mit farbwerten gefüttert werden. verknüpft wird die ganze chose dann beim "laden" der shader zum programmstart:
Code:
glBindFragDataLocation(myShader, [B]0[/B], "oColor");
glBindFragDataLocation(myShader, [B]1[/B], "oBright");
hier wird der shaderoutput oColor auf das attachment 0 gelenkt und oBright auf die 1.

jep, soweit sogut. nu hab ich doch aber auch texturen, die "rein gehen" in den shader. speziell bei mir haben die objekte ja (momentan) ne normale textur (attachment 0) und ne specular-map (attachment 1) - überschreibt sich das ned? oder unterscheidet ogl da? weil der output geht ja ins fbo, die input-texturen gehören aber nich zum fbo. da blick ich atm leider noch garnich durch >< und zum googlen bin ich ma wieder zu blöde. die meisten "tutorials" die ich finde, die enthalten keinen einzigen code schnipsel oder nur code fetzen ohne wirklich wichtige zusammenhänge aufzuzeigen oO


achja: *Kernel ^^ der kernel bezeichnet hier ne 5x5 matrix von werten und wichtungen. in der mitte ist der aktuell betrachtete pixel mit der höchsten wichtung und drumherum in 2 "schalen" werden die umgebenden pixel samt wertung erfasst. das sieht zum bsp so dann aus:
Code:
// 5x5 Gaussian kernel
// 1  4  7  4 1
// 4 16 26 16 4
// 7 26 41 26 7 / 273
// 4 16 26 16 4
// 1  4  7  4 1
also der eigentliche pixel wird mit der höchsten wertung erfasst und die umliegenden mit abnehmenden wertungen. alles zusammen gerechnet und durch die gesamtzahl der wertungen dividiert (hier 273) ergibt den "durchschnittswert" des pixels nach betrachtung mit seinem umfeld.
 
Zuletzt bearbeitet:
AW: [update 2] Bloom-Effekt erzeugen

himmel arsch un zwirn noch eins, ich dreh bald durch hier -.-

ich arbeite mich jetz schritt für schritt vorwärts. zuerst hab ichs mal überhaupt wieder zum laufen gebracht, das war noch der einfachere part. was ich sah, war dann auch ein sexy schwarzer bildschirm als endergebnis ^^ dann hab ich mir mal die colorTexture ausgeben lassen. wirkte irgendwie überstrahlt, aber bloomt noch ned wirklich. zudem scheint auf angeleuchteten flächen alles dahinter durch Oo "in" meinem schiffsmodellchen da is ja noch die erde mit mond usw die sich da lustig drehn (einfach weil das schiffsmodell bissl groß is): auf der schattenseite sieht mans ned durchscheinen, aber auf der "tag"seite leuchten plötzlich die sterne vom hintergrund und die erde samt wolken und mond in dunklem blau durch oO un ich hab keinen blassen wieso plötzlich ><

naja, auf später verschoben. hab jetz erstmal dann die bloomTexture angeschaut, größtenteils schwarz und ab und an weise bereiche. soweit so gut, nur irgendwie hatte das rein garnix mit den hellen stellen des bildes zu tun oO hab das ganze dann bissl modifiziert un nu hauts besser hin. und jetzt kommt meine verzweiflung ins spiel: wie zum henker kann ich denn nen mipmap level einer textur aktualisieren? egal was ich mache, es geht ums verrecken nich. das einzige was funzt, is das automatische glGenerateMipmap() nachm neuzeichnen in die textur. schön und gut, nur wird hier ja nur die textur immer halbiert/verkleinert aber der kernelfilter zum blurren wird ja freilich ned angewendet.

nu hab ich schon versucht den output des shaders auf das entsprechende miplevel zu lenken - kein erfolg. oder glCopyTexSubImage zum kopieren auf das miplevel. nix. bei dem copy ding findet man auch NIRGENDS irgendwelche infos, welche width und height angabe man verwenden muss. muss ich da jetz die base-level (also originale größe) maße nehmen und er shrinkt das selber dann runter auf die entsprechende miplevel größe, oder muss ich das selber angeben oder wie? hat sich die frage noch nie einer gestellt, das keiner drauf kommt, sowas mal zu beantworten im netz *argh* das nächste is, dass ich google hasse - oder goggle hasst mich, was weis ich. gib da ma ein "opengl updating mipmap" oder noch nen level hinten dran. was findet der hurenbock? GENERATING mipmaps. herrgott noch eins, hab ich nachm generieren oder nachm updaten versucht? 10 seiten nur gülle. und wenn man mal ein "tutorial" findet, dann fehlt jeglicher code :lol:

also jungs: ihr wollt euer eignes flugzeug bauen? geht ganz easy, hier mein tutorial: bau nen rumpf, bau 2 flügel und ne schwanzflosse, bastel alles zusammen und kleb noch paar triebwerke und räder unten dran. wers richtig geil will, baut in den rumpf noch fenster rein!

ey, da fasst man sich an die birne... is das nen staatsgeheimnis, das KEINER ne echte anleitung zu sowas mal hergibt oder was?
 
AW: [update 2] Bloom-Effekt erzeugen

Also dass es zu einigen Sachen kaum/keine Tutorials gibt, liegt daran, dass die Techniken dazu entweder viel zu komplex sind oder dass sie auch im kommerziellen Bereich angewendet werden und wer gibt schon gerne seine "Geldeinnahmequelle" für lau Preis?
Kenn ich von der Arbeit, einige Algorithmen zur Simulation von irgendwelchen Volumenberechnungen wirst du in "freier Wildbahn" kaum finden, die gibts nur hinter verschlossenen Türen für viel Geld ;)

Ansonsten habe ich hier: Graphics Programming and Theory - GameDev.net oder hier: DirectX and XNA - GameDev.net vor maximal ein paar Tagen auch einen Thread zu Bloom(ing) gesehen; weiß nicht mehr genau welches Unterforum, aber kannst die beiden ja etwas durchstöbern.
 
AW: [update 2] Bloom-Effekt erzeugen

naja, dx nutzt mir nix. den core des ganzen hab ich ja. hab mir ja auch nen teures buch gekauft wo mir grundlagen erklärt werden - nur wird dort nich mit ner mipmap gearbeitet sondern mit 5 einzel-fbo's mit jeweils einer textur. ich werd das bald so umschreiben wie im buch he -.- aber es MUSS doch gehen. es soll ja auch nich unbedingt schritt für schritt dastehen.

ok, also schritt für schritt: im buch wirds eben auf ne etwas "grobe" tour erklärt und am ende steht dabei, das man als ne art selbstübung ja mal probieren kann, das ganze auf mipmaps umzubauen. also es muss definitiv gehen. dann fand ich im netz nen "tutorial" das quasi genau das is. das sin exakt die selben shader wie im buch, nur eben auf mipmap umgebaut. soweit so gut, hat mir shaderseitig auch nen guten einblick gegeben. nur gibt man ausserhalb des shaders an, wohin das gemalte zeugs fließt, also bringt mir der shader in der richtung recht wenig. ich weis DAS es geht, aber nich wie. das is frustrierend.

und wenn ich nun nach grundlagen google, also ned nach zusammengesetzten algorythmen, dann findet er einfach nix -.- wie kann ich den shaderoutput in ein mipmap-level einer textur umleiten? WIE? xD such mal nach update mipmap. du findest NUR was dazu, wie man se generiert. das is die härte. als ob opengl das garnich könnte lol. das komplexe algorithmen ned offiziell sin is klar, aber ne dokumentation oder suche nach einzelnen funktionen muss doch erfolgversprechend sein *grr*

ich hab jetz auch schon überlegt, jeweils in ne seperate textur zu rendern und diese dann in das miplevel zu kopieren, aber dann hab ich ja wieder die ganzen extra texturen und könnt mir das mipmap gekröse gleich ganz sparen. da fragt man sich nach dem sinn dahinter :/

ich habs jetz zum bsp schon so versucht:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, this->bloomTexture, i+1);
also ich render jedes miplevel in ner forschleife (haupttextur und 4 miplevels). die bloomTexture geht rein und die i-te ebene (bei 0 anfangend bis 3) wird im jeweiligen durchgang als src genommen und mit der zeile wollte ich eben versuchen, das was als ergebnis rauskommt, in die "darunterliegende" eben zu lenken. aber wirklich funtzen tuts ned. er generiert beim erzeugen die miplevel und das erste gerenderte bild bleibt bestehen. danach wird nix mehr geupdatet.

glCopyTexSubImage2D(GL_TEXTURE_2D, i+1, 0, 0, 0, 0, x, y);
das soll glaube ausm back/color buffer des fbo's in die textur kopieren? also eigentlich das falsche für meine zwecke, da ich ja in ne textur render, aber ich wollts zumindest ma probiert ham ^^ klappt jedenfalls auch ned.

rein vom empfinden her, wäre das hier ne tolle anlaufstelle für sowas:
glBindFragDataLocation(this->secondPassShader, 1, "oBright");
also die out variable oBright des secondPassShaders wird hier aufs color-attachment-1 gelenkt. wenn man hier noch das miplevel angeben könnte... aber das is wohl zu einfach xD aber gut, man muss danach den shader jedesma wieder linken und das jeden frame... is sicher nich sehr performatn. naja. ich find jedenfalls absolut nix, was mir filft :/

also wie gesagt: ich brauche keinen kompletten algorithmus, ich brauche keine theorie, ich brauche nen funktionierende möglichkeit, ein bestehendes mipmap-level zu aktualisieren >< das MUSS doch irgendwie gehn.
 
AW: [update 2] Bloom-Effekt erzeugen

Achso du suchst konkret welche Methoden wie anzuwenden sind, naja gut dazu ist das DirectX-Forum dann natürlich nicht geeignet. Ggf. hier: OpenGL - GameDev.net
Mimaps updaten habe ich jetzt bisher auch noch nie gemacht ... immer nur erstellen und dann freuen dass man sie hat und sich nicht mehr um sie kümmern :D
Darüber hinaus habe ich Bloom selbst noch nicht genutzt, soll aber bald auch passieren; da kann ich auf jeden Fall mal die Augen offen halten ;)

PS: ist ja ein bisschen wie in der höheren Mathematik: Ja es gibt mindestens eine (eindeutige) Lösung .... aber wie die aussieht?!?! Da bin ich überfragt xDD
 
AW: [update 2] Bloom-Effekt erzeugen

soa, ich hab seit längerem mal wieder bissl rumgeschraubt. da das mit der mipmap nich funktionieren wollte (und ich mich scheute das umzutüdeln -> lange nix gemacht ^^) hab ichs nun mal angefangen so umzubauen, dass er statt mipmaps halt extra texturen hernimmt. btw: das wird ne etwas größere "erklärerei", da ich das ganze auch nochmal für mich aufbereiten möchte. es stellt also meine "auffassung der wahrheit" dar :ugly: wäre schön, falls wer hier schon grundsatzfehler in der denke findet und mich aufklären könnte :P

also mipmaps sind "bestandteil" eines bildes - einer textur besser gesagt. die textur hat meinetwegen ne auflösung von 1024x1024, dann wäre die erste mipmap das selbe bild nur in 512x512 und das nächste 256x256 usw usf. nur zur erklärung, dass man weiss, was ich machen wollt.

bloom-effekt wird wohl wie folgt realisiert: man rendert die szene ganz normal, macht in diesem durchlauf aber noch nen "bright pass" - also erstellt im gleichen atemzug eine 2. textur, die nur die hellen bereiche der ersten textur enthält. dieser bright pass wird dann mehrfach geblurt. heisst soviel wie, dass man aus der brightpass texture ein kleineres abbild erstellt - aber eben nicht nur verkleinern, sondern das ganze durch nen "kernel" jagen. man betrachtet also jedes pixel der textur und schaut sich im endeffekt die umliegenden pixel auch noch an. das eigentliche pixel erhält die höchste wichtung und je weiter weg die betrachteten pixel liegen, desto geringer fällt deren wichtung aus. ich hab da jetz nen 5x5 kernel (er betrachtet also 5x5 pixel - mit dem ausgangs pixel in der mitte -> also quasi ne "schale" von 2 pixeln dichte um das eigentlich betrachtete pixel drum herum).
joa, und das macht man eben mehrmals. ich hab bei mir jetzt 4 blur images quasi. also im endeffekt 1 color texture, eine brigth pass texture und 4 blur textures.

dadurch, dass die blur- images immer ein verkleinertes abbild ihrer ausgangstextur sind, würde sich hier mipmapping halt anbieten, da der vorgang ja verwandt ist. aber ich habs einfach ned hinbekommen >< also hab ich statt einer textur mit mipmaps eben 5 einzelne gebaut.

weiteres detail: ich rendere natürlich die meiste zeit in texturen, und nicht auf den bildschirm. das is dann nur der letzte schritt. gut, jetzt mal zum ablauf:

ich hab den ganzen textur und framebuffer krams in ne klasse gebaut. beim setup wird nun also auch nen obj der klasse initiiert. dabei werden die fbo's, der tiefenbuffer und die zig texturen angelegt und zusammengebunden ^^ ausserdem werden die shader zusammen geschraubt. hab hier mal exemplarisch den für den sternenhintergrund genommen. die bilden quasi den first-pass dann, also den ersten render durchgang:
PHP:
screenFBO            mFBO;

...

void SetupRC(void) {
    mFBO.init(screenX, screenY);
    ...
    starFieldShader = gltLoadShaderPairWithAttributes("Shader/Star.vp", "Shader/Star.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_COLOR, "vColor");
    locSFUniforms[0] = glGetUniformLocation(starFieldShader, "mvpMatrix");
    locSFUniforms[1] = glGetUniformLocation(starFieldShader, "starImage");
    glBindFragDataLocation(starFieldShader, 0, "oColor");                        // -> in att0 rendern
    glBindFragDataLocation(starFieldShader, 1, "oBright");                        // -> in att1 rendern
    glLinkProgram(starFieldShader);
    ...
}
gut, hier wird nun beim shader die ausgabe durch glBindFragDataLocation() eingestellt. oColor (shader variable) wird also in die 0 (GL_COLOR_ATTACHMENT0) gerendert, und oBright in die 1 (GL_COLOR_ATTACHMENT1). man lenkt hiermit also den output des shaders. der input wird dann über glActiveTexture() geregelt. also als bsp:
PHP:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, screenTexture);
tex0 wird mit screenTexture gefüttert. mit locSFUniforms[1] = glGetUniformLocation(starFieldShader, "starImage"); als bsp hab ich die "location" der uniform-variablen starImage im shader besorgt und mit glUniform1i(locSFUniforms[1], 0); vorm rendern geb ich über die 0 an, dass er die textur, die an tex0 (GL_TEXTURE0) gebunden ist, in den shader feuern soll -> in dem bsp also screenTexture.

gut, zurück zum thema... öh ja, was macht die init des mFBO objekts?
PHP:
void screenFBO::init(GLuint x, GLuint y) {
    int sub_x, sub_y, i;

    this->initialized = true;
    this->screenX = x;
    this->screenY = y;

    this->exposure = 1.0f;
    this->bloomLevel = 0.5;
    this->ratio = 0.5f;

    this->mainFBObuff[0] = GL_COLOR_ATTACHMENT0;
    this->mainFBObuff[1] = GL_COLOR_ATTACHMENT1;
    this->windowBuff[0] = GL_BACK_LEFT;

    // Haupt-FBO erstellen
    glGenFramebuffers(5, this->mainFBO);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
    // tiefen renderbuffer erstellen
    glGenRenderbuffers(1, &this->mainRBOdepth);
    glBindRenderbuffer(GL_RENDERBUFFER, this->mainRBOdepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, this->screenX, this->screenY);
    // colorTexture erstellen
    glGenTextures(1, &this->colorTexture);
    glBindTexture(GL_TEXTURE_2D, this->colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, this->screenX, this->screenY, 0, GL_RGBA, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    glGenerateMipmap(GL_TEXTURE_2D);
    // bloomTexture erstellen
    sub_x = this->screenX;
    sub_y = this->screenY;
    glGenTextures(5, this->bloomTexture);
    for(i = 0; i < 5; i++) {
        glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, sub_x, sub_y, 0, GL_RGBA, GL_FLOAT, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        cout << "BloomTexture[" << i << "] mit Dimension " << sub_x << "x" << sub_y << " erstellt." << endl;
        sub_x = (int)(sub_x * this->ratio);
        sub_y = (int)(sub_y * this->ratio);
    }

    // (tiefen)renderbuffer und texturen an fbo hängen
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->mainRBOdepth);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->colorTexture, 0);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, this->bloomTexture[0], 0);
    for(i = 1; i < 5; i++) {
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->bloomTexture[i], 0);
    }

    // alles wieder unbinden
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    for(i = 0; i < 5; i++)
        this->checkFBO(this->mainFBO[i]);

    // shader initialisieren
    /* secondPassShader für den zweiten durchgang mit erstellung der geblurten sub images */
    this->secondPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/blurShader.fp", 2, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE1, "vTexCoord0");
    this->loc2PUniforms[0] = glGetUniformLocation(this->secondPassShader, "texture");            // texture
    this->loc2PUniforms[1] = glGetUniformLocation(this->secondPassShader, "tc_offset");            // offset array für kernel
    glBindFragDataLocation(this->secondPassShader, 0, "oBright");                                // -> in att0 rendern
    glLinkProgram(this->secondPassShader);

    /* thirdPassShader für den dritten durchgang zur kombinierung der colorTexture mit der geblurrten bloomTexture */
    this->thirdPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/bloomShader.fp", 2, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0");
    this->loc3PUniforms[0] = glGetUniformLocation(this->thirdPassShader, "origImage");            // colorTexture
    this->loc3PUniforms[1] = glGetUniformLocation(this->thirdPassShader, "brightImage0");        // bloomTexture
    this->loc3PUniforms[2] = glGetUniformLocation(this->thirdPassShader, "brightImage1");        // blurTexture1
    this->loc3PUniforms[3] = glGetUniformLocation(this->thirdPassShader, "brightImage2");        // blurTexture2
    this->loc3PUniforms[4] = glGetUniformLocation(this->thirdPassShader, "brightImage3");        // blurTexture3
    this->loc3PUniforms[5] = glGetUniformLocation(this->thirdPassShader, "brightImage4");        // blurTexture4
    this->loc3PUniforms[6] = glGetUniformLocation(this->thirdPassShader, "bloomLevel");            // bloomLevel
    this->loc3PUniforms[7] = glGetUniformLocation(this->thirdPassShader, "exposure");            // belichtung
    glBindFragDataLocation(this->thirdPassShader, 0, "oColor");                                    // -> in att0 rendern
    glLinkProgram(this->thirdPassShader);

    this->GenTexCoordOffsets(this->screenX, this->screenY);
}
es werden also diverse variablen gesetzt und vorallem eben auch die texturen und BO's erzeugt. auch die shader fürs bloomen werden "gebaut". zuerst baue ich also erstmal 5 framebuffer objects (fbo's) und das erste fbo[0] setz ich als aktiv. danach kommt der tiefenbuffer dran und dann die colorTexture. und dann kommen die bloomTextures, wie ich sie hier genannt habe. auch wieder 5 stück. bloomTexture[0] enthält dann den bright pass, der zusammen mit der colorTexture im 1stPass erzeugt wird, [1..4] sind dann die geblurrten subimages, die ich eingangs erwähnte. jedes bekommt sein eigenes fbo dann. joa genau, das follgt dann schon. zuerst wird mainFBO[0] fertig gebastelt, sprich, es bekommt den tiefenbuffer angehängt sowie die beiden texturen colorTexture und bloomTexture[0]. man beachte das GL_COLOR_ATTACHMENT0 bzw GL_COLOR_ATTACHMENT1 - damit wird die ausgabe dieses framebuffers auf die jeweiligen color-attachments gelegt. ergo wird die "spur" 0 auf die colorTexture gelenkt, sprich, alles was darein gerendert wird, kommt in die colorTexture, und alles auf der 1 kommt in die bloomTexture[0].


was im shader welche "spur" ist, wird durch dieses glBindFragDataLocation() gesetzt, was ich vorhin schon erklärte. also beim shader-binden usw wird angegeben, welche variable auf welche "spur" geleitet wird. gut, also haben wir ausserhalb der klasse bei sternen shader die ausgabe auf die richtige spur gesetzt und hier beim framebuffer die ausgangstexturen an diese spuren gehängt.

gut, dann wird noch bissl "aufgeräumt" und die internen shader getüdelt. der 2ndPassShader ist eben dafür zuständig, dass die bloomTexture[0] geblurrt wird und die bloomTexture[1..4] ihren krempel erhalten. der 3rdPassShader macht aus all diesen bunten texturen dann (laut theorie :ugly: ) das finale gebloomte bild ^^


ok, also weiter im text, was passiert jetzt?
PHP:
void RenderScene(void) {
    ...
    mFBO.activate();
    DrawSpace(elapsedTime);
    mFBO.deactivate();
    ...

    // clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    DrawScreenTexture();
    DrawHud();

    glutSwapBuffers();
    glutPostRedisplay();
}
tjoa, also das ist das wichtigste hier runtergebrochen. in meiner fbo klasse hab ich 2 methoden gebaut, die dann alles für den 1stPass vorbereiten, da die shader ja extern verwaltet werden (noch? kA ^^). ich kann das also ein- und wieder ausschalten (code kommt auch gleich noch). dann wird die szene ganz normal gerendert, dabei kommen shader zum einsatz, die eben auf die 2 ausgabe-"spuren" rendern und am ende wird dann die "screenTexture" auf dem bildschirm ausgegeben. diese ominöse screenTexture ist die colorTexture aus derm fbo objekt ^^ dann zum schluss wird noch bissl text ausgegeben zum debuggen bla. is ne fps anzeige, wo die maus is, wie sie sich bewegt, was gedrückt wird... an und für sich unintressant, funzt soweit wunderbar und hab ich auch nix geändert dran.

gut, jetzt nochmal fix zu dem de-activate() gelumbe:
PHP:
void screenFBO::activate(void) {
    if(this->initialized) {
        // frame- und renderbuffer binden und drawbuffers einrichten
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
        glBindRenderbuffer(GL_RENDERBUFFER, this->mainRBOdepth);

        glDrawBuffers(2, this->mainFBObuff);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        this->checkErrors("activate()");
    }
}

void screenFBO::deactivate(void) {
    if(this->initialized) {
        // alles wieder unbinden und drawbuffers zurücksetzen
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
        glDrawBuffers(1, this->windowBuff);
        this->checkErrors("deactivate()");
    }
}
nix wildes - ich "aktiviere" den "haupt" framebuffer (also der, der diese 2-spurige ausgabe beinhaltet, mit color_attachment0 und 1 für colorTexture und bloomTexture[0] bla - siehe oben) und setz die drawbuffers. beim deaktivate() genau andersrum.

SOA! hier kommen wir nun zu meinem problem 1 >< aus irgendeinem grund wird die colorTexture nicht neugemalt. geb ich die aus, steht das bild ab dem ersten frame und sieht aus, wie 20 mal übereinander gemalt. normalerweise zieht das bild dann ja schlieren quasi. es bewegt sich ja aber noch >< machts aber ned. geb ich den brightpass aus (also bloomtexture[0]) klappt das wunderbar. die szene in dunkel mit dem hellen krams hauptsächlich und in voller bewegung. also beim brightpass passt alles, nur beim normal pass quasi is irgendwas im argen :/

hier nochmal der kleine code für drawScreenTexture():
PHP:
void DrawScreenTexture(void) {
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mFBO.getTex());

    projectionMatrix.PushMatrix();
        projectionMatrix.LoadMatrix(orthoMatrix);
        modelViewMatrix.PushMatrix();
            modelViewMatrix.LoadIdentity();
            //mFBO.draw();
            glUseProgram(screenShader);
            glUniform1i(locSSUniforms[0], 0);                                                                            // textur
            screenQuad.Draw();
        modelViewMatrix.PopMatrix();
    projectionMatrix.PopMatrix();
}
er nimmt also quasi nur die textur aus dem fbo objekt und pinselt sie auf nen bildschirmfüllendes viereck. mFBO.draw() is grad noch ausgegraut, da das zu meinem nächsten problem führt. aber erstmal so weiter. wenn mFBO.getTex() die colorTexture liefert, siehts so aus:
SolarSystem 2013-03-12 14-24-40-32.jpg
bei bloomTexture[0] dann so:
SolarSystem 2013-03-12 14-22-46-70.jpg SolarSystem 2013-03-12 14-23-21-40.jpg
die anderen bloomText ebenen sind einfach schwarz ^^ is ja noch nix gemalt worden.

ok, hab grad festgestellt, wenn ichs erste mal starte, dann ist colorTexture quasi uninitialisiert. da war nur schwarzer hintergrund mit vielen rosa tupfen oO. dann lies ichs mal mit der ausgabe auf die bloomtexture laufen und es kam halt das normale gerenderte bild. bewegte szene usw. danach nochmal colorTexture ausgeben lassen und schwupps hatte es ein stehendes bild ohne rosa tupfen. man, was is denn da nur im argen, was ich überseh? ich hoffe irgendwer blickt hier durch und kann helfen ><

gut, also wie gesagt, dass ist mein erstes problem: die colorTexture will einfach nich mehr so, wie ich das will :/ das 2. problem hängt mit dem mFBO.draw() zusammen. da wird das geblurre realisiert:
PHP:
void screenFBO::draw(void) {
    if(this->initialized) {
        // die bloomTexture blurren
        glActiveTexture(GL_TEXTURE0);
        GLuint x = this->screenX;
        GLuint y = this->screenY;
        this->load2PShader();
        for(int i = 1; i < 5; i++) {
            x = (int)(x * this->ratio);
            y = (int)(y * this->ratio);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);    // output texture i bound to fbo i
            glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i-1]);        // input texture is i-1
            glDrawBuffers(1, &this->mainFBObuff[0]);
            glViewport(0, 0, x, y);
            this->screenQuad.Draw();
        }
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
        glDrawBuffers(1, &this->mainFBObuff[0]);
        glViewport(0, 0, this->screenX, this->screenY);

        // colorTexture und blurredTexture kombinieren für die finale szene
        /*this->load3PShader();
        this->screenQuad.Draw();
        // anschließend wieder alle texturen unbinden
        for(int i = 0; i < 6; i++) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
        } */
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glDrawBuffers(1, &this->windowBuff[0]);
        this->checkErrors("draw()");
    }
}
das hauptsächlichste ist erstmal die forschleife. das is quasi mein versuch den 2ndPass zu realisieren. framebuffer hat ja bloomTexture als output deklariert. als input will ich aber die "vorgänger" textur haben - daher binde ich hier bloomTexture[i-1]. das mach ich für alle 4 subtexturen und warte gesapnnt auf das ergebnis:

colorTexture: SolarSystem 2013-03-12 14-34-54-59.jpg

bloomTexture[0]: SolarSystem 2013-03-12 14-36-21-35.jpg

bloomTexture[1]: SolarSystem 2013-03-12 14-37-41-29.jpg
...

selbst dass wenige bischen, was bisher funktioniert hatte, wird nun völlig zerschossen >< wiesooooo?

hoffe, irgendwer weis rat ^^
 
AW: [update 2] Bloom-Effekt erzeugen

ich nochmal. habs gestern geschafft, 2 fehlerchen auszumertzen. zum einen, wieso die bilder bei dem drawScreenTexture so versaubeutelt wurden. ich hatte die textur ausm fbo geladen und dann an den texturen rumgezeichnet (mFBO.draw()) und dann die davor geladene textur ausgegeben. einfach den texture-bind zeitpunkt nach der draw methode aufgerufen, und das problem war schonmal gelöst :klatsch:

das 2. problem, was ich dann in angriff nahm war die nicht gezeichnete colorTexture. hab im shader die variablen vertauscht (also dass die brigtpass farbe auf die normal-farben variable gelegt wurde und umgekehrt und die attachments vertauscht - 0 erfolge. am ende hatte ich einfach mal zum schauen beim binden ans fbo die variablen vertauscht und wieder zurück (also quasi KEINERLEI änderung vorgenommen) - und es ging :stupid: als hätte es da geklemmt und man musste nur mal gegen den kasten latschen, dass es wieder ging :ugly:

nuja, nun läufts als erstmal grundsätzlich wieder. leider hab ichs noch ned hinbekommen, dass er dann bloomTexture[i-1] als vorlage nimmt und in bloomTexture zeichnet (also selbst erstmal einfach nen durchschleifen ohne änderungen am bild selbst). is im grunde vom grundprinzip her nix andres wie mein ausgabe-shader am ende (also das fertige bild aufn moni pinseln) - aber es will nich :/
 
AW: [update 2] Bloom-Effekt erzeugen

mehehehehehhehehehehheeehe *crazy*


ICH HABS! ^^
als ich zufällig mal (das normalerweise immer gleich vom ausgabefensterchen überdeckte) konsolenfensterchen anschaute, grinste mich ein dickes "A GL ERROR OCCURED!" an. k, also irgendwas is wohl im busch ^^ hab dann rumgechekt und er sagte sehr spezifisch, dass "diese operation in diesems state nicht erlaubt sei". aha - welche der 1000 da? ^^ die lösung war zum glück recht simpel: glDrawBuffers sollte man erst nach dem binden des fbo's aufrufen - also ab damit in die schleife:
Code:
        // die bloomTexture blurren
        glActiveTexture(GL_TEXTURE0);
        [COLOR=red]glDrawBuffers(1, this->mainFBObuff);  // hier stands zuerst - löst den error aus. mainFBObuff is nen 2er array mit {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1} - beim default window fbo geht dat nit
        GLuint x = this->screenX;
        GLuint y = this->screenY;
        for(int i = 1; i < 5; i++) {
            x = (int)(x * this->ratio);
            y = (int)(y * this->ratio);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);    // output texture i bound to fbo i
            [COLOR=green]glDrawBuffers(1, this->mainFBObuff); // hier isses korrekt. es darf auch nur das erste (GL_COLOR_ATTACHMENT0) genutzt werden, da ich hier keine 2 texturen gleichzeitig nutze wie im ersten renderdurchlauf)
            glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i-1]);        // input texture is i-1
            this->load2PShader();
            glViewport(0, 0, x, y);
            this->screenQuad.Draw();
        }
gut, so war das schonmal vom tisch. ABER - die rotz ausgabe war immernoch tot. hab dann im shader einfach mal als outputfarbe rot gemacht (ned textur lesen) nur um zu sehn, ob wenigstens das ankommt - jop. also bekommt er keine textur rein. irgendwann siegte mein ordnungswahn... beim initialisieren der shade, also wo ich die uniform locations ermittel usw, hatte ich bei just meinem 2pass shader die eine zeile NICHT umgebrochen und die war halt so lang, dass sie ausm blickfeld verschwand. ich also gelangweilt wie bei den anderen den zeilenumbruch eingefügt und enddeckte DAS:
Code:
    /* secondPassShader für den zweiten durchgang mit erstellung der geblurten sub images */
    this->secondPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/blurShader.fp", 2, // hier fehlte besagter zeilenumbruch übrigens
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE[COLOR=red][B]1[/B], "vTexCoord0");
    this->loc2PUniforms[0] = glGetUniformLocation(this->secondPassShader, "texture0");            // texture
    this->loc2PUniforms[1] = glGetUniformLocation(this->secondPassShader, "tc_offset");            // offset array für kernel
    glBindFragDataLocation(this->secondPassShader, 0, "oBright");                                // -> in att0 rendern
    glLinkProgram(this->secondPassShader);
GLT_ATTRIBUTE_TEXTURE1 - eins, EINS! himmel herrschaftszeiten, ich nutz doch die 0 :klatsch:

gut, das gelöst, passiert dennoch nix :ugly: nu hatte ich bei meinem letzten test da (letzes posting) die externe draw funktion mit in die klasse integriert. dazu brauchte ich auch nen shader (der 3. nun - der war auch mit diesem zeilenumbruch da, also 2 von 3en umgebrochen, einer ned ^^ -> ordnung schaffen *zitter*) der einfach nur ne textur auf den bildschrim ausgibt (bisher hab ich die ja in ne textur gepinselt). also im grunde nix wildes, einfach ausm hauptteil übernommen in die klasse, funzte sofort. so, nun nutze ich für alle diese shader als grundlage den selben vertex-teil (vertex-shade, fragment-shader). UUUUND? da wo besagte falsche 1 stand steht ja dahinter vTexCoord0 <- joa, bei dem neu integrierten steht da aber vTexture0...

naja, der rest ist wohl schnell zusammengereimt. das geändert, BÄM wir haben ein bild xD

tjo, nu würd ich sagen: auffi zum 3p shader xD ich freue mich schon jetzt auf neues gefluche und ewiges suchen von absoluten deppschusselfehlern. ich könnt mich manchmal selber latschen...
 
AW: [update 2] Bloom-Effekt erzeugen

"A GL ERROR OCCURED!" an. k, also irgendwas is wohl im busch ^^
:lol::lol: made my "morning" :D

die lösung war zum glück recht simpel: glDrawBuffers sollte man erst nach dem binden des fbo's aufrufen - also ab damit in die schleife:
Das mit der Reihenfolge ist natürlich so ein typisch leicht zu übersehendes Problem! Aber in obigem Code-Schnipsel sehe ich keine Stelle, wo DrawBuffers schon vor der Bindung aufgerufen wird?!

Btw, wie schauen eigentlich die Shader for OGL aus? (*zu faul zum googlen sei* ^^) Auch HLSL? Dann könnt ich da jedenfalls vielleicht ein bisschen Unterstützung geben, weil für mein DirectX-Projekt werden halt auch HLSL-Shader genutzt. Ansonsten werde ich wohl Ende des aktuellen Semesters auch (zwangsweise) einen OpenGL-Renderer Programmieren müssen; momentan stecken wir noch beim kompletten Sotware-Renderer (Pixel für Pixel von Hand!) fest ...

Achja und wie schaut das fertige Resultat aus? Akzeptabel? ^^
 
AW: [update 2] Bloom-Effekt erzeugen

also bei ogl nennt sichs GLSL ^^

endergebnis... also ich hab gestern nochmal fix den 3rd pass shader angeworfen und wieder nen shcwarzes bild gesehn. da kam ich aber schnell druff. da ich mehrere bilder habe, die ich dem reintüdel, hab ich in ner schleife alle zugewiesen (glActiveTexture...), dann gerendert und dann in ner schleife wieder für alle textures deaktiviert ():
Code:
        // anschließend wieder alle texturen unbinden
        for(int i = 0; i < 6; i++) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
        }
glActiveTexture ist danach also GL_TEXTURE5 - un das kann dann natürlich nix werden, wenn ich der meine textur zur ausgabe binde ^^ gut, das also auch fix gelöst und wir hatten ein bild!

leider sah es ned sehr schön aus >< ok, gestern sah es besser aus :fresse:
SolarSystem 2013-04-29 09-27-44-93.jpg

das ist mit bloomFactor = 0.5f; je größer der wert wird (1.0 is schon grausam), desto heller wird zwar die szene, desto mehr verschmiert sie aber auch oO
SolarSystem 2013-04-29 09-30-20-50.jpg
junge junge, das wird ja immer schlimmer. im oberen rechten teil dieser lila "strich" zur mitte hin ist die sonne, die im bild ihre bahn zieht, statt halt einfach neugezeichnet zu werden. meine herrn, gestern sahs ja wenigstens noch ansatzweise ordentlich aus ><

naja, zumindest kann ich dir hier gleich mal als bsp die shader präsentieren, dann kannste dir vllt selber antworten, wie vergleichbar das ist. zuerst mal der vertex shader - der gibt an sich nur die daten durch (is ja nur nen bildschirm füllendes 4eck):
Code:
#version 330
 
in vec4 vVertex;
in vec4 vTexture0;

smooth out vec2 vTexCoords;

void main(void) {
    // Pass along the texture coordinates
    vTexCoords = vTexture0.st;

    // Pass along geometry
    gl_Position = vVertex;
}
(wie man sieht, steht hier eindeutig vTexture0 und nicht vTexCoord0... ^^)

der dient eigentlich für die meisten schritte (ausser dem ersten schritt halt, wo das bild an sich gemalt wird ^^). hier mal der blurring fragmentshader. also das ding, wo aus dem brightpass des ersten renderdurchgangs die kleineren subimages erstellt werden mit diesem gausian blur kernel da. ist original so ausm buch abgetippselt (oder findet man genau so auch im netz). sind halt 25 "texture lookups" was nicht unbedingt die tollste lösung ist ^^ empfohlen wird da lieber ein horizontal und ein vertical pass mit je 5 lookups. aber ich wollts erstmal so zum laufen bekommen, bevor ich hier die nächste baustelle aufmach :ugly:
Code:
#version 330

smooth in vec2 vTexCoords;

uniform sampler2D texture0;
uniform vec2 tc_offset[25];

out vec4 oBright;

void main(void)
{
    vec4 hdrSample[25];
    for (int i = 0; i < 25; ++i)
    {
        // Perform 25 lookups around the current texel
        hdrSample[i] = texture(texture0, vTexCoords.st + tc_offset[i]);
    }

    // 5x5 Gaussian kernel
    //   1  4  7  4 1
    //   4 16 26 16 4
    //   7 26 41 26 7 / 273
    //   4 16 26 16 4
    //   1  4  7  4 1

    // Calculate weighted color of a region
    oBright = (
                ( 1.0 * (hdrSample[ 0] + hdrSample[ 4] + hdrSample[20] + hdrSample[24])) +
                ( 4.0 * (hdrSample[ 1] + hdrSample[ 3] + hdrSample[ 5] + hdrSample[ 9] + hdrSample[15] + hdrSample[19] + hdrSample[21] + hdrSample[23])) +
                ( 7.0 * (hdrSample[ 2] + hdrSample[10] + hdrSample[14] + hdrSample[22])) +
                (16.0 * (hdrSample[ 6] + hdrSample[ 8] + hdrSample[16] + hdrSample[18])) +
                (26.0 * (hdrSample[ 7] + hdrSample[11] + hdrSample[13] + hdrSample[17])) +
                (41.0 * (hdrSample[12]))
              ) / 273.0;
}

und zu guter letzt noch den 3rd pass shader. also der, der die ganzen erstellten blur-bilderchen von eben zusammen matscht ^^
Code:
#version 330

smooth in vec2 vTexCoords;

uniform sampler2D origImage;
uniform sampler2D brightImage0;
uniform sampler2D brightImage1;
uniform sampler2D brightImage2;
uniform sampler2D brightImage3;
uniform sampler2D brightImage4;

uniform float bloomLevel;
uniform float exposure;

out vec4 oColor;

void main(void)
{
    // Fetch from HDR texture & blur textures
    vec4 baseImage  = texture(origImage,    vTexCoords);
    vec4 brightPass = texture(brightImage0, vTexCoords);
    vec4 blurColor1 = texture(brightImage1, vTexCoords);
    vec4 blurColor2 = texture(brightImage2, vTexCoords);
    vec4 blurColor3 = texture(brightImage3, vTexCoords);
    vec4 blurColor4 = texture(brightImage4, vTexCoords);

    vec4 bloom = brightPass + blurColor1 + blurColor2 + blurColor3 + blurColor4;

    vec4 color = baseImage + bloomLevel * bloom;

    // Apply the exposure to this texel
    oColor = 1.0 - exp2 (-color * exposure);
    oColor.a = 1.0;
}

tjoa, irgendwas is da scheinbar noch nich so ganz wies soll ^^
 
AW: [update 2] Bloom-Effekt erzeugen

Hmmm ... also erkennen tut man ja schon etwas!
Die ganzen Überschneidungen und Farben sehen aber merkwürdig aus. Diese Treppenstufeneffekte/Balken deuten eigentlich oft auf Schleifen hin, deren Daten nicht ordentlich zurückgesetzt wurden.

Vielleicht hilft ja eine der folgenden Ressourcen:
- OpenGL Bloom Shader :: Dönemeier.de
- Philip Rideout :: Bloom
- Tutorial - OpenGL Bloom Effect - openFrameworks forum

Ansonsten hab ich mich an Bloom noch nicht rangewagt, sprich kenne das Vorgehen dahinter auch nicht^^
 
AW: [update 2] Bloom-Effekt erzeugen

hab jetz gradmal noch nen sinnlosschritt wieder ausgebaut. hatte das alles in ne extra textur gerendert und diese dann aufn schirm gerendert - anstatt das gerödel direkt aufn schirm zu packen ^^ hab mir jetzt mal alle einzelbestandteile anzeigen lassen: die coloTexture is mal wieder schwarz -.- die brightPass textur passt und die blur immages weissen diese fehlstellen auf *grrr*
 
AW: [update 2] Bloom-Effekt erzeugen

ho ha!

SolarSystem 2013-05-12 18-38-51-64.jpg SolarSystem 2013-05-12 18-38-54-42.jpg

ich glaube, ich hatte eben ne intressante idee >< ich bin bisher davon ausgegangen, dass man den bright-pass (also die helligkeits textur da) blurred und diese geblurrte kleinere textur wiederrum blurrt. scheinbar bezieht sich das aber NUR auf die ausgangs textur. eben jene wird zigfach verkleinert und diese verkleinerten subimages der originalen werden geblurred und diese geblurrten farben zusammen addiert usw usf. dabei erschloss sich mir auch das mit den mipmaps.

aktuell hab ichs so umgebaut:
- rendere die szene normal und erzeuge dabei color- und brightpass.
- erzeuge vom brightpass mipmaps (4 bei mir)
- im shader geht er nun alle mip-level durch und für jedes mip-level macht er dieses kernel-abtast-gedöhns da (also 2nd pass shader ist in eine for-schleife im shader gewandert)
- diese werden dann zusammengefasst und das gerödel aus dem 3rd pass shader gleich hinterher berechnet (der 3rd pass shader passiert dann also bei der addition der einzelnen werte und nach dieser extra for schleife)
-> ausgabe aufn schirm

hat jetz ne halbe stunde umbau gedauert und lief auf anhieb xD leider sieht der bloom noch ebbes grob aus. also wenn die sonne so durchs bild wandert, schiebt sie sone pixel-bloom-wlkoe mit sich mit >< hoffe das bekomm ich noch hin. is sicherlich das hdr zeugs, mal schauen, wie ich das hinbekomm.
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

Servus,

schaut schonmal gut aus :daumen:
(auch wenn ich auf dem 2. Bild jetzt nicht unbedingt den Blur-Effekt erkenne ^^ )

Hast du schonmal mit mehr MipMaps probiert? Ändert sich die Optik signifikant?

Manchmal sind es die kleineren Sachen, die zum großen Fortschritt beitragen! Ist mir/meiner Gruppe heute auch in unserem Softwarerenderer passiert: Wurzel-Funktion bei der ganzen Datentransformation rausgekürzt und zagggg 1) Alles lief um Welten schneller (klar) 2) keine Interpolationsartefakte mehr übrig :D

Wenn wir zum Ende des Semesters noch Zeit haben können wir auch mal versuchen Blur noch mit reinzuklatschen, mal sehen, wie das auf der CPU läuft :ugly:
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

aufm 2. sah es zumindest weichgezeichneter aus ^^ hab jetzt aber mal die "originale" variante ausm buch genommen, wo wirklich nur die hellen bereiche geblurrt werden. zudem hab ich endlich ma rausgefunden, wieso sich manche bildteile (wenn man hier rauszoomed hat man ja dieses kugel-raumschiff - mit erdtextur xD - und da drückte sich halt mond und erde bla durch in sonem lila blau stich) durchdrückten. im shader wird ja die fragmentfarbe durch licht und specular gedöhnse verändert - und damit auch der alpha wert nebenher geändert. hab also einfach den alphawert vorher gesichert, dann die lichtberechnungen usw gemacht und am ende den fragment-wert wieder überschrieben. war nen test ins blaue hinein und hat gleich gefunzt xD naja, zuerst hatte ich einfach stur alpha = 1 gemacht, da war aber die atmosphäre eben ned mehr transparent - daher "herrüber retten" des originalen werts. funzt top ^^

nächster ansatz war, dass ich einfach mal für die blur-textur da die werte verzehn(hundert, 1000)fache (also beim ersten renderdurchgang, wo color und brightpass erstellt werden) und im 2. durchlauf dann im kernel (am ende teile ich ja /273) diesen wert am ende eben verzehn,hundert,1000fache (2730, 27300...). hatte allerdings 0 effekt ^^ jetzt laß ich im buch aber, dass dieser ganze part danach mit belichtung und bloom bla auch dazu genutzt wird, aus nem hdr bild nen ldr bild zur ausgabe zu machen (per clamp usw). jetz werd ich mal testen, obs was bringt, wenn ich für die brightpass textur die werte ver-zig-fache ^^ und dafür aber die 273 unberührt lasse. ma schauen ><

weitere änderungen: aufsplittung in vertikal und horizontal pass - ergo doch wieder zig einzeltexturen und fbo's bauen >< weil atm bin ich performance mäßig um den faktor 10 gefallen (~800 auf 80fps :ugly: ). und zu guter letzt soll es laut deinem einen link (den ich auch scho immer gefunden hab, als obs nix andres dazu gibt xD) auch 3 reichen. mal schauen. vllt is das tc_offset dingen (das array mit den abtastwerten) ja auch nur irgendwie ungünstig gebaut, werd ich mir wohl auch nochma anschauen müssen.

jedenfalls hätte man bei ner aufteilung statt 25 abtastwerten nur noch 10 (statt 5x5 2x5) und wenn das mit 3en auch funzt ohne verluste, wärens gar nur 6 (2x3) - also nen 4tel.

Edit: mit dem tc_offset lässt sichs wirklich verbessern:
Code:
void screenFBO::GenTexCoordOffsets(GLuint width, GLuint height) {
    float xInc = [B]3.0f[/B] / (GLfloat)(width);
    float yInc = [B]3.0f[/B] / (GLfloat)(height);

    for (int i = 0; i < 5; i++)    {
        for (int j = 0; j < 5; j++)    {
            this->texCoordOffsets[(((i*5)+j)*2)+0] = (-2.0f * xInc) + ((GLfloat)i * xInc);
            this->texCoordOffsets[(((i*5)+j)*2)+1] = (-2.0f * yInc) + ((GLfloat)j * yInc);
        }
    }
}
hier ganz oben x und yInc waren 1 - das war scheinbar zu "nah". habs jetz mal bissl probiert und 3 sieht ganz annehmbar aus. 5 war wieder zu schlimm ^^ also wenn ichs richtig deute, dann tastet er jetz nichmehr 1 oder 2 pixel um den mittleren herum ab, sondern lässt eben 2e abstand dazwischen. hmm, ich versuchs mal als bild zu verdeutlichen:
sol_1er-abtastung.jpg sol_3er-abtastung.jpg
x/yInc = 1 <- beziehungsweise -> x/yInc = 3

wenn man das mal als vergrößerte pixel sieht, dann sind die roten diejenigen, die abgetastet werden.

das ergebnis schaut nun so aus (hoffe das jpg vormat hats nich allzusehr zerstört ><):
SolarSystem 2013-05-15 13-29-30-68.jpg SolarSystem 2013-05-15 13-29-15-29.jpg
beim ersten mal die sonne aus der nahperspektive (ned so ein block-artiger bloom-hof) und beim 2. etwas aus distanz. auch hier wirkt es deutlich besser finde ich. an der linken landestütze sieht man auch noch etwas bloom des specular lights. also vorallem die ruhe des bildes wirkt sehr viel besser wie vorher (der bloom-hof/schein aussenrum is halt ned mehr so quadratisch/blockig und hüpft nicht mehr mit).
 
Zuletzt bearbeitet:
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

Nabend,

kann morgen vielleicht mal unseren Dozenten aus der Grafik-Veranstaltung fragen, ob er noch andere Lektüre zu Bloom(ing) kennt. Rückmeldung kommt dann :)
Die Auswirkungen von Vervielfachung der Werte für die Blur-Textur kann man ja eigentlich schnell zurückverfolgen; ggf. ist da eine Formel auch nicht richtig umgesetzt (letzteres habe ich selbst öfter erfahren (müssen)).
Zur Rechnerei kann ich jetzt nicht so viel sagen ^^ aber ein *hust* negatives Performancewachstum um den Faktor 10 klingt jetzt eher nach irgendeinem Fehler im Vorgehen ...

Die Optik der Sonne in Nahaufnahme ist ja eigentlich schon ganz ansehbar, wird m.M.n. aber vom Aussehen der Erde - oder des Erdenkonstruktes oder was das ist :D - stark übertroffen: Nicht zu auffällig, aber dennoch signifikant, quasi keine "Kanten" -> Top :daumen:
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

najo, es stand schon im buch, dass das viel rechenzeit kostet. also diese pixel-abfrage da (texture() befehl). und da man hier quasi für jeden pixel 25 abfragen macht, hat man also das 25fache abfrage-volumen. demgegenüber nur 10facher einbruch ist schon vorstellbar, denk ich mal. eben deswegen gibt es ja die aufsplittung in vertical und horizontal pass. weil dieser kernel da (ne matrix, wenn man so will) ergibt sich ja aus den "vektoren" (1 4 7 4 1) und das dingen um 90° gedreht ^^ wart ma...

Code:
              / 1 \   1  4  7  4 1
              | 4 |   4 16 26 16 4
(1 4 7 4 1) + | 7 | = 7 26 41 26 7
              | 4 |   4 16 26 16 4
              \ 1 /   1  4  7  4 1
so quasi. und die aufsplittung resultiert dann eben wieder in diesen einzelvektoren. das ergebnisbild sieht genauso aus, nur dass man eben nur 10 statt 25 pixelabfragen hat. gestern hatte ich auch mal ein "early bias" probiert. hatte mal was zu shadowmaps gelesen gehabt, und da kam auch son kernel vor - und da hatten sie zur verbesserung dieses dingen angemerkt. da prüft man quasi erstmal am rand 4 punkte, ob hier bedarf am blurren besteht (also irgendwas in der blurtextur steht) und nur dann, werden die 25 (also die restlichen 21) pixelabfragen komplett durchgezogen. klappte von der performance her auch super, allerdings hatte ich dann keinen ordentlichen bloom mehr, das sah eher wie ne blume aus xD also wenn ich links rechts oben unten die early abfrage mache, dann hatte die sonne usw eben in diesen richtungen nen kreisrunden blur -> blumen effekt ^^ performance also io, optik fürn hund ><

naja, ich werd mich mal an der aufsplittung versuchen irgendwann.
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

Sehr interessantes Projekt und auch sehr interessant zum lesen, auch wenn ich meist nur Bahnhof verstehe.
Doch du beschreibst alles sehr gut in einem humorvollen stil, (auch sehr witzig wenn du dich aufregst lol) wenn lehrbücher auch so geschrieben wären würde das lesen viel mehr spass machen :D
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

hehe danke ^^ ich find es sehr hilfreich für mich selber, wenn ich versuche anderen die problematik zu erklären. oft hilft mir allein schon diese formuliererei der problematik. dann durchdenk ich alles (und da ich keinen bullshit erzählen will, vertief ich mich zusätzlich nochma rein um alles möglichst richtig rüber zubringen) und komm teils allein dabei schon auf lösungen. wenn dann doch mal ab und zu einer was gescheites weis, umso besser :D
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

Mal eine fixe Frage der etwas anderen art in die runde: ich hab hier nen hübsches (rein von den themen her) tutorial für OGL gefunden. leider sind das scheinbar "nur" die quelltexte ohne erläuterungen. ich würd zwar versuchen, mich da erstmal so reinzufuchsen, aber nuja ^^

jedenfalls scheint es besagte erläuterungen dazu in eBook-Form zu geben: 3D-Spieleentwicklung - OpenGL - GLSL - OpenCL - OpenAL - KI - Animation - Spielephysik hier sind 2 amazon links zu den büchern, zusammen unter 10€. ALLERDINGS als "Kindle Edition" - also für diesen besichnen eBook reader da von amazon. Daher jetzt meine frage: braucht man das rotz ding unbedingt oder is das nen stink normales pfd, was ich auch einfach am rechner lesen kann?

kenn mich damit leider 0 aus ><
 
Zurück