Skip to content

Commit 15163d9

Browse files
committed
examples: add custom shader effect example.
1 parent 19d58c6 commit 15163d9

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

examples/config.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@
4747
"effects_postprocessing": "Post processing",
4848
"effects_split": "Splitted rendering",
4949
"effects_stereo": "Stereo effects",
50-
"mars": "Mars atmosphere"
50+
"mars": "Mars atmosphere",
51+
"customColorLayerEffect": "Custom Color Effect"
5152
},
5253

5354
"Miscellaneous": {

examples/customColorLayerEffect.html

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<html>
2+
<head>
3+
<title>Itowns - Custom ColorLayer effect</title>
4+
5+
<meta charset="UTF-8">
6+
<link rel="stylesheet" type="text/css" href="css/example.css">
7+
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
8+
9+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
10+
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
11+
</head>
12+
<body>
13+
<div id="viewerDiv"></div>
14+
<div id="miniDiv"></div>
15+
<script src="../dist/itowns.js"></script>
16+
<script src="js/GUI/LoadingScreen.js"></script>
17+
<script src="../dist/debug.js"></script>
18+
<script src="js/GUI/GuiTools.js"></script>
19+
<script type="text/javascript">
20+
// # Orthographic viewer
21+
22+
// Define geographic extent: CRS, min/max X, min/max Y
23+
var extent = new itowns.Extent(
24+
'EPSG:3857',
25+
-20026376.39, 20026376.39,
26+
-20048966.10, 20048966.10);
27+
28+
// `viewerDiv` will contain iTowns' rendering area (`<canvas>`)
29+
var viewerDiv = document.getElementById('viewerDiv');
30+
31+
// Instanciate PlanarView
32+
// By default itowns' tiles geometry have a "skirt" (ie they have a height),
33+
// but in case of orthographic we don't need this feature, so disable it
34+
var view = new itowns.PlanarView(viewerDiv, extent, { disableSkirt: true, maxSubdivisionLevel: 10,
35+
camera: { type: itowns.CAMERA_TYPE.ORTHOGRAPHIC },
36+
placement: new itowns.Extent('EPSG:3857', -20000000, 20000000, -8000000, 20000000),
37+
diffuse: new itowns.THREE.Color(0x444444),
38+
controls: {
39+
// Faster zoom in/out speed
40+
zoomFactor: 3,
41+
// prevent from zooming in too much
42+
maxResolution: 0.005 // a pixel shall not represent a metric size smaller than 5 mm
43+
},
44+
});
45+
46+
setupLoadingScreen(viewerDiv, view);
47+
48+
itowns.ShaderChunk.customHeaderColorLayer(`
49+
const mat3 sobelKernelX = mat3(1.0, 2.0, 1.0,
50+
0.0, 0.0, 0.0,
51+
-1.0, -2.0, -1.0);
52+
53+
const mat3 sobelKernelY = mat3(1.0, 0.0, -1.0,
54+
2.0, 0.0, -2.0,
55+
1.0, 0.0, -1.0);
56+
57+
//performs a convolution on an image with the given kernel
58+
float convolve(mat3 kernel, mat3 image) {
59+
float result = 0.0;
60+
for (int i = 0; i < 3; i++) {
61+
for (int j = 0; j < 3; j++) {
62+
result += kernel[i][j]*image[i][j];
63+
}
64+
}
65+
return result;
66+
}
67+
68+
float edge(sampler2D textu, float stepx, float stepy, vec2 center){
69+
// get samples around pixel
70+
mat3 image = mat3(length(texture2D(textu,center + vec2(-stepx,stepy)).rgb),
71+
length(texture2D(textu,center + vec2(0,stepy)).rgb),
72+
length(texture2D(textu,center + vec2(stepx,stepy)).rgb),
73+
length(texture2D(textu,center + vec2(-stepx,0)).rgb),
74+
length(texture2D(textu,center).rgb),
75+
length(texture2D(textu,center + vec2(stepx,0)).rgb),
76+
length(texture2D(textu,center + vec2(-stepx,-stepy)).rgb),
77+
length(texture2D(textu,center + vec2(0,-stepy)).rgb),
78+
length(texture2D(textu,center + vec2(stepx,-stepy)).rgb));
79+
vec2 result;
80+
result.x = convolve(sobelKernelX, image);
81+
result.y = convolve(sobelKernelY, image);
82+
83+
float color = clamp(length(result), 0.0, 255.0);
84+
return color;
85+
}
86+
`);
87+
88+
itowns.ShaderChunk.customBodyColorLayer(`
89+
ivec2 textureSize2d = textureSize(tex,0);
90+
vec2 resolution = vec2(float(textureSize2d.x), float(textureSize2d.y));
91+
92+
float step = layer.effect_parameter;
93+
94+
vec2 cuv = pitUV(uv.xy, offsetScale);
95+
96+
float value = edge(tex, step/resolution.x, step/resolution.y, cuv);
97+
98+
color = vec4(vec3(value * 0.8, 0.0, 0.0), value);
99+
`);
100+
101+
// Add a TMS imagery source
102+
var opensmSource = new itowns.TMSSource({
103+
crs: 'EPSG:3857',
104+
isInverted: true,
105+
format: 'image/png',
106+
url: 'http://osm.oslandia.io/styles/klokantech-basic/${z}/${x}/${y}.png',
107+
tileMatrixSet: 'PM'
108+
});
109+
110+
// Add a TMS imagery layer
111+
var opensmEffectLayer = new itowns.ColorLayer('OPENSM_Effect', {
112+
source: opensmSource,
113+
effect_type: itowns.colorLayerEffects.customEffect,
114+
effect_parameter: 1.0,
115+
magFilter: itowns.THREE.NearestFilter,
116+
minFilter: itowns.THREE.NearestFilter,
117+
});
118+
119+
var opensm = new itowns.ColorLayer('OPENSM', { source: opensmSource });
120+
121+
view.addLayer(opensm);
122+
view.addLayer(opensmEffectLayer);
123+
124+
// Request redraw
125+
view.notifyChange();
126+
127+
menuGlobe = new GuiTools('menuDiv', view);
128+
menuGlobe.addImageryLayersGUI(view.getLayers(function gui(l) { return l.isColorLayer; }));
129+
debug.createTileDebugUI(menuGlobe.gui, view);
130+
131+
menuGlobe.gui.add(opensmEffectLayer, 'effect_parameter', 0.0, 1.0).onChange((v) => {
132+
opensmEffectLayer.effect_parameter = v;
133+
view.notifyChange(opensmEffectLayer);
134+
});
135+
136+
view.addEventListener(itowns.GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, () => {
137+
itowns.ColorLayersOrdering.moveLayerToIndex(view, 'OPENSM', 0);
138+
});
139+
</script>
140+
</body>
141+
</html>

0 commit comments

Comments
 (0)