编程知识 cdmana.com

Application of react optimization technique in web version ray tracing

I am using Web Technology to practice Ray Tracing Relevant knowledge , A lot of problems .

After overcoming those problems , I find , It goes with React Optimization techniques are the same ( there React Optimization techniques , It's not about optimizing React Realized Web APP The technique of , It is React Optimization techniques included in the internal implementation ).

Is not so much React Optimization skills in Web Applications in ray tracing . It's better to say ,UI Rendering optimization techniques , stay React ,Ray Tracing Or else? UI platform , It's universal .

It's just that there's an order of hearing , I personally have React background , Go to study again Ray Tracing, So the title . If I go the other way , It is 《Ray Tracing Optimization skills in React Applications in 》 了 .

Next , Let's list the problems and solutions one by one .

problem :Operator Overloading

JavaScript Not yet C++ And so on , Writing vectors 、 In matrix calculation , The code is cumbersome , It's not intuitive .

stay C++ in ,color The function is written like this .

img

Numbers multiply vectors , Only need to use * No . However, in JS You have to write like this :

img

stay JS in ,+-/* Cannot be used in Float32Array And so on . We have to abstract it into add, sub, mul, div And so on . It's dull to write , Debugging is also very painful .

that , How to overcome this problem ?

Solution :Babel Plugin

So far, we can search several Babel Plugin Can let JS Operator overloading is supported , But they all have their own problems .

such as :babel-plugin-overload, Its idea is to refer to Python, stay JS In the use Symbol.for('+') Express overloading.

img

Its principle is , Put all the +-/* The code is compiled like this :

img

Four Operational expressions , It becomes an anonymous function expression . Check left Whether to include overloaded properties .

It's a low degree of completion . Can't handle number * vector such left When the value is a number , There are also very serious performance issues , Each execution creates an anonymous function . It's basically not available .

The other is ,operator-overloading-js, Older , even Symbol All useless , It uses __plus This kind of agreed practice .

img

The idea is , Parse function at run time AST, Then compile and generate the new function and execute it .

Using it means that we rely on esprima,escodegen, Used to parse code and generate code respectively . This part is not small .

also , Because it generates new functions , Our function can't access the variables in the closure at will . This is basically goodbye ES2016 Module writing , Because of the top import Statement to introduce variables , For functions within a module , It's the variable in the closure . In its example , Module writing is commonjs Of .

img

As shown in the figure above ,overload Functions wrap almost all the code . Its runtime overhead , It increases with the size of the code . On the whole, the gains outweigh the losses .

After examining a number of options , I didn't succeed in finding a solution that could be used directly . therefore , I wrote one myself babel plugin, Finding it can be very simple .

In my scene , Just a few dozen lines of code , As shown below :

img

What it does is very simple , Is to put +-*/ The expression of , according to mapping Relationship , Replace with add, sub, mul and div Four function calls . hold left, right The operation value of , Pass in as a parameter .

such , We only need to achieve four runtime-helper function , You can customize +-*/ Behavior .

img

For example, we do it for 3 The behavior of adding a vector of two dimensions , First of all, it's a vector , It's not a vector, it's direct return left + right, Take the branch of default behavior . If it is , Then normalize to two vectors , And then use gl-matrix The method provided in .

sub, mul and div The code is almost the same , It's just calling different vec3 It's just the method .

There's only... Shown here vector Part of , There is no reference to matrix, Because I just can't use it in my current scene matrix. If necessary , It's easy to add , One more branch of judgment . We can also make plug-in registration mechanism .

img

overloading According to the registered plug-ins , Construct the corresponding runtime-helper, The matching plug-ins are detected in turn , Call its processing function .

Use effect , We can write intuitive code , There is no need to worry about the types of operations and left, right The order :

img

Babel The plug-in compiles it into :

img

Compared to our original code :

img

Just look at return sentence , We will find that , The result of its compilation is , It's the same as when we started , It's consistent on the whole . This is exactly what we want , We got the same results as we did by hand , But what we're actually writing is more straightforward code .

problem :Blocking The Main UI Thread

Use Web Technology to learn and implement ray tracing or 3D Graphic rendering , The most attractive advantage is , We can easily deploy and browse effects in browsers .

However , Highly computational algorithms like ray tracing , It takes a long time to calculate , To get the result . If you use synchronous Computing , It will jam the main thread , The page doesn't interact , It's even hard to shut down .

img

The picture above is rendered 500+ Here comes the ball 800 * 400 In the resolution of , Use node.js v8.9.4, It's close to 2 Hours . Even smaller balls , Only 20 To a , It will take more than ten minutes .

such , Even if we solve JS No, operator overloading The problem of , To no avail . No one wants to see a ray tracing that will jam your browser DEMO.

We have to find a way to solve this problem .

How to solve the problem , Please look at the next breakdown . I'll talk about Time Slicing and Streaming Rendering Optimization strategy .

版权声明
本文为[Industrial Agglomeration]所创,转载请带上原文链接,感谢
https://cdmana.com/2020/12/20201224152607724o.html

Scroll to Top