Search Unity

Surface Shader that simulates a larger HD TV screen

Discussion in 'Shaders' started by Ben-BearFish, Jan 15, 2016.

  1. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    I'm attempting to create a simulation of a scene with multiple 55" TV monitors. One of the requirements I've received is that like a TV monitor in real life, depending on the camera's viewing angle to the TV screen's surface, the video on the TV screen should appear darker or lighter (contrast degradation).

    I was wondering has anyone written a shader that is similar to what I'm attempting to do? And if not, how would I go about doing this with Unity's Surface Shaders in Unity 5?

    Here's a visual article of what I'm attempting to recreate in Unity:
    http://lcdtvbuyingguide.com/hdtv/view-angle.html
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    If all you care about is the display getting darker and loosing saturation when off axis, that's fairly simple. Look up how to do a fresnel and just use that value to darken and desaturated the image you want displayed.

    If you care to go further and get different effects depending on which axis you're off from (side to side or above to below) that's a bit more involved, but still possible. Many displays may change color along one axis, and only fade a bit in brightness in another, and some might completely invert the color but only off of one direction and look most fine in the others.
     
  3. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @bgolus I'll look up the fresnel shader, but the thing I'm more concerned about is how am I able to tell what angle the camera is from the object in the shader to change the saturation values?

    Or does it make sense to do the camera/object calculations in Unity and send those values to the shader?
     
  4. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    That part is very easy and also needed for fresnel. It's actually the cosine of the angle between the camera vector and the normal vector. (Calculated with a dot product.) The nice thing is that it is then per pixel instead of per object. Which is more exact.
     
  5. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @jvo3dc I'd assume from your answer that this would be calculated within the shader itself? Thanks.
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    @Ben BearFish It's an important distinction to note that you do not want the camera to object angle, you want the surface normal to camera position angle, which is exactly what fresnel is (or rather, as @jvo3dc notes is the cosine of the angle). Also, all of the data needed to do either are already available to shaders which is why I wanted you to look into fresnel shaders.
     
    Last edited: Jan 18, 2016
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    Another technique that uses a similar calculation as fresnel is rim lighting. Really the part people are interested in is the dot(viewDir, normal) part of the calculation, real fresnel is a more complex calculation that starts with that, and real world rim lighting is completely different, but that initial dot product is often a close enough approximation. The existing Unity samples have a rim lighting shader you can look at.

    http://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html

    Instead of using the dot product to add a glow, you would use it as the inout to a lerp between the tv's image and a dark grey.
     
  8. jvo3dc

    jvo3dc

    Joined:
    Oct 11, 2013
    Posts:
    1,520
    And then to know that the complete fresnel equation is based on complex numbers for the ior. The one you commonly see doesn't include the extinction value k. (Which is mainly required for metals.)

    Here it is in real full form:
    fresnel.png
     
    Last edited: Jan 19, 2016