Skip to content

Commit

Permalink
* Ported over portal fixes - now supports up to 65536 portals as orig…
Browse files Browse the repository at this point in the history
…inally intended.

* Ported over "8-bit interpolated" color mode.
* Ported over shader refactoring to pull out common functionality such as lighting
and texture sampling.
* Ported over UI refactoring for "setting templates."
* Ported over fixes to GPU renderer index buffer (now 32-bit, supports the proper
number of indices/vertices).
* Fixed wireframe so it works properly in Release.
* Fixed wireframe so 3D objects, sector geometry, and sprites are all solid color and
color coded.
  • Loading branch information
luciusDXL committed Jul 29, 2023
1 parent 9a0d27f commit ab9c59a
Show file tree
Hide file tree
Showing 23 changed files with 756 additions and 402 deletions.
33 changes: 33 additions & 0 deletions TheForceEngine/Shaders/filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Adjust the output
vec2 bilinearSharpness(vec2 uv, float sharpness)
{
// Sharpness == 0 is the same as standard bilinear.
if (sharpness == 0.0) { return uv; }

// Sharpness == 1 adjust the filter width based on the per-pixel texel size in order
// to approximate "antialised point-sampling".
if (sharpness == 1.0)
{
vec2 w = fwidth(uv);
float scale = 0.5;
float mag = clamp(-log2(dot(w, w))*scale, 0.0, 1.0);
sharpness = mag * 0.5 + 0.5;
}

// Adjust the sub-texel sample position by mapping the linear change to an exponentiated S-Curve.
float ex = max(1.0, (sharpness - 0.5) * 32.0);
vec2 st = fract(uv);
vec2 stAdj = pow(uv*uv*(3.0 - 2.0*st), vec2(ex));
st = mix(st, stAdj, min(1.0, sharpness*2.0));

// The final texture coordinate is the integer position + adjusted sub-texel position.
return floor(uv) + st;
}

float computeMipLevel(vec2 uv)
{
vec2 dx = dFdx(uv);
vec2 dy = dFdy(uv);
float maxSq = max(dot(dx, dx), dot(dy, dy));
return 0.5 * log2(maxSq); // same as log2(maxSq^0.5)
}
4 changes: 2 additions & 2 deletions TheForceEngine/Shaders/gpu_render_modelHologram.vert
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ in vec4 vtx_color;

void unpackPortalInfo(uint portalInfo, out uint portalOffset, out uint portalCount)
{
portalCount = (portalInfo >> 13u) & 15u;
portalOffset = portalInfo & 8191u;
portalCount = (portalInfo >> 16u) & 15u;
portalOffset = portalInfo & 65535u;
}

flat out int Frag_Color;
Expand Down
89 changes: 23 additions & 66 deletions TheForceEngine/Shaders/gpu_render_modelSolid.frag
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
uniform sampler2D Palette;
uniform sampler2D Colormap;
uniform sampler2DArray Textures;
#include "Shaders/textureSampleFunc.h"
#include "Shaders/filter.h"
#include "Shaders/lighting.h"

uniform vec3 CameraPos;
uniform vec3 CameraDir;
uniform vec2 LightData;
uniform vec4 TextureOffsets;

uniform isamplerBuffer TextureTable;

in vec2 Frag_Uv;
in vec3 Frag_WorldPos;
noperspective in float Frag_Light;
Expand All @@ -19,52 +17,14 @@ flat in int Frag_TextureMode;

out vec4 Out_Color;

vec3 getAttenuatedColor(int baseColor, int light)
{
int color = baseColor;
if (light < 31)
{
ivec2 uv = ivec2(color, light);
color = int(texelFetch(Colormap, uv, 0).r * 255.0);
}
return texelFetch(Palette, ivec2(color, 0), 0).rgb;
}

ivec2 imod(ivec2 x, ivec2 y)
{
return x - (x/y)*y;
}

ivec2 wrapCoord(ivec2 uv, ivec2 edge)
{
uv = imod(uv, edge);
uv.x += (uv.x < 0) ? edge.x : 0;
uv.y += (uv.y < 0) ? edge.y : 0;
return uv;
}

float sampleTexture(int id, vec2 uv)
{
ivec4 sampleData = texelFetch(TextureTable, id);
ivec3 iuv;
iuv.xy = ivec2(uv);
iuv.z = 0;

iuv.xy = wrapCoord(iuv.xy, sampleData.zw);
iuv.xy += (sampleData.xy & ivec2(4095));
iuv.z = sampleData.x >> 12;

return texelFetch(Textures, iuv, 0).r * 255.0;
}

