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

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

19.02.2011, 13:58

HLSL Kompilierung hängt sich auf

Hallo aller seits,
ich arbeite der Zeit immer noch an meiner TechDemo, die ich neben bei erwähnt mit zwei Grafikern von GoldenVertices entwickel.
Der echtzeit Schatten sieht schon sehr schön aus mit OpenGL. Im Grunde schreibe ich die Shader immer erst in GLSL und portiere sie dann nach HLSL (Shader Model 3 für DX9.0c und 5 für DX11).
Nun habe ich bei der HLSL Variante des DeferredShading Shaders ein JitterOffset eingebaut, damit der Schatten zu einem Soft-Shadow wird.
Mit GLSL funktioniert alles Einwand frei und er kompiliert sehr schnell. Bei HLSL brauch meine Grafikkarte (GTX 460) schon relativ lange. Und jetzt mit der Erweiterung des HLSL Shaders
hängt sie sich beim Kompilieren des Shaders komplett auf.
Natürlihc blöd, so was zu debuggen. Ich ging erst davon aus, dass es an der Begrenzung der Shader uniforms liegt und hab das JitterOffset von 64 auf 8 Samples runtergesetzt.
Immer noch das gleiche Ergebnis. Dann hab ich die for-Schleife, die alle JitterOffsets durchläuft in eine extra Funktion verbannt, weil ich dachte, dass der ShaderCompiler so lange
brauch, weil er womöglich die for-Schleifen ausrollt - kann ich mir zwar nur schwer vor stellen, hat dann letzt endlich auch nichts geändert.
Fällt euch noch was ein, woran das liegen kann?
Hier ist mein kompletter HLSL shader:

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//
// CASTLE BENCHMARK
// Copyright (c) 2010/2011 Lukas Hermanns
//
// < DeferredShading Direct3D 9.0c shader >
//

#define LIGHT_COUNT             11
#define EPSILON                 0.001
#define JITTER_OFFSETS_COUNT    64

float4x4 WorldViewProjectionMatrix;

sampler2D DiffuseMap;
sampler2D PositionMap;
sampler2D NormalMap;
sampler2D GlossMap;
//sampler2D AmbientMap;
samplerCUBE DepthCube;

float3 ViewPos;                             // Global camera position
float MaterialShininess;

int RealTimeLightIndex;                     // Index number of the light which performs real-time shadow mapping

float3 JitterOffsets[JITTER_OFFSETS_COUNT]; // Jitter offsets for realtime shadow

float4 LightPositions[LIGHT_COUNT];         // Global light positions (world space) and radius in alpha channel
float4 LightColors[LIGHT_COUNT];            // Light colors and shininess factor in alpha channel

struct VertexInput
{
    float3 Position : POSITION;
    float3 TexCoord : TEXCOORD;
};

struct VertexOutput
{
    float4 Position : POSITION;
    float2 TexCoord : TEXCOORD;
};

struct PixelInput
{
    float2 TexCoord : TEXCOORD;
};

struct PixelOutput
{
    float4 Diffuse  : COLOR0;
    float4 Gloss    : COLOR1;
    float Depth     : DEPTH;
};

void LightingCalculation(int i, float3 Position, float3 Normal, float3 GlossColor, inout float3 LightColor, inout float3 SpecularColor)
{
    float3 LightDir = normalize(Position.xyz - LightPositions[i].xyz);
    
    float NdotL     = -dot(Normal, LightDir);
    
    if (NdotL > 0.0)
    {
        // Compute lighting distance, attenuation, intensity etc.
        float Distance      = distance(Position.xyz, LightPositions[i].xyz);
        
        float AttnLinear    = Distance / (LightPositions[i].w*LightPositions[i].w);
        float AttnQuadric   = AttnLinear * Distance;
        
        float Intensity     = 1.0 / (1.0 + AttnLinear + AttnQuadric);
        
        // Combine final lighting- and gloss color
        LightColor += LightColors[i].rgb * (Intensity * NdotL);
        
        if ( LightColors[i].a > EPSILON && ( GlossColor.r > EPSILON || GlossColor.g > EPSILON || GlossColor.b > EPSILON ) )
        {
            float3 ViewDir          = Position - ViewPos;
            float3 LightHalfeVector = normalize(LightDir + ViewDir);
            float NdotHV            = -dot(Normal, LightHalfeVector);
            
            if (NdotHV > 0.0)
                SpecularColor += LightColors[i].rgb * GlossColor * (Intensity * pow(abs(NdotHV), MaterialShininess) * LightColors[i].a);
        }
    }
}

int GetJitterOffsetSamples(int i, float3 Position)
{
    int Samples = 0;
    float3 Offset;
    
    float PixelLightDistanceVS = distance(LightPositions[i].xyz, Position);
    float PixelLightDistanceLS;
    
    // Get the samples using the jitter offset array
    for (int j = 0; j < JITTER_OFFSETS_COUNT; ++j)
    {
        Offset = JitterOffsets[j] * (PixelLightDistanceVS * 0.01);
        
        PixelLightDistanceLS = texCUBE(DepthCube, normalize(Position - LightPositions[i].xyz + Offset)).r;
        
        if (PixelLightDistanceVS < PixelLightDistanceLS + 0.1)
            ++Samples;
    }
    
    return Samples;
}

