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

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

24.05.2013, 23:51

Hardware Instancing: Vertexshader gibt falsche Koordinaten zurück

Hallo.
Ich versuche mich gerade dem Hardware-Instancing. Mein Code sieht so aus:

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
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
struct INSTANCE_DATA
{
    Color color;

    Vector4 f1,f2,f3,f4;
};

D3DVERTEXELEMENT9 g_VBDecl_Both[] =
{
    {0,  0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
    {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
    {0, 24, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
    {0, 40, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},

    {1,  0,  D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
    {1,  16, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
    {1,  32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
    {1,  48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
    {1,  64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 5},
    D3DDECL_END()
};
IDirect3DVertexDeclaration9* g_pVertexDecl;

// ...

void CreateBuffers()
{
    Direct3D& D3D = Direct3D::Instance();

    // Geometry VB/IB buffer is created by modelclass

    D3D->CreateVertexDeclaration(g_VBDecl_Both, &g_pVertexDecl);

    g_pVBInstanceData = new VertexBuffer;
    g_pVBInstanceData->Init(g_iNumObj * sizeof(INSTANCE_DATA), sizeof(INSTANCE_DATA), 0, D3DUSAGE_WRITEONLY, D3DPOOL_MANAGED);

    INSTANCE_DATA* pID;

    g_pVBInstanceData->GetVB()->Lock(0, 0, (void**)&pID, 0);

    int nRemainingBoxes = g_iNumObj;
    for( int iY = 0; iY < 10; iY++ )
    {
        for( int iZ = 0; iZ < 10; iZ++ )
        {
            for( int iX = 0; iX < 10 && nRemainingBoxes > 0; iX++, nRemainingBoxes-- )
            {
                INSTANCE_DATA iD;

                iD.color = Color(1.0f);
                Matrix m = MatrixTranslation(Vector3(iZ * 6.0f, iY * 6.0f, iX * 6.0f));

                iD.f1 = Vector4(m.m11, m.m21, m.m31, m.m41);
                iD.f2 = Vector4(m.m12, m.m22, m.m32, m.m42);
                iD.f3 = Vector4(m.m13, m.m23, m.m33, m.m43);
                iD.f4 = Vector4(m.m14, m.m24, m.m34, m.m44);

                *pID = iD, pID++;
            }
        }
    }

    g_pVBInstanceData->GetVB()->Unlock();

    return;
}

void RenderInstanced()
{
    Direct3D& D3D = Direct3D::Instance();

    D3D->SetVertexDeclaration(g_pVertexDecl);

    UINT u1 = D3DXGetDeclVertexSize(g_VBDecl_Both, 0);
    UINT u2 = D3DXGetDeclVertexSize(g_VBDecl_Both, 1);

    // Geometry
    D3D->SetStreamSource(0, g_pModel->GetVertexBuffer()->GetVB(), 0, u1);
    D3D->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | g_iNumObj));

    // Data
    D3D->SetStreamSource(1, g_pVBInstanceData->GetVB(), 0, u2);
    D3D->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));

    D3D->SetIndices(g_pModel->GetIndexBuffer()->GetIB());

    Matrix mMat;
    mMat = D3D.GetTransform(D3DTS_VIEW);
    mMat *= D3D.GetTransform(D3DTS_PROJECTION);

    g_pEffect->GetEffect()->SetMatrix( "g_ViewProjectionMatrix", (const D3DXMATRIX*)&mMat );
    g_pEffect->GetEffect()->SetMatrix( "world", (const D3DXMATRIX*)&MatrixIdentity() );

    g_pEffect->SetTexture("ColorMapTexture", (LPDIRECT3DTEXTURE9)g_pModel->GetEffects()[0].apTexture[0]);

    {
        UINT tP;

        g_pEffect->GetEffect()->SetTechnique(g_pEffect->GetEffect()->GetTechniqueByName("HW_Instancing"));
        g_pEffect->GetEffect()->Begin(&tP, 0);
        g_pEffect->GetEffect()->BeginPass(0);

        D3D->DrawIndexedPrimitive(  g_pModel->GetEffects()[0].Header.PrimitiveType, 
                                    0, 
                                    g_pModel->GetEffects()[0].Header.dwMinIndex, 
                                    g_pModel->GetEffects()[0].Header.dwNumVertices, 
                                    g_pModel->GetEffects()[0].Header.dwStartIndex, 
                                    g_pModel->GetEffects()[0].Header.dwNumPrimitives
                                );
        g_pEffect->GetEffect()->EndPass();
        g_pEffect->GetEffect()->End();
    }

    D3D->SetStreamSourceFreq(0, 1);
    D3D->SetStreamSourceFreq(1, 1);
}


Und der Vertexshader sieht so aus:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
TEXTURE     ColorMapTexture;
float4x4    g_ViewProjectionMatrix;
float4x4    world;

sampler colorMap = sampler_state
{
    Texture = <ColorMapTexture>;
    MagFilter = Linear;
    MinFilter = Anisotropic;
    MipFilter = Linear;
    MaxAnisotropy = 16;
};

struct VS_INPUT
{
    float3 position : POSITION;
    float3 normal   : NORMAL;
    float4 tangent  : TANGENT;
    float2 texCoord : TEXCOORD0;

    // Instance data
    float4 f1   : TEXCOORD1;    // 1. row
    float4 f2   : TEXCOORD2;    // 2. row
    float4 f3   : TEXCOORD3;    // 3. row
    float4 f4   : TEXCOORD4;    // 4. row

    float4 f5   : TEXCOORD5;    // color
};

struct VS_OUTPUT
{
    float4 position     : POSITION;
    float2 texCoord     : TEXCOORD0;
    float4 diffuse      : COLOR0;
};

VS_OUTPUT VS_HWInstancing(VS_INPUT input)
{
    VS_OUTPUT Output;

    float4x4 worldMat = float4x4(   
                                    input.f1,
                                    input.f2,
                                    input.f3,
                                    float4(input.f4.xyz, 1.0f)
                                );

    float4x4 o = mul(worldMat, world);

    float4x4 p = mul( o, g_ViewProjectionMatrix );

    Output.position = mul( float4(input.position, 1.0f), p );
    
    Output.texCoord = input.texCoord;
    Output.diffuse = input.f5;

    return Output;
}


Nun zu dem Problem: Aus irgendeinem Grund sind meine Vertices absolut falsch positioniert, nachdem sie durch den Vertexshader gewandert sind. Ich bin mit dem Debugger, sowie mit PIX (siehe Bild) über alle Werte gegangen. Alle sind korrekt. In PIX wird mir auch angezeigt, dass die Vertices-Koordinaten vor dem Vertexshader stimmen und er die richtigen Daten bekommt (f1,f2,f3,f4,f5 : Die Texcoords 1-5). Und dennoch ist nach dem Vertexshader alles durcheinander(siehe 2. Bild).
Ich weiß mir nicht mehr wirklich zu helfen. Ich habe das SDK Sample durchgelesen, GPU Gems 2 durch gelesen, das Netz durchforstet. Ich kann meinen Fehler nicht entdecken. Die Vertices sind natürlich Indiziert. Wenn ich im Vertexshader allerdings

C-/C++-Quelltext

1
2
3
4
5
6
float4x4 worldMat = float4x4(   
                                    1, 0, 0, 0,
                                    0, 1, 0, 0,
                                    0, 0, 1, 0,
                                    0, 0, 0, 1
                                );

statt

C-/C++-Quelltext

1
2
3
4
5
6
float4x4 worldMat = float4x4(   
                                    input.f1,
                                    input.f2,
                                    input.f3,
                                    float4(input.f4.xyz, 1.0f)
                                );

schreibe, dann funktioniert es. Der Würfel wird korrekt auf Position 0,0,0 dargestellt.
Ich wäre euch sehr dankbar, wenn ihr über den Code guckt. ;)

Großes Danke im Voraus.
»FSA« hat folgende Bilder angehängt:
  • PreVS.jpg
  • PostVS.jpg

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

25.05.2013, 00:39

Du baust in deine worldMat als erste Zeile die Farbe ein (TEXCOORD1)... ;)

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

3

25.05.2013, 00:49

Ach verdammt. Vielen Dank dot :)