void main()
{
int baseColor = Frag_Color;
int lightLevel = 31;
float baseColor = float(Frag_Color);
float light = 31.0;
if (Frag_TextureId < 65535) // 0xffff = no texture
{
vec2 uv = Frag_Uv;
if (Frag_TextureMode > 0)
if (Frag_TextureMode > 0) // PLANE shaded.
{
// Sector flat style projection.
float planeY = uv.x + Frag_ModelY;
Expand All @@ -83,45 +43,42 @@ void main()
float ambient = max(0.0, LightData.y > 32.0 ? LightData.y - 64.0 : LightData.y);
if (ambient < 31.0)
{
float light = 0.0;
float scaledAmbient = ambient * 7.0 / 8.0;
light = 0.0;
float z = max(0.0, dot((Frag_WorldPos - CameraPos), CameraDir));

// Handle lighting in a similar way to sector floors and ceilings.
// Camera Light
float worldAmbient = LightData.x;
float cameraLightSource = LightData.y > 63.0 ? 1.0 : 0.0;
float worldAmbient = LightData.x > 64.0 ? LightData.x - 128.0 : LightData.x;
float cameraLightSource = LightData.y > 32.0 ? 1.0 : 0.0;
if (worldAmbient < 31.0 || cameraLightSource > 0.0)
{
float depthScaled = min(floor(z * 4.0), 127.0);
float lightSource = 31.0 - (texture(Colormap, vec2(depthScaled/256.0, 0.0)).g*255.0 + worldAmbient);
float lightSource = getLightRampValue(z, worldAmbient);
if (lightSource > 0)
{
light += lightSource;
}
}
light = max(light, ambient);

// Falloff
float falloff = floor(z / 16.0) + floor(z / 32.0);
lightLevel = int(clamp(light - falloff, scaledAmbient, 31.0));
light = getDepthAttenuation(z, ambient, light, 0.0);
}
}
baseColor = int(sampleTexture(Frag_TextureId, uv));
baseColor = sampleTexture(Frag_TextureId, uv);

#ifdef MODEL_TRANSPARENT_PASS
if (baseColor == 0)
{
discard;
}
if (baseColor < 0.5) { discard; }
#endif
}
// Vertex-lit.
if (Frag_TextureMode == 0)
{
float dither = float(int(gl_FragCoord.x) + int(gl_FragCoord.y) & 1);
lightLevel = int(Frag_Light + 0.5*dither);
#ifdef OPT_COLORMAP_INTERP // Smooth out the attenuation.
light = Frag_Light;
#else // Apply dithering like the original.
light = floor(Frag_Light + 0.5*dither);
#endif
}

Out_Color.rgb = getAttenuatedColor(baseColor, lightLevel);
Out_Color.a = 1.0;
}
Out_Color = getFinalColor(baseColor, light);
// Enable solid color rendering for wireframe.
Out_Color.rgb = LightData.x > 64.0 ? vec3(0.3, 0.3, 0.8) : Out_Color.rgb;
}
25 changes: 13 additions & 12 deletions TheForceEngine/Shaders/gpu_render_modelSolid.vert
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
uniform sampler2D Colormap;
#include "Shaders/lighting.h"

uniform vec3 CameraPos;
uniform vec3 CameraRight;
uniform vec3 CameraDir;
Expand All @@ -9,7 +12,6 @@ uniform mat3 ModelMtx;
uniform vec3 ModelPos;
uniform uvec2 PortalInfo;

uniform sampler2D Colormap;
uniform samplerBuffer DrawListPlanes;

// Vertex Data
Expand All @@ -29,8 +31,8 @@ flat out int Frag_TextureMode;

void unpackPortalInfo(uint portalInfo, out uint portalOffset, out uint portalCount)
{
portalCount = (portalInfo >> 13u) & 15u;
portalOffset = portalInfo & 8191u;
portalCount = (portalInfo >> 16u) & 15u;
portalOffset = portalInfo & 65535u;
}

float directionalLighting(vec3 nrm, float scale)
Expand All @@ -42,7 +44,11 @@ float directionalLighting(vec3 nrm, float scale)
float L = max(0.0, dot(nrm, lightDir));
lighting += L * 31.0;
}
#ifdef OPT_COLORMAP_INTERP // Smooth out the attenuation.
return lighting * scale;
#else
return floor(lighting * scale);
#endif
}

void main()
Expand Down Expand Up @@ -87,26 +93,21 @@ void main()
light += dirLighting;

// Calculate Z value and scaled ambient.
float scaledAmbient = ambient * 7.0 / 8.0;
float z = max(0.0, dot((worldPos - CameraPos), CameraDir));

