[D3D10] Problem mit Shadow Mapping

Anfänger92

Erfahrenes Mitglied
Hallo,

mal wieder ein Problem im Bereich 3D-Grafik.

Also ich render die Scene einmal in eine Textur mit dem Format Float32.
Das Funktioniert auch noch alles ganz gut die Textur wird richtig erstellt.

Mein Problem entsteht anscheinend beim projezieren der Textur in das Kamera-Koordinaten system.

So sieht der Teil des Shaders aus ums den geht:
C++:
struct a2v_Shaded {
	float4 Pos			: POSITION;
	float2 TexCoord		: TEXCOORD0;
	float2 DetailCoord	: TEXCOORD1;
};

struct v2p_Shaded {
	float4	Pos				: SV_POSITION;
	float2	TexCoord		: TEXCOORD0;
	float2	DetailCoord		: TEXCOORD1;
	float4	ShadowTexCoord	: TEXCOORD2;
	float	fDepth			: COLOR;
};

void VS_Shaded( in a2v_Shaded IN, out v2p_Shaded OUT) {
	OUT.Pos = mul(IN.Pos,mWorldViewProj);
	OUT.TexCoord = IN.TexCoord;
	OUT.DetailCoord = IN.DetailCoord;
	
	OUT.fDepth = mul(IN.Pos,mLightViewProj).z;
	OUT.ShadowTexCoord = mul(IN.Pos,mLightViewProj);
}

float4 PS_Shaded( in v2p_Shaded IN): SV_Target
{
	float2 ProjectedTexCoords;
    ProjectedTexCoords[0] = IN.ShadowTexCoord.x/IN.ShadowTexCoord.w/2.0f + 0.5f;
    ProjectedTexCoords[1] = -IN.ShadowTexCoord.y/IN.ShadowTexCoord.w/2.0f + 0.5f;
	
	float fA = IN.fDepth;
	float fB = ShadowTex.Sample(linearSampler,ProjectedTexCoords).r;
	
	if( (fA-0.1f) < fB)
		return ComputeColor(IN);
	else
		return float4(0.1f,0.1f,0.1f,1.0f);
		
}

Weiß vll jemand was falsch ist? Leider findet man dazu nicht sehr viel im Internet.

Im Anhang nochmal das Ergebnis des ganzen.
 

Anhänge

  • Shadow.JPG
    Shadow.JPG
    73,1 KB · Aufrufe: 80
Zuletzt bearbeitet von einem Moderator:
Hallo,

der Shader sieht soweit ganz ok aus. Bist du dir sicher, dass die Shadowmap auch richtig generiert wird? Vielleicht magst du auch den entsprechenden Shader noch hier reinstellen.

Grüße, Matthias

P.S.: In DirectX 10 kann man die Semantiken größtenteils frei benennen, du kannst also z.B. statt COLOR auch DEPTH schreiben.
 
Also hier nohcmal der komplette Shader.

C++:
matrix mWorldViewProj;
matrix mLightViewProj;

Texture2D ColorDef;
Texture2D Layer1;
Texture2D Layer2;
Texture2D Layer3;
Texture2D Layer4;

Texture2D ShadowTex;

SamplerState linearSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};
/*************************************************************
Colored,Shaded Terrain
*************************************************************/

struct a2v_Shaded {
	float4 Pos			: POSITION;
	float2 TexCoord		: TEXCOORD0;
	float2 DetailCoord	: TEXCOORD1;
};

struct v2p_Shaded {
	float4	Pos				: SV_POSITION;
	float2	TexCoord		: TEXCOORD0;
	float2	DetailCoord		: TEXCOORD1;
	float4	ShadowTexCoord	: TEXCOORD2;
	float	fDepth			: DEPTH;
};

void VS_Shaded( in a2v_Shaded IN, out v2p_Shaded OUT) {
	OUT.Pos = mul(IN.Pos,mWorldViewProj);
	OUT.TexCoord = IN.TexCoord;
	OUT.DetailCoord = IN.DetailCoord;
	
	OUT.fDepth = mul(IN.Pos,mLightViewProj).z;
	OUT.ShadowTexCoord = mul(IN.Pos,mLightViewProj);
}

float4 ComputeColor( in v2p_Shaded IN)
{
	float4 ColorAlpha = ColorDef.Sample(linearSampler,IN.TexCoord);
	float4 Color1 = Layer1.Sample(linearSampler,IN.DetailCoord);
	float4 Color2 = Layer2.Sample(linearSampler,IN.DetailCoord);
	float4 Color3 = Layer3.Sample(linearSampler,IN.DetailCoord);
	float4 Color4 = Layer4.Sample(linearSampler,IN.DetailCoord);

	return (Color1 * ColorAlpha.r) + (Color2 * ColorAlpha.g) + (Color3 * ColorAlpha.b) + (Color4 * ColorAlpha.a);
}

