Navigation Menu

Skip to content

Commit

Permalink
fix #5190 (redux)
Browse files Browse the repository at this point in the history
  • Loading branch information
rtri committed Apr 1, 2016
1 parent 777ef09 commit 027c669
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 74 deletions.
75 changes: 45 additions & 30 deletions cont/base/springcontent/shaders/GLSL/ModelFragProg.glsl
Expand Up @@ -22,7 +22,8 @@
// contains a distance fading factor [for features], and alphaPass is 1.0
// texture alpha-masking is done in both passes
uniform vec4 teamColor;
uniform float alphaPass;
uniform vec4 nanoColor;
// uniform float alphaPass;

varying vec4 vertexWorldPos;
varying vec3 cameraDir;
Expand Down Expand Up @@ -50,6 +51,43 @@ float GetShadowCoeff(vec4 shadowCoors)
#endif
}

vec3 DynamicLighting(vec3 normal, vec3 diffuse, vec3 specular) {
vec3 rgb;

for (int i = 0; i < MAX_DYNAMIC_MODEL_LIGHTS; i++) {
vec3 lightVec = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].position.xyz - vertexWorldPos.xyz;
vec3 halfVec = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].halfVector.xyz;

float lightRadius = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].constantAttenuation;
float lightDistance = length(lightVec);
float lightScale = float(lightDistance <= lightRadius);

float lightCosAngDiff = clamp(dot(normal, lightVec / lightDistance), 0.0, 1.0);
float lightCosAngSpec = clamp(dot(normal, normalize(halfVec)), 0.0, 1.0);
#ifdef OGL_SPEC_ATTENUATION
float lightAttenuation =
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].constantAttenuation) +
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].linearAttenuation * lightDistance) +
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].quadraticAttenuation * lightDistance * lightDistance);

lightAttenuation = 1.0 / max(lightAttenuation, 1.0);
#else
float lightAttenuation = 1.0 - min(1.0, ((lightDistance * lightDistance) / (lightRadius * lightRadius)));
#endif

float vectorDot = dot((-lightVec / lightDistance), gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].spotDirection);
float cutoffDot = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].spotCosCutoff;

lightScale *= float(vectorDot >= cutoffDot);

rgb += (lightScale * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].ambient.rgb);
rgb += (lightScale * lightAttenuation * (diffuse.rgb * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].diffuse.rgb * lightCosAngDiff));
rgb += (lightScale * lightAttenuation * (specular.rgb * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].specular.rgb * pow(lightCosAngSpec, 4.0)));
}

return rgb;
}

void main(void)
{
#ifdef use_normalmapping
Expand Down Expand Up @@ -89,40 +127,13 @@ void main(void)
#endif

#if (DEFERRED_MODE == 0 && MAX_DYNAMIC_MODEL_LIGHTS > 0)
for (int i = 0; i < MAX_DYNAMIC_MODEL_LIGHTS; i++) {
vec3 lightVec = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].position.xyz - vertexWorldPos.xyz;
vec3 halfVec = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].halfVector.xyz;

float lightRadius = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].constantAttenuation;
float lightDistance = length(lightVec);
float lightScale = (lightDistance > lightRadius)? 0.0: 1.0;
float lightCosAngDiff = clamp(dot(normal, lightVec / lightDistance), 0.0, 1.0);
float lightCosAngSpec = clamp(dot(normal, normalize(halfVec)), 0.0, 1.0);
#ifdef OGL_SPEC_ATTENUATION
float lightAttenuation =
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].constantAttenuation) +
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].linearAttenuation * lightDistance) +
(gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].quadraticAttenuation * lightDistance * lightDistance);

lightAttenuation = 1.0 / max(lightAttenuation, 1.0);
#else
float lightAttenuation = 1.0 - min(1.0, ((lightDistance * lightDistance) / (lightRadius * lightRadius)));
#endif

float vectorDot = dot((-lightVec / lightDistance), gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].spotDirection);
float cutoffDot = gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].spotCosCutoff;

lightScale *= ((vectorDot < cutoffDot)? 0.0: 1.0);

