Last active
November 4, 2017 16:43
-
-
Save fieldOfView/5097581 to your computer and use it in GitHub Desktop.
Equirectangular viewer Pixel Bender filter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Equirectangular viewer | |
* Last update: 6 March 2013 | |
* | |
* Changelog: | |
* 1.0 - Initial release | |
* | |
* Licensed under the MIT License: | |
* http://www.opensource.org/licenses/mit-license.php | |
* | |
* | |
* Credits and references | |
* ====================== | |
* | |
* Inspired by LittlePlanets by subblue: | |
* http://www.subblue.com/blog/2010/6/17/little_planets | |
* | |
* A good selection of cosc-licensed equirectangular panorama source images can be found here: | |
* http://www.flickr.com/photos/sbprzd/sets/72057594100163739/ | |
* http://www.flickr.com/photos/heiwa4126/sets/72157601609820530/ | |
* http://www.flickr.com/search/?q=equirectangular&z=e&l=deriv&ss=2&ct=5&mt=all&adv=1 | |
* | |
* | |
* Contact | |
* ======= | |
* | |
* This plugin is free to use for personal or commercial projects. | |
* I'd love to hear how you are using it so email me at [email protected] | |
* | |
*/ | |
#define TWOPI 6.283185307179586 | |
#define PI 3.141592653589793 | |
<languageVersion : 1.0;> | |
kernel EquirectangularViewer | |
< namespace : "com.fieldofview"; | |
vendor : "Aldo Hoeben - www.fieldofview.com"; | |
version : 1; | |
displayname: "Equirectangular Viewer"; | |
description : "Unwraps an equirectangular panorama image."; | |
> | |
{ | |
parameter float2 inputSize | |
< | |
minValue: float2(8, 4); | |
maxValue: float2(4096, 4096); | |
defaultValue: float2(2000, 1000); | |
stepInterval: float2(1, 1); | |
displayName: "Input image size"; | |
componentName: "Width|Height"; | |
aeDisplayName: "Input image size"; | |
>; | |
parameter float2 outputSize | |
< | |
minValue: float2(8, 4); | |
maxValue: float2(4096, 4096); | |
defaultValue: float2(800, 400); | |
stepInterval: float2(1, 1); | |
displayName: "Output image size"; | |
componentName: "Width|Height"; | |
aeDisplayName: "Output image size"; | |
>; | |
parameter float yaw | |
< | |
minValue: -180.0; | |
maxValue: 180.0; | |
defaultValue: 0.0; | |
stepInterval: 0.5; | |
displayName: "Yaw"; | |
aeDisplayName: "Yaw"; | |
aeUIControl:"aeAngle"; | |
>; | |
parameter float pitch | |
< | |
minValue: -90.0; | |
maxValue: 90.0; | |
defaultValue: 0.0; | |
stepInterval: 0.5; | |
displayName: "Pitch"; | |
aeDisplayName: "Pitch"; | |
aeUIControl:"aeAngle"; | |
>; | |
parameter float hfov | |
< | |
minValue: 1.0; | |
maxValue: 170.0; | |
defaultValue: 80.0; | |
stepInterval: 1; | |
displayName: "Horizontal Field of View"; | |
aeDisplayName: "Horizontal Field of View"; | |
aeUIControl:"aeAngle"; | |
>; | |
input image4 src; | |
output pixel4 dst; | |
#if !AIF_FLASH_TARGET | |
region needed(region outputRegion, imageRef inputRef) | |
{ | |
return region(float4(0, 0, inputSize.x, inputSize.y)); | |
} | |
region changed(region outputRegion, imageRef inputRef) | |
{ | |
return region(float4(0, 0, outputSize.x, outputSize.y)); | |
} | |
#endif | |
float3x3 rotationMatrix(const float2 euler) | |
{ | |
float2 se = sin(euler); | |
float2 ce = cos(euler); | |
return float3x3( | |
ce.x, 0.,-se.x, | |
0., 1., 0., | |
se.x, 0., ce.x | |
) * float3x3( | |
1., 0., 0., | |
0., ce.y,-se.y, | |
0., se.y, ce.y | |
); | |
} | |
float3 toCartesian(float2 sphericalCoord) | |
{ | |
return normalize(float3(sphericalCoord.x, sphericalCoord.y, 0.5 / tan(0.5 * radians(hfov)))); | |
} | |
float2 toSpherical(float3 cartesianCoord) | |
{ | |
float2 sphericalCoord = float2( | |
atan(cartesianCoord.x, cartesianCoord.z), | |
acos(cartesianCoord.y) | |
); | |
if(sphericalCoord.x < 0.0) | |
sphericalCoord.x += TWOPI; | |
return sphericalCoord; | |
} | |
void evaluatePixel() | |
{ | |
float2 sphericalCoord = outCoord() / outputSize - float2(0.5); | |
sphericalCoord.y *= -outputSize.y / outputSize.x; | |
float3 cartesianCoord = rotationMatrix(float2(radians(yaw+180.), radians(pitch))) * toCartesian(sphericalCoord); | |
dst = sampleLinear(src, toSpherical(cartesianCoord) / float2(TWOPI, PI) * (inputSize-float2(1.0))+float2(0.5)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment