Como criar um relevo em 3D com sombras no R usando o pacote rayshader?

Representar relevos em 2 dimensões não tem muita graça. Veja como criar seus relevos em 3D usando o pacote rayshader no R. Acrescente sombras e água, rotacione e mude o angulo de iluminação.

Há várias formas de representar o relevo de um determinada área, podemos utilizar curvas de nível, cores ou representações em 3 dimensões.

Tais representações em 3D podem ser obtidas em diferentes softwares, como no GRASS GIS, no ArcScene do ArcGIS e com o Qgis2threejs no QGIS. Desta lista, o R, normalmente utilizado para o desenvolvimento de análises estatísticas, também pode ser utilizado.

O pesquisador Tyler Morgan-Wall desenvolveu o pacote rayshader com o objetivo de criar esses mapas em 3D, mostrando o relevo com sombras, perspectiva e diferentes focos.

Exemplo criado com rayshader. Fonte: GitHub rayshader.
Exemplo criado com rayshader. Fonte: GitHub rayshader.

Agora que sabemos das potencialidades deste pacote, vamos criar nosso próprio relevo. Você pode realizar o download de modelos digitais de terreno (MDT) no Earth Explorer ou no SIG-SC (válido somente para Santa Catarina).

Obviamente, antes de iniciarmos, vamos instalar e carregar o pacote rayshader e outros pacotes necessários no nosso R com o código abaixo.


install.packages("rayshader")
install.packages("rgdal")

library(rayshader)
library(rgdal)

Após rodar esse comando, o R irá realizar o download de vários pacotes, dos quais o rayshader depende para funcionar.

Agora, vamos definir nosso ambiente de trabalho para evitarmos ter que escrever o caminho para nossos arquivos todo momento e vamos carregar nosso MDT.

Cuidado com arquivos de MDTs muito pesados, pois isso poderá dificultar o carregamento e processamento dele. Tenha um bom processador para executar esse tipo de arquivo.


setwd("C:/Users/ferna/Desktop/R/") # Define nosso ambiente de trabalho

mdt_local <- raster::raster("MDT10.tif")
mat_elev <- matrix(raster::extract(mdt_local, raster::extent(mdt_local), buffer=1000), nrow = ncol(mdt_local), ncol = nrow(mdt_local))

Note que utilizamos dois “Dois Pontos” para utilizar as funções do pacote Raster sem carregá-lo. Na função raster(), salvamos nosso MDT em uma variável e depois convertemos ela para matriz.

Utilizamos a função extract() para tirar os dados do nosso MDT (elevação, tamanho) e indicamos o número de linhas (nrow) e de colunas (ncol).

Agora que carregamos nosso relevo, vamos visualizá-lo. Perceba que utilizamos o chamado operador Pipe para criar uma sequência de comandos de forma que o resultado da primeira linha é utilizado na segunda, e o resultado da segunda é usado na terceira.


mat_elev %>%
  sphere_shade(texture = "desert") %>%
  plot_map()

Neste exemplo, utilizamos a textura “desert”, mas outras também são possíveis (e.g. “imhof1”, “bw” e “unicorn”).

Relevos gerados com o plot_map() com MDTs de diferentes resoluções.
Relevos gerados com o plot_map() com MDTs de diferentes resoluções.

Note que, conforme o tamanho do pixel é aumentado, há um maior destaque das sombras no relevo (mas se ele for grande demais, perdemos os detalhes do relevo).

Você pode modificar o tamanho do pixel do MDT usando softwares como QGIS (Exportando Raster) e ArcGIS (com a ferramenta Resample).

Dentro do comando sphere_shade() também é possível modificar o ângulo de incidência da luz solar, basta inserir o parâmetro sunangle e igualar ele ao ângulo de interesse (e.g. sphere_angle(sunangle = 45, texture = “desert”).

Também é possível adicionar uma camada de água utilizando as funções:

  • add_water()
  • detect_water()
  • render_water()

Porém, o algoritmo que a função detect_water() utiliza não demarcou o local que deveria ter um rio, mas você pode testar o código no seu MDT.


mat_elev %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(mat_elev), color = "desert") %>%
  plot_map()

No próximo passo, iremos gerar mais alguns tipos de sombra usando a função ray_shade() e ambient_shade().


mat_ray <- ray_shade(mat_elev, lambert = TRUE)
mat_amb <- ambient_shade(mat_elev)

mat_elev %>%
  sphere_shade(texture = "desert") %>%
  #add_water(detect_water(mat_elev), color = "desert") %>%
  add_shadow(mat_ray, 0.7) %>%
  add_shadow(mat_amb, 0.7) %>%
  plot_map()

O resultado das duas funções é apresentado na figura abaixo, onde a primeira imagem representa somente a função ray_shade() e a segunda uma combinação da primeira função e da ambient_shade().

Na esquerda, exemplo somente com ray_shade(); e na direita, exemplo com ray_shade() e ambient_shade().
Na esquerda, exemplo somente com ray_shade(); e na direita, exemplo com ray_shade() e ambient_shade().