gl_FragColor.rgb += (lightScale * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].ambient.rgb);
gl_FragColor.rgb += (lightScale * lightAttenuation * (diffuse.rgb * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].diffuse.rgb * lightCosAngDiff));
gl_FragColor.rgb += (lightScale * lightAttenuation * (specular.rgb * gl_LightSource[BASE_DYNAMIC_MODEL_LIGHT + i].specular.rgb * pow(lightCosAngSpec, 4.0)));
}
gl_FragColor.rgb += DynamicLighting(normal, diffuse, specular);
#endif

#if (DEFERRED_MODE == 1)
gl_FragData[GBUFFER_NORMTEX_IDX] = vec4((normal + vec3(1.0, 1.0, 1.0)) * 0.5, 1.0);
gl_FragData[GBUFFER_DIFFTEX_IDX] = vec4(mix(diffuse.rgb, teamColor.rgb, diffuse.a), extraColor.a * teamColor.a);
gl_FragData[GBUFFER_DIFFTEX_IDX] = mix(gl_FragData[GBUFFER_DIFFTEX_IDX], nanoColor, float(nanoColor.a != 0.0));
// do not premultiply reflection, leave it to the deferred lighting pass
// gl_FragData[GBUFFER_DIFFTEX_IDX] = vec4(mix(diffuse.rgb, teamColor.rgb, diffuse.a) * reflection, extraColor.a * teamColor.a);
// allows standard-lighting reconstruction by lazy LuaMaterials using us
Expand All @@ -132,6 +143,10 @@ void main(void)
#else
gl_FragColor.rgb = mix(gl_Fog.color.rgb, gl_FragColor.rgb, fogFactor); // fog
gl_FragColor.a = extraColor.a * teamColor.a; // apply one-bit mask

// wireframe or polygon color
gl_FragColor.rgb *= float(nanoColor.a == 0.0);
gl_FragColor.rgb += (nanoColor.rgb * float(nanoColor.a != 0.0));
#endif
}

3 changes: 2 additions & 1 deletion doc/changelog.txt
Expand Up @@ -32,7 +32,7 @@ Save/Load:
Rendering:
- reduce number of team-color updates for custom shaders
- use frame-extrapolation for smoother feature movement
- skip drawing being-built units in deferred pass (requires custom shaders)
- draw all model nanoframe stages with shaders by default
- skip drawing icons for void-space units

