mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
103.04k stars 35.41k forks source link

New experimental renderer for Three.js #4936

Closed humu2009 closed 5 years ago

humu2009 commented 10 years ago

Hi:

I'm just working on an experimental renderer for Three.js called TinyGLRenderer. The new renderer is based on another project TinyGL.js, which implements a subset of OpenGL 1.1 compatible API in JavaScript using software rasterization. The interface follows the Three.js's renderer protocol and can be put to work just as Three'js' built-in renderers or other 3rd party ones.

Currently, it supports Mesh, Line, Material, Textures, Lights et Morph animations. I'll work on to add as many as possible. There are already a dozen of Three.js examples ported (by just replacing the renderer instance) to TinyGLRenderer and they seem to work fine, some of which can be found here!

Besides, I have a small question about Three.js: is there any way to determine or guess a Mesh is static? For I want to optimize the draw call by compiling meshes which stay unchanged to OpenGL display lists. It avoids submitting each face et each vertex every time thus improves the performance drastically.

mrdoob commented 10 years ago

Great stuff!

Are you aware of SoftwareRenderer? example

You may want to take a look at the drawTriangle method. Is pretty fast and optimised :)

mrdoob commented 10 years ago

Besides, I have a small question about Three.js: is there any way to determine or guess a Mesh is static? For I want to optimize the draw call by compiling meshes which stay unchanged to OpenGL display lists. It avoids submitting each face et each vertex every time thus improves the performance drastically.

There is the property dynamic in Geometry but it hasn't been used too strictly yet.

humu2009 commented 10 years ago

Really thanks for the prompt reply!

The SoftwareRenderer is just great! However, I don't treat the rasterization in the renderer level. The details of transformation, calculation of illumination and rasterization of primitives are all delegated to TinyGL.js. What the renderer actually does is to break down the scenegraph objects and attributes to opengl API.

In current implementation, the rendering only uses immediate mode that has to submit faces and vertices (via glVertex3f/glNormal3f/glTexCoord2f, etc) frame by frame. I'm trying to find a way to compile static meshes to display lists. The frame rates are expected to be doubled when it's done :-)

mrdoob commented 10 years ago

Ah, I see... Well, I meant that maybe you could consider implementing SoftwareRenderer's drawTriangle in TinyGL.js.

As per static meshes. I would suggest you to focus on BufferGeometry examples as we're slowly moving to those geometry structures.

humu2009 commented 10 years ago

This is really precious advice for me!

I have completed the optimization of drawing static/rigid objects by compiling them to display lists and just call the lists rather than repeatedly submitting faces and vertices frame by frame. This reduces thousands of draw calls per frame for a medium scene. The result looks satisfactory: I ported the Lucy example from Three.js's test suit and it runs at 7 fps on Chrome 28 and 2 more on Firefox 28 (thanks to the powerful asm.js) with the really large mesh up to 100,000 faces! The example mentioned is available here. And for another much smaller test scene, it provides full frame rates.

I'll follow your suggestion and go on to implement the BufferGeometry now. Thanks Doob!

mrdoob commented 10 years ago

Looking good! This has the potential of replacing CanvsRenderer :D

humu2009 commented 10 years ago

Support for BufferGeometry is ready for use now! I just followed THREE.WebGLRenderer's practice to implement this. There's also a working example for it, which looks not bad :-)

Another improvement is that for geometries with face materials, faces using a same material will be packed into a batch. This helps to reduce the number of material switches thus profits the frame rates.

There are about 30 more examples passing the tests with TinyGLRenderer. I'll work on to port more.

mrdoob commented 10 years ago

Looking good! :D

Be aware that the visibility logic has changed in the dev version of the WebGLRenderer. If a object has visible to false its children will no longer render.

humu2009 commented 10 years ago

Oh, current implementation is based on Three.js rv63. I'll move to the latest edition as soon as possible.

daoshengmu commented 10 years ago

@mrdoob I also find out the CanvasRender is a little bit slow, especially on my iPhone. I trace the code and think the bottleneck is drawTriangle too many times and

_context.moveTo( x0, y0 );
_context.lineTo( x1, y1 );
_context.lineTo( x2, y2 );
_context.closePath();

it seems would let performance to be slow.

Therefore, I am trying to use SoftwareRenderer to let my 3D models can be displayed on my iPhone. I find out there is no texture support in the SoftwareRenderer. Do you have any plan to support texturing?

mrdoob commented 10 years ago

Yes! Eventually... But by then WebGL will run on iPhones...

ghost commented 10 years ago

I guess iOS Safari has already Comes WEBGL enabled by default. On 15 Jul 2014 17:06, "Mr.doob" notifications@github.com wrote:

Yes! Eventually... But by then WebGL will run on iPhones...

— Reply to this email directly or view it on GitHub https://github.com/mrdoob/three.js/issues/4936#issuecomment-49019966.

humu2009 commented 10 years ago

The base project of TinyGLRenderer - TinyGL.js has been updated, with several advanced new features such as gl occlusion query API. I'll see if this can be utilized to improve TinyGLRenderer. I think that will be cool!