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

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

11

13.11.2010, 23:17

Also zu den Tangenten und Binormalen. Ich gehe vom Koordinaten System aus, was in DirectX üblich ist.
Bei einem Quadrat, das in der XZ-Ebene liegt, treffen folgende Werte zu:
Normale = (0, 1, 0)
Tangente= (1, 0, 0)
Binormale= (0, 0, 1)

Richtig?
Wenn ja: Im Pixelshader kommen daher auch die richtigen World-Tangenten, World-Normalen und World-Binormalen an.

Nur die Normalen aus der NormalMap werden nicht richtig verarbeitet.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

12

13.11.2010, 23:32

Verwendest du ein rechts- oder linkshändiges Koordinatensystem? Für ein linkshändiges schaut die Binormale in die falsche Richtung wenn du mich fragst. Beachte außerdem dass du, wenn du einen Vektor im VertexShader über das Kreuzprodukt berechnest, trotzdem dessen Vorzeichen an den Shader übergeben musst da der Tangentspace vielleicht eine andere Handedness haben könnte. Gib vielleicht mal die Worldspace Tangente/Binormale aus dem PixelShader als Farbe aus und schau ob plausible Werte rauskommen...

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

13

14.11.2010, 00:06

Ich verwende ein linkshändiges Koordinatensystem.
Ich habe jetzt die Binormale in die andere Richtung zeigen lassen (Parameter im Kreuzprodukt vertauscht).

Wenn ich mir Normale, Tangente und Binormale als Farbe anseh, stimmt da alles.
Nur die Normalen aus der Normalmap, die eigentlich WorldNormalen sein sollten, stimmen nicht. Es kommt mir so vor, als würden die Normalen mit doppelter Geschwindigkeit rotiert werden, als das Objekt.

Zitat

Beachte außerdem dass du, wenn du einen Vektor im VertexShader über das Kreuzprodukt berechnest, trotzdem dessen Vorzeichen an den Shader übergeben musst da der Tangentspace vielleicht eine andere Handedness haben könnte.

Bitte was?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

14.11.2010, 00:33

Wenn ich mir Normale, Tangente und Binormale als Farbe anseh, stimmt da alles.
Nur die Normalen aus der Normalmap, die eigentlich WorldNormalen sein sollten, stimmen nicht. Es kommt mir so vor, als würden die Normalen mit doppelter Geschwindigkeit rotiert werden, als das Objekt.

Kannst du dazu vielleicht einen Screenshot posten?

Zitat

Beachte außerdem dass du, wenn du einen Vektor im VertexShader über das Kreuzprodukt berechnest, trotzdem dessen Vorzeichen an den Shader übergeben musst da der Tangentspace vielleicht eine andere Handedness haben könnte.

Bitte was?

Sry das war etwas unklar ausgedrückt, dein Tangentspace könnte an manchen Vertices rechtshändig sein (z.B. an Stellen wo die Textur gespiegelt ist). Das Kreuzprodukt liefert dir in diesem Fall einen Vektor der in die falsche Richtung zeigt. Um das zu berücksichtigen packt man einfach eine -1 oder 1 in die 4te Koordinate des Tangentenvektors im Vertex mit der man dann das Kreuzprodukt im Shader noch multipliziert.

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

15

14.11.2010, 09:21

Spiegelungen in der Textur habe ich keine.
Angenommen ein simples Quad, linkshändiges Koordinatensystem. Texturkoordinaten unverzerrt unverspiegelt an den Eckpunkten.
Wo laufen dann Tangente und Binormale hin? Entlang der U- und V-Textur-Koordinaten?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

16

14.11.2010, 09:24

Natürlich, Tangente und Binormale laufen per Definition "entlang der u- bzw v-Texturkoordinate"...

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

17

14.11.2010, 09:33

Hier ein paar Screenshots:
Das Quad liegt in der XZ-Ebene

EDIT: Hier noch das Mesh. Ich hoffe das Format ist verständlich.

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
    <Mesh NumTriangles="2">
        <VertexBuffer NumVertices="4">
            <POSITION Encoding="Text">
9.99999905 0.00000000 9.99999809
9.99999905 0.00000000 -10.00000095
-10.00000191 0.00000000 -9.99999905
-9.99999714 0.00000000 10.00000191
            </POSITION>
            <NORMAL Encoding="Text">
0.00000000 1.00000000 0.00000000
0.00000000 1.00000000 0.00000000
0.00000000 1.00000000 0.00000000
0.00000000 1.00000000 0.00000000
            </NORMAL>
            <TANGENT Encoding="Text">
1.00000000 -0.00000000 0.00000002
1.00000000 -0.00000000 -0.00000001
1.00000000 -0.00000000 0.00000002
1.00000000 0.00000000 0.00000005
            </TANGENT>
            <TEXCOORD Encoding="Text">
0.99999994 0.00000024
0.99999988 1.00000000
0.00000000 0.99999982
0.00000033 0.00000000
            </TEXCOORD>
            </VertexBuffer>
        <IndexBuffer NumIndices="6" Encoding="Text">
0 2 3
0 1 2
        </IndexBuffer>
    </Mesh>
»BlazeX« hat folgende Bilder angehängt:
  • WorldTangent.jpg
  • WorldBinormal.jpg
  • WorldNormal.jpg
  • NormalMap (Nur Textur gesampelt).jpg
  • Transformierte WorldNormalen.jpg

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

18

14.11.2010, 09:52

Wenn das Quad nicht irgendwie transformiert ist würde ich eigentlich erwarten dass die Worldspace Tangente knallrot, die Bintangente knallgrün und die Normale Knallblau ist!?
Die Worldspace Normale schaut mir jetzt komischerweise garnichtmal so schlecht aus, aber das kann auch täuschen. Nur wundert mich dass sie an der zur Kamera gerichteten Seite ins blaue geht. Wenn die Kamera in Richtung der positiven z-Achse schaut sollte das doch eigentlich genau anders rum sein (ist vielleicht die Bitangente verkehrt)!?

BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

19

14.11.2010, 10:02

Die Farbe berechne ich so: Color= vIrgendEinVektor / 2 + 0.5
Die WorldNormale zeigt in Richtung positive Y-Achse, die WorldTangente in Richtung positive X-Achse und die Binormale in Richtung negative Z-Achse.
Die Kamera sieht in Richtung positive Z-Achse.

Das ergibt z.B. für die WorldTangente eine Farbe von (1, 0.5, 0.5)

Stimmen die WorldNormale, Tangente und Binormale (auf den 3 ersten Bildern) erstmal?


EDIT: Der Shader sieht jetzt so aus:

HLSL-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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//////////////////////////////////////////////////////////////////
//Includes
#include"Constants.fx"
#include"Sampler.fx"
#include"Textures.fx"
#include"Lighting.fx"


//////////////////////////////////////////////////////////////////
//Layout
struct VSInput
{
    uint IID                    : SV_InstanceID;
    float3 vPosition            : POSITION0;
    float3 vNormal              : NORMAL0;
    float3 vTangent             : TANGENT0;
    float2 vTextureCoord        : TEXCOORD0;
};

struct PSInput
{
    uint IID                    : INSTANCEID;
    float4 vPosition            : SV_Position;
    float3 vWorldPosition       : POSITION0;
    float3 vViewDir             : VIEWDIR0;
    float3 vNormal              : NORMAL0;
    float3 vTangent             : TANGENT0;
    float3 vBinormal            : BINORMAL0;
    float2 vTextureCoord        : TEXCOORD0;
};

struct PSOutput
{
    float4 Color   : SV_Target0;
};

