Make life not suck for whoever wants to edit lighting shaders

pull/593/head
glassmancody.info 4 years ago
parent eecb9886a9
commit d4e7d25d14

@ -1,5 +1,7 @@
#include "advancedpage.hpp" #include "advancedpage.hpp"
#include <unordered_map>
#include <components/config/gamesettings.hpp> #include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp> #include <components/config/launchersettings.hpp>
#include <QFileDialog> #include <QFileDialog>
@ -7,7 +9,6 @@
#include <QProxyStyle> #include <QProxyStyle>
#include <components/contentselector/view/contentselector.hpp> #include <components/contentselector/view/contentselector.hpp>
#include <components/contentselector/model/esmfile.hpp> #include <components/contentselector/model/esmfile.hpp>
#include <components/sceneutil/lightmanager.hpp>
#include <cmath> #include <cmath>
@ -126,10 +127,12 @@ bool Launcher::AdvancedPage::loadSettings()
loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain"); loadSettingBool(activeGridObjectPagingCheckBox, "object paging active grid", "Terrain");
viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera"))); viewingDistanceComboBox->setValue(convertToCells(mEngineSettings.getInt("viewing distance", "Camera")));
auto lightingMethod = SceneUtil::LightManager::getLightingMethodFromString(mEngineSettings.getString("lighting method", "Shaders")); int lightingMethod = 1;
if (lightingMethod == SceneUtil::LightingMethod::Undefined) if (mEngineSettings.getString("lighting method", "Shaders") == "legacy")
lightingMethod = SceneUtil::LightingMethod::PerObjectUniform; lightingMethod = 0;
lightingMethodComboBox->setCurrentIndex(static_cast<int>(lightingMethod)); else if (mEngineSettings.getString("lighting method", "Shaders") == "shaders")
lightingMethod = 2;
lightingMethodComboBox->setCurrentIndex(lightingMethod);
} }
// Camera // Camera
@ -253,8 +256,8 @@ void Launcher::AdvancedPage::saveSettings()
mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance)); mEngineSettings.setInt("viewing distance", "Camera", convertToUnits(viewingDistance));
} }
auto lightingMethodStr = SceneUtil::LightManager::getLightingMethodString(static_cast<SceneUtil::LightingMethod>(lightingMethodComboBox->currentIndex())); static std::unordered_map<int, std::string> lightingMethodMap = {{0, "legacy"}, {1, "shaders compatibility"}, {2, "shaders"}};
mEngineSettings.setString("lighting method", "Shaders", lightingMethodStr); mEngineSettings.setString("lighting method", "Shaders", lightingMethodMap[lightingMethodComboBox->currentIndex()]);
} }
// Camera // Camera

@ -551,7 +551,7 @@ namespace SceneUtil
stateset->setAttributeAndModes(new LightStateAttributePerObjectUniform(std::move(lights), mLightManager), osg::StateAttribute::ON); stateset->setAttributeAndModes(new LightStateAttributePerObjectUniform(std::move(lights), mLightManager), osg::StateAttribute::ON);
stateset->addUniform(new osg::Uniform("PointLightCount", static_cast<int>(lightList.size()))); stateset->addUniform(new osg::Uniform("PointLightCount", static_cast<int>(lightList.size() + 1)));
return stateset; return stateset;
} }
@ -894,10 +894,15 @@ namespace SceneUtil
defines["maxLights"] = std::to_string(getMaxLights()); defines["maxLights"] = std::to_string(getMaxLights());
defines["maxLightsInScene"] = std::to_string(getMaxLightsInScene()); defines["maxLightsInScene"] = std::to_string(getMaxLightsInScene());
defines["lightingModel"] = std::to_string(static_cast<int>(mLightingMethod)); defines["lightingMethodFFP"] = getLightingMethod() == LightingMethod::FFP ? "1" : "0";
defines["useUBO"] = std::to_string(mLightingMethod == LightingMethod::SingleUBO); defines["lightingMethodPerObjectUniform"] = getLightingMethod() == LightingMethod::PerObjectUniform ? "1" : "0";
defines["lightingMethodUBO"] = getLightingMethod() == LightingMethod::SingleUBO ? "1" : "0";
defines["useUBO"] = std::to_string(getLightingMethod() == LightingMethod::SingleUBO);
// exposes bitwise operators // exposes bitwise operators
defines["useGPUShader4"] = std::to_string(mLightingMethod == LightingMethod::SingleUBO); defines["useGPUShader4"] = std::to_string(getLightingMethod() == LightingMethod::SingleUBO);
defines["getLight"] = getLightingMethod() == LightingMethod::FFP ? "gl_LightSource" : "LightBuffer";
defines["startLight"] = getLightingMethod() == LightingMethod::SingleUBO ? "0" : "1";
defines["endLight"] = getLightingMethod() == LightingMethod::FFP ? defines["maxLights"] : "PointLightCount";
return defines; return defines;
} }

