mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 00:42:08 +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++)
|
||||
{
|
||||
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);
|
||||
auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar);
|
||||
gtex->SetWorldPanning(true);
|
||||
|
|
|
@ -235,6 +235,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uShadowmapFilter;
|
||||
|
||||
int uLightBlendMode;
|
||||
};
|
||||
|
||||
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 texture10;
|
||||
uniform sampler2D texture11;
|
||||
uniform sampler2D texture12;
|
||||
|
||||
// timer data
|
||||
uniform float timer;
|
||||
|
|
|
@ -91,6 +91,7 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll)
|
|||
matrices.mPalLightLevels = pll;
|
||||
matrices.mClipLine.X = -10000000.0f;
|
||||
matrices.mShadowmapFilter = gl_shadowmap_filter;
|
||||
matrices.mLightBlendMode = 0;
|
||||
|
||||
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
|
||||
matrices.CalcDependencies();
|
||||
|
|
|
@ -4,6 +4,15 @@
|
|||
|
||||
struct HWDrawInfo;
|
||||
|
||||
enum class ELightBlendMode : uint8_t
|
||||
{
|
||||
CLAMP = 0,
|
||||
CLAMP_COLOR = 1,
|
||||
NOCLAMP = 2,
|
||||
|
||||
DEFAULT = CLAMP,
|
||||
};
|
||||
|
||||
struct HWViewpointUniforms
|
||||
{
|
||||
VSMatrix mProjectionMatrix;
|
||||
|
@ -19,6 +28,8 @@ struct HWViewpointUniforms
|
|||
float mClipHeightDirection = 0.f;
|
||||
int mShadowmapFilter = 1;
|
||||
|
||||
int mLightBlendMode = 0;
|
||||
|
||||
void CalcDependencies()
|
||||
{
|
||||
mNormalViewMatrix.computeNormalMatrix(mViewMatrix);
|
||||
|
|
|
@ -570,7 +570,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm, float flash)
|
|||
|
||||
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; });
|
||||
|
||||
|
@ -598,7 +599,9 @@ void PPTonemap::UpdateTextures()
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -606,14 +609,14 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
|||
UpdateTextures();
|
||||
|
||||
PPShader *shader = nullptr;
|
||||
switch (gl_tonemap)
|
||||
switch (current_tonemap)
|
||||
{
|
||||
default:
|
||||
case Linear: shader = &LinearShader; break;
|
||||
case Reinhard: shader = &ReinhardShader; break;
|
||||
case HejlDawson: shader = &HejlDawsonShader; break;
|
||||
case Uncharted2: shader = &Uncharted2Shader; break;
|
||||
case Palette: shader = &PaletteShader; break;
|
||||
case ETonemapMode::Linear: shader = &LinearShader; break;
|
||||
case ETonemapMode::Reinhard: shader = &ReinhardShader; break;
|
||||
case ETonemapMode::HejlDawson: shader = &HejlDawsonShader; break;
|
||||
case ETonemapMode::Uncharted2: shader = &Uncharted2Shader; break;
|
||||
case ETonemapMode::Palette: shader = &PaletteShader; break;
|
||||
}
|
||||
|
||||
renderstate->PushGroup("tonemap");
|
||||
|
@ -622,7 +625,7 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
|||
renderstate->Shader = shader;
|
||||
renderstate->Viewport = screen->mScreenViewport;
|
||||
renderstate->SetInputCurrent(0);
|
||||
if (gl_tonemap == Palette)
|
||||
if (current_tonemap == ETonemapMode::Palette)
|
||||
renderstate->SetInputTexture(1, &PaletteTexture);
|
||||
renderstate->SetOutputNext();
|
||||
renderstate->SetNoBlend();
|
||||
|
|
|
@ -13,6 +13,19 @@ typedef IntRect PPViewport;
|
|||
class PPTexture;
|
||||
class PPShader;
|
||||
|
||||
enum class ETonemapMode : uint8_t
|
||||
{
|
||||
None,
|
||||
Uncharted2,
|
||||
HejlDawson,
|
||||
Reinhard,
|
||||
Linear,
|
||||
Palette,
|
||||
NumTonemapModes
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class PPFilterMode { Nearest, Linear };
|
||||
enum class PPWrapMode { Clamp, Repeat };
|
||||
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
||||
|
@ -541,6 +554,7 @@ private:
|
|||
class PPTonemap
|
||||
{
|
||||
public:
|
||||
void SetTonemapMode(ETonemapMode tm) { level_tonemap = tm; }
|
||||
void Render(PPRenderState *renderstate);
|
||||
void ClearTonemapPalette() { PaletteTexture = {}; }
|
||||
|
||||
|
@ -554,17 +568,7 @@ private:
|
|||
PPShader HejlDawsonShader = { "shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} };
|
||||
PPShader Uncharted2Shader = { "shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} };
|
||||
PPShader PaletteShader = { "shaders/pp/tonemap.fp", "#define PALETTE\n", {} };
|
||||
|
||||
enum TonemapMode
|
||||
{
|
||||
None,
|
||||
Uncharted2,
|
||||
HejlDawson,
|
||||
Reinhard,
|
||||
Linear,
|
||||
Palette,
|
||||
NumTonemapModes
|
||||
};
|
||||
ETonemapMode level_tonemap = ETonemapMode::None;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -840,8 +844,11 @@ public:
|
|||
PPCustomShaders customShaders;
|
||||
|
||||
|
||||
void SetTonemapMode(ETonemapMode tm) { tonemap.SetTonemapMode(tm); }
|
||||
void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight);
|
||||
void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight);
|
||||
};
|
||||
|
||||
|
||||
extern Postprocess hw_postprocess;
|
||||
|
||||
|
|
|
@ -175,6 +175,8 @@ static const char *shaderBindings = R"(
|
|||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uShadowmapFilter;
|
||||
|
||||
int uLightBlendMode;
|
||||
};
|
||||
|
||||
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 = 9) uniform sampler2D texture10;
|
||||
layout(set = 2, binding = 10) uniform sampler2D texture11;
|
||||
layout(set = 2, binding = 11) uniform sampler2D texture12;
|
||||
|
||||
// This must match the PushConstants struct
|
||||
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 ); \
|
||||
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 ); \
|
||||
ACTION_RETURN_STRING( MapIteratorGetValue(self) ); \
|
||||
FString out; \
|
||||
MapIteratorGetValueString(self , out); \
|
||||
ACTION_RETURN_STRING( out ); \
|
||||
}
|
||||
|
||||
#define DEF_MAP_IT_S_S() \
|
||||
|
|
|
@ -133,12 +133,15 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
if (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
|
||||
{
|
||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||
if (tx->Layers)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
}
|
||||
}
|
||||
mShaderIndex = index;
|
||||
}
|
||||
|
|
|
@ -418,19 +418,34 @@ 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
|
||||
// duplicate of color 0, and remap every graphic so that it uses that entry
|
||||
// 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;
|
||||
PalEntry color0 = BaseColors[0];
|
||||
int i;
|
||||
|
||||
|
||||
// First try for an exact match of color 0. Only Hexen does not have one.
|
||||
for (i = 1; i < 256; ++i)
|
||||
if (!lastcolormap)
|
||||
{
|
||||
if (BaseColors[i] == color0)
|
||||
for (i = 1; i < 256; ++i)
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
if (BaseColors[i] == color0)
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < 256; ++i)
|
||||
{
|
||||
if ((BaseColors[i] == color0) && (lastcolormap[i] == lastcolormap[0]))
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,21 +463,44 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
|||
sortcopy[i] = (BaseColors[i] & 0xffffff) | (i << 24);
|
||||
}
|
||||
qsort(sortcopy, 256, 4, sortforremap);
|
||||
for (i = 255; i > 0; --i)
|
||||
if (!lastcolormap)
|
||||
{
|
||||
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
||||
for (i = 255; i > 0; --i)
|
||||
{
|
||||
int new0 = sortcopy[i].a;
|
||||
int dup = sortcopy[i - 1].a;
|
||||
if (new0 > dup)
|
||||
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
||||
{
|
||||
// Make the lower-numbered entry a copy of color 0. (Just because.)
|
||||
std::swap(new0, dup);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
Remap[0] = new0;
|
||||
Remap[new0] = dup;
|
||||
BaseColors[new0] = color0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
// 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 MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap);
|
||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* cmapdata = nullptr);
|
||||
|
||||
// Colorspace conversion RGB <-> HSV
|
||||
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);
|
||||
SetCameraPos(vp.Pos);
|
||||
VPUniforms.CalcDependencies();
|
||||
VPUniforms.mLightBlendMode = 0;
|
||||
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...
|
||||
float numShades = float(uPalLightLevels & 255);
|
||||
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);
|
||||
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
|
||||
|
||||
float shadowDirToU(vec2 dir)
|
||||
|
@ -491,6 +567,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 = 1) out vec4 vColor;
|
||||
layout(location = 9) out vec3 vLightmap;
|
||||
|
||||
#ifndef SIMPLE // we do not need these for simple shaders
|
||||
layout(location = 3) in vec4 aVertex2;
|
||||
layout(location = 4) in vec4 aNormal;
|
||||
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 = 3) out vec3 glowdist;
|
||||
|
@ -23,6 +27,14 @@ layout(location = 7) out vec4 ClipDistanceA;
|
|||
layout(location = 8) out vec4 ClipDistanceB;
|
||||
#endif
|
||||
|
||||
struct BonesResult
|
||||
{
|
||||
vec3 Normal;
|
||||
vec4 Position;
|
||||
};
|
||||
|
||||
BonesResult ApplyBones();
|
||||
|
||||
void main()
|
||||
{
|
||||
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
|
||||
|
@ -30,8 +42,10 @@ void main()
|
|||
vec2 parmTexCoord;
|
||||
vec4 parmPosition;
|
||||
|
||||
BonesResult bones = ApplyBones();
|
||||
|
||||
parmTexCoord = aTexCoord;
|
||||
parmPosition = aPosition;
|
||||
parmPosition = bones.Position;
|
||||
|
||||
#ifndef SIMPLE
|
||||
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
|
||||
|
@ -51,6 +65,8 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifndef SIMPLE
|
||||
vLightmap = aLightmap;
|
||||
|
||||
pixelpos.xyz = worldcoord.xyz;
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef HAS_UNIFORM_VERTEX_DATA
|
||||
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
|
||||
vWorldNormal = NormalModelMatrix * vec4(normalize(bones.Normal), 1.0);
|
||||
vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0);
|
||||
#endif
|
||||
|
||||
|
@ -142,3 +151,66 @@ void main()
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -67,8 +67,24 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
}
|
||||
}
|
||||
|
||||
dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
||||
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);
|
||||
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
||||
}
|
||||
|
||||
vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb;
|
||||
|
||||
|
|
Loading…
Reference in a new issue