Extrusions: light source calculation with normals (#651)
This commit is contained in:
@@ -5,51 +5,66 @@ 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_light;
|
||||
attribute vec2 a_normal;
|
||||
varying vec4 color;
|
||||
//varying float depth;
|
||||
const float ff = 255.0;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
float l = dot(normalize(r_norm), normalize(u_light));
|
||||
l = clamp((1.0 + l) / 2.0, 0.0, 1.0);
|
||||
return(0.8 + l * 0.2);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// change height by u_alpha
|
||||
// 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);
|
||||
// depth = gl_Position.z;
|
||||
//depth = gl_Position.z;
|
||||
if (u_mode == -1) {
|
||||
;
|
||||
// roof / depth pass
|
||||
// color = u_color[0] * u_alpha;
|
||||
}
|
||||
else if (u_mode == 0) {
|
||||
// roof / depth pass
|
||||
color = u_color[0] * u_alpha;
|
||||
}
|
||||
else if (u_mode == 1) {
|
||||
// sides 1 - use 0xff00
|
||||
// scale direction to -0.5<>0.5
|
||||
float dir = a_light.y / ff;
|
||||
float z = (0.98 + gl_Position.z * 0.02);
|
||||
float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);
|
||||
color = u_color[1];
|
||||
color.rgb *= (0.8 + dir * 0.2) * z * h;
|
||||
color *= u_alpha;
|
||||
}
|
||||
else if (u_mode == 2) {
|
||||
// sides 2 - use 0x00ff
|
||||
float dir = a_light.x / ff;
|
||||
float z = (0.98 + gl_Position.z * 0.02);
|
||||
float h = 0.9 + clamp(a_pos.z / 2000.0, 0.0, 0.1);
|
||||
color = u_color[2];
|
||||
color.rgb *= (0.8 + dir * 0.2) * z * h;
|
||||
} 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);
|
||||
} 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) * z * h;
|
||||
}
|
||||
color *= u_alpha;
|
||||
}
|
||||
else if (u_mode == 3) {
|
||||
// outline
|
||||
// outline
|
||||
float z = (0.98 - gl_Position.z * 0.02);
|
||||
color = u_color[3] * z;
|
||||
}
|
||||
|
||||
@@ -4,35 +4,38 @@ precision highp float;
|
||||
uniform mat4 u_mvp;
|
||||
uniform vec4 u_color;
|
||||
uniform float u_alpha;
|
||||
uniform vec3 u_light;
|
||||
attribute vec4 a_pos;
|
||||
attribute vec2 a_light;
|
||||
attribute vec2 a_normal;
|
||||
varying vec4 color;
|
||||
|
||||
void main() {
|
||||
// change height by u_alpha
|
||||
// change height by u_alpha
|
||||
vec4 pos = a_pos;
|
||||
pos.z *= u_alpha;
|
||||
gl_Position = u_mvp * pos;
|
||||
// normalize face x/y direction
|
||||
vec2 enc = (a_light / 255.0);
|
||||
vec2 fenc = enc * 4.0 - 2.0;
|
||||
float f = dot(fenc, fenc);
|
||||
float g = sqrt(1.0 - f / 4.0);
|
||||
// normalize face x/y direction
|
||||
vec2 enc = (a_normal / 255.0);
|
||||
|
||||
vec3 r_norm;
|
||||
r_norm.xy = fenc * g;
|
||||
r_norm.z = 1.0 - f / 2.0;
|
||||
// normal points up or down (1,-1)
|
||||
//// float dir = 1.0 - (2.0 * abs(mod(a_light.x,2.0)));
|
||||
// recreate face normal vector
|
||||
/// vec3 r_norm = vec3(n.xy, dir * (1.0 - length(n.xy)));
|
||||
vec3 light_dir = normalize(vec3(0.2, 0.2, 1.0));
|
||||
float l = dot(r_norm, light_dir) * 0.8;
|
||||
// 1² - |xy|² = |z|²
|
||||
r_norm.xy = enc * 2.0 - 1.0;
|
||||
// normal points up or down (1,-1)
|
||||
float dir = - 1.0 + (2.0 * abs(mod(a_normal.x, 2.0)));
|
||||
// recreate z vector
|
||||
r_norm.z = dir * sqrt(clamp(1.0 - (r_norm.x * r_norm.x + r_norm.y * r_norm.y), 0.0, 1.0));
|
||||
r_norm = normalize(r_norm);
|
||||
|
||||
light_dir = normalize(vec3(-0.2, -0.2, 1.0));
|
||||
l += dot(r_norm, light_dir) * 0.2;
|
||||
float l = dot(r_norm, normalize(u_light));
|
||||
|
||||
// l = (l + (1.0 - r_norm.z))*0.5;
|
||||
l = 0.4 + l * 0.6;
|
||||
//l *= 0.8
|
||||
//vec3 opp_light_dir = normalize(vec3(-u_light.xy, u_light.z));
|
||||
//l += dot(r_norm, opp_light_dir) * 0.2;
|
||||
|
||||
// [-1,1] to range [0,1]
|
||||
l = (1.0 + l) / 2.0;
|
||||
|
||||
l = 0.75 + l * 0.25;
|
||||
|
||||
// extreme fake-ssao by height
|
||||
l += (clamp(a_pos.z / 2048.0, 0.0, 0.1) - 0.05);
|
||||
|
||||
Reference in New Issue
Block a user