--- title: "Surface and mesh rendering with ggWebGL" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Surface and mesh rendering with ggWebGL} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} ggwebgl_truthy <- function(x) { tolower(x) %in% c("1", "true", "yes", "y") } ggwebgl_ci_vars <- c( "CI", "GITHUB_ACTIONS", "GITLAB_CI", "BUILDKITE", "TRAVIS", "APPVEYOR", "CIRCLECI", "JENKINS_URL" ) ggwebgl_is_ci <- any(vapply(Sys.getenv(ggwebgl_ci_vars), ggwebgl_truthy, logical(1))) ggwebgl_is_check <- nzchar(Sys.getenv("_R_CHECK_PACKAGE_NAME_")) ggwebgl_eval_code <- !ggwebgl_is_ci && !ggwebgl_is_check && ( ggwebgl_truthy(Sys.getenv("NOT_CRAN")) || ggwebgl_truthy(Sys.getenv("GGWEBGL_EVAL_COVERAGE_VIGNETTE")) ) ggwebgl_eval_widgets <- ggwebgl_eval_code && ggwebgl_truthy(Sys.getenv("GGWEBGL_EVAL_LIVE_WIDGETS")) knitr::opts_chunk$set(collapse = TRUE, comment = "#>", eval = ggwebgl_eval_code) if (file.exists("DESCRIPTION") && requireNamespace("pkgload", quietly = TRUE)) { pkgload::load_all(".", export_all = FALSE, helpers = FALSE, quiet = TRUE) } else if (file.exists("../DESCRIPTION") && requireNamespace("pkgload", quietly = TRUE)) { pkgload::load_all("..", export_all = FALSE, helpers = FALSE, quiet = TRUE) } else { library(ggWebGL) } example_candidates <- c( "inst/examples/htmlwidget/surface-gallery.R", file.path("..", "inst", "examples", "htmlwidget", "surface-gallery.R"), system.file("examples", "htmlwidget", "surface-gallery.R", package = "ggWebGL") ) example_candidates <- example_candidates[nzchar(example_candidates) & file.exists(example_candidates)] if (!length(example_candidates)) { stop("Could not find surface-gallery.R") } sys.source(example_candidates[[1L]], envir = knitr::knit_global()) ``` # Purpose `ggWebGL` separates structured surfaces from unstructured meshes. Structured surfaces are rectilinear grids that can carry height colormaps, normals, wireframes, and optional contour overlays. Meshes are indexed triangle geometry with scalar coloring, wireframe edges, and renderer-owned face or vertex ids. Both examples below use small deterministic in-memory data. They are intended to show the renderer contracts, not to report performance numbers. Code examples are shown by default. Live WebGL widgets are disabled during CRAN, package checks, and CI. Rich local or pkgdown rendering requires `GGWEBGL_EVAL_COVERAGE_VIGNETTE=true` and `GGWEBGL_EVAL_LIVE_WIDGETS=true`. **Status.** Structured surfaces and unstructured meshes are `Experimental` public APIs. They cover browser-side indexed geometry examples, while terrain preprocessing, mesh simplification, and high-scale mesh optimization remain outside the core package. # Structured Surface The `volcano` matrix is converted with `surface_matrix()` and rendered as a first-class surface primitive. The widget uses a perspective orbit view and the `surface_height_colormap` shader. ```{r volcano-surface, out.width='100%', eval = ggwebgl_eval_widgets} surface_gallery_volcano_widget(height = 460) ``` # Unstructured Mesh The mesh example uses explicit vertices and triangle indices. Scalar values are stored on vertices and displayed with `mesh_scalar_colormap`; face ids remain available to the renderer for hover or selection payloads. ```{r scalar-mesh, out.width='100%', eval = ggwebgl_eval_widgets} surface_gallery_mesh_widget(height = 460) ``` # Notes The core package keeps rendering in the browser through WebGL. Any expensive terrain preprocessing, mesh simplification, or device-specific acceleration is left to upstream analysis code or optional companion tooling.