Skip to content

Instantly share code, notes, and snippets.

@LaraMateo

LaraMateo/web.md Secret

Forked from SantiagoVelasquezMontoya/web.md
Last active June 6, 2023 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LaraMateo/7d424bb26f4e32e066f4bcc626031599 to your computer and use it in GitHub Desktop.
Save LaraMateo/7d424bb26f4e32e066f4bcc626031599 to your computer and use it in GitHub Desktop.
WebGL

Tecnologías 3D en la Web

Web Graphics Library, es una API de Javascript para implementar gráficos 2D y 3D en el navegador, es una tecnología acelerada por hardware, es decir que se alimenta de la potencia computacional de la maquina, especialmente la tarjeta grafica o GPU, utilizada para implementar sitios web interactivos en 3D o videojuegos en el navegador haciendo uso de la etiqueta “Canvas”

Algunos ejemplos del uso de WebGL puede verse en Google Maps o Google Earth o para visualización de datos, también puede encontrarse comúnmente en páginas de marcas para mostrar sus productos como autos o dispositivos móviles o incluso en Unity para crear experiencias 3D más interactivas en la Web.

Facilitando la implementación de WebGL: Three.js y React Three Fiber

Existen librerías como Three.js y React Three Fiber que facilitan la implementación de WebGL al proporcionar abstracciones de alto nivel y componentes de React para crear y mostrar gráficos 2D y 3D en el navegador de manera más modular y fácil de entender

Porsche

| Porsche en React Three Fiber |

Three.js es una librería de código abierto que se puede utilizar en múltiples navegadores web y está escrita en Javascript, lo cual, la hace accesible a desarrolladores que utilizan cualquier librería o framework de Javascript, React Three Fiber, por otro lado, es una librería basada en Three.js y proporciona componentes de React para renderizar los gráficos 2D y 3D de forma más modular y sencilla.

Optimización de gráficos y rendimiento en WebGL

Es importante destacar que trabajar con WebGL puede ser exigente en términos de recursos de hardware, por lo que es importante optimizar los gráficos y el rendimiento para garantizar una experiencia fluida y eficiente en el navegador.

Aplicaciones prácticas de WebGL

WebGL también se utiliza para mostrar apartamentos en 3D de manera dinámica, proporcionando una experiencia más atractiva e interactiva para los posibles clientes. Con WebGL, los usuarios pueden ver un apartamento en 3D, rotar la cámara para ver el espacio desde diferentes ángulos e incluso caminar virtualmente a través del espacio

Showroom / littleworkshop

Las vistas de productos de 360 grados pueden ser una herramienta poderosa para sitios web de comercio electrónico, ya que permiten a los clientes obtener una mejor idea del diseño y la funcionalidad del producto. También pueden ayudar a los clientes a tomar decisiones de compra más informadas al proporcionar una vista más detallada del producto.

Design the next Iphone / neal.fun

Creación de escenas 3D con Three.js y React Three Fiber: tutorial paso a paso

En los últimos años, ha habido un aumento en la popularidad de la creación de animaciones 3D en el navegador. Una de las herramientas más populares para lograr esto es React Three Fiber, que proporciona un conjunto de componentes de React para construir escenas 3D utilizando Three.js. En esta sección, aprenderemos a crear una sencilla escena 3D que incluye el sol, la tierra y algunas estrellas.

 

earth

| Escena de la tierra en 3D |

Creamos un proyecto de Vite con React

npm create vite@latest earth-sun-system

Instalamos dependencias necesarias

npm i @react-three/fiber @react-three/drei @react-three/postprocessing three

En el componente main.jsx importamos el componente Canvas desde @react-three/fiber y lo instanciamos alrededor de App

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Canvas } from '@react-three/fiber';

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Canvas>
      <App />
    </Canvas>
  </React.StrictMode>
);

Desde el componente App creamos un componente Mesh alrededor de una geometria de esfera con un material basico.

El mesh puede verse como la composicion de un esqueleto y su piel, siendo la geometria esferica el esqueleto y el material basico con la prop de valor red su piel.

import React from 'react';
import './App.css';

const App = () => {
  return (
    <>
      <mesh>
        <sphereGeometry />
        <meshBasicMaterial color='red' />
      </mesh>
    </>
  );
};
export default App;

Con esto es suficiente para generar algo en pantalla, pero antes, en el App.css vamos a establecer estilos para que nuestro canvas ocupe toda la pantalla. Recuerda importarlo en App.jsx

* {
  box-sizing: border-box;
}

html,
body,
#root {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

Ejecutamos

npm run dev

red sphere

