Nicolas Butet


Three.js Lighting Tutorial (JavaScript) | Light Types Explained!

In this project we’re looking at Three.js light types and 3d lighting in JavaScript, exploring the different lighting setups. The goal is to build out a full understanding of the light setups and types, such as ambient, hemisphere, rect, directional, point, and spot lights. We’ll walk through them one by one, going through how they work, how to set them up in code, and some standard uses in big games.

This is part in a series of tutorials on Three.js, aimed at helping beginners understand everything from the ground up. This is a beginners course, aimed at people with no background in the subject. We’ve covered simple setup and basic 3d worlds, and this project should give you a solid understanding of three.js lighting capabilities.

The three.js library is available in JavaScript for cross-browser 3d graphics, wrapping webgl and making high level functionality available in the web browser. It’s an extremely mature and well maintained library that I use for many of these videos.

In the video, we cover:

  • Three.js’s Lighting Types, including examples of usage for each of the major types of lights.
  • AmbientLight, HemisphereLight, RectLight, DirectionalLight, PointLight, SpotLight
  • Common usage of each one in games.
  • How to instantiate and use each in JavaScript.




What is GEEK

Buddha Community

Three.js Lighting Tutorial (JavaScript) | Light Types Explained!

NBB: Ad-hoc CLJS Scripting on Node.js


Not babashka. Node.js babashka!?

Ad-hoc CLJS scripting on Node.js.


Experimental. Please report issues here.

Goals and features

Nbb's main goal is to make it easy to get started with ad hoc CLJS scripting on Node.js.

Additional goals and features are:

  • Fast startup without relying on a custom version of Node.js.
  • Small artifact (current size is around 1.2MB).
  • First class macros.
  • Support building small TUI apps using Reagent.
  • Complement babashka with libraries from the Node.js ecosystem.


Nbb requires Node.js v12 or newer.

How does this tool work?

CLJS code is evaluated through SCI, the same interpreter that powers babashka. Because SCI works with advanced compilation, the bundle size, especially when combined with other dependencies, is smaller than what you get with self-hosted CLJS. That makes startup faster. The trade-off is that execution is less performant and that only a subset of CLJS is available (e.g. no deftype, yet).


Install nbb from NPM:

$ npm install nbb -g

Omit -g for a local install.

Try out an expression:

$ nbb -e '(+ 1 2 3)'

And then install some other NPM libraries to use in the script. E.g.:

$ npm install csv-parse shelljs zx

Create a script which uses the NPM libraries:

(ns script
  (:require ["csv-parse/lib/sync$default" :as csv-parse]
            ["fs" :as fs]
            ["path" :as path]
            ["shelljs$default" :as sh]
            ["term-size$default" :as term-size]
            ["zx$default" :as zx]
            ["zx$fs" :as zxfs]
            [nbb.core :refer [*file*]]))

(prn (path/resolve "."))

(prn (term-size))

(println (count (str (fs/readFileSync *file*))))

(prn (sh/ls "."))

(prn (csv-parse "foo,bar"))

(prn (zxfs/existsSync *file*))

