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

BlackSnake

Community-Fossil

  • »BlackSnake« ist der Autor dieses Themas

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

1

09.08.2007, 19:00

HLSL: Schatten

naben,

ich habe da mal eine frage zu den schatten. ich probiere schon etwas länger schatten hinzubekommen. bis jetzt nur einfache schlagschatten, was für den anfang ja reicht (vom verständniss her) ;) .
ich fange an die szene in eine depthmap zu rendern. dazu berechne ich ja die matrix für das licht. die licht art ist bei mir eine art spotlicht:

C-/C++-Quelltext

1
2
3
4
5
    // Calculate lightviewmatrix

    mLightview = tbMatrixCamera(tbVector3(10.0f, 10.0f, 0.0f), tbVector3(0.0f));

    // Calculate lightviewprojection

    mLightAll = mWorld * mLightview * mProjection;

so sieht meine berechnung der matrizen aus. mWorld ist hier die objekt matrix und mProjection die standard projectionsmatrix.

der shader für das rendern in die texture sieht wie folgt 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
//------------------------------------------------

// VARIABLES

//------------------------------------------------

float4x4                matrix_4x4_WorldLightviewProjection;

//------------------------------------------------

// SAMPLER

//------------------------------------------------


//------------------------------------------------

// STRUCTURES

//------------------------------------------------


// Application to vertexshader

struct a2v
{
    float4 Position:POSITION;
};

// Vertexshader to pixelshader

struct v2p
{
    float4 Position:POSITION;
    float  Depth:TEXCOORD0;
};

// pixleshader to application

struct p2a
{
    float4 Color:TEXCOORD0;
};

//------------------------------------------------

// HELPER FUNCTIONS

//------------------------------------------------


//------------------------------------------------

// VERTEXSHADER

//------------------------------------------------


void VS_CalculateDepthMap(in a2v IN, out v2p OUT)
{
    OUT.Position = mul(IN.Position, matrix_4x4_WorldLightviewProjection);
    OUT.Depth    = OUT.Position.z;
};

//------------------------------------------------

// PIXELSHADER

//------------------------------------------------


void PS_CalculateDepthMap(in v2p IN, out p2a OUT)
{
    OUT.Color = float4(IN.Depth, IN.Depth, IN.Depth, 1.0f);
};

//------------------------------------------------

// TECHNIQUES

//------------------------------------------------

Technique CalculateDepthMap
{
    Pass P1
    {
        Cullmode = CCW;
        
        VertexShader = compile vs_1_1 VS_CalculateDepthMap();
        PixelShader  = compile ps_1_1 PS_CalculateDepthMap();
   }
}

die einzige globale variable ist die matrix aus der sicht des lichtes. die übergebe ich natürlich ;)

jetzt habe ich ja das tiefenbild in der texture. jetzt kann ich ja anfangen mithilfe der texture das objekt zu rendern. wie gesagt probiere ich schlagschatten zu verwenden, dazu kommt diffuse beleuchtung.

der shader sieht so aus: (ein wenig länger)

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
//------------------------------------------------

// VARIABLES

//------------------------------------------------


float4x4        matrix_4x4_World;
float4x4        matrix_4x4_WorldViewProjection;
float4x4                matrix_4x4_WorldLightviewProjection;

float3          vector_3_DirToLight;

float4          vector_4_LightDiffuse;
float4          vector_4_LightAmbient;
float4          vector_4_MaterialDiffuse;
float4          vector_4_MaterialAmbient;

texture         texture_DepthMap;
texture         texture_Surface;

//------------------------------------------------


float4          vector_4_TexCoords;

//------------------------------------------------

// SAMPLER

//------------------------------------------------


sampler ShadowSampler = sampler_state
{
    texture = (texture_DepthMap);
    MIPFILTER = Anisotropic;
    MINFILTER = Anisotropic;
    MAGFILTER = Anisotropic;
  ADDRESSU  = Clamp;
  ADDRESSV  = Clamp;
};

sampler SurfaceSampler = sampler_state
{
    texture = (texture_Surface);
      MIPFILTER = Anisotropic;
      MINFILTER = Anisotropic;
      MAGFILTER = Anisotropic;
};

//------------------------------------------------

// STRUCTURES

//------------------------------------------------


// Application to vertexshader

struct a2v
{
    float4 Position:POSITION;
    float3 Normal:NORMAL;
    float4 Tex:TEXCOORD0;
};

// Vertexshader to pixelshader

struct v2p
{
      float4 Position:POSITION;
      float2 Tex:TEXCOORD0;
    float2 STex:TEXCOORD1;
    float2 DTex:TEXCOORD2;
    float3 Normal:TEXCOORD3;
};

// pixleshader to application

struct p2a
{
      float4 Color:COLOR0;
};

//------------------------------------------------

// HELPER FUNCTIONS

//------------------------------------------------


float4 CalculateDiffuseColor(float3 _normal, float3 _dirToLight)
{
    // Variables

    float4 color;
    float4 diffuse;
    
    diffuse = saturate(dot(_normal, _dirToLight));
    color   = (vector_4_LightAmbient * vector_4_MaterialAmbient) + (diffuse * vector_4_MaterialDiffuse);
    
    return color;
}

//------------------------------------------------

// VERTEXSHADER

//------------------------------------------------


void VS_ShadowMapping(in a2v IN, out v2p OUT, uniform bool _texturized)
{
    OUT.Position        = mul(IN.Position, matrix_4x4_WorldViewProjection);
    OUT.Normal          = mul(IN.Normal, (float3x3)matrix_4x4_World);
    vector_4_TexCoords  = mul(IN.Position, matrix_4x4_WorldLightviewProjection);
    OUT.STex.x          = 0.5f * vector_4_TexCoords.x + 0.5f;
    OUT.STex.y          = 0.5f - 0.5f * vector_4_TexCoords.y;
    OUT.DTex.y          = vector_4_TexCoords.z - 0.015f;
    OUT.DTex.x          = saturate(dot(OUT.Normal, vector_3_DirToLight));
    
    if(_texturized)
        OUT.Tex        = IN.Tex;
    else
        OUT.Tex        = 0;
}

