Skip to content

Commit

Permalink
add panini projection (#288)
Browse files Browse the repository at this point in the history
  • Loading branch information
SArpnt authored Oct 20, 2024
1 parent eb6ff7b commit a097b8a
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 8 deletions.
5 changes: 3 additions & 2 deletions engine/client/render.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,12 @@ typedef enum {
typedef enum
{
PROJ_STANDARD = 0,
PROJ_STEREOGRAPHIC = 1, //aka panini
PROJ_STEREOGRAPHIC = 1,
PROJ_FISHEYE = 2, //standard fisheye
PROJ_PANORAMA = 3, //for nice panoramas
PROJ_LAEA = 4, //lambert azimuthal equal-area
PROJ_EQUIRECTANGULAR = 5 //projects a sphere into 2d. used by vr screenshots.
PROJ_EQUIRECTANGULAR = 5, //projects a sphere into 2d. used by vr screenshots.
PROJ_PANINI = 6 //like stereographic, but vertical lines stay straight.
} qprojection_t;

typedef struct {
Expand Down
2 changes: 1 addition & 1 deletion engine/client/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

#include <ctype.h> // for isdigit();

cvar_t r_projection = CVARD("r_projection", "0", "0: regular perspective.\n1: stereographic (aka: pannini).\n2: fisheye.\n3: panoramic.\n4: lambert azimuthal equal-area.\n5: Equirectangular");
cvar_t r_projection = CVARD("r_projection", "0", "0: regular perspective.\n1: stereographic.\n2: fisheye.\n3: panoramic.\n4: lambert azimuthal equal-area.\n5: equirectangular.\n6: panini.");
cvar_t ffov = CVARFD("ffov", "", 0, "Allows you to set a specific field of view for when a custom projection is specified. If empty, will use regular fov cvar, which might get messy.");
#if defined(_WIN32) && !defined(MINIMAL)
//amusing gimmick / easteregg.
Expand Down
20 changes: 20 additions & 0 deletions engine/gl/gl_rmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,26 @@ qboolean R_RenderScene_Cubemap(void)
}
#endif
break;
case PROJ_PANINI:
shader = R_RegisterShader("postproc_panini", SUF_NONE,
"{\n"
"program postproc_panini\n"
"{\n"
"map $sourcecube\n"
"}\n"
"}\n"
);

facemask |= 1<<4; /*front view*/
if (ffov.value > 70)
{
facemask |= (1<<0) | (1<<1); /*side/top*/
if (ffov.value > 85)
facemask |= (1<<2) | (1<<3); /*bottom views*/
if (ffov.value > 300)
facemask |= 1<<5; /*back view*/
}
break;
}

//FIXME: we should be able to rotate the view
Expand Down
2 changes: 1 addition & 1 deletion engine/shaders/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VKSDKPATH ?= ~/VulkanSDK/1.1.73.0/x86_64/bin/

all:

NAMES= fixedemu fixedemu_flat altwater bloom_blur bloom_filter bloom_final colourtint crepuscular_opaque crepuscular_rays crepuscular_sky depthonly default2d defaultadditivesprite defaultskin defaultsky defaultskybox defaultfill defaultsprite defaultwall defaultwarp defaultgammacb drawflat_wall lpp_depthnorm lpp_light lpp_wall postproc_fisheye postproc_panorama postproc_laea postproc_stereographic postproc_equirectangular fxaa underwaterwarp menutint terrain rtlight
NAMES= fixedemu fixedemu_flat altwater bloom_blur bloom_filter bloom_final colourtint crepuscular_opaque crepuscular_rays crepuscular_sky depthonly default2d defaultadditivesprite defaultskin defaultsky defaultskybox defaultfill defaultsprite defaultwall defaultwarp defaultgammacb drawflat_wall lpp_depthnorm lpp_light lpp_wall postproc_fisheye postproc_panorama postproc_laea postproc_stereographic postproc_equirectangular postproc_panini fxaa underwaterwarp menutint terrain rtlight


ALLNAMES+=$(foreach v,$(NAMES),glsl/$v.glsl)
Expand Down
1 change: 1 addition & 0 deletions engine/shaders/generatebuiltinsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ char shaders[][64] =
"postproc_laea",
"postproc_stereographic",
"postproc_equirectangular",
"postproc_panini",
"postproc_ascii",
"fxaa",
"underwaterwarp",
Expand Down
37 changes: 37 additions & 0 deletions engine/shaders/glsl/postproc_panini.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
!!cvarf ffov
!!samps screen:samplerCube=0

//panini view rendering, for high fovs that are still playable.

#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
varying vec2 texcoord;
uniform float cvar_ffov;
void main()
{
texcoord = v_texcoord.xy;

//make sure the ffov cvar actually does something meaningful
texcoord *= cvar_ffov / 90.0;

gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
varying vec2 texcoord;
void main()
{
vec3 tc;
vec2 d;
vec2 ang;
d = texcoord;

//compute the 2d->3d projection
float div = 1.0 + d.x*d.x + d.y*d.y;
tc.x = 2.0*d.x/div;
tc.y = -d.y;
tc.z = -(-1.0 + d.x*d.x + d.y*d.y)/div;

gl_FragColor = textureCube(s_screen, tc);
}
#endif
6 changes: 3 additions & 3 deletions engine/shaders/glsl/postproc_stereographic.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ void main()
varying vec2 texcoord;
void main()
{
vec3 tc;
vec2 d;
vec2 ang;
vec3 tc;
vec2 d;
vec2 ang;
d = texcoord;

//compute the 2d->3d projection
Expand Down
20 changes: 20 additions & 0 deletions engine/vk/vk_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2687,6 +2687,26 @@ static qboolean VK_R_RenderScene_Cubemap(struct vk_rendertarg *fb)
}
#endif
break;
case PROJ_PANINI:
shader = R_RegisterShader("postproc_panini", SUF_NONE,
"{\n"
"program postproc_panini\n"
"{\n"
"map $sourcecube\n"
"}\n"
"}\n"
);

facemask |= 1<<4; /*front view*/
if (ffov.value > 70)
{
facemask |= (1<<0) | (1<<1); /*side/top*/
if (ffov.value > 85)
facemask |= (1<<2) | (1<<3); /*bottom views*/
if (ffov.value > 300)
facemask |= 1<<5; /*back view*/
}
break;
}

if (!shader || !shader->prog)
Expand Down
3 changes: 2 additions & 1 deletion quakec/menusys/menu/options_effects.qc
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ nonstatic void(mitem_desktop desktop) M_Options_Effects =
)), fl, [0, pos], [0, 8]); pos += 8;
fr.add(menuitemcombo_spawn(_("View Projection"), "r_projection", '280 8', _(
"0 \"Standard\" "
"1 \"Stereographic / Pannini\" "
"1 \"Stereographic\" "
"2 \"Fish-Eye\" "
"3 \"Panoramic\" "
"4 \"Lambert Azimuthal Equal-Area\" "
"5 \"Equirectangular\" "
"6 \"Panini\" "
)), fl, [0, pos], [0, 8]); pos += 8;
fr.add(menuitemcombo_spawn(_("View Projection Fov"), "ffov", '280 8', _(
"90 \"Normal\" "
Expand Down

0 comments on commit a097b8a

Please sign in to comment.