// Camera Light
float worldAmbient = LightData.x;
float cameraLightSource = LightData.y > 63.0 ? 1.0 : 0.0;
float worldAmbient = LightData.x > 64.0 ? LightData.x - 128.0 : LightData.x;
float cameraLightSource = LightData.y > 32.0 ? 1.0 : 0.0;
if (worldAmbient < 31.0 || cameraLightSource > 0.0)
{
float depthScaled = min(floor(z * 4.0), 127.0);
float lightSource = 31.0 - (texture(Colormap, vec2(depthScaled/256.0, 0.0)).g*255.0 + worldAmbient);
float lightSource = getLightRampValue(z, worldAmbient);
if (lightSource > 0)
{
light += lightSource;
}
}
light = max(light, ambient);

// Falloff
float falloff = floor(z / 16.0) + floor(z / 32.0);
light = clamp(light - falloff, scaledAmbient, 31.0);
light = getDepthAttenuation(z, ambient, light, 0.0);
}
else
{
Expand Down
59 changes: 11 additions & 48 deletions TheForceEngine/Shaders/gpu_render_sprite.frag
Original file line number Diff line number Diff line change
@@ -1,51 +1,21 @@
#include "Shaders/textureSampleFunc.h"
#include "Shaders/filter.h"
#include "Shaders/lighting.h"

uniform vec3 CameraPos;
uniform vec3 CameraDir;
uniform vec4 LightData;
uniform vec4 GlobalLightData; // x = flat lighting, y = flat light value.
uniform vec2 SkyParallax;

uniform sampler2D Colormap; // The color map has full RGB pre-backed in.
uniform sampler2D Palette;
uniform sampler2DArray Textures;

uniform isamplerBuffer TextureTable;

in vec2 Frag_Uv;
in vec3 Frag_Pos;
flat in vec3 Frag_Lighting;

flat in int Frag_TextureId;
flat in vec4 Texture_Data;
out vec4 Out_Color;

vec3 getAttenuatedColor(int baseColor, int light)
{
int color = baseColor;
if (light < 31)
{
ivec2 uv = ivec2(color, light);
color = int(texelFetch(Colormap, uv, 0).r * 255.0);
}
return texelFetch(Palette, ivec2(color, 0), 0).rgb;
}

float sampleTextureClamp(int id, vec2 uv)
{
ivec4 sampleData = texelFetch(TextureTable, id);
ivec3 iuv;
iuv.xy = ivec2(uv);
iuv.z = 0;

if ( any(lessThan(iuv.xy, ivec2(0))) || any(greaterThan(iuv.xy, sampleData.zw-1)) )
{
return 0.0;
}

iuv.xy += (sampleData.xy & ivec2(4095));
iuv.z = sampleData.x >> 12;

return texelFetch(Textures, iuv, 0).r * 255.0;
}

void main()
{
vec3 cameraRelativePos = Frag_Pos;
Expand All @@ -67,29 +37,22 @@ void main()
light = 0.0;
if (worldAmbient < 31.0 || cameraLightSource != 0.0)
{
float depthScaled = min(floor(z * 4.0), 127.0);
float lightSource = 31.0 - (texture(Colormap, vec2(depthScaled/256.0, 0.0)).g*255.0 + worldAmbient);
float lightSource = getLightRampValue(z, worldAmbient);
if (lightSource > 0)
{
light += lightSource;
}
}
light = max(light, sectorAmbient);

float minAmbient = sectorAmbient * 7.0 / 8.0;
float depthAtten = floor(z / 16.0f) + floor(z / 32.0f);
light = max(light - depthAtten, minAmbient);
light = clamp(light, 0.0, 31.0);
light = getDepthAttenuation(z, sectorAmbient, light, 0.0);
}
}

// Sample the texture.
baseColor = sampleTextureClamp(Frag_TextureId, Frag_Uv);
if (baseColor < 0.5 && LightData.w < 1.0)
{
discard;
}
if (baseColor < 0.5 && LightData.w < 1.0) { discard; }

Out_Color.rgb = LightData.w > 0.5 ? vec3(0.6, 0.8, 0.6) : getAttenuatedColor(int(baseColor), int(light));
Out_Color.a = 1.0;
Out_Color = getFinalColor(baseColor, light);
// Enable solid color rendering for wireframe.
Out_Color.rgb = LightData.w > 0.5 ? vec3(0.6, 0.8, 0.6) : Out_Color.rgb;
}
4 changes: 2 additions & 2 deletions TheForceEngine/Shaders/gpu_render_sprite.vert
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ flat out int Frag_TextureId;

void unpackPortalInfo(uint portalInfo, out uint portalOffset, out uint portalCount)
{
portalCount = (portalInfo >> 13u) & 15u;
portalOffset = portalInfo & 8191u;
portalCount = (portalInfo >> 16u) & 15u;
portalOffset = portalInfo & 65535u;
}

void main()
Expand Down
Loading

0 comments on commit ab9c59a

Please sign in to comment.