GPU实例化技术(二)

作者:追风剑情 发布于:2024-12-29 11:14 分类:Shader

  开启GPU实例化后,Unity默认仅对材质相同,但位置不同的游戏对象进行批次化。如果想让材质相同,但其它属性不同的游戏对象执行批次化,就需要自定义shader。

示例:材质相同,颜色不同,添加GPU多例化支持

1、在外观着色器中给材质颜色变量增加GPU多例化支持

  1. Shader "Custom/InstancedColorSurfaceShader"
  2. {
  3. Properties
  4. {
  5. _Color ("Color", Color) = (1, 1, 1, 1)
  6. _MainTex ("Albedo (RGB)", 2D) = "white" {}
  7. _Glossiness("Smoothness", Range(0, 1)) = 0.5
  8. _Metallic("Metallic", Range(0, 1)) = 0.0
  9. }
  10. SubShader
  11. {
  12. Tags { "RenderType" = "Opaque" }
  13. LOD 200
  14.  
  15. CGPROGRAM
  16. // 使用 Unity 3D 标准材质的光照模型,所有光源都启动阴影效果
  17. #pragma surface surf Standard fullforwardshadows
  18. // 使用 shader model 3.0
  19. #pragma target 3.0
  20.  
  21. sampler2D _MainTex;
  22. struct Input
  23. {
  24. float2 uv_MainTex;
  25. };
  26. half _Glossiness;
  27. half _Metallic;
  28.  
  29. //开始声明实例化变量
  30. UNITY_INSTANCING_BUFFER_START(Props)
  31. //声明实例化变量 _Color
  32. UNITY_DEFINE_INSTANCED_PROP(fixed4, _Color)
  33. //结束声明实例化变量
  34. UNITY_INSTANCING_BUFFER_END(Props)
  35.  
  36. void surf (Input IN, inout SurfaceOutputStandard o)
  37. {
  38. fixed4 c = tex2D(_MainTex, IN.uv_MainTex) *
  39. UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
  40. o.Albedo = c.rgb;
  41. o.Metallic = _Metallic;
  42. o.Smoothness = _Glossiness;
  43. o.Alpha = c.a;
  44. }
  45.  
  46. ENDCG
  47. }
  48. FallBack "Diffuse"
  49. }


2、写个测试脚本,生成1000个小球

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>
  5. /// 测试GPU实例化技术
  6. /// </summary>
  7. public class GPUInstancedTest : MonoBehaviour
  8. {
  9. public GameObject sphere;
  10. public int count = 500;
  11. public int radius = 200;
  12.  
  13. void Start()
  14. {
  15. MaterialPropertyBlock props = new MaterialPropertyBlock();
  16. MeshRenderer renderer;
  17.  
  18. for (int i=0; i<count; i++)
  19. {
  20. //随机颜色
  21. float r = Random.Range(0.0f, 1.0f);
  22. float g = Random.Range(0.0f, 1.0f);
  23. float b = Random.Range(0.0f, 1.0f);
  24. props.SetColor("_Color", new Color(r, g, b));
  25. //生成小球
  26. GameObject go = Instantiate<GameObject>(sphere);
  27. go.transform.SetParent(transform);
  28. go.transform.localPosition = Random.insideUnitSphere * radius;
  29. renderer = go.GetComponent<MeshRenderer>();
  30. renderer.SetPropertyBlock(props);
  31. }
  32. }
  33. }


3、工程截图
22222.png

4、运行测试
11111.png

标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号