Advertisement
Guest User

Untitled

a guest
Aug 14th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "Unlit/pbr_smoke"
  2. {
  3.     Properties
  4.     {
  5.         // Consider this our "rawLightMap" in the example
  6.         _rawLightMap ("Tangent Light Maps (RGBA)", 2D) = "white" {}
  7.         _auxMap("Color Key (R) and Alpha (G)", 2D) = "white" {}
  8.  
  9.         _lightColor("Light Color", Color) = (1,1,1,1)
  10.         _ambientColor("Ambient Color", Color) = (1,1,1,1)
  11.     }
  12.     SubShader
  13.     {
  14.         Tags { "RenderType" = "Opaque" }
  15.         LOD 100
  16.  
  17.         Pass
  18.         {
  19.             CGPROGRAM
  20.             #pragma vertex vert
  21.             #pragma fragment frag
  22.  
  23.             #include "UnityCG.cginc"
  24.  
  25.             // Probably a bunch of redundant information in vertex to fragment (v2f) as I only pass along appdata.
  26.             struct appdata
  27.             {
  28.                 float4 vertex : POSITION;
  29.                 float2 uv : TEXCOORD0;
  30.                 float4 tangent : TANGENT;
  31.                 float3 normal : NORMAL;
  32.             };
  33.  
  34.             struct v2f
  35.             {
  36.                 float2 uv : TEXCOORD0;
  37.                 float4 vertex : SV_POSITION;
  38.                 float4 tangent : TANGENT;
  39.                 float3 normal : NORMAL;
  40.             };
  41.  
  42.             sampler2D _rawLightMap;
  43.             float4 _rawLightMap_ST; // Apparently used by TRANSFORM_TEX macro
  44.  
  45.             sampler2D _auxMap;
  46.             float4 _auxMap_ST;
  47.  
  48.             float3 _ambientColor;
  49.             float3 _lightColor;
  50.  
  51.             v2f vert (appdata v)
  52.             {
  53.                 v2f o;
  54.                 o.vertex = UnityObjectToClipPos(v.vertex);
  55.                 o.uv = TRANSFORM_TEX(v.uv, _rawLightMap);
  56.                 o.tangent = v.tangent;
  57.                 o.normal = UnityObjectToWorldNormal(v.normal);
  58.                 return o;
  59.             }
  60.            
  61.             fixed4 frag (v2f i) : SV_Target
  62.             {
  63.                 // Normal, Tangent and Binormal
  64.                 float3 N = i.normal; // Already cast into worldspace
  65.                 float3 T = mul((float3x3)unity_ObjectToWorld, i.tangent.xyz);   // Casting the tangent vector to world, ie the vector pointing in X direction from the objects perspective.
  66.                 float3 B = cross(N, T) * i.tangent.w; // Binormal is the cross of Normal and Tangent. Giving us an orthogonal set of vectors.
  67.  
  68.                 // Compose into a matrix, where the Normal of the object is Z, Tangent X and Binormal Y
  69.                 float3x3 worldToTangent = float3x3(T, B, N);
  70.  
  71.                 // Normalized vector for lightDirection, apparently Unity already allows getting the vector for light, should be possible in Unreal as well.
  72.                 float3 lightDirection = _WorldSpaceLightPos0.xyz;
  73.  
  74.                 // Cast lightDirection vector into tangentspace of current object.
  75.                 float3 tangentLightDirection = mul(worldToTangent, lightDirection); // Inverted light vector to match the tutorial
  76.  
  77.                 // Just define the variables
  78.                 float hMap;
  79.                 float vMap;
  80.                 float dMap;
  81.                 float lightMap;
  82.  
  83.                 // Sample and combine the value for pixel into a float for front map
  84.                 float frontMap = 0.25f * ( tex2D(_rawLightMap, i.uv).r + tex2D(_rawLightMap, i.uv).g + tex2D(_rawLightMap, i.uv).b + tex2D(_rawLightMap, i.uv).a );
  85.                 frontMap = pow(frontMap, 0.625);
  86.  
  87.                 float backMap = 1.0f - frontMap;
  88.                 // Assuming the normal used is worldspace?, and backMap * .. four times is pow, not sure why that wasn't used.
  89.                 //backMap = saturate(0.25f * (1.0f - N.x) + 0.5f * pow(backMap, 4));
  90.  
  91.                 // It wasn't, seem like object space normal was needed.
  92.                 float3 N2 = normalize(mul((float3x3)unity_WorldToObject, N));
  93.                 backMap = saturate(0.25f * (1.0f - N2.x) + 0.5f * pow(backMap, 4));
  94.  
  95.                 // Light shining from right-left will be red channel 1 -> -1
  96.                 if (tangentLightDirection.x > 0.0f)
  97.                 {
  98.                     hMap = tex2D(_rawLightMap, i.uv).r; // Right
  99.                 }
  100.                 else {
  101.                     hMap = tex2D(_rawLightMap, i.uv).g; // Left
  102.                 }
  103.  
  104.                 // Light shining from above-below will be green channel
  105.                 if (tangentLightDirection.y > 0.0f)
  106.                 {
  107.                     vMap = tex2D(_rawLightMap, i.uv).b; // Above
  108.                 }
  109.                 else {
  110.                     vMap = tex2D(_rawLightMap, i.uv).a; // Below
  111.                 }
  112.  
  113.                 // Light shining straight at the face will be black, shining through the object will be blue.
  114.                 if (tangentLightDirection.z > 0.0f)
  115.                 {
  116.                     dMap = frontMap; // At
  117.                 }
  118.                 else {
  119.                     dMap = backMap; // Through
  120.                 }
  121.  
  122.                 // The pythagorial combo, map direction times light direction squared for all directions
  123.                 lightMap = hMap * tangentLightDirection.x * tangentLightDirection.x + vMap * tangentLightDirection.y * tangentLightDirection.y + dMap * tangentLightDirection.z * tangentLightDirection.z;
  124.  
  125.                 // Fragment output has to be of type fixed4
  126.                 fixed4 col;
  127.  
  128.                 // Combine the light map as specified on the post.
  129.                 float combinedLight = _lightColor * lightMap + _ambientColor;
  130.  
  131.                 // Set final color and alpha
  132.                 col.rgb = float3(T);
  133.                 col.a = tex2D(_auxMap, i.uv);
  134.  
  135.                 return col;
  136.             }
  137.             ENDCG
  138.         }
  139.     }
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement