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

11

31.05.2012, 18:21

Okay, um die Division durch 0 zu vermeiden, bin ich gewechselt auf trigonometrische Funktionen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
uniform sampler2D world;
uniform vec2 resolution;
uniform vec2 sun;

void main (void)
{
    float stepSize=1.0;
    vec4 texel=texture2D(world,gl_TexCoord[0].st);
    vec2 pos=vec2(floor(gl_FragCoord.x),floor(gl_FragCoord.y));
    vec2 texFac=vec2(1.0/resolution.x,1.0/resolution.y);
    if (texel.a!=0.0)
        discard;
    if (sun.y<pos.y)
        discard;
    float alpha=atan(sun.y-pos.y,sun.x-pos.x);
    vec2 delta=vec2(cos(alpha),sin(alpha));
    vec2 checkPos=pos;
    vec2 checkTex;
    for (;checkPos.y<sun.y;checkPos.y+=delta.y*stepSize) {
        checkTex.x=checkPos.x*texFac.x;
        checkTex.y=checkPos.y*texFac.y;
        texel=texture2D(world,checkTex);
        if (texel.a!=0.0) {
            gl_FragColor=vec(0.0,0.0,0.0,0.95);
            return;
        }
        checkPos.x+=delta.x*stepSize;
    }
}


Jetzt wird die Map schwarz gemalt aber sonst nichts anderes...

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

12

31.05.2012, 18:51

Warum atan() und dann wieder sin()/cos()? Normier doch einfach den Vektor und fertig. Auch abgesehen davon machst Du ziemlichen Unsinn. Ich hätte ja gedacht, Du rechnest einfach Startpos und delta pro Schritt in Texturkoordinaten aus und marschierst los, aber was Du da geschaffen hast, ist ein ziemliches Monster.

Außerdem kann es gut sein, dass Dein Grafikkarten-Treiber Dir den Shader killt, wenn er zulange in der Ausführung ist. Du machst hier im schlimmsten Fall ja ein paar hundert Samples, das reicht auf älteren GPUs schon für den Zusammenbruch. Kaskadiere mehrere Passes, wie ich in meinem ersten Link erklärt habe, und Du bekommst dutzendfache Performance.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

13

31.05.2012, 19:49

okay ich hoffe ich hab erst mal das mit dem normieren richtig hingekriegt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
uniform sampler2D world;
uniform vec2 texFac;
uniform vec2 sun;

void main (void)
{
    float stepSize=256.0;
    vec4 texel=texture2D(world,gl_TexCoord[0].st);
    vec2 pos=vec2(floor(gl_FragCoord.x),floor(gl_FragCoord.y));
    if (texel.a!=0.0)
        discard;
    if (sun.y<pos.y)
        discard;
    vec2 delta=normalize(vec2(sun.y-pos.y,sun.x-pos.x));
    vec2 checkPos=pos;
    vec2 checkTex;
    for (;checkPos.y<sun.y;checkPos.y+=stepSize*delta.y) {
        checkTex.x=checkPos.x*texFac.x;
        checkTex.y=checkPos.y*texFac.y;
        texel=texture2D(world,checkTex);
        if (texel.a!=0.0) {
            gl_FragColor=vec4(0.0,0.0,0.0,0.95);
            return;
        }
        checkPos.x+=delta.x*stepSize;
    }
}

Was ich nicht verstehe: Deine Kaskadenmethode basiert ja auf der Idee nicht jeden Texel überprüfen zu müssen, was ich erst mal mit der "stepSize"-Variable versucht habe zu implementieren. Bei der momentanen Maximalhöhe von der Lichtquelle von 320 dürften es doch hier (stepSize=256) höchstens 2 Samples sein die ich über die gesamte Strecke mache, trotzdem wird der Shader gekillt.

Edit: kleine, erst mal unwichtige Optimierung indem die Berechnungen für die Textur zu Pixel Faktoren nur einmal ausgeführt werden.

14

01.06.2012, 05:59

Vermutlich ist es dir noch nicht aufgefallen, aber er hat den Shadercode sogar gepostet:

HLSL-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
uniform vec2 lightpos;
uniform vec3 lightColor;
uniform float screenHeight;
uniform vec3 lightAttenuation;
uniform float radius;

