mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-22 12:11:21 +00:00
- Backend update from GZDoom.
This commit is contained in:
parent
8001c4041f
commit
fca0bdf379
16 changed files with 310 additions and 59 deletions
|
@ -422,7 +422,7 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
||||||
{
|
{
|
||||||
for (int x = 0; x < numtex_x; x++)
|
for (int x = 0; x < numtex_x; x++)
|
||||||
{
|
{
|
||||||
auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * width, width, height);
|
auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * height, width, height);
|
||||||
FImageTexture *imgtex = new FImageTexture(image);
|
FImageTexture *imgtex = new FImageTexture(image);
|
||||||
auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar);
|
auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar);
|
||||||
gtex->SetWorldPanning(true);
|
gtex->SetWorldPanning(true);
|
||||||
|
|
|
@ -235,6 +235,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
float uClipHeight;
|
float uClipHeight;
|
||||||
float uClipHeightDirection;
|
float uClipHeightDirection;
|
||||||
int uShadowmapFilter;
|
int uShadowmapFilter;
|
||||||
|
|
||||||
|
int uLightBlendMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform int uTextureMode;
|
uniform int uTextureMode;
|
||||||
|
@ -328,6 +330,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
uniform sampler2D texture9;
|
uniform sampler2D texture9;
|
||||||
uniform sampler2D texture10;
|
uniform sampler2D texture10;
|
||||||
uniform sampler2D texture11;
|
uniform sampler2D texture11;
|
||||||
|
uniform sampler2D texture12;
|
||||||
|
|
||||||
// timer data
|
// timer data
|
||||||
uniform float timer;
|
uniform float timer;
|
||||||
|
|
|
@ -91,6 +91,7 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll)
|
||||||
matrices.mPalLightLevels = pll;
|
matrices.mPalLightLevels = pll;
|
||||||
matrices.mClipLine.X = -10000000.0f;
|
matrices.mClipLine.X = -10000000.0f;
|
||||||
matrices.mShadowmapFilter = gl_shadowmap_filter;
|
matrices.mShadowmapFilter = gl_shadowmap_filter;
|
||||||
|
matrices.mLightBlendMode = 0;
|
||||||
|
|
||||||
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
|
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
|
||||||
matrices.CalcDependencies();
|
matrices.CalcDependencies();
|
||||||
|
|
|
@ -4,6 +4,15 @@
|
||||||
|
|
||||||
struct HWDrawInfo;
|
struct HWDrawInfo;
|
||||||
|
|
||||||
|
enum class ELightBlendMode : uint8_t
|
||||||
|
{
|
||||||
|
CLAMP = 0,
|
||||||
|
CLAMP_COLOR = 1,
|
||||||
|
NOCLAMP = 2,
|
||||||
|
|
||||||
|
DEFAULT = CLAMP,
|
||||||
|
};
|
||||||
|
|
||||||
struct HWViewpointUniforms
|
struct HWViewpointUniforms
|
||||||
{
|
{
|
||||||
VSMatrix mProjectionMatrix;
|
VSMatrix mProjectionMatrix;
|
||||||
|
@ -19,6 +28,8 @@ struct HWViewpointUniforms
|
||||||
float mClipHeightDirection = 0.f;
|
float mClipHeightDirection = 0.f;
|
||||||
int mShadowmapFilter = 1;
|
int mShadowmapFilter = 1;
|
||||||
|
|
||||||
|
int mLightBlendMode = 0;
|
||||||
|
|
||||||
void CalcDependencies()
|
void CalcDependencies()
|
||||||
{
|
{
|
||||||
mNormalViewMatrix.computeNormalMatrix(mViewMatrix);
|
mNormalViewMatrix.computeNormalMatrix(mViewMatrix);
|
||||||
|
|
|
@ -570,7 +570,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm, float flash)
|
||||||
|
|
||||||
void PPTonemap::UpdateTextures()
|
void PPTonemap::UpdateTextures()
|
||||||
{
|
{
|
||||||
if (gl_tonemap == Palette && !PaletteTexture.Data)
|
// level.info->tonemap cannot be ETonemapMode::Palette, so it's fine to only check gl_tonemap here
|
||||||
|
if (ETonemapMode((int)gl_tonemap) == ETonemapMode::Palette && !PaletteTexture.Data)
|
||||||
{
|
{
|
||||||
std::shared_ptr<void> data(new uint32_t[512 * 512], [](void *p) { delete[](uint32_t*)p; });
|
std::shared_ptr<void> data(new uint32_t[512 * 512], [](void *p) { delete[](uint32_t*)p; });
|
||||||
|
|
||||||
|
@ -598,7 +599,9 @@ void PPTonemap::UpdateTextures()
|
||||||
|
|
||||||
void PPTonemap::Render(PPRenderState *renderstate)
|
void PPTonemap::Render(PPRenderState *renderstate)
|
||||||
{
|
{
|
||||||
if (gl_tonemap == 0)
|
ETonemapMode current_tonemap = (level_tonemap != ETonemapMode::None) ? level_tonemap : ETonemapMode((int)gl_tonemap);
|
||||||
|
|
||||||
|
if (current_tonemap == ETonemapMode::None)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -606,14 +609,14 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
||||||
UpdateTextures();
|
UpdateTextures();
|
||||||
|
|
||||||
PPShader *shader = nullptr;
|
PPShader *shader = nullptr;
|
||||||
switch (gl_tonemap)
|
switch (current_tonemap)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case Linear: shader = &LinearShader; break;
|
case ETonemapMode::Linear: shader = &LinearShader; break;
|
||||||
case Reinhard: shader = &ReinhardShader; break;
|
case ETonemapMode::Reinhard: shader = &ReinhardShader; break;
|
||||||
case HejlDawson: shader = &HejlDawsonShader; break;
|
case ETonemapMode::HejlDawson: shader = &HejlDawsonShader; break;
|
||||||
case Uncharted2: shader = &Uncharted2Shader; break;
|
case ETonemapMode::Uncharted2: shader = &Uncharted2Shader; break;
|
||||||
case Palette: shader = &PaletteShader; break;
|
case ETonemapMode::Palette: shader = &PaletteShader; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderstate->PushGroup("tonemap");
|
renderstate->PushGroup("tonemap");
|
||||||
|
@ -622,7 +625,7 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
||||||
renderstate->Shader = shader;
|
renderstate->Shader = shader;
|
||||||
renderstate->Viewport = screen->mScreenViewport;
|
renderstate->Viewport = screen->mScreenViewport;
|
||||||
renderstate->SetInputCurrent(0);
|
renderstate->SetInputCurrent(0);
|
||||||
if (gl_tonemap == Palette)
|
if (current_tonemap == ETonemapMode::Palette)
|
||||||
renderstate->SetInputTexture(1, &PaletteTexture);
|
renderstate->SetInputTexture(1, &PaletteTexture);
|
||||||
renderstate->SetOutputNext();
|
renderstate->SetOutputNext();
|
||||||
renderstate->SetNoBlend();
|
renderstate->SetNoBlend();
|
||||||
|
|
|
@ -13,6 +13,19 @@ typedef IntRect PPViewport;
|
||||||
class PPTexture;
|
class PPTexture;
|
||||||
class PPShader;
|
class PPShader;
|
||||||
|
|
||||||
|
enum class ETonemapMode : uint8_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Uncharted2,
|
||||||
|
HejlDawson,
|
||||||
|
Reinhard,
|
||||||
|
Linear,
|
||||||
|
Palette,
|
||||||
|
NumTonemapModes
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
enum class PPFilterMode { Nearest, Linear };
|
enum class PPFilterMode { Nearest, Linear };
|
||||||
enum class PPWrapMode { Clamp, Repeat };
|
enum class PPWrapMode { Clamp, Repeat };
|
||||||
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
||||||
|
@ -541,6 +554,7 @@ private:
|
||||||
class PPTonemap
|
class PPTonemap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void SetTonemapMode(ETonemapMode tm) { level_tonemap = tm; }
|
||||||
void Render(PPRenderState *renderstate);
|
void Render(PPRenderState *renderstate);
|
||||||
void ClearTonemapPalette() { PaletteTexture = {}; }
|
void ClearTonemapPalette() { PaletteTexture = {}; }
|
||||||
|
|
||||||
|
@ -554,17 +568,7 @@ private:
|
||||||
PPShader HejlDawsonShader = { "shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} };
|
PPShader HejlDawsonShader = { "shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} };
|
||||||
PPShader Uncharted2Shader = { "shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} };
|
PPShader Uncharted2Shader = { "shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} };
|
||||||
PPShader PaletteShader = { "shaders/pp/tonemap.fp", "#define PALETTE\n", {} };
|
PPShader PaletteShader = { "shaders/pp/tonemap.fp", "#define PALETTE\n", {} };
|
||||||
|
ETonemapMode level_tonemap = ETonemapMode::None;
|
||||||
enum TonemapMode
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Uncharted2,
|
|
||||||
HejlDawson,
|
|
||||||
Reinhard,
|
|
||||||
Linear,
|
|
||||||
Palette,
|
|
||||||
NumTonemapModes
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -840,8 +844,11 @@ public:
|
||||||
PPCustomShaders customShaders;
|
PPCustomShaders customShaders;
|
||||||
|
|
||||||
|
|
||||||
|
void SetTonemapMode(ETonemapMode tm) { tonemap.SetTonemapMode(tm); }
|
||||||
void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight);
|
void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight);
|
||||||
void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight);
|
void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern Postprocess hw_postprocess;
|
extern Postprocess hw_postprocess;
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,8 @@ static const char *shaderBindings = R"(
|
||||||
float uClipHeight;
|
float uClipHeight;
|
||||||
float uClipHeightDirection;
|
float uClipHeightDirection;
|
||||||
int uShadowmapFilter;
|
int uShadowmapFilter;
|
||||||
|
|
||||||
|
int uLightBlendMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(set = 1, binding = 1, std140) uniform MatricesUBO {
|
layout(set = 1, binding = 1, std140) uniform MatricesUBO {
|
||||||
|
@ -244,6 +246,7 @@ static const char *shaderBindings = R"(
|
||||||
layout(set = 2, binding = 8) uniform sampler2D texture9;
|
layout(set = 2, binding = 8) uniform sampler2D texture9;
|
||||||
layout(set = 2, binding = 9) uniform sampler2D texture10;
|
layout(set = 2, binding = 9) uniform sampler2D texture10;
|
||||||
layout(set = 2, binding = 10) uniform sampler2D texture11;
|
layout(set = 2, binding = 10) uniform sampler2D texture11;
|
||||||
|
layout(set = 2, binding = 11) uniform sampler2D texture12;
|
||||||
|
|
||||||
// This must match the PushConstants struct
|
// This must match the PushConstants struct
|
||||||
layout(push_constant) uniform PushConstants
|
layout(push_constant) uniform PushConstants
|
||||||
|
|
|
@ -438,10 +438,12 @@ template<typename I> void MapIteratorSetValue(I * self, expand_types_vm<typename
|
||||||
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
||||||
ACTION_RETURN_INT( MapIteratorGetKey(self) ); \
|
ACTION_RETURN_INT( MapIteratorGetKey(self) ); \
|
||||||
} \
|
} \
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValue< FMapIterator_I32_Str > ) \
|
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValueString< FMapIterator_I32_Str > ) \
|
||||||
{ \
|
{ \
|
||||||
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
||||||
ACTION_RETURN_STRING( MapIteratorGetValue(self) ); \
|
FString out; \
|
||||||
|
MapIteratorGetValueString(self , out); \
|
||||||
|
ACTION_RETURN_STRING( out ); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEF_MAP_IT_S_S() \
|
#define DEF_MAP_IT_S_S() \
|
||||||
|
|
|
@ -133,13 +133,16 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
||||||
if (index >= FIRST_USER_SHADER)
|
if (index >= FIRST_USER_SHADER)
|
||||||
{
|
{
|
||||||
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
|
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
|
||||||
if (tx->Layers && usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||||
|
{
|
||||||
|
if (tx->Layers)
|
||||||
{
|
{
|
||||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||||
{
|
{
|
||||||
if (texture == nullptr) continue;
|
if (texture == nullptr) continue;
|
||||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||||
}
|
}
|
||||||
|
}
|
||||||
mShaderIndex = index;
|
mShaderIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,13 +418,16 @@ void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, con
|
||||||
// color, so find a duplicate pair of palette entries, make one of them a
|
// color, so find a duplicate pair of palette entries, make one of them a
|
||||||
// duplicate of color 0, and remap every graphic so that it uses that entry
|
// duplicate of color 0, and remap every graphic so that it uses that entry
|
||||||
// instead of entry 0.
|
// instead of entry 0.
|
||||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* lastcolormap)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 256; i++) Remap[i] = i;
|
for (int i = 0; i < 256; i++) Remap[i] = i;
|
||||||
PalEntry color0 = BaseColors[0];
|
PalEntry color0 = BaseColors[0];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
||||||
// First try for an exact match of color 0. Only Hexen does not have one.
|
// First try for an exact match of color 0. Only Hexen does not have one.
|
||||||
|
if (!lastcolormap)
|
||||||
|
{
|
||||||
for (i = 1; i < 256; ++i)
|
for (i = 1; i < 256; ++i)
|
||||||
{
|
{
|
||||||
if (BaseColors[i] == color0)
|
if (BaseColors[i] == color0)
|
||||||
|
@ -433,6 +436,18 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 1; i < 256; ++i)
|
||||||
|
{
|
||||||
|
if ((BaseColors[i] == color0) && (lastcolormap[i] == lastcolormap[0]))
|
||||||
|
{
|
||||||
|
Remap[0] = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there is no duplicate of color 0, find the first set of duplicate
|
// If there is no duplicate of color 0, find the first set of duplicate
|
||||||
// colors and make one of them a duplicate of color 0. In Hexen's PLAYPAL
|
// colors and make one of them a duplicate of color 0. In Hexen's PLAYPAL
|
||||||
|
@ -448,6 +463,8 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
||||||
sortcopy[i] = (BaseColors[i] & 0xffffff) | (i << 24);
|
sortcopy[i] = (BaseColors[i] & 0xffffff) | (i << 24);
|
||||||
}
|
}
|
||||||
qsort(sortcopy, 256, 4, sortforremap);
|
qsort(sortcopy, 256, 4, sortforremap);
|
||||||
|
if (!lastcolormap)
|
||||||
|
{
|
||||||
for (i = 255; i > 0; --i)
|
for (i = 255; i > 0; --i)
|
||||||
{
|
{
|
||||||
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
||||||
|
@ -466,6 +483,27 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 255; i > 0; --i)
|
||||||
|
{
|
||||||
|
if (((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) && (lastcolormap[sortcopy[i].a] == lastcolormap[sortcopy[i - 1].a]))
|
||||||
|
{
|
||||||
|
int new0 = sortcopy[i].a;
|
||||||
|
int dup = sortcopy[i - 1].a;
|
||||||
|
if (new0 > dup)
|
||||||
|
{
|
||||||
|
// Make the lower-numbered entry a copy of color 0. (Just because.)
|
||||||
|
std::swap(new0, dup);
|
||||||
|
}
|
||||||
|
Remap[0] = new0;
|
||||||
|
Remap[new0] = dup;
|
||||||
|
BaseColors[new0] = color0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there were no duplicates, InitPalette() will remap color 0 to the
|
// If there were no duplicates, InitPalette() will remap color 0 to the
|
||||||
// closest matching color. Hopefully nobody will use a palette where all
|
// closest matching color. Hopefully nobody will use a palette where all
|
||||||
|
|
|
@ -14,7 +14,7 @@ void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int
|
||||||
// Given an array of colors, fills in remap with values to remap the
|
// Given an array of colors, fills in remap with values to remap the
|
||||||
// passed array of colors to BaseColors. Used for loading palette downconversions of PNGs.
|
// passed array of colors to BaseColors. Used for loading palette downconversions of PNGs.
|
||||||
void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors);
|
void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors);
|
||||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap);
|
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* cmapdata = nullptr);
|
||||||
|
|
||||||
// Colorspace conversion RGB <-> HSV
|
// Colorspace conversion RGB <-> HSV
|
||||||
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
|
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
|
||||||
|
|
|
@ -250,6 +250,7 @@ void HWDrawInfo::SetupView(FRenderState &state, float vx, float vy, float vz, bo
|
||||||
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
|
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
|
||||||
SetCameraPos(vp.Pos);
|
SetCameraPos(vp.Pos);
|
||||||
VPUniforms.CalcDependencies();
|
VPUniforms.CalcDependencies();
|
||||||
|
VPUniforms.mLightBlendMode = 0;
|
||||||
vpIndex = screen->mViewpoints->SetViewpoint(state, &VPUniforms);
|
vpIndex = screen->mViewpoints->SetViewpoint(state, &VPUniforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -325,7 +325,7 @@ float R_DoomLightingEquation(float light)
|
||||||
// This is a lot more primitive than Doom's lighting...
|
// This is a lot more primitive than Doom's lighting...
|
||||||
float numShades = float(uPalLightLevels & 255);
|
float numShades = float(uPalLightLevels & 255);
|
||||||
float curshade = (1.0 - light) * (numShades - 1.0);
|
float curshade = (1.0 - light) * (numShades - 1.0);
|
||||||
float visibility = max(uGlobVis * uLightFactor * abs(z), 0.0);
|
float visibility = max(uGlobVis * uLightFactor * z, 0.0);
|
||||||
float shade = clamp((curshade + visibility), 0.0, numShades - 1.0);
|
float shade = clamp((curshade + visibility), 0.0, numShades - 1.0);
|
||||||
return clamp(shade * uLightDist, 0.0, 1.0);
|
return clamp(shade * uLightDist, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -344,10 +344,86 @@ float R_DoomLightingEquation(float light)
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// Check if light is in shadow according to its 1D shadow map
|
// Check if light is in shadow
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
#ifdef SUPPORTS_RAYTRACING
|
||||||
|
|
||||||
|
bool traceHit(vec3 origin, vec3 direction, float dist)
|
||||||
|
{
|
||||||
|
rayQueryEXT rayQuery;
|
||||||
|
rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, dist);
|
||||||
|
while(rayQueryProceedEXT(rayQuery)) { }
|
||||||
|
return rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionNoneEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 softshadow[9 * 3] = vec2[](
|
||||||
|
vec2( 0.0, 0.0),
|
||||||
|
vec2(-2.0,-2.0),
|
||||||
|
vec2( 2.0, 2.0),
|
||||||
|
vec2( 2.0,-2.0),
|
||||||
|
vec2(-2.0, 2.0),
|
||||||
|
vec2(-1.0,-1.0),
|
||||||
|
vec2( 1.0, 1.0),
|
||||||
|
vec2( 1.0,-1.0),
|
||||||
|
vec2(-1.0, 1.0),
|
||||||
|
|
||||||
|
vec2( 0.0, 0.0),
|
||||||
|
vec2(-1.5,-1.5),
|
||||||
|
vec2( 1.5, 1.5),
|
||||||
|
vec2( 1.5,-1.5),
|
||||||
|
vec2(-1.5, 1.5),
|
||||||
|
vec2(-0.5,-0.5),
|
||||||
|
vec2( 0.5, 0.5),
|
||||||
|
vec2( 0.5,-0.5),
|
||||||
|
vec2(-0.5, 0.5),
|
||||||
|
|
||||||
|
vec2( 0.0, 0.0),
|
||||||
|
vec2(-1.25,-1.75),
|
||||||
|
vec2( 1.75, 1.25),
|
||||||
|
vec2( 1.25,-1.75),
|
||||||
|
vec2(-1.75, 1.75),
|
||||||
|
vec2(-0.75,-0.25),
|
||||||
|
vec2( 0.25, 0.75),
|
||||||
|
vec2( 0.75,-0.25),
|
||||||
|
vec2(-0.25, 0.75)
|
||||||
|
);
|
||||||
|
|
||||||
|
float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||||
|
{
|
||||||
|
float shadowIndex = abs(lightcolorA) - 1.0;
|
||||||
|
if (shadowIndex >= 1024.0)
|
||||||
|
return 1.0; // Don't cast rays for this light
|
||||||
|
|
||||||
|
vec3 origin = pixelpos.xzy;
|
||||||
|
vec3 target = lightpos.xzy + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes
|
||||||
|
|
||||||
|
vec3 direction = normalize(target - origin);
|
||||||
|
float dist = distance(origin, target);
|
||||||
|
|
||||||
|
if (uShadowmapFilter <= 0)
|
||||||
|
{
|
||||||
|
return traceHit(origin, direction, dist) ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec3 v = (abs(direction.x) > abs(direction.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);
|
||||||
|
vec3 xdir = normalize(cross(direction, v));
|
||||||
|
vec3 ydir = cross(direction, xdir);
|
||||||
|
|
||||||
|
float sum = 0.0;
|
||||||
|
int step_count = uShadowmapFilter * 9;
|
||||||
|
for (int i = 0; i <= step_count; i++)
|
||||||
|
{
|
||||||
|
vec3 pos = target + xdir * softshadow[i].x + ydir * softshadow[i].y;
|
||||||
|
sum += traceHit(origin, normalize(pos - origin), dist) ? 0.0 : 1.0;
|
||||||
|
}
|
||||||
|
return sum / step_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
#ifdef SUPPORTS_SHADOWMAPS
|
#ifdef SUPPORTS_SHADOWMAPS
|
||||||
|
|
||||||
float shadowDirToU(vec2 dir)
|
float shadowDirToU(vec2 dir)
|
||||||
|
@ -491,6 +567,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle)
|
float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle)
|
||||||
|
|
|
@ -5,11 +5,15 @@ layout(location = 2) in vec4 aColor;
|
||||||
|
|
||||||
layout(location = 0) out vec4 vTexCoord;
|
layout(location = 0) out vec4 vTexCoord;
|
||||||
layout(location = 1) out vec4 vColor;
|
layout(location = 1) out vec4 vColor;
|
||||||
|
layout(location = 9) out vec3 vLightmap;
|
||||||
|
|
||||||
#ifndef SIMPLE // we do not need these for simple shaders
|
#ifndef SIMPLE // we do not need these for simple shaders
|
||||||
layout(location = 3) in vec4 aVertex2;
|
layout(location = 3) in vec4 aVertex2;
|
||||||
layout(location = 4) in vec4 aNormal;
|
layout(location = 4) in vec4 aNormal;
|
||||||
layout(location = 5) in vec4 aNormal2;
|
layout(location = 5) in vec4 aNormal2;
|
||||||
|
layout(location = 6) in vec3 aLightmap;
|
||||||
|
layout(location = 7) in vec4 aBoneWeight;
|
||||||
|
layout(location = 8) in uvec4 aBoneSelector;
|
||||||
|
|
||||||
layout(location = 2) out vec4 pixelpos;
|
layout(location = 2) out vec4 pixelpos;
|
||||||
layout(location = 3) out vec3 glowdist;
|
layout(location = 3) out vec3 glowdist;
|
||||||
|
@ -23,6 +27,14 @@ layout(location = 7) out vec4 ClipDistanceA;
|
||||||
layout(location = 8) out vec4 ClipDistanceB;
|
layout(location = 8) out vec4 ClipDistanceB;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct BonesResult
|
||||||
|
{
|
||||||
|
vec3 Normal;
|
||||||
|
vec4 Position;
|
||||||
|
};
|
||||||
|
|
||||||
|
BonesResult ApplyBones();
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
|
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
|
||||||
|
@ -30,8 +42,10 @@ void main()
|
||||||
vec2 parmTexCoord;
|
vec2 parmTexCoord;
|
||||||
vec4 parmPosition;
|
vec4 parmPosition;
|
||||||
|
|
||||||
|
BonesResult bones = ApplyBones();
|
||||||
|
|
||||||
parmTexCoord = aTexCoord;
|
parmTexCoord = aTexCoord;
|
||||||
parmPosition = aPosition;
|
parmPosition = bones.Position;
|
||||||
|
|
||||||
#ifndef SIMPLE
|
#ifndef SIMPLE
|
||||||
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
|
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
|
||||||
|
@ -51,6 +65,8 @@ void main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SIMPLE
|
#ifndef SIMPLE
|
||||||
|
vLightmap = aLightmap;
|
||||||
|
|
||||||
pixelpos.xyz = worldcoord.xyz;
|
pixelpos.xyz = worldcoord.xyz;
|
||||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||||
|
|
||||||
|
@ -78,14 +94,7 @@ void main()
|
||||||
ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_UNIFORM_VERTEX_DATA
|
vWorldNormal = NormalModelMatrix * vec4(normalize(bones.Normal), 1.0);
|
||||||
if ((useVertexData & 2) == 0)
|
|
||||||
vWorldNormal = NormalModelMatrix * vec4(normalize(uVertexNormal.xyz), 1.0);
|
|
||||||
else
|
|
||||||
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
|
|
||||||
#else
|
|
||||||
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
|
|
||||||
#endif
|
|
||||||
vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0);
|
vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -142,3 +151,66 @@ void main()
|
||||||
|
|
||||||
gl_PointSize = 1.0;
|
gl_PointSize = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(SIMPLE)
|
||||||
|
vec3 GetAttrNormal()
|
||||||
|
{
|
||||||
|
#ifdef HAS_UNIFORM_VERTEX_DATA
|
||||||
|
if ((useVertexData & 2) == 0)
|
||||||
|
return uVertexNormal.xyz;
|
||||||
|
else
|
||||||
|
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
|
||||||
|
#else
|
||||||
|
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddWeightedBone(uint boneIndex, float weight, inout vec4 position, inout vec3 normal)
|
||||||
|
{
|
||||||
|
if (weight != 0.0)
|
||||||
|
{
|
||||||
|
mat4 transform = bones[uBoneIndexBase + int(boneIndex)];
|
||||||
|
mat3 rotation = mat3(transform);
|
||||||
|
position += (transform * aPosition) * weight;
|
||||||
|
normal += (rotation * aNormal.xyz) * weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BonesResult ApplyBones()
|
||||||
|
{
|
||||||
|
BonesResult result;
|
||||||
|
if (uBoneIndexBase >= 0 && aBoneWeight != vec4(0.0))
|
||||||
|
{
|
||||||
|
result.Position = vec4(0.0);
|
||||||
|
result.Normal = vec3(0.0);
|
||||||
|
|
||||||
|
// We use low precision input for our bone weights. Rescale so the sum still is 1.0
|
||||||
|
float totalWeight = aBoneWeight.x + aBoneWeight.y + aBoneWeight.z + aBoneWeight.w;
|
||||||
|
float weightMultiplier = 1.0 / totalWeight;
|
||||||
|
vec4 boneWeight = aBoneWeight * weightMultiplier;
|
||||||
|
|
||||||
|
AddWeightedBone(aBoneSelector.x, boneWeight.x, result.Position, result.Normal);
|
||||||
|
AddWeightedBone(aBoneSelector.y, boneWeight.y, result.Position, result.Normal);
|
||||||
|
AddWeightedBone(aBoneSelector.z, boneWeight.z, result.Position, result.Normal);
|
||||||
|
AddWeightedBone(aBoneSelector.w, boneWeight.w, result.Position, result.Normal);
|
||||||
|
|
||||||
|
result.Position.w = 1.0; // For numerical stability
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Position = aPosition;
|
||||||
|
result.Normal = GetAttrNormal();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
BonesResult ApplyBones()
|
||||||
|
{
|
||||||
|
BonesResult result;
|
||||||
|
result.Position = aPosition;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -59,7 +59,21 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
vec3 frag;
|
||||||
|
|
||||||
|
if ( uLightBlendMode == 1 )
|
||||||
|
{ // COLOR_CORRECT_CLAMPING
|
||||||
|
vec3 lightcolor = color + desaturate(dynlight).rgb;
|
||||||
|
frag = material.Base.rgb * ((lightcolor / max(max(max(lightcolor.r, lightcolor.g), lightcolor.b), 1.4) * 1.4));
|
||||||
|
}
|
||||||
|
else if ( uLightBlendMode == 2 )
|
||||||
|
{ // UNCLAMPED
|
||||||
|
frag = material.Base.rgb * (color + desaturate(dynlight).rgb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||||
|
}
|
||||||
|
|
||||||
if (uLightIndex >= 0)
|
if (uLightIndex >= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,8 +67,24 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( uLightBlendMode == 1 )
|
||||||
|
{ // COLOR_CORRECT_CLAMPING
|
||||||
|
dynlight.rgb = color + desaturate(dynlight).rgb;
|
||||||
|
specular.rgb = desaturate(specular).rgb;
|
||||||
|
|
||||||
|
dynlight.rgb = ((dynlight.rgb / max(max(max(dynlight.r, dynlight.g), dynlight.b), 1.4) * 1.4));
|
||||||
|
specular.rgb = ((specular.rgb / max(max(max(specular.r, specular.g), specular.b), 1.4) * 1.4));
|
||||||
|
}
|
||||||
|
else if ( uLightBlendMode == 2 )
|
||||||
|
{ // UNCLAMPED
|
||||||
|
dynlight.rgb = color + desaturate(dynlight).rgb;
|
||||||
|
specular.rgb = desaturate(specular).rgb;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||||
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb;
|
vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue