Do materials the way ID does it!

A neat idea, which could help from some rendering performance aspects. Who wants to use a separate material for each separate model part, especially when you’ve got flesh, cloth, metal, and glass all on the same model? I mean, when you’re doing diffuse only, it sure ain’t make sense to make a material for each.

So, I was searching the web in search [ omg a new concept, searching ] of how to generate some mesh tangents that won’t make my lighting look like it’s coming from the wrong direction - and I came across this page: Link.

More importantly, I saw this picture: Link.

Then I thought, hey, Unity can do that! So I spent about five minutes writing the following code.

Now, the code definitely will not work ‘out of the box,’ but it does work somewhat - it has been tested in chunks - and it is a pretty cool idea. I’m not exactly using it, but here it is. The idea is here. Not sure if this has been posted before, but what the heck.

// Returns one of the HitType enumerations, which is created by you.
public HitType GetHitEffect ( RaycastHit in_hitInfo )
{
   // This works with no null reference exceptions because of short circuiting
   if (( in_hitInfo.collider != null )( in_hitInfo.collider.gameObject != null )( in_hitInfo.collider.gameObject.renderer != null ))
   {
      if ( in_hitInfo.collider.gameObject.renderer.material != null )
      {
         // Obviously, the following line requires a sort of custom shader
         Texture2D t_hit_texture = (Texture2D)( in_hitInfo.collider.gameObject.renderer.material.GetTexture( "_HitMat" ) );
         if ( t_hit_texture != null )
         {
            Color hit_color = t_hit_texture.GetPixel(  in_hitInfo.textureCoord.x * t_hit_texture.width, in_hitInfo.textureCoord.y * t_hit_texture.height );
            // Another function created by you
            return GetHitTypeFromColor( hit_color );
         }
      }
   }
   return HitType.Generic;
}

private HitType GetHitTypeFromColor ( Color in_color )
{
   // Since Color is a struct, this is totally safe
   switch ( in_color )
   {
      case (new IntegerColor( 255, 255, 255, 255 )):
         return HitType.Glass;
      default:
         return HitType.Generic;
   }
}

// This just converts a Color (basically a struct of floats) into a comparable version
private IntegerColor ToIntegerColor ( Color in_color )
{
   return new IntegerColor( (int)(in_color.r * 255), (int)(in_color.g * 255), (int)(in_color.b * 255), (int)(in_color.a * 255));
}

public struct IntegerColor
{
    public int r, g, b, a;
    public IntegerColor( int c1, int c2, int c3, int c4 ) 
    {
        r = c1;
        g = c2;
        b = c3;
        a = c4;
    }
}

Now, to find some way to generate those tangents…

Nothing I can do to help with creating this. But just wanted to say that does sound like a very cool idea that could benefit, well… everyone!

hmm it sounds very cool and useful, but i dont understand the connection between the mesh and the colliders. the hit takes place on the colliders, right? but a collider is untextured. so how can the hit see what color is on the meshes texture? or am i completely misunderstanding this?

@woodn: the collider detects the hit and tells you where on the model the hit occurred – in this case, the code is getting the location of the hit in texture coordinates, which it can then use to find out the colour of the texture at that pixel location.

@oblivionfeet: nice idea – and you can avoid the hassle of needing a custom shader by simply attaching the hit material map (texture) to the script itself.

That would be a huge boost to its usefulness when adding it into a project that hadn’t previously been made with it fully in mind. No having to change shaders, and since the script would only execute on a per trigger/hit basis, little to no effect on speed either I would imagine?

The more I look at this thread, the more I could totally love this method lol.

It could be used, besides hit effects, but also choosing the decal types, the sounds, sounds given when walking on certain materials even too?

Wow, this is so simple and ingenious. I might just use this in my current project.

Better yet, by associating the texture-map with the script, you could have multiple scripts using the same mechanic to map all kinds of attributes using different textures.

Doesn’t that mean the collider has to be the same geometry than the model around it? or is there another way of finding out the texture-coordinates on a “close -to-the-collider-mesh”?

Your hit map can simply be to the geometry of the collider instead of the model.

This is exactly how I used to do collision testing on the Amiga back in the day lol. I would have an objects future position checked for pixel color ID not the color itself but the color ID. I would make it any color I wanted after mapping them out as IDs.

This is a great way to do it.