float4 PS_Shaded( in v2p_Shaded IN): SV_Target
{
	float2 ProjectedTexCoords;
    ProjectedTexCoords[0] = IN.ShadowTexCoord.x/IN.ShadowTexCoord.w/2.0f + 0.5f;
    ProjectedTexCoords[1] = -IN.ShadowTexCoord.y/IN.ShadowTexCoord.w/2.0f + 0.5f;
	
	float fA = IN.fDepth;
	float fB = ShadowTex.Sample(linearSampler,ProjectedTexCoords).r;
	
	if( (fA-0.1f) < fB)
		return ComputeColor(IN);
	else
		return float4(0.1f,0.1f,0.1f,1.0f);
		
}

technique10 Shaded
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Shaded() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Shaded() ) );
    }
}

/*************************************************************
Shadow
*************************************************************/
struct a2v_Shadow {
	float4 Pos			: POSITION;
	float2 TexCoord		: TEXCOORD0;
	float2 DetailCoord	: TEXCOORD1;
};

struct v2p_Shadow {
	float4 Pos			: SV_POSITION;
	float  fDepth		: COLOR;
};

void VS_Shadow( in a2v_Shadow IN, out v2p_Shadow OUT) {
	float4 Pos = mul(IN.Pos,mLightViewProj);
	OUT.Pos = Pos;
	OUT.fDepth = Pos.z;
}

float4 PS_Shadow( in v2p_Shadow IN): SV_Target
{
	return float4(IN.fDepth,IN.fDepth,IN.fDepth,1.0f);
}

technique10 Shadow
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Shadow() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Shadow() ) );
    }
}

Mir ist noch was aufgefallen:

Muss ich die Tiefe nicht berechnen, indem ich die Position mit der WorldViewProjection multipliziere?

Immoment multipliziere ich mit der LightViewProj.

Das komische ist, egal mit welcher Matrix ich mutlipliziere, die Ausgabe sieht immer gleich aus.

Aber ja, es sind verschiedene Matrizen, habe das ganze getestet.

Gruß
Anfänger
 
Zuletzt bearbeitet von einem Moderator:
Also hier nohcmal der komplette Shader.
Sieht eigentlich auf den ersten Blick auch ganz gut aus. Es ist nur etwas ungewöhnlich, mit dem homogenen z-Wert zu rechnen. Normalerweise übergibt man hier Pos.zw an den Pixelshader und berechnet dort dann Pos.z/Pos.w, um einen Wert in [0, 1] zu erhalten. Beim Erstellen der Shadowmap könntest du auch einfach deine Textur als Depth-Stencil binden, dann landen dort automatisch genau diese Werte. Der Vorteil hiervor ist, dass du dann DepthBias, SlopeScaledDepthBias und DepthBiasClamp verwenden kannst (einstellbar im RasterizerState).

Muss ich die Tiefe nicht berechnen, indem ich die Position mit der WorldViewProjection multipliziere?

Immoment multipliziere ich mit der LightViewProj.
Nein, das stimmt schon so. Du willst ja den Abstand zur Lichtquelle herausfinden, nicht zur Kamera.

Grüße, Matthias
 
Ok,

war leider die Woche nicht da, jetzt gehts aber weiter.
Das Problem hat sich immernoch nicht gelöst.

Hab jetzt mal die Tiefe mit z / w berechnet.

Nun ist fast alles Schwarz, nur manche Stellen sind noch hell.

Auch interessant finde ich, das sich die Schatierten Flächen ändern, wenn man die Kamera bewegt, die Position der Lichtquelle wird aber nicht geändert.

Vll. könnte ich das Projekt auch mal jemanden schicken der Ahnung von Shadow-Mapping hat? Vll hab ich ja auch woanders nen Fehler.

Was mich auch noch interesiert:
C++:
float2 ProjectedTexCoords;
ProjectedTexCoords[0] = IN.ShadowTexCoord.x/IN.ShadowTexCoord.w/2.0f + 0.5f;
ProjectedTexCoords[1] = -IN.ShadowTexCoord.y/IN.ShadowTexCoord.w/2.0f + 0.5f;

Ich muss ja die Texturcoordinaten noch transformieren. ABer Warum?
Beim schreiben in die Textur mache ich das ja auch nihct. Muss ich das dort auchnoch machen?

