Search Unity

Shadow receiver offset

Discussion in 'Shaders' started by cowtrix, Jul 27, 2015.

  1. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Hey guys. So basically, I have an FPS viewmodel that is required to stay at the origin due to floating point limitations in the skinning. We draw this viewmodel with Depth Only as the clear mode. We rotate it with the world camera, so directional light is respected, however this viewmodel does not receive shadows or pixel lights.

    Is there any way to say in a shader, "light me as if I was at this position in the world", even when the actual mesh isn't?
     
  2. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Bump? Any ideas anyone?
     
  3. Jonny-Roy

    Jonny-Roy

    Joined:
    May 29, 2013
    Posts:
    666
    So the camera stays still and you move the whole world lights and all? Camera only rotates with player turning.

    No reason you shouldn't get shadows working like this.
     
  4. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Hey Jonny. No, we have a world camera that moves around, and a viewmodel camera that is rendered after the world camera, that stays at the origin due to floating-point precision errors.
     
  5. Jonny-Roy

    Jonny-Roy

    Joined:
    May 29, 2013
    Posts:
    666
    So your problem is probably related to the way shadows work, they generally use the primary camera I think as a reference to render the shadows, your best bet for debugging would be to duplicate the scene get rid of one camera and then test, then try again the other way round.
     
  6. Plutoman

    Plutoman

    Joined:
    May 24, 2013
    Posts:
    257
    A solution that I can think of is to use a command buffer to copy the shadow-buffer from the main camera, into a render texture, and then a second command buffer to copy that render texture into the second camera's shadow buffer.

    However, I'm not quite sure on pixel lights.

    I'm really not entirely sure of the context you are doing this in, though - the view model does 'what' exactly? Is it rendering geometry? GUI? What? Is it rendering the first-person 'gun/object' models, then, that you want to receive pixel lights + shadows?

    If the latter, then you could use a custom shader where you take the MVP matrix from the first camera, and calculate world position through it, light the source, but output the pixel position in reference to the viewmodel camera's MVP matrix. This assumes forward rendering. If deferred, there is no way I can see besides doing a render texture with the gun model at the correct position, and merging it back in.. but there'd be no reason to do that, anyways. You might be able to get away with rendering only the view-model camera in forward (which is basically allowing calculations of the light source per object, instead of per pixel, which is why it happens in the shader - and thus you control how it is lit).

    What floating point issues do you have? You shouldn't get floating point issues for quite a while, and if it's a larger world, then you might need to look into alternatives.
     
  7. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    I'm not super concerned with shadows. I realised I should have really called my post something else - more like "Lighting receiver offset". If the viewmodel could appropriately receive some spherical harmonics, I'd be more than happy with that solution.

    Hey Plutoman - yes, that's pretty much exactly the scenario. It renders a gun/item the player is carrying. You described something pretty close to what I was thinking, but I haven't been able to find any shader code that shows how it could be done. The second camera will always render in forward (thanks for the bugginess with multiple cameras, Unity!) so this solution should be viable. Any idea what it might look like?

    The floating point issues are to do with our animation rig and skinning - visual artifacts and bone drift start visibly appearing once you're over 2000m from the origin. Other solutions (e.g. shifting the whole world) aren't viable as this is a multiplayer game.
     
    Last edited: Aug 11, 2015
  8. cowtrix

    cowtrix

    Joined:
    Oct 23, 2012
    Posts:
    322
    Just bumping this thread as I never arrived at a good solution to this. Anyone have any ideas?