Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial attempt: use lightmap in the object shader #3375

Merged
merged 1 commit into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion data/base/shaders/tcmask_depth_instanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ VERTEX_INPUT vec4 instancePackedValues; // shaderStretch_ecmState_alphaTest_anim
VERTEX_INPUT vec4 instanceColour;
VERTEX_INPUT vec4 instanceTeamColour;

float when_gt(float x, float y) {
return max(sign(x - y), 0.0);
}

void main()
{
// unpack inputs
Expand All @@ -45,7 +49,10 @@ void main()
vec4 position = vertex;
if (vertex.y <= 0.0) // use vertex here directly to help shader compiler optimization
{
position.y -= stretch;
// NOTE: 'stretch' may be:
// - if positive: building stretching
// - if negative: the height above the terrain of the model intance overall
position.y -= (stretch * when_gt(stretch, 0.f));
}

// Translate every vertex according to the Model View and Projection Matrix
Expand Down
18 changes: 15 additions & 3 deletions data/base/shaders/tcmask_instanced.frag
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ uniform sampler2D TextureTcmask; // tcmask
uniform sampler2D TextureNormal; // normal map
uniform sampler2D TextureSpecular; // specular map
uniform sampler2DArrayShadow shadowMap; // shadow map
uniform sampler2D lightmap_tex;

uniform mat4 ViewMatrix;

Expand Down Expand Up @@ -56,6 +57,7 @@ FRAGMENT_INPUT mat4 NormalMatrix;
FRAGMENT_INPUT vec4 colour;
FRAGMENT_INPUT vec4 teamcolour;
FRAGMENT_INPUT vec4 packed_ecmState_alphaTest;
FRAGMENT_INPUT vec3 uvLightmap; // uvLightmap in .xy, heightAboveTerrain in .z

// For Shadows
FRAGMENT_INPUT vec3 fragPos;
Expand Down Expand Up @@ -289,6 +291,10 @@ float getShadowVisibility()
#endif
}

vec3 blendAddEffectLighting(vec3 a, vec3 b) {
return min(a + b, vec3(1.0));
}

void main()
{
// unpack inputs
Expand Down Expand Up @@ -327,6 +333,9 @@ void main()
vec3 L = normalize(lightDir);
float lambertTerm = max(dot(N, L), 0.0); //diffuse light
float visibility = getShadowVisibility();
vec4 lightmap_vec4 = texture(lightmap_tex, uvLightmap.xy, 0.f);
float distanceAboveTerrain = uvLightmap.z;
float lightmapFactor = 1.0f - (clamp(distanceAboveTerrain, 0.f, 300.f) / 300.f);

if (lambertTerm > 0.0)
{
Expand All @@ -350,7 +359,10 @@ void main()
light += diffuse * lambertTerm * diffuseMap * vanillaFactor;
}
// ambient light maxed for classic models to keep results similar to original
light += ambient * diffuseMap * (1.0 + (1.0 - float(specularmap)));
light += vec4(blendAddEffectLighting(ambient.rgb, ((lightmap_vec4.rgb * lightmapFactor) / 3.f)), ambient.a) * diffuseMap * (1.0 + (1.0 - float(specularmap)));

light.rgb *= visibility;
light.a = 1.0f;

vec4 fragColour;
if (tcmask != 0)
Expand All @@ -359,11 +371,11 @@ void main()
float maskAlpha = texture(TextureTcmask, texCoord, WZ_MIP_LOAD_BIAS).r;

// Apply color using grain merge with tcmask
fragColour = visibility * (light + (teamcolour - 0.5) * maskAlpha) * colour;
fragColour = (light + (teamcolour - 0.5) * maskAlpha) * colour;
}
else
{
fragColour = visibility * light * colour;
fragColour = light * colour;
}

if (ecmEffect)
Expand Down
15 changes: 14 additions & 1 deletion data/base/shaders/tcmask_instanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

uniform mat4 ProjectionMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ModelUVLightmapMatrix;

uniform int hasTangents; // whether tangents were calculated for model
uniform vec4 lightPosition;

Expand Down Expand Up @@ -45,11 +47,16 @@ VERTEX_OUTPUT mat4 NormalMatrix;
VERTEX_OUTPUT vec4 colour;
VERTEX_OUTPUT vec4 teamcolour;
VERTEX_OUTPUT vec4 packed_ecmState_alphaTest;
VERTEX_OUTPUT vec3 uvLightmap; // uvLightmap in .xy, heightAboveTerrain in .z

// for Shadows
VERTEX_OUTPUT vec3 fragPos;
VERTEX_OUTPUT vec3 fragNormal;

