Seite 1 von 1

[HLSL] Font - Pixelshader

Verfasst: 09.01.2014, 20:50
von Raven280438
Hi,

ich habe versucht einen PixelShader für meine Font-Engine zu programmieren.
Leider funktioniert er nicht so richtig. Die Font-Texture hat einen Schwarzen Hintergrund, die Zeichen sind Weiß.

Wenn ich Zeichen rendere, wird der schwarze Hintergrund aber trotzdem angezeigt.
Kann mir jemand sagen, was ich falsch mache?

Code: Alles auswählen

Texture2D shaderTexture;
SamplerState SampleType;

float4 PShader(float4 position : SV_POSITION, float4 color : COLOR, float2 tex : TEXCOORD0) : SV_TARGET
{
	float4 texturecolor;

	// Sample the texture pixel at this location.
	texturecolor = shaderTexture.Sample(SampleType, tex);

	// If the color is black on the texture then treat this pixel as transparent.
	if (texturecolor.r == 0.0f)
	{
		texturecolor.a = 0.0f;
	}
	else
	{
		texturecolor.a = 1.0f;
		texturecolor = texturecolor * color;
	}

	return texturecolor;
}
Im Anhang noch ein Bild, wie der Text im Moment gerendert wird


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 09.01.2014, 21:13
von Spiele Programmierer
Hast du eine RGB Textur?
Du hast im Pixelshader einen Gleitkommavergleich. Das ist grundsätzlich keine gute Idee, weil Gleitkommazahlen häufig sich binär unterscheiden wenn sie nahezu den selben Wert enthalten. Informationen darüber gibt es genug im Internet. Gebe besser einen Schwellwert an. Zum Beispiel: "< 0.005"
Außerdem: Hast du Blending überhaupt angeschaltet und richtig konfiguriert?

Re: [HLSL] Font - Pixelshader

Verfasst: 09.01.2014, 21:26
von xq
Schließe mich Spiele Programmierer an.
Dein Vergleich ist gar nicht nötig, du weißt einfach deinem Alpha-Kanal den R-Kanal zu und aktivierst Alpha Blending mit Src=SrcAlpha und Dest=InvertSrcAlpha (oder wie die blend states bei DirectX so heißen).

Grüße

Re: [HLSL] Font - Pixelshader

Verfasst: 10.01.2014, 11:11
von Raven280438
Hi,

ich bin leider noch ziemlicher Anfänger was DirectX und Shader angeht.
Außerdem: Hast du Blending überhaupt angeschaltet und richtig konfiguriert?
Wo/Wie kann ich das machen?


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 10.01.2014, 11:43
von Raven280438
Hi,

ok Kommando zurück, ich hab bei Rastertek nachgelesen wie man das Alpha-Blending an und aus schaltet.
Wenn ich noch Probleme hab, melde ich mich nochmal.


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 12.01.2014, 19:17
von Raven280438
Hi,

ok ich hab das AlphaBlending jetzt eingeschaltet.
Allerdings haben ich um die Buchstaben ein komischen schwarzen Rand drum (Siehe Anhang).

Ich dachte, dass es vielleicht mit dem AntiAliasing zutun hat, aber das hab ich eigendlich abgeschaltet

Code: Alles auswählen

rasterDesc.AntialiasedLineEnable = false;
	rasterDesc.CullMode = D3D11_CULL_BACK;
	rasterDesc.DepthBias = 0;
	rasterDesc.DepthBiasClamp = 0.0f;
	rasterDesc.DepthClipEnable = true;
	rasterDesc.FillMode = D3D11_FILL_SOLID;
	rasterDesc.FrontCounterClockwise = false;
	rasterDesc.MultisampleEnable = false;
	rasterDesc.ScissorEnable = false;
	rasterDesc.SlopeScaledDepthBias = 0.0f;
Mein 2. Gedanke war, dass es an der Font-Bilddatei liegt. Die ist im BMP-Format, und es gibt nur Weiße und Schwarze Pixel, keine Zwischenwerte

Woran kann das sonst noch liegen?


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 12.01.2014, 19:27
von xq
Fonts verwenden normalerweise ein eigenes anti-aliasing
wie sieht denn dein shader grade aus? wenn du den von oben verwendest musst du da ein paar kleine änderungen daran machen

Re: [HLSL] Font - Pixelshader

Verfasst: 12.01.2014, 20:31
von Raven280438
Hi,

das sind im Moment meine Shader für Fonts:

Code: Alles auswählen

cbuffer ShaderInput
{
	float2 ScreenSize;
};

struct VOut
{
	float4 position : SV_POSITION;
	float4 color : COLOR;
	float2 tex : TEXCOORD0;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR, float2 tex : TEXCOORD0)
{
	VOut output;
	output.position = position;

	float FactorWidth = ScreenSize.x / 2;
	float FactorHeight = ScreenSize.y / 2;

	output.position.x = (position.x / FactorWidth) - 1;
	output.position.y = (position.y / FactorHeight) - 1;

	//Da in der GPU oben Rechts (1,1) ist -> vertikal spiegeln
	output.position.y = output.position.y * -1;

	output.color = color;
	output.tex = tex;

	return output;
}

Code: Alles auswählen

Texture2D shaderTexture;
SamplerState SampleType;

