SHARE
TWEET

The Witcher 3 drunk shader (reversed) v 1.0

a guest Aug 31st, 2018 356 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. cbuffer cb0 : register (b0)
  2. {
  3.     float4 cb0_v0;
  4.     float4 cb0_v1;
  5. }
  6.  
  7. cbuffer cb3 : register (b3)
  8. {
  9.     float4 cb3_v0;
  10.     float4 cb3_v1;
  11.     float4 cb3_v2;
  12. }
  13.  
  14. Texture2D texture0 : register (t0);
  15. SamplerState sampler0 : register (s0);
  16.  
  17. struct VS_OUTPUT
  18.  {
  19.     float4 PositionH : SV_Position;
  20.     float2 Texcoords : Texcoord0;
  21. };
  22.  
  23. static const float2 pointsAroundPixel[8] =
  24. {
  25.     float2(1.0, 0.0),
  26.     float2(-1.0, 0.0),
  27.     float2(0.707,  0.707),
  28.     float2(-0.707, -0.707),
  29.     float2(0.0,  1.0),
  30.     float2(0.0, -1.0),
  31.     float2(-0.707, 0.707),
  32.     float2(0.707, -0.707)
  33. };
  34.  
  35. float4 DrunkPS( in VS_OUTPUT Input ) : SV_Target0
  36. {
  37.     /* Inputs */
  38.     float  rotationAroundPixelRadius = cb3_v0.x;
  39.     float  drunkIntensity = cb3_v0.y;
  40.     float2 texelSize = cb0_v1.zw;
  41.     float2 centerPoint = cb3_v2.xy;
  42.    
  43.     float2 rotationSinCos = cb3_v1.xy;
  44.     float  rotationSpeed = 0.05;  
  45.     float2 rotationDirection = rotationSinCos.xy * rotationSpeed;
  46.  
  47.     float2 pixelPosition = Input.PositionH.xy * texelSize;
  48.     float2 centerToPixel = pixelPosition - centerPoint;
  49.    
  50.  
  51.     /* Rotation part */
  52.     float distanceFromCenterToPixel = length(centerToPixel);
  53.  
  54.     float intensityMask = dot(centerToPixel, centerToPixel);
  55.     intensityMask *= 10.0;
  56.     intensityMask = min( intensityMask, 1.0 );
  57.     intensityMask *= drunkIntensity;
  58.            
  59.     // Scale rotation direction (sin/cos pair) by distance from center
  60.     float2 rotationOffsets = rotationDirection * distanceFromCenterToPixel;
  61.  
  62.    
  63.     float zoomFactor = -0.1 * drunkIntensity + 1; // 1.0 - 0.1*drunkIntensity (clearer for me)
  64.  
  65.     /* Calculating base rotation texcoords: */
  66.     /* Approach #1 (closest approximation to original shader in terms of assembly) */
  67.     float2 baseTexcoords0 = zoomFactor*centerToPixel + rotationDirection * distanceFromCenterToPixel;;
  68.     float2 baseTexcoords1 = zoomFactor*centerToPixel - rotationDirection * distanceFromCenterToPixel;;
  69.     baseTexcoords0 += centerPoint;
  70.     baseTexcoords1 += centerPoint;
  71.  
  72.     /* Approach #2 (less instructions and more understandable (lerp) */
  73.     //float2 zoomedTexcoords = lerp( centerPoint, pixelPosition, zoomFactor );
  74.     //float2 baseTexcoords0 = zoomedTexcoords + rotationOffsets;
  75.     //float2 baseTexcoords1 = zoomedTexcoords - rotationOffsets;
  76.  
  77.     float rotationTexcoordsOffsetIntensity = intensityMask * rotationAroundPixelRadius.x;
  78.     rotationTexcoordsOffsetIntensity *= 5.0;
  79.  
  80.     float2 rotationTexcoordsOffset = rotationTexcoordsOffsetIntensity * texelSize;
  81.    
  82.     // For opposite directions (difference by 180 degrees)
  83.     float4 rotation0 = 0.0;
  84.     float4 rotation1 = 0.0;
  85.  
  86.     int i=0;
  87.     [unroll] for (i = 0; i < 8; i++)
  88.     {
  89.         rotation0 += texture0.Sample( sampler0, baseTexcoords0 + rotationTexcoordsOffset * pointsAroundPixel[i] );
  90.     }
  91.     rotation0 /= 16.0;
  92.  
  93.     [unroll] for (i = 0; i < 8; i++)
  94.     {
  95.         rotation1 += texture0.Sample( sampler0, baseTexcoords1 + rotationTexcoordsOffset * pointsAroundPixel[i] );
  96.     }
  97.     rotation1 /= 16.0;
  98.  
  99.     float4 rotationPart =  rotation0 + rotation1;
  100.  
  101.  
  102.     /* Zooming in/out part */
  103.     float zoomInOutScalePixels = drunkIntensity * 8.0;
  104.     float2 zoomInOutScaleNormalizedScreenCoordinates = texelSize.xy * zoomInOutScalePixels;
  105.     float  zoomInOutAmplitude = 1.0 + 0.02 * rotationSinCos.y;
  106.     float2 zoomInOutfromCenterToTexel = zoomInOutAmplitude * centerToPixel;
  107.    
  108.     float2 zoomInOutBaseTextureUV = lerp(centerPoint, pixelPosition, zoomInOutAmplitude);
  109.     float2 zoomInOutAddTextureUV0 = zoomInOutBaseTextureUV + zoomInOutfromCenterToTexel * zoomInOutScaleNormalizedScreenCoordinates;
  110.     float2 zoomInOutAddTextureUV1 = zoomInOutBaseTextureUV + 2.0 * zoomInOutfromCenterToTexel * zoomInOutScaleNormalizedScreenCoordinates;
  111.  
  112.     float4 zoomColor0 = texture0.Sample( sampler0, zoomInOutBaseTextureUV );
  113.     float4 zoomColor1 = texture0.Sample( sampler0, zoomInOutAddTextureUV0 );
  114.     float4 zoomColor2 = texture0.Sample( sampler0, zoomInOutAddTextureUV1 );
  115.    
  116.     float4 zoomingPart = ( zoomColor0 + zoomColor1 + zoomColor2 ) / 3.0;
  117.  
  118.    
  119.     /* Combine rotation & zooming */
  120.  
  121.     /* Approach 1 (closest approximation to assembly from original shader) */
  122.     float4 finalColor = intensityMask * (rotationPart - zoomingPart);
  123.     finalColor = drunkIntensity * finalColor + zoomingPart;
  124.  
  125.     /* Approach 2 (you can deduce it from #1 formula, makes more sense for me */
  126.     //finalColor = lerp(zoomingPart, rotationPart, intensityMask * drunkIntensity);
  127.    
  128.  
  129.     return finalColor;
  130. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top