float when_gt(float x, float y) {
return max(sign(x - y), 0.0);
}

void main()
{
// unpack inputs
Expand Down Expand Up @@ -93,13 +100,19 @@ void main()
vec4 position = vertex;
if (vertex.y <= 0.0) // use vertex here directly to help shader compiler optimization
{
position.y -= stretch;
// NOTE: 'stretch' may be:
// - if positive: building stretching
// - if negative: the height above the terrain of the model intance overall
position.y -= (stretch * when_gt(stretch, 0.f));
}

vec4 positionModelSpace = instanceModelMatrix * position;
fragPos = positionModelSpace.xyz;
fragNormal = vertexNormal;

float heightAboveTerrain = abs(clamp(sign(stretch), -1.f, 0.f)) * abs(stretch);
uvLightmap = vec3((ModelUVLightmapMatrix * positionModelSpace).xy, position.y + heightAboveTerrain);

// Translate every vertex according to the Model View and Projection Matrix
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ModelViewMatrix;
vec4 gposition = ModelViewProjectionMatrix * position;
Expand Down
9 changes: 8 additions & 1 deletion data/base/shaders/vk/tcmask_depth_instanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ layout(location = 9) in vec4 instancePackedValues; // shaderStretch_ecmState_alp
layout(location = 10) in vec4 instanceColour;
layout(location = 11) in vec4 instanceTeamColour;

float when_gt(float x, float y) {
return max(sign(x - y), 0.0);
}

void main()
{
// unpack inputs
Expand All @@ -26,7 +30,10 @@ void main()
vec4 position = vertex;
if (vertex.y <= 0.0) // use vertex here directly to help shader compiler optimization
{
position.y -= stretch;
// NOTE: 'stretch' may be:
// - if positive: building stretching
// - if negative: the height above the terrain of the model intance overall
position.y -= (stretch * when_gt(stretch, 0.f));
}

// Translate every vertex according to the Model View and Projection Matrix
Expand Down
20 changes: 16 additions & 4 deletions data/base/shaders/vk/tcmask_instanced.frag
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ layout(set = 2, binding = 1) uniform sampler2D TextureTcmask; // tcmask
layout(set = 2, binding = 2) uniform sampler2D TextureNormal; // normal map
layout(set = 2, binding = 3) uniform sampler2D TextureSpecular; // specular map
layout(set = 2, binding = 4) uniform sampler2DArrayShadow shadowMap; // shadow map
layout(set = 2, binding = 5) uniform sampler2D lightmap_tex;

layout(location = 0) in vec4 texCoord_vertexDistance; // vec(2) texCoord, float vertexDistance, (unused float)
layout(location = 1) in vec3 normal;
Expand All @@ -22,8 +23,9 @@ layout(location = 4) in mat4 NormalMatrix;
layout(location = 8) in vec4 colour;
layout(location = 9) in vec4 teamcolour;
layout(location = 10) in vec4 packed_ecmState_alphaTest;
layout(location = 11) in vec3 uvLightmap; // uvLightmap in .xy, heightAboveTerrain in .z
// For Shadows
layout(location = 11) in vec3 fragPos;
layout(location = 12) in vec3 fragPos;
//layout(location = 13) in vec3 fragNormal;

layout(location = 0) out vec4 FragColor;
Expand Down Expand Up @@ -259,6 +261,10 @@ float getShadowVisibility()
}
}

vec3 blendAddEffectLighting(vec3 a, vec3 b) {
return min(a + b, vec3(1.0));
}

void main()
{
// unpack inputs
Expand Down Expand Up @@ -297,6 +303,9 @@ void main()
vec3 L = normalize(lightDir);
float lambertTerm = max(dot(N, L), 0.0); //diffuse light
float visibility = getShadowVisibility();
vec4 lightmap_vec4 = texture(lightmap_tex, uvLightmap.xy, 0.f);
float distanceAboveTerrain = uvLightmap.z;
float lightmapFactor = 1.0f - (clamp(distanceAboveTerrain, 0.f, 300.f) / 300.f);

if (lambertTerm > 0.0)
{
Expand All @@ -320,7 +329,10 @@ void main()
light += diffuse * lambertTerm * diffuseMap * vanillaFactor;
}
// ambient light maxed for classic models to keep results similar to original
light += ambient * diffuseMap * (1.0 + (1.0 - float(specularmap)));
light += vec4(blendAddEffectLighting(ambient.rgb, ((lightmap_vec4.rgb * lightmapFactor) / 3.f)), ambient.a) * diffuseMap * (1.0 + (1.0 - float(specularmap)));

light.rgb *= visibility;
light.a = 1.0f;

vec4 fragColour;
if (tcmask != 0)
Expand All @@ -329,11 +341,11 @@ void main()
float maskAlpha = texture(TextureTcmask, texCoord, WZ_MIP_LOAD_BIAS).r;

// Apply color using grain merge with tcmask
fragColour = visibility * (light + (teamcolour - 0.5) * maskAlpha) * colour;
fragColour = (light + (teamcolour - 0.5) * maskAlpha) * colour;
}
else
{
fragColour = visibility * light * colour;
fragColour = light * colour;
}