(zx/$ #js ["ls"])

Call the script:

$ nbb script.cljs
#js {:columns 216, :rows 47}
#js ["node_modules" "package-lock.json" "package.json" "script.cljs"]
#js [#js ["foo" "bar"]]
$ ls


Nbb has first class support for macros: you can define them right inside your .cljs file, like you are used to from JVM Clojure. Consider the plet macro to make working with promises more palatable:

(defmacro plet
  [bindings & body]
  (let [binding-pairs (reverse (partition 2 bindings))
        body (cons 'do body)]
    (reduce (fn [body [sym expr]]
              (let [expr (list '.resolve 'js/Promise expr)]
                (list '.then expr (list 'clojure.core/fn (vector sym)

Using this macro we can look async code more like sync code. Consider this puppeteer example:

(-> (.launch puppeteer)
      (.then (fn [browser]
               (-> (.newPage browser)
                   (.then (fn [page]
                            (-> (.goto page "")
                                (.then #(.screenshot page #js{:path "screenshot.png"}))
                                (.catch #(js/console.log %))
                                (.then #(.close browser)))))))))

Using plet this becomes:

(plet [browser (.launch puppeteer)
       page (.newPage browser)
       _ (.goto page "")
       _ (-> (.screenshot page #js{:path "screenshot.png"})
             (.catch #(js/console.log %)))]
      (.close browser))

See the puppeteer example for the full code.

Since v0.0.36, nbb includes promesa which is a library to deal with promises. The above plet macro is similar to promesa.core/let.

Startup time

$ time nbb -e '(+ 1 2 3)'
nbb -e '(+ 1 2 3)'   0.17s  user 0.02s system 109% cpu 0.168 total

The baseline startup time for a script is about 170ms seconds on my laptop. When invoked via npx this adds another 300ms or so, so for faster startup, either use a globally installed nbb or use $(npm bin)/nbb script.cljs to bypass npx.


NPM dependencies

Nbb does not depend on any NPM dependencies. All NPM libraries loaded by a script are resolved relative to that script. When using the Reagent module, React is resolved in the same way as any other NPM library.


To load .cljs files from local paths or dependencies, you can use the --classpath argument. The current dir is added to the classpath automatically. So if there is a file foo/bar.cljs relative to your current dir, then you can load it via (:require [ :as fb]). Note that nbb uses the same naming conventions for namespaces and directories as other Clojure tools: foo-bar in the namespace name becomes foo_bar in the directory name.

To load dependencies from the Clojure ecosystem, you can use the Clojure CLI or babashka to download them and produce a classpath:

$ classpath="$(clojure -A:nbb -Spath -Sdeps '{:aliases {:nbb {:replace-deps {com.github.seancorfield/honeysql {:git/tag "v2.0.0-rc5" :git/sha "01c3a55"}}}}}')"

and then feed it to the --classpath argument:

$ nbb --classpath "$classpath" -e "(require '[honey.sql :as sql]) (sql/format {:select :foo :from :bar :where [:= :baz 2]})"
["SELECT foo FROM bar WHERE baz = ?" 2]

Currently nbb only reads from directories, not jar files, so you are encouraged to use git libs. Support for .jar files will be added later.

Current file

The name of the file that is currently being executed is available via nbb.core/*file* or on the metadata of vars:

(ns foo
  (:require [nbb.core :refer [*file*]]))

(prn *file*) ;; "/private/tmp/foo.cljs"

(defn f [])
(prn (:file (meta #'f))) ;; "/private/tmp/foo.cljs"


Nbb includes reagent.core which will be lazily loaded when required. You can use this together with ink to create a TUI application:

$ npm install ink


(ns ink-demo
  (:require ["ink" :refer [render Text]]
            [reagent.core :as r]))

(defonce state (r/atom 0))

(doseq [n (range 1 11)]
  (js/setTimeout #(swap! state inc) (* n 500)))

(defn hello []
  [:> Text {:color "green"} "Hello, world! " @state])

(render (r/as-element [hello]))


Working with callbacks and promises can become tedious. Since nbb v0.0.36 the promesa.core namespace is included with the let and do! macros. An example:

(ns prom
  (:require [promesa.core :as p]))

(defn sleep [ms]
   (fn [resolve _]
     (js/setTimeout resolve ms))))

(defn do-stuff
   (println "Doing stuff which takes a while")
   (sleep 1000)

(p/let [a (do-stuff)
        b (inc a)
        c (do-stuff)
        d (+ b c)]
  (prn d))
$ nbb prom.cljs
Doing stuff which takes a while
Doing stuff which takes a while

Also see API docs.


Since nbb v0.0.75 applied-science/js-interop is available:

(ns example
  (:require [applied-science.js-interop :as j]))

(def o (j/lit {:a 1 :b 2 :c {:d 1}}))

(prn (j/select-keys o [:a :b])) ;; #js {:a 1, :b 2}
(prn (j/get-in o [:c :d])) ;; 1

Most of this library is supported in nbb, except the following:

  • destructuring using :syms
  • property access using .-x notation. In nbb, you must use keywords.

See the example of what is currently supported.


See the examples directory for small examples.

Also check out these projects built with nbb:


See API documentation.

Migrating to shadow-cljs

See this gist on how to convert an nbb script or project to shadow-cljs.



  • babashka >= 0.4.0
  • Clojure CLI >=
  • Node.js 16.5.0 (lower version may work, but this is the one I used to build)

To build:

  • Clone and cd into this repo
  • bb release

Run bb tasks for more project-related tasks.

Download Details:
Author: borkdude
Download Link: Download The Source Code
Official Website: 
License: EPL-1.0

#node #javascript

Three.js Realistic Lighting Setup Tutorial

Now we’re going to talk about how to setup light and shadow to make our model look realistic.

Basic Scene Setup

So first let’s start downloading a free 3D model on sketchfab. Extract the file and put the content into your web directory.

This is image title

Now this project is going to need to import 3 files. First is three.js core file. The second one is orbitcontrols.js for the camera control. And the last one is GLTFloader.js for loading 3D model.

You can find all of this in three.js master zip file. The orbitcontrol.js is inside the example/js/control folder and GLTFLoader.js is in example/js/loaders.

<script src="three.min.js"></script>
<script src="GLTFLoader.js"></script>
<script src="OrbitControls.js"></script>

And for the basic scene setup, I’ll start with creating a scene object and set the background color to light gray. Then setup a perspective camera with 60 degree FOV with orbitcontrol enabled.

This time I’m going to also add Axeshelper. This will add x-y-z axis to the scene for easier development.

Then setup the WebGL renderer and rendering loop

let scene, camera, renderer, controls;
function init() {

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0xdddddd);

  camera = new THREE.PerspectiveCamera(60,window.innerWidth/window.innerHeight,1,5000);
  controls = new THREE.OrbitControls(camera);

  scene.add( new THREE.AxesHelper(500));

  renderer = new THREE.WebGLRenderer();

function animate() {

You should see Axeshelper on the page now.

This is image title

Then I’m going to load the 3D model using GLTFLoader (also start the render loop after the loading process)

new THREE.GLTFLoader().load('model/scene.gltf', result => { 
  model = result.scene.children[0]; 

You should see the pitched black model in the scene now. Next we’ll work on the light.

This is image title

Light Setup

First I’m going to setup a HemisphereLight which is a light positioned directly above the scene, fading from sky color to the ground color. This is similar to the reflection of the sunlight during the day. I’m going to use a pale orange as a sky color and grey for the ground with 4 intensity.

hemiLight = new THREE.HemisphereLight(0xffeeb1, 0x080820, 4);

This is image title

Now we can see the model. But the color is too saturated and unrealistic. We can fix that by changing the color tone mapping.

For this project I’m going to use a Reinhard tone mapping which has balance HDR amount. But this will make the scene dimmer so I’ll also increase the exposure. You can try other tonemapping types in Three.js for various result.

This is image title

Next I’m going to add a spotlight. This will represent the main source of the light like the sun. I’ll use an orange yellow color with 4 intensity. We’ll need this light to cast shadow so I’ll set the castshadow property to true

light = new THREE.SpotLight(0xffa95c,4);
light.castShadow = true;
scene.add( light );

Then inside the rendering loop, I’ll use the camera position to update the light position with a small offset. This is a trick to simulate the real world dynamic light sources.

function animate() {
    camera.position.x + 10,
    camera.position.y + 10,
    camera.position.z + 10,

This is image title

Now you will notice that the shadow is still invisible. We’ll fix that.

Shadow Setup

First we’ll need to iterate through all mesh in the model and set the castShadow and receiveShadow properties to true. We can do that using traverse method and update the properties if the object is a mesh. And we’ll also increase the texture filtering quality by increasing anisotropy property of the model texture map to 16x.

model.traverse(n => { if ( n.isMesh ) {
  n.castShadow = true; 
  n.receiveShadow = true;
  if( = 16; 

Then we’ll need to enable the shadowmap in our renderer.

renderer.shadowMap.enabled = true;

To prevent shadow artifacts, we’ll decrease shadow bias. This will reduce the shadow sensitivity. Then we’ll increase the shadow resolution by increasing the mapSize to a multiplier of 1024

light.shadow.bias = -0.0001;
light.shadow.mapSize.width = 1024*4;
light.shadow.mapSize.height = 1024*4;

This is image title

Looks goods, and after replaced the background with blurred cubemap texture and removed the Axeshelper, here is the final result!

This is image title

You can download the source code here (No model included)

And that’s the basic of light and shadow setup in the three.js. And if you want to see more web development tips and tutorials, don’t forget to subscribe our channel to stay tune for weekly update 🙂

Originally published by TK at

#js #three.js #javascript

Terry  Tremblay

Terry Tremblay


Now Learn JavaScript Programming Language With Microsoft

icrosoft has released a new series of video tutorials on YouTube for novice programmers to get a hands-on renowned programming language — JavaScript.

This isn’t the first attempt by Microsoft to come up with video tutorials by beginner programmers. The company also has a series of YouTube tutorials on Python for beginners.

For JavaScript, Microsoft has launched a series of 51 videos as ‘Beginner’s Series to JavaScript,’ for young programmers, developers and coders who are interested in building browser applications using JavaScript. These video tutorials will also help programmers and coders to use relevant software development kits (SDKs) and JavaScript frameworks, such as Google’s Angular.

“Learning a new framework or development environment is made even more difficult when you don’t know the programming language,” stated on the Microsoft Developer channel on YouTube. “Fortunately, we’re here to help! We’ve created this series of videos to focus on the core concepts of JavaScript.”

It further stated — while the tutorials don’t cover every aspect of JavaScript, it indeed will help in building a foundation from which one can continue to grow. By the end of this series, Microsoft claims that the novice programmers will be able to work through tutorials, quick starts, books, and other resources, continuing to grow on their own.

#news #javascript #javascript tutorial #javascript tutorials #microsoft tutorials on javascript

sachin jaiswal

sachin jaiswal


Best Tutorial To Become Master In JavaScript Closure - CodesQuery

#javascript #web-development #angular #node-js #reactjs #vue-js #angular-js #react-native #typescript #express #es6 #three-js

CSS Boss

CSS Boss


How to create a calculator using javascript - Pure JS tutorials |Web Tutorials

In this video I will tell you How to create a calculator using javascript very easily.

#how to build a simple calculator in javascript #how to create simple calculator using javascript #javascript calculator tutorial #javascript birthday calculator #calculator using javascript and html