//------------------------------------------------

// PIXELSHADER

//------------------------------------------------


void PS_ShadowMapping(in v2p IN, out p2a OUT, uniform bool _texturized)
{
    // Variables

    float a;
    float4 diffuse;
    
    diffuse = CalculateDiffuseColor(normalize(IN.Normal), normalize(vector_3_DirToLight));
    a = step(0.0f, tex2D(ShadowSampler, IN.STex).z - IN.DTex.y);
    
    if(_texturized)
        OUT.Color = a * tex2D(SurfaceSampler, IN.Tex) * diffuse;
    else
        OUT.Color = a * diffuse;
}

//------------------------------------------------

// TECHNIQUES

//------------------------------------------------

Technique ShadowMappingWithTextures
{
    Pass P1
    {
        Cullmode = CCW;
        
        VertexShader = compile vs_1_1 VS_ShadowMapping(true);
        PixelShader  = compile ps_2_0 PS_ShadowMapping(true);
   }
}

Technique ShadowMappingWithoutTextures
{
    Pass P1
    {
        Cullmode = CCW;
        
        VertexShader = compile vs_1_1 VS_ShadowMapping(false);
        PixelShader  = compile ps_2_0 PS_ShadowMapping(false);
   }
}

Technique ShadowMappingWithWireframe
{
    Pass P1
    {
    Fillmode = Wireframe;
        Cullmode = None;
        
        VertexShader = compile vs_1_1 VS_ShadowMapping(false);
        PixelShader  = compile ps_2_0 PS_ShadowMapping(false);
   }
}

es klappt alles, bisauf das mit den schatten. sobald ich im pixelshader, die variable "a" mit in die multiplikation mit hinzunehmen, wird alles null(schwarz).

mein erstes lösungsansatz wäre eine orthogonale projektionsmatrix zu benutzen, aber wenn ich das mache, ist nichts in der depth map. wenn ich es aber mit der normel machen, sehe ich praktisch einen screenshot von dem modell aus der sicht des lichtes. das ganze in schwarz weiß. also kein stufiges bild wie es eigentlich sein sollte...

kann mir da evtl jemand helfen?
danke für jegliche hilfe...

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

2

10.08.2007, 14:22

Dein Projective Texturemapping stimmt nicht und damit die Texturkoordinaten für die Depthmap nicht. Bzw.... du hast kein Projective Texturemapping ^^

Dazu brauchst du erstmal eine sog. (glaub ich jedenfalls) Biasmatrix. Die erstellst du dir so:

C-/C++-Quelltext

1
2
3
4
5
float fTexOffs = 0.5f + (0.5f / (float)m_iShadowMapSize);
m_matTexAdj = gve::Matrix(0.5f,     0.0f,     0.0f, 0.0f,
                      0.0f,    -0.5f,     0.0f, 0.0f,
                      0.0f,     0.0f,     1.0f, 0.0f,
                      fTexOffs, fTexOffs, 0.0f, 1.0f);


Diese multiplizierst du dann mit der Lichtmatrix uns setzt sie im Shader... also zb so:

C-/C++-Quelltext

1
2
m_matShadowMapProj = m_matLightViewProj * m_matTexAdj;
m_pShader->SetMatrix("matShadowMapProjection", m_matShadowMapProj);


Im Vertexshader muliplizierst du die untransformierte Position mit dieser Matrix und schiebst den Vector (mit 3 Komponenten!) dann als Texturkoordianten zum Pixelshader rüber.
Im Pixelshader nutzt du dann für deine Depthmap Tex.xy / Tex.z (Tex soll das sein was du vorhin in Vertexshader ausgerechnet hast). Das muss leider so sein ... ehrlichgesagt keine Ahnung warum.. wenn du es im Vertexshader bereits dividierst gehts nicht.
... Hab heut nen guten Tag, daher zeig ich dir meinen Shader. Der ist jedoch für einen zusätzlichen Pass gedacht und malt auch nur den Schatten auf Mattscheibe.

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
struct VSOUTPUT_Shadow
{
   float4 vPos      : POSITION;
   float3 vTexCoord   : TEXCOORD0;
   float  fDepth      : TEXCOORD1;
};

VSOUTPUT_Shadow VS_Shadow(float4 Position : POSITION)
{
   VSOUTPUT_Shadow Out;

   Out.vPos = mul(Position, matWorldViewProjection);                // Echte Position

   float4 shadowPos = mul(Position, matWorldViewProjection_Light);
   Out.fDepth = shadowPos.z - fShadowBias;                          // Tiefe zum Licht

   Out.vTexCoord = mul(Position, matShadowMapProjection).xyw;       // Texturkoordinaten berechnen

   
   return Out;
}

float4 PS_Shadow(float3 vTexCoord   : TEXCOORD0,
             float  fDepth          : TEXCOORD1) : COLOR0
{  
   float fDepthFromLight = tex2D(sampShadowMap, vTexCoord.xy / vTexCoord.z).r;  
   return (fDepth < fDepthFromLight);
};


Ach und noch 2 allgemeine Tipps:
- Pixel- und Vertexshaderversion immer gleich machen, weils sonst zu Problemem kommen könnten (laut DX Doku)
- Die If Anweisungen lieber sein lassen und dafür 2 Shader schreiben ... if zieht mehr an der Rechenleistung des GPUs als man glauben will