3

I'm developing for movil VR so performances in mandatory here.

It is written in every good practice for VR to avoid unity's skybox and use skydomes instead. I created a dome in blender with its texture and it all.

I import the dome as fbx, apply a Mobile/Unlit shader and the texture image, it looks great.

My problem is that when running the game the dome gets out of the far clipping plane. Options:

  • Set bigger far clipping plane, it leads plenty of stuff I'd like to clip .. not being clipped.
  • Set some kind of two pass render, I did not even try, the overhead sounds awful.
  • Set high far clipping plane, and then setting the culling per layer lower for everything else, that works but leads to resolution problem since the "action" actually happens close to the player.

I did not test but I'm pretty sure for a dome in VR we can go with a single render as background, same for both eyes (since it is in the infinite and should not parallax.


I did as sugested, added a second camera, Clear Flags: Depth only, culling mask only DomeLayer and actually moved the camera to the DomeLayer Main Camera (from googleVR demo scene) is set to Clear Flags: Don't clear, culling mask to Everything but DomeLayer

And it kind of works but

  1. There is a de-synchronization between both cameras. enter image description here Notice the angle of the small first cone (main camera) and the direction of the bigger outer cone (dome camera), btw I cannot set the camera as child of the Left or Right cameras because they don't exists before I start the game.

  2. The overhead when switching second camera on is kind of impressive.. enter image description here I switched off the dome camera, let it run for a while and switch it back on, notice the SetPass and any other metrics. The impact of the second camera is ugly..

I am running in a notebook that has no dedicated graphics card but still, the overhead is there and the thing is meant to run on a mobile device ..

Am I doing something wrong ?

javirs
  • 1,049
  • 26
  • 52
  • 1
    Use a second camera which render only the layer your dome is in, then configure your first camera to not render any skybox. – Ludovic Feltz Mar 21 '17 at 09:51
  • @Ludovic I don't fully get it ... rendering two cameras and them mixing the outcomes (per pixel).. wouldn't that be really bad for mobile VR performance? In general you get instructions to avoid per pixel post processing. Or you mix them in other ways? – javirs Mar 21 '17 at 10:14
  • You do not have to mix it by yourself Unity does it. I often use different camera (in my case one for the UI and the other for anything else) and i do VR too. I think the camera with the dome will only take one drawcall, so it will not be bad for mobile VR – Ludovic Feltz Mar 21 '17 at 10:22
  • Have a look at this article, it may help you: http://blog.theknightsofunity.com/using-multiple-unity-cameras-why-this-may-be-important/ – Ludovic Feltz Mar 21 '17 at 10:26
  • @Ludovic sounds like a really good approach, I'm using google vr for cardboard. Could you please enter in the details on how to user the two cameras and merge the output as an answer? I will gladly select it – javirs Mar 21 '17 at 13:04
  • Does my answer fits your need? – Ludovic Feltz Mar 21 '17 at 20:52

3 Answers3

4

You can accomplish this with some shader tricks and a single camera.

Create a new unlit shader.

Set the RenderQueue of the material to render after geometry. This will reduce overdraw. https://docs.unity3d.com/Manual/SL-SubShaderTags.html

Try

"Queue"="Geometry+1"

Disable depth write (Zwrite Off) - this saves performance, and prevents your skydome from clipping any transparency.

Enable depth test (ZTest LEqual) - this prevents your skysphere from occluding other geometry.

In the vertex shader, you can create the illusion of a skysphere at 'infinity', by fiddling with the near / far clip plane.

Proj Mat [2][2] = -(far+near) / (far - near)
Proj Mat [3][2] = -2*far*near / (far - near)

http://www.terathon.com/gdc07_lengyel.pdf

float4x4 newMat= UNITY_MATRIX_P;
newMat[2][2]= -(1001.0/999.0);
newMat[3][2]= -2*1000.0/999.0;
v.vertex.xyz *= 100;
v.vertex = mul(UNITY_MATRIX_V,v.vertex);
o.vertex = mul(newMat,v.vertex);
birdimus
  • 111
  • 3
2

Add a new Camera for your skyDome and Do Following Steps

  • Make sure camera for skyDome has not the tag mainCamera.
  • make a New layer skyDome.
  • Change layer of this camera to skyDome.
  • Change the skyDome mesh layer to skyDome.
  • Set Clear flag of this camera to Skybox.
  • Set culling mask of this camera to only skyDome layer.
  • Set Clear flag of mainCamera to Depth only.
  • Set culling mask of layer to everything other then skyDome.
Nain
  • 1,204
  • 1
  • 12
  • 17
1

Simply use two camera, the first one will render all your environments and the second one will only render your dome. Simply change what each camera will render with theses following steps:

1) First camera: set tag as MainCamera then parameters clear flags: Don't Clear and Culling Mask: Mixed... (select every layer except the DomeLayer)

2) Create a new layer named DomeLayer

3) Create a second camera as a child of the first camera then set parameters: Clear Flags: Depth Only and Culling Mask: DomeLayer. Also the second camera Depth parameter should be -1

4) Then put your Dome object on the DomeLayer and every other object on any layers except DomeLayer

Here are some screenshot of an example scene:

First camera: enter image description here

Second camera (child of the first camera):

enter image description here

This way you can set the clip plane of your two camera individually without loosing performances.

Ludovic Feltz
  • 11,416
  • 4
  • 47
  • 63
  • I did test something between your idea and Nain 's, please check my edit – javirs Mar 22 '17 at 08:44
  • I guess in point 2 you meant to name the layer as `DomeLayer`, not skyDome, am I right ? – javirs Mar 22 '17 at 08:45
  • Make sure your second camera is not tagged as `MainCamera` and his rotation is `(0,0,0)`. Also i forgot to say that the second camera `Depth` parameter should be -1 – Ludovic Feltz Mar 22 '17 at 08:53