Git Product home page Git Product logo

node-gles's Introduction

Headless WebGL / OpenGL ES runtime for Node.js

This repo is under active development and is not production-ready. We are actively developing as an open source project.

Details

This project aims to provide a headless runtime for WebGL and OpenGL ES shaders under Node.js. This package will use the ANGLE engine to translate WebGL and OpenGL ES shaders to the target runtime. Please see the ANGLE project for more details on support.

Future plans include surfacing an API for running Compute Shaders and a OpenGL ES API. Patches are welcome!

Supported platforms

  • Mac OS
  • Windows
  • Linux

Creating a WebGL context

To create a new WebGLRenderingContext or WebGL2RenderingContext - simply include the package and call createWebGLRenderingContext():

const nodeGles = require('node-gles');

const gl = nodeGles.binding.createWebGLRenderingContext();

// Now, use `gl` for regular WebGL calls:
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
...

Run demo

Clone this repo for current demos - examples coming soon

  • Float32 texture upload and download:
$ yarn ts-node src/tests/float_texture_upload_test.ts
...

buffer:  Float32Array [ 0.5, 1.5, 2.5, 3.5 ]
  • Float16 texture upload and download:
$ yarn ts-node src/tests/half_float_texture_upload_test.ts
...

buffer:  Float32Array [ 0.5, 1.5, 2.5, 3.5 ]
  • Unsigned byte texture upload and download:
$ yarn ts-node src/tests/unsigned_byte_texture_upload_test.ts
...

buffer:  Uint8Array [ 1, 2, 3, 4 ]

Development

Build instructions are under heavy development and will include an Angle binary

This project currently requires ANGLE to be checked out and built in the same parent folder as this repo. Checkout and build ANGLE with the Debug setup. After ANGLE is built, run yarn for this project.

node-gles's People

Contributors

alexvestin avatar dependabot[bot] avatar nkreeger avatar rnconrad avatar robertleeplummerjr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-gles's Issues

PreBuilt Angle binaries no longer work "Error loading EGL entry points."

As of 2022, node-gles no longer works on due to the outdated ANGLE binary the installer uses.

It is still possible to make it work:

  • build Angle from source (do a Release build and set is_component_build = false)
  • copy the Release folder from the Angle build directory to node-gles/deps/angle/out/Release
  • rename "libEGL.dll.lib" -> "libEGL.lib" and "libGLESv2.dll.lib" -> "libGLESv2.lib"
  • node-gyp rebuild
  • If you're on windows and get a "Module Not Found" error, copy "libEGL.dll" and "libGLESv2.dll" into the build/Release folder

@nkreeger is it possible to get an updated ANGLE binary somewhere?

LF in getProgramInfoLog

A (very) minor issue, but there is a linefeed in the getProgramInfoLog after it has been linked
Edit: Also when created it should yield a 0 length string, but instead there is a 1 length string,
with a null char. So maybe double null characters have been added?

const nodeGles = require("node-gles");
const gl = nodeGles.binding.createWebGLRenderingContext();
var program = gl.createProgram();
let log = gl.getProgramInfoLog(program);

console.log(log.length, log.charCodeAt(0));

const vs = `// Vertex Shader
void main() {
  gl_Position = vec4(1.);
}`

const fs = `// Fragment shader
void main() {
  gl_FragColor = vec4(1.);
}`

function loadShader(gl, type, source) {
    const shader = gl.createShader(type);  
    gl.shaderSource(shader, source);  
    gl.compileShader(shader);  
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      gl.deleteShader(shader);
      return null;
    }
    return shader;
}

gl.attachShader(program, loadShader(gl, gl.VERTEX_SHADER, vs));
gl.attachShader(program, loadShader(gl, gl.FRAGMENT_SHADER, fs));
gl.linkProgram(program);

if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));
}

log = gl.getProgramInfoLog(program);
console.log(log.length, log.charCodeAt(0))

yields

1 0
2 10

Which makes checks for if (log === "") fail

Multiple Textures

Trying to use a frag shader with multiple texture samplers, code works fine in WebGL but in node-gles the second texture is empty. Also, swapping the activeTexture and uniform1i indexes, the same result just the other way around.

Approx date for TFJS support?

Still watching this project and wondering approximately when we can run TFJS using it?

Also, Mozilla’s been working on a Rust based implementation of WebGPU. I doubt that the TFJS team has started porting to WebGPU but it is on the horizon. So does this mean node-gles is an interim solution?

I’d like to make a decision on which platform to pick for running TFJS server side without exclusively depending on CUDA.

Testing WebGL with some CI

I find that puppeter in headless mode not support this list of extension:

WebGL:
EXT_disjoint_timer_query
EXT_frag_depth
EXT_shader_texture_lod
EXT_sRGB
WEBGL_compressed_texture_s3tc_srgb

WebGL2:
EXT_disjoint_timer_query_webgl2
WEBGL_compressed_texture_s3tc_srgb

Can I use node-gles for testing webgl code with some CI? As I understand your package supported some of them.

Add a helper to extract JS values as C-buffers

Some WebGL APIs allow "Array-like" objects to be passed into the call. This is a problem for generic JS Array types because they allow mixed data types. A helper method should be generated to properly place these items in a temporary buffer. This will also involve making sure all data-types match.

Specified module not found (windows 10)

Error: Le module spécifié est introuvable.
\?\F:\Lapin\api\node_modules\node-gles\build\Release\nodejs_gl_binding.node
at Object.Module._extensions..node (internal/modules/cjs/loader.js:730:18)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at bindings (F:\Lapin\api\node_modules\bindings\bindings.js:112:48)
at Object. (F:\Lapin\api\node_modules\node-gles\dist\index.js:4:15)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)

Error: Unsupported getParameter() option

I'm trying to use node-gles with three.js and get the following error:
Error: Unsupported getParameter() option

I guess get Parameter is not implemented yet?

When do you think it's realistic for me to try my three.js experiment again?

Running in Docker

Hi, any idea how to get this running inside a docker container? Currently integrated as part of WebGL unit testing which works perfectly. Except, fails on the CI/CD side since this is a docker environment. Makes sense since there are no GPU drivers. But even emulation would be acceptable since performance is a non-issue. This is all under Ubuntu. Any help is much appreciated.

How does it compare to Electron-TF for non-GUI apps?

I can already use Electron to bypass CUDA and rely on it for exposing WebGL to TFJS. How does Electron manage to work with all kinds of desktop GPUs? Does it use something like Angle under the hood? Or it works differently?

Besides being dramatically lighter and aimed at non-GUI apps that can be written on top of OpenGLES (and I assume having a WebGL backend fo TFJS), how does Node-GLES compare to Electron?

My evolving aim (as of now) is to be able to build TF apps in JS in embedded form factor without relying on NVIDIA specific libraries like CUDA and cuDNN.

I could use some clarity.

Unable to run demo files

yarn ts-node unsigned_byte_texture_upload_test.ts

dyld[75129]: missing symbol called
error Command failed with signal "SIGABRT".

The line causing this issue: const gl = gles.createWebGLRenderingContext();

Add integration tests

It would be great to have:

  • Automatic tests from WebGL conformance tests
  • Jasmine tests for specific functionality

Any instructions for running Tensorflow.js?

Hi,

Which version of tensorflow.js is currently supported?

Is there an example somewhere of tensorflow.js running on node-gles?

Last and most key question is: does this offer any benefit over using the C version of tensorflow for nodejs (I believe there is a tensorflow native module for node out there, based on my vague recollection) For instance, does node-gles allow tensorflow.js to fully exploit the GPU (if present on the system) whereas tensorflow nodejs native module is a CPU only version? Also, what if the system has multiple GPUs, does tensorflow.js have any plans to support local distributed training or distributed inference using multiple GPUs?

Would love to hear back soon. Thank you. This is EXCITING.

glReadPixels only affects first four elements

Sorry for spamming your repo ha.
A little less minor bug, is glReadPixels is only setting the first 4 elements of the array.

I made a test painting a red fullscreen quad, so every n*4 and (n+3)*4 element should be 255.

const nodeGles = require("node-gles");
const width = 256;
const height = 256;

//var gl = require('gl')(width, height, { preserveDrawingBuffer: true })
const gl = nodeGles.binding.createWebGLRenderingContext();

var program = gl.createProgram();

const vs = `// Vertex Shader
attribute vec4 aVertexPosition;
void main() {
  gl_Position = aVertexPosition;
}`

const fs = `// Fragment shader
void main() {
  gl_FragColor = vec4(1., 0., 0., 1.0);
}`

function loadShader(gl, type, source) {
    const shader = gl.createShader(type);  
    gl.shaderSource(shader, source);  
    gl.compileShader(shader);  
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
      gl.deleteShader(shader);
      return null;
    }
    return shader;
}

gl.attachShader(program, loadShader(gl, gl.VERTEX_SHADER, vs));
gl.attachShader(program, loadShader(gl, gl.FRAGMENT_SHADER, fs));
gl.linkProgram(program);

if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program));
}

const positionLocation = gl.getAttribLocation(program, 'aVertexPosition');

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
  -1.0,  1.0,
   1.0,  1.0,
  -1.0, -1.0,
   1.0, -1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
gl.useProgram(program);
gl.viewport(0,0,width, height);

gl.clearColor(0.3, 0.3, 0.3, 1.0);  // Clear to black, fully opaque
gl.clearDepth(1.0);                 // Clear everything
gl.enable(gl.DEPTH_TEST);           // Enable depth testing
gl.depthFunc(gl.LEQUAL);            // Near things obscure far things

// Clear the canvas before we start drawing on it.

gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);


const pixels = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

for(var i = 0; i < pixels.length; i++) {
  if (pixels[i] > 0) {
    console.log(i, pixels[i])
  }
}

which yields

0 255 
3 255 

So the first pixel is being read and put in to the pixel array.

I can't use it on Windows 10

Unable to find specified module. Can anyone help me?

`D:\Sviluppo\VirtualTVStudio\gles>node index
D:\Sviluppo\VirtualTVStudio\gles\node_modules\bindings\bindings.js:121
throw e;
^

Error: Impossibile trovare il modulo specificato.
\?\D:\Sviluppo\VirtualTVStudio\gles\node_modules\node-gles\build\Release\nodejs_gl_binding.node
�[90m at Object.Module._extensions..node (internal/modules/cjs/loader.js:1065:18)�[39m
�[90m at Module.load (internal/modules/cjs/loader.js:879:32)�[39m
�[90m at Function.Module._load (internal/modules/cjs/loader.js:724:14)�[39m
�[90m at Module.require (internal/modules/cjs/loader.js:903:19)�[39m
�[90m at require (internal/modules/cjs/helpers.js:74:18)�[39m
at bindings (D:\Sviluppo\VirtualTVStudio\gles\node_modules\�[4mbindings�[24m\bindings.js:112:48)
at Object. (D:\Sviluppo\VirtualTVStudio\gles\node_modules\�[4mnode-gles�[24m\dist\index.js:4:15)
�[90m at Module._compile (internal/modules/cjs/loader.js:1015:30)�[39m
�[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)�[39m
�[90m at Module.load (internal/modules/cjs/loader.js:879:32)�[39m`

Error: The platform win32-x64 is not currently supported!

C:\Users\alexd\gpu-brick-sort>yarn add node-gles
yarn add v1.16.0
warning ......\package.json: No license field
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.3.0".
[4/4] Building fresh packages...
error C:\Users\alexd\gpu-brick-sort\node_modules\node-gles: Command failed.
Exit code: 1
Command: node scripts/install.js
Arguments:
Directory: C:\Users\alexd\gpu-brick-sort\node_modules\node-gles
Output:
C:\Users\alexd\gpu-brick-sort\node_modules\node-gles\scripts\install.js:44
throw new Error(The platform ${platformArch} is not currently supported!);
^

Error: The platform win32-x64 is not currently supported!
at Object. (C:\Users\alexd\gpu-brick-sort\node_modules\node-gles\scripts\install.js:44:9)
at Module._compile (internal/modules/cjs/loader.js:805:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:816:10)
at Module.load (internal/modules/cjs/loader.js:672:32)
at tryModuleLoad (internal/modules/cjs/loader.js:612:12)
at Function.Module._load (internal/modules/cjs/loader.js:604:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:868:12)
at internal/main/run_main_module.js:21:11
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

The README says windows support is planned

Ubuntu on Windows (WSL) ?

Hey ! I wanted to know if it's possible to run noide-gles in Ubuntu on Windows! Currently I can install everything but when I run yarn ts-node src/tests/unsigned_byte_texture_upload_test.ts or similar I get the following error:

dummy@PC:~/dev/node-gles$ yarn ts-node src/tests/unsigned_byte_texture_upload_test.ts
yarn run v1.10.1
$ /home/dummy/dev/node-gles/node_modules/.bin/ts-node src/tests/unsigned_byte_texture_upload_test.ts
terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)
error Command failed with exit code 134.

Add Windows support

1.) Provide a pre-built version of ANGLE for Windows (chromium/3729).
2.) Update scripts/install.js to handle Windows download
3.) Update binding.gyp (see tfjs-node for reference code).

Enable the ability to create a WebGL rendering context with options

The current method for creating a WebGL session createWebGLRenderingContext() simply tries to default a WebGL EGL/GL context and session with the best options. It would be nice to allow for specific versions and potentially extensions to be enabled/disabled at creation.

gl.getSupportedExtensions return empty.

webgl_rendering_context.cc

napi_value WebGLRenderingContext::GetSupportedExtensions(...
std::string s(context->eglContextWrapper_->angle_requestable_extensions
                    ->GetExtensions());

the s value is empty.

printf("angle_requestable_extensions: %s\n\n", context->eglContextWrapper_->angle_requestable_extensions
                    ->GetExtensions());
printf("egl_extensions: %s\n\n", context->eglContextWrapper_->egl_extensions
                    ->GetExtensions());
printf("gl_extensions: %s\n\n", context->eglContextWrapper_->gl_extensions
                    ->GetExtensions());

output:

angle_requestable_extensions: 

egl_extensions: EGL_KHR_create_context EGL_KHR_get_all_proc_addresses EGL_ANGLE_create_context_webgl_compatibility EGL_CHROMIUM_create_context_bind_generates_resource EGL_EXT_pixel_format_float EGL_KHR_surfaceless_context EGL_ANGLE_display_texture_share_group EGL_ANGLE_create_context_client_arrays EGL_ANGLE_program_cache_control EGL_ANGLE_robust_resource_initialization EGL_ANGLE_iosurface_client_buffer EGL_ANGLE_create_context_extensions_enabled EGL_ANDROID_blob_cache EGL_ANDROID_recordable 

gl_extensions: GL_ANGLE_client_arrays GL_ANGLE_depth_texture GL_ANGLE_explicit_context GL_ANGLE_explicit_context_gles1 GL_ANGLE_framebuffer_blit GL_ANGLE_framebuffer_multisample GL_ANGLE_instanced_arrays GL_ANGLE_memory_size GL_ANGLE_multi_draw GL_ANGLE_program_cache_control GL_ANGLE_provoking_vertex GL_ANGLE_request_extension GL_ANGLE_robust_client_memory GL_ANGLE_texture_compression_dxt3 GL_ANGLE_texture_compression_dxt5 GL_ANGLE_texture_multisample GL_ANGLE_texture_rectangle GL_ANGLE_translated_shader_source GL_CHROMIUM_bind_generates_resource GL_CHROMIUM_bind_uniform_location GL_CHROMIUM_color_buffer_float_rgb GL_CHROMIUM_color_buffer_float_rgba GL_CHROMIUM_copy_texture GL_CHROMIUM_sync_query GL_EXT_blend_minmax GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_debug_marker GL_EXT_disjoint_timer_query GL_EXT_draw_buffers GL_EXT_float_blend GL_EXT_frag_depth GL_EXT_instanced_arrays GL_EXT_map_buffer_range GL_EXT_multisample_compatibility GL_EXT_occlusion_query_boolean GL_EXT_read_format_bgra GL_EXT_sRGB GL_EXT_sRGB_write_control GL_EXT_shader_texture_lod GL_EXT_texture_compression_dxt1 GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_texture_rg GL_EXT_texture_storage GL_EXT_unpack_subimage GL_KHR_debug GL_KHR_parallel_shader_compile GL_NV_fence GL_NV_pack_subimage GL_OES_depth32 GL_OES_element_index_uint GL_OES_fbo_render_mipmap GL_OES_mapbuffer GL_OES_packed_depth_stencil GL_OES_rgb8_rgba8 GL_OES_standard_derivatives GL_OES_surfaceless_context GL_OES_texture_border_clamp GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_OES_texture_npot GL_OES_vertex_array_object

Error: Argument is not a number!

I'm trying to use node-gles with three.js and its WebGLRenderTarget class:

const width = 1920;
const height = 1080;
const renderTarget = new WebGLRenderTarget(width, height, {
  depthBuffer: true,
  stencilBuffer: true,
  format: RGBAFormat
});
renderer.render(scene, camera, renderTarget);

but an error has occurred:

????/node_modules/three/build/three.js:21507
                        _gl.pixelStorei( 37440, texture.flipY );
                            ^

Error: Argument is not a number!
    at uploadTexture (????/node_modules/three/build/three.js:21507:8)
    at setTexture2D (????/node_modules/three/build/three.js:21244:6)
    at setupDepthTexture (????/node_modules/three/build/three.js:21785:4)
    at setupDepthRenderbuffer (????/node_modules/three/build/three.js:21816:5)
    at WebGLTextures.setupRenderTarget (????/node_modules/three/build/three.js:21957:5)
    at WebGLRenderer.setRenderTarget (????/node_modules/three/build/three.js:25482:14)
    at WebGLRenderer.render (????/node_modules/three/build/three.js:24239:10)

In the description of the page WebGLRenderingContext.pixelStorei, the second parameter of method WebGLRenderingContext.pixelStorei can be GLint, GLboolean or GLenum, however the line 3720 of binding/webgl_rendering_context.cc file seems to only support GLint:

Maybe using Texture will also have the same problem? I will try it.
Using textures will also have the same problem and more.
I try to modify the "WebGLRenderingContext::PixelStorei" method to support gl.UNPACK_FLIP_Y_WEBGL with GLboolean value, but it didn't work at all, whatever true or false.

/* static */
napi_value WebGLRenderingContext::PixelStorei(napi_env env,
                                              napi_callback_info info) {
  LOG_CALL("PixelStorei");

  napi_status nstatus;
  size_t argc = 2;
  napi_value args[2];
  napi_value js_this;
  nstatus = napi_get_cb_info(env, info, &argc, args, &js_this, nullptr);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);
  ENSURE_ARGC_RETVAL(env, argc, 2, nullptr);

  ENSURE_VALUE_IS_NUMBER_RETVAL(env, args[0], nullptr);
  // ENSURE_VALUE_IS_NUMBER_RETVAL(env, args[1], nullptr);
  napi_valuetype type;
  nstatus = napi_typeof(env, args[1], &type);
  if (nstatus != napi_ok || (type != napi_number && type != napi_boolean)) {
    NapiThrowError(env, "Argument is not a number or boolean!", __FILE__, __LINE__);
    return nullptr;
  }

  WebGLRenderingContext *context = nullptr;
  nstatus = UnwrapContext(env, js_this, &context);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);

  GLenum pname;
  nstatus = napi_get_value_uint32(env, args[0], &pname);
  ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);

  // GLint param;
  // nstatus = napi_get_value_int32(env, args[1], &param);
  // ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);
  //
  // context->eglContextWrapper_->glPixelStorei(pname, param);
  if (type == napi_number) {
    GLint param;
    nstatus = napi_get_value_int32(env, args[1], &param);
    ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);
    
    context->eglContextWrapper_->glPixelStorei(pname, param);
  }
  else if (type == napi_boolean) {
    bool param;
    nstatus = napi_get_value_bool(env, args[1], &param);
    ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr);
    
    context->eglContextWrapper_->glPixelStorei(pname, static_cast<GLboolean>(param));
  }

#if DEBUG
  context->CheckForErrors();
#endif
  return nullptr;
}

(gl.UNPACK_FLIP_Y_WEBGL=false) Expectation:
texture flip y expectation

(gl.UNPACK_FLIP_Y_WEBGL=false) Result:
texture flip y result

macOS 10.14.6, node.js 11.13.0,
with node-gles 0.0.14
with three.js 0.107.0

Better build instructions

This project currently requires ANGLE to be checked out and built in the same parent folder as this repo. is a bit confusing. Just a few lines would be very helpful.

Understanding the differences between headless-gl?

First off, I love seeing that Google is contributing in this space 👍

Like many Node.js devs, I'm currently a heavy user of headless-gl.

I was wondering if you could break down the differences in project aim, scope, and implementation between these two related projects?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.