uniform sampler2D texture;

void main()
{ 
    vec2 pixel=gl_FragCoord.xy; 
    pixel.y=screenHeight-pixel.y;   
    vec2 aux=lightpos-pixel;
    float distance=length(aux);
    float attenuation=1.0/(lightAttenuation.x+lightAttenuation.y*distance+lightAttenuation.z*distance*distance);    
    vec4 color=vec4(attenuation,attenuation,attenuation,1.0)*vec4(lightColor,1.0);  
    gl_FragColor = color;//*texture2D(texture,gl_TexCoord[0].st);
}

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »appfyr« (01.06.2012, 06:25)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

15

01.06.2012, 06:51

Appfyr, vermutlich ist es Dir noch nicht aufgefallen, aber er hat den Shader sogar gelesen und schon erwähnt, dass dort von Raycasting nichts drin steht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

16

02.06.2012, 14:04

Hi,
erste Ausgaben vom Shader der mittlerweile so aussieht:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#version 120

uniform sampler2D world;
uniform vec2 texFac;
uniform vec2 sun;

void main (void)
{
    float stepSize=8.0;
    vec4 texel=texture2D(world,gl_TexCoord[0].st);
    vec2 pos=vec2(floor(gl_FragCoord.x),floor(gl_FragCoord.y));
    if (texel.a!=0.0)
       discard;
    if (sun.y<pos.y)
        discard;
    vec2 delta=normalize(vec2(sun.y-pos.y,sun.x-pos.x));
    if (delta.y<0.0) {
        gl_FragColor=vec4(1.0,0.0,1.0,1.0);
        return;
    }
    vec2 checkPos=pos;
    vec2 checkTex;
    while (checkPos.y<sun.y) {
        checkTex.x=checkPos.x*texFac.x;
        checkTex.y=checkPos.y*texFac.y;
        texel=texture2D(world,checkTex);
        if (texel.a!=0.0) {
            gl_FragColor=vec4(0.0,0.0,0.0,0.95);
            checkPos.y=sun.y+100000000.0;
            break;
        }
        checkPos.x+=delta.x*stepSize;
        checkPos.y+=delta.y*stepSize;
    }
}

Wenn man sich von einem utopischen stepSize Wert (z.B: 32000000) runterklettert kann man teilweise bis 8.0 kommen... ein Fehltritt und man muss von vorne anfangen ansonsten gibt es nur Grafiktreiberabstürze, wobei auch schon mal ein Bluescreen kam, was immer sehr motivierend ist, dazu noch 2 Internetabstürze, sodass dies das 3. Mal ist das ich diesen Post schreibe und ein wenig meinen Optimismus verloren habe...
Ich habe es nach einiger Zeit geschafft ein paar Screenshots zu verschiedenen stepSize Werten zu machen:
stepSize=64

(Link)

stepSize=32

(Link)

stepSize=24

(Link)

stepSize=16

(Link)

Zu den Screenshots ist zu bemerken:
  1. Das Pinkene sind Fragmente dessen delta.y kleiner 0 ist, die also aus der schleife nicht rauskommen können
  2. Das Weiße sind Fragmente, bei denen während des Raycasten die checkPos.x Variable größer ist als die Textur (in diesem Fall >512)
  3. Vor allem bei stepSize=32 sieht man rechts unten deutlich einen Schatten der die gleiche Form hat wie die Map rechts nebendran..
  4. Desto niedriger stepSize ist desto korrekter fallen die Schatten aus (<- ist klar...)
  5. In dem Weißen sieht man Stufen die mehr werden je niederiger stepSize ist
  6. Dort wo die linke obere Ecke des Pinkenen ist, ist die Lichtquelle (sun)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

17

03.06.2012, 08:55

Mal 'ne ganz andere Frage: Wozu eigentlich? Soll der Rasen noch dunkler werden an den Stellen oder sollen da wirklich so dunkelblaue Dreiecke drin bleiben? Denn Schatten findet man auf Himmelhintergrund in der Realität ja eher nicht und es sieht komisch aus. Ich weiß, das mag für Deine Idee und investierte Zeit jetzt hart klingen, aber vielleicht verschwendest Du da Zeit an etwas, was am Ende total hässlich und falsch aussieht?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige