assets.shaders.extrusion_layer_ext.glsl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vtm Show documentation
Show all versions of vtm Show documentation
OpenGL vector map library written in Java - running on Android, iOS, Desktop and within the browser.
#ifdef GLES
precision highp float;
#endif
uniform mat4 u_mvp;
uniform vec4 u_color[4];
uniform int u_mode;
uniform float u_alpha;
uniform vec3 u_light;
uniform float u_zlimit;
attribute vec4 a_pos;
attribute vec2 a_normal;
varying vec4 color;
//varying float depth;
const float ff = 255.0;
#ifdef SHADOW
uniform mat4 u_light_mvp;
varying vec4 v_shadow_coords;
#endif
/**
* The diffuse of surface dependent on the light position.
*
* @param r_norm the normal vector of vertex's face
*/
float diffuse(in vec3 r_norm, out bool hasLight) {
float l = dot(normalize(r_norm), normalize(u_light));
hasLight = l > 0.0;
l = clamp((1.0 + l) / 2.0, 0.0, 1.0);
#ifdef SHADOW
if (hasLight) {
//l = (l + (1.0 - r_norm.z)) * 0.5;
l = 0.8 + l * 0.2;
} else {
l = 0.5 + l * 0.3;
}
#else
l = 0.8 + l * 0.2;
#endif
return (l);
}
void main() {
// change height by u_alpha
float height = a_pos.z * u_alpha;
if (height > u_zlimit) {
height = u_zlimit;
}
gl_Position = u_mvp * vec4(a_pos.xy, height, 1.0);
bool hasLight = false;
//depth = gl_Position.z;
if (u_mode == -1) {
;
} else if (u_mode >= 0 && u_mode <= 2) {
vec3 r_norm;
if (u_mode == 0) {
// roof / depth pass
r_norm = vec3(0.0, 0.0, 1.0);
color = u_color[0] * u_alpha;
color.rgb *= diffuse(r_norm, hasLight);
} else {
float lightX = u_mode == 1 ? a_normal.y : a_normal.x;
r_norm.x = (lightX / ff) * 2.0 - 1.0;
// normal points y left or right (1 or -1)
float dir = -1.0 + (2.0 * abs(mod(lightX, 2.0)));
// recreate y vector
r_norm.y = dir * sqrt(clamp(1.0 - (r_norm.x * r_norm.x), 0.0, 1.0));
r_norm.z = 0.0;
float z = (0.98 + gl_Position.z * 0.02);
float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);
if (u_mode == 1) {
// sides 1 - use 0xff00
color = u_color[1];
} else {
// sides 2 - use 0x00ff
color = u_color[2];
}
color.rgb *= diffuse(r_norm, hasLight) * z * h;
}
color *= u_alpha;
} else if (u_mode == 3) {
// outline
float z = (0.98 - gl_Position.z * 0.02);
color = u_color[3] * z;
}
#ifdef SHADOW
if (hasLight) {
vec4 positionFromLight = u_light_mvp * a_pos;
v_shadow_coords = (positionFromLight / positionFromLight.w);
} else {
// Discard shadow on unlighted faces
v_shadow_coords = vec4(-1.0);
}
#endif
}
$$
#ifdef GLES
precision highp float;
#endif
varying vec4 color;
#ifdef SHADOW
varying vec4 v_shadow_coords; // the coords in shadow map
uniform sampler2D u_shadowMap;
uniform vec4 u_lightColor;
uniform float u_shadowRes;
const bool DEBUG = false;
const float transitionDistance = 0.05; // relative transition distance at the border of shadow tex
const float minTrans = 1.0 - transitionDistance;
const int pcfCount = 2; // the number of surrounding pixels to smooth shadow
const float biasOffset = 0.005; // offset to remove shadow acne
const float pcfTexels = float((pcfCount * 2 + 1) * (pcfCount * 2 + 1));
#if GLVERSION == 20
float decodeFloat (vec4 color) {
const vec4 bitShift = vec4(
1.0 / (256.0 * 256.0 * 256.0),
1.0 / (256.0 * 256.0),
1.0 / 256.0,
1.0
);
return dot(color, bitShift);
}
#endif
#endif
void main() {
#ifdef SHADOW
float shadowX = abs((v_shadow_coords.x - 0.5) * 2.0);
float shadowY = abs((v_shadow_coords.y - 0.5) * 2.0);
if (shadowX > 1.0 || shadowY > 1.0) {
// Outside the light texture set to 0.0
gl_FragColor = vec4(color.rgb * u_lightColor.rgb, color.a);
if (DEBUG) {
gl_FragColor = vec4(0.0, 1.0, 0.0, 0.1);
}
} else {
// Inside set to 1.0; make a transition to the border
float shadowOpacity = (shadowX < minTrans && shadowY < minTrans) ? 1.0 :
(1.0 - (max(shadowX - minTrans, shadowY - minTrans) / transitionDistance));
float distanceToLight = clamp(v_shadow_coords.z - biasOffset, 0.0, 1.0); // avoid unexpected shadow
// Smooth shadow at borders
float shadowDiffuse = 0.0;
float texelSize = 1.0 / u_shadowRes;
for (int x = -pcfCount; x <= pcfCount; x++) {
for (int y = -pcfCount; y <= pcfCount; y++) {
#if GLVERSION == 30
float depth = texture2D(u_shadowMap, v_shadow_coords.xy + vec2(x, y) * texelSize).r;
#else
float depth = decodeFloat(texture2D(u_shadowMap, v_shadow_coords.xy + vec2(x, y) * texelSize));
#endif
if (distanceToLight > depth) {
shadowDiffuse += 1.0;
}
}
}
shadowDiffuse /= pcfTexels;
shadowDiffuse *= shadowOpacity;
if (DEBUG && shadowDiffuse < 1.0) {
gl_FragColor = vec4(shadowDiffuse, color.gb, 0.1);
} else {
gl_FragColor = vec4((color.rgb * u_lightColor.rgb) * (1.0 - u_lightColor.a * shadowDiffuse), color.a);
}
}
#else
gl_FragColor = color;
#endif
}