Agora que aprendemos como carregar nosso raster, mostrar ele com diferentes texturas e adicionar sombras, vamos usar a função plot_3d(). Nesta função, temos vários parâmetros para serem configurados, os quais são apresentados abaixo:

  • zscale: Este parâmetro controla o exagero vertical, quanto maior for o número, maior é a distância entre os pixels (resultando em elevações menos exageradas);
  • theta: Rotação no eixo Z;
  • zoom: Fator de zoom;
  • phi: ângulo azimute;
  • windowsize: Tamanho da janela que irá gerar o relevo 3D.

Com o código abaixo, iremos gerar o relevo em três dimensões.


mat_ray <- ray_shade(mat_elev, zscale=3,maxsearch = 300)
mat_amb <- ambient_shade(mat_elev)

mat_elev %>%
  sphere_shade(texture = "desert") %>%
  #add_water(detect_water(mat_elev), color = "desert") %>%
  add_shadow(mat_ray, 0.7) %>%
  add_shadow(mat_amb, 0.7) %>%
  #plot_map()
  plot_3d(mat_elev,zscale=3,fov=0,theta=135,zoom=0.75,phi=45, windowsize = c(800,600))

O resultado deste código é apresentado abaixo.

Relevo em 3D criado pelo pacote "rayshader".
Relevo em 3D criado pelo pacote “rayshader”.

Já havíamos comentado de como inserir uma camada d’água no nosso relevo, mas também é possível adicionar após gerar ele usando os parâmetros como “water” (para carregar a camada) e “waterdepth” (determina a cota da lâmina d’água) na função plot_3d().


mat_elev %>%
  sphere_shade(texture = "imhof1") %>%
  #add_water(detect_water(mat_elev), color = "desert") %>%
  add_shadow(mat_ray, 0.7) %>%
  add_shadow(mat_amb, 0.7) %>%
  #plot_map()
  plot_3d(mat_elev,zscale=3,fov=0,theta=135,zoom=0.75,phi=45, windowsize = c(800,600),
  water=TRUE, waterdepth=80, wateralpha=0.5, watercolor="lightblue",
  waterlinecolor = "white", waterlinealpha = 0.3)

O resultado deste procedimento é apresentado na figura abaixo.

Relevo em 3D com camada de água.
Relevo em 3D com camada de água.

Veja que a cota de água é constante ao longo do relevo, o que, neste caso, acaba representando incorretamente a camada de água.

Também é possível utilizar o pacote rayshader para criar objetos para serem impressos em impressoras 3D, basta utilizar a função save_3dprint(). Mais detalhes no blog do Tyler Morgan-Wall.

Agora com o código pronto, podemos pegar outros MDTs e gerar nossos relevos em 3D, confira abaixo o relevo da bacia hidrográfica do rio Urussanga.

Relevo em 3D da bacia hidrográfica do Rio Urussanga (SC).
Relevo em 3D da bacia hidrográfica do Rio Urussanga (SC).

O rayshader também tem algumas funcionalidades que estão em desenvolvimento, tais como inserir rótulos e desfocar a imagem. Porém, para usá-las, você precisa instalar a versão do pacote em desenvolvimento, que é realizada usando os comandos abaixo.


install.packages('devtools')
devtools::install_github("tylermorganwall/rayshader")

Ficou com alguma dúvida? Deixe ela nos comentários que estaremos respondendo assim que possível e se o artigo te ajudou, compartilhe ele.

Fontes Consultadas.

rayshader github. Disponível em: <https://github.com/tylermorganwall/rayshader>. Acesso em 22 dez. 2018.

Confira também o twitter do desenvolver do pacote: Tyler Morgan-Wall.


Clique na figura abaixo e assine nossa lista de emails para receber nosso ebook "Como criar mapas de localização com ArcGIS 10.x".


Author: Fernando BS

Engenheiro Ambiental e de Segurança do Trabalho. Atua nas áreas de recuperação ambiental, geoprocessamento e ciência do solo. Busca soluções utilizando softwares como ArcGIS, R e MATLAB.

2 thoughts on “Como criar um relevo em 3D com sombras no R usando o pacote rayshader?”

    1. Boa tarde Krisnara,

      Obrigado pelo comentário.

      No RStudio, o relevo em 3D irá aparecer na janela de plotagem (Plot) e poderá ser exportado como imagem clicando em “Export” e “Save as Image”.

      Porém, no uso da função plot_3d(), você pode dar um print screen. Considerando que o pacote rayshader usa o rgl na função plot_3d(), é possível que esse comando funcione para exportar o gráfico em 3d como imagem: rgl.snapshot(filename = “plot.png”) (Fonte: http://www.sthda.com/english/wiki/a-complete-guide-to-3d-visualization-device-system-in-r-r-software-and-data-visualization#export-images-as-png-or-pdf).

      Trabalhando apenas com código, acredito que seja possível salvar como imagem usando funções do tipo png() ou jpg().

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *