Light Probe Proxy Volume: 5.4 Feature Showcase

February 3, 2016 in Tecnologia

Unity 5.4 has entered beta and a stand out feature is the Light Probe Proxy Volume (LPPV). I just wanted to share with you all what it is, the workflow and some small experiments to show it in action.

Correct as of 30.01.2016 – Subject to changes during 5.4 beta.

What Is A Light Probe Proxy Volume?

The LPPV is a component which allows for more light information to be used on larger dynamic objects that cannot use baked lightmaps, think Skinned Meshes or Particle Systems. Yes! Particle Systems receiving Baked Light information, awesome!

How To Use The LPPV Component?

The LPPV component requires an exisiting Light Probe Group. The component is located under Component -> Rendering -> Light Probe Proxy Volume, by default, the component looks like this:
Light Probe Proxy Volume Component_1

It’s a component you will need to add to the GameObject such as a 3d model or even a Light Probe Group. The GameObject you want to be affected by the LPPV needs to have a MeshRenderer / Renderer that has the Light Probes property set to “Use Proxy Volume”:

Light Probe Proxy Volume Component_3

You can borrow an existing LPPV component which is used by another GameObject by using the Proxy Volume Override, just drag and drop it into the property field for each Renderer you want to use it on. An example: If you added the LPPV component to the Light Probe Group object, you can then share that across all renderers with the Proxy Volume Override property:

Use Proxy Volume

Setting up the Bounding Box:

There are three options for setting up your Bounding Box:

  • Automatic Local
  • Automatic World
  • Custom

Automatic Local:

Default property setting – the bounding box is computed in local space, interpolated light probe positions will be generated inside this box. The bounding box computation encloses the current Renderer and all the Renderers down the hierarchy that have the Light Probes property set to Use Proxy Volume, same behaviour for Automatic World.

Light Probe Proxy Volume Component_1

Automatic World:

A world-aligned bounding box is computed. Automatic Global and Automatic Local options should be used in conjunction with Proxy Volume Override property on other Renderers. Additionally you could have a hierarchy of GameObjects that use the same LPPV component set on a parent in the hierarchy.

The Difference between this mode and Automatic Local is that in Automatic Local the bounding box is more expensive to compute when a large hierarchy of GameObjects uses the same LPPV component from a parent game object, but the resulting bounding box may be smaller in size, meaning the lighting data is more compact.

Custom:

Empowers you to edit the bounding box volume yourself in the UI, changing the size and origin values in the Inspector or by using the tools to edit in the scene view. Bounding box is specified in local space of the GameObject. You will need to ensure that all the renderers are within the bounding box of the LPPV in this case.

Light Probe Proxy Volume Component

Setting Up Resolution / Density:

After setting up your bounding box, you need to then consider the density / resolution of the Proxy Volume. To do this there’s two options available under Resolution Mode:

Automatic:

Default property setting – set a value for the density i.e. number of probes per unit. Number of probes per unit is calculated in the X, Y and Z axis, so defined by the bounding box size.

Custom:

Set up custom resolution values in the X, Y and Z axis using the drop down menu. Values start at 1 and increment to a power of 2 up to 32. You can have 32x32x32 interpolating probes

Interpolating Probes

Performance Measurements To Consider When Using LPPV:

Keep in mind the interpolation for every batch of 64 interpolated light probes will cost around 0.15ms on CPU (i7 – 4Ghz) (at the time of Profiling). The light probe interpolation is multi-threaded, anything less than or equal to 64 interpolation light probes will not be multi-threaded and will run on the main thread.

Using Unity’s built-in Profiler you can see BlendLightProbesJob on the main thread using the Timeline viewer, if you increase the amount of interpolated light probes to more than 64 you will see BlendLightProbesJob on the worker thread as well:

BlendLightProbesJob

The behaviour for just one batch of 64 interpolated light probes is it will run only on the main thread and if there are more batches (>64) it will schedule one on the main thread and others on the worker threads, but this behaviour is just for one LPPV. If you have a lot of LPPVs with less than 64 interpolated light probes each, they will all run on the main thread.

Hardware Requirements:

The component will require at least Shader Model 4 graphics hardware and API support, including support for 3D textures with 32-bit floating-point format and linear filtering.

Sample shader for particle systems that uses ShadeSHPerPixel function:

The Standard shaders have support for this feature. If you want to add this to a custom shader, use ShadeSHPerPixel function. Check out this sample to see how to use this function:

