Search Unity

Take sample offset in the screen coordinates.

Discussion in 'Shaders' started by WereVarg, Mar 5, 2017.

  1. WereVarg

    WereVarg

    Joined:
    Apr 9, 2012
    Posts:
    20
    I have a shader which drops shadow and does a bevel for the quad with alpha texture. The problem is that shadow is rotating with the object.

    Code (CSharp):
    1.  
    2. ...
    3. _ShadowColor("Shadow Color", Color) = (0,0,0,0.5)
    4. _ShadowX("Shadow X Offset", Range(-32,32)) = 4
    5. _ShadowY("Shadow Y Offset", Range(-32,32)) = 4
    6. ...
    7. float4 sampleColor(float2 coord)
    8.     {
    9.         return tex2D(_MainTex, coord);
    10.     }
    11. ...
    12. float2 shadowOffset = _MainTex_TexelSize.xy * float2(_ShadowX, -_ShadowY);
    13.  
    14. float shadowSample = sampleColor(IN.texcoord - shadowOffset).a / 5 + sampleColor(IN.texcoord - shadowOffset*1.3).a / 5 + sampleColor(IN.texcoord - shadowOffset*1.5).a / 5 + sampleColor(IN.texcoord - shadowOffset*1.7).a / 5 + sampleColor(IN.texcoord - shadowOffset * 2).a / 5;
    15. ...      
    16.  
    Is there a way to get sample with the offset in pixels relative to the screen in the screen coordinates?
    I will try to multiply Offset on the "inverse" object transformation matrix for now.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
  3. WereVarg

    WereVarg

    Joined:
    Apr 9, 2012
    Posts:
    20
    Shadows are faked - I just set the offset in pixels. No lights in the scene.
    To make my question more short - I just want my "float4 sampleColor" to get some input parameter and offset in "world" pixels" and return the color which was there. What input parameters can I use? What will be inside that function?
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    I put "light direction" in quotes for a reason, your shadow offset is, in effect, a light direction. Tangent space is the technical term for "local UV direction", most commonly used with normal maps and lighting, but you're still asking for the same thing here where you want an on-screen pixel offset converted into a local UV position, and for that you need the starting UV position (which you have as the texcoord) plus an offset in UV space. When the polygon surface and screens space align then these are essentially the same thing, but when you rotate they don't match and you get what you're seeing, hence needing to convert from world / screen space into local UV space, aka tangent space.
     
    WereVarg likes this.
  5. WereVarg

    WereVarg

    Joined:
    Apr 9, 2012
    Posts:
    20
    Ye it turned out to be easier than i thought especially cause i have 1 unit = 1 pixel; Thank you for taking care of the shaders' subforum.
    Code (CSharp):
    1. float4 sampleColor(v2f IN, float2 offset)
    2.     {
    3.         IN.texcoord -= mul(unity_WorldToObject, offset);
    4.         return tex2D(_MainTex, IN.texcoord);
    5.     }