summaryrefslogtreecommitdiff
path: root/Data/Sys/Shaders/lens_distortion.glsl
blob: b0c872c45e4da0eb4b3a1ea2ea2b652a6cc82971 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
[configuration]

[OptionRangeFloat]
GUIName = Distortion amount
OptionName = DISTORTION_FACTOR
MinValue = 1.0
MaxValue = 10.0
StepAmount = 0.5
DefaultValue = 4.0

[OptionRangeFloat]
GUIName = Eye Distance Offset
OptionName = EYE_OFFSET
MinValue = 0.0
MaxValue = 10.0
StepAmount = 0.25
DefaultValue = 5.0

[OptionRangeFloat]
GUIName = Zoom adjustment
OptionName = SIZE_ADJUST
MinValue = 0.0
MaxValue = 1.0
StepAmount = 0.025
DefaultValue = 0.5

[OptionRangeFloat]
GUIName = Aspect Ratio adjustment
OptionName = ASPECT_ADJUST
MinValue = 0.0
MaxValue = 1.0
StepAmount = 0.025
DefaultValue = 0.5

[/configuration]
*/


void main()
{
  // Base Cardboard distortion parameters
  float factor = GetOption(DISTORTION_FACTOR) * 0.01f;
  float ka = factor * 3.0f;
  float kb = factor * 5.0f;

  // size and aspect adjustment
  float sizeAdjust = 1.0f - GetOption(SIZE_ADJUST) + 0.5f;
  float aspectAdjustment = 1.25f - GetOption(ASPECT_ADJUST);

  // offset centering per eye
  float stereoOffset = GetOption(EYE_OFFSET) * 0.01f;
  float offsetAdd;

  // layer0 = left eye, layer1 = right eye
  if (src_layer == 1)
  {
    offsetAdd = stereoOffset;
  }
  else
  {
    offsetAdd = 0.0 - stereoOffset;
  }

  // convert coordinates to NDC space
  float2 fragPos = (GetCoordinates() - 0.5f - float2(offsetAdd, 0.0f)) * 2.0f;

  // Calculate the source location "radius" (distance from the centre of the viewport)
  float destR = length(fragPos);

  // find the radius multiplier
  float srcR = destR * sizeAdjust + ( ka * pow(destR, 2.0) + kb * pow(destR, 4.0));

  // Calculate the source vector (radial)
  float2 correctedRadial = normalize(fragPos) * srcR;

  // fix aspect ratio
  float2 widenedRadial = correctedRadial * float2(aspectAdjustment, 1.0f);

  // Transform the coordinates (from [-1,1]^2 to [0, 1]^2)
  float2 uv = (widenedRadial/2.0f) + float2(0.5f, 0.5f) + float2(offsetAdd, 0.0f);

  // Sample the texture at the source location
  if (clamp(uv, 0.0, 1.0) != uv)
  {
    // black if beyond bounds
    SetOutput(float4(0.0, 0.0, 0.0, 0.0));
  }
  else
  {
    SetOutput(SampleLocation(uv));
  }
}