Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

7. November 2017


With the upcoming Godot 3.0 release, there is a pretty major change to the physics system within the engine.  They have decided to replace the in-house physics engine with the open source Bullet physics engine.  Bullet is a well established open source project and has been used in such games as Rocket League, Grand Theft Auto 4 and DiRT as well as powering applications such as Blender and Cinema4D.  This change will not affect 2D physics in the Godot engine.


From the Godot announcement:

Introducing Bullet

Godot always supported an abstract physics interface, so Andrea Catania (Odino) volunteered to add Bullet support as a backend. I initially though it would not be possible to replicate Godot's API in Bullet faithfully, but Andrea proved me wrong and did a fantastic job. He also finished before the Beta deadline, so his work was just merged and will be present in Godot 3.0.

Physics should work just like before, and no code should change, except Bullet is being used internally. Godot's old physics engine is provided for compatibility and can be selected in the project settings, but will likely be removed by the time 3.1 is out.


In an unrelated but similarly timed announcement VR support was also added to Godot in the recently released Alpha 2.  You can read more about VR support here.  I did a hands-on video about both physics and VR in Godot available here or embedded below.

GameDev News ,

11. October 2017


At the annual Oculus Connect developer conference, there have been several announcements on the VR front.  First is a pretty massive price cut to the existing Oculus Rift bundle, the second such price cut, driving the price down to $399 USD.

Summer of Rift had a major impact on the VR industry, and the community’s response showed that the appetite for best-in-class VR hardware and games is stronger than ever. We want to continue getting VR into more people’s hands, so we’re permanently lowering the price of Rift to $399 USD.

Each Rift bundle comes with Touch controllers, sensors, and six free apps that give you hours of entertainment including Epic’s arcade shooter, Robo Recall, and our creative tools, Medium and Quill.

Read more about the price cut here.


In addition to the price cuts, they also announced an all new Oculus device, the Oculus Go.  It is binary compatible with the Gear VR.  Essentially it seems to be a GearVR without the phone requirement and built in speakers.  Available for $199USD, it also comes with a controller and will certainly OcGomake VR more accessible to a wider audience.

Our first standalone product is Oculus Go—the easiest way to jump into VR. It ships early next year, starting at $199 USD. It’s awesome for watching movies or concerts, playing games, or just hanging out with your friends in VR.

This all-in-one device makes VR more accessible than ever and represents a huge leap forward in comfort, visual clarity, and ease-of-use.

The headset is super lightweight, and the new fabric used for the facial interface is soft and breathable.

The high-resolution fast-switch LCD screen dramatically improves visual clarity and reduces screen door effect. And the next-generation lenses are our best ever—offering a wide field of view with significantly reduced glare.

Oculus Go also ships with integrated spatial audio. The speakers are built right into the headset, transporting you straight into VR and making the headset easy to share with someone else. If you need it, there’s also a 3.5mm headphone jack for private listening.

Gear VR and Oculus Go apps are binary compatible, and they share the same controller input set—that means developers building for Gear VR are already building for Oculus Go. As an added plus, the best of our mobile VR content library will be available to everyone on day one.

Oculus Go pushes the envelope of what’s possible at such an accessible price point, and we can’t wait to share more early next year.

Read more about the new device here.


They also announced the open sourcing of the Rift DK2.

Today, we’re excited to announce the open source release of Rift Development Kit 2 (DK2). Our progress since the release of DK1 has been thanks in no small part to this community working tirelessly alongside us. We’re doing this both to preserve and share what we learned about VR in the early days, and to let anyone use the design in their own projects.

The open source release of the DK2 hardware follows on from our earlier releases of Rift DK1 and Latency Tester. This includes schematics, board layout, mechanical CAD, artwork, and specifications under a Creative Commons Attribution 4.0 license, and firmware under BSD+PATENT licences. We present a guided tour of DK2 for those interested in digging in deeper.


All told, a pretty big day for VR.  I’ve long held that the future of VR is a standalone device, untethered from a computer.  Hopefully the new Oculus Go solves many of the GearVR’s thermal issues and has a serviceable battery life.  VR is a great experience, but when its limited to 15 minute intervals, it kind of loses something!


GameDev News

10. October 2017


Like many other techies, after reading Neuromancer or Snow Crash the idea of a 3D internet has been a distant dream.  There have been attempts certainly, like VRML 1 and 2 for example, or the online MMO Second Life, but none of really come close.  These days however a number of technologies are converging that might actually make it possible.  Fast computers, fast internet connections, WebGL in the browser and perhaps most importantly the rise of consumer level VR headsets.  All of these technologies combine to make the 3D web a possibility and A-Frame brings them all together.  A-Frame was founded by Mozilla, is an open source project that builds a VR framework over top of the popular open source Three.js engine.  You develop your game works using a HTML5 style markup working with a familiar entity/component model.


Here is a simple A-Frame application.

<!DOCTYPE html>
<html>
<head>
    <title>Hello, WebVR! - A-Frame</title>
    <meta name="description" content="Hello, WebVR! - A-Frame">
    <script src="https://aframe.io/releases/0.6.0/aframe.min.js"></script>
</head>
<body>
<a-scene fog="type: linear; color: #AAA">
    <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
    <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
    <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
    <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
    <a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>


Run this in browser and you will see:

image


Run it in a browser using a VR headset and you will have full 3D head tracking.  Even cooler, hit Ctrl + Alt + I and you get access to the inspector:

image


Giving you full access over the entities making up your scene, the components attached to them and even give you the ability to create completely new ones.  If you are interested in learning more be sure to check out the video below.

Programming ,

10. January 2017

 

Carmel is a new WebVR browser available for the Oculus Gear VR in preview form.  WebVR is an attempt to bring Virtual Reality to the web browser, while Carmel is their mobile browser supporting it.  You can learn more about the VR web here. In a nutshell, WebVR is going to enable you to write VR experiences in a similar experience to creating dynamic web pages today.  To help with that, Oculus have released the Carmel VR Starter Kit.  It’s a set of samples and examples to get you up and running in WebVR for the Carmel browser. 

 

You can download the starter kit on Github and getting started is easy assuming you have Node.js installed.

Running Samples

First, run npm install to get the npm dependencies used for hosting the samples locally.

Run npm start to start a local http server on port 8000.

You can navigate to, http://:8000/index.html, to access the samples on a Gear VR enabled mobile device.

The top category of links will launch each sample into the Carmel Technical Preview.

The bottom category of links can be used to launch each sample directly in your browser if the sample supports rendering monoscopically.

 

Here is a look at the Hello World example’s code:

<!DOCTYPE html>
<!--
  Copyright 2016-present, Oculus VR, LLC.
  All rights reserved.

  This source code is licensed under the license found in the
  LICENSE-examples file in the root directory of this source tree.
-->
<html>
  <head>
    <title>Hello WebVR</title>
    <style>
      body {
        margin: 0;
      }
      canvas {
        position: absolute;
        width: 100%;
        height: 100%;
      }
      #messages {
        position: absolute;
        color: white;
        width: 100%;
        height: 100%;
      }
    </style>
    <script>
      var vrDisplay;      // The VRDisplay we will present to, discovered from 
      getVRDisplays
      var frameData;      // HMD information, populated each frame by 
      getFrameData
      var layerSource;    // The source of the VRLayer passed to requestPresent, 
      our canvas element.

      var gl;             // The webgl context of the canvas element, used to 
      render the scene
      var quadProgram;    // The WebGLProgram we will create, a simple quad 
      rendering program
      var attribs;        // A map of shader attributes to their location in the 
      program
      var uniforms;       // A map of shader uniforms to their location in the 
      program
      var vertBuffer;     // Vertex buffer used for rendering the scene
      var texture;        // The texture that will be bound to the diffuse 
      sampler
      var quadModelMat;   // The quad's model matrix which we will animate

      // This is the entrypoint to this sample and where we attempt to begin VR 
      presentation
      function requestPresent() {
        // First, initialize our WebGL program for rendering a simple quad
        initWebGLProgram();

        // Next, we will get the first VRDisplay that is available and try to 
        requestPresent.
        // If VR is unavailable or we aren't able to present, we will simply 
        display an HTML message in the page.
        if (navigator.getVRDisplays) {
          navigator.getVRDisplays().then(function (displays) {
            if (displays.length > 0) {
              // We reuse this every frame to avoid generating garbage
              frameData = new VRFrameData();

              vrDisplay = displays[0];

              // We must adjust the canvas (our VRLayer source) to match the 
              VRDisplay
              var leftEye = vrDisplay.getEyeParameters("left");
              var rightEye = vrDisplay.getEyeParameters("right");

              // This layer source is a canvas so we will update its width and 
              height based on the eye parameters.
              // For simplicity we will render each eye at the same resolution
              layerSource.width = Math.max(leftEye.renderWidth, rightEye.
              renderWidth) * 2;
              layerSource.height = Math.max(leftEye.renderHeight, rightEye.
              renderHeight);

              // This can normally only be called in response to a user gesture.
              // In Carmel, we can begin presenting the VR scene right away.
              vrDisplay.requestPresent([{ source: layerSource }]).then(function (
              ) {
                // Start our render loop, which is synchronized with the 
                VRDisplay refresh rate
                vrDisplay.requestAnimationFrame(onAnimationFrame);
              }).catch(function (err) {
                // The Carmel Developer preview allows entry into VR at any time 
                because it is a VR first experience.
                // Other browsers will only allow this to succeed if called in 
                response to user interaction, such as a click or tap though.
                // We expect this to fail outside of Carmel and would present 
                the user with an "Enter VR" button of some sort instead.
                addHTMLMessage("Failed to requestPresent.");
              });
            } else {
              // Usually you would want to hook the vrdisplayconnect event and 
              only try to request present then.
              addHTMLMessage("There are no VR displays connected.");
            }
          }).catch(function (err) {
            addHTMLMessage("VR Displays are not accessible in this context.  
            Perhaps you are in an iframe without the allowvr attribute specified.
            ");
          });
        } else {
          addHTMLMessage("WebVR is not supported on this browser.");
          addHTMLMessage("To support progressive enhancement your fallback code 
          should render a normal Canvas based WebGL experience for the user.");
        }
      }

      // Once we are presenting this will get called any time a new frame should 
      be rendered on the VRDisplay
      // The timestamp passed to our callback is the current DOMHighResTimeStamp 
      at the start of the frame.
      // We can use the timestamp to update our scene and perform animations in 
      a framerate independent way.
      function onAnimationFrame(timestamp) {
        // Continue to request frames to keep the render loop going
        vrDisplay.requestAnimationFrame(onAnimationFrame);

        // Clear the layer source - we do this outside of render to avoid 
        clearing twice
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        // Update the scene once per frame
        update(timestamp);

        // Get the current pose data
        vrDisplay.getFrameData(frameData);

        // Render the left eye
        gl.viewport(0, 0, layerSource.width * 0.5, layerSource.height);
        render(frameData.leftProjectionMatrix, frameData.leftViewMatrix);

        // Render the right eye
        gl.viewport(layerSource.width * 0.5, 0, layerSource.width * 0.5, 
        layerSource.height);
        render(frameData.rightProjectionMatrix, frameData.rightViewMatrix);

        // Submit the newly rendered layer to be presented by the VRDisplay
        vrDisplay.submitFrame();
      }

      function update(timestamp) {
        // Animate the z location of the quad based on the current frame 
        timestamp
        var oscillationSpeed =  Math.PI / 2;
        var z = -1 + Math.cos(oscillationSpeed * timestamp / 1000);
        quadModelMat[14] = z
      }

      // For VR, it's important that your render method is parameterized by the 
      camera
      // (projection and view matrices) so that it can be used to render from 
      each
      // eye's perspective
      function render(projectionMat, viewMat) {
        gl.useProgram(quadProgram);

        // The view and projection uniforms are passed in and are different for 
        the left eye and right eye
        gl.uniformMatrix4fv(uniforms.projectionMat, false, projectionMat);
        gl.uniformMatrix4fv(uniforms.viewMat, false, viewMat);

        // The remainder of our rendering is the same for both eyes now that 
        view and projection have been set up.
        gl.uniformMatrix4fv(uniforms.modelMat, false, quadModelMat);

        gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);

        gl.enableVertexAttribArray(attribs.position);
        gl.enableVertexAttribArray(attribs.texCoord);

        gl.vertexAttribPointer(attribs.position, 3, gl.FLOAT, false, 20, 0);
        gl.vertexAttribPointer(attribs.texCoord, 2, gl.FLOAT, false, 20, 12);

        gl.activeTexture(gl.TEXTURE0);
        gl.uniform1i(uniforms.diffuse, 0);
        gl.bindTexture(gl.TEXTURE_2D, texture);

        gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
      }

      function initWebGLProgram() {
        layerSource =  document.getElementById("webgl-canvas");

        var glAttribs = {
          alpha: false,                   // The canvas will not contain an 
          alpha channel
          antialias: true,                // We want the canvas to perform anti-
          aliasing
          preserveDrawingBuffer: false    // We don't want our drawing to be 
          retained between frames, we will fully rerender each frame.
        };

        // You should also check for "experimental-webgl" when implementing 
        support for canvas based WebGL fallback when VR is not available.
        gl = layerSource.getContext("webgl", glAttribs);

        var quadVS = [
          "uniform mat4 projectionMat;",
          "uniform mat4 viewMat;",
          "uniform mat4 modelMat;",
          "attribute vec3 position;",
          "attribute vec2 texCoord;",
          "varying vec2 vTexCoord;",

          "void main() {",
          "  vTexCoord = texCoord;",
          "  gl_Position = projectionMat * viewMat * modelMat * vec4(position, 1.
          0);",
          "}",
        ].join("\n");

        var quadFS = [
          "precision mediump float;",
          "uniform sampler2D diffuse;",
          "varying vec2 vTexCoord;",

          "void main() {",
          "  gl_FragColor = texture2D(diffuse, vTexCoord);",
          "}",
        ].join("\n");

        quadProgram = gl.createProgram();

        var vertexShader = gl.createShader(gl.VERTEX_SHADER);
        gl.attachShader(quadProgram, vertexShader);
        gl.shaderSource(vertexShader, quadVS);
        gl.compileShader(vertexShader);

        var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.attachShader(quadProgram, fragmentShader);
        gl.shaderSource(fragmentShader, quadFS);
        gl.compileShader(fragmentShader);

        attribs = {
          position: 0,
          texCoord: 1
        };

        gl.bindAttribLocation(quadProgram, attribs.position, "position");
        gl.bindAttribLocation(quadProgram, attribs.texCoord, "texCoord");

        gl.linkProgram(quadProgram);

        uniforms = {
          projectionMat: gl.getUniformLocation(quadProgram, "projectionMat"),
          modelMat: gl.getUniformLocation(quadProgram, "modelMat"),
          viewMat: gl.getUniformLocation(quadProgram, "viewMat"),
          diffuse: gl.getUniformLocation(quadProgram, "diffuse")
        };

        var size = 0.2;
        var quadVerts = [];

        var x = 0;
        var y = 0;
        var z = -1;
        quadVerts.push(x - size, y - size, z + size, 0.0, 1.0);
        quadVerts.push(x + size, y - size, z + size, 1.0, 1.0);
        quadVerts.push(x + size, y + size, z + size, 1.0, 0.0);
        quadVerts.push(x - size, y + size, z + size, 0.0, 0.0);

        vertBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(quadVerts), gl.
        STATIC_DRAW);

        quadModelMat = new Float32Array([
          1, 0, 0, 0,
          0, 1, 0, 0,
          0, 0, 1, 0,
          0, 0, 0, 1
        ]);

        texture = gl.createTexture();

        var image = new Image();

        // When the image is loaded, we will copy it to the GL texture
        image.addEventListener("load", function() {
          gl.bindTexture(gl.TEXTURE_2D, texture);
          gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, 
          image);

          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
          gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.
          LINEAR_MIPMAP_NEAREST);

          // To avoid bad aliasing artifacts we will generate mip maps to use 
          when rendering this texture at various distances
          gl.generateMipmap(gl.TEXTURE_2D);
        }, false);

        // Start loading the image
        image.src = "../assets/cube-sea.png";
      }

      function addHTMLMessage(msgText) {
        var message = document.createElement("div");
        message.innerHTML = msgText;
        document.getElementById("messages").appendChild(message);
      }
    </script>
  </head>
  <body onload="requestPresent()">
    <canvas id="webgl-canvas"></canvas>
    <div id="messages"></div>
  </body>
</html>

News

10. October 2016

 

Bullet is a popular open source C++ based 3D physics engine available on Github under the zlib permissive license, a very liberal open source license.  They just released version 2.84.   This release brings a few new features:

  • pybullet -- python bindings
  • VR support for the HTC Vive
  • VR support for the Oculus Rift
  • support for Inverse Kinematics

 

The following video demonstrates the new python bindings in action, using inverse kinematics and running on an HTC Vive.

GameDev News

Month List

Popular Comments