Author Topic: Panorama exporter with Google Cardboard  (Read 12386 times)

2015-09-11, 06:43:54

Alex Abarca

  • Active Users
  • **
  • Posts: 364
  • Corona Certified Instructor
    • View Profile
    • www.alexabarcaviz.wordpress.com
Hi development team,

Is is possible to write code so that panorama exporter is viewable in google cardboard IOS?

Or make a viewer?



2015-09-11, 14:33:20
Reply #2

arqrenderz

  • Active Users
  • **
  • Posts: 736
  • arqrenderz.com
    • View Profile
    • arqrenderz

2015-09-11, 15:54:16
Reply #3

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
I can see there is a lot of interest in VR and augmented reality recently (I mean not in Corona community, but generally in the CG world). I even bought myself a simple version of Cardboard (for ~4€). :) These are some really promising technologies.

2015-09-11, 16:35:29
Reply #4

romullus

  • Global Moderator
  • Active Users
  • ****
  • Posts: 6581
  • Let's move this topic, shall we?
    • View Profile
    • My Models
Would like to play with cardboard, but my phone hasn't gyro :[
I'm not Corona Team member. Everything i say, is my personal opinion only.
My Models | My Videos | My Pictures

2015-09-11, 19:24:47
Reply #5

Alex Abarca

  • Active Users
  • **
  • Posts: 364
  • Corona Certified Instructor
    • View Profile
    • www.alexabarcaviz.wordpress.com
Staring at renderings is cool, but panos are way better. am doing 10k pixel panos with cardboard.

2015-09-11, 19:45:15
Reply #6

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
You can also cross your eyes if you have enough skill and see the cardboard stuff without cardboard. ;)

2015-09-11, 23:53:50
Reply #7

Alex Abarca

  • Active Users
  • **
  • Posts: 364
  • Corona Certified Instructor
    • View Profile
    • www.alexabarcaviz.wordpress.com

2015-09-12, 13:57:08
Reply #8

rambambulli

  • Active Users
  • **
  • Posts: 160
    • View Profile
I don't know what is worse no gyro or an iPhone in The Netherlands. iTunes (my least favorite software ever) doens't support google cardboard in The Netherlands. I think they all imagined the Dutch have cross eyes by birth ;(

Alex do you want to have a script or do you want to know how to make a google cardboard photosphere?
Btw for animation or for stills or both?

Maybe you already know this but here is a nice tutorial:
http://elevr.com/cg-vr-1/
the next turorial is for Maya but can used in 3ds max and corona. Just link 2 cameras. 
http://elevr.com/cg-vr-2/

2015-09-12, 17:12:23
Reply #9

Jpjapers

  • Active Users
  • **
  • Posts: 1350
    • View Profile
Max's built in panorama exporter works great and it works on the google cardboard. All you need to do is render out 2 panoramas from 2 cameras on a rig of 2 cameras. i tried this out back in v0.7 and it worked then perfectly, i cant see why it wouldnt work now.

EDIT: My bad i now realise you want full stereo. Perhaps someone could so something similar to max's wraparound lens shader only with the pivot offset.
« Last Edit: 2015-09-12, 17:47:05 by jpjapers »

2015-09-12, 22:19:21
Reply #10

Alex Abarca

  • Active Users
  • **
  • Posts: 364
  • Corona Certified Instructor
    • View Profile
    • www.alexabarcaviz.wordpress.com
Rambambulli, the iphone is worst piece of crap ever. I chose it to give it a chance and to try to be cool. It limits you everywhere and it doesn't even have a foking back button. The VR Gallery app on android lets you browse your pictures on the phone (technically you can get your pano done by Corona render. But the dumb iphone can do that with the same app. WTH



Jpjapers, Corona Render exports panoramas quite well not complaints there. When something is well done there always more to be desired...a compliment!


I was just thinking of added functionality to dead clowns script that pushes the pano to Internet explorer. I thought that was genius! because usually our clients are not app savy and everyone in the world has IE, so kudos to deadclown on that.

Can the the pano be delivered with a VR cardboard player too. Something that enables to package your projects?

2015-09-14, 15:20:44
Reply #11

Jpjapers

  • Active Users
  • **
  • Posts: 1350
    • View Profile
Oh right i see. I completely forgot about deadclowns script. So you want something people can view on mobile in the cardboard but that doesnt rely on an app etc? Im pretty sure chrome users have overtaken IE users quite drastically and im sure theres plenty of chromeVR utilities for this purpose?
« Last Edit: 2015-09-14, 15:24:14 by jpjapers »

2015-09-16, 17:17:00
Reply #12

rfletchr

  • Active Users
  • **
  • Posts: 41
    • View Profile
Max's built in panorama exporter works great and it works on the google cardboard. All you need to do is render out 2 panoramas from 2 cameras on a rig of 2 cameras. i tried this out back in v0.7 and it worked then perfectly, i cant see why it wouldnt work now.

EDIT: My bad i now realise you want full stereo. Perhaps someone could so something similar to max's wraparound lens shader only with the pivot offset.

You dont need that tool at all, Corona has a modifier for the camera that lets you render panoramas really easily.
https://coronarenderer.freshdesk.com/support/solutions/articles/5000515644-how-to-make-panoramic-renders-in-corona-

2015-11-25, 21:37:10
Reply #13

rambambulli

  • Active Users
  • **
  • Posts: 160
    • View Profile
@Alex. Are you still looking for a web based vr viewer for a cardboad viewer?

I wrote a simple Three.js script that runs on all WebGL gyro phones I tried so far. I am no javascript expert so the script needs some tweaking and improving but it works fine for me. Especially because everybody (with a phone) can watch and use it. You don't have to download some app.

For the panoramas I use the same spherical corona panorama for the left as well as for the right eye. The code can be simply altered to display a slightly different panorama for the left and the right eye. 8 out of 10 people can see some depth with this setup. So right now it works fine for me.
To improve the setup I need some time to figure out how to create a "2 eye off axis spherical lens rig" in corona (like in this tutorial http://elevr.com/cg-vr-1/). Or someone smart can help me out here :)

If anyone has some good ideas to improve this please do!
the html/javascript code:

Code: [Select]
<!DOCTYPE html>
<html lang="en">
<head>

<title>Web Vr Panorama Viewer | Three.js</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1">

<!-- Background turns red is Moble phone is not WebGL ready -->

<style TYPE="text/css">
body {

margin: 0px;
background-color: #F00000;
overflow: hidden;
}


</style>
</head>
<body>

<div id="container"></div>

<!-- libraries can be downloaded from the three.js website: http://cdnjs.com/libraries/three.js/ -->

<script src="js/three.min.js"></script>
<script src="js/DeviceOrientationControls.js"></script>
<script src="js/StereoEffect.js"></script>

<script>

(function() {

  "use strict";

  window.addEventListener('load', function() {

var container, camera, scene, rendererLeft, rendererRight, controls, geometry, mesh;
var animate = function(){

window.requestAnimationFrame( animate );

controls.update();
rendererLeft.render(scene, camera);
rendererRight.render(scene, camera);

};

container = document.getElementById( 'container' );

camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 700);
camera.aspect = (window.innerWidth/2) / window.innerHeight;
camera.updateProjectionMatrix();

controls = new THREE.DeviceOrientationControls( camera );

scene = new THREE.Scene();

var geometry = new THREE.SphereGeometry( 500, 32, 32 );
geometry.scale( - 1, 1, 1 );

// change image to your own
var material = new THREE.MeshBasicMaterial( {
map: THREE.ImageUtils.loadTexture( 'img/Corona_Panorama.jpg' )
} );

var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

//left eye
rendererLeft = new THREE.WebGLRenderer();
rendererLeft.setPixelRatio( window.devicePixelRatio);
rendererLeft.setSize(window.innerWidth/2, window.innerHeight);
rendererLeft.domElement.style.top = 0;
container.appendChild(rendererLeft.domElement);

//right eye
rendererRight = new THREE.WebGLRenderer();
rendererRight.setPixelRatio( window.devicePixelRatio);
rendererRight.setSize(window.innerWidth/2, window.innerHeight);
rendererRight.domElement.style.top = 0;
container.appendChild(rendererRight.domElement);

window.addEventListener('resize', function() {

camera.aspect = (window.innerWidth/2) / window.innerHeight;
camera.updateProjectionMatrix();
rendererLeft.setSize((window.innerWidth/2), window.innerHeight );
rendererRight.setSize((window.innerWidth/2), window.innerHeight );

}, false);

animate();

  }, false);

})();

</script>
</body>
</html>


 

2015-11-26, 12:53:47
Reply #14

johan belmans

  • Primary Certified Instructor
  • Active Users
  • ***
  • Posts: 728
    • View Profile
    • belly.be

2015-11-26, 22:33:24
Reply #15

arqrenderz

  • Active Users
  • **
  • Posts: 736
  • arqrenderz.com
    • View Profile
    • arqrenderz
+1 for a stereo camera rig for corona!!!!

2015-11-27, 14:36:04
Reply #16

peterguthrie

  • Active Users
  • **
  • Posts: 241
    • View Profile
    • Peter Guthrie Visualisation
+1 here too!

and thanks for the interesting links rambambulli

2015-11-29, 20:58:02
Reply #17

rambambulli

  • Active Users
  • **
  • Posts: 160
    • View Profile
I don't know how complicated it is to write the Corona Sperical Stereo Rig but I can imagine that there are more urgent issues for the Corona team to work on first :D

So in the meantime I will try to create one. For who is interested, here is my research on this topic. Feel free to comment. I'm new to this so it only can get better.

My first tests are based on the EleVR blog mentioned above and the http://paulbourke.net/stereographics/stereopanoramic/ site.
The Domemaster camera (explained in the EleVr blog part 2) is not working with Corona or I don't understand how to use it. It uses lens shaders I as far as I know they aren't available for Corona.

So I started from scratch using this workflow:
- create a rig made from 2 cameras revolving around a center point. Both cameras a bit (30mm) off to the left and the right to mimic the eyes positions.
I added my simple max file. The rig has as many frames as the renderwidth of the image/strip width. So a image of 2400p pixels has 2400 frames if the strip is 1 pixel wide. 1200 pixels if the strip is 2 pixels wide. etc.
See the rig example image.

- I use the corona spherical lens and slice it in very narrow parts. So if my image is 2400x1200. I render strips of 1x1200 pixels.
(Maybe it is better to render a FOV 180 degrees camera but I get a really strange results.)

- I use a focus point to which both cameras of the rig look. The rig setup is almost similar and easy for parallel.
The third "Off Axis" is a bit more complicated. To produce a correct camera you should use a horizontal tilt shift lens. You can use the Vray camera. Calculate the horizontal tilt and render them. But if I add the coronacameramod to create a spherical image it neutrilizes the tilt shift of the Vray camera. Not solved yet.

- To make it work you should render X thin images and combine them into one big image for each eye/camera. To do this I wrote a few simple lines of maxscript code.
 
Code: [Select]

-- change so the output width of a image divided by the stripwidth makes a whole number
stripwidth = 1
 
-- the left eye image
PanLeft = bitmap renderwidth renderheight
-- the right eye image
PanRight = bitmap renderwidth renderheight
 
--set a region to render a crop
viewport.setRegionRect 1 (Box2 (renderwidth/2) 0 stripwidth renderheight)
 
parts = renderwidth/stripwidth
-- for testing parts = 100  or whatever you like

- for the left eye
 
for t = 0 to parts do (
display panLeft
--make sure the left eye camera is cold cameraL. Or change the name here
viewport.setCamera $cameraL
strip = render rendertype:#crop vfb:false frame:t 
    pastebitmap strip panLeft [0,0] [(t*stripwidth),0]
)
 
-- and for the right eye
 
for t = 0 to parts do (
display panRight
--make sure the left eye camera is cold cameraL. Or change the name here
viewport.setCamera $cameraR
strip = render rendertype:#crop vfb:false frame:t c  pastebitmap strip panRight [0,0] [(t*stripwidth),0]



So far so good. To show you what happend I made a good old red-cyan overlay image. If you have some old school glasses you can check them. It works. (sorry for the extreme dull test image btw)

To remove horizontal lines in low pass renders correct turn off "Lock sampling pattern" in the Corona Render menu. If you leave this option on Corona will render each strip the same way. This results in fine horizontal lines on your images.
 
At the end there is a anti aliasing problem. All strips are stitched together without aliasing. So you get jagged edges. Not solved yet.

So as a conclusion. It works. It is a bit slow. The "off axis" method doesn't work yet. Anti aliasing is a must and doens't work yet.
I will create a script that makes the rig and starts te rendering automaticaly and update the earlier posted javascript so it can be used with 2 images.


« Last Edit: 2015-11-29, 21:13:43 by rambambulli »

2015-12-13, 11:14:55
Reply #18

peterguthrie

  • Active Users
  • **
  • Posts: 241
    • View Profile
    • Peter Guthrie Visualisation
thanks for your work rambambulli

can anyone from the corona team help with the bits that dont work?

2015-12-14, 13:35:37
Reply #19

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
I am trying to get some results with the script. The idea seems to be good. Here is the updated version, I think the code got messed due to copypasting:

Code: [Select]
-- change so the output width of a image divided by the stripwidth makes a whole number
stripwidth = 1
 
-- the left eye image
PanLeft = bitmap renderwidth renderheight
-- the right eye image
PanRight = bitmap renderwidth renderheight
 
--set a region to render a crop
viewport.setRegionRect 1 (Box2 (renderwidth/2) 0 stripwidth renderheight)
 
parts = renderwidth/stripwidth
-- for testing parts = 100  or whatever you like

-- for the left eye
 
for t = 0 to parts do (
display panLeft
--make sure the left eye camera is cold cameraL. Or change the name here
viewport.setCamera $cameraL
strip = render rendertype:#crop vfb:false frame:t 
    pastebitmap strip panLeft [0,0] [(t*stripwidth),0]
)
 
-- and for the right eye
 
for t = 0 to parts do (
display panRight
--make sure the left eye camera is cold cameraL. Or change the name here
viewport.setCamera $cameraR
strip = render rendertype:#crop vfb:false frame:t 
pastebitmap strip panRight [0,0] [(t*stripwidth),0]



2015-12-14, 17:17:43
Reply #20

rambambulli

  • Active Users
  • **
  • Posts: 160
    • View Profile
Oops. Sloppy me. Sorry guys. Thanks Maru.

BTW more errors. At the CameraR comment it should say --make sure the Right eye camera is called cameraR.
A lot of late night testing/copying/pasting :D

2015-12-16, 11:48:51
Reply #21

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
Ok, this officially works. I was able to use it with krpano on my phone + google cardboard. I will be soon back with a full guide. Also, there is a chance that *soon* there will be a built in-option in Corona. ;)

2015-12-16, 13:16:24
Reply #22

arqrenderz

  • Active Users
  • **
  • Posts: 736
  • arqrenderz.com
    • View Profile
    • arqrenderz
So exited to start use it!! :) alredy made some panos for cardboard, I just have to close one eye to see them :P

2015-12-16, 13:44:45
Reply #23

peterguthrie

  • Active Users
  • **
  • Posts: 241
    • View Profile
    • Peter Guthrie Visualisation
Ok, this officially works. I was able to use it with krpano on my phone + google cardboard. I will be soon back with a full guide. Also, there is a chance that *soon* there will be a built in-option in Corona. ;)

