Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by gashraf · Jul 31, 2018 at 10:13 PM · shader programmingsurface shaderinstancing

GPU Instancing with Surface Shader

I am not being able to get the StructuredBuffer to work with a Surface Shader, simply because UNITY_INSTANCING_ENABLED or UNITY_PROCEDURAL_INSTANCING_ENABLED are not getting enabled. I am trying to render GPU instanced meshes via a DrawMeshInstancedIndirect call, along with an instance buffer (and another indexed color look up buffer for efficient color variation). All the instances are being rendered but at the same location. I have managed to successfully get this working with vertex/fragment shader (image attached from my ECS walkers demo), but am just stuck trying to make it work for a lit Standard Surface Shader. Would really appreciate it if someone can help me understand if I am missing something in any setup.

I have ensured that the Material's "Enable Instancing" checkbox is on. Any word of advice pls @richardkettlewell ?

alt text

The shader code is attached below:

 Shader "Instanced/InstancedSurfaceShader" {
     Properties {
         _Color ("Color", Color) = (1,1,1,1)
         _MainTex ("Albedo (RGB)", 2D) = "white" {}
         _Glossiness ("Smoothness", Range(0,1)) = 0.5
         _Metallic ("Metallic", Range(0,1)) = 0.0
     }
     SubShader {
         Tags { "RenderType"="Opaque" }
         LOD 200
 
         CGPROGRAM
 
         #pragma surface surf Standard vertex:vert 
         #pragma target 4.5
         //#pragma multi_compile_instancing
         
         #include "UnityCG.cginc"
         #include "UnityInstancing.cginc"
         
         struct instanceBuf
         {
             float4 posScale;
             float4 rotQuat;
             float batchID;
         };
 
         struct colorTable
         {
             float3 batchColor;
         };
 
 
     #ifdef UNITY_INSTANCING_ENABLED
         StructuredBuffer<instanceBuf> instanceBuffer;
         StructuredBuffer<colorTable> colorLUT;
     #endif
         
         struct appdata {
             float4 vertex : POSITION;
             float3 normal : NORMAL;
             float4 texcoord : TEXCOORD0;
             float4 color : COLOR;
             UNITY_VERTEX_INPUT_INSTANCE_ID //not sure if this is needed
         };
 
         struct Input
         {
             float2 uv_MainTex : TEXCOORD0;
             float4 color : COLOR;
         };
 
         void vert(inout appdata v, out Input o)
         {
             UNITY_INITIALIZE_OUTPUT(Input,o);
             UNITY_SETUP_INSTANCE_ID(v);//not sure if this is needed
 
         #ifdef UNITY_INSTANCING_ENABLED
             float4 data1 = instanceBuffer[unity_InstanceID].posScale;
             float4 q = instanceBuffer[unity_InstanceID].rotQuat;
             float3 color = colorLUT[instanceBuffer[unity_InstanceID].batchID)].batchColor;
         #else
             float4 data1 = 4;//Purposely scale up 4x for debug purposes
             float4 q = 0;//sadly, this block gets called always
             float3 color = (.4,.2,.3);
         #endif
 
             float3 v0 = v.vertex.xyz * data1.w;//scale
             float3 v1 = v0 + 2.0 * cross(q.xyz, cross(q.xyz, v0) + q.w * v0);//rotate
 
             float3 worldPosition = data1.xyz + v1;
             float3 n = normalize(v.normal);
             float3 worldNormal = n + 2.0 * cross(q.xyz, cross(q.xyz, n) + q.w * n);//rotate
 
             v.vertex.xyz = worldPosition;
             v.normal = worldNormal;
                                                                                    
             o.uv_MainTex = v.texcoord;
             o.color = (color,1);
         }
 
         half _Glossiness;
         half _Metallic;
         float4 _Color;
         sampler2D _MainTex;
 
         void surf (Input f, inout SurfaceOutputStandard o) 
         {
             fixed4 c = tex2D(_MainTex, f.uv_MainTex);
             o.Albedo = c.rgb * (0.3*_Color + 0.7*f.color);
             o.Alpha = c.a;
 
             // Metallic and smoothness come from slider variables
             o.Metallic = _Metallic;
             o.Smoothness = _Glossiness;
         }
         ENDCG
     }
     FallBack "Diffuse"
 }

I am also attaching the relevant snippets that setup the buffers leading up to the draw call here in the C# RenderSystem class. This works well for vertex/fragment shaders but does not yet work for Surface Shaders or Deferred Shaders. Pls. let me know if this is not the correct approach for Surface Shaders:

                 //1. populate the instance buffer
                 instanceBuffer.Add(new ComputeBuffer(instanceCount,9*sizeof(float)));
                 float[] tx = new float[instanceCount * 9];
                 for (int j = 0, k = 0; j < instanceCount; j++, k += 9)
                 {
                     Vector3 p = pos[j].Value;
 
                     tx[k] = p.x;
                     tx[k + 1] = p.y;
                     tx[k + 2] = p.z;
                     tx[k + 3] = size[j].Value;
                     tx[k + 4] = rot[j].Value.value.x;
                     tx[k + 5] = rot[j].Value.value.y;
                     tx[k + 6] = rot[j].Value.value.z;
                     tx[k + 7] = rot[j].Value.value.w;
                     tx[k + 8] = boid[j].Value;
                 }
                 instanceBuffer[i].SetData(tx);
                      
                 //2. Setup args buffer
                 args[0] = (uint)instanceMesh[j].GetIndexCount(subMeshIndex);
                 args[1] = (uint)instanceCount;
                 args[2] = (uint)instanceMesh[j].GetIndexStart(subMeshIndex);
                 args[3] = uint)instanceMesh[j].GetBaseVertex(subMeshIndex);
 
                 argsBuffer[j].SetData(args);
 
                 //3. Link the buffers to the shader material
                 instanceMaterial.SetBuffer("instanceBuffer", instanceBuffer[i]);
                 instanceMaterial.SetBuffer("colorLUT", colorLUT);
 
                 //4. Now Render all the instances for the given mesh
                 Graphics.DrawMeshInstancedIndirect(instanceMesh[j], 0, instanceMaterial,new Bounds(new Vector3(0f, 1f, 0f), new Vector3(200f, 200f, 200f)),argsBuffer[j],0,null,0,false);

References

  1. Unity docs on SurfaceShading with DrawMeshInstancedIndirect

  2. Keijiro's Cloner

  3. Physics Shader

wallkers-01.jpg (480.3 kB)
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image jpq · Jan 28, 2020 at 11:31 PM 0
Share

@gashraf Sorry for the late reply, I have the same question. Did you figure this out?

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

153 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

,Help Changing a "Doom" Style Billboard Shader to a Surface Shader 0 Answers

Problem with surface shader using uv2 1 Answer

Custom Surface shader don't work with fresnel reflection and normal map at the same time 0 Answers

color array in Unity Surface Shader causing weird aliasing 0 Answers

Unity 5.4 - unity 2017 ruin GPU instansing 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges