[HLSL] Font - Pixelshader

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

[HLSL] Font - Pixelshader

Beitrag 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ß
Dateianhänge
Font Rendering
Font Rendering
font.png (4.54 KiB) 3788 mal betrachtet
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

Re: [HLSL] Font - Pixelshader

Beitrag 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?
Benutzeravatar
xq
Establishment
Beiträge: 1589
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [HLSL] Font - Pixelshader

Beitrag 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
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Dateianhänge
fps.jpg
fps.jpg (20.83 KiB) 3662 mal betrachtet
Benutzeravatar
xq
Establishment
Beiträge: 1589
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [HLSL] Font - Pixelshader

Beitrag 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
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Benutzeravatar
xq
Establishment
Beiträge: 1589
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [HLSL] Font - Pixelshader

Beitrag 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
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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?
Dateianhänge
font.jpg
font.jpg (20.54 KiB) 3598 mal betrachtet
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [HLSL] Font - Pixelshader

Beitrag 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.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [HLSL] Font - Pixelshader

Beitrag 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.
Benutzeravatar
xq
Establishment
Beiträge: 1589
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [HLSL] Font - Pixelshader

Beitrag 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, ...)
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Dateianhänge
Arial.gif
Benutzeravatar
xq
Establishment
Beiträge: 1589
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

Re: [HLSL] Font - Pixelshader

Beitrag 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?
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [HLSL] Font - Pixelshader

Beitrag 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 :-)
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: [HLSL] Font - Pixelshader

Beitrag 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ß
Dateianhänge
font.png
font.png (5.32 KiB) 3033 mal betrachtet
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [HLSL] Font - Pixelshader

Beitrag 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.
Antworten