- Calculate globvis/r_visibility in r_utility and use it in GL and poly renderers

This commit is contained in:
Magnus Norddahl 2017-07-09 19:01:34 +02:00
parent c8e713b067
commit ddd1b629c3
17 changed files with 102 additions and 59 deletions

View file

@ -151,6 +151,8 @@ public:
float mSceneClearColor[3]; float mSceneClearColor[3];
float mGlobVis = 0.0f;
FGLRenderer(OpenGLFrameBuffer *fb); FGLRenderer(OpenGLFrameBuffer *fb);
~FGLRenderer() ; ~FGLRenderer() ;

View file

@ -151,6 +151,7 @@ bool FRenderState::ApplyShader()
activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muDesaturation.Set(mDesaturation / 255.f);
activeShader->muFogEnabled.Set(fogset); activeShader->muFogEnabled.Set(fogset);
activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8)); activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8));
activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f);
activeShader->muTextureMode.Set(mTextureMode); activeShader->muTextureMode.Set(mTextureMode);
activeShader->muCameraPos.Set(mCameraPos.vec); activeShader->muCameraPos.Set(mCameraPos.vec);
activeShader->muLightParms.Set(mLightParms); activeShader->muLightParms.Set(mLightParms);

View file

@ -83,7 +83,7 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
EXTERN_CVAR (Bool, cl_capfps) EXTERN_CVAR (Bool, cl_capfps)
EXTERN_CVAR (Bool, r_deathcamera) EXTERN_CVAR (Bool, r_deathcamera)
EXTERN_CVAR (Float, underwater_fade_scalar) EXTERN_CVAR (Float, underwater_fade_scalar)
EXTERN_CVAR (Float, r_visibility)
extern bool NoInterpolateView; extern bool NoInterpolateView;
@ -785,6 +785,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f
R_SetupFrame (r_viewpoint, r_viewwindow, camera); R_SetupFrame (r_viewpoint, r_viewwindow, camera);
SetViewArea(); SetViewArea();
GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility);
// We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1.
double radPitch = r_viewpoint.Angles.Pitch.Normalized180().Radians(); double radPitch = r_viewpoint.Angles.Pitch.Normalized180().Radians();
double angx = cos(radPitch); double angx = cos(radPitch);

View file

@ -227,6 +227,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
muDesaturation.Init(hShader, "uDesaturationFactor"); muDesaturation.Init(hShader, "uDesaturationFactor");
muFogEnabled.Init(hShader, "uFogEnabled"); muFogEnabled.Init(hShader, "uFogEnabled");
muPalLightLevels.Init(hShader, "uPalLightLevels"); muPalLightLevels.Init(hShader, "uPalLightLevels");
muGlobVis.Init(hShader, "uGlobVis");
muTextureMode.Init(hShader, "uTextureMode"); muTextureMode.Init(hShader, "uTextureMode");
muCameraPos.Init(hShader, "uCameraPos"); muCameraPos.Init(hShader, "uCameraPos");
muLightParms.Init(hShader, "uLightAttr"); muLightParms.Init(hShader, "uLightAttr");

View file

@ -260,6 +260,7 @@ class FShader
FBufferedUniform1f muDesaturation; FBufferedUniform1f muDesaturation;
FBufferedUniform1i muFogEnabled; FBufferedUniform1i muFogEnabled;
FBufferedUniform1i muPalLightLevels; FBufferedUniform1i muPalLightLevels;
FBufferedUniform1f muGlobVis;
FBufferedUniform1i muTextureMode; FBufferedUniform1i muTextureMode;
FBufferedUniform4f muCameraPos; FBufferedUniform4f muCameraPos;
FBufferedUniform4f muLightParms; FBufferedUniform4f muLightParms;

View file

@ -40,6 +40,7 @@
EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Bool, r_shadercolormaps)
EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Int, screenblocks)
EXTERN_CVAR(Float, r_visibility)
void InitGLRMapinfoData(); void InitGLRMapinfoData();
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -122,6 +123,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps; if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps;
else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend; else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend;
Light.SetVisibility(Viewwindow, r_visibility);
PolyCameraLight::Instance()->SetCamera(Viewpoint, RenderTarget, actor); PolyCameraLight::Instance()->SetCamera(Viewpoint, RenderTarget, actor);
//Viewport->SetupFreelook(); //Viewport->SetupFreelook();

View file

@ -27,6 +27,11 @@
#include "poly_light.h" #include "poly_light.h"
#include "polyrenderer/poly_renderer.h" #include "polyrenderer/poly_renderer.h"
void PolyLightVisibility::SetVisibility(FViewWindow &viewwindow, float vis)
{
GlobVis = R_GetGlobVis(viewwindow, vis);
}
fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
{ {
bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE));
@ -42,8 +47,3 @@ fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128)); return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128));
} }
} }
double PolyLightVisibility::FocalTangent()
{
return PolyRenderer::Instance()->Viewwindow.FocalTangent;
}