//VertexShader
PSInput VertexShaderProc(VSInput In)
{
    PSInput Out;
    
    Out.IID= In.IID;
    
    float4 vWorldPosition= mul(float4(In.vPosition, 1.0), Instance[In.IID].mWorld);
    Out.vPosition= mul(vWorldPosition, mViewProjection);
    
    Out.vWorldPosition= vWorldPosition.xyz;
    Out.vViewDir= normalize(Out.vWorldPosition - vCameraPosition);
    float3 vNormal= mul(In.vNormal, (float3x3)Instance[In.IID].mWorld);
    Out.vNormal= vNormal;
    
    Out.vTangent= mul(In.vTangent, (float3x3)Instance[In.IID].mWorld);
    Out.vBinormal= cross(Out.vNormal, Out.vTangent);
    
    Out.vTextureCoord= In.vTextureCoord;
    
    return(Out);
}

//PixelShader
PSOutput PixelShaderProc(PSInput In)
{
    PSOutput Out;
    
    //NormalMapping
    row_major float3x3 mTSToWS= {In.vTangent, In.vBinormal, In.vNormal};
    float3 vNormal= mul(TexNormalHeight.Sample(TextureSamplerWrap, In.vTextureCoord).rgb * 2.0 - 1.0, mTSToWS);
    
    //Illumination
    float3 DiffuseLight= float3(0, 0, 0);
    float3 SpecularLight= float3(0, 0, 0);
    LightSource Light;
    uint LightIndex;

    //Light #0 (Directional)
    LightIndex= Instance[In.IID].aLightIndices[0].LID;
    if(LightIndex != 0xFFFFFFFF)
    {
        Light= aLights[LightIndex];
        DiffuseLight+= DirectionalLightDiffuse(Light, vNormal);
        SpecularLight+= DirectionalLightSpecular(Light, vNormal, MatSpecularColorPower.a, In.vViewDir);
    }
    //Color-Sources
    float4 ColorAlpha= MatColorAlpha;
    float4 SpecularColorPower= MatSpecularColorPower;
    float4 EmissiveAmbient= MatEmissiveAmbient;
    float4 MirrorColorSaturation= MatMirrorColorSaturation;
    
    ColorAlpha*= TexColorAlpha.Sample(TextureSamplerWrap, In.vTextureCoord);
    
    Out.Color= float4(0, 0, 0, 1);
    Out.Color.rgb+= AmbientLight.rgb * EmissiveAmbient.a * ColorAlpha.rgb;
    Out.Color.rgb+= DiffuseLight * ColorAlpha.rgb;
    Out.Color.rgb+= SpecularLight * SpecularColorPower.rgb;
    
    Out.Color.rgb= (vNormal) / 2 + 0.5; return(Out);
}

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlazeX« (14.11.2010, 10:12)


BlazeX

Alter Hase

  • »BlazeX« ist der Autor dieses Themas

Beiträge: 478

Wohnort: DD

Beruf: Maschinenbau-Student

  • Private Nachricht senden

20

14.11.2010, 12:13

Ich hab ein Problem gefunden, die Normalmaps aus dem DirectX SDK sind alle rechtshändig. Bei denen zeigt grün nach oben!
Drauf gekommen bin ich, als ich die Binormale testweise mit -1 multipliziert hatte, da sah alles in Ordnung aus.

Jetzt funktioniert alles, wie es soll. Die Fehler waren:
1.) rechtshändige (grün oben) Normalmaps (aus dem DXSDK), die sollten eigentlich linkshändig (grün unten) sein, da die Binormale in Richtung der V-Achse zeigt.
2.) Binormalen zeigen in Richtung V-Achse, das heißt nach unten. Bei mir zeigten sie nach oben.
3.) Die BTN-Matrix spaltenweise zu intitialisieren funktionierte nicht so richtig.

Als ich das entwickelt habe, haben sich die Fehler irgendwie gegenseitig aufgehoben. Etwas rotiert brachte es aber jetzt Fehler.
Jetzt funktioniert alles erstmal perfekt.

Danke Dot, für deine Hilfe!

Anbei noch der Beweis: Eine Kugel wird von oben rechts beleuchtet. Die Normalmap habe ich "verlinkshändigt".
»BlazeX« hat folgendes Bild angehängt:
  • VonObenRechtsBestrahlt.jpg

Werbeanzeige