Shader "Particles/AdditiveLPPV" {

Properties 
{
    _MainTex ("Particle Texture", 2D) = "white" {}
    _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
}

Category 
    {
    Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
    Blend SrcAlpha One
    ColorMask RGB
    Cull Off Lighting Off ZWrite Off

    SubShader 
    {
        Pass 
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_particles
            #pragma multi_compile_fog
            // Don’t forget to specify the target
            #pragma target 3.0

            #include "UnityCG.cginc"
            // You have to include this header to have access to ShadeSHPerPixel
            #include "UnityStandardUtils.cginc"

            fixed4 _TintColor;
            sampler2D _MainTex;

            struct appdata_t 
            {
                   float4 vertex : POSITION;
                   float3 normal : NORMAL;
                   fixed4 color : COLOR;
                   float2 texcoord : TEXCOORD0;
            };

            struct v2f 
            {
                   float4 vertex : SV_POSITION;
                   fixed4 color : COLOR;
                   float2 texcoord : TEXCOORD0;
                   UNITY_FOG_COORDS(1)
                   float3 worldPos : TEXCOORD2;
                   float3 worldNormal : TEXCOORD3;
            };

            float4 _MainTex_ST;
            v2f vert (appdata_t v)
            {
                  v2f o;
                  o.vertex = UnityObjectToClipPos(v.vertex);
                  o.worldNormal = UnityObjectToWorldNormal(v.normal);
                  o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
                  o.color = v.color;
                  o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
                  UNITY_TRANSFER_FOG(o,o.vertex);
                  return o;
             }
            
             fixed4 frag (v2f i) : SV_Target
             {
                    half3 currentAmbient = half3(0, 0, 0);
                    half3 ambient = ShadeSHPerPixel(i.worldNormal, currentAmbient, i.worldPos);
                    fixed4 col = _TintColor * i.color * tex2D(_MainTex, i.texcoord);
                    >col.xyz += ambient;
                    UNITY_APPLY_FOG_COLOR(i.fogCoord, col, fixed4(0,0,0,0)); // fog towards black due to our blend mode
                    return col;
             }
             ENDCG
         }
      }
   }
}

Comments (20)

Subscribe to comments
  1. Brian

    February 9, 2016 at 11:28 pm / 

    I made something similar a while ago that works on mobile.

    1. Brian

      February 9, 2016 at 11:29 pm / 

  2. Chris

    February 8, 2016 at 3:53 am / 

    Great! More useless features that nobody wants! Definitely work on crap like this instead of the important stuff like… oh, I dunno… FIXING ENLIGHTEN?!!?!!???!

    As it currently stands, Unity 5 is a useless piece of garbage.

    1. Christopher

      February 16, 2016 at 6:41 pm / 

      Yup. But wait for 6.x when they make it forced subscription and break even more shit yet call it amazing!

      At this point Unity is losing too many good people to do anything about it even if they tried (which they are not).

      1. Andrew

        March 11, 2016 at 6:29 pm / 

        Exactly, my team is working on building our own game engine so we can dump shitty Unity.

  3. jim bachalo

    February 5, 2016 at 8:41 pm / 

    Nice, but what’s missing is an actual demo, video showing how this feature improves rendering of particles, etc.

  4. Michał Piątek

    February 5, 2016 at 10:16 am / 

    For those who say that this is not important:
    It MIGHT not be important if you are doing mobile game, but since Unity is also used by PC gaming companies this is a HUGE live saver for getting more quality in graphics (especially for —->particles<—-).

  5. David

    February 4, 2016 at 9:31 pm / 

    Not really something that interestes me. In fact, generally I turn off light probes to avoid the overhead.

    What I DO want to see is documentation on the GPU Mesh Instancing feature that’s supposed to be in 5.4. How about a preview video of how that’s going to work and what changes are going to need to be made with existing 5.3 projects.

    thanks
    David

    1. Alkis

      February 7, 2016 at 3:22 am / 

      You can find some basic information here:

      https://docs.google.com/document/d/1RS6cVjE8mBVOKqQUuXbaZcPW3kmw3ZWySJwr-5rDwSs/edit#

      It was posted on the beta section of the forum, on release of 5.4. It might not be all you’re looking for, but it is a start!

      1. David

        February 8, 2016 at 6:53 am / 

        Yikes, sounds like we’re writing our own shaders to use this? Seems sort of, hmmm “anti-unity”. I get that you can’t have a single stock shader do everything, but why not just include addtional ‘instancing’ shaders (along the lines of the mobile shaders already included). Well, anyway, would have made more sense to have a blog posting about that than light probes.

        1. Alkis

          February 9, 2016 at 2:09 am / 

          I’m under the impression that this is the state of affairs in the beta, not necessarily what is going to get released with the full version.

  6. rad

    February 4, 2016 at 5:34 pm / 

    we don’t need this at all.
    Please focus on cloth physics, it’s shame what unity missed.

    1. Ardi Vaba

      February 22, 2016 at 12:54 pm / 

      You mean that YOU don’t need that.

  7. erik

    February 4, 2016 at 10:42 am / 

    Shader error in ‘Particles/AdditiveLPPV’: Can’t find include file UnityStandardUtils.cginc at line 30

    1. Romain

      February 4, 2016 at 11:59 am / 

      That’s a 5.4 feature

  8. Robert Cummings

    February 3, 2016 at 10:33 pm / 

    @WAHOONEY

    Hardware Requirements:

    The component will require at least Shader Model 4 graphics hardware and API support, including support for 3D textures with 32-bit floating-point format and linear filtering.

  9. Wahooney

    February 3, 2016 at 4:44 pm / 

    This is great! Will it work on mobile?

    1. Jonney Shih

      February 9, 2016 at 10:56 pm / 

      Apparently NOT

    2. Jack

      February 12, 2016 at 12:47 am / 

      Shader Level 4 seems it’s a DirectX 12 / Vulcan API feature – there will probably be mobile HW/SW for sale in 4th quarter of 2016 that can do that. Depending on how deep you are in your development you may not want to target anything lower as there are supposed to be major speed improvements by then. It will take a year or so but eventually that will be the commodity level HW and developers should have an easy time of it.

      1. Björn

        March 21, 2016 at 10:06 am / 

        http://docs.unity3d.com/ScriptReference/SystemInfo-graphicsShaderLevel.html
        Shader level 4 should be DX 10, not DX12.
        So basically any PC worth gaming on at all.
        Mobiles however, they seem to be lagging behind, although Metal for iOS might solve it?

Comments are closed.