Skip to content

Commit

Permalink
Renderer: Added a camera vignette effect
Browse files Browse the repository at this point in the history
In a physical camera lens, less light is received from the edges
of the image compared to the center, making the center appear
brighter. This is called "vignetting" and it can be used to enhance
the appearance of a frame by making it seem more natural and
to subtly help focus the eye on the center of the frame.

See: http://en.wikipedia.org/wiki/Vignetting

The renderer now draws a simple vignette by default. It can be
toggled on and off with "rend-vignette", and further configured
with "rend-vignette-darkness" and "rend-vignette-width".
  • Loading branch information
skyjake committed Jul 9, 2012
1 parent 687779b commit fe6b657
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 2 deletions.
Binary file added doomsday/engine/data/graphics/vignette.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions doomsday/engine/engine.pro
Expand Up @@ -313,6 +313,7 @@ DENG_HEADERS += \
portable/include/render/rend_shadow.h \
portable/include/render/rend_sky.h \
portable/include/render/rend_sprite.h \
portable/include/render/vignette.h \
portable/include/resourcenamespace.h \
portable/include/s_cache.h \
portable/include/s_environ.h \
Expand Down Expand Up @@ -600,6 +601,7 @@ SOURCES += \
portable/src/render/rend_shadow.c \
portable/src/render/rend_sky.c \
portable/src/render/rend_sprite.c \
portable/src/render/vignette.c \
portable/src/resourcenamespace.c \
portable/src/s_cache.c \
portable/src/s_environ.cpp \
Expand Down
1 change: 1 addition & 0 deletions doomsday/engine/portable/include/r_data.h
Expand Up @@ -263,6 +263,7 @@ typedef enum lightingtexid_e {
LST_RADIO_CC, // FakeRadio closed/closed corner shadow
LST_RADIO_OO, // FakeRadio open/open shadow
LST_RADIO_OE, // FakeRadio open/edge shadow
LST_CAMERA_VIGNETTE,
NUM_LIGHTING_TEXTURES
} lightingtexid_t;

Expand Down
49 changes: 49 additions & 0 deletions doomsday/engine/portable/include/render/vignette.h
@@ -0,0 +1,49 @@
/**
* @file vignette.h
* Renders a vignette for the player view. @ingroup render
*
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#ifndef LIBDENG_RENDER_VIGNETTE_H
#define LIBDENG_RENDER_VIGNETTE_H

#include "rect.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* Initializes the vignette rendering module. This includes registering console
* commands.
*/
void Vignette_Register(void);

/**
* Renders the vignette for the player's view.
*
* @param viewRect View window where to draw the vignette.
* @param fov Current horizontal FOV angle (degrees).
*/
void Vignette_Render(const RectRaw* viewRect, float fov);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // LIBDENG_RENDER_VIGNETTE_H
7 changes: 5 additions & 2 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -1326,6 +1326,7 @@ void GL_LoadSystemTextures(void)
// Preload lighting system textures.
GL_PrepareLSTexture(LST_DYNAMIC);
GL_PrepareLSTexture(LST_GRADIENT);
GL_PrepareLSTexture(LST_CAMERA_VIGNETTE);

GL_PrepareSysFlareTexture(FXT_ROUND);
GL_PrepareSysFlareTexture(FXT_FLARE);
Expand Down Expand Up @@ -2162,14 +2163,16 @@ DGLuint GL_PrepareLSTexture(lightingtexid_t which)
{ "radioCO", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE },
{ "radioCC", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE },
{ "radioOO", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE },
{ "radioOE", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE }
{ "radioOE", GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE },
{ "vignette", GL_REPEAT, GL_CLAMP_TO_EDGE }
};

if(novideo || which < 0 || which >= NUM_LIGHTING_TEXTURES) return 0;