great stuff maru, and an official method would be awesome too

2015-12-16, 17:14:47
Reply #24

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
I have just finished upgrading the script as it looked like it's having problems in some scenarios. I have completely 0 scripting knowledge, so it took me a while, but the satisfaction was worth it. :)
I should finish the guide today or tomorrow (the unofficial one).

2015-12-16, 17:17:56
Reply #25

rambambulli

  • Active Users
  • **
  • Posts: 160
    • View Profile
Of course all this is really for the time being and we patiently wait for the official version.

Until then for who is interested I copy/pasted a web based viewer for webgl-gyro-phones. It can view different images for the left and the right eye.
@Maru, I hope it is error free this time :D
I checked it on a iphone 5 with safari and chrome. Both browsers work fine.

Code: [Select]
<!DOCTYPE html>
<html lang="en">
<head>
<title>Stereo Viewer Corona-Cardboard</title>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1">
<style TYPE="text/css">
body {
margin: 0px;
background-color: #000000;
overflow: hidden;
}


</style>
</head>
<body>

<div id="container"></div>

<script src="js/three.min.js"></script>
<script src="js/DeviceOrientationControls.js"></script>
<script src="js/StereoEffect.js"></script>

<script>
(function() {
  "use strict";

  window.addEventListener('load', function() {

var container
var camera1, scene1, renderer1, controls1, geometry1, mesh1;
var camera2, scene2, renderer2, controls2, geomerty2, mesh2;


var animate = function(){

window.requestAnimationFrame( animate );

controls1.update();
controls2.update();
renderer1.render(scene1, camera1);
renderer2.render(scene2, camera2);

};

container = document.getElementById( 'container' );

camera1 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 700);
camera1.aspect = (window.innerWidth/2) / window.innerHeight;
camera1.updateProjectionMatrix();

camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.001, 700);
camera2.aspect = (window.innerWidth/2) / window.innerHeight;
camera2.updateProjectionMatrix();

controls1 = new THREE.DeviceOrientationControls( camera1 );

controls2 = new THREE.DeviceOrientationControls( camera2 );

scene1 = new THREE.Scene();

scene2 = new THREE.Scene();

var geometry1 = new THREE.SphereGeometry( 500, 32, 32 );
geometry1.scale( - 1, 1, 1 );

var geometry2 = new THREE.SphereGeometry( 500, 32, 32 );
geometry2.scale( - 1, 1, 1 );

var material1 = new THREE.MeshBasicMaterial( {
map: THREE.ImageUtils.loadTexture( 'img/YOUR_LEFT_IMAGE.jpg' )
} );

var material2 = new THREE.MeshBasicMaterial( {
map: THREE.ImageUtils.loadTexture( 'img/YOUR_RIGHT_IMAGE.jpg' )
} );

var mesh1 = new THREE.Mesh( geometry1, material1 );
scene1.add( mesh1 );

var mesh2 = new THREE.Mesh( geometry2, material2 );
scene2.add( mesh2 );


renderer1 = new THREE.WebGLRenderer();
renderer1.setPixelRatio( window.devicePixelRatio);
renderer1.setClearColor( 0xffffff );
renderer1.setSize(window.innerWidth/2, window.innerHeight);
renderer1.domElement.style.top = 0;
container.appendChild(renderer1.domElement);

renderer2 = new THREE.WebGLRenderer();
renderer2.setPixelRatio( window.devicePixelRatio);
renderer2.setSize(window.innerWidth/2, window.innerHeight);
renderer2.domElement.style.top = 0;
container.appendChild(renderer2.domElement);


window.addEventListener('resize', function() {

camera1.aspect = (window.innerWidth/2) / window.innerHeight;
camera1.updateProjectionMatrix();

camera2.aspect = (window.innerWidth/2) / window.innerHeight;
camera2.updateProjectionMatrix();

renderer1.setSize((window.innerWidth/2), window.innerHeight );
renderer2.setSize((window.innerWidth/2), window.innerHeight );

}, false);

animate();

  }, false);

})();
</script>

</body>
</html>

2015-12-17, 13:24:03
Reply #26

maru

  • Corona Team
  • Active Users
  • ****
  • Posts: 9978
  • Marcin
    • View Profile
Here is my guide:
https://corona-renderer.com/forum/index.php/topic,10592.msg67619.html#msg67619
If someone has time to test it, it would be appreciated. Let me know if I made some mistake in it, or if something doesn't work. This is the "unofficial" way. VR support should be soon in Corona.