float4 PShader(float4 position : SV_POSITION, float4 color : COLOR, float2 tex : TEXCOORD0) : SV_TARGET
{
	float4 texturecolor;

	// Sample the texture pixel at this location.
	texturecolor = shaderTexture.Sample(SampleType, tex);

	// If the color is black on the texture then treat this pixel as transparent.
	if (texturecolor.r < 0.05f)
	{
		texturecolor.a = 0.0f;
	}
	else
	{
		texturecolor = texturecolor * color;
	}

	return texturecolor;
}
Wie kann man denn AntiAliasing mit den Fonts verwenden? Hab mich im Moment an das RasterTek.com Tutorial gehalten.


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 12.01.2014, 21:40
von xq
Das Problem bei dir ist, dass du dein Anti-Aliasing unterdrückst. Deine Quads werden an sich antialiased gerendert, aber die Pixel der Font nicht. Das gute ist aber, dass die Pixel (denke ich) schon antialiased gespeichert sind.

ändere mal deinen Pixel Shader so ab:

Code: Alles auswählen

float4 PShader(float4 position : SV_POSITION, float4 color : COLOR, float2 tex : TEXCOORD0) : SV_TARGET
{
float alpha = shaderTexture.Sample(SampleType, tex).r; // Wir nehmen den Rot-Kanal direkt als Alpha
return float4(1, 1, 1, alpha) * color;
}
So hat die Font deine angegebene Farbe, aber blendet gemäß der Font. Außerdem kannst du so sogar die Font halbtransparent (color.a = 0.5) rendern.

Grüße

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 19:59
von Raven280438
Hi,

so richtig verstanden hab ich den Shader nicht ...

Ich hab ihn mal testweise compiliert, das Ergebnis sieht so wie im Anhang aus.

Was hab ich da falsch gemacht?

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:22
von Niki
Windows BMP ist ein eher bescheidenes Format für Texturen. DDS und PNG sind da besser. Windows BMP hat aber auch gewisse Eigenarten was das Pixel-Format anbelangt (es speichert Kanäle in der Reihenfolge BGR statt RGB). Kannst du mal folgendes ausprobieren?

In MasterQ32's Pixel-Shader mit float Alpha = shaderTexture.Sample(SampleType, tex).r... probier mal am Ende statt dem r ein g oder ein b aus. Wenn's das ist, dann ist was bei der Texture-Erstellung von BMP kaputt.

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:28
von Raven280438
Hi,

folgendes Funktioniert:

Code: Alles auswählen

float alpha = shaderTexture.Sample(SampleType, tex).g;
Ausserdem hab ich die BMP-Datei in eine Gif umgewandelt.

Danke für die Hilfe.



Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:31
von Niki
Dachte ich mir schon. Jetzt möchte ich nur noch sicher stellen, dass du auch mitgekriegt hast, dass der Bug NICHT in MasterQ32's Pixel Shader liegt. Das muss auch mit ".r" funktionieren. Tut es das nicht, dann ist es ein Bug in deinem Texturlader für BMPs. Du solltest also wieder auf ".r" zurückstellen und versuchen den Fehler zu finden. Es muss sowohl mit ".r", mit ".g", und mit ".b" gehen. Erst dann ist es korrekt.

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:32
von xq
Gif ist noch schlimmer als BMP ;)
Es verwendet intern eine Farbtabelle und kann (im Normalfall) nur 256 farben abspeichern.

Was uns helfen würde: Poste doch mal deine Font oder erkläre uns mal, wie die Font aussieht (Schwarz/Weiß, Komplett weiß mit alpha, Farbkodiert, ...)

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:37
von Raven280438
Hi,

im Anhang die Font-Bilddatei für Arial.

Dabei sind die ASCII-Zeichen 0-255 jeweils normal, bold, italic und bold-italic untereinander.
Dazu gibts dann noch ne ini-Datei, wo die jeweilige Zeichen-Breite drinsteht.

Das ganze hab ich mit dem "Bitmap Font Builder" gemacht und dann die Bild-Dateien zu einer Großen zusammengefügt.


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:38
von xq
Fehlerquelle dürfte also ziemlich sicher dein Ladecode sein. Wie erstellst du denn die Textur? Und mit welchem Tool hast du die Bitmap (Gimp, Paint, ...) erstellt?

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:43
von Niki
Vielleicht kennt sich Raven mit den Formaten noch nicht so gut aus. Ich schaue mir grad die Webseite vom Bitmap Font Builder an. Da steht, dass das Programm 32-bit TGA schreiben kann, also ein Format mit echtem Alpha-Kanal. Wenn du das als Grundlage nimmst, dann kann evtl. das DirectX Texture Tool daraus eine DDS Datei erstellen. (oder ein besseres Malprogram eine PNG-Datei, aber DDS ist meist vorzuziehen).

EDIT: Ein Alpha-Kanal ist auch das was dir beim Font anti-aliasing gibt. Allerdings ändert sich damit der Pixel Shader wieder :-)

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:53
von Raven280438
Hi,

man kann beim Bitmap Font Builder die Texture als TGA 32bit exportieren.
Allerdings bekomm ich da nur eine weiße Datei raus.

Deshalb hatte ich dann das BMP-Format gewählt.

Edit:
So wie im Anhang siehts im Moment aus. Ist doch eigendlich recht ordentlich. :)


Gruß

Re: [HLSL] Font - Pixelshader

Verfasst: 13.01.2014, 20:56
von Niki
Raven280438 hat geschrieben:Allerdings bekomm ich da nur eine weiße Datei raus.
Viele einfache Bildviewer oder simpelste Malprogramme zeigen oft nicht den Alphakanal an, sondern nur die RGB-Kanäle, die bei einem solchen Bild komplett weiß sind. Die Graustufen für den ge-anti-aliasten Font sind aber im Alpha-Kanal. Versuch das mal mit GIMP oder Photoshop zu öffnen, und schau dir dann die Kanäle an.