View file

@ -24,6 +24,8 @@
#include "swrenderer/scene/r_light.h" #include "swrenderer/scene/r_light.h"
struct FViewWindow;
// Keep using the software renderer's camera light class, for now. // Keep using the software renderer's camera light class, for now.
// The DFrameBuffer abstraction relies on this being globally shared // The DFrameBuffer abstraction relies on this being globally shared
typedef swrenderer::CameraLight PolyCameraLight; typedef swrenderer::CameraLight PolyCameraLight;
@ -31,9 +33,11 @@ typedef swrenderer::CameraLight PolyCameraLight;
class PolyLightVisibility class PolyLightVisibility
{ {
public: public:
double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); } void SetVisibility(FViewWindow &viewwindow, float vis);
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); }
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility * 0.5 / FocalTangent(); } double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis; }
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis; }
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis * 0.5; }
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; }
@ -43,9 +47,6 @@ public:
static fixed_t LightLevelToShade(int lightlevel, bool foggy); static fixed_t LightLevelToShade(int lightlevel, bool foggy);
private: private:
static double FocalTangent(); double GlobVis = 0.0f;
// 1706 is the value for walls on 1080p 16:9 displays.
double WallVisibility = 1706.0;
bool NoLightFade = false; bool NoLightFade = false;
}; };

View file

@ -54,9 +54,6 @@ struct FRenderer
virtual void CleanLevelData() {} virtual void CleanLevelData() {}
virtual bool RequireGLNodes() { return false; } virtual bool RequireGLNodes() { return false; }
virtual double GetVisibility() { return 8.f; }
virtual void SetVisibility(double vis) { }
}; };

View file

@ -278,6 +278,77 @@ void R_ExecuteSetViewSize (FRenderViewpoint &viewpoint, FViewWindow &viewwindow)
viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (StatusBar->GetTopOfStatusbar() - viewheight) >> 1; viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (StatusBar->GetTopOfStatusbar() - viewheight) >> 1;
} }
//==========================================================================
//
// r_visibility
//
// Controls how quickly light ramps across a 1/z range.
//
//==========================================================================
double R_ClampVisibility(double vis)
{
// Allow negative visibilities, just for novelty's sake
return clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio)
}
CUSTOM_CVAR(Float, r_visibility, 8.0f, CVAR_NOINITCALL)
{
if (netgame && self != 8.0f)
{
Printf("Visibility cannot be changed in net games.\n");
self = 8.0f;
}
else
{
float clampValue = (float)R_ClampVisibility(self);
if (self != clampValue)
self = clampValue;
}
}
//==========================================================================
//
// R_GetGlobVis
//
// Calculates the global visibility constant used by the software renderer
//
//==========================================================================
double R_GetGlobVis(const FViewWindow &viewwindow, double vis)
{
vis = R_ClampVisibility(vis);
double virtwidth = screen->GetWidth();
double virtheight = screen->GetHeight();
if (AspectTallerThanWide(viewwindow.WidescreenRatio))
{
virtheight = (virtheight * AspectMultiplier(viewwindow.WidescreenRatio)) / 48;
}
else
{
virtwidth = (virtwidth * AspectMultiplier(viewwindow.WidescreenRatio)) / 48;
}
double YaspectMul = 320.0 * virtheight / (200.0 * virtwidth);
double InvZtoScale = YaspectMul * viewwindow.centerx;
double wallVisibility = vis;
// Prevent overflow on walls
double maxVisForWall = (InvZtoScale * (screen->GetWidth() * r_Yaspect) / (viewwidth * screen->GetHeight() * viewwindow.FocalTangent));
maxVisForWall = 32767.0 / maxVisForWall;
if (vis < 0 && vis < -maxVisForWall)
wallVisibility = -maxVisForWall;
else if (vis > 0 && vis > maxVisForWall)
wallVisibility = maxVisForWall;
wallVisibility = InvZtoScale * screen->GetWidth() * AspectBaseHeight(viewwindow.WidescreenRatio) / (viewwidth * screen->GetHeight() * 3) * (wallVisibility * viewwindow.FocalTangent);
return wallVisibility / viewwindow.FocalTangent;
}
//========================================================================== //==========================================================================
// //
// CVAR screenblocks // CVAR screenblocks

View file