@ -18,6 +18,7 @@ set(SHADER_FILES
terrain_vertex.glsl terrain_vertex.glsl
terrain_fragment.glsl terrain_fragment.glsl
lighting.glsl lighting.glsl
lighting_util.glsl
parallax.glsl parallax.glsl
s360_fragment.glsl s360_fragment.glsl
s360_vertex.glsl s360_vertex.glsl

@ -1,98 +1,9 @@
#define LIGHTING_MODEL_FFP 0 #include "lighting_util.glsl"
#define LIGHTING_MODEL_PER_OBJECT_UNIFORM 1
#define LIGHTING_MODEL_SINGLE_UBO 2
#if @lightingModel != LIGHTING_MODEL_FFP void perLightSun(out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal)
#define getLight LightBuffer
float quickstep(float x)
{
x = clamp(x, 0.0, 1.0);
x = 1.0 - x*x;
x = 1.0 - x*x;
return x;
}
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO
const int mask = int(0xff);
const ivec4 shift = ivec4(int(0), int(8), int(16), int(24));
vec3 unpackRGB(int data)
{
return vec3( (float(((data >> shift.x) & mask)) / 255.0)
,(float(((data >> shift.y) & mask)) / 255.0)
,(float(((data >> shift.z) & mask)) / 255.0));
}
vec4 unpackRGBA(int data)
{
return vec4( (float(((data >> shift.x) & mask)) / 255.0)
,(float(((data >> shift.y) & mask)) / 255.0)
,(float(((data >> shift.z) & mask)) / 255.0)
,(float(((data >> shift.w) & mask)) / 255.0));
}
/* Layout:
packedColors: 8-bit unsigned RGB packed as (diffuse, ambient, specular).
sign bit is stored in unused alpha component
attenuation: constant, linear, quadratic, light radius (as defined in content)
*/
struct LightData
{
ivec4 packedColors;
vec4 position;
vec4 attenuation;
};
uniform int PointLightIndex[@maxLights];
uniform int PointLightCount;
// Defaults to shared layout. If we ever move to GLSL 140, std140 layout should be considered
uniform LightBufferBinding
{ {
LightData LightBuffer[@maxLightsInScene]; vec3 sunDiffuse = lcalcDiffuse(0).xyz;
}; vec3 lightDir = normalize(lcalcPosition(0).xyz);
#else
/* Layout:
--------------------------------------- -----------
| pos_x | ambi_r | diff_r | spec_r |
| pos_y | ambi_g | diff_g | spec_g |
| pos_z | ambi_b | diff_b | spec_b |
| att_c | att_l | att_q | radius/spec_a |
--------------------------------------------------
*/
uniform mat4 LightBuffer[@maxLights];
uniform int PointLightCount;
#endif
#else
#define getLight gl_LightSource
#endif
void perLightSun(out vec3 ambientOut, out vec3 diffuseOut, vec3 viewPos, vec3 viewNormal)
{
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
ambientOut = getLight[0][1].xyz;
vec3 sunDiffuse = getLight[0][2].xyz;
vec3 lightDir = normalize(getLight[0][0].xyz);
#elif @lightingModel == LIGHTING_MODEL_SINGLE_UBO
ivec4 data = getLight[0].packedColors;
ambientOut = unpackRGB(data.y);
vec3 sunDiffuse = unpackRGB(data.x);
vec3 lightDir = normalize(getLight[0].position.xyz);
#else // LIGHTING_MODEL_SINGLE_UBO
ambientOut = getLight[0].ambient.xyz;
vec3 sunDiffuse = getLight[0].diffuse.xyz;
vec3 lightDir = normalize(getLight[0].position.xyz);
#endif
float lambert = dot(viewNormal.xyz, lightDir); float lambert = dot(viewNormal.xyz, lightDir);
#ifndef GROUNDCOVER #ifndef GROUNDCOVER
@ -112,21 +23,12 @@ void perLightSun(out vec3 ambientOut, out vec3 diffuseOut, vec3 viewPos, vec3 vi
void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal) void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec3 viewPos, vec3 viewNormal)
{ {
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM vec3 lightPos = lcalcPosition(lightIndex) - viewPos;
vec3 lightPos = getLight[lightIndex][0].xyz - viewPos;
#else
vec3 lightPos = getLight[lightIndex].position.xyz - viewPos;
#endif
float lightDistance = length(lightPos); float lightDistance = length(lightPos);
// cull non-FFP point lighting by radius, light is guaranteed to not fall outside this bound with our cutoff // cull non-FFP point lighting by radius, light is guaranteed to not fall outside this bound with our cutoff
#if @lightingModel != LIGHTING_MODEL_FFP #if !@lightingMethodFFP
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM float radius = lcalcRadius(lightIndex);
float radius = getLight[lightIndex][3][3];
#else
float radius = getLight[lightIndex].attenuation.w;
#endif
if (lightDistance > radius * 2.0) if (lightDistance > radius * 2.0)
{ {
@ -138,22 +40,8 @@ void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec
lightPos = normalize(lightPos); lightPos = normalize(lightPos);
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM float illumination = lcalcIllumination(lightIndex, lightDistance);
float illumination = clamp(1.0 / (getLight[lightIndex][0].w + getLight[lightIndex][1].w * lightDistance + getLight[lightIndex][2].w * lightDistance * lightDistance), 0.0, 1.0); ambientOut = lcalcAmbient(lightIndex) * illumination;
illumination *= 1.0 - quickstep((lightDistance / radius) - 1.0);
ambientOut = getLight[lightIndex][1].xyz * illumination;
#elif @lightingModel == LIGHTING_MODEL_SINGLE_UBO
float illumination = clamp(1.0 / (getLight[lightIndex].attenuation.x + getLight[lightIndex].attenuation.y * lightDistance + getLight[lightIndex].attenuation.z * lightDistance * lightDistance), 0.0, 1.0);
illumination *= 1.0 - quickstep((lightDistance / radius) - 1.0);
ivec4 data = getLight[lightIndex].packedColors;
ambientOut = unpackRGB(data.y) * illumination;
#else
float illumination = clamp(1.0 / (getLight[lightIndex].constantAttenuation + getLight[lightIndex].linearAttenuation * lightDistance + getLight[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0);
ambientOut = getLight[lightIndex].ambient.xyz * illumination;
#endif
float lambert = dot(viewNormal.xyz, lightPos) * illumination; float lambert = dot(viewNormal.xyz, lightPos) * illumination;
#ifndef GROUNDCOVER #ifndef GROUNDCOVER
@ -168,13 +56,7 @@ void perLightPoint(out vec3 ambientOut, out vec3 diffuseOut, int lightIndex, vec
lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0); lambert *= clamp(-8.0 * (1.0 - 0.3) * eyeCosine + 1.0, 0.3, 1.0);
#endif #endif
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO diffuseOut = lcalcDiffuse(lightIndex) * lambert;
diffuseOut = unpackRGB(data.x) * lambert * float(int(data.w));
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
diffuseOut = getLight[lightIndex][2].xyz * lambert;
#else
diffuseOut = getLight[lightIndex].diffuse.xyz * lambert;
#endif
} }
#if PER_PIXEL_LIGHTING #if PER_PIXEL_LIGHTING
@ -186,9 +68,7 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a
vec3 ambientOut, diffuseOut; vec3 ambientOut, diffuseOut;
ambientLight = gl_LightModel.ambient.xyz; ambientLight = gl_LightModel.ambient.xyz;
// sun light perLightSun(diffuseOut, viewPos, viewNormal);
perLightSun(ambientOut, diffuseOut, viewPos, viewNormal);
ambientLight += ambientOut;
#if PER_PIXEL_LIGHTING #if PER_PIXEL_LIGHTING
diffuseLight = diffuseOut * shadowing; diffuseLight = diffuseOut * shadowing;
#else #else
@ -196,43 +76,22 @@ void doLighting(vec3 viewPos, vec3 viewNormal, out vec3 diffuseLight, out vec3 a
diffuseLight = diffuseOut; diffuseLight = diffuseOut;
#endif #endif
// point lights for (int i = @startLight; i < @endLight; ++i)
#if @lightingModel == LIGHTING_MODEL_FFP
for (int i=1; i < @maxLights; ++i)
{
perLightPoint(ambientOut, diffuseOut, i, viewPos, viewNormal);
ambientLight += ambientOut;
diffuseLight += diffuseOut;
}
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
for (int i=1; i <= PointLightCount; ++i)
{
perLightPoint(ambientOut, diffuseOut, i, viewPos, viewNormal);
ambientLight += ambientOut;
diffuseLight += diffuseOut;
}
#else
for (int i=0; i < PointLightCount; ++i)
{ {
#if @lightingMethodUBO
perLightPoint(ambientOut, diffuseOut, PointLightIndex[i], viewPos, viewNormal); perLightPoint(ambientOut, diffuseOut, PointLightIndex[i], viewPos, viewNormal);
#else
perLightPoint(ambientOut, diffuseOut, i, viewPos, viewNormal);
#endif
ambientLight += ambientOut; ambientLight += ambientOut;
diffuseLight += diffuseOut; diffuseLight += diffuseOut;
} }
#endif
} }
vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matSpec) vec3 getSpecular(vec3 viewNormal, vec3 viewDirection, float shininess, vec3 matSpec)
{ {
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO vec3 sunDir = lcalcPosition(0);
vec3 sunDir = getLight[0].position.xyz; vec3 sunSpec = lcalcSpecular(0).xyz;
vec3 sunSpec = unpackRGB(getLight[0].packedColors.z);
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec3 sunDir = getLight[0][0].xyz;
vec3 sunSpec = getLight[0][3].xyz;
#else
vec3 sunSpec = getLight[0].specular.xyz;
vec3 sunDir = getLight[0].position.xyz;
#endif
vec3 lightDir = normalize(sunDir); vec3 lightDir = normalize(sunDir);
float NdotL = dot(viewNormal, lightDir); float NdotL = dot(viewNormal, lightDir);

@ -0,0 +1,131 @@
#if !@lightingMethodFFP
float quickstep(float x)
{
x = clamp(x, 0.0, 1.0);
x = 1.0 - x*x;
x = 1.0 - x*x;
return x;
}
#endif
#if @lightingMethodUBO
const int mask = int(0xff);
const ivec4 shift = ivec4(int(0), int(8), int(16), int(24));
vec3 unpackRGB(int data)
{
return vec3( (float(((data >> shift.x) & mask)) / 255.0)
,(float(((data >> shift.y) & mask)) / 255.0)
,(float(((data >> shift.z) & mask)) / 255.0));
}
vec4 unpackRGBA(int data)
{
return vec4( (float(((data >> shift.x) & mask)) / 255.0)
,(float(((data >> shift.y) & mask)) / 255.0)
,(float(((data >> shift.z) & mask)) / 255.0)
,(float(((data >> shift.w) & mask)) / 255.0));
}
/* Layout:
packedColors: 8-bit unsigned RGB packed as (diffuse, ambient, specular).
sign bit is stored in unused alpha component
attenuation: constant, linear, quadratic, light radius (as defined in content)
*/
struct LightData
{
ivec4 packedColors;
vec4 position;
vec4 attenuation;
};
uniform int PointLightIndex[@maxLights];
uniform int PointLightCount;
// Defaults to shared layout. If we ever move to GLSL 140, std140 layout should be considered
uniform LightBufferBinding
{
LightData LightBuffer[@maxLightsInScene];
};
#elif @lightingMethodPerObjectUniform
/* Layout:
--------------------------------------- -----------
| pos_x | ambi_r | diff_r | spec_r |
| pos_y | ambi_g | diff_g | spec_g |
| pos_z | ambi_b | diff_b | spec_b |
| att_c | att_l | att_q | radius/spec_a |
--------------------------------------------------
*/
uniform mat4 LightBuffer[@maxLights];
uniform int PointLightCount;
#endif
#if !@lightingMethodFFP
float lcalcRadius(int lightIndex)
{
#if @lightingMethodPerObjectUniform
return @getLight[lightIndex][3].w;
#else
return @getLight[lightIndex].attenuation.w;
#endif
}
#endif
float lcalcIllumination(int lightIndex, float lightDistance)
{
#if @lightingMethodPerObjectUniform
float illumination = clamp(1.0 / (@getLight[lightIndex][0].w + @getLight[lightIndex][1].w * lightDistance + @getLight[lightIndex][2].w * lightDistance * lightDistance), 0.0, 1.0);
return (illumination * (1.0 - quickstep((lightDistance / lcalcRadius(lightIndex)) - 1.0)));
#elif @lightingMethodUBO
float illumination = clamp(1.0 / (@getLight[lightIndex].attenuation.x + @getLight[lightIndex].attenuation.y * lightDistance + @getLight[lightIndex].attenuation.z * lightDistance * lightDistance), 0.0, 1.0);
return (illumination * (1.0 - quickstep((lightDistance / lcalcRadius(lightIndex)) - 1.0)));
#else
return clamp(1.0 / (@getLight[lightIndex].constantAttenuation + @getLight[lightIndex].linearAttenuation * lightDistance + @getLight[lightIndex].quadraticAttenuation * lightDistance * lightDistance), 0.0, 1.0);
#endif
}
vec3 lcalcPosition(int lightIndex)
{
#if @lightingMethodPerObjectUniform
return @getLight[lightIndex][0].xyz;
#else
return @getLight[lightIndex].position.xyz;
#endif
}
vec3 lcalcDiffuse(int lightIndex)
{
#if @lightingMethodPerObjectUniform
return @getLight[lightIndex][2].xyz;
#elif @lightingMethodUBO
return unpackRGB(@getLight[lightIndex].packedColors.x) * float(int(@getLight[lightIndex].packedColors.w));
#else
return @getLight[lightIndex].diffuse.xyz;
#endif
}
vec3 lcalcAmbient(int lightIndex)
{
#if @lightingMethodPerObjectUniform
return @getLight[lightIndex][1].xyz;
#elif @lightingMethodUBO
return unpackRGB(@getLight[lightIndex].packedColors.y);
#else
return @getLight[lightIndex].ambient.xyz;
#endif
}
vec4 lcalcSpecular(int lightIndex)
{
#if @lightingMethodPerObjectUniform
return @getLight[lightIndex][3];
#elif @lightingMethodUBO
return unpackRGBA(@getLight[lightIndex].packedColors.z);
#else
return @getLight[lightIndex].specular;
#endif
}

@ -203,11 +203,7 @@ void main(void)
normal3 * midWaves.y + normal4 * smallWaves.x + normal5 * smallWaves.y + rippleAdd); normal3 * midWaves.y + normal4 * smallWaves.x + normal5 * smallWaves.y + rippleAdd);
normal = normalize(vec3(-normal.x * bump, -normal.y * bump, normal.z)); normal = normalize(vec3(-normal.x * bump, -normal.y * bump, normal.z));
#if @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM vec3 lVec = normalize((gl_ModelViewMatrixInverse * vec4(lcalcPosition(0).xyz, 0.0)).xyz);
vec3 lVec = normalize((gl_ModelViewMatrixInverse * vec4(getLight[0][0].xyz, 0.0)).xyz);
#else
vec3 lVec = normalize((gl_ModelViewMatrixInverse * vec4(getLight[0].position.xyz, 0.0)).xyz);
#endif
vec3 cameraPos = (gl_ModelViewMatrixInverse * vec4(0,0,0,1)).xyz; vec3 cameraPos = (gl_ModelViewMatrixInverse * vec4(0,0,0,1)).xyz;
vec3 vVec = normalize(position.xyz - cameraPos.xyz); vec3 vVec = normalize(position.xyz - cameraPos.xyz);
@ -242,13 +238,7 @@ void main(void)
vec3 waterColor = WATER_COLOR * sunFade; vec3 waterColor = WATER_COLOR * sunFade;
#if @lightingModel == LIGHTING_MODEL_SINGLE_UBO vec4 sunSpec = lcalcSpecular(0);
vec4 sunSpec = unpackRGBA(getLight[0].packedColors.z);
#elif @lightingModel == LIGHTING_MODEL_PER_OBJECT_UNIFORM
vec4 sunSpec = getLight[0][3];
#else
vec4 sunSpec = getLight[0].specular;
#endif
#if REFRACTION #if REFRACTION
// refraction // refraction

Loading…
Cancel
Save