webgl for dynamic virtual globes - cesium
TRANSCRIPT
No anisotropic filteringOverview
● Cesium○ A WebGL virtual globe for visualizing dynamic data
● Today
○ Demos - lots of em○ Architecture○ Selected implementation details○ Future plans
Lots of Satellites Demo
Cesium Architecture
Scene
Renderer
Core
Visualizers Buffers
Local file
Server.czm
KMLServer-side Computation
...
.czm
Client
Cesium Architecture - Core
Scene
Renderer
Core
● Core - client-side number crunching○ Matrices, vectors, quaternions○ Transformations○ Sun position○ Splines○ Triangulation*
○ Subdivision surfaces○ ...
* We might move this server-side
Cesium Architecture - Renderer
Scene
Renderer
Core
● Renderer - a thin abstraction over WebGL○ Shader programs
■ Built-in uniforms and functions○ Textures and cube maps○ Buffers and vertex arrays○ Render states○ Framebuffers
Cesium Architecture - Scene
Scene
Renderer
Core
● Scene - Virtual globe constructs○ Streaming high-resolution imagery○ Polylines, polygons, billboards, labels○ Materials*
○ Animations○ Cameras
* Might belong in Renderer. We're still thinking about it. :)
Sandbox Demo
Demo - One API, Multiple Views
● 3D● 2D● Columbus view - 2.5Dish
3D
2D
Columbus View
Columbus View (Pat. Pend.)
CZM
● CZM○ A streamable JSON scene description○ Describes the value of properties over time○ Intended to become an OGC standard○ Implemented using Server-Sent Events*
*http://dev.w3.org/html5/eventsource/
Server
push
Cesium Client
buffering and prefetching
CZM
[{ "id": "any unique identifier", "properties": [{ "name": "label_text", // Static properties, value is constant across time
"value": "Iridium 77" },{ "name": "billboard_color", // Interval properties, value is constant within intervals
"intervals": [{ "start": {"day": 2455971, "secondsOfDay": 35220.59}, "stop": {"day": 2455971, "secondsOfDay": 37020.59}, "value": { "a": 255, "r": 255, "g": 0, "b": 0 } }] },{ "name": "position", // Sampled properties, value is interpolated across time
"times": [ {"day": 2455971, "secondsOfDay": 35220.59}, {"day": 2455971, "secondsOfDay": 35340.59}
], "values": [ {"x": 5389687.9027777817, "y": 361715.80718983803, "z": -4702183.7113378914}, {"x": 5928861.67967367, "y": 420278.37160484237, "z": -3994351.3905959018}
], "interpolationType": "LAGRANGE", "interpolationDegree": 5 }]}]
CZM Demos
● Content is king.
Server.czm
KMLServer-side Computation
...
Cesium Client
Selected Implementation
Details
No anisotrop ic filteringHigh-Resolution Imagery Rendering
● Tiles requested based on pixel error● Throttled texture creation*
● Cracks between tiles filled in screen space
*http://media.tojicode.com/webglCamp4/
Dusk / dawnHalo
Yellow shows cracks between tiles
Dusk / dawnHalo
Two-pass Gaussian blur fills cracks in screen space
No anisotrop ic filteringDepth Plane
● How do we draw polylines, polygons, etc. on the surface of the globe?○ Can't write gl_FragDepth in WebGL yet.
viewer
Subdivided polyline is actually under the surface
Dusk / dawnHaloThe plane intersects the ellipsoid at the horizon
Dusk / dawnHaloRay casting the ellipsoid within the plane discards fragments in space
Dusk / dawnHaloThe plane is rendered with depth only, so it occludes objects on the backface of the ellipsoid
No anisotropic filteringAnisotropic Filtering
● Uses more texture samples to improve visual quality for horizon views○ WEBKIT_EXT_texture_filter_anisotropic○ MOZ_EXT_texture_filter_anisotropic
No anisotropic filtering
With anisotropic filtering
FuturePlans
Open Source
● Cesium will be open source ● Code available as soon as April
○ github.com/AnalyticalGraphicsInc/cesium
● Mailing lists available now
● Development - groups.google.com/d/forum/cesium-dev
● Announcements - groups.google.com/d/forum/cesium-announce
● Please join our developer community○ grassroots opportunity
Contributors
Matt Amato @matt_amatoDan BagnellKristian Calhoun @KristianCalhounPatrick Cozzi @pjcozziMatt Ford
Scott HunterEd Mackey @emackeyKevin RingChris SeltzerFrank Stoner
Roadmap
2012 April August
Code publicly available End user release● Terrain● 3D models - COLLADA● Improved precision● Improved visual quality● RequireJS
WebGL Reporthttp://analyticalgraphicsinc.github.com/webglreport/
● Implementation-dependent maximums
● Supported extensions
Resources
● Demos: cesium.agi.com
● Mailing Lists
● Development - groups.google.com/d/forum/cesium-dev
● Announcements - groups.google.com/d/forum/cesium-announce
● Source code (soon): github.com/AnalyticalGraphicsInc/cesium
Bonus Slides(time permitting)
Cesium Architecture - Renderer
● Example Built-in uniforms and functions ● Create shaders in one line of JavaScript
gl_Position = agi_modelViewProjection * position;v_positionWC = (agi_model * position).xyz;v_positionEC = (agi_modelView * position).xyz;v_normalEC = agi_normal * normal; // ... agi_ray ray = agi_ray(vec3(0.0), normalize(v_positionEC));agi_raySegment interval = agi_rayEllipsoidIntersectionInterval ( ray, ellipsoid);
var sp = context.getShaderCache().getShaderProgram(vs, fs);
Cesium Architecture - Renderer
● Textures and uniforms○ Never worry about binding a texture○ Never call getUniformLocation on a uniform
that was optimized out
this.bumpTexture = context.createTexture2D({ source : bumpImage, pixelFormat : PixelFormat.LUMINANCE }); // ... var that = this;var uniforms = { u_bumpMap : function() { return that.bumpTexture; }, u_nightIntensity : function() { return 0.8; }};
Cesium Architecture - Renderer
● Buffers and vertex arrays○ Simplify organizing vertex attributes
var mesh = BoxTessellator.compute({ dimensions : new Cartesian3(1.0, 2.0, 3.0)})); var va = context.createVertexArrayFromMesh({ mesh : mesh, bufferUsage : BufferUsage.STATIC_DRAW, vertexLayout : VertexLayout.INTERLEAVED});
Cesium Architecture - Renderer
● Render states - no global state
var rs = context.createRenderState({ depthTest : { enabled : true }, cull : { enabled : true, face :CullFace.BACK }, blending : BlendingState.ALPHA_BLEND});
Cesium Architecture - Renderer● Draw an object:
context.draw({ primitiveType:PrimitiveType.TRIANGLES, shaderProgram: sp, uniformMap: uniforms, vertexArray: va, renderState: rs});
context.beginDraw({ shaderProgram : sp, renderState : rs}); for ... context.continueDraw({ primitiveType :PrimitiveType.TRIANGLES, vertexArray : va[i], uniformMap : uniforms[i]}); context.endDraw();
● Or draw several:
No anisotropic filteringBillboard Rendering
● Need to render up to 10,000s of viewport-aligned quads
No anisotropic filteringBillboard Rendering
● Vertex shader determines each billboard's size● One batch for
○ Static billboards○ Dynamic billboards
● Batching enabled by use of a texture atlas, e.g.:
Image from www.virtualglobebook.com
No anisotropic filteringBillboard Rendering
● Each vertex can have several attributes, e.g.:○ Position○ Color○ Pixel offset○ ...
● Large vertices make dynamic updates expensive○ Consider one interleaved buffer:
● What if we only update positions?
p0 c0 o0 p1 c1 o1 p2 c2 o2 p3 c3 o3
No anisotropic filteringBillboard Rendering
● Replace one buffer with two organized based on update rate, e.g.:
● Re-balance static/dynamic based on usage
p0
c0 o0
p1
c1 o1
p2
c2 o2
p3
c3 o3
dynamic:
static:
Label Rendering
● How do we render lots of labels?
Label Rendering
Atmospheric Scattering
● Using Sean O'Neil's Accurate Atmospheric Scattering from GPU Gems 2○ http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html
Dusk / dawnHalo
Dusk / dawnDusk / dawn
Dusk / dawn