@ -122,6 +122,8 @@ void R_ExecuteSetViewSize (FRenderViewpoint &viewpoint, FViewWindow &viewwindow)
void R_SetViewSize (int blocks); void R_SetViewSize (int blocks);
void R_SetWindow (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false); void R_SetWindow (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false);
double R_GetGlobVis(const FViewWindow &viewwindow, double vis);
double R_ClampVisibility(double vis);
extern void R_FreePastViewers (); extern void R_FreePastViewers ();
extern void R_ClearPastViewer (AActor *actor); extern void R_ClearPastViewer (AActor *actor);

View file

@ -378,14 +378,3 @@ void FSoftwareRenderer::PreprocessLevel()
void FSoftwareRenderer::CleanLevelData() void FSoftwareRenderer::CleanLevelData()
{ {
} }
double FSoftwareRenderer::GetVisibility()
{
return mScene.MainThread()->Light->GetVisibility();
}
void FSoftwareRenderer::SetVisibility(double vis)
{
mScene.MainThread()->Light->SetVisibility(mScene.MainThread()->Viewport.get(), vis);
}

View file

@ -35,9 +35,6 @@ struct FSoftwareRenderer : public FRenderer
void PreprocessLevel() override; void PreprocessLevel() override;
void CleanLevelData() override; void CleanLevelData() override;
double GetVisibility() override;
void SetVisibility(double vis) override;
private: private:
void PrecacheTexture(FTexture *tex, int cache); void PrecacheTexture(FTexture *tex, int cache);

View file

@ -104,8 +104,7 @@ namespace swrenderer
// Changes how rapidly things get dark with distance // Changes how rapidly things get dark with distance
void LightVisibility::SetVisibility(RenderViewport *viewport, double vis) void LightVisibility::SetVisibility(RenderViewport *viewport, double vis)
{ {
// Allow negative visibilities, just for novelty's sake vis = R_ClampVisibility(vis);
vis = clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio)
CurrentVisibility = vis; CurrentVisibility = vis;
@ -167,25 +166,6 @@ namespace swrenderer
} }
} }
// Controls how quickly light ramps across a 1/z range. Set this, and it
// sets all the r_*Visibility variables (except r_SkyVisibilily, which is
// currently unused).
CCMD(r_visibility)
{
if (argv.argc() < 2)
{
Printf("Visibility is %g\n", Renderer->GetVisibility());
}
else if (!netgame)
{
Renderer->SetVisibility(atof(argv[1]));
}
else
{
Printf("Visibility cannot be changed in net games.\n");
}
}
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
void ColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack) void ColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack)

View file

@ -46,6 +46,8 @@
CVAR(String, r_viewsize, "", CVAR_NOSET) CVAR(String, r_viewsize, "", CVAR_NOSET)
EXTERN_CVAR(Float, r_visibility);
namespace swrenderer namespace swrenderer
{ {
RenderViewport::RenderViewport() RenderViewport::RenderViewport()
@ -109,7 +111,7 @@ namespace swrenderer
InitTextureMapping(); InitTextureMapping();
// Reset r_*Visibility vars // Reset r_*Visibility vars
thread->Light->SetVisibility(this, thread->Light->GetVisibility()); thread->Light->SetVisibility(this, r_visibility);
SetupBuffer(); SetupBuffer();
} }

View file

@ -103,12 +103,6 @@ vec4 getTexel(vec2 st)
//=========================================================================== //===========================================================================
float R_DoomLightingEquation(float light) float R_DoomLightingEquation(float light)
{ {
// globVis = WallVisibility / r_viewwindow.FocalTangent / 32.0
//
// WallVisibility is calculated in LightVisibility::SetVisibility
// 1706 is the default value for WallVisibility on 1080p 16:9 displays.
float globVis = 1706.0 / 1.3333333333333333 / 32.0;
// L is the integer light level used in the game // L is the integer light level used in the game
float L = light * 255.0; float L = light * 255.0;
@ -124,7 +118,7 @@ float R_DoomLightingEquation(float light)
} }
// The zdoom light equation // The zdoom light equation
float vis = min(globVis / z, 24.0 / 32.0); float vis = min(uGlobVis / z, 24.0 / 32.0);
float shade = 2.0 - (L + 12.0) / 128.0; float shade = 2.0 - (L + 12.0) / 128.0;
float lightscale; float lightscale;
if ((uPalLightLevels & 0xff) != 0) if ((uPalLightLevels & 0xff) != 0)

View file

@ -43,6 +43,7 @@ uniform vec4 uLightAttr;
#define uLightDist uLightAttr.r #define uLightDist uLightAttr.r
uniform int uFogEnabled; uniform int uFogEnabled;
uniform int uPalLightLevels; uniform int uPalLightLevels;
uniform float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
// dynamic lights // dynamic lights
uniform int uLightIndex; uniform int uLightIndex;