<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicolas Rannou</title>
    <description>The latest articles on DEV Community by Nicolas Rannou (@nicolasrannou).</description>
    <link>https://dev.to/nicolasrannou</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F91513%2Fcfc8d37f-7617-45b5-a43f-b667e231d731.jpeg</url>
      <title>DEV Community: Nicolas Rannou</title>
      <link>https://dev.to/nicolasrannou</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicolasrannou"/>
    <language>en</language>
    <item>
      <title>WASM in Create-React-App 4 in 5mn (without ejecting)</title>
      <dc:creator>Nicolas Rannou</dc:creator>
      <pubDate>Tue, 22 Dec 2020 15:24:37 +0000</pubDate>
      <link>https://dev.to/nicolasrannou/wasm-in-create-react-app-4-in-5mn-without-ejecting-cf6</link>
      <guid>https://dev.to/nicolasrannou/wasm-in-create-react-app-4-in-5mn-without-ejecting-cf6</guid>
      <description>&lt;h3&gt;
  
  
  First word
&lt;/h3&gt;

&lt;p&gt;In this post, we will write some rust code, compile it to WASM and run it from a CRA4 application without ejecting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rust to WASM FTW
&lt;/h3&gt;

&lt;p&gt;Why Rust? It's cool. There is a lot of hype around it so I decided to give it a go. The &lt;a href="https://doc.rust-lang.org/book/"&gt;rust book&lt;/a&gt; and &lt;a href="https://doc.rust-lang.org/stable/rust-by-example/"&gt;rust by examples&lt;/a&gt; were pretty useful to get an understanding of the basics.&lt;/p&gt;

&lt;p&gt;Once I got my head around the basic concepts, time to look into the conversion to WASM. There is a &lt;a href="https://rustwasm.github.io/docs/book/introduction.html"&gt;lot of nice documentation&lt;/a&gt; out there (from the Rust official documentation of course ;)).&lt;/p&gt;

&lt;p&gt;The recommendation is to use &lt;a href="https://rustwasm.github.io/docs/wasm-pack/quickstart.html"&gt;wasm-pack&lt;/a&gt;. That allows you to build and ship an importable WASM module in less than 2mn.&lt;/p&gt;

&lt;h4&gt;
  
  
  Create the project
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$&amp;gt; wasm-pack new my-wasm-project
$&amp;gt; cd my-wasm-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Package and public (&lt;a href="https://rustwasm.github.io/docs/wasm-pack/tutorials/npm-browser-packages/packaging-and-publishing.html"&gt;details&lt;/a&gt;)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$&amp;gt; wasm-pack build --scope nicolasrannou
$&amp;gt; cd pkg
/*make sure the package.json includes the right files. At the time I write this post some .js and .wasm files were missing.*/
$&amp;gt; npm publish --access=public
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CRACO
&lt;/h3&gt;

&lt;p&gt;To load the exported module I chose &lt;a href="https://github.com/gsoft-inc/craco"&gt;CRACO&lt;/a&gt; because it appears Create-react-app-rewired is not really maintained anymore and doesn't work well with CRA4.&lt;/p&gt;

&lt;h4&gt;
  
  
  Adding dependencies in your CRA4 project
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$&amp;gt; cd my-cra4-project
$&amp;gt; yarn add @nicolasrannou/my-wasm-project
$&amp;gt; yarn add @craco/craco
$&amp;gt; yarn add wasm-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not forget to update &lt;code&gt;package.json&lt;/code&gt; by replacing &lt;code&gt;react-scripts&lt;/code&gt; by &lt;code&gt;craco&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Setup the config file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$&amp;gt; cat craco.config.js

const { addBeforeLoader, loaderByName } = require('@craco/craco');

