mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +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();
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -128,10 +133,28 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bo
|
|||
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)];
|
||||
data[0] = pos.X;
|
||||
data[1] = pos.Z;
|
||||
data[2] = pos.Y;
|
||||
data[0] = eyePos[0];
|
||||
data[1] = eyePos[1];
|
||||
data[2] = eyePos[2];
|
||||
data[3] = radius;
|
||||
data[4] = r;
|
||||
data[5] = g;
|
||||
|
|
|
@ -144,6 +144,7 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f);
|
||||
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
|
||||
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
|
||||
activeShader->muLightMath.Set(gl_light_math);
|
||||
activeShader->muClipSplit.Set(mClipSplit);
|
||||
|
||||
if (mGlowEnabled)
|
||||
|
|
|
@ -246,6 +246,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
muColormapStart.Init(hShader, "uFixedColormapStart");
|
||||
muColormapRange.Init(hShader, "uFixedColormapRange");
|
||||
muLightIndex.Init(hShader, "uLightIndex");
|
||||
muLightMath.Init(hShader, "uLightMath");
|
||||
muFogColor.Init(hShader, "uFogColor");
|
||||
muDynLightColor.Init(hShader, "uDynLightColor");
|
||||
muObjectColor.Init(hShader, "uObjectColor");
|
||||
|
|
|
@ -221,6 +221,7 @@ class FShader
|
|||
FUniform1i muFixedColormap;
|
||||
FUniform4f muColormapStart;
|
||||
FUniform4f muColormapRange;
|
||||
FBufferedUniform1i muLightMath;
|
||||
FBufferedUniform1i muLightIndex;
|
||||
FBufferedUniformPE muFogColor;
|
||||
FBufferedUniform4f muDynLightColor;
|
||||
|
|
|
@ -29,6 +29,7 @@ EXTERN_CVAR (Float, gl_lights_size);
|
|||
EXTERN_CVAR (Bool, gl_lights_additive);
|
||||
EXTERN_CVAR (Bool, gl_light_sprites);
|
||||
EXTERN_CVAR (Bool, gl_light_particles);
|
||||
EXTERN_CVAR (Int, gl_light_math);
|
||||
|
||||
EXTERN_CVAR(Int, gl_fogmode)
|
||||
EXTERN_CVAR(Int, gl_lightmode)
|
||||
|
|
|
@ -2603,6 +2603,7 @@ GLLIGHTMNU_LIGHTPARTICLES = "Lights affect particles";
|
|||
GLLIGHTMNU_FORCEADDITIVE = "Force additive lighting";
|
||||
GLLIGHTMNU_LIGHTINTENSITY = "Light intensity";
|
||||
GLLIGHTMNU_LIGHTSIZE = "Light size";
|
||||
GLLIGHTMNU_LIGHTMATH = "Light quality";
|
||||
|
||||
// OpenGL Preferences
|
||||
GLPREFMNU_TITLE = "OPENGL PREFERENCES";
|
||||
|
@ -2700,4 +2701,7 @@ OPTVAL_QUADBUFFERED = "Quad-buffered";
|
|||
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
||||
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"
|
||||
}
|
||||
|
||||
OptionValue "LightMathModes"
|
||||
{
|
||||
0, "$OPTVAL_LOW"
|
||||
1, "$OPTVAL_MEDIUM"
|
||||
2, "$OPTVAL_HIGH"
|
||||
}
|
||||
|
||||
OptionValue "HWGammaModes"
|
||||
{
|
||||
0, "$OPTVAL_ON"
|
||||
|
@ -193,6 +200,7 @@ OptionMenu "GLLightOptions"
|
|||
Option "$GLLIGHTMNU_LIGHTSPRITES", gl_light_sprites, "YesNo"
|
||||
Option "$GLLIGHTMNU_LIGHTPARTICLES", gl_light_particles, "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_LIGHTSIZE", gl_lights_size, 0.0, 2.0, 0.1
|
||||
}
|
||||
|
|
|
@ -25,6 +25,88 @@ vec4 Process(vec4 color);
|
|||
vec4 ProcessTexel();
|
||||
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 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;
|
||||
}
|
||||
//
|
||||
|
@ -233,8 +315,8 @@ vec4 getLightColor(float fogdist, float fogfactor)
|
|||
{
|
||||
vec4 lightpos = lights[i];
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +349,13 @@ vec4 applyFog(vec4 frag, float fogfactor)
|
|||
void main()
|
||||
{
|
||||
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
|
||||
if (frag.a <= uAlphaThreshold) discard;
|
||||
|
@ -292,12 +381,11 @@ void main()
|
|||
}
|
||||
else
|
||||
{
|
||||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
||||
fogdist = max(16.0, length(pixelpos.xyz));
|
||||
}
|
||||
fogfactor = exp2 (uFogDensity * fogdist);
|
||||
}
|
||||
|
||||
|
||||
frag *= getLightColor(fogdist, fogfactor);
|
||||
|
||||
#if defined NUM_UBO_LIGHTS || defined SHADER_STORAGE_LIGHTS
|
||||
|
@ -316,7 +404,7 @@ void main()
|
|||
vec4 lightpos = lights[i];
|
||||
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;
|
||||
}
|
||||
frag.rgb = clamp(frag.rgb + desaturate(addlight).rgb, 0.0, 1.0);
|
||||
|
@ -363,7 +451,7 @@ void main()
|
|||
}
|
||||
else
|
||||
{
|
||||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
||||
fogdist = max(16.0, length(pixelpos.xyz));
|
||||
}
|
||||
fogfactor = exp2 (uFogDensity * fogdist);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ void main()
|
|||
vColor = aColor;
|
||||
|
||||
#ifndef SIMPLE
|
||||
pixelpos.xyz = worldcoord.xyz;
|
||||
pixelpos.xyz = eyeCoordPos.xyz;
|
||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||
|
||||
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
|
||||
uniform int uLightIndex;
|
||||
uniform int uLightMath; // 0, when using only attenuation, 1 for diffuse light, 2 for blinn specular light
|
||||
|
||||
// quad drawer stuff
|
||||
#ifdef USE_QUAD_DRAWER
|
||||
|
|
Loading…
Reference in a new issue