Außerdem ist das die Tranformatrion für DX 9.
Bei DX liegt das Raster aber zwischen -1 und 1 und nicht zwischen 0 und 1.
Ich habe mi gedacht das man statt + 0.5f einfach -0.5f schreiben muss oder?
Gruß
Anfänger
 
Zuletzt bearbeitet von einem Moderator:
OK

Habs jetzt geschafft.

Am Code im Programm hab ich nichts geändert.
Hier der Shader der Funktioniert:

C++:
matrix mWorldViewProj;
matrix mLightViewProj;

Texture2D ColorDef;
Texture2D Layer1;
Texture2D Layer2;
Texture2D Layer3;
Texture2D Layer4;

Texture2D ShadowTex;

float		fShadMapSize = 512.0f;

SamplerState linearSampler
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

shared RasterizerState noCullRS
{
    CullMode = None;
    FillMode = Solid;
    MultisampleEnable = false;
};
/*************************************************************
Colored,Shaded Terrain
*************************************************************/

struct a2v_Shaded {
	float4 Pos			: POSITION;
	float2 TexCoord		: TEXCOORD0;
	float2 DetailCoord	: TEXCOORD1;
};

struct v2p_Shaded {
	float4	Pos				: SV_POSITION;
	float2	TexCoord		: TEXCOORD0;
	float2	DetailCoord		: TEXCOORD1;
	float4	lightViewPos	: LIGHT;
};

void VS_Shaded( in a2v_Shaded IN, out v2p_Shaded OUT) {
	float4 Pos = IN.Pos;
	OUT.Pos = mul(Pos,mWorldViewProj);
	OUT.TexCoord = IN.TexCoord;
	OUT.DetailCoord = IN.DetailCoord;
	OUT.lightViewPos = mul(Pos,mLightViewProj);
}

float4 ComputeColor( in v2p_Shaded IN)
{
	float4 ColorAlpha = ColorDef.Sample(linearSampler,IN.TexCoord);
	float4 Color1 = Layer1.Sample(linearSampler,IN.DetailCoord);
	float4 Color2 = Layer2.Sample(linearSampler,IN.DetailCoord);
	float4 Color3 = Layer3.Sample(linearSampler,IN.DetailCoord);
	float4 Color4 = Layer4.Sample(linearSampler,IN.DetailCoord);

	return (Color1 * ColorAlpha.r) + (Color2 * ColorAlpha.g) + (Color3 * ColorAlpha.b) + (Color4 * ColorAlpha.a);
}

float4 PS_Shaded( in v2p_Shaded IN): SV_Target
{
	float4 lightViewPos = IN.lightViewPos;
    lightViewPos.xy /= lightViewPos.w;
    float2 tex = lightViewPos.xy * float2( 0.5f, -0.5f ) + 0.5f;
	
	float fA = lightViewPos.z/lightViewPos.w;
	
	float fShad = 0.0f;
	for(int x=-1;x<2;x++)
		for(int y=-1;y<2;y++)
		{
			fB = ShadowTex.Sample(linearSampler,tex.xy + float2(x/fShadMapSize,y/fShadMapSize)).r;
			if( ((fA-0.0001) <= fB))
				fShad += 1.0f;
		}
				
	fShad /= 9.0f;
	
	return ComputeColor(IN) * fShad;
}

technique10 Shaded
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Shaded() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Shaded() ) );
        
        SetRasterizerState( noCullRS );
    }
}

/*************************************************************
Shadow
*************************************************************/
struct a2v_Shadow {
	float4 Pos			: POSITION;
	float2 TexCoord		: TEXCOORD0;
	float2 DetailCoord	: TEXCOORD1;
};

struct v2p_Shadow {
	float4 Pos			: SV_POSITION;
	float4 Light		: LIGHT;
};

void VS_Shadow( in a2v_Shadow IN, out v2p_Shadow OUT) {
	OUT.Pos = mul(IN.Pos,mLightViewProj);
	OUT.Light = mul(IN.Pos,mLightViewProj);
}

float4 PS_Shadow( in v2p_Shadow IN): SV_Target
{
	float fDepth = IN.Light.z/IN.Light.w;
	return float4(fDepth,fDepth,fDepth,1.0f);
}

technique10 Shadow
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, VS_Shadow() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, PS_Shadow() ) );
        
        SetRasterizerState( noCullRS );
    }
}

Hier ein paar Sachen von denen ich glaube das sie den Fehler verursacht haben:

1. Ich habe mehrfach auf eine Variable der Eingabe-Daten zugegriffen, was nicht geht.
2. Ich habe beim rendern der Shadow-Map das Backface-Culling nicht abgeschaltet.

Danke für die Hilfe.
Gruß
Anfänger
 
Zuletzt bearbeitet von einem Moderator:
Zurück