Lösung:

C-/C++-Quelltext

1
2
3
4
5
struct INSTANCE_DATA
{
    Vector4 f1,f2,f3,f4;
    Color color;
};

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

4

25.05.2013, 01:04

Wie zu erwarten, geht es aber trotzdem nicht so, wie gewünscht :(
Wenn ich zwei Objekte rendern will, wird das erste richtig gerendert. Beim zweiten sieht das ganze aus, wie im Bild 1. PIX zeigt mir für das zweite Modell P12-P23 wieder Müll an.
»FSA« hat folgende Bilder angehängt:
  • Render.jpg
  • PIX.jpg

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

5

25.05.2013, 01:24

Uff es ist schon spät. Ich habe die Matrix falsch gesetzt. Lösung:

C-/C++-Quelltext

1
2
3
4
iD.f1 = Vector4(m.m11, m.m12, m.m13, m.m14);
iD.f2 = Vector4(m.m21, m.m22, m.m23, m.m24);
iD.f3 = Vector4(m.m31, m.m32, m.m33, m.m34);
iD.f4 = Vector4(m.m41, m.m42, m.m43, m.m44);

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

6

25.05.2013, 14:37

Ja, im Zweifelsfall mal transponieren hilft bei so manchem seltsamen Shader-Problem :-)
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.

Werbeanzeige