VertexOutput VertexMain(VertexInput Input)
{
    VertexOutput Output = (VertexOutput)0;
    
    Output.Position     = mul(float4(Input.Position, 1.0), WorldViewProjectionMatrix);
    Output.TexCoord     = Input.TexCoord.xy;
    
    return Output;
}

PixelOutput PixelMain(PixelInput Input)
{
    PixelOutput Output = (PixelOutput)0;
    
    // Get texture colors/ vectors
    float3 DiffuseColor = tex2D(DiffuseMap, Input.TexCoord).rgb;
    float4 Position     = tex2D(PositionMap, Input.TexCoord);
    float3 Normal       = normalize(tex2D(NormalMap, Input.TexCoord).xyz);
    float4 GlossColor   = tex2D(GlossMap, Input.TexCoord);
    //float3 AmbientColor   = tex2D(AmbientMap, Input.TexCoord).rgb;
    
    // Process lighting calculations
    float3 LightColor       = 0.0;
    float3 SpecularColor    = 0.0;
    
    if (GlossColor.a < EPSILON)
    {
        for (int i = 0; i < LIGHT_COUNT; ++i)
        {
            if (i == RealTimeLightIndex)
            {
                int Samples = GetJitterOffsetSamples(i, Position.xyz);
                
                if (Samples > 0)
                {
                    float Factor = (float)Samples / JITTER_OFFSETS_COUNT;
                    
                    float3 TempLightColor       = 0.0;
                    float3 TempSpecularColor    = 0.0;
                    
                    LightingCalculation(i, Position.xyz, Normal, GlossColor.rgb, TempLightColor, TempSpecularColor);
                    
                    LightColor      += TempLightColor       * Factor;
                    SpecularColor   += TempSpecularColor    * Factor;
                }
                else
                    continue;
            }
            else
                LightingCalculation(i, Position.xyz, Normal, GlossColor.rgb, LightColor, SpecularColor);
        }
    }
    else
        SpecularColor   = GlossColor.rgb * GlossColor.a;
    
    // Set final pixel colors
    Output.Diffuse.rgb  = DiffuseColor * LightColor/*(*AmbientColor)*/ + SpecularColor;
    Output.Diffuse.a    = 1.0;
    
    Output.Gloss.rgb    = SpecularColor;
    Output.Gloss.a      = 1.0;
    
    Output.Depth        = Position.w;
    
    return Output;
}

2

19.02.2011, 14:09

Wie testest du denn?
Verwendest du DX Composer, Render Monkey oder ähnliches?
fka tm

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

19.02.2011, 14:15

Ich teste gar nicht, ich versuche das einfach mit meiner Engine zu kompilieren. Geht ja auch bei allen anderen Shadern. Das Problem liegt anscheinend einfach irgendwie am Shader.
Ich verwende ShaderModel 3 ("vs_3" und "ps_3") und kompiliere mit der Funktion "D3DXCompileShader". Und bei dieser Funktion hängt sich das Programm auf.

Beiträge: 721

Wohnort: /dev/null

Beruf: Software-Entwickler/Nerd

  • Private Nachricht senden

4

19.02.2011, 14:23

Hast du mal zum Testen die komplette For-Schleife ausgebaut?

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

5

19.02.2011, 14:31

Jo hab's grad ma gestet. Der scheint sich nicht auf zu hängen, sondern der brauch einfach eine halbe Ewigkeit. Wenn ich das Array JitterOffset von 64 auf 2 revidiere, dauert dass schon 6 Sekunden. Wenn ich nur 8 Nehme dauert das schon locker ne Minute schätze ich.
Irgendwie kommt der mit den Scheifen nicht zurecht :( aber egal welche, hab's jetzt schon mit for, while und do-while Schleifen probiert. Immer das selbe Problem.

6

19.02.2011, 14:41

Hast du nach dem Kompilieren 'ppErrorMsgs' mal geprüft?
fka tm

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

7

19.02.2011, 14:46

Der bleibt in der Funktion "D3DXCompileShader" hängen. Der brauch einfach sau lange. Wenn ich das etwas reduziere (die Anzahl Durchläufe pro Schleife) und ewig warte, meldet der auch keine Fehler.
Kann man nicht irgendwie per Macro Optimierungs Einstellungen vornehmne, damit der nicht maximal optimiert. Wär ja nicht das erste Mal, dass solche Probleme wegen Optimierungsversuchen entstehen.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

8

19.02.2011, 15:04

Also ich hab jetzt erst ma ne übergangslösung gefunden, aber die ist auch nicht gerade das Gelbe vom Ei.
Wenn ich schreib das Attribute [loop] vor die for-Schleife schreibe, wird der mim Kompilieren in halbwegs akzeptabler Zeit fertig. Aber es ruckelt wie Mist, und das obwohl gerade mal 64 float3 Variablen zum Shader hochgepumpt werden.
OpenGL hat damit ja auch keine Probleme. Wenn ich das Attribute [fastopt] nehme, dauert es eig. schon wieder zu lange mit dem Kompilieren, zwar nicht so ewig wie vorher aber immer noch lange. Wenigstens rockelt es dann nicht so sehr, aber die Performance ist bei OpenGL bei weitem besser.
Wie gesagt, die optimal Lösung kann dann jawohl noch nicht sein :(

Werbeanzeige