Podemos ver un canvas estatico con una esfera en roja en 3D en la pantalla, aunque aun no podremos orbitar la camara.

Ahora podemos importar las texturas que usaremos, @react-three/drei nos permite importar texturas de manera sencilla.

Importamos la libreria y las texturas, tendremos en cuenta que la direccion de las texturas es public/textures/..., el hook useTexture ya determina por defecto la ruta public, una vez importadas, cambiaremos el material de nuestro mesh de meshBasicMaterial a meshStandardMaterial y le asigamos la textura daymap mediante el prop map, este material soporta las texturas que usaremos, todo queda de la siguiente manera.

Las imagenes se pueden encontrar el Repositorio

import { useTexture } from '@react-three/drei';
import React from 'react';
import './App.css';

const App = () => {
  const [daymap, cloudMap, bump] = useTexture([
    'textures/daymap.jpg',
    'textures/cloudmap.jpg',
    'textures/elevation.jpg',
  ]);

  return (
    <>
      <mesh>
        <sphereGeometry />
        <meshStandardMaterial map={daymap} />
      </mesh>
    </>
  );
};
export default App;

Black sphere

Ahora vemos una esfera oscura en pantalla, esto es debido a que el material meshStandardMaterial es afectado por la luz, y aun no hay luz en la escena.

Procedemos a crear una luz ambiental con una intensidad de 0.5 debajo del mesh.

Tambien importaremos y agregaremos el componente OrbitControls para mover nuestra escena con el cursor.

import { OrbitControls, useTexture } from '@react-three/drei';
import React from 'react';
import './App.css';

const App = () => {
  const [daymap, cloudMap, bump] = useTexture([
    'textures/daymap.jpg',
    'textures/cloudmap.jpg',
    'textures/elevation.jpg',
  ]);

  return (
    <>
      <mesh>
        <sphereGeometry />
        <meshStandardMaterial map={daymap} />
      </mesh>
      <ambientLight intensity={0.5} />
      <OrbitControls />
    </>
  );
};
export default App;

Ya comienza a tener forma.

planeta-tierra

Procedemos a agregar la textura de relieve al meshStandardMaterial y una escala de relieve

//...
<mesh>
  <sphereGeometry />
  <meshStandardMaterial map={daymap} bumpMap={bump} bumpScale={0.7} />
</mesh>
//...

Si te diste cuenta, no ha hecho ninguna diferencia, esto es porque esta texture es reactiva a la luz, sin embargo la luz ambiental no es suficiente para activar el efecto, por lo que debemos agregar una luz con direccion, como pointLight

//...
      <mesh>
        <sphereGeometry />
        <meshStandardMaterial map={daymap} bumpMap={bump} bumpScale={0.7} />
      </mesh>
      <ambientLight intensity={0.5} />
      <pointLight intensity={2} position={[5, 5, 5]} />
//...

planeta-tierra-relieve

Ahora podemos ver que se ve mucho mas detallado e ilumanado no uniformente ya que la luz pointLight llega una direccion especifica, como el sol.

Para la implementacion de las nubes no lo haremos directamente en la Tierra sino que crearemos un nuevo mesh con el mapa de textura de las nubes y con una transparencia y opacidad definida, ademas con un radio un poco mayor al de la tierra, pero con el mismo centro, para cree la ilusion correctamente.

//..
      <mesh>
            <sphereGeometry />
            <meshStandardMaterial map={daymap} bumpMap={bump} bumpScale={0.7} />
      </mesh>
        <mesh>
            <sphereGeometry scale={1.025} />
            <meshStandardMaterial transparent opacity={0.22} map={cloudMap} />
        </mesh>
      <ambientLight intensity={0.5} />
      <pointLight intensity={2} position={[5, 5, 5]} />
//..

planeta-tierra-nubes

Ahora se pueden ver las nubes.

Ahora agregaremos un fondo mas oscuro con el componente color, debajo de pointLight lo instanciamos asi.

//..
      <pointLight intensity={2} position={[5, 5, 5]} />
      <color args={['black']} attach="background" />
//..

con la propiedad attach indicamos que este se va a adherir a la propiedad background del Canvas ya que este es el Parent de color

Ahora es momento de agregar la estrellas, lo cual @react-three/drei hace que sea bastante simple, con el componente Stars y algunos props lo instanciamos rapidamente.

import { Stars, OrbitControls, useTexture } from '@react-three/drei';
//...
<Stars
  radius={100}
  depth={200}
  count={5000}
  factor={6}
  saturation={0}
  color='green'
  fade
  speed={1}
/>;
//...

planeta-tierra-estrellas

