Ineluki80

DarkVision.fx - Natural Selection 2 Alien Vision Shader

Jan 26th, 2013
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.98 KB | None | 0 0
  1. /*************************************************************************************\
  2. *  Alien Vision Shader for Natural Selection 2                                        *
  3. *  To be used with Dark Vision Mod for Natural Selection 2                            *
  4. *  Steam Workshop: http://steamcommunity.com/sharedfiles/filedetails/?id=108510422    *
  5. *  Forum: http://forums.unknownworlds.com/discussion/comment/2066954/#Comment_2066954 *
  6. *  Example Video: http://www.youtube.com/watch?v=Q7TNh9Cbngg                          *
  7. *                                                                                     *
  8. *  Author: Ineluki80                                                                  *
  9. *  Date: 2013-01-26                                                                   *
  10. *  Version: v0.2                                                                      *
  11. *                                                                                     *
  12. *  Features:                                                                          *
  13. *    - Insectoide compound eyes using a rhombohedral instead of a hexagonal lattice   *
  14. *    - sonar sight using sound pulses with exponential decay and distance based       *
  15. *      resolution                                                                     *
  16. *    - importance highlighting for biological and technological compounds             *
  17. \*************************************************************************************/
  18.  
  19. struct VS_INPUT
  20. {
  21.     float3 ssPosition   : POSITION;
  22.     float2 texCoord     : TEXCOORD0;
  23.     float4 color        : COLOR0;
  24. };
  25.  
  26. struct VS_OUTPUT
  27. {
  28.     float4 ssPosition   : POSITION;
  29.     float2 texCoord     : TEXCOORD0;
  30.     float4 color        : COLOR0;
  31. };
  32.  
  33. struct PS_INPUT
  34. {
  35.     float2 texCoord     : TEXCOORD0;
  36.     float4 color        : COLOR0;
  37. };
  38.  
  39. texture     baseTexture;
  40. texture     depthTexture;
  41. float       time;
  42. float       startTime;
  43. float       amount;
  44.  
  45. sampler baseTextureSampler = sampler_state
  46.     {
  47.         texture       = (baseTexture);
  48.         AddressU      = Wrap;
  49.         AddressV      = Wrap;
  50.         MinFilter     = Linear;
  51.         MagFilter     = Linear;
  52.         MipFilter     = Linear;
  53.         SRGBTexture   = False;
  54.     };
  55.    
  56. sampler depthTextureSampler = sampler_state
  57.     {
  58.         texture       = (depthTexture);
  59.         AddressU      = Clamp;
  60.         AddressV      = Clamp;
  61.         MinFilter     = Linear;
  62.         MagFilter     = Linear;
  63.         MipFilter     = None;
  64.         SRGBTexture   = False;
  65.     }; 
  66.  
  67. /**
  68.  * Vertex shader.
  69.  */  
  70. VS_OUTPUT SFXBasicVS(VS_INPUT input)
  71. {
  72.  
  73.     VS_OUTPUT output;
  74.  
  75.     output.ssPosition = float4(input.ssPosition, 1);
  76.     output.texCoord   = input.texCoord;
  77.     output.color      = input.color;
  78.  
  79.     return output;
  80.  
  81. }
  82.  
  83. float4 SFXDarkVisionPS(PS_INPUT input) : COLOR0
  84. {
  85.  
  86.   // Get the rendered image as a texture
  87.     float4 inputPixel = tex2D(baseTextureSampler, input.texCoord);                          // this is the rendered image which we want to pixelshade
  88.     float4 outputPixel = float4(inputPixel.r, inputPixel.g, inputPixel.b, 0.0);             // here we get the pixel colours from the rendered image
  89.  
  90.   // insectoid eyes
  91.     const  float  grain  = 50.0;                                                            // granularity of the eyes .. how many cells per row and column
  92.     const  float4 delta  = float4(-1.0,0.0,1.0,0.0)/3;                                      // offset for the different colours channels
  93.            float  x      = (input.texCoord.x) * grain;                                      // X and Y coordinates within the granularity
  94.            float  y      = (input.texCoord.y) * grain;        
  95.     float4 eyePattern    = 0.5+0.8*pow(fmod(delta+x+y,1.0)*fmod(grain+delta+x-y,1.0),1.3);  // creates a rectangular grid, slightly dislocated for all colour channels
  96.    
  97.  
  98.   // Edge Highlighting
  99.     float2 depthMap = tex2D(depthTextureSampler, input.texCoord).rg;                         // this texture contains the depth information in r and importance factor in g
  100.    
  101.     float  offset   = 0.0010;                                                                // offset is the difference between two pixels for which we do an edge test.
  102.     float4 ETest    = float4(
  103.                         tex2D(depthTextureSampler, input.texCoord + float2(-offset,0)).r,    // we get the depth value of each pixel around the one we want to shade
  104.                         tex2D(depthTextureSampler, input.texCoord + float2(+offset,0)).r,    // above in -x, now in +x direction
  105.                         tex2D(depthTextureSampler, input.texCoord + float2(0,-offset)).r,    // now in -y, next in +y direction
  106.                         tex2D(depthTextureSampler, input.texCoord + float2(0,+offset)).r
  107.                       );
  108.    
  109.     const float falloff = 10.0 / log(2);                                                     // edge intensity is halved for each 10 units,
  110.                                                                                              // so it's 1/4 for 20 units, 1/8 for 30 units, ...
  111.     float edge = saturate (                                                                  // edge is a value which highlights each pixel with values between 0 and 1
  112.                    length(ETest-depthMap.r)*exp(-depthMap.r/falloff)                         // an edge is a pixel which distance to its neighbours scaled by the
  113.                  );                                                                          // exponential perception factor is in the order of magnitude 1 or bigger
  114.  
  115.                  
  116.   // Sonar effect                                                                            // By applying a time modified pulse using a slater function, we can
  117.     float sonar = 0.02+0.70*exp(-abs(depthMap.r-fmod(50*(time-startTime),100.0))/10.0);      // emulate a sonar. Sound travels 50 units per second, pulses are 10 units long
  118.                                                                                              // and travel 100 units before the next pulse is emitted.
  119.                                                                                              // Minimum brightness is 2%, maximum brightness is 72%.
  120.    
  121.   // Importance highlighting
  122.     float4 edgeColor;                                                                        // This will hold the colour of the edge based on information content.
  123.     if ( depthMap.g > 0.5 && depthMap.r > 0.4 ) {                                            // If the pixel belongs to something important (bio, tech, marines, etc)
  124.       edgeColor   = float4( 2.97, 0.37, -0.13, 0.0 ) * depthMap.g;                           // and the distance is bigger than 0.4 units (so we ignore our snoute).
  125.       outputPixel = outputPixel + 0.1*edgeColor;                                             // We set the edge colour to a bright orange weighted by importance, and
  126.       edge        = edge * 5.0;                                                              // overlay the object colour with that orange, too. Finally we add some
  127.     } else {                                                                                 // glow effect to the edges by oversaturating them via a huge factor.
  128.       edgeColor = float4( 1.0, 1.0, 1.0, 0.0 );                                              // If the object is not important, edge colour is plain white.
  129.     }
  130.    
  131.   // Adding all information together
  132.     return outputPixel*eyePattern + edge*edgeColor*sonar;                                    // We overlay the rendered scene with our eyePattern and add coloured edges.
  133.                                                                                                // Finally, we return the calculated colour as result.
  134. }
  135.  
  136. technique SFXDarkVision
  137. {
  138.     pass p0
  139.     {
  140.         ZEnable             = False;
  141.         ZWriteEnable        = False;   
  142.         VertexShader        = compile vs_2_0 SFXBasicVS();
  143.         PixelShader         = compile ps_2_0 SFXDarkVisionPS();
  144.         CullMode            = None;
  145.     }
  146. }
Advertisement
Add Comment
Please, Sign In to add comment