Lots of texture combination for character creation/evolution

So, I’m working on a game were you create your own beast.
When you train this beast, the texture is supposed to change to reflect the change in stats.
There are four stats, so there’s four different looks to mix between.

My first approach was to offer the artists only three different textures, and that the mix was binary. This made it 8 texture combination for each beast, and I’d just cycle between them.

The artists then went mad. They don’t want that, they want more!

So, as the change in stat does not happen often, I figured maybe it’s possible to have the different textures on the iPhone, and then actually have the game read it in, and do the blending and save it to a texture (“currentBlend.alpha”).

My worries are texture bandwidth, but having only alpha here, would make it only 8 bit (so a doubling of 4 bit of the compressed texture)

The iPhone supports two texture multitexturing, and the other channel is for tattoos.

So my question to you, is this. Have anyone of you tried something similar? Would it be hopeless to expect that this would even work?

What should I be looking at in order to actually code this system? I guess maybe some integratioin of objective c/c++ to produce the currentBlend.alpha image is needed.

would a combiner of alpha + color and decal on a skinned mesh * 2 (beasts fight each other), be too much strain on the system?

Aaah, damn artists and game designers, they never opt for the easy way of doing things :stuck_out_tongue:

Hope anyone has some tips or opinions.

:slight_smile:

This is very possible (I’m using the same approach), with GetPixels / SetPixels methods.

They are cpu hungry, though. But if it’s made on load time, wouldn’t be that much of a burden.

What kind of quality did you use for the textures?
Not being compressed (I figure that PVRTC compression on the iPhone is pretty much out of the question), they can take up quite a bit of bandwith.

We were thinking of going for alpha textures, but RGB gives much more variation and possibilities.

Another thing is implementation… Since you seem to have done this, could you point me in the direction for where I would read more about integrating this pure opengl code with unity?

I have experience with opengl, so I wouldn’t have problems understanding that nor C code, but I have never attempted to extend the unity iPhone functionality , so I’m not sure where to start looking.

hope you can help. Great to know someone’s done something similar. :slight_smile:

Sure, glad to help :wink:

Quality is a simple 16-bit RGB, as PVRTC is not supported in Texture Atlases (I found they are vital for texture skinning, as it saves a lot of drawcalls). For Texture Atlasing, see Texture2D.PackTexture() method.

If you want to use alpha, like adding a tatoo on a body, you’ll have to use RGBA. It is the most hungry resource, but well, this is alpha after all.

Finally, I tested with 2 chars onscreen (41 bones each, but with mesh combining), a HUD, and a 1440 x 900 fragmented background. All the textures are packed into 4 entities (HUD, chars, and background).

On a 3G, I hit ~20 fps. 40 on 3GS. But I didn’t roam through the deep optimization process yet.
Also, the Profiler is telling that the most consuming resource are animations (2 x 2000 frames with baked IKs) and Skinning (~700 polys chars), so if you’re not a bone fanatic like me, you should have some good performance overall, even on 3G.

And as the 1.1 unity iPhone is coming with a big skinning performance gain, you can expect even higher FPS if you’re on a fighting game too.

For the implementation, I didn’t use OpenGL code at all. Everything is made with native Unity methods, during loading screen. But I’ll check later if OpenGL implementation can be faster.

For unity methods, you could just check the Texture2D class, it gots plenty of useful manipulation methods :slight_smile:

Good luck !

here is an example of a simple (and inefficient way) of doing to on the fly texture maniuplation. THis just does a simple multiply type blend operation

/*
 *
 * Created by raleigh rinehart on 8/07/09.
 * Copyright 2009 Pixel Nation Games. All rights reserved.
 *
 */

using UnityEngine;
using System.Collections;

public class ImageBlend : MonoBehaviour {


    public enum BlendMode {Multiply};

    public static Texture2D BlendTex(Texture2D pTexA, Texture2D pTexB, BlendMode pBlendMode)
    {
        int _width = pTexA.width;
        int _height = pTexA.height;
        Texture2D _resultTex = new Texture2D(_width, _height);
        //Texture2D _tempA = (Texture2D)MonoBehaviour.Instantiate(pTexA, Vector3.zero, Quaternion.identity);
        //Texture2D _tempB = (Texture2D)MonoBehaviour.Instantiate(pTexB, Vector3.zero, Quaternion.identity);

        switch(pBlendMode)
        {
            case (BlendMode.Multiply):
                Color c1 = new Color(); 
                Color c2 = new Color(); 
                float red, green, blue, alpha;
                
                for (int x = 0; x < _width; ++x)
                    for (int y = 0; y < _height; ++y)
                    {
                        c1 = pTexA.GetPixel(x, y); 
                        c2 = pTexB.GetPixel(x, y); 
                       
                       /* adjust the mix of the channels seperatly for different effects
                        //red
                        red = Mathf.Clamp(c1.r * c2.r, 0f, 255f); 
                        //green
                        green = Mathf.Clamp(c1.g * c2.g, 0f, 255f); 
                        //blue
                        blue = Mathf.Clamp(c1.b * c2.b, 0f, 255f); 
                        //alpha 
                        alpha = Mathf.Clamp(c1.a * c2.a, 0f, 255f); 
                        */
                        _resultTex.SetPixel(x,y, c1*c2); 
                    }
                _resultTex.Apply(); 
            break;
            default:
                Debug.Log("not implemented");
            break;

        }

       return _resultTex;
    }
}