distortion correction - conformal perspective
- Tojkar
Would it be possible to add a fourth mode, which removes the curvature effect but makes the distances smaller towards the edges? Similar to the Photoshop effect spherize distortion added both horizontally and vertically.Fu-Bama wrote: Perfect Perspective FX has drop down menu where you can choose 3 modes. Diagonal aligns the image to the corners of the screen, leaving no black space.
Image for clarification of what I mean: www.dropbox.com/s/y49408xvixm7nsm/Untitled-1.png?dl=0
Please Log in or Create an account to join the conversation.
Same effect applied to diagonal checker gives curved distortion (just rotate image 45 degrees and apply effect). Also it does not fix proportions, but makes objects disproportional in XY axis. Look at the squares at the edges, they are not smaller but rectangular.Tojkar wrote: Would it be possible to add a fourth mode, which removes the curvature effect but makes the distances smaller towards the edges? Similar to the Photoshop effect spherize distortion added both horizontally and vertically.
Image for clarification of what I mean: www.dropbox.com/s/y49408xvixm7nsm/Untitled-1.png?dl=0
Please Log in or Create an account to join the conversation.
- Tojkar
Please Log in or Create an account to join the conversation.
/*
Copyright (c) 2018 Jacob Maximilian Fober
This work is licensed under the Creative Commons
Attribution-ShareAlike 4.0 International License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/4.0/.
*/
// PerspTest PS
////////////////////
/////// MENU ///////
////////////////////
uniform float Strength <
ui_type = "drag";
ui_min = 0.0; ui_max = 1.0;
> = 0.5;
//////////////////////
/////// SHADER ///////
//////////////////////
#include "ReShade.fxh"
float Overlay(float coord)
{
float a = max(coord, 0.5) * 2.0 - 1.0;
a *= a;
a *= 0.5;
float b = 1.0 - min(coord, 0.5) * 2.0;
b *= b;
b = 1.0 - b;
b *= 0.5;
return a + b;
}
float3 PerspTestPS(float4 vois : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
// Get Aspect Ratio
float AspectR = ReShade::AspectRatio;
// Distortion correction amount
float2 SphCoord = lerp(texcoord, float2(Overlay(texcoord.x), Overlay(texcoord.y)), Strength);
// Sample display image
float3 Display = tex2D(ReShade::BackBuffer, SphCoord).rgb;
return Display;
}
technique PerspTest
{
pass
{
VertexShader = PostProcessVS;
PixelShader = PerspTestPS;
}
}
Please Log in or Create an account to join the conversation.
- Tojkar
Again, image for clarification. The first is in-game shader with value 1.0 where you can clearly see the extreme stretching on the center. Next is edited in PS. Here you can see the strenth of the effect gradually increases and the center is quite clean looking despite using max values and applying the effect multiple times. Third one shown unedited picture for reference. The lines are nearly the same as in the screenshot. www.dropbox.com/s/9ja7br3w7zm2q6m/GRW%20...%2012-32-20.png?dl=0
Please Log in or Create an account to join the conversation.
Verticals and Horizontals are straight, but Diagonals are stretched. It does not work.
here's proof:
/*
Copyright (c) 2018 Jacob Maximilian Fober
This work is licensed under the Creative Commons
Attribution-ShareAlike 4.0 International License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-sa/4.0/.
*/
// Perspective Test PS
////////////////////
/////// MENU ///////
////////////////////
uniform float Strength <
ui_tooltip = "Distortion scale. 0 is Linear perspective and 1 is LSD trip.";
ui_type = "drag";
ui_min = 0.0; ui_max = 1.0;
> = 1.0;
uniform float3 Color <
ui_label = "Background Color";
ui_type = "Color";
> = float3(0.027, 0.027, 0.027);
uniform int FOV <
ui_label = "Field of View";
ui_tooltip = "In-game horizontal Field of View";
ui_type = "drag";
ui_min = 60; ui_max = 110;
> = 90;
uniform int Type <
ui_label = "Type of alignment";
ui_type = "combo";
ui_items = "horizontal\0vertical\0";
> = 1;
//////////////////////
/////// SHADER ///////
//////////////////////
#include "ReShade.fxh"
float3 PerspectiveTestPS(float4 vois : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
// Convert FOV to half-radians and calc cotangent
float ctanFOVh = radians(FOV * 0.5);
ctanFOVh = cos(ctanFOVh) / sin(ctanFOVh);
// Get Aspect Ratio
float AspectR = ReShade::AspectRatio;
float Edge;
float2 SphCoord = texcoord;
// Horizontal
if (Type == 0)
{
Edge = 1.0;
}
// Vertical
else
{
Edge = 1.0 / AspectR;
}
// Convert UV to Radial Coordinates
SphCoord = SphCoord * 2.0 - 1.0;
// Aspect Ratio correction
SphCoord.y /= AspectR;
// Wierd transform
SphCoord.x *=
(ctanFOVh + length( float2(SphCoord.x, ctanFOVh) ))
/
(ctanFOVh + length( float2(Edge, ctanFOVh) ))
;
SphCoord.y *=
(ctanFOVh + length( float2(SphCoord.y, ctanFOVh) ))
/
(ctanFOVh + length( float2(Edge, ctanFOVh) ))
;
// Aspect Ratio back to square
SphCoord.y *= AspectR;
// Back to UV Coordinates
SphCoord = (SphCoord + 1.0) * 0.5;
// Distortion correction amount
SphCoord = lerp(texcoord, SphCoord, Strength);
// Sample display image
float3 Display = tex2D(ReShade::BackBuffer, SphCoord).rgb;
// Mask out outside-border pixels
if (SphCoord.x < 1.0 && SphCoord.x > 0.0 && SphCoord.y < 1.0 && SphCoord.y > 0.0)
{
return Display;
}
else
{
return Color;
}
}
technique PerspectiveTest
{
pass
{
VertexShader = PostProcessVS;
PixelShader = PerspectiveTestPS;
}
}
Please Log in or Create an account to join the conversation.
- Tojkar
I am fully aware of that and wasn't trying to argue. Also, one reason which I didn't state yet for this request is that I love the old lo-fi monitors, which curves the picture due to their physical properties, but I equally hate the black borders and corners. I was trying to modify some existing shaders which has the fisheye effect included, but I never managed to succeed. That being said...Fu-Bama wrote: @Tojkar It's wierd AF in movement.
Verticals and Horizontals are straight, but Diagonals are stretched. It does not work.
here's proof
...now I see what my mistake was. I meant to say that the edges need very strong compressing but the strength quickly falls off so that instead of stretching the middle axises unrecognizeably.
I have hard time finding a way to explain this in my own laguage, so again I must resort to pictures. The upper half is what I'm trying to explain and lower half is what your shader currently does. The stretching curve is linear in your shader versus logarithmic/expotential in the upper half. www.dropbox.com/s/y49408xvixm7nsm/Untitled-1.png?dl=0
Also, my request might not completely be in the scope of your plans, so if you wan't I could make a new thread for this. Just say so.
Please Log in or Create an account to join the conversation.
- Insomnia
But with these I can get perspective correction like in those Star Wars pictures, or like in Resident Evil 7. It will however make the centre a bit blurry depending on the zoom settings, but that's unavoidable. I don't know if this might be something you are interested in, but I figured you might want to check it out nevertheless.
Fisheye Horizontal
/*
Credits :: icelaglace, a.o => (ported from some blog, author unknown)
Credits :: Pascal aka Marty McFly
Amateur port by Insomnia
*/
uniform float fFisheyeZoom <
ui_type = "drag";
ui_min = 0.5; ui_max = 1.0;
ui_label = "Fish Eye Zoom";
ui_tooltip = "Lens zoom to hide bugged edges due to texcoord modification";
> = 0.55;
uniform float fFisheyeDistortion <
ui_type = "drag";
ui_min = -0.300; ui_max = 0.300;
ui_label = "Fisheye Distortion";
ui_tooltip = "Distortion of image";
> = 0.01;
uniform float fFisheyeDistortionCubic <
ui_type = "drag";
ui_min = -0.300; ui_max = 0.300;
ui_label = "Fisheye Distortion Cubic";
ui_tooltip = "Distortion of image, cube based";
> = 0.7;
uniform float fFisheyeColorshift <
ui_type = "drag";
ui_min = -0.10; ui_max = 0.10;
ui_label = "Colorshift";
ui_tooltip = "Amount of color shifting";
> = 0.002;
#include "ReShade.fxh"
float3 FISHEYE_CAPass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb;
float4 coord=0.0;
coord.xy=texcoord.xy;
coord.w=0.0;
color.rgb = 0.0;
float3 eta = float3(1.0+fFisheyeColorshift*0.9,1.0+fFisheyeColorshift*0.6,1.0+fFisheyeColorshift*0.3);
float2 center;
center.x = coord.x-0.5;
center.y = coord.y-0.5;
float LensZoom = 1.0/fFisheyeZoom;
float r2 = (texcoord.y-0.5) * (texcoord.y-0.5);// + (texcoord.y-0.5) * (texcoord.y-0.5);
float f = 0;
if( fFisheyeDistortionCubic == 0.0){
f = 1 + r2 * fFisheyeDistortion;
}else{
f = 1 + r2 * (fFisheyeDistortion + fFisheyeDistortionCubic * sqrt(r2));
};
float x = f*LensZoom*(coord.x-0.5)+0.5;
float y = f*LensZoom*(coord.y-0.5)+0.5;
float2 rCoords = (f*eta.r)*LensZoom*(center.xy*0.5)+0.5;
float2 gCoords = (f*eta.g)*LensZoom*(center.xy*0.5)+0.5;
float2 bCoords = (f*eta.b)*LensZoom*(center.xy*0.5)+0.5;
color.x = tex2D(ReShade::BackBuffer,rCoords).r;
color.y = tex2D(ReShade::BackBuffer,gCoords).g;
color.z = tex2D(ReShade::BackBuffer,bCoords).b;
return color.rgb;
}
technique FISHEYE_CA_HORIZONTAL
{
pass
{
VertexShader = PostProcessVS;
PixelShader = FISHEYE_CAPass;
}
}
Fisheye Vertical
/*
Credits :: icelaglace, a.o => (ported from some blog, author unknown)
Credits :: Pascal aka Marty McFly
Amateur port by Insomnia
*/
uniform float fFisheyeZoom <
ui_type = "drag";
ui_min = 0.5; ui_max = 1.0;
ui_label = "Fish Eye Zoom";
ui_tooltip = "Lens zoom to hide bugged edges due to texcoord modification";
> = 0.55;
uniform float fFisheyeDistortion <
ui_type = "drag";
ui_min = -0.300; ui_max = 0.300;
ui_label = "Fisheye Distortion";
ui_tooltip = "Distortion of image";
> = 0.01;
uniform float fFisheyeDistortionCubic <
ui_type = "drag";
ui_min = -0.300; ui_max = 0.300;
ui_label = "Fisheye Distortion Cubic";
ui_tooltip = "Distortion of image, cube based";
> = 0.7;
uniform float fFisheyeColorshift <
ui_type = "drag";
ui_min = -0.10; ui_max = 0.10;
ui_label = "Colorshift";
ui_tooltip = "Amount of color shifting";
> = 0.002;
#include "ReShade.fxh"
float3 FISHEYE_CAPass(float4 position : SV_Position, float2 texcoord : TexCoord) : SV_Target
{
float3 color = tex2D(ReShade::BackBuffer, texcoord).rgb;
float4 coord=0.0;
coord.xy=texcoord.xy;
coord.w=0.0;
color.rgb = 0.0;
float3 eta = float3(1.0+fFisheyeColorshift*0.9,1.0+fFisheyeColorshift*0.6,1.0+fFisheyeColorshift*0.3);
float2 center;
center.x = coord.x-0.5;
center.y = coord.y-0.5;
float LensZoom = 1.0/fFisheyeZoom;
float r2 = (texcoord.x-0.5) * (texcoord.x-0.5);// + (texcoord.y-0.5) * (texcoord.y-0.5);
float f = 0;
if( fFisheyeDistortionCubic == 0.0){
f = 1 + r2 * fFisheyeDistortion;
}else{
f = 1 + r2 * (fFisheyeDistortion + fFisheyeDistortionCubic * sqrt(r2));
};
float x = f*LensZoom*(coord.x-0.5)+0.5;
float y = f*LensZoom*(coord.y-0.5)+0.5;
float2 rCoords = (f*eta.r)*LensZoom*(center.xy*0.5)+0.5;
float2 gCoords = (f*eta.g)*LensZoom*(center.xy*0.5)+0.5;
float2 bCoords = (f*eta.b)*LensZoom*(center.xy*0.5)+0.5;
color.x = tex2D(ReShade::BackBuffer,rCoords).r;
color.y = tex2D(ReShade::BackBuffer,gCoords).g;
color.z = tex2D(ReShade::BackBuffer,bCoords).b;
return color.rgb;
}
technique FISHEYE_CA_VERTICAL
{
pass
{
VertexShader = PostProcessVS;
PixelShader = FISHEYE_CAPass;
}
}
Example pics with the shaders:
Please Log in or Create an account to join the conversation.
- Marty McFly
Please Log in or Create an account to join the conversation.
Star Wars pictures were made with Panavision anamorphic lenses which tend to bend horizontal lines more than vertical.
This comes out from very specific reason. Dominant movement in movies is camera pan and its mostly level to the ground, so vertical distortion is not needed so much.
In games there's also a lot of camera panning, when you look at horizon and turn mouse left and right. But when you look up or down there's camera roll movement.
Which in panini-like distortion looks unpleasant. In movies, they would switch to spherical lenses in such case, with even vertical and horizontal distortion.
Unfortunately without access to camera direction vector in world space, it's impossible to adjust vertical distortion on the fly.
I experimented a lot with this and stereographic distortion is best suited for this case.
Beside, Panavision lenses do much more then that. They have breathing effect when changing focus, thus driving viewer attention on focused objects.
vimeo.com/167045643
Duble vision blur which makes out of focus objects unrecognizable.
vimeo.com/167050590
And famous horizontal lens flares.
vimeo.com/167045648
Please Log in or Create an account to join the conversation.
- Insomnia
Marty McFly wrote: I never wrote this shader, ported it from some blog. IIRC it follows standard lens correction model, so it's not viable to use it for this purpose.
Sorry. I did noticed the name Icelaglace in the credits though. You want me to change the credits info?
Please Log in or Create an account to join the conversation.
- Marty McFly
Please Log in or Create an account to join the conversation.
I made another workaround for games that don't draw their own cursor.Martigen wrote: This is a really awesome shader Just one problem: as it bends the whole screen, when interacting with in-game menus or game inventories the visible button for a is of course now off-center, making it sometimes impossible to use menus or inventories, as where you click for the corrected perspective is of course not where the game is needing to register the click on screen. It can't be helped really, as we're bending the image without considering the interface. (...)
Cursor.fx that you can put before perspective correction
drive.google.com/file/d/1n8bPOvnYhxjY95x...5mn/view?usp=sharing
Please Log in or Create an account to join the conversation.
- Martigen
Great I'll try this!Fu-Bama wrote:
I made another workaround for games that don't draw their own cursor.Martigen wrote: This is a really awesome shader Just one problem: as it bends the whole screen, when interacting with in-game menus or game inventories the visible button for a is of course now off-center, making it sometimes impossible to use menus or inventories, as where you click for the corrected perspective is of course not where the game is needing to register the click on screen. It can't be helped really, as we're bending the image without considering the interface. (...)
Cursor.fx that you can put before perspective correction
drive.google.com/file/d/1n8bPOvnYhxjY95x...5mn/view?usp=sharing
Thanks
Please Log in or Create an account to join the conversation.
- Martigen
So this works perfectly, the cursor is exactly aligned with the curved interface. Great!Fu-Bama wrote:
I made another workaround for games that don't draw their own cursor.Martigen wrote: This is a really awesome shader Just one problem: as it bends the whole screen, when interacting with in-game menus or game inventories the visible button for a is of course now off-center, making it sometimes impossible to use menus or inventories, as where you click for the corrected perspective is of course not where the game is needing to register the click on screen. It can't be helped really, as we're bending the image without considering the interface. (...)
Cursor.fx that you can put before perspective correction
drive.google.com/file/d/1n8bPOvnYhxjY95x...5mn/view?usp=sharing
Not so great, the cursor is always visible So it's there on screen moving around when playing -- example:
steamcommunity.com/sharedfiles/filedetails/?id=1293415498
I guess we can assign a hotkey to cursor.fx. Ideally, this should be the key that brings up the interface. One problem here: this key for a lot of games is ESC, but Reshade won't let you assign ESC as a key for a shader. I think it would have to be coded in, but it will differ for different games. Also, there may be multiple interfaces -- main menu, inventory, skill tree etc depending on the game, needing multiple keys... I don't think there's an easy solution, except intercepting the UI and not having it curved. I don't think this is possible with Reshade unless we have a way to easily determine the injection point on each game.
But thankyou for your work!
Please Log in or Create an account to join the conversation.
- crosire
Haven't tried this, but technically ESC should work. You just can't bind it via the in-game UI, but have to manually set it in the preset file. The keycode for ESC is 27.Martigen wrote: One problem here: this key for a lot of games is ESC, but Reshade won't let you assign ESC as a key for a shader. I think it would have to be coded in, but it will differ for different games.
Please Log in or Create an account to join the conversation.
- brussell
I've written a shader that toggles effects depending on HUD visibility. It's not really sophisticated though, but it gets the job done. It just checks if certain pixels on the screen matches with that from a hud layer. I will post it here soon. Maybe it's useful for you too.
Please Log in or Create an account to join the conversation.
- Martigen
That does sound useful, thank you.brussell wrote: @Martigen
I've written a shader that toggles effects depending on HUD visibility. It's not really sophisticated though, but it gets the job done. It just checks if certain pixels on the screen matches with that from a hud layer. I will post it here soon. Maybe it's useful for you too.
Does it handle multiple 'huds' - i.e difference between a main menu or an in-game inventory? I imagine it depends on the layout of the hud and recognised pixels.
Please Log in or Create an account to join the conversation.
- brussell
Yes. In short: HudDetected == (Hud1Pixel1 && Hud1Pixel2) || (Hud2Pixel1 && Hud2Pixel2 && Hud2Pixel3 && ...) || ...Martigen wrote: Does it handle multiple 'huds' - i.e difference between a main menu or an in-game inventory? I imagine it depends on the layout of the hud and recognised pixels.
Please Log in or Create an account to join the conversation.
- Martigen
Nice! Where's the shader?brussell wrote:
Yes. In short: HudDetected == (Hud1Pixel1 && Hud1Pixel2) || (Hud2Pixel1 && Hud2Pixel2 && Hud2Pixel3 && ...) || ...Martigen wrote: Does it handle multiple 'huds' - i.e difference between a main menu or an in-game inventory? I imagine it depends on the layout of the hud and recognised pixels.
Please Log in or Create an account to join the conversation.