Search Unity

Radial Directional Light With Shadows

Discussion in 'Shaders' started by KoryHeath, May 24, 2017.

  1. KoryHeath

    KoryHeath

    Joined:
    Aug 10, 2015
    Posts:
    4
    I'm working on a simple game in which the player is inside a tube which stretches away down the z axis. The camera is always at x,y (0, 0). It faces and moves forward (positive z), and can rotate around the z axis. There are various simple objects affixed to the walls of the tube (cubes, pyramids, circular arcs, etc.) that the player needs to avoid. These objects are often moving and / or changing size and shape in real time, and they are created on the fly procedurally as you proceed down the tube (and are destroyed after you pass them).

    I currently have a spotlight affixed to the camera at a fixed distance down the tube which points directly at the camera, in order to light the walls of the tube, and more importantly, to cast real time shadows stretching toward the player. It looks pretty cool, but there are things about it I don't like. There's an obvious ring of light some ways down the tube where the edge of the spotlight starts (which I don't like), and obviously all the objects further than that down the tube don't cast shadows (which I definitely don't like). I'm also not crazy about the way that the shadows elongate as objects move closer to the camera (i.e. as the camera and spotlight move down the tube). I've tried versions with multiple spotlights (both moving and fixed), but I didn't like the results. I've tried versions with point lights and/or directional lights, but so far the single spotlight solution is my favorite.

    What I'd really like (I think) is what I would call a radial directional light - a kind of cross between a directional light and a spotlight. Imagine that there's an infinite line at x,y (0, 0) stretching along the z axis, and at every point along this line, it shoots out a radial ring of rays towards the wall of the tube, at some definable angle (0 would shoot rays directly at the tube, 90 would be equivalent to a directional light pointing straight at the camera, somewhere in between would cause shadows to stretch some distance out in front of all objects all around the tube.) Or a different way of looking at it: every point on the surface of the tube or object has a ray of light shining on it (unless blocked) that has its origin at x, y (0, 0) and its z somewhere further down the tube.

    I've started tinkering with a custom shader to see if I can get this effect, but I haven't gotten very far. As a test, I have a simple vertex/fragment shader that uses SHADOW_COORDS(1), TRANSFER_SHADOW, and SHADOW_ATTENUATION that works as expected with a single directional light, and I've tried messing around with the values that TRANSFER_SHADOW sets (i.e. the values of _ShadowCoord), but I don't have a clear enough understanding of how the shadow depth texture works to know if I'm on the right track, or if what I want to do is even possible.

    Is what I'm trying to do possible? What's the best way to go about it?
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    It's possible, but you would have to do all the shadow map rendering manually, there's nothing built in to Unity that would work the way you want. That means you can't rely on Unity's built in lights, or shaders, or most of the shader macros for shaders, it'll all have to be done from scratch. It also requires you use some rather unorthodox projection matrices for the shadow map rendering, which might lead to some complications for you as well.

    The lighting itself isn't too hard to do, really you'd just need to pass the xy position of the mesh vertices to the fragment shader, normalize that 2D vector. You can rotate that by adding some value to Z and normalizing the resulting 3D vector.

    But shadows are much harder. Here's a link on how Unity does it's directional shadows for kind of an example on what you'd need to do:
    http://catlikecoding.com/unity/tutorials/rendering/part-7/
     
  3. KoryHeath

    KoryHeath

    Joined:
    Aug 10, 2015
    Posts:
    4
    Thanks for the reply. This is the same conclusion I've come to myself. (And the page you linked to is the the one I had been using to figure all of this stuff out!)