1
\$\begingroup\$

It might be a trivial question, but I couldn't come up with a simple solution. I need to create a cube like on the image below in Unity.

enter image description here

As always, I target mobile so it would be nice if it was made on a mobile/diffuse shader.

I was playing with lights a little bit, but in order to achieve this kind of look, I'd need to stack multiple lights because one shadow is not enough. Also, I tried adjusting the angles of the lighting - with no luck.

Do you have any tips, how could I make one in a most efficient way?

\$\endgroup\$
  • \$\begingroup\$ Can you cheat with a texture? As in, just make a texture that's yellow on top and dark on the sides? \$\endgroup\$ – MichaelHouse Jun 27 '17 at 21:19
  • \$\begingroup\$ Yep! As long as it stays mobile/diffuse :) \$\endgroup\$ – Jacob Jun 27 '17 at 21:21
  • \$\begingroup\$ Be more specific, ONLY a face pointing TOP should have a color? All others faces are going to be black? Or are we talking about blending these colors, accordingly to the normal of that said face? \$\endgroup\$ – Guilherme Junqueira Coutinho Jun 27 '17 at 23:34
3
\$\begingroup\$

I will be giving you two answers, The one for your actuall problem,and another one with a cube that has faces colored based on how much they are facing top:


To simply create a Cube like that:

  • Create an image, and color it like the left half should be COLOR_X and the other half, COLOR_Y, save it; (paint will do it)
  • create a cube inside blender, and go to UV/Unwrapp;
  • place the face you want to be COLOR_X in the left, the others in the right;
  • Export to Unity;
  • Inside Unity create a simple Unlit/Texture Material;
  • Set the image you created as the Texture;
  • Apply the material to the UV/mapped cube;

Faces should have a color depending of the normal angle;

    Shader "Unlit/NormalColored"
    {
        Properties
        {
            _NormalColor ("Color facing TOP", Color) = (1,.5,0,1)
        }
        SubShader
        {
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                // include file that contains UnityObjectToWorldNormal helper function
                #include "UnityCG.cginc"

                struct v2f {
                    // we'll output world space normal as one of regular ("texcoord") interpolators
                    half3 worldNormal : TEXCOORD0;
                    float4 pos : SV_POSITION;
                };

                // vertex shader: takes object space normal as input too
                v2f vert (float4 vertex : POSITION, float3 normal : NORMAL)
                {
                    v2f o;
                    o.pos = UnityObjectToClipPos(vertex);
                    // UnityCG.cginc file contains function to transform
                    // normal from object to world space, use that
                    o.worldNormal = UnityObjectToWorldNormal(normal);
                    return o;
                }

                float4 _NormalColor;
                float _ShadeColor;

                fixed4 frag (v2f i) : SV_Target
                {
                    // The Y component is TOP direction
                    float normal_y = (i.worldNormal).y/2 + .5;
                    float normal_y_2 = (i.worldNormal).y;
                    return (normal_y_2 * _NormalColor);
                }
                ENDCG
            }
        }
    }
  • only a face pointing EXACTLY TOP should be colored, change the Frag function to this;

    fixed4 frag (v2f i) : SV_Target
                {
                    // The Y component is TOP direction
                    float normal_y = (i.worldNormal).y/2 + .5;
                    if (normal_y >= .999) // THIS VALUE CAN BE SET AS A PROPERTY SO U CAN PLAY AROUND WITH IT
                        return _NormalColor;
                    return 0;
                }
    
\$\endgroup\$
  • \$\begingroup\$ I assume you know how to create a shader and then a material from this shader? If not, create one shader inside unity, then double click it, copy paste my code, then apply it to a material. It will be under Unlit/NormalColored \$\endgroup\$ – Guilherme Junqueira Coutinho Jun 28 '17 at 0:04
  • \$\begingroup\$ Btw, unlit shaders are the most performatic shaders... If this is not what you wanted, be more specific, but upvote my answer because it actually does what u described. \$\endgroup\$ – Guilherme Junqueira Coutinho Jun 28 '17 at 0:05
  • \$\begingroup\$ Yeah, this is what I want, but I need to color 5 other faces with a different one so top is color X and 5 other are color Y. \$\endgroup\$ – Jacob Jun 28 '17 at 13:47
  • \$\begingroup\$ Which frag function are you using? The "EXACTLY TOP should be colored,"? \$\endgroup\$ – Guilherme Junqueira Coutinho Jun 28 '17 at 14:03
  • \$\begingroup\$ The first one, with angles \$\endgroup\$ – Jacob Jun 28 '17 at 14:07

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.