This commit is contained in:
Rachael Alexanderson 2018-02-10 07:09:08 -05:00
commit e5e9b49d82
17 changed files with 232 additions and 171 deletions

View file

@ -52,20 +52,177 @@
#include "gl/textures/gl_material.h"
#include "gl/dynlights/gl_lightbuffer.h"
//==========================================================================
//
//
//
//==========================================================================
static bool IsGlslWhitespace(char c)
{
switch (c)
{
case ' ':
case '\r':
case '\n':
case '\t':
case '\f':
return true;
default:
return false;
}
}
static FString RemoveLegacyUserUniforms(FString code)
{
// User shaders must declare their uniforms via the GLDEFS file.
// The following code searches for uniform declarations in the shader itself and replaces them with whitespace.
long len = (long)code.Len();
char *chars = code.LockBuffer();
long startIndex = 0;
while (true)
{
long matchIndex = code.IndexOf("uniform", startIndex);
if (matchIndex == -1)
break;
bool isKeywordStart = matchIndex == 0 || IsGlslWhitespace(chars[matchIndex - 1]);
bool isKeywordEnd = matchIndex + 7 == len || IsGlslWhitespace(chars[matchIndex + 7]);
if (isKeywordStart && isKeywordEnd)
{
long statementEndIndex = code.IndexOf(';', matchIndex + 7);
if (statementEndIndex == -1)
statementEndIndex = len;
for (long i = matchIndex; i < statementEndIndex; i++)
{
if (!IsGlslWhitespace(chars[i]))
chars[i] = ' ';
}
startIndex = statementEndIndex;
}
else
{
startIndex = matchIndex + 7;
}
}
code.UnlockBuffer();
return code;
}
bool FShader::Load(const char * name, const char * vert_prog_lump, const char * frag_prog_lump, const char * proc_prog_lump, const char * defines)
{
static char buffer[10000];
FString error;
int i_lump = Wads.CheckNumForFullName("shaders/glsl/shaderdefs.i", 0);
if (i_lump == -1) I_Error("Unable to load 'shaders/glsl/shaderdefs.i'");
FMemLump i_data = Wads.ReadLump(i_lump);
FString i_data;
// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here.
i_data += "precision highp int;\n";
i_data += "precision highp float;\n";
i_data += "uniform vec4 uCameraPos;\n";
i_data += "uniform int uTextureMode;\n";
i_data += "uniform float uClipHeight;\n";
i_data += "uniform float uClipHeightDirection;\n";
i_data += "uniform vec2 uClipSplit;\n";
i_data += "uniform vec4 uClipLine;\n";
i_data += "uniform float uAlphaThreshold;\n";
// colors
i_data += "uniform vec4 uObjectColor;\n";
i_data += "uniform vec4 uObjectColor2;\n";
i_data += "uniform vec4 uDynLightColor;\n";
i_data += "uniform vec4 uFogColor;\n";
i_data += "uniform float uDesaturationFactor;\n";
i_data += "uniform float uInterpolationFactor;\n";
// Fixed colormap stuff
i_data += "uniform int uFixedColormap;\n"; // 0, when no fixed colormap, 1 for a light value, 2 for a color blend, 3 for a fog layer
i_data += "uniform vec4 uFixedColormapStart;\n";
i_data += "uniform vec4 uFixedColormapRange;\n";
// Glowing walls stuff
i_data += "uniform vec4 uGlowTopPlane;\n";
i_data += "uniform vec4 uGlowTopColor;\n";
i_data += "uniform vec4 uGlowBottomPlane;\n";
i_data += "uniform vec4 uGlowBottomColor;\n";
i_data += "uniform vec4 uSplitTopPlane;\n";
i_data += "uniform vec4 uSplitBottomPlane;\n";
// Lighting + Fog
i_data += "uniform vec4 uLightAttr;\n";
i_data += "#define uLightLevel uLightAttr.a\n";
i_data += "#define uFogDensity uLightAttr.b\n";
i_data += "#define uLightFactor uLightAttr.g\n";
i_data += "#define uLightDist uLightAttr.r\n";
i_data += "uniform int uFogEnabled;\n";
i_data += "uniform int uPalLightLevels;\n";
i_data += "uniform float uGlobVis;\n"; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
// dynamic lights
i_data += "uniform int uLightIndex;\n";
// Software fuzz scaling
i_data += "uniform int uViewHeight;\n";
// Blinn glossiness and specular level
i_data += "uniform vec2 uSpecularMaterial;\n";
// quad drawer stuff
i_data += "#ifdef USE_QUAD_DRAWER\n";
i_data += "uniform mat4 uQuadVertices;\n";
i_data += "uniform mat4 uQuadTexCoords;\n";
i_data += "uniform int uQuadMode;\n";
i_data += "#endif\n";
// matrices
i_data += "uniform mat4 ProjectionMatrix;\n";
i_data += "uniform mat4 ViewMatrix;\n";
i_data += "uniform mat4 ModelMatrix;\n";
i_data += "uniform mat4 NormalViewMatrix;\n";
i_data += "uniform mat4 NormalModelMatrix;\n";
i_data += "uniform mat4 TextureMatrix;\n";
// light buffers
i_data += "#ifdef SHADER_STORAGE_LIGHTS\n";
i_data += "layout(std430, binding = 1) buffer LightBufferSSO\n";
i_data += "{\n";
i_data += " vec4 lights[];\n";
i_data += "};\n";
i_data += "#elif defined NUM_UBO_LIGHTS\n";
i_data += "uniform LightBufferUBO\n";
i_data += "{\n";
i_data += " vec4 lights[NUM_UBO_LIGHTS];\n";
i_data += "};\n";
i_data += "#endif\n";
// textures
i_data += "uniform sampler2D tex;\n";
i_data += "uniform sampler2D ShadowMap;\n";
i_data += "uniform sampler2D texture2;\n";
i_data += "uniform sampler2D texture3;\n";
i_data += "uniform sampler2D texture4;\n";
i_data += "uniform sampler2D texture5;\n";
i_data += "uniform sampler2D texture6;\n";
// timer data
i_data += "uniform float timer;\n"; // To do: we must search user shaders for this declaration and remove it
// material types
i_data += "#if defined(SPECULAR)\n";
i_data += "#define normaltexture texture2\n";
i_data += "#define speculartexture texture3\n";
i_data += "#define brighttexture texture4\n";
i_data += "#elif defined(PBR)\n";
i_data += "#define normaltexture texture2\n";
i_data += "#define metallictexture texture3\n";
i_data += "#define roughnesstexture texture4\n";
i_data += "#define aotexture texture5\n";
i_data += "#define brighttexture texture6\n";
i_data += "#else\n";
i_data += "#define brighttexture texture2\n";
i_data += "#endif\n";
i_data += "#line 1\n";
int vp_lump = Wads.CheckNumForFullName(vert_prog_lump, 0);
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
@ -120,11 +277,11 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
vp_comb << "#define SUPPORTS_SHADOWMAPS\n";
}
vp_comb << defines << i_data.GetString().GetChars();
vp_comb << defines << i_data.GetChars();
FString fp_comb = vp_comb;
vp_comb << vp_data.GetString().GetChars() << "\n";
fp_comb << fp_data.GetString().GetChars() << "\n";
fp_comb << RemoveLegacyUserUniforms(fp_data.GetString()).GetChars() << "\n";
if (proc_prog_lump != NULL)
{

View file

@ -1,5 +1,4 @@
uniform sampler2D tex;
uniform sampler2D texture2;
in vec4 vTexCoord;
in vec4 vColor;
out vec4 FragColor;

View file

@ -1,13 +1,3 @@
#if defined(SPECULAR)
uniform sampler2D texture4;
#define brighttexture texture4
#elif defined(PBR)
uniform sampler2D texture6;
#define brighttexture texture6
#else
uniform sampler2D texture2;
#define brighttexture texture2
#endif
vec4 ProcessTexel()
{

View file

@ -1,4 +1,3 @@
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,4 +1,3 @@
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,4 +1,3 @@
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,4 +1,3 @@
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
// Fuzz effect as rendered by the software renderer
uniform float timer;
#define FUZZTABLE 50
#define FUZZ_RANDOM_X_SIZE 100

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -1,5 +1,4 @@
//created by Evil Space Tomato
uniform float timer;
vec4 ProcessTexel()
{

View file

@ -12,38 +12,6 @@ out vec4 FragFog;
out vec4 FragNormal;
#endif
#ifdef SHADER_STORAGE_LIGHTS
layout(std430, binding = 1) buffer LightBufferSSO
{
vec4 lights[];
};
#elif defined NUM_UBO_LIGHTS
/*layout(std140)*/ uniform LightBufferUBO
{
vec4 lights[NUM_UBO_LIGHTS];
};
#endif
uniform sampler2D tex;
uniform sampler2D ShadowMap;
#if defined(SPECULAR)
uniform sampler2D texture2;
uniform sampler2D texture3;
#define normaltexture texture2
#define speculartexture texture3
#elif defined(PBR)
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D texture4;
uniform sampler2D texture5;
#define normaltexture texture2
#define metallictexture texture3
#define roughnesstexture texture4
#define aotexture texture5
#endif
vec4 Process(vec4 color);
vec4 ProcessTexel();
vec4 ProcessLight(vec4 color);
@ -432,6 +400,27 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}
float quadraticDistanceAttenuation(vec4 lightpos)
{
float strength = (1.0 + lightpos.w * lightpos.w * 0.25) * 0.5;
vec3 distVec = lightpos.xyz - pixelpos.xyz;
float attenuation = strength / (1.0 + dot(distVec, distVec));
if (attenuation <= 1.0 / 256.0) return 0.0;
return attenuation;
}
float shadowAttenuation(vec4 lightpos, float lightcolorA)
{
#ifdef SUPPORTS_SHADOWMAPS
float shadowIndex = abs(lightcolorA) - 1.0;
return shadowmapAttenuation(lightpos, shadowIndex);
#else
return 1.0;
#endif
}
vec3 applyLight(vec3 albedo, vec3 ambientLight)
{
vec3 worldpos = pixelpos.xyz;
@ -439,12 +428,11 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
albedo = pow(albedo, vec3(2.2)); // sRGB to linear
ambientLight = pow(ambientLight, vec3(2.2));
vec3 normal = ApplyNormalMap();
float metallic = texture(metallictexture, vTexCoord.st).r;
float roughness = texture(roughnesstexture, vTexCoord.st).r;
float ao = texture(aotexture, vTexCoord.st).r;
vec3 N = normalize(normal);
vec3 N = ApplyNormalMap();
vec3 V = normalize(uCameraPos.xyz - worldpos);
vec3 F0 = mix(vec3(0.04), albedo, metallic);
@ -469,28 +457,33 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
vec3 L = normalize(lightpos.xyz - worldpos);
vec3 H = normalize(V + L);
//float distance = length(lightpos.xyz - worldpos);
//float attenuation = 1.0 / (distance * distance);
float attenuation = pointLightAttenuation(lightpos, lightcolor.a).x;
float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
if (lightcolor.a < 0.0)
attenuation *= clamp(dot(N, L), 0.0, 1.0); // Sign bit is the attenuated light flag
vec3 radiance = lightcolor.rgb * attenuation;
if (attenuation > 0.0)
{
attenuation *= shadowAttenuation(lightpos, lightcolor.a);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 radiance = lightcolor.rgb * attenuation;
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
vec3 nominator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
vec3 specular = nominator / max(denominator, 0.001);
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
float NdotL = max(dot(N, L), 0.0);
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
vec3 nominator = NDF * G * F;
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, L), 0.0, 1.0);
vec3 specular = nominator / max(denominator, 0.001);
Lo += (kD * albedo / PI + specular) * radiance;
}
}
//
// subtractive lights
@ -504,28 +497,33 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
vec3 L = normalize(lightpos.xyz - worldpos);
vec3 H = normalize(V + L);
//float distance = length(lightpos.xyz - worldpos);
//float attenuation = 1.0 / (distance * distance);
float attenuation = pointLightAttenuation(lightpos, lightcolor.a).x;
float attenuation = quadraticDistanceAttenuation(lightpos) * shadowAttenuation(lightpos, lightcolor.a);
if (lightspot1.w == 1.0)
attenuation *= spotLightAttenuation(lightpos, lightspot1.xyz, lightspot2.x, lightspot2.y);
if (lightcolor.a < 0.0)
attenuation *= clamp(dot(N, L), 0.0, 1.0); // Sign bit is the attenuated light flag
vec3 radiance = lightcolor.rgb * attenuation;
if (attenuation > 0.0)
{
attenuation *= shadowAttenuation(lightpos, lightcolor.a);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
vec3 radiance = lightcolor.rgb * attenuation;
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
// cook-torrance brdf
float NDF = DistributionGGX(N, H, roughness);
float G = GeometrySmith(N, V, L, roughness);
vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
vec3 nominator = NDF * G * F;
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0);
vec3 specular = nominator / max(denominator, 0.001);
vec3 kS = F;
vec3 kD = (vec3(1.0) - kS) * (1.0 - metallic);
float NdotL = max(dot(N, L), 0.0);
Lo -= (kD * albedo / PI + specular) * radiance * NdotL;
vec3 nominator = NDF * G * F;
float denominator = 4.0 * clamp(dot(N, V), 0.0, 1.0) * clamp(dot(N, L), 0.0, 1.0);
vec3 specular = nominator / max(denominator, 0.001);
Lo -= (kD * albedo / PI + specular) * radiance;
}
}
}
}
@ -533,7 +531,7 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
// Pretend we sampled the sector light level from an irradiance map
vec3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);
vec3 F = fresnelSchlickRoughness(clamp(dot(N, V), 0.0, 1.0), F0, roughness);
vec3 kS = F;
vec3 kD = 1.0 - kS;
@ -544,7 +542,7 @@ vec3 applyLight(vec3 albedo, vec3 ambientLight)
//kD *= 1.0 - metallic;
//const float MAX_REFLECTION_LOD = 4.0;
//vec3 prefilteredColor = textureLod(prefilterMap, R, roughness * MAX_REFLECTION_LOD).rgb;
//vec2 envBRDF = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
//vec2 envBRDF = texture(brdfLUT, vec2(clamp(dot(N, V), 0.0, 1.0), roughness)).rg;
//vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
//vec3 ambient = (kD * diffuse + specular) * ao;

