mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 23:23:07 +00:00
Added gl_light_math and changed pixelpos + lights to be in eye space
This commit is contained in:
parent
f79c442df5
commit
9525d3690f
10 changed files with 140 additions and 12 deletions
|
@ -80,6 +80,11 @@ CUSTOM_CVAR (Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG
|
||||||
gl_RecreateAllAttachedLights();
|
gl_RecreateAllAttachedLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUSTOM_CVAR(Int, gl_light_math, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
{
|
||||||
|
if (self < 0 || self > 2) self = 0;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// Sets up the parameters to render one dynamic light onto one plane
|
// Sets up the parameters to render one dynamic light onto one plane
|
||||||
|
@ -128,10 +133,28 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
||||||
i = 1;
|
i = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float worldPos[4] = { (float)pos.X, (float)pos.Z, (float)pos.Y, 1.0f };
|
||||||
|
float eyePos[4];
|
||||||
|
gl_RenderState.mViewMatrix.multMatrixPoint(worldPos, eyePos);
|
||||||
|
|
||||||
|
if (gl_light_math != 0)
|
||||||
|
{
|
||||||
|
// Adjust light slightly to make the range better match plain attenuation
|
||||||
|
radius *= 1.5;
|
||||||
|
|
||||||
|
// Move light up because flasks/vials have their light source location at/below the floor.
|
||||||
|
//
|
||||||
|
// If the point is exactly on the wall plane it might cause some acne as some pixels could
|
||||||
|
// be in front and some behind. Move light just a tiny bit to avoid this.
|
||||||
|
eyePos[0] += 0.01f;
|
||||||
|
eyePos[1] += 5.01f;
|
||||||
|
eyePos[2] += 0.01f;
|
||||||
|
}
|
||||||
|
|
||||||
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
|
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
|
||||||
data[0] = pos.X;
|
data[0] = eyePos[0];
|
||||||
data[1] = pos.Z;
|
data[1] = eyePos[1];
|
||||||
data[2] = pos.Y;
|
data[2] = eyePos[2];
|
||||||
data[3] = radius;
|
data[3] = radius;
|
||||||
data[4] = r;
|
data[4] = r;
|
||||||
data[5] = g;
|
data[5] = g;
|
||||||
|
|
|
@ -144,6 +144,7 @@ bool FRenderState::ApplyShader()
|
||||||
activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f);
|
activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f);
|
||||||
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
|
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
|
||||||
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
|
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
|
||||||
|
activeShader->muLightMath.Set(gl_light_math);
|
||||||
activeShader->muClipSplit.Set(mClipSplit);
|
activeShader->muClipSplit.Set(mClipSplit);
|
||||||
|
|
||||||
if (mGlowEnabled)
|
if (mGlowEnabled)
|
||||||
|
|
|
@ -246,6 +246,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
||||||
muColormapStart.Init(hShader, "uFixedColormapStart");
|
muColormapStart.Init(hShader, "uFixedColormapStart");
|
||||||
muColormapRange.Init(hShader, "uFixedColormapRange");
|
muColormapRange.Init(hShader, "uFixedColormapRange");
|
||||||
muLightIndex.Init(hShader, "uLightIndex");
|
muLightIndex.Init(hShader, "uLightIndex");
|
||||||
|
muLightMath.Init(hShader, "uLightMath");
|
||||||
muFogColor.Init(hShader, "uFogColor");
|
muFogColor.Init(hShader, "uFogColor");
|
||||||
muDynLightColor.Init(hShader, "uDynLightColor");
|
muDynLightColor.Init(hShader, "uDynLightColor");
|
||||||
muObjectColor.Init(hShader, "uObjectColor");
|
muObjectColor.Init(hShader, "uObjectColor");
|
||||||
|
|
|
@ -221,6 +221,7 @@ class FShader
|
||||||
FUniform1i muFixedColormap;
|
FUniform1i muFixedColormap;
|
||||||
FUniform4f muColormapStart;
|
FUniform4f muColormapStart;
|
||||||
FUniform4f muColormapRange;
|
FUniform4f muColormapRange;
|
||||||
|
FBufferedUniform1i muLightMath;
|
||||||
FBufferedUniform1i muLightIndex;
|
FBufferedUniform1i muLightIndex;
|
||||||
FBufferedUniformPE muFogColor;
|
FBufferedUniformPE muFogColor;
|
||||||
FBufferedUniform4f muDynLightColor;
|
FBufferedUniform4f muDynLightColor;
|
||||||
|
|
|
@ -29,6 +29,7 @@ EXTERN_CVAR (Float, gl_lights_size);
|
||||||
EXTERN_CVAR (Bool, gl_lights_additive);
|
EXTERN_CVAR (Bool, gl_lights_additive);
|
||||||
EXTERN_CVAR (Bool, gl_light_sprites);
|
EXTERN_CVAR (Bool, gl_light_sprites);
|
||||||
EXTERN_CVAR (Bool, gl_light_particles);
|
EXTERN_CVAR (Bool, gl_light_particles);
|
||||||
|
EXTERN_CVAR (Int, gl_light_math);
|
||||||
|
|
||||||
EXTERN_CVAR(Int, gl_fogmode)
|
EXTERN_CVAR(Int, gl_fogmode)
|
||||||
EXTERN_CVAR(Int, gl_lightmode)
|
EXTERN_CVAR(Int, gl_lightmode)
|
||||||
|
|
|
@ -2603,6 +2603,7 @@ GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
|
||||||
GLLIGHTMNU_FORCEADDITIVE = "Force additive lighting";
|
GLLIGHTMNU_FORCEADDITIVE = "Force additive lighting";
|
||||||
GLLIGHTMNU_LIGHTINTENSITY = "Light intensity";
|
GLLIGHTMNU_LIGHTINTENSITY = "Light intensity";
|
||||||
GLLIGHTMNU_LIGHTSIZE = "Light size";
|
GLLIGHTMNU_LIGHTSIZE = "Light size";
|
||||||
|
GLLIGHTMNU_LIGHTMATH = "Light quality";
|
||||||
|
|
||||||
// OpenGL Preferences
|
// OpenGL Preferences
|
||||||
GLPREFMNU_TITLE = "OPENGL PREFERENCES";
|
GLPREFMNU_TITLE = "OPENGL PREFERENCES";
|
||||||
|
@ -2701,3 +2702,6 @@ OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||||
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
||||||
OPTVAL_REINHARD = "Reinhard";
|
OPTVAL_REINHARD = "Reinhard";
|
||||||
OPTVAL_PALETTE = "Palette";
|
OPTVAL_PALETTE = "Palette";
|
||||||
|
OPTVAL_LOW = "Low";
|
||||||
|
OPTVAL_MEDIUM = "Medium";
|
||||||
|
OPTVAL_HIGH = "High";
|
||||||
|
|
|
@ -25,6 +25,13 @@ OptionValue "FilterModes"
|
||||||
4, "$OPTVAL_TRILINEAR"
|
4, "$OPTVAL_TRILINEAR"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OptionValue "LightMathModes"
|
||||||
|
{
|
||||||
|
0, "$OPTVAL_LOW"
|
||||||
|
1, "$OPTVAL_MEDIUM"
|
||||||
|
2, "$OPTVAL_HIGH"
|
||||||
|
}
|
||||||
|
|
||||||
OptionValue "HWGammaModes"
|
OptionValue "HWGammaModes"
|
||||||
{
|
{
|
||||||
0, "$OPTVAL_ON"
|
0, "$OPTVAL_ON"
|
||||||
|
@ -193,6 +200,7 @@ OptionMenu "GLLightOptions"
|
||||||
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
||||||
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
|
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "YesNo"
|
||||||
Option "$GLLIGHTMNU_FORCEADDITIVE", gl_lights_additive, "YesNo"
|
Option "$GLLIGHTMNU_FORCEADDITIVE", gl_lights_additive, "YesNo"
|
||||||
|
Option "$GLLIGHTMNU_LIGHTMATH", gl_light_math, "LightMathModes"
|
||||||
Slider "$GLLIGHTMNU_LIGHTINTENSITY", gl_lights_intensity, 0.0, 1.0, 0.1
|
Slider "$GLLIGHTMNU_LIGHTINTENSITY", gl_lights_intensity, 0.0, 1.0, 0.1
|
||||||
Slider "$GLLIGHTMNU_LIGHTSIZE", gl_lights_size, 0.0, 2.0, 0.1
|
Slider "$GLLIGHTMNU_LIGHTSIZE", gl_lights_size, 0.0, 2.0, 0.1
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,88 @@ vec4 Process(vec4 color);
|
||||||
vec4 ProcessTexel();
|
vec4 ProcessTexel();
|
||||||
vec4 ProcessLight(vec4 color);
|
vec4 ProcessLight(vec4 color);
|
||||||
|
|
||||||
|
// Smoothed normal used for the face, in eye space. Should be converted to an 'in' variable in the future.
|
||||||
|
vec3 pixelnormal;
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Calculates the face normal vector for the fragment, in eye space
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
vec3 calculateFaceNormal()
|
||||||
|
{
|
||||||
|
#if __VERSION__ < 450
|
||||||
|
vec3 dFdxPos = dFdx(pixelpos.xyz);
|
||||||
|
vec3 dFdyPos = dFdy(pixelpos.xyz);
|
||||||
|
#else
|
||||||
|
vec3 dFdxPos = dFdxCoarse(pixelpos.xyz);
|
||||||
|
vec3 dFdyPos = dFdyCoarse(pixelpos.xyz);
|
||||||
|
#endif
|
||||||
|
return normalize(cross(dFdxPos,dFdyPos));
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Standard lambertian diffuse light calculation
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
float diffuseContribution(vec3 eyeLightDirection, vec3 eyeNormal)
|
||||||
|
{
|
||||||
|
return max(dot(eyeNormal, eyeLightDirection), 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Blinn specular light calculation
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
float blinnSpecularContribution(float diffuseContribution, vec3 eyeLightDirection, vec3 eyePosition, vec3 eyeNormal, float glossiness, float specularLevel)
|
||||||
|
{
|
||||||
|
if (diffuseContribution > 0.0f)
|
||||||
|
{
|
||||||
|
vec3 viewDir = normalize(-eyePosition);
|
||||||
|
vec3 halfDir = normalize(eyeLightDirection + viewDir);
|
||||||
|
float specAngle = max(dot(halfDir, eyeNormal), 0.0f);
|
||||||
|
float phExp = glossiness * 4.0f;
|
||||||
|
return specularLevel * pow(specAngle, phExp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Calculates the brightness of a dynamic point light
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
float pointLightAttenuation(vec4 lightpos)
|
||||||
|
{
|
||||||
|
float attenuation = max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
||||||
|
if (uLightMath == 0)
|
||||||
|
{
|
||||||
|
return attenuation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec3 lightDirection = normalize(lightpos.xyz - pixelpos.xyz);
|
||||||
|
float diffuseAmount = diffuseContribution(lightDirection, pixelnormal);
|
||||||
|
if (uLightMath == 1)
|
||||||
|
{
|
||||||
|
return attenuation * diffuseAmount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float specularAmount = blinnSpecularContribution(diffuseAmount, lightDirection, pixelpos.xyz, pixelnormal, 3.0, 1.2);
|
||||||
|
return attenuation * (diffuseAmount + specularAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -223,7 +305,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
||||||
vec4 lightpos = lights[i];
|
vec4 lightpos = lights[i];
|
||||||
vec4 lightcolor = lights[i+1];
|
vec4 lightcolor = lights[i+1];
|
||||||
|
|
||||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||||
dynlight.rgb += lightcolor.rgb;
|
dynlight.rgb += lightcolor.rgb;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -234,7 +316,7 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
||||||
vec4 lightpos = lights[i];
|
vec4 lightpos = lights[i];
|
||||||
vec4 lightcolor = lights[i+1];
|
vec4 lightcolor = lights[i+1];
|
||||||
|
|
||||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||||
dynlight.rgb -= lightcolor.rgb;
|
dynlight.rgb -= lightcolor.rgb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,6 +350,13 @@ void main()
|
||||||
{
|
{
|
||||||
vec4 frag = ProcessTexel();
|
vec4 frag = ProcessTexel();
|
||||||
|
|
||||||
|
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
||||||
|
if (uLightMath != 0) // Remove this if pixelnormal is converted to an 'in' variable
|
||||||
|
{
|
||||||
|
pixelnormal = calculateFaceNormal();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_ALPHATEST
|
#ifndef NO_ALPHATEST
|
||||||
if (frag.a <= uAlphaThreshold) discard;
|
if (frag.a <= uAlphaThreshold) discard;
|
||||||
#endif
|
#endif
|
||||||
|
@ -292,12 +381,11 @@ void main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
fogdist = max(16.0, length(pixelpos.xyz));
|
||||||
}
|
}
|
||||||
fogfactor = exp2 (uFogDensity * fogdist);
|
fogfactor = exp2 (uFogDensity * fogdist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
frag *= getLightColor(fogdist, fogfactor);
|
frag *= getLightColor(fogdist, fogfactor);
|
||||||
|
|
||||||
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
||||||
|
@ -316,7 +404,7 @@ void main()
|
||||||
vec4 lightpos = lights[i];
|
vec4 lightpos = lights[i];
|
||||||
vec4 lightcolor = lights[i+1];
|
vec4 lightcolor = lights[i+1];
|
||||||
|
|
||||||
lightcolor.rgb *= max(lightpos.w - distance(pixelpos.xyz, lightpos.xyz),0.0) / lightpos.w;
|
lightcolor.rgb *= pointLightAttenuation(lightpos);
|
||||||
addlight.rgb += lightcolor.rgb;
|
addlight.rgb += lightcolor.rgb;
|
||||||
}
|
}
|
||||||
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);
|
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);
|
||||||
|
@ -363,7 +451,7 @@ void main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
fogdist = max(16.0, length(pixelpos.xyz));
|
||||||
}
|
}
|
||||||
fogfactor = exp2 (uFogDensity * fogdist);
|
fogfactor = exp2 (uFogDensity * fogdist);
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ void main()
|
||||||
vColor = aColor;
|
vColor = aColor;
|
||||||
|
|
||||||
#ifndef SIMPLE
|
#ifndef SIMPLE
|
||||||
pixelpos.xyz = worldcoord.xyz;
|
pixelpos.xyz = eyeCoordPos.xyz;
|
||||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||||
|
|
||||||
glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y;
|
glowdist.x = -((uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z) - worldcoord.y;
|
||||||
|
|
|
@ -44,6 +44,7 @@ uniform int uFogEnabled;
|
||||||
|
|
||||||
// dynamic lights
|
// dynamic lights
|
||||||
uniform int uLightIndex;
|
uniform int uLightIndex;
|
||||||
|
uniform int uLightMath; // 0, when using only attenuation, 1 for diffuse light, 2 for blinn specular light
|
||||||
|
|
||||||
// quad drawer stuff
|
// quad drawer stuff
|
||||||
#ifdef USE_QUAD_DRAWER
|
#ifdef USE_QUAD_DRAWER
|
||||||
|
|
Loading…
Reference in a new issue