Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice
  2. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  3. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Indirect Instanced Rendering Does Not Support Lambertian Lighting

Discussion in '5.6 Beta' started by jknight-nc, Mar 30, 2017.

  1. jknight-nc

    jknight-nc

    Joined:
    Jun 10, 2014
    Posts:
    52
    I'm testing Indirect Instanced Rendering and am trying to use a Lambert lighting scheme. I've taken the basic Indirect Instanced Shader and changed it to use the Lambert lighting scheme.

    Note I am using a Mac and the Metal Renderer System. The cubes are unlit both in the Editor and in the Player.

    And I built the test project to an Android device and the cubes are unlit there as well.

    The top cube is using Legacy -> Diffuse

    The top cube is a basic cube using Legacy->Diffuse, the middle row is rendered using Indirect Instanced Rendering using a Standard Lighting surface shader and the bottom row is rendered using Indirect Instanced Rendering using a Lambert lighting surface shader.



    This is the Indirect Instanced Lambert Surface shader I am using (this does not work, even though Lambert lighting can be used on InstancedRendering)


    Code (CSharp):
    1. Shader "Instanced/InstancedIndirectLambert" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 200
    8.        
    9.         CGPROGRAM
    10.         #pragma surface surf Lambert fullforwardshadows addshadow
    11.         #pragma target 3.0
    12.         #pragma multi_compile_instancing
    13.         #pragma instancing_options procedural:setup
    14.  
    15.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    16.             StructuredBuffer<float3> positions;
    17.         #endif
    18.  
    19.         sampler2D _MainTex;
    20.  
    21.         struct Input {
    22.             float2 uv_MainTex;
    23.         };
    24.  
    25.  
    26.  
    27.         void setup()
    28.         {
    29.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    30.             float3 position     = positions[unity_InstanceID];
    31.             unity_ObjectToWorld._11_21_31_41 = float4(1, 0, 0, 0);
    32.             unity_ObjectToWorld._12_22_32_42 = float4(0, 1, 0, 0);
    33.             unity_ObjectToWorld._13_23_33_43 = float4(0, 0, 1, 0);
    34.             unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
    35.  
    36.             unity_WorldToObject = unity_ObjectToWorld;
    37.             unity_WorldToObject._14_24_34 *= -1;
    38.             unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
    39.         #endif
    40.         }
    41.         UNITY_INSTANCING_CBUFFER_START(Props)
    42.             UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)    // Make _Color an instanced property (i.e. an array)
    43.         UNITY_INSTANCING_CBUFFER_END
    44.  
    45.         void surf (Input IN, inout SurfaceOutput o) {
    46.             fixed4 c = UNITY_ACCESS_INSTANCED_PROP(_Color);
    47.             o.Albedo = c.rgb;
    48.             o.Alpha = c.a;
    49.         }
    50.         ENDCG
    51.     }
    52.     FallBack "Diffuse"
    53. }
    54.  
    This is the Indirect Instanced Standard Surface shader I am using (this one works):


    Code (CSharp):
    1. Shader "Instanced/InstancedIndirectStandard" {
    2.     Properties {
    3.         _Color ("Color", Color) = (1,1,1,1)
    4.     }
    5.     SubShader {
    6.         Tags { "RenderType"="Opaque" }
    7.         LOD 200
    8.        
    9.         CGPROGRAM
    10.         #pragma surface surf Standard fullforwardshadows addshadow
    11.         #pragma target 3.0
    12.         #pragma multi_compile_instancing
    13.         #pragma instancing_options procedural:setup
    14.  
    15.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    16.             StructuredBuffer<float3> positions;
    17.         #endif
    18.  
    19.         sampler2D _MainTex;
    20.  
    21.         struct Input {
    22.             float2 uv_MainTex;
    23.         };
    24.  
    25.         void setup()
    26.         {
    27.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    28.             float3 position     = positions[unity_InstanceID];
    29.             unity_ObjectToWorld._11_21_31_41 = float4(1, 0, 0, 0);
    30.             unity_ObjectToWorld._12_22_32_42 = float4(0, 1, 0, 0);
    31.             unity_ObjectToWorld._13_23_33_43 = float4(0, 0, 1, 0);
    32.             unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
    33.  
    34.             unity_WorldToObject = unity_ObjectToWorld;
    35.             unity_WorldToObject._14_24_34 *= -1;
    36.             unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
    37.         #endif
    38.         }
    39.  
    40.         UNITY_INSTANCING_CBUFFER_START(Props)
    41.             UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)    // Make _Color an instanced property (i.e. an array)
    42.         UNITY_INSTANCING_CBUFFER_END
    43.  
    44.         void surf(Input IN, inout SurfaceOutputStandard o) {
    45.             fixed4 c = UNITY_ACCESS_INSTANCED_PROP(_Color);
    46.             o.Albedo = c.rgb;
    47.             o.Alpha = c.a;
    48.         }
    49.         ENDCG
    50.     }
    51.     FallBack "Diffuse"
    52. }
    53.  

    This is the rendering script I am using for both lighting schemes (just with different materials)


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class InstancedIndirectRenderer : MonoBehaviour {
    6.  
    7.     public Material m_instancedIndirectMaterial;
    8.     public Mesh m_cubeMesh;
    9.     public int m_numMeshes;
    10.     public Bounds m_bounds;
    11.  
    12.     private ComputeBuffer m_bufferWithArgs;
    13.     private Vector3[] m_positionArray;
    14.     private ComputeBuffer m_positionBuffer;
    15.  
    16.     void Start () {
    17.         // Setup buffer with args
    18.         uint indexCountPerInstance         = m_cubeMesh.GetIndexCount(0);
    19.         uint instanceCount                 = (uint)m_numMeshes;
    20.         uint startIndexLocation         = 0;
    21.         uint baseVertexLocation         = 0;
    22.         uint startInstanceLocation         = 0;
    23.         uint[] args = new uint[]{indexCountPerInstance, instanceCount , startIndexLocation, baseVertexLocation, startInstanceLocation};
    24.  
    25.         m_bufferWithArgs = new ComputeBuffer(1, args.Length*sizeof(uint), ComputeBufferType.IndirectArguments);
    26.         m_bufferWithArgs.SetData(args);
    27.  
    28.         // Setup positions
    29.         m_positionArray                 = new Vector3[m_numMeshes];
    30.         for (int i = 0; i < m_numMeshes; i++) {
    31.             m_positionArray[i] = new Vector3(i,0,0) + transform.position;
    32.         }
    33.         m_positionBuffer = new ComputeBuffer(m_numMeshes, sizeof(float)*3);
    34.         m_positionBuffer.SetData(m_positionArray);
    35.         m_instancedIndirectMaterial.SetBuffer("positions", m_positionBuffer);
    36.     }
    37.    
    38.  
    39.     void Update () {
    40.         Graphics.DrawMeshInstancedIndirect(m_cubeMesh, 0, m_instancedIndirectMaterial, m_bounds, m_bufferWithArgs, 0, null,UnityEngine.Rendering.ShadowCastingMode.On, true, 0, Camera.main);
    41.     }
    42.  
    43.     void OnDestroy() {
    44.         m_bufferWithArgs.Dispose();
    45.         m_bufferWithArgs = null;
    46.  
    47.         m_positionBuffer.Dispose();
    48.         m_positionBuffer = null;
    49.     }
    50. }
    51.  

    I reported this bug and it's case number is 896648.

    This is crucial for our team because we are using the Lambertian lighting scheme in our voxel based game and would like to use this new API in combination with a GPU accelerated physics system that we are writing.

    Please let me know if this is in the roadmap to be resolved or if there are any problems with my implementation!
     
    richardkettlewell likes this.