AI:
Expand All @@ -49,6 +49,7 @@ Misc:
Bugfixes:
- fix invisible OBJ models
- fix gl.DeleteShader allowing repeated deletion
- fix drawing of being-built units during deferred pass
- fix invisible ground on voidwater maps when AdvMapShading=0 (in L-view)
- fix Spring.SetSunLighting crash when AdvMapShading=0
- fix Spring.ValidUnitID to accept nils again
Expand Down
42 changes: 17 additions & 25 deletions rts/Rendering/UnitDrawer.cpp
Expand Up @@ -520,8 +520,6 @@ bool CUnitDrawer::CanDrawOpaqueUnit(
return false;
if (unit->isIcon)
return false;
if (unit->beingBuilt && !drawBeingBuiltModels)
return false;

if (!(unit->losStatus[gu->myAllyTeam] & LOS_INLOS) && !gu->spectatingFullView)
return false;
Expand Down Expand Up @@ -712,8 +710,6 @@ void CUnitDrawer::SetupAlphaDrawing(bool deferredPass)
unitDrawerStates[DRAWER_STATE_SEL] = const_cast<IUnitDrawerState*>(GetWantedDrawerState(true));
unitDrawerStates[DRAWER_STATE_SEL]->Enable(this, deferredPass && false, true);

drawBeingBuiltModels = !deferredPass;

glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Expand All @@ -724,8 +720,6 @@ void CUnitDrawer::SetupAlphaDrawing(bool deferredPass)

void CUnitDrawer::ResetAlphaDrawing(bool deferredPass)
{
drawBeingBuiltModels = true;

unitDrawerStates[DRAWER_STATE_SEL]->Disable(this, deferredPass && false);

glPopAttrib();
Expand Down Expand Up @@ -958,9 +952,6 @@ void CUnitDrawer::SetupOpaqueDrawing(bool deferredPass)
unitDrawerStates[DRAWER_STATE_SEL] = const_cast<IUnitDrawerState*>(GetWantedDrawerState(false));
unitDrawerStates[DRAWER_STATE_SEL]->Enable(this, deferredPass, false);

// should never execute DrawUnitModelBeingBuilt* in a deferred pass
drawBeingBuiltModels = !deferredPass;

// NOTE:
// when deferredPass is true we MUST be able to use the SSP render-state
// all calling code (reached from DrawOpaquePass(deferred=true)) should
Expand All @@ -971,8 +962,6 @@ void CUnitDrawer::SetupOpaqueDrawing(bool deferredPass)

void CUnitDrawer::ResetOpaqueDrawing(bool deferredPass)
{
drawBeingBuiltModels = true;

unitDrawerStates[DRAWER_STATE_SEL]->Disable(this, deferredPass);

glPopAttrib();
Expand Down Expand Up @@ -1269,6 +1258,7 @@ static const void DrawModelWireBuildStage(
glClipPlane(GL_CLIP_PLANE1, lowerPlane);
}

// FFP-only drawing still needs raw colors
glColorf3(stageColor);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
CUnitDrawer::DrawUnitModel(unit, noLuaCall);
Expand Down Expand Up @@ -1309,6 +1299,7 @@ static const void DrawModelFillBuildStage(
glClipPlane(GL_CLIP_PLANE0, upperPlane);
}

glColorf3(stageColor);
glPolygonOffset(1.0f, 1.0f);
glEnable(GL_POLYGON_OFFSET_FILL);
CUnitDrawer::DrawUnitModel(unit, noLuaCall);
Expand All @@ -1335,9 +1326,6 @@ void CUnitDrawer::DrawUnitModelBeingBuiltShadow(const CUnit* unit, bool noLuaCal

void CUnitDrawer::DrawUnitModelBeingBuiltOpaque(const CUnit* unit, bool noLuaCall)
{
// could allow the last stage in deferred context, but KISS
assert(unitDrawer->DrawBeingBuiltModels());

const S3DModel* model = unit->model;
const CTeam* team = teamHandler->Team(unit->team);
const SColor color = team->color;
Expand Down Expand Up @@ -1374,25 +1362,31 @@ void CUnitDrawer::DrawUnitModelBeingBuiltOpaque(const CUnit* unit, bool noLuaCal
DrawModelBuildStageFunc stageFunc = nullptr;
IUnitDrawerState* selState = unitDrawer->GetDrawerState(DRAWER_STATE_SEL);

selState->DisableShaders(unitDrawer);
selState->DisableTextures(unitDrawer);

glPushAttrib(GL_CURRENT_BIT);
glEnable(GL_CLIP_PLANE0);
glEnable(GL_CLIP_PLANE1);

// wireframe (FFP), unconditional

selState->SetNanoColor(float4(stageColors[0] * wireColorMult, 1.0f));
selState->DisableTextures(unitDrawer);

// wireframe, unconditional
stageFunc = drawModelBuildStageFuncs[(STAGE_WIRE + 1) * true];
stageFunc(unit, &upperPlanes[STAGE_WIRE * 4], &lowerPlanes[STAGE_WIRE * 4], stageColors[0] * wireColorMult, noLuaCall);

// flat-colored (FFP), conditional

selState->SetNanoColor(float4(stageColors[1] * flatColorMult, 1.0f));

// flat-colored, conditional
stageFunc = drawModelBuildStageFuncs[(STAGE_FLAT + 1) * (stageBounds.z > 0.333f)];
stageFunc(unit, &upperPlanes[STAGE_FLAT * 4], &lowerPlanes[STAGE_FLAT * 4], stageColors[1] * flatColorMult, noLuaCall);

glDisable(GL_CLIP_PLANE1);


// pass alpha=0 so shader will ignore nanoColor
selState->SetNanoColor(float4(stageColors[2], 0.0f));
selState->EnableTextures(unitDrawer);
selState->EnableShaders(unitDrawer);

// fully-shaded, conditional
stageFunc = drawModelBuildStageFuncs[(STAGE_FILL + 1) * (stageBounds.z > 0.666f)];
Expand Down Expand Up @@ -1429,11 +1423,9 @@ void CUnitDrawer::DrawUnitNoTrans(

// if called from LuaObjectDrawer, unit has a custom material
//
// DrawUnitBeingBuilt effectively disables the current state
// (killing *any* shader that is currently active) while we
// want Lua-material shaders to have full control over build
// visualisation, so keep it simple and make LOD-calls draw
// the full model
// we want Lua-material shaders to have full control over build
// visualisation, so keep it simple and make LOD-calls draw the
// full model
//
// NOTE: "raw" calls will no longer skip DrawUnitBeingBuilt
//
Expand Down
2 changes: 0 additions & 2 deletions rts/Rendering/UnitDrawer.h
Expand Up @@ -148,8 +148,6 @@ class CUnitDrawer: public CEventClient
bool UseAdvShading() const { return advShading; }
bool& UseAdvShadingRef() { return advShading; }

bool DrawBeingBuiltModels() const { return drawBeingBuiltModels; }

public:
struct TempDrawUnit {
const UnitDef* unitDef;
Expand Down
38 changes: 22 additions & 16 deletions rts/Rendering/UnitDrawerState.cpp
Expand Up @@ -330,12 +330,13 @@ bool UnitDrawerStateGLSL::Init(const CUnitDrawer* ud) {
modelShaders[n]->SetUniformLocation("cameraMat"); // idx 7
modelShaders[n]->SetUniformLocation("cameraMatInv"); // idx 8
modelShaders[n]->SetUniformLocation("teamColor"); // idx 9
modelShaders[n]->SetUniformLocation("sunAmbient"); // idx 10
modelShaders[n]->SetUniformLocation("sunDiffuse"); // idx 11
modelShaders[n]->SetUniformLocation("shadowDensity"); // idx 12
modelShaders[n]->SetUniformLocation("shadowMatrix"); // idx 13
modelShaders[n]->SetUniformLocation("shadowParams"); // idx 14
modelShaders[n]->SetUniformLocation("alphaPass"); // idx 15
modelShaders[n]->SetUniformLocation("nanoColor"); // idx 10
modelShaders[n]->SetUniformLocation("sunAmbient"); // idx 11
modelShaders[n]->SetUniformLocation("sunDiffuse"); // idx 12
modelShaders[n]->SetUniformLocation("shadowDensity"); // idx 13
modelShaders[n]->SetUniformLocation("shadowMatrix"); // idx 14
modelShaders[n]->SetUniformLocation("shadowParams"); // idx 15
// modelShaders[n]->SetUniformLocation("alphaPass"); // idx 16

modelShaders[n]->Enable();
modelShaders[n]->SetUniform1i(0, 0); // diffuseTex (idx 0, texunit 0)
Expand All @@ -344,10 +345,10 @@ bool UnitDrawerStateGLSL::Init(const CUnitDrawer* ud) {
modelShaders[n]->SetUniform1i(3, 3); // reflectTex (idx 3, texunit 3)
modelShaders[n]->SetUniform1i(4, 4); // specularTex (idx 4, texunit 4)
modelShaders[n]->SetUniform3fv(5, &sky->GetLight()->GetLightDir().x);
modelShaders[n]->SetUniform3fv(10, &sunLighting->unitAmbientColor[0]);
modelShaders[n]->SetUniform3fv(11, &sunLighting->unitDiffuseColor[0]);
modelShaders[n]->SetUniform1f(12, sky->GetLight()->GetUnitShadowDensity());
modelShaders[n]->SetUniform1f(15, 0.0f); // alphaPass
modelShaders[n]->SetUniform3fv(11, &sunLighting->unitAmbientColor[0]);
modelShaders[n]->SetUniform3fv(12, &sunLighting->unitDiffuseColor[0]);
modelShaders[n]->SetUniform1f(13, sky->GetLight()->GetUnitShadowDensity());
// modelShaders[n]->SetUniform1f(16, 0.0f); // alphaPass
modelShaders[n]->Disable();
modelShaders[n]->Validate();
}
Expand All @@ -374,8 +375,8 @@ void UnitDrawerStateGLSL::Enable(const CUnitDrawer* ud, bool deferredPass, bool
modelShaders[MODEL_SHADER_ACTIVE]->SetUniform3fv(6, &camera->GetPos()[0]);
modelShaders[MODEL_SHADER_ACTIVE]->SetUniformMatrix4fv(7, false, camera->GetViewMatrix());
modelShaders[MODEL_SHADER_ACTIVE]->SetUniformMatrix4fv(8, false, camera->GetViewMatrixInverse());
modelShaders[MODEL_SHADER_ACTIVE]->SetUniformMatrix4fv(13, false, shadowHandler->GetShadowMatrixRaw());
modelShaders[MODEL_SHADER_ACTIVE]->SetUniform4fv(14, &(shadowHandler->GetShadowParams().x));
modelShaders[MODEL_SHADER_ACTIVE]->SetUniformMatrix4fv(14, false, shadowHandler->GetShadowMatrixRaw());
modelShaders[MODEL_SHADER_ACTIVE]->SetUniform4fv(15, &(shadowHandler->GetShadowParams().x));

const_cast<GL::LightHandler*>(ud->GetLightHandler())->Update(modelShaders[MODEL_SHADER_ACTIVE]);
}
Expand All @@ -397,9 +398,9 @@ void UnitDrawerStateGLSL::UpdateCurrentShaderSky(const CUnitDrawer* ud, const IS
for (unsigned int n = MODEL_SHADER_NOSHADOW_STANDARD; n <= MODEL_SHADER_SHADOWED_DEFERRED; n++) {
modelShaders[n]->Enable();
modelShaders[n]->SetUniform3fv(5, &skyLight->GetLightDir().x);
modelShaders[n]->SetUniform3fv(10, &sunLighting->unitAmbientColor[0]);
modelShaders[n]->SetUniform3fv(11, &sunLighting->unitDiffuseColor[0]);
modelShaders[n]->SetUniform1f(12, skyLight->GetUnitShadowDensity());
modelShaders[n]->SetUniform3fv(11, &sunLighting->unitAmbientColor[0]);
modelShaders[n]->SetUniform3fv(12, &sunLighting->unitDiffuseColor[0]);
modelShaders[n]->SetUniform1f(13, skyLight->GetUnitShadowDensity());
modelShaders[n]->Disable();
}
}
Expand All @@ -410,6 +411,11 @@ void UnitDrawerStateGLSL::SetTeamColor(int team, const float2 alpha) const {
assert(modelShaders[MODEL_SHADER_ACTIVE]->IsBound());

modelShaders[MODEL_SHADER_ACTIVE]->SetUniform4fv(9, std::move(GetTeamColor(team, alpha.x)));
modelShaders[MODEL_SHADER_ACTIVE]->SetUniform1f(15, alpha.y);
// modelShaders[MODEL_SHADER_ACTIVE]->SetUniform1f(16, alpha.y);
}

void UnitDrawerStateGLSL::SetNanoColor(const float4& color) const {
assert(modelShaders[MODEL_SHADER_ACTIVE]->IsBound());
modelShaders[MODEL_SHADER_ACTIVE]->SetUniform4fv(10, color);
}

2 changes: 2 additions & 0 deletions rts/Rendering/UnitDrawerState.hpp
Expand Up @@ -52,6 +52,7 @@ struct IUnitDrawerState {

virtual void UpdateCurrentShaderSky(const CUnitDrawer*, const ISkyLight*) const {}
virtual void SetTeamColor(int team, const float2 alpha) const = 0;
virtual void SetNanoColor(const float4& color) const {}

void SetActiveShader(unsigned int shadowed, unsigned int deferred) {
// shadowed=1 --> shader 1 (deferred=0) or 3 (deferred=1)
Expand Down Expand Up @@ -135,6 +136,7 @@ struct UnitDrawerStateGLSL: public IUnitDrawerState {

void UpdateCurrentShaderSky(const CUnitDrawer*, const ISkyLight*) const;
void SetTeamColor(int team, const float2 alpha) const;
void SetNanoColor(const float4& color) const;
};

#endif
Expand Down

0 comments on commit 027c669

Please sign in to comment.