if (ecmEffect)
Expand Down
1 change: 1 addition & 0 deletions data/base/shaders/vk/tcmask_instanced.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ layout(std140, set = 0, binding = 0) uniform globaluniforms
{
mat4 ProjectionMatrix;
mat4 ViewMatrix;
mat4 ModelUVLightmapMatrix;
mat4 ShadowMapMVPMatrix[WZ_MAX_SHADOW_CASCADES];
vec4 lightPosition;
vec4 sceneColor;
Expand Down
15 changes: 13 additions & 2 deletions data/base/shaders/vk/tcmask_instanced.vert
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,15 @@ layout(location = 4) out mat4 NormalMatrix;
layout(location = 8) out vec4 colour;
layout(location = 9) out vec4 teamcolour;
layout(location = 10) out vec4 packed_ecmState_alphaTest;
layout(location = 11) out vec3 uvLightmap; // uvLightmap in .xy, heightAboveTerrain in .z
// For Shadows
layout(location = 11) out vec3 fragPos;
layout(location = 12) out vec3 fragPos;
//layout(location = 13) out vec3 fragNormal;

float when_gt(float x, float y) {
return max(sign(x - y), 0.0);
}

void main()
{
// unpack inputs
Expand Down Expand Up @@ -67,13 +72,19 @@ void main()
vec4 position = vertex;
if (vertex.y <= 0.0) // use vertex here directly to help shader compiler optimization
{
position.y -= stretch;
// NOTE: 'stretch' may be:
// - if positive: building stretching
// - if negative: the height above the terrain of the model intance overall
position.y -= (stretch * when_gt(stretch, 0.f));
}

vec4 positionModelSpace = instanceModelMatrix * position;
fragPos = positionModelSpace.xyz;
// fragNormal = vertexNormal;

float heightAboveTerrain = abs(clamp(sign(stretch), -1.f, 0.f)) * abs(stretch);
uvLightmap = vec3((ModelUVLightmapMatrix * positionModelSpace).xy, position.y + heightAboveTerrain);

// Translate every vertex according to the Model View and Projection Matrix
mat4 ModelViewProjectionMatrix = ProjectionMatrix * ModelViewMatrix;
vec4 gposition = ModelViewProjectionMatrix * position;
Expand Down
4 changes: 3 additions & 1 deletion lib/ivis_opengl/gfx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,7 @@ namespace gfx_api
{
glm::mat4 ProjectionMatrix;
glm::mat4 ViewMatrix;
glm::mat4 ModelUVLightmapMatrix;
glm::mat4 ShadowMapMVPMatrix[WZ_MAX_SHADOW_CASCADES];
glm::vec4 sunPos;
glm::vec4 sceneColor;
Expand Down Expand Up @@ -797,7 +798,8 @@ namespace gfx_api
texture_description<1, sampler_type::bilinear>, // team color mask
texture_description<2, sampler_type::anisotropic>, // normal map
texture_description<3, sampler_type::anisotropic>, // specular map
texture_description<4, sampler_type::bilinear_border, pixel_format_target::depth_map, border_color::opaque_white> // depth / shadow map
texture_description<4, sampler_type::bilinear_border, pixel_format_target::depth_map, border_color::opaque_white>, // depth / shadow map
texture_description<5, sampler_type::bilinear> // lightmap
>, shader>;

using Draw3DShapeOpaque_Instanced = Draw3DShapeInstanced<REND_OPAQUE, SHADER_COMPONENT_INSTANCED, DEPTH_CMP_LEQ_WRT_ON>;
Expand Down
42 changes: 22 additions & 20 deletions lib/ivis_opengl/gfx_api_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,12 +647,13 @@ static const std::map<SHADER_MODE, program_data> shader_to_file_table =
std::make_pair(SHADER_COMPONENT_INSTANCED, program_data{ "Component program", "shaders/tcmask_instanced.vert", "shaders/tcmask_instanced.frag",
{
// per-frame global uniforms
"ProjectionMatrix", "ViewMatrix", "ShadowMapMVPMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular", "fogColor", "ShadowMapCascadeSplits", "ShadowMapSize", "fogEnd", "fogStart", "graphicsCycle", "fogEnabled",
"ProjectionMatrix", "ViewMatrix", "ModelUVLightmapMatrix", "ShadowMapMVPMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular", "fogColor", "ShadowMapCascadeSplits", "ShadowMapSize", "fogEnd", "fogStart", "graphicsCycle", "fogEnabled",
// per-mesh uniforms
"tcmask", "normalmap", "specularmap", "hasTangents"
},
{
{"shadowMap", 4}
{"shadowMap", 4},
{"lightmap_tex", 5}
} }),
std::make_pair(SHADER_COMPONENT_DEPTH_INSTANCED, program_data{ "Component program", "shaders/tcmask_depth_instanced.vert", "shaders/tcmask_depth_instanced.frag",
{
Expand All @@ -671,7 +672,7 @@ static const std::map<SHADER_MODE, program_data> shader_to_file_table =
std::make_pair(SHADER_NOLIGHT_INSTANCED, program_data{ "Plain program", "shaders/nolight_instanced.vert", "shaders/nolight_instanced.frag",
{
// per-frame global uniforms
"ProjectionMatrix", "ViewMatrix", "ShadowMapMVPMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular", "fogColor", "ShadowMapCascadeSplits", "ShadowMapSize", "fogEnd", "fogStart", "graphicsCycle", "fogEnabled",
"ProjectionMatrix", "ViewMatrix", "ModelUVLightmapMatrix", "ShadowMapMVPMatrix", "lightPosition", "sceneColor", "ambient", "diffuse", "specular", "fogColor", "ShadowMapCascadeSplits", "ShadowMapSize", "fogEnd", "fogStart", "graphicsCycle", "fogEnabled",
// per-mesh uniforms
"tcmask", "normalmap", "specularmap", "hasTangents",
},
Expand Down Expand Up @@ -1862,27 +1863,28 @@ void gl_pipeline_state_object::set_constants(const gfx_api::Draw3DShapeInstanced
{
setUniforms(0, cbuf.ProjectionMatrix);
setUniforms(1, cbuf.ViewMatrix);
setUniforms(2, cbuf.ShadowMapMVPMatrix, WZ_MAX_SHADOW_CASCADES);
setUniforms(3, cbuf.sunPos);
setUniforms(4, cbuf.sceneColor);
setUniforms(5, cbuf.ambient);
setUniforms(6, cbuf.diffuse);
setUniforms(7, cbuf.specular);
setUniforms(8, cbuf.fogColour);
setUniforms(9, cbuf.ShadowMapCascadeSplits);
setUniforms(10, cbuf.ShadowMapSize);
setUniforms(11, cbuf.fogEnd);
setUniforms(12, cbuf.fogBegin);
setUniforms(13, cbuf.timeState);
setUniforms(14, cbuf.fogEnabled);
setUniforms(2, cbuf.ModelUVLightmapMatrix);
setUniforms(3, cbuf.ShadowMapMVPMatrix, WZ_MAX_SHADOW_CASCADES);
setUniforms(4, cbuf.sunPos);
setUniforms(5, cbuf.sceneColor);
setUniforms(6, cbuf.ambient);
setUniforms(7, cbuf.diffuse);
setUniforms(8, cbuf.specular);
setUniforms(9, cbuf.fogColour);
setUniforms(10, cbuf.ShadowMapCascadeSplits);
setUniforms(11, cbuf.ShadowMapSize);
setUniforms(12, cbuf.fogEnd);
setUniforms(13, cbuf.fogBegin);
setUniforms(14, cbuf.timeState);
setUniforms(15, cbuf.fogEnabled);
}

void gl_pipeline_state_object::set_constants(const gfx_api::Draw3DShapeInstancedPerMeshUniforms& cbuf)
{
setUniforms(15, cbuf.tcmask);
setUniforms(16, cbuf.normalMap);
setUniforms(17, cbuf.specularMap);
setUniforms(18, cbuf.hasTangents);
setUniforms(16, cbuf.tcmask);
setUniforms(17, cbuf.normalMap);
setUniforms(18, cbuf.specularMap);
setUniforms(19, cbuf.hasTangents);
}

void gl_pipeline_state_object::set_constants(const gfx_api::Draw3DShapeInstancedDepthOnlyGlobalUniforms& cbuf)
Expand Down
Loading
Loading