if(!lightingTextures[which].tex)
{
lightingTextures[which].tex = GL_PrepareExtTexture(lstexes[which].name, LGM_WHITE_ALPHA,
lightingTextures[which].tex = GL_PrepareExtTexture(lstexes[which].name,
which == LST_CAMERA_VIGNETTE? LGM_NORMAL : LGM_WHITE_ALPHA,
false, GL_LINEAR, GL_LINEAR, -1 /*best anisotropy*/, lstexes[which].wrapS,
lstexes[which].wrapT, TXCF_NO_COMPRESSION);
}
Expand Down
3 changes: 3 additions & 0 deletions doomsday/engine/portable/src/r_main.c
Expand Up @@ -48,6 +48,7 @@
#include "de_ui.h"

#include "font.h"
#include "vignette.h"

// MACROS ------------------------------------------------------------------

Expand Down Expand Up @@ -1160,6 +1161,8 @@ void R_RenderPlayerView(int num)
GL_DrawFilter();
}

Vignette_Render(&vd->window, fieldOfView);

// Now we can show the viewPlayer's mobj again.
if(!(player->shared.flags & DDPF_CHASECAM))
player->shared.mo->ddFlags = oldFlags;
Expand Down
2 changes: 2 additions & 0 deletions doomsday/engine/portable/src/render/rend_main.c
Expand Up @@ -42,6 +42,7 @@
#include "texturevariant.h"
#include "materialvariant.h"
#include "blockmapvisual.h"
#include "vignette.h"

// Surface (tangent-space) Vector Flags.
#define SVF_TANGENT 0x01
Expand Down Expand Up @@ -194,6 +195,7 @@ void Rend_Register(void)
Rend_RadioRegister();
Rend_SpriteRegister();
Rend_ConsoleRegister();
Vignette_Register();
}

/**
Expand Down
96 changes: 96 additions & 0 deletions doomsday/engine/portable/src/render/vignette.c
@@ -0,0 +1,96 @@
/**
* @file vignette.c
* Renders a vignette for the player view. @ingroup render
*
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/

#include "de_base.h"
#include "de_console.h"
#include "de_graphics.h"
#include "m_vector.h"
#include <math.h>

static byte vignetteEnabled = true;
static float vignetteDarkness = 1.0f;
static float vignetteWidth = 1.0f;

void Vignette_Register(void)
{
C_VAR_BYTE ("rend-vignette", &vignetteEnabled, 0, 0, 1);
C_VAR_FLOAT("rend-vignette-darkness", &vignetteDarkness, CVF_NO_MAX, 0, 0);
C_VAR_FLOAT("rend-vignette-width", &vignetteWidth, 0, 0, 2);
}

void Vignette_Render(const RectRaw* viewRect, float fov)
{
const int DIVS = 60;
vec2f_t vec;
float cx, cy, outer, inner;
float alpha;
int i;

if(!vignetteEnabled) return;

// Center point.
cx = viewRect->origin.x + viewRect->size.width/2;
cy = viewRect->origin.y + viewRect->size.height/2;

// Radius.
V2f_Set(vec, viewRect->size.width/2, viewRect->size.height/2);
outer = V2f_Length(vec) + 1; // Extra pixel to account for a possible gap.
if(fov < 100)
{
// Small FOV angles cause the vignette to be thinner/lighter.
outer *= (1 + 100.f/fov) / 2;
}
inner = outer * vignetteWidth * .4f;
if(fov > 100)
{
// High FOV angles cause the vignette to be wider.
inner *= 100.f/fov;
}

alpha = vignetteDarkness * .5f;
if(fov > 100)
{
// High FOV angles cause the vignette to be darker.
alpha *= fov/100.f;
}

GL_BindTextureUnmanaged(GL_PrepareLSTexture(LST_CAMERA_VIGNETTE), GL_LINEAR);
glEnable(GL_TEXTURE_2D);

glBegin(GL_TRIANGLE_STRIP);
for(i = 0; i <= DIVS; ++i)
{
float ang = (float)(2 * PI * i) / (float)DIVS;
float dx = cos(ang);
float dy = sin(ang);

glColor4f(0, 0, 0, alpha);
glTexCoord2f(0, 1);
glVertex2f(cx + outer * dx, cy + outer * dy);

glColor4f(0, 0, 0, 0);
glTexCoord2f(0, 0);
glVertex2f(cx + inner * dx, cy + inner * dy);
}
glEnd();

glDisable(GL_TEXTURE_2D);
}

0 comments on commit fe6b657

Please sign in to comment.