Rendering Perspective Text

Started by
2 comments, last by Wyrframe 8 years, 11 months ago

I have a spritebatch class, and a number of classes that use it, in order to render textures and text to the screen.

I also have a billboard rendering class. It renders sprites in a 3d world.

It turns out, I need a combination of these two classes' abilities; I need to render 2d text in a 3d world.

I am not going to create new "label" classes in order to use the billboard renderer; that's just stupid.

Applying matrix transformations to my text before sending them to the spritebatch is also cumbersome. (For some reason too, the images-text rendered this way is fixed to pixel coordinates, resulting in a weird "wobble" effect when they (or the camera) move around in the world).

So, the way I see it, I have two choices:

1) Render my labels and whatnot thourgh the spritebatch class to a renderTarget (not the screen), and then use the billboard renderer to render the final result in the 3d world.

2) Re-write my spritebatch class to actualy use internaly the billboard renderer, and thus give me the option to render my labels etc... any way i want.

Any suggestions? The first option is the easiest to code, and I have seen many people suggest that approach. I can't help but find it extremely inefficient (this changing back between renderTarget and backbuffer should have quite an effect on performance).

Advertisement

Not sure if you want them rotated and perspective correct - but if you want them as billboard labels - maybe something like this:

[source]

Matrix inv = Matrix.CreateScale(1,-1,1);
basicEffect.World = inv;
basicEffect.View = Matrix.Identity;
basicEffect.Projection = projection;

spriteBatch.Begin(0, null, null, DepthStencilState.DepthRead, RasterizerState.CullNone, basicEffect);
i=0;
do {
Vector3 position = billboard.pos;
Vector3 viewingSpacePos = Vector3.Transform(position, view * inv);
Vector2 origin = spriteFont.MeasureString(billboard.text) / 2;
const float size = 0.4f;
// last parameter is Z coord:
spriteBatch.DrawString(spriteFont, billboard.text, new Vector2(viewingSpacePos.X, viewingSpacePos.Y), Color.White, 0, origin, size, 0, viewingSpacePos.Z);
i++;
}while(i<num_billboards);
spriteBatch.End();

[/source]

Also may want to adjust pixel offset by half pixel in projection: projection = projection * Matrix.CreateTranslation(-0.5f, -0.5f, 0);

Thanks, but I'm using my own custom classes.

I guess my question is a bit on the abstract, more relating to architecture than anything else.

Spritebatch draws quads, to screen space.

BillboardRenderer draws quads to world coordinates, depending on camera frustum.

I just wonder if there is a elegant way to combine the two, to have perspective text.

Why not transform just the "anchor" point of the text (usually the bottom-center of a line, or the top-left of the leftmost character, or something) to get a screen-space position for the text, and then draw your glyph-sprites relative to that position using Spritebatch. Round to the nearest pixel after calculating the screen-space position to reduce aliasing effects.

Unless you need your text to have size and rotation appropriate for billboarded objects in-world? Then create a billboard transformation matrix appropriate to the anchor of your text, and then just lay out your glyphs within that single billboard model space.

I'm not sure what you're asking for with "perspective text", nor why you think it's too much work to transform individual glyphs before passing them to Spritebatch. It sounds like a necessary step to get any individual sprites into the scene.

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

This topic is closed to new replies.

Advertisement