public virtual void OnEnable() { m_trans = GetComponent <Transform>(); if (m_materials == null || m_materials.Length == 0) { m_materials = new Material[1] { m_material }; } m_actual_materials = new List <List <Material> >(); while (m_actual_materials.Count < m_materials.Length) { m_actual_materials.Add(new List <Material>()); } if (m_expanded_mesh == null && m_mesh != null) { m_expanded_mesh = BatchRendererUtil.CreateExpandedMesh(m_mesh, out m_instances_par_batch); m_expanded_mesh.UploadMeshData(true); } int layer_mask = m_layer_selector.value; for (int i = 0; i < 32; ++i) { if ((layer_mask & (1 << i)) != 0) { m_layer = i; m_layer_selector.value = 1 << i; break; } } }
public virtual void Flush() { if (m_expanded_mesh == null || m_instance_count == 0) { m_instance_count = 0; return; } Vector3 scale = m_trans.localScale; m_expanded_mesh.bounds = new Bounds(m_trans.position, new Vector3(m_bounds_size.x * scale.x, m_bounds_size.y * scale.y, m_bounds_size.y * scale.y)); m_instance_count = Mathf.Min(m_instance_count, m_max_instances); m_batch_count = BatchRendererUtil.ceildiv(m_instance_count, m_instances_par_batch); for (int i = 0; i < m_actual_materials.Count; ++i) { var a = m_actual_materials[i]; while (a.Count < m_batch_count) { Material m = CloneMaterial(m_materials[i], a.Count); a.Add(m); } } UpdateGPUResources(); IssueDrawCall(); m_instance_count = m_batch_count = 0; }
public virtual void ResetGPUResoures() { ReleaseGPUResources(); m_buf_trail_params = new ComputeBuffer(1, MPGPTrailParams.size); m_buf_trail_entities = new ComputeBuffer(m_max_entities, MPGPTrailEntity.size); m_buf_trail_history = new ComputeBuffer(m_max_entities * m_max_trail_history, MPGPTrailHistory.size); m_buf_trail_vertices = new ComputeBuffer(m_max_entities * m_max_trail_history, MPGPTrailVertex.size); { int[] indices = new int[(m_max_trail_history - 1) * 6]; int[] ls = new int[6] { 0, 3, 1, 0, 2, 3 }; for (int i = 0; i < m_max_trail_history - 1; ++i) { indices[i * 6 + 0] = i * 2 + ls[0]; indices[i * 6 + 1] = i * 2 + ls[1]; indices[i * 6 + 2] = i * 2 + ls[2]; indices[i * 6 + 3] = i * 2 + ls[3]; indices[i * 6 + 4] = i * 2 + ls[4]; indices[i * 6 + 5] = i * 2 + ls[5]; } m_expanded_mesh = BatchRendererUtil.CreateIndexOnlyMesh(m_max_trail_history * 2, indices, out m_instances_par_batch); } UpdateGPUResources(); }
public void UploadInstanceData_TextureWithPlugin() { BatchRendererUtil.DataConversion cv34 = BatchRendererUtil.DataConversion.Float3ToFloat4; BatchRendererUtil.DataConversion cv44 = BatchRendererUtil.DataConversion.Float4ToFloat4; if (m_instance_texture.translation.format == RenderTextureFormat.ARGBHalf) { cv34 = BatchRendererUtil.DataConversion.Float3ToHalf4; cv44 = BatchRendererUtil.DataConversion.Float4ToHalf4; } BatchRendererUtil.CopyToTexture(m_instance_texture.translation, m_instance_data.translation, m_instance_count, cv34); if (m_enable_rotation) { BatchRendererUtil.CopyToTexture(m_instance_texture.rotation, m_instance_data.rotation, m_instance_count, cv44); } if (m_enable_scale) { BatchRendererUtil.CopyToTexture(m_instance_texture.scale, m_instance_data.scale, m_instance_count, cv34); } if (m_enable_color) { BatchRendererUtil.CopyToTexture(m_instance_texture.color, m_instance_data.color, m_instance_count, cv44); } if (m_enable_emission) { BatchRendererUtil.CopyToTexture(m_instance_texture.emission, m_instance_data.emission, m_instance_count, cv44); } if (m_enable_uv_offset) { BatchRendererUtil.CopyToTexture(m_instance_texture.uv_offset, m_instance_data.uv_offset, m_instance_count, cv44); } }
public override void OnEnable() { base.OnEnable(); if (m_mesh == null) { return; } if (m_data_transfer_mode == DataTransferMode.Buffer && !SystemInfo.supportsComputeShaders) { Debug.Log("BatchRenderer: ComputeBuffer is not available. fallback to TextureWithMesh data transfer mode."); m_data_transfer_mode = DataTransferMode.TextureWithMesh; } if (m_data_transfer_mode == DataTransferMode.TextureWithPlugin && !BatchRendererUtil.IsCopyToTextureAvailable()) { Debug.Log("BatchRenderer: CopyToTexture plugin is not available. fallback to TextureWithMesh data transfer mode."); m_data_transfer_mode = DataTransferMode.TextureWithMesh; } m_instance_data = new InstanceData(); if (m_data_transfer_mode == DataTransferMode.Buffer) { m_instance_buffer = new InstanceBuffer(); } else { m_instance_texture = new InstanceTexture(); if (m_data_transfer_mode == DataTransferMode.TextureWithMesh) { m_data_transfer_mesh = BatchRendererUtil.CreateDataTransferMesh(m_max_instances); } } ResetGPUData(); }
RenderTexture CreateDataTexture(int num_max_instances) { int width = texture_width; int height = BatchRendererUtil.ceildiv(num_max_instances, texture_width); RenderTexture r = null; if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBFloat)) { r = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Default); } else if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf)) { Debug.Log("BatchRenderer: float texture is not available. use half texture instead"); r = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default); } else { Debug.Log("BatchRenderer: both float and half texture are not available. give up."); return(null); } r.filterMode = FilterMode.Point; r.Create(); return(r); }
public void UploadInstanceData_TextureWithMesh() { m_data_transfer_material.SetVector("g_texel", m_instance_texel_size); BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.translation, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.translation, m_instance_count); if (m_enable_rotation) { BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.rotation, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.rotation, m_instance_count); } if (m_enable_scale) { BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.scale, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.scale, m_instance_count); } if (m_enable_color) { BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.color, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.color, m_instance_count); } if (m_enable_emission) { BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.emission, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.emission, m_instance_count); } if (m_enable_uv_offset) { BatchRendererUtil.CopyToTextureViaMesh(m_instance_texture.uv_offset, m_data_transfer_mesh, m_data_transfer_material, m_instance_data.uv_offset, m_instance_count); } }
public virtual void Flush() { if (m_mesh == null || m_instance_count == 0) { m_instance_count = 0; return; } m_expanded_mesh.bounds = new Bounds(m_trans.position, m_trans.localScale); m_instance_count = Mathf.Min(m_instance_count, m_max_instances); m_batch_count = BatchRendererUtil.ceildiv(m_instance_count, m_instances_par_batch); while (m_materials.Count < m_batch_count) { Material m = CloneMaterial(m_materials.Count); m_materials.Add(m); } UpdateGPUData(); Matrix4x4 matrix = Matrix4x4.identity; for (int i = 0; i < m_batch_count; ++i) { Graphics.DrawMesh(m_expanded_mesh, matrix, m_materials[i], m_layer, m_camera, 0, null, m_cast_shadow, m_receive_shadow); } m_instance_count = m_batch_count = 0; }
public override void OnEnable() { base.OnEnable(); if (m_mesh == null) { return; } m_instance_data = new InstanceData(); ReleaseGPUData(); if (m_data_transfer_mode == DataTransferMode.Buffer) { m_instance_buffer = new InstanceBuffer(); } else { m_instance_texture = new InstanceTexture(); if (m_data_transfer_mode == DataTransferMode.TextureWithMesh) { m_data_transfer_mesh = BatchRendererUtil.CreateDataTransferMesh(m_max_instances); } } ResetGPUData(); }
void UpdateTask(System.Object arg) { Range r = (Range)arg; int num = r.end - r.begin; Texture tex = m_renderer.m_material.mainTexture; for (int i = r.begin; i < r.end; ++i) { float time = m_instance_time[i] + m_time; float e = 0.75f + Mathf.Sin(time * 10.0f) * 0.25f; int a = (int)(time * 5.0f) % 16; m_instance_color[i] = new Color(1.0f, 1.0f, 1.0f, e); m_instance_uv[i] = BatchRendererUtil.ComputeUVOffset(tex, new Rect(32 * (a % 4), 32 * (a / 4), 32, 32)); } { int reserved_index; int reserved_num; BatchRenderer.InstanceData data = m_renderer.ReserveInstance(num, out reserved_index, out reserved_num); System.Array.Copy(m_instance_t, r.begin, data.translation, reserved_index, reserved_num); System.Array.Copy(m_instance_color, r.begin, data.color, reserved_index, reserved_num); System.Array.Copy(m_instance_uv, r.begin, data.uv_offset, reserved_index, reserved_num); } Interlocked.Decrement(ref m_num_active_tasks); }
public void ResetGPUData() { ReleaseGPUData(); m_instance_data.Resize(m_max_instances); if (m_instance_buffer != null) { m_instance_buffer.Allocate(m_max_instances); } BatchRendererUtil.CreateVertexBuffer(m_mesh, ref m_vertex_buffer, ref m_vertex_count); { Material m = m_material; m.SetInt("g_flag_rotation", m_enable_rotation ? 1 : 0); m.SetInt("g_flag_scale", m_enable_scale ? 1 : 0); m.SetInt("g_flag_color", m_enable_color ? 1 : 0); m.SetInt("g_flag_emission", m_enable_emission ? 1 : 0); m.SetInt("g_flag_uvoffset", m_enable_uv_offset ? 1 : 0); if (m_instance_buffer != null) { m.SetBuffer("g_vertices", m_vertex_buffer); m.SetBuffer("g_instance_buffer_t", m_instance_buffer.translation); m.SetBuffer("g_instance_buffer_r", m_instance_buffer.rotation); m.SetBuffer("g_instance_buffer_s", m_instance_buffer.scale); m.SetBuffer("g_instance_buffer_color", m_instance_buffer.color); m.SetBuffer("g_instance_buffer_emission", m_instance_buffer.emission); m.SetBuffer("g_instance_buffer_uv", m_instance_buffer.uv_offset); } } { m_cb = new CommandBuffer(); m_cb.name = "ProceduralGBuffer"; m_cb.DrawProcedural(Matrix4x4.identity, m_material, 0, MeshTopology.Triangles, m_vertex_count, m_max_instances); m_camera.AddCommandBuffer(CameraEvent.AfterGBuffer, m_cb); } // set default values UpdateGPUResources(); }
public virtual void Flush() { if (m_expanded_mesh == null || m_instance_count == 0) { m_instance_count = 0; return; } Vector3 scale = m_trans.localScale; m_expanded_mesh.bounds = new Bounds(m_trans.position, new Vector3(m_bounds_size.x * scale.x, m_bounds_size.y * scale.y, m_bounds_size.y * scale.y)); m_instance_count = Mathf.Min(m_instance_count, m_max_instances); m_batch_count = BatchRendererUtil.ceildiv(m_instance_count, m_instances_par_batch); for (int i = 0; i < m_actual_materials.Count; ++i) { var a = m_actual_materials[i]; while (a.Count < m_batch_count) { Material m = CloneMaterial(m_materials[i], a.Count); a.Add(m); } } UpdateGPUResources(); Matrix4x4 matrix = Matrix4x4.identity; m_actual_materials.ForEach(a => { for (int i = 0; i < m_batch_count; ++i) { Graphics.DrawMesh(m_expanded_mesh, matrix, a[i], m_layer, m_camera, 0, null, m_cast_shadow, m_receive_shadow); } }); m_instance_count = m_batch_count = 0; }
public virtual void OnEnable() { if (m_mesh == null) { return; } m_trans = GetComponent <Transform>(); m_materials = new List <Material>(); m_expanded_mesh = BatchRendererUtil.CreateExpandedMesh(m_mesh, out m_instances_par_batch); m_expanded_mesh.UploadMeshData(true); int layer_mask = m_layer_selector.value; for (int i = 0; i < 32; ++i) { if ((layer_mask & (1 << i)) != 0) { m_layer = i; m_layer_selector.value = 1 << i; break; } } if (m_data_transfer_mode == DataTransferMode.Buffer && !SystemInfo.supportsComputeShaders) { Debug.Log("BatchRenderer: ComputeBuffer is not available. fallback to TextureWithMesh data transfer mode."); m_data_transfer_mode = DataTransferMode.TextureWithMesh; } if (m_data_transfer_mode == DataTransferMode.TextureWithPlugin && !BatchRendererUtil.IsCopyToTextureAvailable()) { Debug.Log("BatchRenderer: CopyToTexture plugin is not available. fallback to TextureWithMesh data transfer mode."); m_data_transfer_mode = DataTransferMode.TextureWithMesh; } }