module.exports = {
  webpack: {
    configure: (webpackConfig) =&amp;gt; {
      const wasmExtensionRegExp = /\.wasm$/;
      webpackConfig.resolve.extensions.push('.wasm');

      webpackConfig.module.rules.forEach((rule) =&amp;gt; {
        (rule.oneOf || []).forEach((oneOf) =&amp;gt; {
          if (oneOf.loader &amp;amp;&amp;amp; oneOf.loader.indexOf('file-loader') &amp;gt;= 0) {
            oneOf.exclude.push(wasmExtensionRegExp);
          }
        });
      });

      const wasmLoader = {
        test: /\.wasm$/,
        exclude: /node_modules/,
        loaders: ['wasm-loader'],
      };

      addBeforeLoader(webpackConfig, loaderByName('file-loader'), wasmLoader);

      return webpackConfig;
    },
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Import the WASM code
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$&amp;gt; cat App.tsx
...
  useEffect(async () =&amp;gt; {
    const promise = await import("@nicolasrannou/my-wasm-project");

    promise.greet();
  }, []);
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👋 Until next time!&lt;/p&gt;

</description>
      <category>craco</category>
      <category>cra4</category>
      <category>webassembly</category>
      <category>rust</category>
    </item>
    <item>
      <title>Create textures from data in ThreeJS</title>
      <dc:creator>Nicolas Rannou</dc:creator>
      <pubDate>Fri, 17 Apr 2020 11:48:03 +0000</pubDate>
      <link>https://dev.to/nicolasrannou/create-textures-from-data-in-threejs-5bap</link>
      <guid>https://dev.to/nicolasrannou/create-textures-from-data-in-threejs-5bap</guid>
      <description>&lt;p&gt;I've been looking into creating a texture from data in &lt;code&gt;three.js&lt;/code&gt;. It is super easy, but there are some caveats, and some parts can be confusing. I fell into some traps many years ago, then fall into it again recently, so I decided to write about it!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is confusing (me)?&lt;/li&gt;
&lt;li&gt;
Grayscale textures

&lt;ul&gt;
&lt;li&gt;Which format&lt;/li&gt;
&lt;li&gt;Luminance format allows 3 types (WebGL1)&lt;/li&gt;
&lt;li&gt;Type to TypedArray containing the data&lt;/li&gt;
&lt;li&gt;Access the data in the fragment shader&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
Gimme some concrete examples!

&lt;ul&gt;
&lt;li&gt;UnsignedByte Texture&lt;/li&gt;
&lt;li&gt;HalfFloat Texture&lt;/li&gt;
&lt;li&gt;Float Texture&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Until next time!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;small&gt;&lt;i&gt;&lt;a href="http://ecotrust-canada.github.io/markdown-toc/"&gt;Table of contents generated with markdown-toc&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  What is confusing (me)?
&lt;/h1&gt;

&lt;p&gt;When creating a new texture, from data, you must set a &lt;code&gt;Format&lt;/code&gt;, a &lt;code&gt;Type,&lt;/code&gt; and provide you data in a specific type of &lt;code&gt;TypedArray&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DataTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The doc says&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"type" must correspond to the "format".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok... so how do I know which &lt;code&gt;Type&lt;/code&gt; to set for the &lt;code&gt;Format&lt;/code&gt; I want to use?&lt;/p&gt;

&lt;h1&gt;
  
  
  Grayscale textures
&lt;/h1&gt;

&lt;p&gt;In this post, I will only discuss grayscale (single channel) texture for WebGL1 since it is my current focus. Everything in the rest of this post will apply to whatever you are trying to support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which format
&lt;/h2&gt;

&lt;p&gt;Alright, I want to create a single channel (grayscale) texture.&lt;br&gt;
In the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/texImage2D"&gt;'internal format' section&lt;/a&gt;, you can find which &lt;code&gt;Format&lt;/code&gt; is the best fit for you, depending on the number of channels and the bytes per pixel.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LUMINANCE&lt;/code&gt; is the natural fit for grayscale textures. The caveat is that it only supports &lt;code&gt;UnsignedByte&lt;/code&gt; texture type for Webgl1.&lt;/p&gt;

&lt;p&gt;If you work with WebGL2, &lt;code&gt;R*&lt;/code&gt; formats allow you to support a variety of different bit-depth.&lt;/p&gt;

&lt;p&gt;To know more about what the different file format means, I found this page useful: &lt;a href="https://www.khronos.org/opengl/wiki/Image_Format"&gt;https://www.khronos.org/opengl/wiki/Image_Format&lt;/a&gt;. It explains what the suffix of the file format means &lt;code&gt;*F&lt;/code&gt;, &lt;code&gt;*_SNORM&lt;/code&gt; means and how those type of textures are interpreted. That is important regarding the data normalization. (keep reading)&lt;/p&gt;
&lt;h2&gt;
  
  
  Luminance format allows three types (WebGL1)
&lt;/h2&gt;

&lt;p&gt;Alright, we just learned that for WebGL1, &lt;code&gt;Luminance&lt;/code&gt; format goes with &lt;code&gt;UnsignedByte&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;Can we do better?&lt;/p&gt;

&lt;p&gt;If your browser supports the &lt;code&gt;OES_texture_float&lt;/code&gt; extension, a bunch of new types (&lt;code&gt;Float&lt;/code&gt; and &lt;code&gt;HalfFloat&lt;/code&gt;) are available for the &lt;code&gt;LUMINANCE&lt;/code&gt; format. (&lt;a href="https://www.khronos.org/registry/OpenGL/extensions/OES/OES_texture_float.txt"&gt;official documentation&lt;/a&gt;)&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Byte per Pixel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RGBA&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RGB&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LUMINANCE_ALPHA&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LUMINANCE&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALPHA&lt;/td&gt;
&lt;td&gt;FLOAT&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RGBA&lt;/td&gt;
&lt;td&gt;HALF_FLOAT_OES&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RGB&lt;/td&gt;
&lt;td&gt;HALF_FLOAT_OES&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LUMINANCE_ALPHA&lt;/td&gt;
&lt;td&gt;HALF_FLOAT_OES&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LUMINANCE&lt;/td&gt;
&lt;td&gt;HALF_FLOAT_OES&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ALPHA&lt;/td&gt;
&lt;td&gt;HALF_FLOAT_OES&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Type to TypedArray containing the data
&lt;/h2&gt;

&lt;p&gt;It is pretty straight forward:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Byte per Pixel&lt;/th&gt;
&lt;th&gt;Typed Array&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UnsignedByte&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Uint8Array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HalfFloat&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Uint16Array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Float&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Float32Array&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;What is important there is that the number of bits in the type array matches the byte per pixel in the table. Also, for &lt;code&gt;HalfFloat&lt;/code&gt; the data should be prepared appropriately.&lt;/p&gt;
&lt;h2&gt;
  
  
  Access the data in the fragment shader
&lt;/h2&gt;

&lt;p&gt;All the integer textures (including &lt;code&gt;UnsignedByteType&lt;/code&gt;) are normalized automatically while uploaded to the shaders, whereas the floating/integral textures (including &lt;code&gt;Float&lt;/code&gt; and &lt;code&gt;HalfFloat&lt;/code&gt;) are passed as it is.&lt;/p&gt;

&lt;p&gt;Based on the &lt;code&gt;Format&lt;/code&gt; name, you can know with which type of data you are dealing with and whether that will be normalized for you or not. (&lt;a href="https://www.khronos.org/opengl/wiki/Image_Format"&gt;ref&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In other words, in the fragment shader, when using an &lt;code&gt;UnsignedByteType&lt;/code&gt; texture, the values you get from the texture 2D are normalized between 0 and 1 automatically. For &lt;code&gt;FloatType&lt;/code&gt; and &lt;code&gt;HalfFloatType&lt;/code&gt; you get the value that was in the typed array without any normalization.&lt;/p&gt;
&lt;h1&gt;
  
  
  Gimme some concrete examples!
&lt;/h1&gt;
&lt;h2&gt;
  
  
  UnsignedByte Texture
&lt;/h2&gt;


&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pass anything from 0 to 255&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DataTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LUMINACE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UnsignedByteType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="k"&gt;varying&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;sampler2D&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="kt"&gt;vec3&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;texture2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;gl_FragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  HalfFloat Texture
&lt;/h2&gt;

&lt;p&gt;To convert a number to half float, do it the &lt;code&gt;three.js&lt;/code&gt; way: &lt;a href="https://github.com/mrdoob/three.js/blob/790811db742ea9d7c54fe28f83865d7576f14134/examples/jsm/loaders/RGBELoader.js#L352-L396"&gt;like this&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Watch out for &lt;a href="(https://en.wikipedia.org/wiki/Half-precision_floating-point_format)"&gt;precision errors&lt;/a&gt; when converting numbers to half float precision!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Uint16Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;largeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// pass anything from 0 to 10000&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toHalfFloat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;largeNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DataTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LUMINACE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HalfFloatType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="k"&gt;varying&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;sampler2D&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;uMax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="kt"&gt;vec3&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;texture2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;normalizedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uMax&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;gl_FragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Float Texture
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Float32Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;dataSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;largeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// pass anything from 0 to 10000&lt;/span&gt;
  &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;largeNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DataTexture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textureSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LUMINACE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FloatType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight glsl"&gt;&lt;code&gt;&lt;span class="k"&gt;varying&lt;/span&gt; &lt;span class="kt"&gt;vec2&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;sampler2D&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;uMax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;uniform&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="kt"&gt;vec3&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;texture2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;uData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vUv&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;vec4&lt;/span&gt; &lt;span class="n"&gt;normalizedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uMax&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;uMin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;gl_FragColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;vec4&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xyz&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Until next time!
&lt;/h1&gt;

&lt;p&gt;Until next time 🙋‍♂️, happy coding!&lt;/p&gt;

</description>
      <category>threejs</category>
      <category>datatexture</category>
    </item>
    <item>
      <title>Web-workers in Create React App (CRA) without unmounting</title>
      <dc:creator>Nicolas Rannou</dc:creator>
      <pubDate>Thu, 26 Mar 2020 16:31:02 +0000</pubDate>
      <link>https://dev.to/nicolasrannou/web-workers-in-create-react-app-cra-without-unmounting-4865</link>
      <guid>https://dev.to/nicolasrannou/web-workers-in-create-react-app-cra-without-unmounting-4865</guid>
      <description>&lt;p&gt;There are a lot of great options available when it comes to using web-workers in your web-app. Unfortunately, it can be challenging to use in a &lt;a href="https://dev.toxxx"&gt;Create React Application (CRA)&lt;/a&gt; without un-mounting your application.&lt;/p&gt;

&lt;p&gt;In this article, we share my journey of using web-workers in CRA (without un-mounting!)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why not unmounting?&lt;/li&gt;
&lt;li&gt;
Finding the right tools for YOU

&lt;ul&gt;
&lt;li&gt;Attempt 1: Threads.js&lt;/li&gt;
&lt;li&gt;Attempt 2: Workarize&lt;/li&gt;
&lt;li&gt;Attempt 3: Worker-loader&lt;/li&gt;
&lt;li&gt;Attempt 4: Comlink&lt;/li&gt;
&lt;li&gt;How it looks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;That's it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;small&gt;&lt;i&gt;&lt;a href="http://ecotrust-canada.github.io/markdown-toc/"&gt;Table of contents generated with markdown-toc&lt;/a&gt;&lt;/i&gt;&lt;/small&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why not unmounting?
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Webpack configuration can be overwhelming&lt;/li&gt;
&lt;li&gt;It can be difficult to upgrade to the next version of &lt;code&gt;react-scripts&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CRA team will not help us if something goes side-ways&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Finding the right tools for YOU
&lt;/h1&gt;

&lt;p&gt;The right tool for me would check the items in the following list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Must: Not unmounting CRA&lt;/li&gt;
&lt;li&gt;Must: Support &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Transferable"&gt;transferable objects&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nice to have: Easy to use&lt;/li&gt;
&lt;li&gt;Nice to have: Typescript support&lt;/li&gt;
&lt;li&gt;Nice to have: Pooling system&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Attempt 1: Threads.js
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/andywer/threads.js/"&gt;Threads.js&lt;/a&gt; looked very promising and feature complete (according to my requirements).&lt;/p&gt;

&lt;p&gt;However, to use it within &lt;code&gt;webpack&lt;/code&gt;, you must use its companion loader (&lt;a href="https://github.com/andywer/threads-plugin"&gt;threads-plugin&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;That means you must access the &lt;code&gt;webpack&lt;/code&gt; configuration file and add the loader there. That was a no-go for me because it implies un-mounting CRA.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 2: Workarize
&lt;/h2&gt;

&lt;p&gt;The next step was to find a tool that leverages &lt;code&gt;webpack loaders&lt;/code&gt; rather than plugins. With &lt;code&gt;webpack loaders&lt;/code&gt;, we can inline the loader in the import statement, therefore, we do not need to modify the &lt;code&gt;webpack&lt;/code&gt; configuration file to use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;\\&lt;/span&gt; &lt;span class="nx"&gt;inline&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;loader&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;statement&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Something&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-loader!./utils/filename&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/developit/workerize"&gt;workarize&lt;/a&gt; and its &lt;a href="https://github.com/developit/workerize-loader"&gt;workarize-loader&lt;/a&gt; seemed pretty cool. Although it doesn't support pooling the API looked awesome and super intuitive.&lt;/p&gt;

&lt;p&gt;But it doesn't support transferable objects at the time I write this post (03-26-2020), so that was another no-go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 3: Worker-loader
&lt;/h2&gt;

&lt;p&gt;Next, I tested &lt;a href="https://github.com/webpack-contrib/worker-loader"&gt;worker-loader&lt;/a&gt; and its transferable objects.&lt;/p&gt;

&lt;p&gt;It worked fine but using web-workers without sugar on top just didn't feel right for me - we can do better!&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt 4: Comlink
&lt;/h2&gt;

&lt;p&gt;Then comes &lt;a href="https://github.com/GoogleChromeLabs/comlink"&gt;comlink&lt;/a&gt;. It "makes WebWorkers enjoyable again" (to quote their README).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;comlink&lt;/code&gt; works nicely with the &lt;code&gt;worker-loader&lt;/code&gt; and adds this nice touch on top of the web-workers to make it easy to use.&lt;/p&gt;

&lt;p&gt;It may provide features you do not need but works fine in my experience (so far 🤞).&lt;/p&gt;

&lt;p&gt;It also works well with Typescript.&lt;/p&gt;

&lt;p&gt;It doesn't support pooling but I can live with that!&lt;/p&gt;

&lt;h3&gt;
  
  
  How it looks
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;\\&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Comlink&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comlink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cm"&gt;/* eslint-disable import/no-webpack-loader-syntax */&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Worker&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worker-loader!../util/worker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Comlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="err"&gt;\\&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Comlink&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comlink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;inc&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;Comlink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  That's it
&lt;/h1&gt;

&lt;p&gt;Each tool that was tested is great and you should really consider what you are looking for before making an informed decision.&lt;/p&gt;

&lt;p&gt;I can live without pooling as long as it is enjoyable to work with the web-worker so that's why I chose &lt;code&gt;comlink&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;TLDR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅Must: Not unmounting CRA&lt;/li&gt;
&lt;li&gt;✅Must: Support &lt;a href="https://dev.toxxx"&gt;transferable objects&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;✅Nice to have: Easy to use&lt;/li&gt;
&lt;li&gt;✅Nice to have: Typescript support&lt;/li&gt;
&lt;li&gt;🔴Nice to have: Pooling system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

</description>
      <category>createreactapp</category>
      <category>comlink</category>
      <category>workerize</category>
      <category>threadsjs</category>
    </item>
    <item>
      <title>Save lives with WebGL</title>
      <dc:creator>Nicolas Rannou</dc:creator>
      <pubDate>Fri, 10 Aug 2018 10:21:25 +0000</pubDate>
      <link>https://dev.to/nicolasrannou/save-lives-with-webgl-4ka0</link>
      <guid>https://dev.to/nicolasrannou/save-lives-with-webgl-4ka0</guid>
      <description>&lt;p&gt;*Images are courtesy of [1] - Evelyn DappaKai HigashigaitoJürgen FornaroSebastian LeschkaSimon WildermuthHatem Alkadhi - Cinematic rendering – an alternative to volume rendering for 3D computed tomography imaging&lt;/p&gt;

&lt;p&gt;I'm looking for WebGL / OpenGL / Passionate folks who could help me implement cinematic volume rendering in WebGL.&lt;/p&gt;

&lt;p&gt;This project aims to provide real life like visualization of medical data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcd89m8nvmb1x8r8ufbps.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcd89m8nvmb1x8r8ufbps.gif"&gt;&lt;/a&gt;&lt;br&gt;
[Left cinematic rendering / right volume rendering - image from [1]]&lt;/p&gt;

&lt;p&gt;I've implemented some classic volume rendering and I'd like to take it to the next level. However I think my volume rendering implementation is already a bit clumsy so cinematic rendering may be too much of a challenge.&lt;/p&gt;

&lt;p&gt;Currently at &lt;a href="https://github.com/FNNDSC/ami:" rel="noopener noreferrer"&gt;https://github.com/FNNDSC/ami:&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpg87qqjujvft0uzlnb5h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fpg87qqjujvft0uzlnb5h.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Any directions, help, suggestion would be awesome!&lt;/p&gt;

&lt;p&gt;Refs:&lt;/p&gt;

&lt;p&gt;[1] - Cinematic rendering – an alternative to volume rendering for 3D computed tomography imaging - &lt;a href="https://link.springer.com/article/10.1007/s13244-016-0518-1" rel="noopener noreferrer"&gt;https://link.springer.com/article/10.1007/s13244-016-0518-1&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webgl</category>
      <category>opengl</category>
      <category>cinematicrendering</category>
      <category>help</category>
    </item>
  </channel>
</rss>
