tylermorganwall / rayshader

R Package for 2D and 3D mapping and data visualization
https://www.rayshader.com/
2.07k stars 214 forks source link

render_highquality animation. type="bezier" causes overlays to be ignored when frames gets large. #291

Open apsteinmetz opened 1 year ago

apsteinmetz commented 1 year ago

The code below produces a render with the overlay ignored. The plot_3d() window looks fine. The render is correct if curve type="cubic" OR the number of frames is "small." I don't know what the cutoff number of frames is.

library(rayshader)
library(elevatr)
library(png)
library(sf)
library(terra)
library(raster)
library(osrm)
library(maptiles)
library(tidyverse)

start_point <- c(-74.2548014,41.0248253) # where skyline drive meets i-287
end_point <- c(-74.28869990,41.22772724) # north end of windermere ave. in Greenwood Lake
full_extent <- ext(-8278678.63106571, -8264262.03289493, 5015662.67345158, 5049556.38996736)
map_ras <- rast(extent = full_extent, crs="EPSG:3857")

# get basemap tiles
gwl_basemap <- maptiles::get_tiles(map_ras,
                                   provider="Thunderforest.Outdoors",
                                   crop = TRUE,
                                   zoom = 14,
                                   apikey = Sys.getenv("THUNDERFOREST_KEY"))

terra::writeRaster(gwl_basemap,"img/gwl_basemap.png",overwrite=TRUE)
gwl_png <- readPNG("img/gwl_basemap.png")

gwl_route_detailed <- osrm::osrmRoute(start_point,end_point,overview = "full") |> 
  st_transform(crs(map_ras))

raw_elevation <- get_elev_raster(raster(map_ras),z = 12)
elevation <- raw_elevation |> 
  rast() |> 
  terra::crop(map_ras)

elev_matrix <- elevation |> 
  raster_to_matrix()

route_overlay <- generate_line_overlay(gwl_route_detailed,
                                       map_ras,
                                       # dimensions same as image overlay, otherwise jaggy
                                       width = 1510,
                                       height = 3549,
                                       color = "red",
                                       linewidth = 2)

shadow_lamb <- lamb_shade(elev_matrix)
shadow_ray <- ray_shade(elev_matrix,lambert=FALSE)
shadow_ambient <- ambient_shade(elev_matrix)

elev_matrix |> 
  sphere_shade() |> 
  add_overlay(gwl_png,rescale_original = TRUE) |> 
  add_shadow(shadow_ray) |> 
  add_shadow(shadow_lamb) |> 
  add_shadow(shadow_ambient) |> 
  add_overlay(route_overlay) |> 
  plot_3d(elev_matrix,zscale = 7)

camera_coords <-
  convert_path_to_animation_coords(
    gwl_route_detailed,
    extent = full_extent,
    heightmap = elev_matrix,
    zscale = 7,
    resample_path_evenly = TRUE,
    offset = 10,
    offset_lookat = 10,
    altitude = 400,
    follow_camera = TRUE,
    follow_distance = 100,
    follow_fixed = FALSE,
    follow_angle = 15,
    damp_motion = TRUE,
    damp_magnitude = 1,
    type="bezier",
    curvature_adjust = "both",
    frames = 600,
  )
render_highquality(animation_camera_coords = camera_coords, width=800, height=800,
                   samples=128, line_radius=0.5, sample_method = "sobol_blue",
                   ambient_light = TRUE,
                   filename="frames/gwl_")

Here is the first frame:

gwl_1_bad

New coords with default curve type. Everything else the same.

camera_coords <-
  convert_path_to_animation_coords(
    gwl_route_detailed,
    extent = full_extent,
    heightmap = elev_matrix,
    zscale = 7,
    resample_path_evenly = TRUE,
    offset = 10,
    offset_lookat = 10,
    altitude = 400,
    follow_camera = TRUE,
    follow_distance = 100,
    follow_fixed = FALSE,
    follow_angle = 15,
    damp_motion = TRUE,
    damp_magnitude = 1,
    # type="bezier",
    # curvature_adjust = "both",
    frames = 600,
  )

gwl_1_good

> sessionInfo()
R version 4.3.0 (2023-04-21 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 11 x64 (build 22621)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.utf8  LC_CTYPE=English_United States.utf8    LC_MONETARY=English_United States.utf8
[4] LC_NUMERIC=C                           LC_TIME=English_United States.utf8    

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] raster_3.6-23    sp_2.0-0         lubridate_1.9.2  forcats_1.0.0    stringr_1.5.0    dplyr_1.1.2      purrr_1.0.2     
 [8] readr_2.1.4      tidyr_1.3.0      tibble_3.2.1     ggplot2_3.4.3    tidyverse_2.0.0  maptiles_0.5.0   osrm_4.1.1      
