Skip to content

Instantly share code, notes, and snippets.

@jasonphillips
Last active April 6, 2020 06:52
Show Gist options
  • Save jasonphillips/4cc91e85f128eae4f086118a59241ca1 to your computer and use it in GitHub Desktop.
Save jasonphillips/4cc91e85f128eae4f086118a59241ca1 to your computer and use it in GitHub Desktop.
Lens distortion for Dolphin emulator (for VR viewers) as custom shader
/*
[configuration]
[OptionRangeInteger]
GUIName = Distortion amount
OptionName = DISTORTION_FACTOR
MinValue = 1
MaxValue = 10
StepAmount = 1
DefaultValue = 4
[OptionRangeInteger]
GUIName = Eye Distance Offset
OptionName = EYE_OFFSET
MinValue = 0
MaxValue = 10
StepAmount = 1
DefaultValue = 5
[OptionRangeFloat]
GUIName = Zoom adjustment
OptionName = SIZE_ADJUST
MinValue = 0.0
MaxValue = 1.0
StepAmount = 0.1
DefaultValue = 0.5
[OptionRangeFloat]
GUIName = Aspect Ratio adjustment
OptionName = ASPECT_ADJUST
MinValue = 0.0
MaxValue = 1.0
StepAmount = 0.1
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;
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 (layer == 1) {
offsetAdd = stereoOffset;
} else {
offsetAdd = 0 - stereoOffset;
}
// convert coordinates to NDC space
float2 fragPos = (GetCoordinates() - 0.5f - vec2(offsetAdd, 0.0f)) * 2.0f;
// Calculate the source location "radius" (distance from the centre of the viewport)
float destR = length(fragPos);
float srcR = destR * sizeAdjust + ( ka * pow(destR,2) + kb * pow(destR,4));
// Calculate the source vector (radial)
vec2 correctedRadial = normalize(fragPos) * srcR;
// fix aspect ratio
vec2 widenedRadial = correctedRadial * vec2(aspectAdjustment, 1.0f);
// Transform the coordinates (from [-1,1]^2 to [0, 1]^2)
vec2 uv = (widenedRadial/2.0f) + vec2(0.5f) + vec2(offsetAdd, 0.0f);
// Sample the texture at the source location
if (uv[0] > 1.0 || uv[1] > 1.0 || uv[0] < 0.0 || uv[1] < 0.0) {
// black if beyond bounds
SetOutput(float4(0,0,0,0));
} else {
SetOutput(SampleLocation(uv));
}
}
@jasonphillips
Copy link
Author

Please note that my code has now been merged into the official Dolphin project:
dolphin-emu/dolphin#4209

As of this moment, you'll have to download the latest development release here:
https://dolphin-emu.org/download/

The shader is now named lens_distortion in the Post-Processing dropdown.

@Air-max-fr
Copy link

Hello,
I have a problem with this shader.
When initializing a game at startup, I get a error :
error C1503 undefined variable "layer"

I note that this refers to line 56 :
"if (layer == 1)"
But this variable is never defined higher in the code...how to fix this?
I read that your shader is now integrated in Dophin under the name lens_distortion.glsl ...but the shader codes are strictly identical, and the result is unfortunately also strictly identical.... C1503 error :/

Thanks in advance for your answer, I really want to test your shader ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment