Jump to content

Create a mini-map


Recommended Posts

Someone would have an idea of how to create a mini-map. I imagine that it must be a different camera in spelling which am the main camera. But how do i do that? Is there a second canvas?


I would like to be able to display in the top right corner, a mini map that takes into account the displacement of the main camera or character that the camera follow.

Thank you for your councils.

Link to comment
Share on other sites

I am not sure to understand the viewport. This lack of example.
And for the DynamicTexture? It could suit if the texture may show what see the camera.
On Unity, for example, I made a mini-map thanks to a DynamicTexture and an orthographic camera.

Link to comment
Share on other sites

In made i used a translator French to English and it happens that the translation is not always correct obviously.

Please excuse my bad english and be lenient. and do not ignore me because of the language barrier. I tried to help here when I can, but not large world does help me unfortunately.

Link to comment
Share on other sites

Try to push the cameras (to the activeCameras array) in the opposite order. It may put your "mini-map" viewport on the main viewport.


EDIT: that was not the solution, the fix has been provided by Deltakosh (http://www.html5gamedevs.com/topic/3295-problem-with-the-multi-views-and-shadows-that-disappears/?p=21414)

Edited by gwenael
Link to comment
Share on other sites

Good, the viewport does not go at all. If you scrool the page, you end up with a large white part. Also, the viewport of my mini card passes behind the ground if i him puts a value higher than the height of the camera 1, which is not suitable if you want the camera 1 is behind the character (RPG) and that the camera 2 is at the top of the character to a height of 80 for example to see a good part of the card.


In short, this is not really adapt to make a mini-map the viewport in are current state. The ideal would be the use of a DynamicTexture, but I am not sure that with babylonjs this is possible.

Link to comment
Share on other sites

It does not work. and the plane does not remain at the top right of the screen when i moves the camera.
Concole error :
TypeError: Not enough arguments to HTMLCanvasElement.getContext.
dynamicTexture = canvas.getContext();

    var MiniMap = BABYLON.Mesh.CreatePlane("SupportMiniMap", 30, scene);        var materialMap = new BABYLON.StandardMaterial("default", scene);    materialMap.backFaceCulling = false;        MiniMap.material = materialMap;        MiniMap.renderingGroupId = 2;            var dynamicTexture = new BABYLON.DynamicTexture("MaterialMiniMap", 512, scene, true);    materialMap.diffuseTexture = dynamicTexture;            scene.beforeRender = function() {        var textureContext = dynamicTexture.getContext();                dynamicTexture.update();            };

I am not sure that I understood. and this lack of explanation in the tutorial.


Documentation :
getContext() → {object}
Get the context of the texture


I don't recover the state of the scene : canvas.getContext();


DynamicTexture allow to show only of the text in texture.


There is no solution I have the impression.

Link to comment
Share on other sites

You have to use getContext("2d")


If you want to render the scene into a texture you have to use a RenderTargetTexture instead of a DynamicTexture. You can create a renderTargetTexture like this:

        var myRenderTarget = new BABYLON.RenderTargetTexture("ref", 512, scene, true);  


then you have to register it with the scene:


Finally you can define what to do before and after rendering to the texture (like moving your camera and restoring it):


        myRenderTarget.onBeforeRender = function() {        };        myRenderTarget.onAfterRender = function() {        };

This texture can then be used by a material like any other texture.

Link to comment
Share on other sites

Thank you for advice. I have a lot to teach of this motor.

I obtain a texture black, I do not know if what I made is correct.

    var myRenderTarget = new BABYLON.RenderTargetTexture("TextureMiniMap", 512, scene, true);      scene.customRenderTargets.push(myRenderTarget);        var MiniMap = BABYLON.Mesh.CreatePlane("SupportMiniMap", 9, scene);    var materialMap = new BABYLON.StandardMaterial("MaterialMiniMap", scene);            materialMap.diffuseTexture = myRenderTarget;    MiniMap.material = materialMap;            myRenderTarget.onBeforeRender = function() {                    };    myRenderTarget.onAfterRender = function() {            };

I think that the viewport props better and is more to adapt to make it, but I had of problems to regulate the height of camera2 which was above the head of of actor. I am going to leave again on a viewport, i had succeeded in having something to compare has now or I acquire nothing that works and or I do not understand much without more study by tutoriel.
There should be more of tutoriel for Babylon, especially when we start with and that we do not have an expert level.

Link to comment
Share on other sites

Glad you found your solution.

May I ask you to post the part of the code that you used to get what you wanted?

I'm not sure that your link won't break someday (if your remove your example from the Internet) so people on this forum would never know how you got what you wanted.


Moreover, I think people are more interested by how you did it than by the result. I may be wrong though.


Do you mind to the set http://www.html5gamedevs.com/topic/3230-create-a-mini-map/?p=20992 as the best answer since finally it's what you used. (the bug that you had here  has been fixed by Deltakosh ()?


Thank you.

Link to comment
Share on other sites

This code, allows you to display a mini-map, to control a character and displays the shadows on the scene.

var canvas = document.getElementById("renderCanvas");var parentCamera;var keys={letft:0,right:0,arriere:0,forward:0};var orbite = false;function createScene() {       var engine = new BABYLON.Engine(canvas, true);    var scene = new BABYLON.Scene(engine);           var LightDirectional = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(-1, -4, -1), scene);        LightDirectional.diffuse = new BABYLON.Color3(1, 1, 1);        LightDirectional.specular = new BABYLON.Color3(0, 0, 0);    LightDirectional.position = new BABYLON.Vector3(250, 400, 0);    LightDirectional.intensity = 1.8;        var rotateCamera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 4.7, Math.PI/2, 30, new BABYLON.Vector3(0, 10, 0), scene);    var camera2 = new BABYLON.FreeCamera("Camera2", new BABYLON.Vector3(0, 0, 0), scene);    camera2.fov = 2;        scene.activeCameras.push(rotateCamera);    scene.activeCameras.push(camera2);    rotateCamera.attachControl(canvas);    scene.activeCamera.__fxaa_cookie = new BABYLON.FxaaPostProcess("fxaa", 1.0, scene.activeCamera);        rotateCamera.viewport = new BABYLON.Viewport(0, 0, 1.0, 1.0);    camera2.viewport = new BABYLON.Viewport(0.85, 0.75, 0.145, 0.24);            var ground = BABYLON.Mesh.CreateGround("terrain", 500, 500, 50, scene, true);    ground.position.y = -0.1;    var matGround = new BABYLON.StandardMaterial("MaterialCamera", scene);    matGround.diffuseTexture = new BABYLON.Texture("terre.png", scene);    matGround.diffuseTexture.uScale = 50.0;    matGround.diffuseTexture.vScale = 50.0;            ground.material = matGround;        var cube = BABYLON.Mesh.CreateBox("Box", 2, scene);    cube.scaling.y = 3;    cube.position.y = 3;    cube.position.z = 0;    var materialCube = new BABYLON.StandardMaterial("default", scene);    materialCube.diffuseColor = new BABYLON.Color3(0.76, 0, 0);        cube.material = materialCube;        camera2.position = new BABYLON.Vector3(cube.position.x, 120, cube.position.z);    camera2.rotation = new BABYLON.Vector3(Math.PI/2, 0, 0);        camera2.parent = cube;        var maison = BABYLON.Mesh.CreateBox("Box", 6, scene);        maison.position.y = 3;    maison.position.z = 100;    var materialCube = new BABYLON.StandardMaterial("default", scene);    materialCube.diffuseColor = new BABYLON.Color3(0.76, 0, 0);        maison.material = materialCube;               var skybox = BABYLON.Mesh.CreateBox("skyBox", 1000, scene);        skybox.infiniteDistance = true;    var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);    skyboxMaterial.backFaceCulling = false;    skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("skybox/skybox", scene);    skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;    skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);    skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);    skybox.material = skyboxMaterial;            var shadowGenerator = new BABYLON.ShadowGenerator(4096, LightDirectional);    shadowGenerator.getShadowMap().renderList.push(cube);    shadowGenerator.getShadowMap().renderList.push(maison);    ground.receiveShadows = true;           engine.runRenderLoop(function () {        scene.render();            if(orbite == false) cube.rotation.y = 4.7 - rotateCamera.alpha;                rotateCamera.target = new BABYLON.Vector3(cube.position.x, 10, cube.position.z);            });        scene.registerBeforeRender(function(){        if (keys.forward==1){            var posX = Math.sin(cube.rotation.y);            var posZ = Math.cos(cube.rotation.y);                        cube.position.x += posX;            cube.position.z += posZ;                    }        if (keys.left==1) cube.rotation.y=cube.rotation.y+0.1;                if (keys.arriere==1){            var posX = Math.sin(cube.rotation.y);            var posZ = Math.cos(cube.rotation.y);                        cube.position.x -= posX;            cube.position.z -= posZ;                    }        if (keys.right==1) cube.rotation.y=cube.rotation.y-0.1;    });        window.oncontextmenu = function () { return false; };        window.addEventListener('mousedown',function(e){        e.preventDefault();        var rightclick;        if (!e) var e = window.event;        if (e.which) rightclick = (e.which == 3);        else if (e.button) rightclick = (e.button == 2);        if(rightclick == true) {            cube.rotation.y = 0;                orbite = true;        }        else if(rightclick == false) {            orbite = false;        }    });    window.addEventListener('mouseup',function(e){        orbite = false;    });        window.addEventListener('keydown',function(event){        var ch = String.fromCharCode(event.keyCode);        if (ch == "Q") keys.left=1;                if (ch == "D") keys.right=1;        if (ch == "S") keys.arriere=1;        if (ch == "Z") keys.forward=1;    });        window.addEventListener('keyup',function(event){        var ch = String.fromCharCode(event.keyCode);        if (ch == "Q") keys.left=0;        if (ch == "D") keys.right=0;        if (ch == "S") keys.arriere=0;        if (ch == "Z") keys.forward=0;    });        window.addEventListener("resize", function () {        engine.resize();    });}

index.html (You must change the image of the part of the mini-map)

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>    <title>BABYLON - Mini-Map</title>    <script src="../hand.js"></script>        <style>        html, body, canvas {            width: 100%;            height: 100%;            padding: 0;            margin: 0;            overflow: hidden;        }    </style></head><body>            <canvas id="renderCanvas"></canvas>            <div style="background:url(Radar_Border.png);background-size:100% 100%;width:14.5%;height:24.2%;right:0.5%; top:0.87%; position:absolute;"></div>    <script src="./../babylon.js"></script>    <script src="Camera.js"></script>    <script>createScene();</script></body></html>
Link to comment
Share on other sites

Please post only 

var rotateCamera = new BABYLON.ArcRotateCamera("ArcRotateCamera", 4.7, 1.57, 30, new BABYLON.Vector3(0, 10, 0), scene);    var camera2 = new BABYLON.FreeCamera("Camera2", new BABYLON.Vector3(0, 0, 0), scene);    camera2.fov = 2;scene.activeCameras.push(rotateCamera);  scene.activeCameras.push(camera2);rotateCamera.attachControl(canvas);    rotateCamera.viewport = new BABYLON.Viewport(0, 0, 1.0, 1.0);camera2.viewport = new BABYLON.Viewport(0.85, 0.75, 0.145, 0.24);

which is the key with

camera2.position = new BABYLON.Vector3(cube.position.x, 120, cube.position.z);camera2.rotation = new BABYLON.Vector3(Math.PI/2, 0, 0);

(I removed camera2.viewport.renderGroupId since this variable doesn't exist on a Viewport in BabylonJS and I applied what Nico suggested here http://www.html5gamedevs.com/topic/3295-problem-with-the-multi-views-and-shadows-that-disappears/?p=21464)

(I also replaced 1.57 by Math.PI/2)


By the way, instead of setting camera2.position and camera2.rotation at each frame, you should parent it to cube.

Link to comment
Share on other sites

I've corrected the code here with everything that you say:

- I removed camera2.viewport.renderGroupId
- camera2.position and camera2.rotation at each frame is removed and camera2.parent = cube; in place.

- rotateCamera.attachControl(canvas) Rather than scene.activeCameras[0]

- Math.PI/2  Rather than 1.57

- And added scene.activeCamera.__fxaa_cookie = new BABYLON.FxaaPostProcess("fxaa", 1.0, scene.activeCamera);


Thanks you

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...