Skip to content

Commit

Permalink
feat: imageLayer支持图像增强 (#2186)
Browse files Browse the repository at this point in the history
* fix: fillImage中uniform没对齐的bug

* feat: imageLayer支持图片效果增强 (#2180)

* chore: 删除imageLayer中的颜色叠加

* docs: 更新imageLayer.style中新增的图像增强的参数的文档

---------

Co-authored-by: huyang <[email protected]>
  • Loading branch information
taiyuanhy and huyang authored Dec 19, 2023
1 parent 467585f commit 55efe0e
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 70 deletions.
67 changes: 61 additions & 6 deletions dev-demos/features/imageLayer/image.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,91 @@
import { ImageLayer, Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';

//加载外部脚本
function addExternalScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => resolve();
script.onerror = () => reject();
document.body.appendChild(script);
});
}
export default () => {
useEffect(() => {
const scene = new Scene({
id: 'map',
pickBufferScale: 1.0,
renderer: 'device',
map: new GaodeMap({
center: [121.268, 30.3628],
pitch: 0,
style: 'normal',
zoom: 10,
}),
});

const layerStyle = {
brightness: 1.0,
gamma: 1.0,
color: '#ffffff',
opacity: 1.0,
saturation: 1.0,
contrast: 1.0,
};
const layer = new ImageLayer({});
layer.source(
// 'https://gw.alipayobjects.com/zos/rmsportal/FnHFeFklTzKDdUESRNDv.jpg',
// 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*0TVXSbkyKvsAAAAAAAAAAAAAARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*4k6vT6rUsk4AAAAAAAAAAAAAARQnAQ',
'https://cdn.uino.cn/thing-earth-space/images/refraction.jpg',
// 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*4k6vT6rUsk4AAAAAAAAAAAAAARQnAQ',
{
parser: {
type: 'image',
extent: [121.168, 30.2828, 121.384, 30.4219],
},
},
);

layer.style(layerStyle);
scene.on('loaded', () => {
scene.addLayer(layer);
scene.startAnimate();
});
const gui = new dat.GUI();
gui.domElement.style.position = 'absolute';
gui.domElement.style.top = '202px';
gui.domElement.style.right = '220px';
gui.add(layerStyle, 'brightness', 0, 2, 0.01).onChange((v) => {
layer.style({
brightness: v,
});
scene.render();
});
gui.add(layerStyle, 'saturation', 0, 2, 0.01).onChange((v) => {
layer.style({
saturation: v,
});
scene.render();
});
gui.add(layerStyle, 'contrast', 0, 2, 0.01).onChange((v) => {
layer.style({
contrast: v,
});
scene.render();
});
gui.add(layerStyle, 'gamma', 0, 2, 0.01).onChange((v) => {
layer.style({
gamma: v,
});
scene.render();
});
gui.add(layerStyle, 'opacity', 0, 1, 0.01).onChange((v) => {
layer.style({
opacity: v,
});
scene.render();
});

return () => {
gui.destroy();
};
}, []);
return (
<div
Expand Down
91 changes: 45 additions & 46 deletions dev-demos/features/line/demos/linePopulation.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { LineLayer, Scene } from '@antv/l7';
import { GaodeMap} from '@antv/l7-maps';
import { GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';
//加载外部脚本
function addExternalScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = () => resolve();
script.onerror = () => reject();
document.body.appendChild(script);
});
}
/**
* @private
* 点数据转线数据
Expand All @@ -32,10 +22,16 @@ function processPointToLine(data, minValue = 0) {
let lines = Object.values(groupedPoints).map((points) => {
let result = [];
let lastLon = -500;
points = points.filter(v => { return parseFloat(v.properties.value) > minValue })
points = points.filter((v) => {
return parseFloat(v.properties.value) > minValue;
});
for (let i = 0; i < points.length; i++) {
if (Math.abs(points[i].geometry.coordinates[0] - lastLon) >= 2) {
const line = { type: 'Feature', geometry: { type: 'LineString', coordinates: [] }, properties: { heights: [] } };
const line = {
type: 'Feature',
geometry: { type: 'LineString', coordinates: [] },
properties: { heights: [] },
};
result.push(line);
}
const line = result[result.length - 1];
Expand All @@ -45,10 +41,12 @@ function processPointToLine(data, minValue = 0) {
line.properties.heights.push(coordinates[2]);
lastLon = points[i].geometry.coordinates[0];
}
result = result.filter(v => { return v.geometry.coordinates.length > 1 });
result = result.filter((v) => {
return v.geometry.coordinates.length > 1;
});
return result;
});
lines = lines.flat(1)
lines = lines.flat(1);
// 创建包含多条线的新 GeoJSON 对象
return {
type: 'FeatureCollection',
Expand Down Expand Up @@ -88,28 +86,31 @@ export default () => {
useEffect(() => {
const scene = new Scene({
id: 'map',
renderer: process.env.renderer,
renderer: process.env.renderer,
map: new GaodeMap({
pitch: 40,
style: 'dark',
center: [43.686824, -4.665872],
zoom: 1.2,
token:"pk.eyJ1Ijoic2tvcm5vdXMiLCJhIjoiY2s4dDBkNjY1MG13ZTNzcWEyZDYycGkzMyJ9.tjfwvJ8G_VDmXoClOyxufg"
})
token:
'pk.eyJ1Ijoic2tvcm5vdXMiLCJhIjoiY2s4dDBkNjY1MG13ZTNzcWEyZDYycGkzMyJ9.tjfwvJ8G_VDmXoClOyxufg',
}),
});
const guiConfig = {
height: 30,
minValue: 10000,
color: '#0D5EFF',
// opacity:1.0,
blend: 'additive'
}
let layer, originData,gui;
blend: 'additive',
};
let layer, originData, gui;

scene.on('loaded', () => {
fetch('https://static.observableusercontent.com/files/c517bc4710d3a5daf34549dde51fd3a0e457a62ce3113847cf804dd21b78a95dd0ecc0b975455c4c162f87e74e665e6994bb9bbd457a420e46d6b6179200b47d')
.then(res => res.text())
.then(data => {
fetch(
'https://static.observableusercontent.com/files/c517bc4710d3a5daf34549dde51fd3a0e457a62ce3113847cf804dd21b78a95dd0ecc0b975455c4c162f87e74e665e6994bb9bbd457a420e46d6b6179200b47d',
)
.then((res) => res.text())
.then((data) => {
originData = csvToGeojson(data);
const dataSource = processPointToLine(originData, guiConfig.minValue);
layer = new LineLayer({
Expand All @@ -125,30 +126,28 @@ export default () => {
.color(guiConfig.color);
scene.addLayer(layer);
});
addExternalScript('https://cdn.uino.cn/thing-earth-space/libs/dat.gui.min.js').then(() => {
gui = new dat.GUI();
gui.domElement.style.position = 'absolute';
gui.domElement.style.top = '202px';
gui.domElement.style.right = '220px';
gui.add(guiConfig, "height", 1, 100, 0.1).onChange((v) => {
layer.style({
vertexHeightScale: 0.01 * v
});
scene.render();
});
gui.add(guiConfig, "minValue", 10000, 1000000, 1).onChange((v) => {
const dataSource = processPointToLine(originData, guiConfig.minValue);
layer.setData(dataSource);
gui = new dat.GUI();
gui.domElement.style.position = 'absolute';
gui.domElement.style.top = '202px';
gui.domElement.style.right = '220px';
gui.add(guiConfig, 'height', 1, 100, 0.1).onChange((v) => {
layer.style({
vertexHeightScale: 0.01 * v,
});
scene.render();
});
gui.add(guiConfig, 'minValue', 10000, 1000000, 1).onChange((v) => {
const dataSource = processPointToLine(originData, guiConfig.minValue);
layer.setData(dataSource);
});

gui.add(guiConfig, "blend", ['additive', 'normal']).onChange((v) => {
layer.setBlend(v);
});
gui.addColor(guiConfig, "color").onChange((v) => {
layer.color(v);
scene.render();
});
})
gui.add(guiConfig, 'blend', ['additive', 'normal']).onChange((v) => {
layer.setBlend(v);
});
gui.addColor(guiConfig, 'color').onChange((v) => {
layer.color(v);
scene.render();
});
});
return () => {
gui.destroy();
Expand Down
5 changes: 4 additions & 1 deletion packages/layers/src/core/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export enum TextureBlend {
NORMAL = 'normal',
REPLACE = 'replace',
}

/**
* 基础图层类型定义
*/
Expand Down Expand Up @@ -199,6 +198,10 @@ export interface IImageLayerStyleOptions extends IBaseLayerStyleOptions {
clampHigh?: boolean;
rampColors?: IColorRamp;
colorTexture?: ITexture2D;
brightness?: number;
contrast?: number;
saturation ?: number;
gamma?: number;
}

