Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Graphics.DrawMeshInstancedIndirect Does Not Support Lambertian Lighting

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


    Code (CSharp):
    1. Code (CSharp):
    2. Shader "Instanced/InstancedIndirectStandard" {
    3.     Properties {
    4.         _Color ("Color", Color) = (1,1,1,1)
    5.     }
    6.     SubShader {
    7.         Tags { "RenderType"="Opaque" }
    8.         LOD 200
    9.      
    10.         CGPROGRAM
    11.         #pragma surface surf Standard fullforwardshadows addshadow
    12.         #pragma target 3.0
    13.         #pragma multi_compile_instancing
    14.         #pragma instancing_options procedural:setup
    15.  
    16.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    17.             StructuredBuffer<float3> positions;
    18.         #endif
    19.  
    20.         sampler2D _MainTex;
    21.  
    22.         struct Input {
    23.             float2 uv_MainTex;
    24.         };
    25.  
    26.         void setup()
    27.         {
    28.         #ifdef UNITY_PROCEDURAL_INSTANCING_ENABLED
    29.             float3 position    = positions[unity_InstanceID];
    30.             unity_ObjectToWorld._11_21_31_41 = float4(1, 0, 0, 0);
    31.             unity_ObjectToWorld._12_22_32_42 = float4(0, 1, 0, 0);
    32.             unity_ObjectToWorld._13_23_33_43 = float4(0, 0, 1, 0);
    33.             unity_ObjectToWorld._14_24_34_44 = float4(position.xyz, 1);
    34.  
    35.             unity_WorldToObject = unity_ObjectToWorld;
    36.             unity_WorldToObject._14_24_34 *= -1;
    37.             unity_WorldToObject._11_22_33 = 1.0f / unity_WorldToObject._11_22_33;
    38.         #endif
    39.         }
    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 SurfaceOutputStandard 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 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!
     
unityunity