Advertisement
Guest User

2D normal map rotation HLSL shader

a guest
Dec 13th, 2014
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.19 KB | None | 0 0
  1. #define _vs(r)  : register(vs, r)
  2. #define _ps(r)  : register(ps, r)
  3. #define _cb(r)
  4.  
  5. Texture NormalMap;
  6. sampler NormalMapSampler : register(s0) = sampler_state {
  7.     texture = <NormalMap>; 
  8.     MinFilter = LINEAR;
  9.     AddressU = MIRROR;
  10.     AddressV = MIRROR;
  11. };
  12.  
  13. static const float PI = 3.14159265f;
  14. float4x4 MatrixTransform    _vs(c0) _cb(c0);
  15.  
  16. void SpriteVertexShader(inout float4 color    : COLOR0,
  17.                         inout float2 texCoord : TEXCOORD0,
  18.                         inout float4 position : SV_Position)
  19. {
  20.     position = mul(position, MatrixTransform);
  21. }
  22.  
  23. inline float4 EncodeFloatRGBA( float v ) {
  24.   float4 enc = float4(1.0, 255.0, 65025.0, 160581375.0) * v;
  25.   enc = frac(enc);
  26.   enc -= enc.yzww * float4(1.0/255.0,1.0/255.0,1.0/255.0,0.0);
  27.   return enc;
  28. }
  29.  
  30. inline float DecodeFloatRGBA( float4 rgba ) {
  31.   return dot( rgba, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
  32. }
  33.  
  34. float3 CartesianToSpherical( in float3 xyz )
  35. {
  36.     float r = length( xyz );
  37.     xyz *= 1.f/r;
  38.     float theta = acos( xyz.z );
  39.     float phi = atan2( xyz.y, xyz.x );
  40.     phi += ( phi < 0 ) ? 2*PI : 0;  // only if you want [0,2pi)
  41.  
  42.     return float3( phi, theta, r );
  43. }
  44.  
  45. // Rotates the normals by the amount encoded in the color input parameter
  46. float4 SpritePixelShader(float4 color : COLOR0, float2 texCoord : TEXCOORD0) : SV_Target0 {
  47.    
  48.     float4 inputColor = tex2D(NormalMapSampler, texCoord);
  49.    
  50.     if (inputColor.w > 0.1f) {
  51.    
  52.         float3 normal = (2.0f * (inputColor.xyz)) - 1.0f;  
  53.            
  54.         // Color components  r and g specify the angle in 0-1 range, Multiply with 2 Pi to get radian angle.
  55.         float angle = (color.r + color.g/255.0) * 6.283185f;
  56.  
  57.         float x2 = normal.x * cos(angle) - normal.y * sin(angle);
  58.         float y2 = normal.x * sin(angle) + normal.y * cos(angle);
  59.        
  60.         float4 rotated = float4((x2 + 1.0f) / 2.0f, (y2 + 1.0f) / 2.0f, (normal.z  + 1.0f) / 2.0f, inputColor.w);
  61.         rotated  = float4(rotated.xyz * inputColor.w, inputColor.w); // Premultiply alpha
  62.            
  63.         return rotated;
  64.    
  65.     } else {
  66.         return float4(0,0,0,0);
  67.     }
  68.    
  69. }
  70.  
  71. technique NormalRotateByColor
  72. {
  73.     pass
  74.     {
  75.         VertexShader = compile vs_2_0 SpriteVertexShader();
  76.         PixelShader  = compile ps_2_0 SpritePixelShader();
  77.     }
  78. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement