3
\$\begingroup\$

I want different textures for the outside and inside of a box (cube).
The image below shows what I want to achieve. It is kind of an open box, where we can see a different texture inside:

goal

I was trying to solve it by checking whether the normal of the face is point towards the view or to inside the screen, that is we are seeing the "back" of the face.

I was also looking into cube mapping, but it does not seem to be the way.

What method should I use to achieve that result?

\$\endgroup\$
  • 3
    \$\begingroup\$ Have you considered using the SV_IsFrontFace semantic to make this determination? \$\endgroup\$ – DMGregory Nov 2 '20 at 12:58
  • 1
    \$\begingroup\$ Thanks, @DMGregory! Your suggestion helped me a lot. I just have a question about it. If you check my answer below you will see that I had to use the wood colour when is front face and rock when is not. Why? It seems to be inverted. \$\endgroup\$ – mfloriani Nov 2 '20 at 13:29
2
\$\begingroup\$

Following @DMGregory suggestion, I set the pixel shader as:

float4 PS(PS_INPUT input, bool isFrontFace : SV_IsFrontFace) : SV_Target
{
    float4 color = 0;

    if(isFrontFace)
        color = texWood.Sample(samLinear, input.Tex);
    else
        color = texRock.Sample(samLinear, input.Tex);

    return color * vMeshColor;
}

Then I got the intended result:

result

But there is one thing that I am not understanding. It seems that SV_IsFrontFac is giving me the inverted value of what I would expect from it. By looking to my PS code you will notice that I had to set the wood colour when isFrontFace is true and rock colour when is false. I already checked if the textures are assigned properly to the Texture2D variable.

\$\endgroup\$
  • 2
    \$\begingroup\$ Sounds like your triangle winding might be opposite what you expect? \$\endgroup\$ – DMGregory Nov 2 '20 at 13:28
  • \$\begingroup\$ Probably it is something related to that. I will check, thanks! \$\endgroup\$ – mfloriani Nov 2 '20 at 13:45
0
\$\begingroup\$

You can only put materials on one side of any given object unless you are using shaders which specifically render backfaces. Because of backface culling being one of the simplest and fastest graphics optimizations, it is always assumed that you will be viewing meshes from one side only!

For what you want to do here, I would have two cubes- one with the normals pointing out, and one with the normals pointing in. You'll have to use some external application to make the 'inside-out' one, because Unity does not normally provide that kind (Blender/Maya).

You could always build a texture shader and use Cull Off/Cull Front/Cull Back to achieve the same result nonetheless.

 Shader "Show Insides" {
   SubShader {
   
     Tags { "RenderType" = "Opaque" }
   
     Cull Front
   
     CGPROGRAM
   
     #pragma surface surf Lambert vertex:vert
   
     void vert(inout appdata_full v)
     {
         v.normal.xyz = v.normal * -1;
     }
   
     struct Input {
         float4 color : COLOR;
     };
   
     void surf (Input IN, inout SurfaceOutput o) {
         o.Albedo = 1;
     }
   
     ENDCG
   
   }
 
   Fallback "Diffuse"
}


 
\$\endgroup\$
  • 4
    \$\begingroup\$ It looks like you've written a Unity-style surface shader here, but it sounds like this user is building their own DirectX app that does not use Unity. \$\endgroup\$ – DMGregory Nov 2 '20 at 13:29
  • \$\begingroup\$ Thanks, @WRECKER_1! \$\endgroup\$ – mfloriani Nov 2 '20 at 13:46
  • \$\begingroup\$ You’re right @DMGregory I apologize for the incorrect interpretation. Unity is all I can think of in so it was naive of me not to check the tags. \$\endgroup\$ – WRECKER_1 Nov 3 '20 at 2:41

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.