<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@v0.170.0/build/three.webgpu.js",
      "three/tsl": "https://cdn.jsdelivr.net/npm/three@v0.170.0/build/three.webgpu.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@v0.170.0/examples/jsm/"
    }
  }
</script>

<div id="courses"><a href="https://niklever.com/courses" target="_blank">niklever.com/courses</a></div>

<style>
			#source {
				position: absolute;
				top: 0;
				left: 0;
				width: 50%;
				height: 100%;
			}
			#result {
				position: absolute;
				top: 0;
				right: 0;
				width: 50%;
				height: 100%;
			}
			#renderer {
				position: absolute;
				bottom: 15px;
				right: calc( 50% + 15px );
				width: 200px;
				height: 200px;
				z-index: 100;
				pointer-events: none;
			}
		</style>

		<div id="source"></div>
		<div id="result"></div>
		<div id="renderer"></div>
body{
  padding: 0;
  margin: 0;
}

#courses{
  font: bold 30px "Arial";
  position: fixed;
  left: 20px;
  top: 20px;
  color: #ffffff;
  text-decoration: none;
}

a:link {
  color: white;
  text-decoration: none;
}

a:hover{
  color: #dddd33;
  text-decoration: underline;
}

a:visited {
  color: white;
  text-decoration: none;
}


import Transpiler from 'three/addons/transpiler/Transpiler.js';
			import GLSLDecoder from 'three/addons/transpiler/GLSLDecoder.js';
			import TSLEncoder from 'three/addons/transpiler/TSLEncoder.js';

			init();

			function init() {

				// editor

				window.require.config( { paths: { 'vs': 'https://cdn.jsdelivr.net/npm/monaco-editor@0.48.0/min/vs' } } );

				require( [ 'vs/editor/editor.main' ], () => {

					let timeout = null;

					const editorDOM = document.getElementById( 'source' );
					const resultDOM = document.getElementById( 'result' );

					const glslCode = `float turbulence( vec3 p ) {
	  float t = -.5;

	  for (float f = 1.0 ; f <= 10.0 ; f++ ){
		float power = pow( 2.0, f );
		t += abs( pnoise( vec3( power * p ), vec3(1.0) ) / power );
	  }

	  return t;
	}
`;

					const editor = window.monaco.editor.create( editorDOM, {
						value: glslCode,
						language: 'glsl',
						theme: 'vs-dark',
						automaticLayout: true,
						minimap: { enabled: false }
					} );

					const result = window.monaco.editor.create( resultDOM, {
						value: '',
						language: 'javascript',
						theme: 'vs-dark',
						automaticLayout: true,
						readOnly: true,
						minimap: { enabled: false }
					} );

					const showCode = ( code ) => {

						result.setValue( code );
						result.revealLine( 1 );

					};

					const build = () => {

						try {

							const glsl = editor.getValue();

							const decoder = new GLSLDecoder();
							const encoder = new TSLEncoder();

							const transpiler = new Transpiler( decoder, encoder );
							const tsl = transpiler.parse( glsl );

							showCode( tsl );

						} catch ( e ) {

							result.setValue( 'Error: ' + e.message );

						}

					};

					build();

					editor.getModel().onDidChangeContent( () => {

						if ( timeout ) clearTimeout( timeout );

						timeout = setTimeout( build, 1000 );

					} );

				} );

			}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/monaco-editor@latest/min/vs/loader.min.js