Skip to content

Commit

Permalink
Split up water shaders
Browse files Browse the repository at this point in the history
  • Loading branch information
past-due committed Sep 11, 2023
1 parent ff87aa0 commit b323f32
Show file tree
Hide file tree
Showing 13 changed files with 474 additions and 128 deletions.
2 changes: 2 additions & 0 deletions data/CMakeLists.txt
Expand Up @@ -83,6 +83,7 @@ file(GLOB VK_SHADERS
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_depth.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_depth_only.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_water.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_water_high.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_water_classic.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/decals.vert"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/nolight.vert"
Expand All @@ -103,6 +104,7 @@ file(GLOB VK_SHADERS
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terraindepth.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_depth_only.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/water.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_water_high.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/terrain_water_classic.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/decals.frag"
"${CMAKE_CURRENT_SOURCE_DIR}/base/shaders/vk/nolight.frag"
Expand Down
104 changes: 104 additions & 0 deletions data/base/shaders/terrain_water_high.frag
@@ -0,0 +1,104 @@
// Version directive is set by Warzone when loading the shader
// (This shader supports GLSL 1.20 - 1.50 core.)

// constants overridden by WZ when loading shaders (do not modify here in the shader source!)
#define WZ_MIP_LOAD_BIAS 0.f
//

uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex1_nm;
uniform sampler2D tex2_nm;
uniform sampler2D tex1_sm;
uniform sampler2D tex2_sm;
uniform sampler2D lightmap_tex;

// light colors/intensity:
uniform vec4 emissiveLight;
uniform vec4 ambientLight;
uniform vec4 diffuseLight;
uniform vec4 specularLight;

uniform vec4 fogColor;
uniform int fogEnabled; // whether fog is enabled
uniform float fogEnd;
uniform float fogStart;

#if (!defined(GL_ES) && (__VERSION__ >= 130)) || (defined(GL_ES) && (__VERSION__ >= 300))
#define NEWGL
#define FRAGMENT_INPUT in
#else
#define texture(tex,uv,bias) texture2D(tex,uv,bias)
#define FRAGMENT_INPUT varying
#endif

FRAGMENT_INPUT vec4 uv1_uv2;
FRAGMENT_INPUT vec2 uvLightmap;
FRAGMENT_INPUT float depth;
FRAGMENT_INPUT float depth2;
FRAGMENT_INPUT float vertexDistance;
// light in modelSpace:
FRAGMENT_INPUT vec3 lightDir;
FRAGMENT_INPUT vec3 halfVec;

#ifdef NEWGL
out vec4 FragColor;
#else
#define FragColor gl_FragColor
#endif

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

vec4 main_bumpMapping()
{
vec2 uv1 = uv1_uv2.xy;
vec2 uv2 = uv1_uv2.zw;

vec3 N1 = texture(tex1_nm, uv2, WZ_MIP_LOAD_BIAS).xzy; // y is up in modelSpace
vec3 N2 = texture(tex2_nm, uv1, WZ_MIP_LOAD_BIAS).xzy;
vec3 N; //use overlay blending to mix normal maps properly
N.x = N1.x < 0.5 ? (2.0 * N1.x * N2.x) : (1.0 - 2.0 * (1.0 - N1.x) * (1.0 - N2.x));
N.z = N1.z < 0.5 ? (2.0 * N1.z * N2.z) : (1.0 - 2.0 * (1.0 - N1.z) * (1.0 - N2.z));
N.y = N1.y < 0.5 ? (2.0 * N1.y * N2.y) : (1.0 - 2.0 * (1.0 - N1.y) * (1.0 - N2.y));
if (N == vec3(0.0,0.0,0.0)) {
N = vec3(0.0,1.0,0.0);
} else {
N = normalize(N * 2.0 - 1.0);
}

float lambertTerm = max(dot(N, lightDir), 0.0); // diffuse lighting

// Gaussian specular term computation
float gloss = texture(tex1_sm, uv1, WZ_MIP_LOAD_BIAS).r * texture(tex2_sm, uv2, WZ_MIP_LOAD_BIAS).r;
vec3 H = normalize(halfVec);
float exponent = acos(dot(H, N)) / (gloss + 0.05);
float gaussianTerm = exp(-(exponent * exponent));

vec4 fragColor = (texture(tex1, uv1, WZ_MIP_LOAD_BIAS)+texture(tex2, uv2, WZ_MIP_LOAD_BIAS)) * (gloss+vec4(0.08,0.13,0.15,1.0));
fragColor = fragColor*(ambientLight+diffuseLight*lambertTerm) + specularLight*(1.0-gloss)*gaussianTerm*vec4(1.0,0.843,0.686,1.0);
vec4 lightmap_vec4 = texture(lightmap_tex, uvLightmap, 0.f);
vec4 color = fragColor * vec4(vec3(lightmap_vec4.a), 1.f); // ... * tile brightness / ambient occlusion (stored in lightmap.a);
color.rgb = blendAddEffectLighting(color.rgb, (lightmap_vec4.rgb / 1.5f)); // additive color (from environmental point lights / effects)
return color;
}

void main()
{
vec4 fragColor = main_bumpMapping();
fragColor = mix(fragColor, fragColor-depth*0.0007, depth*0.0009);
fragColor.a = mix(0.25, 1.0, depth2*0.005);

if (fogEnabled > 0)
{
// Calculate linear fog
float fogFactor = (fogEnd - vertexDistance) / (fogEnd - fogStart);
fogFactor = clamp(fogFactor, 0.0, 1.0);

// Return fragment color
fragColor = mix(fragColor, fogColor, fogFactor);
}

FragColor = fragColor;
}
54 changes: 54 additions & 0 deletions data/base/shaders/terrain_water_high.vert
@@ -0,0 +1,54 @@
// Version directive is set by Warzone when loading the shader
// (This shader supports GLSL 1.20 - 1.50 core.)

#if (!defined(GL_ES) && (__VERSION__ >= 130)) || (defined(GL_ES) && (__VERSION__ >= 300))
#define NEWGL
#endif

uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelUVLightmapMatrix;
uniform mat4 ModelUV1Matrix;
uniform mat4 ModelUV2Matrix;

uniform float timeSec;

uniform vec4 cameraPos; // in modelSpace
uniform vec4 sunPos; // in modelSpace, normalized

#ifdef NEWGL
#define VERTEX_INPUT in
#define VERTEX_OUTPUT out
#else
#define VERTEX_INPUT attribute
#define VERTEX_OUTPUT varying
#endif

VERTEX_INPUT vec4 vertex; // w is depth

VERTEX_OUTPUT vec4 uv1_uv2;
VERTEX_OUTPUT vec2 uvLightmap;
VERTEX_OUTPUT float depth;
VERTEX_OUTPUT float depth2;
VERTEX_OUTPUT float vertexDistance;
// light in modelSpace:
VERTEX_OUTPUT vec3 lightDir;
VERTEX_OUTPUT vec3 halfVec;

void main()
{
uvLightmap = (ModelUVLightmapMatrix * vec4(vertex.xyz, 1.f)).xy;
depth = vertex.w;
depth2 = length(vertex.y - vertex.w);

vec2 uv1 = vec2(vertex.x/4.f/128.f + timeSec/80.f, -vertex.z/4.f/128.f + timeSec/40.f); // (ModelUV1Matrix * vertex).xy;
vec2 uv2 = vec2(vertex.x/4.f/128.f, -vertex.z/4.f/128.f - timeSec/40.f); // (ModelUV2Matrix * vertex).xy;
uv1_uv2 = vec4(uv1.x, uv1.y, uv2.x, uv2.y);

vec3 eyeVec = normalize(cameraPos.xyz - vertex.xyz);
lightDir = sunPos.xyz;
halfVec = lightDir + eyeVec;

vec4 position = ModelViewProjectionMatrix * vec4(vertex.xyz, 1.f);
vertexDistance = position.z;
gl_Position = position;
}
1 change: 0 additions & 1 deletion data/base/shaders/vk/terrain_water.vert
Expand Up @@ -16,7 +16,6 @@ layout(std140, set = 0, binding = 0) uniform cbuffer {
float fogEnd;
float fogStart;
float timeSec;
int quality;
};

layout(location = 0) in vec4 vertex; // .w is depth
Expand Down
94 changes: 94 additions & 0 deletions data/base/shaders/vk/terrain_water_high.frag
@@ -0,0 +1,94 @@
#version 450

layout (constant_id = 0) const float WZ_MIP_LOAD_BIAS = 0.f;

layout(set = 1, binding = 0) uniform sampler2D tex1;
layout(set = 1, binding = 1) uniform sampler2D tex2;
layout(set = 1, binding = 2) uniform sampler2D tex1_nm;
layout(set = 1, binding = 3) uniform sampler2D tex2_nm;
layout(set = 1, binding = 4) uniform sampler2D tex1_sm;
layout(set = 1, binding = 5) uniform sampler2D tex2_sm;
layout(set = 1, binding = 6) uniform sampler2D lightmap_tex;

layout(std140, set = 0, binding = 0) uniform cbuffer {
mat4 ModelViewProjectionMatrix;
mat4 ModelUVLightmapMatrix;
mat4 ModelUV1Matrix;
mat4 ModelUV2Matrix;
vec4 cameraPos; // in modelSpace
vec4 sunPos; // in modelSpace, normalized
vec4 emissiveLight; // light colors/intensity
vec4 ambientLight;
vec4 diffuseLight;
vec4 specularLight;
vec4 fogColor;
int fogEnabled; // whether fog is enabled
float fogEnd;
float fogStart;
float timeSec;
};

layout(location = 1) in vec4 uv1_uv2;
layout(location = 2) in vec2 uvLightmap;
layout(location = 3) in float vertexDistance;
layout(location = 4) in vec3 lightDir;
layout(location = 5) in vec3 halfVec;
layout(location = 6) in float depth;
layout(location = 7) in float depth2;

layout(location = 0) out vec4 FragColor;

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

vec4 main_bumpMapping()
{
vec2 uv1 = uv1_uv2.xy;
vec2 uv2 = uv1_uv2.zw;

vec3 N1 = texture(tex1_nm, uv2, WZ_MIP_LOAD_BIAS).xzy; // y is up in modelSpace
vec3 N2 = texture(tex2_nm, uv1, WZ_MIP_LOAD_BIAS).xzy;
vec3 N; //use overlay blending to mix normal maps properly
N.x = N1.x < 0.5 ? (2.0 * N1.x * N2.x) : (1.0 - 2.0 * (1.0 - N1.x) * (1.0 - N2.x));
N.z = N1.z < 0.5 ? (2.0 * N1.z * N2.z) : (1.0 - 2.0 * (1.0 - N1.z) * (1.0 - N2.z));
N.y = N1.y < 0.5 ? (2.0 * N1.y * N2.y) : (1.0 - 2.0 * (1.0 - N1.y) * (1.0 - N2.y));
if (N == vec3(0.0,0.0,0.0)) {
N = vec3(0.0,1.0,0.0);
} else {
N = normalize(N * 2.0 - 1.0);
}
float lambertTerm = max(dot(N, lightDir), 0.0); // diffuse lighting

// Gaussian specular term computation
float gloss = texture(tex1_sm, uv1, WZ_MIP_LOAD_BIAS).r * texture(tex2_sm, uv2, WZ_MIP_LOAD_BIAS).r;
vec3 H = normalize(halfVec);
float exponent = acos(dot(H, N)) / (gloss + 0.05);
float gaussianTerm = exp(-(exponent * exponent));

vec4 fragColor = (texture(tex1, uv1, WZ_MIP_LOAD_BIAS)+texture(tex2, uv2, WZ_MIP_LOAD_BIAS)) * (gloss+vec4(0.08,0.13,0.15,1.0));
fragColor = fragColor*(ambientLight+diffuseLight*lambertTerm) + specularLight*(1.0-gloss)*gaussianTerm*vec4(1.0,0.843,0.686,1.0);
vec4 lightmap_vec4 = texture(lightmap_tex, uvLightmap, 0.f);
vec4 color = fragColor * vec4(vec3(lightmap_vec4.a), 1.f); // ... * tile brightness / ambient occlusion (stored in lightmap.a);
color.rgb = blendAddEffectLighting(color.rgb, (lightmap_vec4.rgb / 1.5f)); // additive color (from environmental point lights / effects)
return color;
}

void main()
{
vec4 fragColor = main_bumpMapping();
fragColor = mix(fragColor, fragColor-depth*0.0007, depth*0.0009);
fragColor.a = mix(0.25, 1.0, depth2*0.005);

if (fogEnabled > 0)
{
// Calculate linear fog
float fogFactor = (fogEnd - vertexDistance) / (fogEnd - fogStart);
fogFactor = clamp(fogFactor, 0.0, 1.0);

// Return fragment color
fragColor = mix(fragColor, fogColor, fogFactor);
}

FragColor = fragColor;
}
50 changes: 50 additions & 0 deletions data/base/shaders/vk/terrain_water_high.vert
@@ -0,0 +1,50 @@
#version 450

layout(std140, set = 0, binding = 0) uniform cbuffer {
mat4 ModelViewProjectionMatrix;
mat4 ModelUVLightmapMatrix;
mat4 ModelUV1Matrix;
mat4 ModelUV2Matrix;
vec4 cameraPos; // in modelSpace
vec4 sunPos; // in modelSpace, normalized
vec4 emissiveLight; // light colors/intensity
vec4 ambientLight;
vec4 diffuseLight;
vec4 specularLight;
vec4 fogColor;
int fogEnabled; // whether fog is enabled
float fogEnd;
float fogStart;
float timeSec;
};

layout(location = 0) in vec4 vertex; // .w is depth

layout(location = 1) out vec4 uv1_uv2;
layout(location = 2) out vec2 uvLightmap;
layout(location = 3) out float vertexDistance;
layout(location = 4) out vec3 lightDir;
layout(location = 5) out vec3 halfVec;
layout(location = 6) out float depth;
layout(location = 7) out float depth2;

void main()
{
uvLightmap = (ModelUVLightmapMatrix * vec4(vertex.xyz, 1.f)).xy;
depth = vertex.w;
depth2 = length(vertex.y - vertex.w);

vec2 uv1 = vec2(vertex.x/4.f/128.f + timeSec/80.f, -vertex.z/4.f/128.f + timeSec/40.f); // (ModelUV1Matrix * vertex).xy;
vec2 uv2 = vec2(vertex.x/4.f/128.f, -vertex.z/4.f/128.f - timeSec/40.f); // (ModelUV2Matrix * vertex).xy;
uv1_uv2 = vec4(uv1.x, uv1.y, uv2.x, uv2.y);

vec3 eyeVec = normalize(cameraPos.xyz - vertex.xyz);
lightDir = sunPos.xyz;
halfVec = lightDir + eyeVec;

vec4 position = ModelViewProjectionMatrix * vec4(vertex.xyz, 1.f);
vertexDistance = position.z;
gl_Position = position;
gl_Position.y *= -1.;
gl_Position.z = (gl_Position.z + gl_Position.w) / 2.0;
}

0 comments on commit b323f32

Please sign in to comment.