View file

@ -1,71 +0,0 @@
// This file contains common data definitions for both vertex and fragment shader
// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here.
precision highp int;
precision highp float;
uniform vec4 uCameraPos;
uniform int uTextureMode;
uniform float uClipHeight, uClipHeightDirection;
uniform vec2 uClipSplit;
uniform vec4 uClipLine;
uniform float uAlphaThreshold;
// colors
uniform vec4 uObjectColor;
uniform vec4 uObjectColor2;
uniform vec4 uDynLightColor;
uniform vec4 uFogColor;
uniform float uDesaturationFactor;
uniform float uInterpolationFactor;
// Fixed colormap stuff
uniform int uFixedColormap; // 0, when no fixed colormap, 1 for a light value, 2 for a color blend, 3 for a fog layer
uniform vec4 uFixedColormapStart;
uniform vec4 uFixedColormapRange;
// Glowing walls stuff
uniform vec4 uGlowTopPlane;
uniform vec4 uGlowTopColor;
uniform vec4 uGlowBottomPlane;
uniform vec4 uGlowBottomColor;
uniform vec4 uSplitTopPlane;
uniform vec4 uSplitBottomPlane;
// Lighting + Fog
uniform vec4 uLightAttr;
#define uLightLevel uLightAttr.a
#define uFogDensity uLightAttr.b
#define uLightFactor uLightAttr.g
#define uLightDist uLightAttr.r
uniform int uFogEnabled;
uniform int uPalLightLevels;
uniform float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
// dynamic lights
uniform int uLightIndex;
// Software fuzz scaling
uniform int uViewHeight;
// Blinn glossiness and specular level
uniform vec2 uSpecularMaterial;
// quad drawer stuff
#ifdef USE_QUAD_DRAWER
uniform mat4 uQuadVertices;
uniform mat4 uQuadTexCoords;
uniform int uQuadMode;
#endif
// matrices
uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ModelMatrix;
uniform mat4 NormalViewMatrix;
uniform mat4 NormalModelMatrix;
uniform mat4 TextureMatrix;