# 3D Renderer Demo

**URL:** <https://forum.makecode.com/t/3d-renderer-demo/2294>\
**Category:** Arcade\
**Created:** [June 2, 2020, 7:39pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294 "2020-06-02T19:39:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 2, 2020, 7:39pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/1 "2020-06-02T19:39:19Z")

</div>

Hi all. I’m new here. I thought I would try making a 3d renderer for Arcade, and here’s what I came up with:

> **[3d](https://arcade.makecode.com/90744-06161-01451-92108)**
>
> Made with ❤️ in Microsoft MakeCode Arcade.

![2020-06-02_12-03-43](https://us1.discourse-cdn.com/flex020/uploads/makecode/original/2X/2/21cb0c686013ccd962a1a7c29669f8f1f004a083.gif)

Controls:

- Joystick: Move camera
- A: Cycle the lighting model (None, Flat, Dither)
- B: Toggle wireframe overdraw

The renderer has an optional depth buffer, but using it causes an out-of-memory error (err 22) on my PyGamer! I’m trying to think of a clever way to solve that. The depth buffer can be disabled in engine.ts, in case you wanted to try running this on your device.

Not a surprise, but it runs really slooow on device, even with just one object in the scene. Flat shading mode speeds it up a little. Dither mode (pictured) is pretty expensive.

Still todo:

- Improve perspective projection
- Find a way to support depth buffer on device
- Proper triangle/view frustum clipping
- Add more primitive shapes
- Make a better looking demo scene (spaceship flying through a city ala [https://youtu.be/XezcZVu66QI?t=485](https://youtu.be/XezcZVu66QI?t=485) ?)
- Experiment with other types of lighting
- Find performance problems and try to improve them
- Or maybe just call it good enough and move on to the next thing 🙂

I hope you enjoy it!

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 2, 2020, 8:57pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/2 "2020-06-02T20:57:47Z")

</div>

One aspect of this experiment I found particularly interesting was having to implement sine and cosine for the fixed-point Fx8 type. I ended up using a quarter-arc lookup table (64 entries), mapping to a 256-angle unit circle. I probably should mention in a code comment that angles are not in radians OR degrees! They’re in “Fx8ians”, I guess :).

---

<div class="post-metadata">

**Author:** ![jwunderl](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/jwunderl/32/5308_2.png) [@jwunderl](https://forum.makecode.com/u/jwunderl)\
**Post date:** [June 2, 2020, 9:32pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/3 "2020-06-02T21:32:02Z")

</div>

Hmm, haven’t looked too deeply into the implementation yet but a few things I’ll point out in case you haven’t seen them :

- michal’s 3d raycasting demo for wolfenstein-likes: [3D raycasting in Arcade](https://forum.makecode.com/t/3d-raycasting-in-arcade/474) and associated pr [https://github.com/microsoft/pxt-common-packages/pull/940](https://github.com/microsoft/pxt-common-packages/pull/940) (added blit row)
- maybe get / set rows and mapRect for optimizing dithering? [https://github.com/microsoft/pxt-common-packages/pull/660](https://github.com/microsoft/pxt-common-packages/pull/660)

(Also nice to meet you, I’m Joey!)

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 2, 2020, 9:42pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/4 "2020-06-02T21:42:26Z")

</div>

Oh nice I will check those out, thanks. On device the renderer seems to be pixel-bound. Multiple cubes rotate at a nice clip as long as I zoom way out.

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 3, 2020, 12:27am UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/5 "2020-06-03T00:27:31Z")

</div>

I looked at michal’s 3d raycasting demo, very cool! The `screen.blitRow` has obvious perf benefits. I wasn’t able to easily adopt it because my renderer doesn’t write to an off-screen image. I wonder if doing that would improve performance though. I think I will try that later.

In the meantime, I made a tweak that noticeably improved performance: instead of writing each pixel to the screen individually, I create an Image for the scan line (an n-by-1 image) and write the pixels to that. Then I `drawTransparentImage` to copy the scan line to the screen. Much better performance both in the simulator and on device.

michal’s 3d raycasting demo has much better input handling than my clunky solution. I will be adopting that :).

Updated the demo link above.

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 5, 2020, 12:26am UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/6 "2020-06-05T00:26:29Z")

</div>

Latest code is here for anyone interested: [https://github.com/eanders-ms/pxt-3d](https://github.com/eanders-ms/pxt-3d)

(also, improved dithering:)  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/makecode/original/2X/1/1bf0e0f0c272cf58489970dfa3b61db5530a6890.png)

---

<div class="post-metadata">

**Author:** ![darzu](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/darzu/32/1882_2.png) [@darzu](https://forum.makecode.com/u/darzu)\
**Post date:** [June 6, 2020, 1:36am UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/7 "2020-06-06T01:36:33Z")

</div>

This is awesome!

@eanders, while it’s fresh in your mind, do you have any product feedback on Arcade? Thoughts on how to improve the text language experience?

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 6, 2020, 7:00pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/8 "2020-06-06T19:00:48Z")

</div>

Overall it was a delightful experience. I was surprised at how much I could do with it. Having a debugger was very helpful. There were a few areas I think could use refinement, but overall fantastic:

- Debugger feedback:

- Editor feedback:

- GitHub integration:

That’s all! Excellent work!

---

<div class="post-metadata">

**Author:** ![jwunderl](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/jwunderl/32/5308_2.png) [@jwunderl](https://forum.makecode.com/u/jwunderl)\
**Post date:** [June 6, 2020, 7:46pm UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/9 "2020-06-06T19:46:03Z")

</div>

Ooh great feedback @eanders ! A few of those things have already made their way into beta ([https://arcade.makecode.com/beta](https://arcade.makecode.com/beta)):

- Debugger variables now have hover text, and if you click on them it will expand and let you copy the current value
- We’ve got a new error list that Hristo, an intern on the team, has been working on, to help find syntax errors (and locate runtime errors). I’ll note that we did recently increase the debounce time for error checking so the red squiggles / error list won’t pop up quite as fast at the moment.
- (also if you haven’t used beta yet, you should check out the github integration there - significant changes, including automatically building a gh pages site for you with the test code e.g. [https://jwunderl.github.io/pxt-fireworks/](https://jwunderl.github.io/pxt-fireworks/))

gif w/ both:

 ![beta-monaco-features](https://us1.discourse-cdn.com/flex020/uploads/makecode/original/2X/d/d545ef17474aac0e29dfa7dbdd842ef9525234f5.gif)

Also, re: not being able to see member variables in debugger – that’s fixable with a comment annotation, `//% callInDebugger`, like here: [https://github.com/microsoft/pxt-common-packages/blob/master/libs/game/sprite.ts#L70](https://github.com/microsoft/pxt-common-packages/blob/master/libs/game/sprite.ts#L70) . The reason we need the comment annotation is because any member variable may also be a getter that mutates state, so we can’t safely call them in debug mode without potentially changing the behavior of ‘normal’ mode (I’d say they typically shouldn’t, but ` ¯\_(ツ)_/¯` maybe you wanna lazy load an object). Also relevant beta feature, injecting globals to show up in debugger: [https://github.com/microsoft/pxt/pull/6872](https://github.com/microsoft/pxt/pull/6872) && [https://github.com/microsoft/pxt-microbit/pull/2852/files](https://github.com/microsoft/pxt-microbit/pull/2852/files)

---

<div class="post-metadata">

**Author:** ![eanders](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.makecode.com/eanders/32/3134_2.png) [@eanders](https://forum.makecode.com/u/eanders)\
**Post date:** [June 7, 2020, 12:27am UTC](https://forum.makecode.com/t/3d-renderer-demo/2294/10 "2020-06-07T00:27:19Z")

</div>

Ah yes it was an accessor that I couldn’t expand! That makes sense. I’ll try adding `//% callInDebugger`. Beta debug features look like really nice improvements.
