Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

31.05.2014, 14:06

GLSL Frage

Tag,

ich hätte eine kleine Frage zu GLSL.
Und zwar brauche ich für mein nächstes Projekt Schatten. Dabei möchte ich gerne optional mit Textur rendern können (z.B. für Blätter).

Sowas funktioniert (nur Fragment Shader):

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#version 330

precision highp float;

uniform sampler2D texture0;
uniform bool useTexture = false;

in vec2 texCoord;

void main(){    
    if(useTexture){
        discard;
    }
}


Also wenn ich für useTexture true sende (und eine Textur mit Texturkoordinaten binde), wird nichts in die depth map geschrieben. Für den Rest aber schon noch.
Ergebnis:


(Link)


Dass hier gerade noch ein Problem mit dem blending auftritt ist erstmal nebensächlich. Aber man sieht wie alle Würfel, bis auf den mit der komischen transparenten Textur, Schatten werfen. So wie ich es erwartet habe.
Wenn ich jedoch das hier mache:

Quellcode

1
2
3
4
5
6
7
void main(){    
    if(useTexture){
        if(texture(texture0, texCoord).a == 1.0){
            discard;
        }
    }
}


Wird gar nichts mehr in die depth map geschrieben... So wird gerendert: in update().
Woran liegt das?

2

31.05.2014, 14:23

Wie sieht denn die Textur aus?
Wenn ich mir die aus dem res/models/box/ verzeichnis ansehe, hat die keine Alpha-Werte.

btw.: die alpha-farbkomponente gibt die Transparenz des Objekts an, nicht die Sichtbarkeit.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

31.05.2014, 14:39

Da sind 4 "Boxen", die schwarze (Mitte über der roten) hat ja wohl offensichtlich Transparenz.
GitHub kann keine TGAs anzeigen.

Zitat

die alpha-farbkomponente gibt die Transparenz des Objekts an, nicht die Sichtbarkeit.

Ja und? Wer sagt dass ich das nicht dafür missbrauchen kann?
Die andere Geometrie guckt ja auch nur Pixel ja/nein -> Tiefenwert schreiben.
Ich muss ja auch nicht mit der original Textur benutzen.

Im Grunde will ich nur eine Textur haben, gucken welchen Wert der Alpha Kanal hat, wenn der 1 ist -> nicht schreiben.
Und das ganze soll optional sein, also harte Geometrie soll immer noch ohne Textur stumpf in die depth map schreiben.

Das Problem ist definitiv diese Zeile, die verhindert dass auch die anderen Boxen (ohne Textur) in die depth map schreiben:

Quellcode

1
if(texture(texture0, texCoord).a == 1.0){


Wobei natürlich die umschließende Bedingung gar nicht erst zutreffen sollte (useTexture).

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

31.05.2014, 14:50

Zitat von »DeKugelschieber«

== 1.0

Gleitkommazahlen sollten niemals auf Gleichheit geprüft werden, wegen diversen Schwierigkeiten bei der exakten Darstellung. Sieh zb. hier.

Ich hoffe auch das dir bewusst ist, das "discard", Verzweigungen etc. möglicherweise der Verarbeitungsweise von GPUs nicht gefallen, es leicht passieren kann, dass die Leistung vergleichsweise stark leidet. Eventuell sind andere Ansätze bei dir möglich, wie zum Beispiel verschiedene Shadervarianten oder wenn Verfügbar auch Subroutines.

Zitat von »DeKugelschieber«

gucken welchen Wert der Alpha Kanal hat, wenn der 1 ist -> nicht schreiben.

Wieso verwendest du eigentlich nicht einfach den Alpha-Test?

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Spiele Programmierer« (31.05.2014, 14:55)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

31.05.2014, 15:23

Zitat

Gleitkommazahlen sollten niemals auf Gleichheit geprüft

Weiß ich, ist hier nur experimentell. Später hätte ich eher auf >= geprüft oder so etwas.

Zitat

Ich hoffe auch das dir bewusst ist, das "discard", Verzweigungen etc. möglicherweise der Verarbeitungsweise von GPUs nicht gefallen, es leicht passieren kann, dass die Leistung vergleichsweise stark leidet. Eventuell sind andere Ansätze bei dir möglich, wie zum Beispiel verschiedene Shadervarianten oder wenn Verfügbar auch Subroutines.

Nein war mir nicht bewusst, aber danke dafür.

Zitat

Wieso verwendest du eigentlich nicht einfach den Alpha-Test?

Hmm habe ich gar nicht drüber nachgedacht. Geht das für depth Werte?
Ich teste es mal, wäre ja noch einfacher :P

6

31.05.2014, 15:38

Wenn jeder Pixel discarded wird, hat scheinbar jedes Texel deiner Textur Einen alphawert von 1.0. Deine Zeile ist völlig in Ordnung, auch wenn es auch anders ginge.

Somit muss das Problem beim Laden bzw. Schreiben liegen.. Oder eben an der Textur selber. ;)
Dementsprechend würde auch der alphatest nicht funktionieren.
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

SlinDev

Treue Seele

Beiträge: 142

Wohnort: Lübeck

Beruf: Programmierer

  • Private Nachricht senden

7

31.05.2014, 15:57

Also Alpha Testing solltest du nicht nutzen, das gibt es im Core Profile auch nicht mehr.
Die eigentliche Frage ist ja, warum useTexture true ist, obwohl es als false gesetzt ist. Der Shader sieht aber soweit okay aus, von daher habe ich mir mal deine Shaderklasse angeguckt und da gibt es kein sendUniform für bool, eventuell solltest du damit mal anfangen. Er wird dir da also ein int draus machen und versuchen es deiner bool Shadervariablen zuzuweisen, wo ich eigentlich einen glError erwarten würde, so dass da dann irgendwas passiert aber nicht was du möchtest.

Edit:
Discard und Branches sind zwar teilweise nicht toll, aber wenn man es nicht völlig falsch macht auch nicht wirklich schlimm und in Verbindung mit "Approaching Zero Driver Overhead" werden Übershader mit dynamischen Branches sogar empfohlen.
"For starters, branching is not nearly as bad as it once was. In particular, if branching is coherent based on the value of a constant (pulled from a UBO, of course), then the cost is negligible."
Discard ist hauptsächlich auf manchen mobilen GPUs etwas problematisch wenn man es falsch nutzt, weshalb es irgendwie den Ruf bekommen hat generell böse zu sein.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »SlinDev« (31.05.2014, 16:29)


Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

8

31.05.2014, 16:44

Das es den Alpha Test nicht mehr gibt, ist mir neu. :!:
Dann ist es ist möglicherweise hier sogar der sinnvollste Weg über "if" + "discard"

Ich bleibe jedoch bei meiner Aussage, das zumindest die äußere Verzweigung nicht optimal ist.

Zitat von »iSmokiieZz«

Deine Zeile ist völlig in Ordnung

Es funktioniert != völlig in Ordnung

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

9

01.06.2014, 14:40

Also erstmal: wie wird denn Transparenz gerendert, wenn es den Alpha Test nicht mehr gibt? Selbst machen?
Ist mir jetzt auch neu...

Dann:

Quellcode

1
2
3
4
5
6
7
void main(){    
    if(useTexture){
        //if(texture(texture0, texCoord).a == 1.0){ // does not work...
            discard;
        //}
    }
}


Funktioniert das so, wie gewünscht. Also die uniform wird übergeben (egal ob int oder nicht, wird dann eben true oder false je nachdem ob das int 0 ist oder einen Wert hat).
Die Bedingung lässt sich auch tauschen (if(useTexture == false)) und liefert das erwartete Ergebnis (die anderen Boxen haben keinen Schatten).

Sobald ich jedoch den Alpha Wert aus der Textur auslesen will geht es nicht mehr. Auch wenn keine Textur genommen werden soll und useTexture dann eben false ist.

Noch mal deutlicher, das führt dazu dass gar nichts mehr geschrieben wird, der Shader schmeißt keinen Fehler beim compilieren:

Quellcode

1
2
3
4
5
6
7
void main(){
    if(useTexture){
        vec4 color = texture(texture0, texCoord);
        
        discard;
    }
}

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

10

01.06.2014, 14:52

Zitat von »DeKugelschieber«

wie wird denn Transparenz gerendert, wenn es den Alpha Test nicht mehr gibt? Selbst machen?

Ja, "discard" ist dann wohl die einzige Möglichkeit.
Für Semi-Transparenz gibt es ja auch noch Alpha Blending.

Ansonsten verstehe ich im Moment dein Problem ehrlich gesagt nicht ganz.
Ich würde halt mal ein "> 0.99" draus machen, um da auf der sicheren Seite sein.
Die Bedingung würde ich wie gesagt abschaffen. Zb. zwei Shader: Einer mit Textur und einer ohne.

Werbeanzeige