feat: lighting

This commit is contained in:
yuqi.pyq 2019-06-13 19:47:49 +08:00
parent a233c588f4
commit f8269ee35b
7 changed files with 209 additions and 108 deletions

View File

@ -32,35 +32,35 @@ const scene = new L7.Scene({
});
window.scene = scene;
scene.on('loaded', () => {
$.get('https://gw.alipayobjects.com/os/rmsportal/XHMbjQwrSrajvLLvMPbK.json', data => {
scene.PolygonLayer({
zIndex: 0
})
.source(data)
.shape('fill')
.active({fill:'blue'})
.color('rgb(79,174,234)')
.render();
});
$.get('https://gw.alipayobjects.com/os/rmsportal/VifgwJEyBIXnDrjCwWdK.json', data => {
scene.PolygonLayer({
zIndex: 0
})
.source(data)
.shape('fill')
.color('rgb(156,194,116)')
.render();
});
$.get('https://gw.alipayobjects.com/os/rmsportal/ZseLNWMOPGrgqQYfvtli.json', data => {
scene.LineLayer({
zIndex: 2
})
.source(data)
.shape('line')
.size([3,0])
.color('rgb(79,174,234)')
.render();
});
// $.get('https://gw.alipayobjects.com/os/rmsportal/XHMbjQwrSrajvLLvMPbK.json', data => {
// scene.PolygonLayer({
// zIndex: 0
// })
// .source(data)
// .shape('fill')
// .active({fill:'blue'})
// .color('rgb(79,174,234)')
// .render();
// });
// $.get('https://gw.alipayobjects.com/os/rmsportal/VifgwJEyBIXnDrjCwWdK.json', data => {
// scene.PolygonLayer({
// zIndex: 0
// })
// .source(data)
// .shape('fill')
// .color('rgb(156,194,116)')
// .render();
// });
// $.get('https://gw.alipayobjects.com/os/rmsportal/ZseLNWMOPGrgqQYfvtli.json', data => {
// scene.LineLayer({
// zIndex: 2
// })
// .source(data)
// .shape('line')
// .size([3,0])
// .color('rgb(79,174,234)')
// .render();
// });
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
citylayer = scene.PolygonLayer({
@ -69,6 +69,24 @@ scene.on('loaded', () => {
.source(data)
.shape('extrude')
.active({fill:'red'})
// .style({
// lights: [
// {
// type: 'directional',
// direction: [ 1, -10.5, 12 ],
// ambient: [ 0.2, 0.2, 0.2 ],
// diffuse: 'red',
// specular: [ 0.1, 0.1, 0.1 ]
// },
// {
// type: 'directional',
// direction: [ 1, 10.5, 12 ],
// ambient: [ 0.2, 0.2, 0.2 ],
// diffuse: 'green',
// specular: [ 0.1, 0.1, 0.1 ]
// },
// ]
// })
.size('floor',[10,2000])
.color('rgba(242,246,250,0.96)')
.render();

View File

@ -52,11 +52,13 @@ import common from './common.glsl';
import { registerModule } from '../../util/shaderModule';
import pick_color from './shaderChunks/pick_color.glsl';
import decode from './shaderChunks/decode.glsl';
import lighting from './shaderChunks/lighting.glsl';
export function compileBuiltinModules() {
registerModule('point', { vs: point_vert, fs: point_frag });
registerModule('common', { vs: common, fs: common });
registerModule('decode', { vs: decode, fs: '' });
registerModule('lighting', { vs: lighting, fs: '' });
registerModule('pick_color', { vs: pick_color, fs: pick_color });
registerModule('circle', { vs: circle_vert, fs: circle_frag });
registerModule('polygon', { vs: polygon_vert, fs: polygon_frag });

View File

@ -1,5 +1,5 @@
precision highp float;
uniform sampler2D u_texture;
uniform vec4 u_baseColor;
uniform vec4 u_brightColor;
uniform vec4 u_windowColor;
@ -7,10 +7,12 @@ uniform float u_zoom;
uniform float u_time;
uniform float u_near;
uniform float u_far;
#ifdef ANIMATE
varying vec2 v_texCoord;
varying vec4 v_color;
varying float v_lightWeight;
varying float v_size;
#endif
varying vec4 v_color;
varying vec4 worldId;
vec3 getWindowColor(float n, float hot, vec3 brightColor, vec3 darkColor) {
@ -41,12 +43,6 @@ float sdRect(vec2 p, vec2 sz) {
float inside = min(max(d.x, d.y), 0.);
return outside + inside;
}
float circle(in vec2 _st, in float _radius){
vec2 dist = _st-vec2(0.5);
return 1.-smoothstep(_radius-(_radius*0.01),
_radius+(_radius*0.01),
dot(dist,dist)*4.0);
}
void main() {
if(v_color.w == 0.0) {
@ -104,19 +100,13 @@ void main() {
// if(head ==1.0) { // 顶部亮线
// color = brightColor;
// }
color = color * v_lightWeight;
color = v_color.rgb;
vec3 foggedColor = fog(color,fogColor,depth);
gl_FragColor = vec4(foggedColor,1.0);
}
#else
// #ifdef SHAPE
// vec2 st = gl_FragCoord.xy / v_size ;
// vec3 color = vec3(circle(st,0.5));
// gl_FragColor = vec4(color, 1.0 );
// return;
// #endif
gl_FragColor = vec4(v_color.xyz , v_color.w);
#endif

View File

@ -1,61 +1,50 @@
precision highp float;
#define ambientRatio 0.5
#define diffuseRatio 0.4
#define specularRatio 0.1
attribute vec4 a_color;
attribute vec2 faceUv;
attribute vec3 a_shape;
attribute vec3 a_size;
uniform float u_zoom;
uniform float u_opacity;
varying vec2 v_texCoord;
varying vec4 v_color;
varying float v_lightWeight;
varying float v_size;
uniform float u_activeId;
uniform vec4 u_activeColor;
void main() {
float scale = pow(2.0,(20.0 - u_zoom));
mat4 matModelViewProjection = projectionMatrix * modelViewMatrix;
worldId = id_toPickColor(pickingId);
vec3 newposition = position;
// newposition.x -= 128.0;
#ifdef SHAPE
newposition =position + a_size * scale* a_shape + vec3(0., a_size.y * scale / 4., 0.);
#endif
v_texCoord = faceUv;
if(normal == vec3(0.,0.,1.)){
v_color = a_color;
v_color.a *= u_opacity;
if(pickingId == u_activeId) {
v_color = u_activeColor;
}
v_size = a_size.x * scale;
gl_Position = matModelViewProjection * vec4(newposition, 1.0);
return;
}
vec3 worldPos = vec3(vec4(newposition,1.0) * modelMatrix);
vec3 worldNormal = vec3(vec4(normal,1.0) * modelMatrix);
// //cal light weight
vec3 viewDir = normalize(cameraPosition - worldPos);
//vec3 lightDir = normalize(vec3(1, -10.5, 12));
vec3 lightDir = normalize(vec3(0.,-10.,1.));
vec3 halfDir = normalize(viewDir+lightDir);
// //lambert
float lambert = dot(worldNormal, lightDir);
//specular
float specular = pow( max(0.0, dot(worldNormal, halfDir)), 32.0);
//sum to light weight
float lightWeight = ambientRatio + diffuseRatio * lambert + specularRatio * specular;
v_texCoord = faceUv;
v_lightWeight = lightWeight;
v_color =vec4(a_color.rgb*lightWeight, a_color.w);
if(pickingId == u_activeId) {
v_color = u_activeColor;
}
gl_Position = matModelViewProjection * vec4(newposition, 1.0);
attribute vec4 a_color;
#ifdef SHAPE
attribute vec3 a_size;
attribute vec3 a_shape;
#endif
#ifdef ANIMATE
attribute vec2 faceUv;
varying vec2 v_texCoord;
#endif
varying vec4 v_color;
uniform float u_zoom;
uniform float u_opacity : 1.0;
uniform float u_activeId : 0;
uniform vec4 u_activeColor : [1.0, 0.0, 0.0, 1.0];
#pragma include "lighting"
void main() {
#ifdef ANIMATE
v_texCoord = faceUv;
#endif
v_color = a_color;
v_color.a *= u_opacity;
// put offset in world space & shrink with current zoom level
float scale = pow(2.0,(20.0 - u_zoom));
vec3 offset = vec3(0.);
#ifdef SHAPE
offset = vec3(a_size * scale * a_shape);
#endif
gl_Position = projectionMatrix * modelViewMatrix * vec4(position + offset, 1.);
#ifdef LIGHTING
if (normal != vec3(0., 0., 1.)) {
vec3 viewDir = normalize(cameraPosition - position);
v_color.rgb *= calc_lighting(position, normal, viewDir);
}
#endif
if(pickingId == u_activeId) {
v_color = u_activeColor;
}
worldId = id_toPickColor(pickingId);
}

View File

@ -0,0 +1,98 @@
// Blinn-Phong model
// apply lighting in vertex shader instead of fragment shader
// @see https://learnopengl.com/Advanced-Lighting/Advanced-Lighting
// TODO: support point light、spot light & sun light
uniform float u_ambient : 1.0;
uniform float u_diffuse : 1.0;
uniform float u_specular : 1.0;
uniform int u_num_of_directional_lights : 1;
uniform int u_num_of_spot_lights : 0;
#define SHININESS 32.0
#define MAX_NUM_OF_DIRECTIONAL_LIGHTS 3
#define MAX_NUM_OF_SPOT_LIGHTS 3
struct DirectionalLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
struct SpotLight {
vec3 position;
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
float angle;
float blur;
float exponent;
};
uniform DirectionalLight u_directional_lights[MAX_NUM_OF_DIRECTIONAL_LIGHTS];
uniform SpotLight u_spot_lights[MAX_NUM_OF_SPOT_LIGHTS];
vec3 calc_directional_light(DirectionalLight light, vec3 normal, vec3 viewDir) {
vec3 lightDir = normalize(-light.direction);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// Blinn-Phong specular shading
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(normal, halfwayDir), 0.0), SHININESS);
vec3 ambient = light.ambient * u_ambient;
vec3 diffuse = light.diffuse * diff * u_diffuse;
vec3 specular = light.specular * spec * u_specular;
return ambient + diffuse + specular;
}
// vec3 calc_spot_light(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) {
// vec3 lightDir = normalize(light.position - fragPos);
// // diffuse shading
// float diff = max(dot(normal, lightDir), 0.0);
// // specular shading
// vec3 reflectDir = reflect(-lightDir, normal);
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), SHININESS);
// // attenuation
// float distance = length(light.position - fragPos);
// float attenuation = 1.0 / (light.constant + light.linear * distance +
// light.quadratic * (distance * distance));
// vec3 ambient = light.ambient * u_ambient;
// vec3 diffuse = light.diffuse * diff * u_diffuse;
// vec3 specular = light.specular * spec * u_specular;
// float spotEffect = dot(normalize(light.direction), -lightDir);
// float spotCosCutoff = cos(light.angle / 180.0 * PI);
// float spotCosOuterCutoff = cos((light.angle + light.blur) / 180.0 * PI);
// float spotCosInnerCutoff = cos((light.angle - light.blur) / 180.0 * PI);
// if (spotEffect > spotCosCutoff) {
// spotEffect = pow(smoothstep(spotCosOuterCutoff, spotCosInnerCutoff, spotEffect), light.exponent);
// } else {
// spotEffect = 0.0;
// }
// return ambient + attenuation * (spotEffect * diffuse + specular);
// }
vec3 calc_lighting(vec3 position, vec3 normal, vec3 viewDir) {
vec3 weight = vec3(0.0);
for (int i = 0; i < MAX_NUM_OF_DIRECTIONAL_LIGHTS; i++) {
if (i >= u_num_of_directional_lights) {
break;
}
weight += calc_directional_light(u_directional_lights[i], normal, viewDir);
}
// for (int i = 0; i < MAX_NUM_OF_SPOT_LIGHTS; i++) {
// if (i >= u_num_of_spot_lights) {
// break;
// }
// weight += calc_spot_light(u_spot_lights[i], normal, position, viewDir);
// }
return weight;
}

View File

@ -1,6 +1,7 @@
import * as THREE from '../../../core/three';
import PolygonBuffer from '../../../geom/buffer/polygon';
import PolygonMaterial from '../../../geom/material/polygonMaterial';
import { generateLightingUniforms } from '../../../util/shaderModule';
export default function DrawPolygonFill(layerData, layer) {
const style = layer.get('styleOptions');
@ -9,7 +10,7 @@ export default function DrawPolygonFill(layerData, layer) {
...style,
activeColor: activeOption.fill
};
const { opacity, activeColor } = config;
const { opacity, activeColor, lights } = config;
const { attributes } = new PolygonBuffer({
shape: layer.shape,
layerData
@ -21,9 +22,11 @@ export default function DrawPolygonFill(layerData, layer) {
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
const material = new PolygonMaterial({
u_opacity: opacity,
u_activeColor: activeColor
u_activeColor: activeColor,
...generateLightingUniforms(lights)
}, {
SHAPE: false
SHAPE: false,
LIGHTING: true
});
const fillPolygonMesh = new THREE.Mesh(geometry, material);
return fillPolygonMesh;

View File

@ -178,7 +178,8 @@ export function wrapUniforms(uniforms) {
const DEFAULT_LIGHT = {
type: 'directional',
direction: [ 1, 10.5, 12 ],
// direction: [ 1, 10.5, 12 ],
direction: [ 0, -10.5, 1 ],
ambient: [ 0.2, 0.2, 0.2 ],
diffuse: [ 0.6, 0.6, 0.6 ],
specular: [ 0.1, 0.1, 0.1 ]