Ahora procederemos a agregar el Sol, para el sol crearemos una esfera y ademas, la pointLight que creamos antes estara en la misma posicion que el Sol, para que asi la luz venga en esa direccion, a su vez aumentaremos su intensidad a 4 ya que estara mas alejada y le agregaremos el mismo color.

//...
{
  /* Sol */
}
<mesh position={[-100, 45, 0]} scale={1.5}>
  <sphereGeometry />
  <meshStandardMaterial color={[1, 1, 0]} />
</mesh>;

{
  /* Luz generada por el Sol */
}
<pointLight intensity={4} position={[-100, 45, 0]} color={'#e5b04d'} />;
//...

Ademas, bajaremos la intensidad de la luz ambiental para dar un efecto mas inmersivo, ya que la otra cara de la tierra es demasiado clara.

//...
<ambientLight intensity={0.1} />
//...

planeta-tierra-sol

Parece que el Sol esta demasiado apagado. Para el toque final agregaremos un efecto de Post-procesado, con un Capa de Bloom, esta capa genera un efecto de "Encandelillamiento" que hara ver nuestra escena mucho mejor.

Los Efectos de Post-Procesado pueden afectar bastante el rendimiento de una aplicacion, y por cada capa que se agregue puede ser aun mas exigente para el Hardware.

Para agregar el Bloom, desde la libreria @react-three/postprocessing importamos el Compositor y el efecto Bloom

Ademas, vamos a saturar los colores del material correspondiente a l Sol y a agregar propeidades emisivas para que se vea afectado por el Bloom.

Queda de la sigiente manera

..//

      {/* Sol */}
      <mesh position={[-100, 45, 0]} scale={4.5}>
        <sphereGeometry />
        <meshStandardMaterial
          color={[100, 100, 0]}
          emissiveIntensity={100} //Intensidad emisiva
          emissive={'#e5b04d'} //Color de emision
          toneMapped={false} //Mapeo de tono
        />
      </mesh>

    {/* Compositor y capa de Bloom */}
    <EffectComposer>
        <Bloom mipmapBlur intensity={0.1} luminanceThreshold={0} />
    </EffectComposer>
//...

Resultado final

planeta-tierra-sol-bloom

Y Codigo final de App

import { OrbitControls, useTexture, Stars } from '@react-three/drei';
import { Bloom, EffectComposer } from '@react-three/postprocessing';
import React from 'react';
import './App.css';

const App = () => {
  const [daymap, cloudMap, bump] = useTexture([
    'textures/daymap.jpg',
    'textures/cloudmap.jpg',
    'textures/elevation.jpg',
  ]);

  return (
    <>
      {/* Tierra */}
      <mesh>
        <sphereGeometry />
        <meshStandardMaterial map={daymap} bumpMap={bump} bumpScale={0.7} />
      </mesh>
      {/* Nubes */}
      <mesh scale={1.025}>
        <sphereGeometry />
        <meshStandardMaterial transparent opacity={0.22} map={cloudMap} />
      </mesh>
      {/* Estrellas */}
      <Stars
        radius={100}
        depth={200}
        count={5000}
        factor={6}
        saturation={0}
        color='green'
        fade
        speed={1}
      />
      {/* Sol */}
      <mesh position={[-100, 45, 0]} scale={4.5}>
        <sphereGeometry />
        <meshStandardMaterial
          color={[100, 100, 0]}
          emissiveIntensity={100}
          emissive={'#e5b04d'}
          toneMapped={false}
        />
      </mesh>
      {/* Luz generada por el Sol */}
      <pointLight intensity={4} position={[-100, 45, 0]} color={'#e5b04d'} />;{/* Compositor y capa de Bloom */}
      <EffectComposer>
        <Bloom mipmapBlur intensity={0.1} luminanceThreshold={0} />
      </EffectComposer>
      {/* Luz ambiental */}
      <ambientLight intensity={0.1} />
      {/* Controles */}
      <OrbitControls />
      {/* Fondo */}
      <color args={['black']} attach='background' />
    </>
  );
};
export default App;

Conclusiones

En conclusión, tecnologias como WebGL, Three.js y React Three Fiber, permiten a los desarrolladores crear gráficos 2D y 3D en el navegador de manera más fácil y modular, lo que ha llevado a una mayor cantidad de sitios web interactivos en 3D y videojuegos en línea. Aunque es importante tener en cuenta que trabajar con WebGL puede ser exigente en términos de recursos de hardware, la optimización del rendimiento garantiza una experiencia fluida y eficiente en el navegador. En general, el uso de estas tecnologías ha llevado a una experiencia más atractiva e interactiva en la web.

Articulo Elaborado Por:

Desarrollador de software en

BlogIAS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment