Search Unity

Help with Nebula shader

Discussion in 'Shaders' started by toddw, Oct 20, 2012.

  1. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    130
    Hi,

    I'm attempting to use the logic in this video to create a dynamic nebula shader:



    The video basically says I need to use the absolute of the dot product of the vertex normal and the camera view direction. Here is my shader code:

    Code (csharp):
    1.  
    2.  
    3. Shader "Custom/Dynamic Nebula" {
    4. Properties {
    5.         _MainTex ("MainTex (RGB)", 2D) = "white" {}
    6.         _Color ("Color", Color) = (0,0,0,1)
    7. }
    8.  
    9. Category {
    10.  
    11.     Tags { "Queue"="Transparent" }
    12.  
    13.     SubShader
    14.     {      
    15.     Blend SrcAlpha One
    16.     Cull Off Lighting Off ZWrite Off Fog { Color (0,0,0,0) }
    17.         Pass
    18.         {
    19.             Name "BASE"
    20.             Tags { "LightMode" = "Always" }
    21.                        
    22.             CGPROGRAM
    23.             #pragma vertex vert
    24.             #pragma fragment frag
    25.             #pragma fragmentoption ARB_precision_hint_fastest
    26.             #include "UnityCG.cginc"
    27.  
    28.             struct appdata_t {
    29.                 float4 vertex : POSITION;
    30.                 float4 color : COLOR;
    31.                 float2 texcoord: TEXCOORD0;
    32.                 float3 normal : NORMAL0;
    33.             };
    34.  
    35.             struct v2f {   
    36.                 float4 vertex : POSITION;  
    37.                 float4 color : COLOR;
    38.                 float2 texcoord: TEXCOORD0;
    39.                 float3 normal : TEXCOORD1;
    40.                 float3 view : TEXCOORD2;
    41.             };
    42.  
    43.             float4 _MainTex_ST;
    44.             float4 _Color;
    45.  
    46.             v2f vert (appdata_t v)
    47.             {
    48.                 v2f o;
    49.                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    50.                 o.color = _Color;
    51.                 o.texcoord = v.texcoord;
    52.                 o.view = normalize(ObjSpaceViewDir(v.vertex));
    53.                 o.normal = v.normal;
    54.                
    55.                 return o;
    56.             }
    57.            
    58.             sampler2D _MainTex;
    59.  
    60.             half4 frag(v2f i) :COLOR0
    61.             {
    62.                 float4 result = i.color * tex2D(_MainTex, i.texcoord);
    63.                               result.a *= abs(dot(i.view, i.normal));
    64.                 return result;
    65.             }
    66.             ENDCG
    67.         } // end pass
    68.  
    69.     } // end subshader
    70.  
    71.    
    72. } // end category
    73.  
    74. } // end shader
    75.  
    Here is the screen shot of several planes with the shader that are rotated at different angles, the plane in the middle oriented straight up and down is an example fo the problem:



    What I need is for the apha to drop as the polygon normal lines up closer to the normal of the camera, that way when the polygon is rotated flat the image is invisible and when the polygon normal faces the camera the image is fully visible. What I have is close but not the same as the video shows, so I figured I'd see if some of you shader experts can help!

    Thanks in advance!
     
  2. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    130
    bump.
     
  3. scarpelius

    scarpelius

    Joined:
    Aug 19, 2007
    Posts:
    966
    If you listen to that guy in video he says the trick is to hide the polygon when its almost facing its edge to the camera.
    One way is to apply a function to the texture alpha that is not linear like yours, instead you need a power function like in the picture bellow
    $f4.jpg

    So, instead of
    Code (csharp):
    1. result.a *= abs(dot(i.view, i.normal));
    use

    Code (csharp):
    1. result.a *= pow(abs(dot(i.view, i.normal)), 4);
    PS The more you increase the power of the function, the more it will be flattened at the bottom, meaning the you will get near zero values for higher values of abs(dot(i.view, i.normal))
     
  4. toddw

    toddw

    Joined:
    May 9, 2010
    Posts:
    130
    That did the trick, thanks so much for your help!!!
     
  5. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    Doesn't work anymore :(
    Anyone know of an updated shader that does this?
     
  6. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    There's no reason this shouldn't work anymore, it's basic shader math. Unless you mean that this shader file doesn't work with LWRP/HDRP, then sure, in which case you can recreate it in shadergraph or copy the default shader of the pipeline you're using and slot the relevant math from this shader into its appropriate sections.
     
  7. BadSeedProductions

    BadSeedProductions

    Joined:
    Dec 26, 2014
    Posts:
    144
    Thanks for the reply! So from what I understand (very little about shaders) this shader is supposed to reduce the alpha to 0 as the camera angle approaches the edges. However if I copy pasta and save the shader (inside Visual studio... going ot give shadergraph a shot), it appears to work as a normal additive particle shader would, but it does not adjust the alpha depending on camera angle. I know little to nothing about shaders so any direction is helpful, going to experiment with shadergraph today!
    Edit: Tried again, and for some reason its working now. Just one of those things I guess where a Unity restart fixed the issue... OR perhaps I thought the effect would be more dramatic and just didn't notice (it seems to only reach alpha 0 when camera is directly on edge, it should reach 0before). I'm going to mess with the algo and see if I can get it to work a little better.
    Edit: So I thought I had saved the shader with scarpeliuses algo, but I had not, after making the changes it works great, just user error! Thanks for the help
     
    Last edited: Aug 4, 2019
    Invertex likes this.