How can I project a normal map onto a wall?

Hey there. I’m looking to project a normal map onto a wall, so that I can move the image of the object (a stereo jack) across multiple surfaces, making it appear that the object is moving beneath the deforming surface.

  • I’ve done a little research with Projectors (from here), but I’m unsure of how to get that shader to work with normal maps, or integrate with the Standard Shader.

  • I’ve also looked into cookies for Spot lights, but these don’t seem to be able to use normal maps.

  • I’ve found a Decal Projector Component, but there doesn’t seem to be any documentation for it.

Can anybody suggest a way to project normal maps onto surfaces? I have a normal map and a mask ready…!

What projector does is, that it renders all the mesh renderers within its frustum with a projector’s material. This material should use a special shader that reads values

float4x4 unity_Projector;
float4x4 unity_ProjectorClip;

to map the textures in a projector-calculated space. See any default projector shader.
Now apparently this projector does not render the material as lit, rendering only the first pass or something. BUT, you could write your own projector using Graphics.DrawMesh which lets you render a mesh by including it in the full pipeline (causing it to be lit, receive shadows, etc)

So what you need is to write a script that:

  1. Determines which mesh renderers to project to (either by querying the scene, or simply by assigning references to the projection target renderer)
  2. Calculating the unity_Projector and unity_ProjectorClip and setting them as global shader values
  3. Use a projector shader that utilizes these, but is a surface shader
  4. Call Graphics.DrawMesh, with your projector material and matrix and mesh from the meshRenderer