mirror of https://gitee.com/antv-l7/antv-l7
feat: lighting
This commit is contained in:
parent
37049f4301
commit
bfe3ab89e2
|
@ -32,35 +32,35 @@ const scene = new L7.Scene({
|
||||||
});
|
});
|
||||||
window.scene = scene;
|
window.scene = scene;
|
||||||
scene.on('loaded', () => {
|
scene.on('loaded', () => {
|
||||||
$.get('https://gw.alipayobjects.com/os/rmsportal/XHMbjQwrSrajvLLvMPbK.json', data => {
|
// $.get('https://gw.alipayobjects.com/os/rmsportal/XHMbjQwrSrajvLLvMPbK.json', data => {
|
||||||
scene.PolygonLayer({
|
// scene.PolygonLayer({
|
||||||
zIndex: 0
|
// zIndex: 0
|
||||||
})
|
// })
|
||||||
.source(data)
|
// .source(data)
|
||||||
.shape('fill')
|
// .shape('fill')
|
||||||
.active({fill:'blue'})
|
// .active({fill:'blue'})
|
||||||
.color('rgb(79,174,234)')
|
// .color('rgb(79,174,234)')
|
||||||
.render();
|
// .render();
|
||||||
});
|
// });
|
||||||
$.get('https://gw.alipayobjects.com/os/rmsportal/VifgwJEyBIXnDrjCwWdK.json', data => {
|
// $.get('https://gw.alipayobjects.com/os/rmsportal/VifgwJEyBIXnDrjCwWdK.json', data => {
|
||||||
scene.PolygonLayer({
|
// scene.PolygonLayer({
|
||||||
zIndex: 0
|
// zIndex: 0
|
||||||
})
|
// })
|
||||||
.source(data)
|
// .source(data)
|
||||||
.shape('fill')
|
// .shape('fill')
|
||||||
.color('rgb(156,194,116)')
|
// .color('rgb(156,194,116)')
|
||||||
.render();
|
// .render();
|
||||||
});
|
// });
|
||||||
$.get('https://gw.alipayobjects.com/os/rmsportal/ZseLNWMOPGrgqQYfvtli.json', data => {
|
// $.get('https://gw.alipayobjects.com/os/rmsportal/ZseLNWMOPGrgqQYfvtli.json', data => {
|
||||||
scene.LineLayer({
|
// scene.LineLayer({
|
||||||
zIndex: 2
|
// zIndex: 2
|
||||||
})
|
// })
|
||||||
.source(data)
|
// .source(data)
|
||||||
.shape('line')
|
// .shape('line')
|
||||||
.size([3,0])
|
// .size([3,0])
|
||||||
.color('rgb(79,174,234)')
|
// .color('rgb(79,174,234)')
|
||||||
.render();
|
// .render();
|
||||||
});
|
// });
|
||||||
|
|
||||||
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
|
$.get('https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json', data => {
|
||||||
citylayer = scene.PolygonLayer({
|
citylayer = scene.PolygonLayer({
|
||||||
|
@ -69,6 +69,24 @@ scene.on('loaded', () => {
|
||||||
.source(data)
|
.source(data)
|
||||||
.shape('extrude')
|
.shape('extrude')
|
||||||
.active({fill:'red'})
|
.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])
|
.size('floor',[10,2000])
|
||||||
.color('rgba(242,246,250,0.96)')
|
.color('rgba(242,246,250,0.96)')
|
||||||
.render();
|
.render();
|
||||||
|
|
|
@ -52,11 +52,13 @@ import common from './common.glsl';
|
||||||
import { registerModule } from '../../util/shaderModule';
|
import { registerModule } from '../../util/shaderModule';
|
||||||
import pick_color from './shaderChunks/pick_color.glsl';
|
import pick_color from './shaderChunks/pick_color.glsl';
|
||||||
import decode from './shaderChunks/decode.glsl';
|
import decode from './shaderChunks/decode.glsl';
|
||||||
|
import lighting from './shaderChunks/lighting.glsl';
|
||||||
|
|
||||||
export function compileBuiltinModules() {
|
export function compileBuiltinModules() {
|
||||||
registerModule('point', { vs: point_vert, fs: point_frag });
|
registerModule('point', { vs: point_vert, fs: point_frag });
|
||||||
registerModule('common', { vs: common, fs: common });
|
registerModule('common', { vs: common, fs: common });
|
||||||
registerModule('decode', { vs: decode, fs: '' });
|
registerModule('decode', { vs: decode, fs: '' });
|
||||||
|
registerModule('lighting', { vs: lighting, fs: '' });
|
||||||
registerModule('pick_color', { vs: pick_color, fs: pick_color });
|
registerModule('pick_color', { vs: pick_color, fs: pick_color });
|
||||||
registerModule('circle', { vs: circle_vert, fs: circle_frag });
|
registerModule('circle', { vs: circle_vert, fs: circle_frag });
|
||||||
registerModule('polygon', { vs: polygon_vert, fs: polygon_frag });
|
registerModule('polygon', { vs: polygon_vert, fs: polygon_frag });
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
precision highp float;
|
precision highp float;
|
||||||
uniform sampler2D u_texture;
|
|
||||||
uniform vec4 u_baseColor;
|
uniform vec4 u_baseColor;
|
||||||
uniform vec4 u_brightColor;
|
uniform vec4 u_brightColor;
|
||||||
uniform vec4 u_windowColor;
|
uniform vec4 u_windowColor;
|
||||||
|
@ -7,10 +7,12 @@ uniform float u_zoom;
|
||||||
uniform float u_time;
|
uniform float u_time;
|
||||||
uniform float u_near;
|
uniform float u_near;
|
||||||
uniform float u_far;
|
uniform float u_far;
|
||||||
|
|
||||||
|
#ifdef ANIMATE
|
||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
varying vec4 v_color;
|
#endif
|
||||||
varying float v_lightWeight;
|
|
||||||
varying float v_size;
|
varying vec4 v_color;
|
||||||
varying vec4 worldId;
|
varying vec4 worldId;
|
||||||
|
|
||||||
vec3 getWindowColor(float n, float hot, vec3 brightColor, vec3 darkColor) {
|
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.);
|
float inside = min(max(d.x, d.y), 0.);
|
||||||
return outside + inside;
|
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() {
|
void main() {
|
||||||
if(v_color.w == 0.0) {
|
if(v_color.w == 0.0) {
|
||||||
|
@ -104,19 +100,13 @@ void main() {
|
||||||
// if(head ==1.0) { // 顶部亮线
|
// if(head ==1.0) { // 顶部亮线
|
||||||
// color = brightColor;
|
// color = brightColor;
|
||||||
// }
|
// }
|
||||||
color = color * v_lightWeight;
|
color = v_color.rgb;
|
||||||
|
|
||||||
vec3 foggedColor = fog(color,fogColor,depth);
|
vec3 foggedColor = fog(color,fogColor,depth);
|
||||||
|
|
||||||
gl_FragColor = vec4(foggedColor,1.0);
|
gl_FragColor = vec4(foggedColor,1.0);
|
||||||
}
|
}
|
||||||
#else
|
#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);
|
gl_FragColor = vec4(v_color.xyz , v_color.w);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,61 +1,50 @@
|
||||||
precision highp float;
|
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);
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import * as THREE from '../../../core/three';
|
import * as THREE from '../../../core/three';
|
||||||
import PolygonBuffer from '../../../geom/buffer/polygon';
|
import PolygonBuffer from '../../../geom/buffer/polygon';
|
||||||
import PolygonMaterial from '../../../geom/material/polygonMaterial';
|
import PolygonMaterial from '../../../geom/material/polygonMaterial';
|
||||||
|
import { generateLightingUniforms } from '../../../util/shaderModule';
|
||||||
|
|
||||||
export default function DrawPolygonFill(layerData, layer) {
|
export default function DrawPolygonFill(layerData, layer) {
|
||||||
const style = layer.get('styleOptions');
|
const style = layer.get('styleOptions');
|
||||||
|
@ -9,7 +10,7 @@ export default function DrawPolygonFill(layerData, layer) {
|
||||||
...style,
|
...style,
|
||||||
activeColor: activeOption.fill
|
activeColor: activeOption.fill
|
||||||
};
|
};
|
||||||
const { opacity, activeColor } = config;
|
const { opacity, activeColor, lights } = config;
|
||||||
const { attributes } = new PolygonBuffer({
|
const { attributes } = new PolygonBuffer({
|
||||||
shape: layer.shape,
|
shape: layer.shape,
|
||||||
layerData
|
layerData
|
||||||
|
@ -21,9 +22,11 @@ export default function DrawPolygonFill(layerData, layer) {
|
||||||
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
|
geometry.addAttribute('normal', new THREE.Float32BufferAttribute(attributes.normals, 3));
|
||||||
const material = new PolygonMaterial({
|
const material = new PolygonMaterial({
|
||||||
u_opacity: opacity,
|
u_opacity: opacity,
|
||||||
u_activeColor: activeColor
|
u_activeColor: activeColor,
|
||||||
|
...generateLightingUniforms(lights)
|
||||||
}, {
|
}, {
|
||||||
SHAPE: false
|
SHAPE: false,
|
||||||
|
LIGHTING: true
|
||||||
});
|
});
|
||||||
const fillPolygonMesh = new THREE.Mesh(geometry, material);
|
const fillPolygonMesh = new THREE.Mesh(geometry, material);
|
||||||
return fillPolygonMesh;
|
return fillPolygonMesh;
|
||||||
|
|
|
@ -178,7 +178,8 @@ export function wrapUniforms(uniforms) {
|
||||||
|
|
||||||
const DEFAULT_LIGHT = {
|
const DEFAULT_LIGHT = {
|
||||||
type: 'directional',
|
type: 'directional',
|
||||||
direction: [ 1, 10.5, 12 ],
|
// direction: [ 1, 10.5, 12 ],
|
||||||
|
direction: [ 0, -10.5, 1 ],
|
||||||
ambient: [ 0.2, 0.2, 0.2 ],
|
ambient: [ 0.2, 0.2, 0.2 ],
|
||||||
diffuse: [ 0.6, 0.6, 0.6 ],
|
diffuse: [ 0.6, 0.6, 0.6 ],
|
||||||
specular: [ 0.1, 0.1, 0.1 ]
|
specular: [ 0.1, 0.1, 0.1 ]
|
||||||
|
|
Loading…
Reference in New Issue