[15] terra_1.7-39     sf_1.0-14        png_0.1-8        elevatr_0.4.5    rayshader_0.36.1

loaded via a namespace (and not attached):
 [1] gtable_0.3.4          xfun_0.40             htmlwidgets_1.6.2     lattice_0.21-8        tzdb_0.4.0           
 [6] vctrs_0.6.3           tools_4.3.0           generics_0.1.3        curl_5.0.2            parallel_4.3.0       
[11] rgl_1.2.1             proxy_0.4-27          fansi_1.0.4           pkgconfig_2.0.3       KernSmooth_2.23-20   
[16] lifecycle_1.0.3       compiler_4.3.0        googlePolylines_0.8.3 tictoc_1.2            progress_1.2.2       
[21] munsell_0.5.0         codetools_0.2-19      htmltools_0.5.6       class_7.3-21          rayimage_0.9.1       
[26] pillar_1.9.0          crayon_1.5.2          slippymath_0.3.1      rsconnect_1.0.2       classInt_0.4-9       
[31] magick_2.7.5          iterators_1.0.14      foreach_1.5.2         tidyselect_1.2.0      digest_0.6.33        
[36] stringi_1.7.12        fastmap_1.1.1         grid_4.3.0            colorspace_2.1-0      cli_3.6.1            
[41] magrittr_2.0.3        base64enc_0.1-3       utf8_1.2.3            e1071_1.7-13          RcppSimdJson_0.1.10  
[46] withr_2.5.0           prettyunits_1.1.1     scales_1.2.1          timechange_0.2.0      rayrender_0.30.0     
[51] httr_1.4.7            progressr_0.14.0      hms_1.1.3             knitr_1.43            rayvertex_0.8.2      
[56] rgdal_1.6-7           doParallel_1.0.17     rlang_1.1.1           Rcpp_1.0.11           isoband_0.2.7        
[61] glue_1.6.2            DBI_1.1.3             mapiso_0.3.0          rstudioapi_0.15.0     jsonlite_1.8.7       
[66] R6_2.5.1              units_0.8-3  
tylermorganwall commented 11 months ago

I don't have the API key for the thunderforest map source, so I ran the following and did not see the same problem (the red line existed). Do you see the red line overlay when you run the following code, and do you still have this problem?

library(rayshader)
library(elevatr)
library(png)
library(sf)
library(terra)
library(raster)
library(osrm)
library(maptiles)
library(tidyverse)

start_point <- c(-74.2548014,41.0248253) # where skyline drive meets i-287
end_point <- c(-74.28869990,41.22772724) # north end of windermere ave. in Greenwood Lake
full_extent <- ext(-8278678.63106571, -8264262.03289493, 5015662.67345158, 5049556.38996736)
map_ras <- rast(extent = full_extent, crs="EPSG:3857")

gwl_route_detailed <- osrm::osrmRoute(start_point,end_point,overview = "full") |> 
  st_transform(crs(map_ras))

raw_elevation <- get_elev_raster(raster(map_ras),z = 12)
elevation <- raw_elevation |> 
  rast() |> 
  terra::crop(map_ras)

elev_matrix <- elevation |> 
  raster_to_matrix()

route_overlay <- generate_line_overlay(gwl_route_detailed,
                                       map_ras,
                                       # dimensions same as image overlay, otherwise jaggy
                                       width = 1510,
                                       height = 3549,
                                       color = "red",
                                       linewidth = 2)

shadow_lamb <- lamb_shade(elev_matrix)

elev_matrix |>
  sphere_shade() |> 
  add_overlay(route_overlay) |> 
  plot_3d(elev_matrix,zscale = 7)

camera_coords <-
  convert_path_to_animation_coords(
    gwl_route_detailed,
    extent = full_extent,
    heightmap = elev_matrix,
    zscale = 7,
    resample_path_evenly = TRUE,
    offset = 10,
    offset_lookat = 10,
    altitude = 400,
    follow_camera = TRUE,
    follow_distance = 100,
    follow_fixed = FALSE,
    follow_angle = 15,
    damp_motion = TRUE,
    damp_magnitude = 1,
    type="bezier",
    curvature_adjust = "both",
    frames = 600,
  )
render_highquality(animation_camera_coords = camera_coords, width=800, height=800,
                   samples=4, line_radius=0.5, sample_method = "sobol_blue",
                   ambient_light = TRUE,
                   filename="gwl_")