Extruding 3D Shapes from an SVG Element
Learn how to create 3D shapes from SVG and explore THREE.ParametricGeometry.
Use SVG to create 3D shapes
In THREE.ShapeGeometry
, we mentioned that SVG follows pretty much the same approach to drawing shapes. In this lesson, we’ll look at how we can use SVG images together with THREE.SVGLoader
to extrude SVG images. We’ll use the Batman logo as an example:
What is SVG?
SVG is an XML-based standard that can be used to create vector-based 2D images for the web. This is an open standard that is supported by all modern browsers. Directly working with SVG and manipulating it from JavaScript, however, isn’t very straightforward. Luckily, there are a couple of open source JavaScript libraries that make working with SVG a lot easier. Paper.js, Snap.js, D3.js, and Raphael.js are some of the best. If we want a graphical editor, we can also use the open-source Inkscape product.
Example: ExtrudeGeometry
Let’s execute the extrude-svg.js
example in the playground below by clicking the “Run” button:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') // const CopyWebpackPlugin = require('copy-webpack-plugin') const fs = require('fs').promises // we should search through the directories in examples, and use // the name from the files to generate the HtmlWebpackPlugin settings. module.exports = async () => { return { module: { rules: [ { test: /\.glsl$/i, use: 'raw-loader' } ] }, mode: 'development', entry: { 'chapter-6': './samples/chapters/chapter-6/extrude-svg.js', }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: '/', }, plugins: [ new HtmlWebpackPlugin(), ], experiments: { asyncWebAssembly: true }, devServer: { allowedHosts: 'all', host: '0.0.0.0', port: '3000', static: [ { directory: path.join(__dirname, 'assets'), publicPath: '/assets' }, { directory: path.join(__dirname, 'dist') } ] }, mode: 'development', } }
Note: We can change the properties of the geometries from the right control panel in the output screen.
The THREE.SVGLoader
First, let’s look at what the original SVG code looks like:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" x="0px" y="0px"width="1152px" height="1152px" xml:space="preserve"><g><path id="batman-path" style="fill:rgb(0,0,0);"d="M 261.135 114.535C 254.906 116.662 247.491 118.825 244.659 119.344C 229.433 122.131 177.907 142.565 151.973 156.101C 111.417 177.269 78.9808 203.399 49.2992 238.815C 41.0479 248.66 26.5057 277.248 21.0148 294.418C 14.873 313.624 15.3588 357.341 21.9304 376.806C 29.244 398.469 39.6107 416.935 52.0865 430.524C 58.2431 437.23 63.3085 443.321 63.3431 444.06C 63.4748 446.883 102.278 479.707 120.51 492.418C 131.003 499.734 148.168 509.93 158.654 515.075C 169.139 520.22 179.431 525.34 181.524 526.454C 187.725 529.754 187.304 527.547 179.472 515.713C 164.806 493.553 158.448 464.659 164.322 446.861C 169.457 431.303 192.013 421.501 214.324 425.132C 234.042 428.341 252.142 439.186 270.958 459.064C 286.677 475.67 292.133 482.967 295.31 491.634C 297.466 497.514 298.948 495.91 304.862 481.293C 313.673 459.519 329.808 445.735 346.35 445.851C 367.654 446 399.679 478.239 412.801 512.745C 414.093 516.144 416.593 522.632 418.355 527.163C 420.118 531.695 423.604 542.319 426.103 550.773C 430.848 566.832 432.355 566.851 434.872 550.88C 436.395 541.215 451.403 502.522 455.655 497.298C 457.038 495.599 460.63 489.896 463.636 484.625C 471.696 470.498 492.318 452.688 505.387 448.568C 514.602 445.663 517.533 445.549 525.51 447.782C 539.676 451.749 553.43 467.773 560.706 488.788L 563.242 496.114 L 567.096 490.012C 577.709 473.208 593.665 453.899 602.47 447.206C 607.884 443.09 613.378 438.825 614.679 437.729C 615.98 436.632 622.927 433.259 630.118 430.233C 655.159 419.693 681.195 423.407 693.273 439.241C 697.957 445.382 698.932 448.971 699.538 462.294C 700.174 476.284 699.51 479.864 693.686 493.854C 690.073 502.533 684.912 512.883 682.217 516.854C 679.523 520.825 678.172 524.074 679.215 524.074C 681.932 524.074 718.787 504.481 732.525 495.734C 760.018 478.228 788.909 452.599 803.9 432.418C 807.266 427.886 810.569 423.715 811.239 423.149C 814.498 420.395 828.253 393.099 833.17 379.627C 838.223 365.782 838.713 361.822 838.741 334.582C 838.776 300.425 836.431 291.124 820.154 260.873C 810.649 243.207 807.498 239.005 788.417 218.543C 751.511 178.968 688.147 142.549 621.582 122.654C 581.7 110.734 580.388 110.465 580.388 114.195C 580.388 115.328 581.302 116.255 582.418 116.255C 584.279 116.255 587.705 122.106 603.399 152.085C 613.977 172.29 618.077 189.427 618.264 214.21C 618.42 234.928 617.88 238.368 612.285 252.269C 604.327 272.04 590.066 286.889 572.829 293.352C 558.526 298.714 549.193 297.86 535.704 289.955C 526.777 284.723 512.304 267.644 509.816 259.404C 509.132 257.138 507.129 251.358 505.366 246.558C 503.602 241.759 501.646 231.564 501.018 223.902C 500.39 216.24 498.491 198.402 496.797 184.261C 495.104 170.121 493.307 152.047 492.803 144.097C 492.299 136.147 491.292 125.625 490.565 120.715L 489.242 111.787 L 483.323 118.267C 480.067 121.832 477.404 125.618 477.404 126.681C 477.404 127.744 476.603 128.613 475.624 128.613C 474.645 128.613 471.275 132.321 468.135 136.852L 462.426 145.091 L 431.038 145.091 L 399.65 145.091 L 386.811 128.494C 379.749 119.365 373.509 112.36 372.943 112.926C 372.377 113.491 371.57 118.875 371.15 124.888C 370.73 130.902 368.94 147.744 367.172 162.315C 365.405 176.887 363.523 195.424 362.99 203.509C 360.283 244.622 352.784 266.044 335.323 282.544C 326.456 290.923 312.488 297.497 303.508 297.518C 294.864 297.539 278.732 290.063 269.473 281.748C 246.952 261.521 238.846 229.614 245.481 187.314C 247.894 171.928 266.562 131.612 275.927 121.56C 277.987 119.348 279.673 116.786 279.673 115.867C 279.673 114.947 279.905 113.593 280.188 112.856C 281.28 110.017 271.977 110.837 261.136 114.536L 261.135 114.535 " /></g></svg>
Unless we’re an SVG guru, this probably won’t mean too much to us. Basically, what we see here is a set of drawing instructions. For instance on line 5, C 277.987 119.348 279.673 116.786 279.673 115.867
tells the browser to draw a cubic bezier curve, and L 489.242 111.787
tells us that we should draw a line to that specific position. ...