Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add haziness property to fog #10537

Merged
merged 3 commits into from
Apr 6, 2021
Merged

Add haziness property to fog #10537

merged 3 commits into from
Apr 6, 2021

Conversation

rreusser
Copy link
Contributor

@rreusser rreusser commented Apr 3, 2021

Update: I've updated the following description to match the current state of the PR.

This PR adds a "haziness" property to fog. The requirements of this PR are to:

  • improve the visual appearance of a (not-physically-based) atmosphere
  • not interfere with fog as currently implemented
  • add minimal cost to the rendering

A big additional advantage is that haze is more nicely visible than fog without looking like pea soup. It accomplishes this by simply adding the haze color and then tone-mapping the result to avoid blown out colors. It's too bad this isn't even minimally based on a proper atmospheric model so that it would match time of day with the skybox. It might be possible without excessive computational or implementation cost, but I don't know if that's reasonable to add at this time.

It adds three properties to fog:

  • strength: [0, 1]: how strong is the fog? Fog layers on top of haze, and as this goes to zero, you're left with just haze.
  • haze-color: Color of the haze
  • haze-energy: A multiplicative factor for the fog color. Overlaps with the lightness of haze-color but allows you to change the amount of haze without changing its color.

When the haze color is black, haze disappears. When haze-energy is zero, it exactly reduces to fog.

When fog strength decreases, it multiplies fog opacity by smoothstep to a power. This has the effect of pushing it away from the camera but looks much, much less like it's literally changing the near/far limits, which was very obvious and distracting. Raising the fog opacity to a power has the effect of delaying the onset of fog relative to haze:

easing

Haze is computed with the following algorithm:

  1. convert the color from srgb -> linear rgb
  2. add haze opacity * haze color
  3. tone-map the result (see: https://www.desmos.com/calculator/vb9fax8pc2 )
  4. convert the result from linear rgb -> srgb
  5. mix the tone-mapped result with the original input color so that unaffected regions are not tone-mapped (bright spots like glaciers otherwise get slightly darkened by tone-mapping)
  6. compute fog by mixing colors with the previous algorithm

haze-energy=0, fog-strength=1:

Screen Shot 2021-04-02 at 9 00 30 PM copy

haze-energy=1, fog-strength=0:

Screen Shot 2021-04-02 at 9 23 00 PM copy

@rreusser
Copy link
Contributor Author

rreusser commented Apr 5, 2021

Also:

  • I considered a redundant property (haze-magnitude?) that would scale the color contribution instead of making the color lighter or darker to accomplish that. Color feels somewhat overloaded currently since it has two effects: the color and the magnitude of the haze contribution.
  • I also considered haze-start or some other property so that fog and haze simply scale separately. The downside is just having to compute two fog opacities rather than using one for both. I don't have strong feelings. haziness instead just adjust the balance between fog and haze. It feels a bit too clever, I think.
  • Tests won't pass, but I think that's from the fog-implementation branch and not this branch.

@karimnaaji
Copy link
Contributor

Tests won't pass, but I think that's from the fog-implementation branch and not this branch.

Could you rebase the branch? CI has been unreliable in triggering in the branch, so this would be a good sanity check if we get it to pass in this branch. I fixed most of the issues locally but there might be a few left.

const uniforms = {};

uniforms['u_cam_matrix'] = tileID ? this.transform.calculateCameraMatrix(tileID) : this.identityMat;
uniforms['u_fog_range'] = fog.properties.get('range');
uniforms['u_fog_color'] = [fogColor.r, fogColor.g, fogColor.b];
uniforms['u_haze_color_linear'] = [hazeColor.r, hazeColor.g, hazeColor.b].map(c => 1.5 * Math.pow(c, 2.2));
Copy link
Contributor Author

@rreusser rreusser Apr 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this factor of 1.5 (totally arbitrary, chosen to put colors in a reasonable magnitude range), and would not be against just making this the mentioned additional style property (haze-magnitude, haze-amount, haze-intensity or something) so that you don't have to change the haze color in order to change the amount.

This is different than haziness, which is more of a selector knob for whether fog acts like pure fog or includes haze. I wouldn't actually mind removing that and just adding haze-start for that control instead (haze end is presumably the same as fog end). The reason I didn't is the discrepancy between fog-range (both limits) and haze-start (only one) which seemed a bit inconsistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, there's alpha as a way to specify the amount of haze, I suppose. The only downside there is that you're still clipped to kind of an arbitrary range since alpha = [0, 1]. What is "normal" haze? alpha = 0.2??

@karimnaaji
Copy link
Contributor

Thanks for the rebase, I think we get more meaningful errors now.

lint

/home/circleci/mapbox-gl-js/debug/fog.html
  40:26  error  A space is required after ','  comma-spacing
  40:30  error  A space is required after ','  comma-spacing

✖ 2 problems (2 errors, 0 warnings)
  2 errors and 0 warnings potentially fixable with the `--fix` option.

flow

Error ------------------------------------------------------------------------------------- src/render/painter.js:853:50

Cannot call `program.setFogUniformValues` with `uniforms` bound to `fogUniformsValues` because array type [1] has an
unknown number of elements, so is incompatible with tuple type [2] in property `u_haze_color_linear`.

 src/render/painter.js:853:50
 853|             program.setFogUniformValues(context, uniforms);
                                                       ^^^^^^^^

References:
 /tmp/flow/flowlib_211a3b78/core.js:251:89
 251|     map<U>(callbackfn: (value: T, index: number, array: Array<T>) => U, thisArg?: any): Array<U>;
                                                                                              ^^^^^^^^ [1]
 src/render/uniform_binding.js:66:33
  66| class Uniform3f extends Uniform<[number, number, number]> {
                                      ^^^^^^^^^^^^^^^^^^^^^^^^ [2]


Comment on lines 14 to 16
// Exponential smooth min
const float k = 8.0;
return -log2(exp2(-k * color) + exp2(-k)) * (1.0 / k);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constant evaluation of the second exp2 call seems to get optimized away. I'm not confident that's always the case, but I hope most shader compiler would make this static evaluation.

Screen Shot 2021-04-05 at 11 30 47 AM

Copy link
Contributor

@karimnaaji karimnaaji Apr 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(e.g. exp2(-k) constant evaluated as 1/256 -> 0.00390625)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks for checking. I considered hard-coding this, but was hoping even the most basic, rudimentary, minimal constant folding would catch this. Also wasn't 100% certain 8.0 is the right constant and thought I'd wait before hard-coding it. Glad to though if it's a more sure thing.

Comment on lines 17 to 21

// Cubic smooth min (works well)
//const float k = 0.8;
//vec3 h = max(k - abs(color - 1.0), vec3(0)) / k;
//return max(vec3(0), min(color, vec3(1)) - h * h * h * k * (1.0 / 6.0));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Remove extraneous comment (can be left in PR description for archiving).

Suggested change
// Cubic smooth min (works well)
//const float k = 0.8;
//vec3 h = max(k - abs(color - 1.0), vec3(0)) / k;
//return max(vec3(0), min(color, vec3(1)) - h * h * h * k * (1.0 / 6.0));
// Cubic smooth min (works well)
//const float k = 0.8;
//vec3 h = max(k - abs(color - 1.0), vec3(0)) / k;
//return max(vec3(0), min(color, vec3(1)) - h * h * h * k * (1.0 / 6.0));

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functions are almost visually indistinguishable. Thought I might double-check if we have a good way to micro-benchmark before definitely removing.

src/shaders/_prelude_fog.fragment.glsl Outdated Show resolved Hide resolved
Comment on lines 73 to 84
float haze_opac = fog_opacity(pos);
// When haze is present, raise the fog to a power to decrease it
float fog_opac = pow(haze_opac, u_fog_exponent);
vec3 haze = u_haziness * haze_opac * u_haze_color_linear;

// When there's any haze, we prefer the tone map, but when haze goes away,
// we transition to simply the original color
color = srgb_to_linear(color);
color = mix(color, tonemap(color + haze), sqrt(haze_opac));

// Mix the fog color to the result so that it still blends with the sky
return mix(linear_to_srgb(color), u_fog_color, fog_opac);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this code path, we may investigate adding a variant for haze disabled (by adding an extra define FOG_HAZE) that would make this code path the simplified expression return mix(color, u_fog_color, fog_opacity(pos)); when haze == 0.

This may seem extraneous, but since we're adding these new shader statements on every possible rendered fragment, there may be a non-negligible cost to these new function calls (sqrt and pow may be expensive function evaluations).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You read my mind. I definitely support this since it's so easy and probably does result in some small but measurable performance boost.

@karimnaaji
Copy link
Contributor

On linux (ubuntu firefox), I noticed possible NaNs evaluations.

Screen Shot 2021-04-05 at 11 59 11 AM

I can look into this issue as I have a clear repro of that (it does not seem to happen in the fog-implementation branch, only visible from this one).

The linux driver might be more finicky and less grateful about handling undefined behavior so we should double-check to make sure we don't have division by zero or possible infinite function evaluation.

@rreusser
Copy link
Contributor Author

rreusser commented Apr 5, 2021

@karimnaaji does the bug increase with haziness? If so, that's a strong argument that the culprit is the large power of a number in [0, 1] (which I semi-suspect is a bad idea in the first place)

@rreusser
Copy link
Contributor Author

rreusser commented Apr 5, 2021

In case they're needed later: I tried a couple smooth min functions for tonemapping—which here is just a smooth min between y=x and y=1. They worked fine. I went with exponential, though I have no particular reason to prefer it. I haven't benchmarked, but I suspect the difference is probably a bit below what we can meaningfully micro-benchmark.

const float k = 8.0;
return -log2(exp2(-k * color) + exp2(-k)) * (1.0 / k); 
const float k = 0.8;
vec3 h = max(k - abs(color - 1.0), vec3(0)) / k;
return max(vec3(0), min(color, vec3(1)) - h * h * h * k * (1.0 / 6.0));

@rreusser
Copy link
Contributor Author

rreusser commented Apr 6, 2021

@karimnaaji I've updated the PR with what I think are greatly improved parameters and have fixed the culling and cpu opacity calculations to match.

Haze and fog are now mostly independent:

  • Adjust fog.strength to change how strong the pure fog is
  • Adjust fog.haze-energy to adjust the multiplicative factor of haze

I'd even consider changing haze-energy to haze-strength so that the two are closely aligned since they're the basic two knobs to turn. I'd describe it more, but if you give it a try, it'll hopefully make sense right away.

src/render/painter.js Show resolved Hide resolved
src/style/fog.js Outdated Show resolved Hide resolved

return falloff * u_fog_opacity;
float haze_opac = fog_opacity(pos);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rearrange this code to be wrapping the shader expresion (length(pos) - u_fog_range.x) / (u_fog_range.y - u_fog_range.x), otherwise it's evaluated twice: for t and within the call to fog_opacity (maybe in a function or by passing t to fog_opacity directly?).

Copy link
Contributor Author

@rreusser rreusser Apr 6, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The short answer is not cleanly, no, I don't think so. The statement is duplicated so that the operations are not repeated. I instead added a note in 62f0ac2 pointing out that fog_opacity(vec3) is only rarely called (e.g. heatmap) while all other fog opacity computations go through fog_opacity(float) via fog_apply.

src/shaders/_prelude_fog.fragment.glsl Show resolved Hide resolved
@rreusser
Copy link
Contributor Author

rreusser commented Apr 6, 2021

I can't promise a property name or a constant won't change before production, but other than that, I don't anticipate further structural changes, so I don't have anything else to add to this PR.

@karimnaaji karimnaaji merged commit f133d3b into fog-implementation Apr 6, 2021
@karimnaaji karimnaaji deleted the ricky/fog-haze branch April 6, 2021 19:31
karimnaaji pushed a commit that referenced this pull request Apr 7, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request Apr 16, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request Apr 20, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request Apr 23, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request May 4, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request May 4, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji pushed a commit that referenced this pull request May 6, 2021
* Add haziness to fog

* Fix flow types

* Apply PR feedback
karimnaaji added a commit that referenced this pull request May 7, 2021
* Add fog stylespec

* Add fog type specification

* Add fog stylespec validation

Lint

* Add setFog() and getFog() APIs

* Add debug page

* Add note to validate fog

* Add Fog preludes and inject preprocessor defines when enabled

Fix Lint

Fix Flow

drop: Test Fog define

* Inject shader preludes and connect to globally defined fog uniforms

Fixup

* Apply fog to sky layers

Remove unnecessary shader statement

* Apply fog to terrain render

* Fix fog on sky gradient layers

* Apply fog to fill-extrusion layer

* Apply fog to fill layer

* Apply fog to fill-extrusion-pattern layer

Fixup shader statement

* Apply fog to fill-outline, fill-outline-pattern, fill-pattern layers

* Apply fog to background layer

* rename posMatrix to projMatrix

* Add cameraMatrix

* add separate cameraMatrix

* Calculate worldsize for cameraMatrix based on camera distance distance to sealevel

Fix flow and lint errors

* Simplify shader statement, remove extra division by w
u_cam_matrix is not projective and w is always 1 for points

* Add fading in of fog around 60 deg pitch

Fix lint errors

* Improve fog demo example and add GUI controls

* Fog tile culling in tile cover

Fixup comment

* Remove extraneous mult

Remove unused

* Simplify fog tile culling

Fix lint and flow

* Apply correct fog+blending in shaders (#10496)

* Make an attempt to implement consistent fog logic

* Add comments

* Apply premultiplied fix across shaders

* Clean up gamma correction

* Simply GLSL defines and fix shader compile error

* Fix syntax error and remove unused gamma correction

* Add fog to circles

* Apply fog to background pattern and hillshade

* Clean up a small shader optimization

* Add dithering to fog (#10506)

* Add basic dithering to fog

* Add temporal offset for fog

* Make uniform naming consistent

* Code golf the shaders just a little

* Separate dithering from fog function

* Rework the fog falloff function (#10515)

* Rework the fog falloff function

* Rework the fog function

* Add some spec validation

* Support fog on markers (#10516)

* Apply fog to Markers

* Fix lint flow and cleanup

* Fix opacity not updating for terrain and fog after updating the spec properties

* Add map.getFogOpacity API

* Code style

* Evaluate opacity less often

* Update per rebased changes

* Minor tweak

* Update src/style/fog.js

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/ui/marker.js

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/ui/map.js

Co-authored-by: Ricky Reusser <[email protected]>

* Update variable name per review

* Fixup invalid commit from github

* Address review comments

* Update per review

Co-authored-by: Ricky Reusser <[email protected]>

Fix popup tip not being occluded

* Fog-sky blending (#10527)

* Improve fog blending

* Clean up blending

* Remove fog-sky blending fix

Fix tests and low

* Do not cull tiles crossing over the horizon during fog culling phase
This prevents sudden pop in and out for tiles within the fog culling range

* Use fog color as default context clear color when enabled
This prevents unaffected fragments resulting in empty holes in location
where we do not draw fragments

* Cull at 80% of the distance between fog start end fog end
This leaves a non-noticeable 2% fog opacity change threshold
and reduces the distance before we start culling

* Add style diffing support and unit tests fog setFog and getFog

* Cutoff fog-opacity from the style specification

* Fix a bug using stale tile cover result due missing update to fog ranges
This issue was visible when updating fog properties and an incorrect tile
cover run would potentially leave invalid tiles on the viewport

* Switch fog to use window-scaled units (#10533)

* Switch fog to use window-scaled units

* Update style spec for fog range

* Update fog validation tests to match new limits

* Update fog validations

* Add haziness property to fog (#10537)

* Add haziness to fog

* Fix flow types

* Apply PR feedback

* Update marker opacity to use viewport-scaled height (#10542)

* Update marker opacity to use viewport-scaled height

* add units to variable names to make intent clear

* Code cleanup: Simplify getDistanceToSeaLevel + remove extraneous transform variable

* Add unit tests for furthestTileCorner

* Add unit tests for coveringTiles with fog culling

* Add basic symbol clipping when fog opacity is high (#10541)

* Rename cameraMatrix --> fogMatrix (#10544)

* Offload terrain fog to vertex shader (#10549)

* Offload terrain fog to vertex shader

* Don't set haze uniforms unless haze is present

* Remove haze varying unless haze is used

* Disable fog code path on the 2d case

* Remove redundant uniforms

* Simplify fog render logic

Co-authored-by: Karim Naaji <[email protected]>

* Add documentation of the public facing fog APIs + revise defaults (#10545)

* Add documentation of the public facing APIs

* Fixup missing `}`

* Update fog range docs

* Disable haze by default and fix mixed up haze properties

* Update src/style-spec/reference/v8.json

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/style-spec/reference/v8.json

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/style-spec/reference/v8.json

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/style-spec/reference/v8.json

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/ui/map.js

Co-authored-by: Ricky Reusser <[email protected]>

Co-authored-by: Ricky Reusser <[email protected]>

* Extract getAABBPointSquareDist from fog culling and add unit tests

* Use implicit vec3.transformMat4 division by w instead of explicit one

* Add fog as part of the release testing

* Add fog culling render test

* Add sky-blend render tests

* Add more style diffing unit tests and coverage around setFog/getFog public APIs

* Add unit tests for getFogOpacity

* Add basic terrain render tests

* Add fog marker occlusion unit tests

Remove extraneous note

* Add 2D tests for fog (#10566)

* Add 2D render tests for fog

* Test fog shaders

* Swap raster test

* Add half float heatmap render test image

* Increase test allowance for raster test

* Add more fog style spec render test coverage

* Fix shader preprocessor define leading to invalid shaders on production build variants (#10582)

* Prevent shader stripping issue on production builds
Always use same function signature independently of shader variant

* Use const for the unused param

* Directly use inlined parameter

* Fixup

* Fix render tests
Cannot use const as 'out' or 'inout' parameters.

* Fog style spec changes (#10590)

* Clean up fog style properties

* Present a more reasonable example

* Fix fog tests and validations

* Improve haze wording

* Apply review feedback: getFogOpacity -> queryFogOpacity

* Apply review feedback: Keep seperation of DOM-based and non-DOM based map element updates
Defer marker opacity update in DOM task queue

* Fix fog sky blending (#10578)

* Clean up fog sky blending

* Add fog sky blending fix to cpu side

Fix post rebase flow

* Better consistency in naming conventions

* Apply review feedback: Remove extraneous function call

* Apply review feedback: Rename sky-blend -> horizon-blend

* Apply review feedback: Increase range of pitch fading to be less aggressive

* Simplify haze evaluation (#10606)

* Simplify fog evaluation

* Switch to approximate gamma conversion

* Factor out haze application

* Document the haze_apply function

* Remove backticks

* Update src/shaders/_prelude_fog.fragment.glsl

* Apply review feedback: Consolidate shader code that can be shared in shared prelude

* Remove haze (#10613)

* Remove haze

* Remove density

* Catch a couple more small cleanup items

* Fix broken shader

* Tighten/restore fog culling

* Update src/render/painter.js

* Revert fog opacity regression from #10578 with CPU side evaluation of horizon blend

* Demo: Update default location

* Revise comments and cleanup shader code for readability
- Also removes extraneous branching with min in fog_apply_premultiplied

* Share fog varying globally in new shader prelude

* Revise comments and naming

* Code cleanup for better readability

* Fix validation error on complex style expression of fog color validation

* Fix validation error on complex style expression of fog range validation and add validation tests

* Simplify fog validation checks for expression(s)

* Switch fog from percentage window height to CSS vh units (#10632)

* Switch fog from percentage window height to CSS vh units

* Fix tests

* Fix more tests

* Fix still more tests

* Update src/style-spec/reference/v8.json

* Don't leave alpha of fog color unused (#10633)

* Don't leave alpha of fog color unused

* Apply review comments: Simplify flow, reduce uniforms

* Fix naming

* Update docs

* Fix flow

* Update all render tests to use new units

* Fixup consistent naming

* Add symbol clipping render test

* Sample terrain to estimate de facto camera scale (#10621)

* Continuously adjust the fog scale by raycasting

* Remove unused function

* Fix linter errors

* Name thresholds for clarity

* Hard-code sampling pattern

* Rearrange conditional

* Adjust sampling by horizon line

* Replace arbitrary constant with epsilon

* Remove stray import

* Simplify logic

* Only calc fog matrices on avg elevation change

* Fix cloning of transform

* Fix bug in state management

* Fix linter errors

* Remove debug code

* Move samples points inside function

* Fix accidental call to calcMatrices

* We still love you, flow

* Clarify code

* Add tests for EasedVariable

* Add one more test

* Fix default per latest changes and add render tests

* Fix alpha composing of horizon blend with sky gradient (#10640)

Make sure to un/post multiply alpha before/after applying sky gradient
contribution, as color ramps are premultiplied-alpha colors.  This prevents
washed out colors when using transparency.

* Account for FOV in fog (#10629)

* Account for FOV in fog

* Fix a typo

* Fix flow errors

* Fix a factor of two to make tests pass

* Fix bad merge

* Fix tests

* Shift fog range zero to the map center

* Fix debug

* Fix ranges to account for fov

* Remove unused variable

* Apply review feedback: Directly update marker style opacity

* Update per latest discussion: Use nameless units to prevent confusion
when trying to reason about them. As the units of the range are representing
3d distances on a sphere centered around camera center point, they can
hardly be reasoned about in terms of window height.

* Fixup naming consistency

* Fix race condition in fog terrain sampling (#10642)

* Fix race condition in fog terrain sampling

* Use frame start time stamp

* Update render test expectation

* Remove fog vh units (#10648)

* Remove fog vh units

* Fix floating point errors in test expectations

* Fix geo test

* Add fog demo and transition fixes (#10649)

* Skip unnecessary uniform code path when terrain is rendering to texture
On a typical frame with terrain this was called ~200 times, where only
20 were necessary (~10%)

* Fix invalid transition evaluation
When `delay` was undefined but not `now`, properties.begin and properties.end
were assigned incorrect values, leading to an immediate transition interpolation.
This was noticed when testing transitions on fog.

* Fix style.hasTransition() when fog is transitioning values

* Add a fog demo for release

* Directly use DOM queue rencently introduced by #10530

* Apply review feedback: Directly clear the timer here instead of unsetting it

* Apply review feedback: Fix nits, mark queryFogOpacity private until we
need to expose it publicly

* Update src/util/util.js

Co-authored-by: Ricky Reusser <[email protected]>

* Update src/util/util.js

Co-authored-by: Ricky Reusser <[email protected]>

* Apply review feedback: Fix nits

* Apply review feedback: Simplify matrix initialization

* make private methods private for docs

Co-authored-by: Arindam Bose <[email protected]>
Co-authored-by: Ricky Reusser <[email protected]>
Co-authored-by: Ansis Brammanis <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants