0
\$\begingroup\$

I have a large number of items in my game, that will eventually have a texture associated with them. The problem is, for right now, I have nothing. I would really like to do something with, say, the first 2 letters of the object's name. As my main system will be pure textures, I really don't want to add a text object to the texture, I would really like to just create a texture with the object's first two letters.

Is there a way I can create a texture, realtime, with font rendered on that texture? Preferably without a camera/ render texture, unless I can create them once. I really want to create a unique default texture for each item at runtime, preferably with some kind of font. Can I do this?

\$\endgroup\$
2
\$\begingroup\$

EDIT

You could find too many approaches for solve your texturing problem, below I’ll share to you two of my favorites solutions based on some prototypes I’ve been working this week.

SCRIPT FOR CHANGE MATERIAL TEXTURES

This is relative easy and straightforward solution; the idea is to create as many textures as needed and then use a script for assign/change those textures in your materials. For further reading in this approach you could start browsing in google:

Unity script change texture; Material.SetTexture

CREATE YOUR CUSTOM FONT BITMAP READER USING SHADERS

Although this approach could not be as easy as the last is truly generating a “dynamic texture” using a different render target in a secondary camera and drawing the generated render texture to a plane that is viewing the primary camera. The steps for implement this approach are described below.

Bold fonts are keywords for search in google (e.g. Unity render target)

1. Create your bitmap font

You could create your own bitmap font in software like photoshop.

Example of custom bitmap font texture

The previous image has a width and height equal to 512px, so every letter is into an area box of (512/3)**2.

You also must assign an index for each word in the bitmap (e.g: A has index 0, B has index 1, and so on…).

2. Setup your Scene

Setup your scene

In the image, you can see how the space being renderer for the BufferCamera is projected as texture into the Plane (that is viewing the Main Camera) If you want more than one word in your texture Plane is necessary to create another BufferCamera and another BufferPlane and project its content to the same Plane, then you must create a custom shader that receives the two rendered textures as minimum and play with the scale and offset values.

Bold fonts are gameobjects in the current scene

3. Create your bitmap font reader shader

The BufferPlane shader is the shader that read from your bitmap font, below I’ll paste for you a first functional prototype I built for that shader while experimenting on your problem last night.

This is probably the hardest part of this solution proposal, the idea here is to draw only parts of your bitmap font texture (those parts associated with and index letter).

Shader "Custom/FontbitmapReader" {
Properties {
    _MainTex ("Albedo (RGB)", 2D) = "white" {}
    _Index ("Text index for draw", Range(0, 8)) = 0.0
}
SubShader {
    Tags { 
        "RenderType"="Opaque" 
    }
    LOD 200

    CGPROGRAM
    #pragma surface surf FontBitMap

    // Use shader model 3.0 target, to get nicer looking lighting
    #pragma target 3.0

    #pragma debug


    sampler2D _MainTex;

    struct Input {
        float2 uv_MainTex;
    };

    int _Index;

    float4 LightingFontBitMap(SurfaceOutput s, float3 lightDir, float atten)
    {
        return float4(s.Albedo, 1.0) * s.Alpha;
    }

    void surf (Input IN, inout SurfaceOutput o)
    {
        /*
            G = 0   H = 1   I = 2
            D = 3   E = 4   F = 5
            A = 6   B = 7   C = 8
        */

        float i = _Index;
        float4 texel = 0;
        float2 uv = IN.uv_MainTex;

        // 1.0 / 3.0 = 0.3
        float uvScale = 1.0 / 3.0;
        float2 uvOffset = float2(fmod(i, 3.0) / 3.0,
                                floor(i / 3.0) / 3.0); 
        float2 transformedUV = IN.uv_MainTex * uvScale + uvOffset;
        texel = tex2D(_MainTex, transformedUV);

        o.Albedo = texel.rgb;
        o.Alpha = texel.a;
    }
    ENDCG
}
FallBack "Diffuse" 
}

4. Create a script for modyfing your shader material

This script must input two things:

  1. The material to which you attached your custom shader
  2. The letters you want to draw

You could use a switch to associate each typed letter with a bitmap font index and then pass that index to your shader material.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.