export interface ICityBuildLayerStyleOptions {
Expand Down
22 changes: 8 additions & 14 deletions packages/layers/src/image/models/image.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
IEncodeFeature,
IModel,
IModelUniform,
ITexture2D} from '@antv/l7-core';
import {
AttributeType,
Expand All @@ -13,24 +12,19 @@ import { RasterImageTriangulation } from '../../core/triangulation';
import ImageFrag from '../shaders/image_frag.glsl';
import ImageVert from '../shaders/image_vert.glsl';
import { ShaderLocation } from '../../core/CommonStyleAttribute';

import { defaultValue, rgb2arr } from '@antv/l7-utils';
export default class ImageModel extends BaseModel {
protected texture: ITexture2D;
public getUninforms(): IModelUniform {
const commoninfo = this.getCommonUniformsInfo();
const attributeInfo = this.getUniformsBufferInfo(this.getStyleAttribute());
this.updateStyleUnifoms();
return {
...commoninfo.uniformsOption,
...attributeInfo.uniformsOption,
}
}

protected getCommonUniformsInfo(): { uniformsArray: number[]; uniformsLength: number; uniformsOption: { [key: string]: any; }; } {
const { opacity } = this.layer.getLayerConfig() as IImageLayerStyleOptions;
const { color = 'rgb(255,255,255)',opacity,brightness,contrast,saturation,gamma } = this.layer.getLayerConfig() as IImageLayerStyleOptions;
const colorArry = rgb2arr(color);
const commonOptions = {
u_opacity: opacity || 1,
u_texture: this.texture,
u_opacity:defaultValue(opacity,1.0),
u_brightness:defaultValue(brightness,1.0),
u_contrast:defaultValue(contrast,1.0),
u_saturation:defaultValue(saturation,1.0),
u_gamma:defaultValue(gamma,1.0)
};
this.textures = [this.texture]
const commonBufferInfo = this.getUniformsBufferInfo(commonOptions);
Expand Down
26 changes: 25 additions & 1 deletion packages/layers/src/image/shaders/image_frag.glsl
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
uniform sampler2D u_texture;
layout(std140) uniform commonUniforms {
float u_opacity;
float u_opacity:1.0;
float u_brightness:1.0;
float u_contrast:1.0;
float u_saturation:1.0;
float u_gamma:1.0;
};

in vec2 v_texCoord;
out vec4 outputColor;
vec3 setContrast(vec3 rgb, float contrast) {
vec3 color = mix(vec3(0.5), rgb, contrast);
color = clamp(color, 0.0, 1.0);
return color;
}
vec3 setSaturation(vec3 rgb, float adjustment) {
const vec3 grayVector = vec3(0.2125, 0.7154, 0.0721);
vec3 intensity = vec3(dot(rgb, grayVector));
vec3 color = mix(intensity, rgb, adjustment);
color = clamp(color, 0.0, 1.0);
return color;
}
void main() {
vec4 color = texture(SAMPLER_2D(u_texture),vec2(v_texCoord.x,v_texCoord.y));
//brightness
color.rgb = mix(vec3(0.0, 0.0, 0.0), color.rgb, u_brightness);
//contrast
color.rgb = setContrast(color.rgb, u_contrast);
// saturation
color.rgb = setSaturation(color.rgb, u_saturation);
// gamma
color.rgb = pow(color.rgb, vec3(u_gamma));
outputColor = color;
outputColor.a *= u_opacity;
if(outputColor.a < 0.01)
Expand Down
6 changes: 5 additions & 1 deletion packages/layers/src/image/shaders/image_vert.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ layout(location = 0) in vec3 a_Position;
layout(location = 14) in vec2 a_Uv;

layout(std140) uniform commonUniforms {
float u_opacity;
float u_opacity:1.0;
float u_brightness:1.0;
float u_contrast:1.0;
float u_saturation:1.0;
float u_gamma:1.0;
};

out vec2 v_texCoord;
Expand Down
4 changes: 4 additions & 0 deletions packages/site/docs/api/image_layer/style.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ order: 4
| style | 类型 | 描述 | 默认值 |
| ------- | -------- | ------------ | ------ |
| opacity | `number` | 图形的透明度 | `1` |
| brightness | `number` | 图形的亮度 | `1` |
| contrast | `number` | 图形的对比度 | `1` |
| saturation | `number` | 图形的饱和度 | `1` |
| gamma | `number` | 图形的伽马值 | `1` |
2 changes: 2 additions & 0 deletions packages/utils/.umirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ export default defineConfig({
'https://gw.alipayobjects.com/os/lib/antd/4.19.4/dist/antd.js',
/** lodash */
'https://gw.alipayobjects.com/os/lib/lodash/4.17.20/lodash.min.js',
//dat.gui
'https://cdn.uino.cn/thing-earth-space/libs/dat.gui.min.js',
],

// more config: https://d.umijs.org/config
Expand Down
8 changes: 7 additions & 1 deletion packages/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ export * as Satistics from './statistics';
export * from './tileset-manager';
export * from './worker-helper';
export * from './workers/triangulation';
export * from './interface/map'
export * from './interface/map'
export function defaultValue(v1:any,v2:any){
if(v1===undefined||v1===null){
return v2;
}
return v1;
}

0 comments on commit 55efe0e

Please sign in to comment.