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

1

26.04.2009, 18:46

HLSL Lighting

Hi Spieleprogrammierer!

Ich bin noch etwas neu in der großen und weiten Shader Welt, und versuche mich gerade an einem Directionalen Perpixel-Lighting. Soweit klappt das auch sehr gut, bis zu meiner WorldMatrix noch eine Rotation hinzu kommt.

Nun erstmal der Shader (ist ja noch sehr klein):

Quellcode

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
36
37
38
39
float4x4 WorldMatrix;
float4x4 ViewMatrix;
float4x4 ProjectionMatrix;

struct VS_OUTPUT
{
    float4 Position : POSITION;
    float3 Normal   : TEXCOORD1;
};

VS_OUTPUT vs_main(float4 Position : POSITION, float3 Normal : NORMAL)
{
    VS_OUTPUT Out = (VS_OUTPUT) 0;

    float4 worldPosition = mul(Position, WorldMatrix);  
    float4 viewPosition  = mul(worldPosition, ViewMatrix);  
 
    Out.Position = mul(viewPosition, ProjectionMatrix); 
    Out.Normal   = Normal;
 
    return Out;
}


float4 ps_main(float4 Position : POSITION, float3 Normal : TEXCOORD1) : COLOR0
{
    float4 LightDir = {1.0f, -0.3f, 1.0f, 1.0f};

    return (dot(LightDir, Normal)+0.2f);
}

technique aaa
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 vs_main();
        PixelShader  = compile ps_2_0 ps_main();
    }
}


Wenn ich nun meine Rotations Matrix mit meiner Translations Matrix multiplitziere, und diese dann den Shader als WorldMatrix übergebe, scheint die Rotation nicht beachtet zu werden, was auch kein wunder ist, da ich die Position bei der Lichtberechnung garnicht beachte, sondern nur die Normalen.

Quellcode

1
return (dot(LightDir, Normal)+0.2f);


Nun habe ich keine Idee wie ich da noch die Position unterbringen sollte!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

26.04.2009, 19:10

Wieso transformierst du die Normalen nicht mit?

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

26.04.2009, 20:36

david_pb hats auf den punkt gebracht. du musst die normalen mit der worldmatrix mulitplizieren.

ansonsten wenn du vorher Rotation * Translation als worldmatrix übergibst ist das schon korrekt wenn auch etwas unperformant pro vertex 3 matrixmultiplikationen anstatt einer zu machen, aber das kann man später machen das sollte auch so klappen.

4

26.04.2009, 21:14

Nicht direkt. Die Normalvektoren müssen mit der transponierten, invertierten Worldmatrix multipliziert werden. Die ist aber auch des öfteren identisch mit der Worldmatrix, aber eben nicht unbedingt immer.

http://www.lighthouse3d.com/opengl/glsl/index.php?normalmatrix
Lieber dumm fragen, als dumm bleiben!

5

26.04.2009, 21:43

Danke! Glaub das sollte ich soweit hin bekommen. Dachte das wäre ein wenig komplizierter ;)

6

28.04.2009, 17:15

Muss euch dann doch nochmal um Rat fragen :roll:

Ich möchte nun mehrere Lichter in meine Scene einbauen, dazu habe ich mit dann einfach gedacht das ich ein Array anlege, welcher die Farbdaten der jeweiligen Lichter trägt.

Quellcode

1
2
3
int LightCount;
float4 LightColor[LightCount];
float3 LightDirection[LightCount];


Nun scheint das ganze nicht so zu funktionieren wie es soll. Ich vermute weil LightCount "noch" undefiniert ist, kann dieser Integer nicht zur Größenbeschreibung eines Arrays dienen, und es kommt zu einem Fehler.

Ich möchte nur ungerne die Anzahl der Lichter begrenzen und würde gerne von euch wissen wie ihr das macht?

7

28.04.2009, 19:49

womit verwendest du den shader? weil afaik gibts bei direkter verwendung von D3DX, oder einer engine mit entsprechendem Interace die möglichkeit präprozessordefinitionen anzugeben, damit könntest du dann beim laden des shaders die anzahl der Lichter auf das maximum der GraKa setzen ;)

zugegeben, ich hab sowas nioch nie gemacht, wär aber mien erster gedanke ;)

8

28.04.2009, 23:58

Ich benutze die ID3DXEffect Klasse als Schnitstelle.

Währe das denn nicht eine unheimliche Speicher verschwendung auf der Grafikkarte? Wenn ich einen float4 Array mit der Größe von 9999999, dann währe das dann doch ein wenig verschwendung. Habe die begrenzung der Lichter auf 16 gesetzt, das sollte eigentlich vollkommen ausreichen :)

Werde deine Idee aber mal ausprobieren, vieleicht klappt das ja ganz gut. Werde mich auf jeden fall nochmal melden wenn ich es eingebunden habe.

9

29.04.2009, 17:38

Zitat von »"Deppomat"«

***** das denn nicht eine unheimliche Speicher verschwendung auf der Grafikkarte? Wenn ich einen float4 Array mit der Größe von 9999999, dann ***** das dann doch ein wenig verschwendung. Habe die begrenzung der Lichter auf 16 gesetzt, das sollte eigentlich vollkommen ausreichen :)

also ich weiß ja nicht, was für ne graka du hast, aber meine unterstützt nur 8 lichter (ja, 16 oder vllt sogar 32 mag ja sein je nach modell, aber 99999999?). mag ja sein, das du in nem shader aus irgendwelchen gründen mehr lichter unterbringen kannst, als die graka bei fixed function unterstützt (das meinte ich), aber das macht wirklich keinen sinn ;)

10

29.04.2009, 23:24

Habe bisher nie die Fixed-Funktion-Pipeline für Lichter benutzt, wusste garnicht das die Anzahl der Lichter so stark begrenzt ist. Ich frag mich nur wie diese relativ alten Spiele wie Unreal Tournament um die 50 Lichter auf einen Haufen unterstützt haben?

Werbeanzeige