Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Transparency based on view direction.

Discussion in 'Shaders' started by CapLonelyFlaw, Feb 7, 2015.

  1. CapLonelyFlaw

    CapLonelyFlaw

    Joined:
    Nov 27, 2013
    Posts:
    2
    Hi, I am start to learn shaders. And I have some issue, with writing some interesting effect.
    I want shader that change transparent area according to the view direction. Like at the image but white - transparent. According to view direction, means, transparent area always be where face normal directed towards to view.

    I wrote custom lighting model. But I can`t figure out how access face normal at surf function and then change Alpha. It is possible?
    View direction stored at Input struct. Where face normal?

    Code (CSharp):
    1.         inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten)
    2.         {
    3.             float2 difLight = dot (s.Normal, viewDir);
    4.             float3 ramp = tex2D(_RampTex, difLight).rgb;
    5.            
    6.             float4 col;
    7.             col.rgb = s.Albedo * _LightColor0.rgb * (ramp);
    8.             col.a = s.Alpha;
    9.             return col;
    10.         }
    11.        
    12.          void surf (Input IN, inout SurfaceOutput o)  
    13.          {    
    14.              float4 c;    
    15.              c =  pow((_EmissiveColor + _AmbientColor), _MySliderValue);
    16.              o.Albedo = c.rgb;    
    17.              o.Alpha = c.a;  
    18.          }
     

    Attached Files:

  2. CapLonelyFlaw

    CapLonelyFlaw

    Joined:
    Nov 27, 2013
    Posts:
    2
    Issue solved. With vertex/fragment shader.

    Code (CSharp):
    1. Shader "Custom/Atmosphere" {
    2.     Properties {
    3.         _RampTex ("Base (RGB)", 2D) = "white" {}  
    4.         _AmbientColor  ("Ambient Color", Color) = (1,1,1,1)  
    5.     }
    6.    
    7.     Category {
    8.     Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
    9.     Blend One OneMinusSrcAlpha
    10.  
    11.    
    12.         SubShader {
    13.             Pass {
    14.            
    15.                 CGPROGRAM
    16.                
    17.                 #pragma vertex vert
    18.                 #pragma fragment frag
    19.                 #include "UnityCG.cginc"
    20.                
    21.                 sampler2D _RampTex;
    22.                 float4 _AmbientColor;  
    23.                
    24.                 struct v2f
    25.                 {
    26.                      float4 pos : SV_POSITION;
    27.                      fixed4 color : COLOR;
    28.                      float3 normal : TEXCOORD0; //you don't need these semantics except for XBox360
    29.                      float3 viewT : TEXCOORD1; //you don't need these semantics except for XBox360
    30.                   };
    31.        
    32.                  v2f vert (appdata_base v)
    33.                  {
    34.                      v2f o;
    35.                      o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    36.                      o.normal = normalize(v.normal);
    37.                      o.viewT = normalize(ObjSpaceViewDir(v.vertex));
    38.  
    39.                      return o;
    40.                  }
    41.  
    42.                  fixed4 frag(v2f i) : COLOR0
    43.                  {
    44.                      float difLight = dot(i.normal, i.viewT);
    45.                     float4 ramp = tex2D(_RampTex, difLight);
    46.                    
    47.                     ramp.rgb = ramp.a * _AmbientColor.rgb;
    48.                     return ramp;
    49.                 }
    50.                
    51.                 ENDCG
    52.             }
    53.         }
    54.     }
    55. }
    56.  
    I can see smooth atmosphere light from any position when I use halfCircleFalloff.png. But when I use simplefalloff.png I see square at center of sphere. Why?
     

    Attached Files:

  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,414
    Here are two surface shader examples that show how you could apply transparency depending on the surface normal and the viewing direction. This is pretty much how rim-lighting (1 2) works, but we use it for alpha instead.

    Things you want to read:

    The first example calculates the "view intensity", the part you want to modify, inside the fragment shader (per pixel):
    Code (CSharp):
    1. Shader "Custom/ExampleShader" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5. }
    6.  
    7. SubShader {
    8.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    9.     LOD 200
    10.  
    11. CGPROGRAM
    12. #pragma surface surf Lambert alpha
    13.  
    14. sampler2D _MainTex;
    15. fixed4 _Color;
    16.  
    17. struct Input {
    18.     float2 uv_MainTex;
    19.  
    20.     // The documentation for viewDir explanation:
    21.     // http://docs.unity3d.com/Manual/SL-SurfaceShaders.html
    22.     float3 viewDir;
    23. };
    24.  
    25. void surf (Input IN, inout SurfaceOutput o) {
    26.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    27.     o.Albedo = c.rgb;
    28.  
    29.     // Calculate alpha according to "angle" between surface normal and view direction.
    30.     // This is the part you want to play with.
    31.     half viewIntensity = saturate(dot(normalize(IN.viewDir), o.Normal));
    32.     o.Alpha = c.a * viewIntensity;
    33. }
    34. ENDCG
    35. }
    36.  
    37. Fallback "Transparent/VertexLit"
    38. }
    39.  

    The second example calculates the "view intensity" inside the vertex shader (per vertex), which might perform a little better than the first one.
    Code (CSharp):
    1. Shader "Custom/Example2Shader" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    5. }
    6.  
    7. SubShader {
    8.     Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    9.     LOD 200
    10.  
    11. CGPROGRAM
    12. #pragma surface surf Lambert alpha vertex:vert
    13.  
    14. sampler2D _MainTex;
    15. fixed4 _Color;
    16.  
    17. struct Input {
    18.     float2 uv_MainTex;
    19.    
    20.     fixed viewIntensity;
    21. };
    22.  
    23. void vert (inout appdata_full v, out Input o)
    24. {
    25.     UNITY_INITIALIZE_OUTPUT(Input,o);
    26.  
    27.     float3 viewDir = ObjSpaceViewDir(v.vertex);
    28.     o.viewIntensity = saturate(dot(normalize(viewDir), v.normal));
    29. }
    30.  
    31. void surf (Input IN, inout SurfaceOutput o)
    32. {
    33.     fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    34.     o.Albedo = c.rgb;
    35.     o.Alpha = c.a * IN.viewIntensity;
    36. }
    37. ENDCG
    38. }
    39.  
    40. Fallback "Transparent/VertexLit"
    41. }
    42.  

    EDIT: Meh, 26 minutes too late, need to get faster writing answers.
     
    marcell123455, Remjie, Deanit and 2 others like this.
  4. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    270
    Hi @Peter77

    I am kinda new to shaders, but got my simple billboard shader working. I am trying to imlement your solution into my shader but don´t even really know where to start :/ . As you have said I tried to fiddel arround with the frag method and looked at the linked doc pages but nah...even with some experementing I couln´d get it.

    Do you think you could you take a look at my shader?
    Code (CSharp):
    1. Shader "Custom/Billboard"
    2. {
    3.     Properties
    4.     {
    5.        _MainTex("Texture Image", 2D) = "white" {}
    6.        _Color("Color", Color) = (1,1,1,1)
    7.        _ScaleX("Scale X", Float) = 1.0
    8.        _ScaleY("Scale Y", Float) = 1.0
    9.     }
    10.         SubShader
    11.        {
    12.            Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent"}
    13.            ZWrite Off
    14.            Blend SrcAlpha OneMinusSrcAlpha
    15.            Offset -100,-100
    16.  
    17.            Pass
    18.            {
    19.                CGPROGRAM
    20.  
    21.                #pragma vertex vert
    22.                #pragma fragment frag
    23.  
    24.                // User-specified uniforms          
    25.                uniform sampler2D _MainTex;
    26.                float4 _Color;
    27.                uniform float _ScaleX;
    28.                uniform float _ScaleY;
    29.                fixed viewIntensity;
    30.  
    31.                struct vertexInput
    32.                {
    33.                    float4 vertex : POSITION;
    34.                    float4 tex : TEXCOORD0;
    35.                    float4 vertColor : COLOR;
    36.                };
    37.                struct vertexOutput
    38.                {
    39.                    float4 pos : SV_POSITION;
    40.                    float4 tex : TEXCOORD0;
    41.                    float4 vertColor : COLOR;
    42.                };
    43.  
    44.                vertexOutput vert(vertexInput input)
    45.                {
    46.                    vertexOutput output;
    47.  
    48.                    output.pos = mul(UNITY_MATRIX_P,
    49.                    mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    50.                    + float4(input.vertex.x, input.vertex.y, 0.0, 0.2)
    51.                    * float4(_ScaleX, _ScaleY, 1.0, 1.0));
    52.  
    53.                    output.tex = input.tex;
    54.                    output.vertColor = input.vertColor;
    55.  
    56.  
    57.                    return output;
    58.                }
    59.  
    60.                float4 frag(vertexOutput input) : COLOR
    61.                {
    62.                    return tex2D(_MainTex, float2(input.tex.xy)) * input.vertColor * _Color;
    63.                }
    64.  
    65.                ENDCG
    66.            }
    67.        }
    68. }
    Thanks
     
  5. marcell123455

    marcell123455

    Joined:
    Jun 18, 2014
    Posts:
    270
    No problem, got it working. Thanks for your example code ;)