void Start() { Reallocate(4); m_Data = new List <CustomData>() { new CustomData() { position = new Vector3(0, 0, 0), rectangle = new Rectangle() { color = new Vector3(1, 1, 1), size = new Vector2(1024, 1024) } } }; m_Buffer.SetData(m_Data); }
void GeneratePerlinPermTexture(byte[] _perms) { int bufferCount = BufferCount(); int[] datas = new int[bufferCount]; for (int y = 0; y < SIZE; y++) { for (int x = 0; x < SIZE; x++) { int A = _perms[x] + y; int AA = _perms[A]; int AB = _perms[A + 1]; int B = _perms[x + 1] + y; int BA = _perms[B]; int BB = _perms[B + 1]; int index = y * SIZE + x; datas[index] = ((AA << 24) | (AB << 16) | (BA << 8) | (BB)); } } PerlinPerm.SetData(datas); }
void Generate(long _seed) { seed = _seed; int size = Setting.SimplexNoiseSize; int[] source = new int[size]; for (int i = 0; i < size; ++i) { source[i] = i; } Vector2[] GRADIENTS_2D; CreateGradient(out GRADIENTS_2D); int[] rawPerm = new int[size]; Vector2[] rawGrad2 = new Vector2[size]; for (int i = size - 1; 0 <= i; --i) { _seed = _seed * 6364136223846793005L + 1442695040888963407L; int r = (int)((seed + 31) % (i + 1)); if (r < 0) { r += (i + 1); } rawPerm[i] = source[r]; rawGrad2[i] = GRADIENTS_2D[rawPerm[i]]; source[r] = source[i]; } perm.SetData(rawPerm); permGrad2.SetData(rawGrad2); }
void InitializeGPUBuffers() { int sizeOfVector3 = System.Runtime.InteropServices.Marshal.SizeOf((object)Vector3.zero); GPU_VertexBuffer = new ComputeBuffer(m_vertexBufferCPU.Length, sizeof(float) * 8); GPU_VertexBuffer.SetData(m_vertexBufferCPU); GPU_defaultPositionsBuffer = new ComputeBuffer(m_verticesPosition.Length, sizeOfVector3); GPU_defaultPositionsBuffer.SetData(m_verticesPosition); int kernel = m_computeShader.FindKernel(kernelName); m_computeShader.SetBuffer(kernel, "_VertexBuffer", GPU_VertexBuffer); m_computeShader.SetBuffer(kernel, "_InitialPositionBuffer", GPU_defaultPositionsBuffer); m_computeShader.SetFloat("_distanceBegin", ScaleFromWorldtoMeshSpace(m_colliderBeginDistance)); m_computeShader.SetFloat("_distnaceEnd", ScaleFromWorldtoMeshSpace(m_colliderEndDistance)); m_computeShader.SetFloat("_pushforce", m_pushforce); m_computeShader.SetFloat("_elacticity", m_elasticity); m_computeShader.SetFloat("_drag", m_drag); Debug.Log(string.Format("Initialized the GPU buffers with {0} vertices, for the compute shader", m_verticesPosition.Length)); if (m_renderingMethod == RenderMethod.WithDrawProcedural) { GPU_IndexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, m_indexBuffer.Length, sizeof(int)); GPU_IndexBuffer.SetData(m_indexBuffer); } }
private void CreateIndexBuffer() { var vertexCount = _vertexCountPerDim; var quadCount = (vertexCount - 1) * (vertexCount - 1); _indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, quadCount * 6, sizeof(int)); int[] indicies = new int[_indexBuffer.count]; for (var x = 0; x < vertexCount - 1; x++) { for (var y = 0; y < vertexCount - 1; y++) { var vertexIndex = (y * vertexCount + x); var quadIndex = y * (vertexCount - 1) + x; var upVertexIndex = (vertexIndex + vertexCount); var offset = quadIndex * 6; indicies[offset] = vertexIndex; indicies[offset + 1] = (vertexIndex + 1); indicies[offset + 2] = upVertexIndex; indicies[offset + 3] = upVertexIndex; indicies[offset + 4] = (vertexIndex + 1); indicies[offset + 5] = (upVertexIndex + 1); } } _indexBuffer.SetData(new List <int>(indicies)); }
void Setup() { if (method == eDRAW.INDEX_NO) { // make vertices data from triangles vertCount = mesh.triangles.Length; vertexBuffer = GetTrignleVertices(mesh); } else { vertexBuffer = GetVertices(mesh); // make indices data from index buffer indexCount = (int)mesh.GetIndexCount(0); indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, indexCount, 4); indexBuffer.SetData(mesh.GetIndices(0)); // make arguement if (method == eDRAW.INDEX_INDIRECT) { bufferWithArgs = GetArgsBuffer((uint)indexCount, (uint)instanceCount); } } material.SetBuffer("points", vertexBuffer); lastMethod = method; lastInstanceCount = instanceCount; }
private void InitializeVertexBuffer(Mesh mesh) { vertexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, mesh.vertexCount, VertexBufferStride); Shader.SetGlobalBuffer(VertexBufferId, this.vertexBuffer); var meshBuffer = new float[mesh.vertexCount * VertexBufferStride / 4]; var positions = new List <Vector3>(); var uvs = new List <Vector2>(); var normals = new List <Vector3>(); uint meshBufferIdx = 0; mesh.GetVertices(positions); mesh.GetUVs(0, uvs); mesh.GetNormals(normals); for (var j = 0; j < positions.Count; ++j) { meshBuffer[meshBufferIdx++] = positions[j].x; meshBuffer[meshBufferIdx++] = positions[j].y; meshBuffer[meshBufferIdx++] = positions[j].z; meshBuffer[meshBufferIdx++] = 1; meshBuffer[meshBufferIdx++] = uvs[j].x; meshBuffer[meshBufferIdx++] = uvs[j].y; meshBuffer[meshBufferIdx++] = normals[j].x; meshBuffer[meshBufferIdx++] = normals[j].y; meshBuffer[meshBufferIdx++] = normals[j].z; } vertexBuffer.SetData(meshBuffer); Debug.Log("Init Vertex Buffer"); }
unsafe void UpdateBuffers(ImDrawDataPtr drawData) { int drawArgCount = 0; // nr of drawArgs is the same as the nr of ImDrawCmd for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n) { drawArgCount += drawData.CmdListsRange[n].CmdBuffer.Size; } // create or resize vertex/index buffers if (_vtxBuf == null || _vtxBuf.count < drawData.TotalVtxCount) { CreateOrResizeVtxBuffer(ref _vtxBuf, drawData.TotalVtxCount); } if (_idxBuf == null || _idxBuf.count < drawData.TotalIdxCount) { CreateOrResizeIdxBuffer(ref _idxBuf, drawData.TotalIdxCount); } if (_argBuf == null || _argBuf.count < drawArgCount * 5) { CreateOrResizeArgBuffer(ref _argBuf, drawArgCount * 5); } // upload vertex/index data into buffers int vtxOf = 0; int idxOf = 0; int argOf = 0; for (int n = 0, nMax = drawData.CmdListsCount; n < nMax; ++n) { ImDrawListPtr drawList = drawData.CmdListsRange[n]; NativeArray <ImDrawVert> vtxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ImDrawVert>( (void *)drawList.VtxBuffer.Data, drawList.VtxBuffer.Size, Allocator.None); NativeArray <ushort> idxArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <ushort>( (void *)drawList.IdxBuffer.Data, drawList.IdxBuffer.Size, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref vtxArray, AtomicSafetyHandle.GetTempMemoryHandle()); NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref idxArray, AtomicSafetyHandle.GetTempMemoryHandle()); #endif // upload vertex/index data _vtxBuf.SetData(vtxArray, 0, vtxOf, vtxArray.Length); _idxBuf.SetData(idxArray, 0, idxOf, idxArray.Length); // arguments for indexed draw _drawArgs[3] = vtxOf; // base vertex location for (int i = 0, iMax = drawList.CmdBuffer.Size; i < iMax; ++i) { ImDrawCmdPtr cmd = drawList.CmdBuffer[i]; _drawArgs[0] = (int)cmd.ElemCount; // index count per instance _drawArgs[2] = idxOf + (int)cmd.IdxOffset; // start index location _argBuf.SetData(_drawArgs, 0, argOf, 5); argOf += 5; // 5 int for each cmd } vtxOf += vtxArray.Length; idxOf += idxArray.Length; } }
void Start() { var filt = GetComponent <MeshFilter>(); var mesh = filt.sharedMesh; if (weld) { mesh = Weld(filt.sharedMesh); filt.mesh = mesh; } var vrts = mesh.vertices; var tris = mesh.GetIndices(0); var frtos = new Vector3Int[tris.Length]; var bglns = new Vector2Int[vrts.Length]; mat = GetComponent <MeshRenderer>().sharedMaterial; len = vrts.Length; for (var i = 0; i < tris.Length; i += 3) { var i0 = tris[i]; var i1 = tris[i + 1]; var i2 = tris[i + 2]; frtos[i + 0] = new Vector3Int(i0, i1, i2); frtos[i + 1] = new Vector3Int(i1, i2, i0); frtos[i + 2] = new Vector3Int(i2, i0, i1); } frtos = frtos.OrderBy(ft => ft.x).ToArray(); int fr = 0; int bg = 0; for (var i = 0; i < frtos.Length; i++) { var curr = frtos[i]; if (curr.x == fr + 1) { bglns[fr] = new Vector2Int(bg, i - bg); bg = i; fr++; if (curr.x == vrts.Length - 1) { bglns[curr.x] = new Vector2Int(bg, frtos.Length - bg); } } } vrtBuff = new GraphicsBuffer(Target.Vertex, vrts.Length, sizeof(float) * 3); colBuff = new GraphicsBuffer(Target.Structured, vrts.Length, sizeof(float)); idxBuff = new GraphicsBuffer(Target.Structured, frtos.Length, sizeof(int) * 3); tblBuff = new GraphicsBuffer(Target.Structured, bglns.Length, sizeof(int) * 2); idxBuff.SetData(frtos); tblBuff.SetData(bglns); vrtBuff.SetData(vrts); }
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { if (renderingData.cameraData.renderType != CameraRenderType.Base) { return; } var cameraID = renderingData.cameraData.camera.GetInstanceID(); // Recreate resources on domain reload. var firstFrame = !passes.TryGetValue(cameraID, out var pass); // if (pass?.Material == null) { // passes.Remove(cameraID); // firstFrame = true; // } // Create a new pass per-camera (or get it if already created). if (firstFrame) { pass = new SheepPass(sheepMesh, sheepMaterial); passes.Add(cameraID, pass); } #if UNITY_EDITOR if (lastMesh != sheepMesh) { vertexBuffer?.Dispose(); indexBuffer?.Dispose(); InitializeVertexBuffer(sheepMesh); InitializeIndexBuffer(sheepMesh); lastMesh = sheepMesh; } #endif // Update drawArgs. if (drawArgsBuffer != null && sheepMesh != null) { var drawArgs = new int[1 * 1 * 5]; drawArgs[0] = sheepMesh.GetSubMesh(0).indexCount; drawArgs[1] = sheepCount; drawArgs[2] = 0; drawArgs[3] = 0; drawArgs[4] = 0; drawArgsBuffer.SetData(drawArgs); } // Update the ambient light. SetSHCoefficients(sheepMaterial); // Update the pass values and enqueue it. pass.Update(indexBuffer, drawArgsBuffer); renderer.EnqueuePass(pass); }
public (GraphicsBuffer, GraphicsBuffer) CreateBuffers() { var bvhBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, bvhDatas.Count, Marshal.SizeOf <BvhData>()); bvhBuffer.SetData(bvhDatas); var triangleBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, triangles.Count, Marshal.SizeOf <Triangle>()); triangleBuffer.SetData(triangles); return(bvhBuffer, triangleBuffer); }
// Update is called once per frame void Update() { m_phase += Time.fixedDeltaTime * m_motionSpeed; if (m_motionAmplitude > 0.0f) { Vector3 pos = new Vector3(0, 0, Mathf.Cos(m_phase) * m_motionAmplitude); UpdatePositions(pos + m_center); // upload the full buffer m_GPUPersistentInstanceData.SetData(m_sysmemBuffer); } }
void CreateArgumentBuffer() { uint[] args = new uint[] { 1u, // number of work groups in X dimension 1u, // number of work groups in Y dimension 1u, // number of work groups in Z dimension }; argBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, args.Length, sizeof(uint)); argBuffer.SetData(args); }
void Reallocate(int newSize) { if (m_Buffer != null) { m_Buffer.Release(); } m_Buffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, newSize, Marshal.SizeOf(typeof(CustomData))); m_Buffer.SetData(new CustomData[newSize]); var vfx = GetComponent <VisualEffect>(); vfx.SetGraphicsBuffer(s_BufferID, m_Buffer); }
public void PreRender() { if (fragmentLinkBuffer == null || startOffsetBuffer == null || startOffsetBuffer.count != resetTable.Length) { return; } //reset StartOffsetBuffer to zeros startOffsetBuffer.SetData(resetTable); // set buffers for rendering Graphics.SetRandomWriteTarget(1, fragmentLinkBuffer); Graphics.SetRandomWriteTarget(2, startOffsetBuffer); }
private void LateUpdate() { _bufferWithArgs = new GraphicsBuffer(GraphicsBuffer.Target.Structured, 4, 12); _bufferWithArgs.SetData(new List <Vector3> { new float3(-1, 0, 0), new float3(0, 1, 0), new float3(1, 0, 0), new float3(2, 0, 0), }); var materialPropertyBlock = new MaterialPropertyBlock(); materialPropertyBlock.SetBuffer("_AllInstancesTransformBuffer", _bufferWithArgs); Graphics.DrawMeshInstancedProcedural(Mesh, 0, Material, new Bounds(Vector3.zero, Vector3.one * 200), 4, materialPropertyBlock); }
public void Initialize() { if (isInitialized) { return; } GetRenderData(positionData.GetNumPositions(), out indices, out numVertices, out numThreads); int numPositions = positionData.GetNumPositions(); indexBuffer = new ComputeBuffer(indices.Length, sizeof(int)); indexBuffer.SetData(indices); indexBufferGraphics = new GraphicsBuffer(GraphicsBuffer.Target.Index, indices.Length, sizeof(int)); indexBufferGraphics.SetData(indices); isInitialized = true; }
private void CreateBuffer() { ReleaseBuffer(); if (m_TargetCSV == null) { return; } var data = CreateDataFromCSV(m_TargetCSV.text, Allocator.Temp); if (data.Length > 0) { m_Buffer = new GraphicsBuffer(GraphicsBuffer.Target.Constant, data.Length * 4, 4); m_Buffer.SetData <Vector4>(data); } data.Dispose(); }
public void Draw(float[] mask, int width, int height) { if (mask == null) { ApplyMaterial(_prevMaterial); return; } if (mask.Length != width * height) { throw new ArgumentException("mask size must equal width * height"); } ApplyMaterial(_material); _maskBuffer.SetData(mask); }
void Update() { // Update vertices. Quaternion rotation = Quaternion.Euler(0, 0, 360 / 8f * Time.deltaTime); for (int v = 0; v < _vertices.Length; v++) { Vertex vert = _vertices[v]; vert.position = rotation * vert.position; _vertices[v] = vert; } // Apply to mesh. _vertexBuffer.SetData(_vertices); // Draw. Graphics.DrawMesh(_mesh, Matrix4x4.identity, material, gameObject.layer); }
void Awake() { int vertexCount = 3; // Create vertices. _vertices = new Vertex[] { new Vertex() { position = Quaternion.AngleAxis(0 / 3f * 360, Vector3.forward) * Vector3.up * 0.5f, normal = Vector3.back }, new Vertex() { position = Quaternion.AngleAxis(2 / 3f * 360, Vector3.forward) * Vector3.up * 0.5f, normal = Vector3.back }, new Vertex() { position = Quaternion.AngleAxis(1 / 3f * 360, Vector3.forward) * Vector3.up * 0.5f, normal = Vector3.back }, }; // Create mesh. _mesh = new Mesh(); _mesh.name = GetType().Name; _mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 1000); _mesh.SetVertexBufferParams( vertexCount: 3, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3), new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, 3) ); _mesh.SetIndexBufferParams(indexCount: vertexCount, IndexFormat.UInt32); _mesh.SetSubMesh(index: 0, new SubMeshDescriptor(indexStart: 0, vertexCount), MeshUpdateFlags.DontRecalculateBounds); // Access Graphic buffers as raw data. _mesh.indexBufferTarget |= GraphicsBuffer.Target.Raw; _mesh.vertexBufferTarget |= GraphicsBuffer.Target.Raw; // Get GraphicBuffers (Mesh will create them internally). _indexBuffer = _mesh.GetIndexBuffer(); _vertexBuffer = _mesh.GetVertexBuffer(index: 0); // Set initial mesh data. _indexBuffer.SetData(new int[] { 0, 1, 2 }); _vertexBuffer.SetData(_vertices); }
void Awake() { _material = new Material(Shader.Find("Hidden/" + GetType().Name)); _buffer = new ComputeBuffer(vertCount, sizeof(float) * 4); _drawArgsBuffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments); // vertex count per instance, instance count, start vertex location, and start instance location _drawArgsBuffer.SetData(new int[] { 6, 1, 0, 0 }); //indices count _indexBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Index, 6, sizeof(short)); _indexBuffer.SetData(new short[] { 0, 1, 2, 0, 2, 3 }); _computeShader = Instantiate(Resources.Load <ComputeShader>(GetType().Name)); _awakeKernel = _computeShader.FindKernel("Awake"); _updateKernel = _computeShader.FindKernel("Update"); _computeShader.SetBuffer(_awakeKernel, ShaderIDs.buffer, _buffer); _computeShader.SetBuffer(_updateKernel, ShaderIDs.buffer, _buffer); _material.SetBuffer(ShaderIDs.buffer, _buffer); _computeShader.Dispatch(_awakeKernel, vertCount, 1, 1); }
int CreateBuffer(float[] _datas, out GraphicsBuffer _buffer) { int len = Mathf.NextPowerOfTwo(_datas.Length); BitonicSortData[] stream = new BitonicSortData[len]; for (int i = 0; i < _datas.Length; ++i) { stream[i].index = (uint)i; stream[i].key = _datas[i]; } for (int i = _datas.Length; i < len; ++i) { stream[i].index = (uint)i; stream[i].key = MIN_FLOAT; } _buffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, len, System.Runtime.InteropServices.Marshal.SizeOf(stream[0])); _buffer.SetData(stream); return(len); }
void ResetGraphicsBuffer(int nodeSize) { ConsumeNodeList.SetCounterValue(0); AppendNodeList.SetCounterValue(0); AppendFinalNodeList.SetCounterValue(0); QuadTreeNode[] nodes = new QuadTreeNode[nodeSize * nodeSize]; int index = 0; for (int i = 0; i < nodeSize; ++i) { for (int j = 0; j < nodeSize; ++j) { nodes[index].x = (uint)j; nodes[index].y = (uint)i; ++index; } } ConsumeNodeList.SetData(nodes); ConsumeNodeList.SetCounterValue((uint)nodes.Length); }
void GeneratePerlinGradTexture(byte[] perm) { int[] GRADIENT2 = new int[] { 0, 1, 1, 1, 1, 0, 1, -1, 0, -1, -1, -1, -1, 0, -1, 1, }; int bufferCount = BufferCount(); int[] datas = new int[bufferCount]; for (int y = 0; y < SIZE; ++y) { int gradIdxY = perm[y] & 0x07; // remap [-1,1] -> [0, 2] int B = (GRADIENT2[gradIdxY * 2 + 0] + 1); int A = (GRADIENT2[gradIdxY * 2 + 1] + 1); for (int x = 0; x < SIZE; ++x) { int gradIdxX = perm[x] & 0x07; // remap [-1,1] -> [0, 2] int R = (GRADIENT2[gradIdxX * 2 + 0] + 1); int G = (GRADIENT2[gradIdxX * 2 + 1] + 1); int index = y * SIZE + x; datas[index] = ((R << 24) | (G << 16) | (B << 8) | (A)); } } PerlinGrad.SetData(datas); }
static private bool getArgBuffer(Mesh mesh, out GraphicsBuffer argBuffer) { argBuffer = null; if (mesh == null) { return(false); } // Indirect args uint[] args = new uint[] { (uint)mesh.GetIndexCount(0), // index count per instance (uint)1, // instance count (uint)mesh.GetIndexStart(0), // start index location (uint)mesh.GetBaseVertex(0), // base vertex location (uint)0 // start instance location }; argBuffer = new GraphicsBuffer(GraphicsBuffer.Target.IndirectArguments, args.Length, sizeof(uint)); argBuffer.SetData(args); return(true); }
void CreateParticleBuffer() { particleBuffer = new GraphicsBuffer(GraphicsBuffer.Target.Structured, particleCount, Marshal.SizeOf <Particle>()); var datas = new NativeArray <Particle>(particleCount, Allocator.Temp); for (var i = 0; i < particleCount; ++i) { var randomVector = new Vector3(Random.value, Random.value, Random.value); var pos = Vector3.Scale(randomVector, spawnBounds.size) + spawnBounds.min; datas[i] = new Particle() { poision = pos, color = Color.Lerp(Color.gray, Color.white, Random.value), randState = (uint)i + 1 // not allow 0 }; } particleBuffer.SetData(datas); datas.Dispose(); }
// Start is called before the first frame update void Start() { m_BatchRendererGroup = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero); #if ENABLE_PICKING m_PickingMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/BRGPicking"); m_BatchRendererGroup.SetPickingMaterial(m_PickingMaterial); #endif #if ENABLE_ERROR_LOADING_MATERIALS if (SetFallbackMaterialsOnStart) { m_ErrorMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/MaterialError"); m_BatchRendererGroup.SetErrorMaterial(m_ErrorMaterial); m_LoadingMaterial = LoadMaterialWithHideAndDontSave("Hidden/HDRP/MaterialLoading"); m_BatchRendererGroup.SetLoadingMaterial(m_LoadingMaterial); } #endif // Create a batch... var renderers = FindObjectsOfType <MeshRenderer>(); Debug.Log("Converting " + renderers.Length + " renderers..."); m_renderers = new NativeArray <DrawRenderer>(renderers.Length, Allocator.Persistent); m_batchHash = new NativeHashMap <DrawKey, int>(1024, Allocator.Persistent); m_rangeHash = new NativeHashMap <RangeKey, int>(1024, Allocator.Persistent); m_drawBatches = new NativeList <DrawBatch>(Allocator.Persistent); m_drawRanges = new NativeList <DrawRange>(Allocator.Persistent); // Fill the GPU-persistent scene data ComputeBuffer int bigDataBufferVector4Count = 4 /*zero*/ + 1 /*probes*/ + 1 /*speccube*/ + 7 /*SH*/ + m_renderers.Length * 3 * 2 /*per renderer 4x3 matrix+inverse*/; var vectorBuffer = new NativeArray <Vector4>(bigDataBufferVector4Count, Allocator.Temp); // First 4xfloat4 of ComputeBuffer needed to be zero filled for default property fall back! vectorBuffer[0] = new Vector4(0, 0, 0, 0); vectorBuffer[1] = new Vector4(0, 0, 0, 0); vectorBuffer[2] = new Vector4(0, 0, 0, 0); vectorBuffer[3] = new Vector4(0, 0, 0, 0); var startOffset = 4; // Fill global data (shared between all batches) var probesOcclusionOffset = startOffset; vectorBuffer[probesOcclusionOffset] = new Vector4(1, 1, 1, 1); startOffset++; var specCubeOffset = startOffset; vectorBuffer[specCubeOffset] = ReflectionProbe.defaultTextureHDRDecodeValues; startOffset++; var SHOffset = startOffset; var SH = new SHProperties(RenderSettings.ambientProbe); vectorBuffer[SHOffset + 0] = SH.SHAr; vectorBuffer[SHOffset + 1] = SH.SHAg; vectorBuffer[SHOffset + 2] = SH.SHAb; vectorBuffer[SHOffset + 3] = SH.SHBr; vectorBuffer[SHOffset + 4] = SH.SHBg; vectorBuffer[SHOffset + 5] = SH.SHBb; vectorBuffer[SHOffset + 6] = SH.SHC; startOffset += 7; var localToWorldOffset = startOffset; var worldToLocalOffset = localToWorldOffset + m_renderers.Length * 3; m_instances = new NativeList <DrawInstance>(1024, Allocator.Persistent); for (int i = 0; i < renderers.Length; i++) { var renderer = renderers[i]; m_renderers[i] = new DrawRenderer { bounds = new AABB { Center = new float3(0, 0, 0), Extents = new float3(0, 0, 0) } }; var meshFilter = renderer.gameObject.GetComponent <MeshFilter>(); if (!renderer || !meshFilter || !meshFilter.sharedMesh || renderer.enabled == false) { continue; } // Disable the existing Unity MeshRenderer to avoid double rendering! renderer.enabled = false; /* mat4x3 packed like this: * p1.x, p1.w, p2.z, p3.y, * p1.y, p2.x, p2.w, p3.z, * p1.z, p2.y, p3.x, p3.w, * 0.0, 0.0, 0.0, 1.0 */ var m = renderer.transform.localToWorldMatrix; vectorBuffer[i * 3 + 0 + localToWorldOffset] = new Vector4(m.m00, m.m10, m.m20, m.m01); vectorBuffer[i * 3 + 1 + localToWorldOffset] = new Vector4(m.m11, m.m21, m.m02, m.m12); vectorBuffer[i * 3 + 2 + localToWorldOffset] = new Vector4(m.m22, m.m03, m.m13, m.m23); var mi = renderer.transform.worldToLocalMatrix; vectorBuffer[i * 3 + 0 + worldToLocalOffset] = new Vector4(mi.m00, mi.m10, mi.m20, mi.m01); vectorBuffer[i * 3 + 1 + worldToLocalOffset] = new Vector4(mi.m11, mi.m21, mi.m02, mi.m12); vectorBuffer[i * 3 + 2 + worldToLocalOffset] = new Vector4(mi.m22, mi.m03, mi.m13, mi.m23); // Renderer bounds var transformedBounds = AABB.Transform(m, meshFilter.sharedMesh.bounds.ToAABB()); m_renderers[i] = new DrawRenderer { bounds = transformedBounds }; var mesh = m_BatchRendererGroup.RegisterMesh(meshFilter.sharedMesh); var sharedMaterials = new List <Material>(); renderer.GetSharedMaterials(sharedMaterials); var shadows = renderer.shadowCastingMode; for (int matIndex = 0; matIndex < sharedMaterials.Count; matIndex++) { var material = m_BatchRendererGroup.RegisterMaterial(sharedMaterials[matIndex]); var key = new DrawKey { material = material, meshID = mesh, submeshIndex = (uint)matIndex, shadows = shadows }; #if ENABLE_PICKING key.pickableObjectInstanceID = renderer.gameObject.GetInstanceID(); #endif var drawBatch = new DrawBatch { key = key, instanceCount = 0, instanceOffset = 0 }; m_instances.Add(new DrawInstance { key = key, instanceIndex = i }); int drawBatchIndex; if (m_batchHash.TryGetValue(key, out drawBatchIndex)) { drawBatch = m_drawBatches[drawBatchIndex]; } else { drawBatchIndex = m_drawBatches.Length; m_drawBatches.Add(drawBatch); m_batchHash[key] = drawBatchIndex; // Different renderer settings? -> new range var rangeKey = new RangeKey { shadows = shadows }; var drawRange = new DrawRange { key = rangeKey, drawCount = 0, drawOffset = 0, }; int drawRangeIndex; if (m_rangeHash.TryGetValue(rangeKey, out drawRangeIndex)) { drawRange = m_drawRanges[drawRangeIndex]; } else { drawRangeIndex = m_drawRanges.Length; m_drawRanges.Add(drawRange); m_rangeHash[rangeKey] = drawRangeIndex; } drawRange.drawCount++; m_drawRanges[drawRangeIndex] = drawRange; } drawBatch.instanceCount++; m_drawBatches[drawBatchIndex] = drawBatch; } } m_GPUPersistentInstanceData = new GraphicsBuffer(GraphicsBuffer.Target.Raw, (int)bigDataBufferVector4Count * 16 / 4, 4); m_GPUPersistentInstanceData.SetData(vectorBuffer); Debug.Log("DrawRanges: " + m_drawRanges.Length + ", DrawBatches: " + m_drawBatches.Length + ", Instances: " + m_instances.Length); // Prefix sum to calculate draw offsets for each DrawRange int prefixSum = 0; for (int i = 0; i < m_drawRanges.Length; i++) { var drawRange = m_drawRanges[i]; drawRange.drawOffset = prefixSum; m_drawRanges[i] = drawRange; prefixSum += drawRange.drawCount; } // Generate draw index ranges for each DrawRange m_drawIndices = new NativeArray <int>(m_drawBatches.Length, Allocator.Persistent); var m_internalRangeIndex = new NativeArray <int>(m_drawRanges.Length, Allocator.Temp); for (int i = 0; i < m_drawBatches.Length; i++) { var draw = m_drawBatches[i]; if (m_rangeHash.TryGetValue(new RangeKey { shadows = draw.key.shadows }, out int drawRangeIndex)) { var drawRange = m_drawRanges[drawRangeIndex]; m_drawIndices[drawRange.drawOffset + m_internalRangeIndex[drawRangeIndex]] = i; m_internalRangeIndex[drawRangeIndex]++; } } m_internalRangeIndex.Dispose(); // Prefix sum to calculate instance offsets for each DrawCommand prefixSum = 0; for (int i = 0; i < m_drawBatches.Length; i++) { // DrawIndices remap to get DrawCommands ordered by DrawRange var remappedIndex = m_drawIndices[i]; var drawBatch = m_drawBatches[remappedIndex]; drawBatch.instanceOffset = prefixSum; m_drawBatches[remappedIndex] = drawBatch; prefixSum += drawBatch.instanceCount; } // Generate instance index ranges for each DrawCommand m_instanceIndices = new NativeArray <int>(m_instances.Length, Allocator.Persistent); var m_internalDrawIndex = new NativeArray <int>(m_drawBatches.Length, Allocator.Temp); for (int i = 0; i < m_instances.Length; i++) { var instance = m_instances[i]; if (m_batchHash.TryGetValue(instance.key, out int drawBatchIndex)) { var drawBatch = m_drawBatches[drawBatchIndex]; m_instanceIndices[drawBatch.instanceOffset + m_internalDrawIndex[drawBatchIndex]] = instance.instanceIndex; m_internalDrawIndex[drawBatchIndex]++; } } m_internalDrawIndex.Dispose(); // Bounds ("infinite") UnityEngine.Bounds bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(1048576.0f, 1048576.0f, 1048576.0f)); m_BatchRendererGroup.SetGlobalBounds(bounds); // Batch metadata buffer... // Per instance data int objectToWorldID = Shader.PropertyToID("unity_ObjectToWorld"); int worldToObjectID = Shader.PropertyToID("unity_WorldToObject"); int colorID = Shader.PropertyToID("_BaseColor"); // Global data (should be moved to C++ side) int probesOcclusionID = Shader.PropertyToID("unity_ProbesOcclusion"); int specCubeID = Shader.PropertyToID("unity_SpecCube0_HDR"); int SHArID = Shader.PropertyToID("unity_SHAr"); int SHAgID = Shader.PropertyToID("unity_SHAg"); int SHAbID = Shader.PropertyToID("unity_SHAb"); int SHBrID = Shader.PropertyToID("unity_SHBr"); int SHBgID = Shader.PropertyToID("unity_SHBg"); int SHBbID = Shader.PropertyToID("unity_SHBb"); int SHCID = Shader.PropertyToID("unity_SHC"); var batchMetadata = new NativeArray <MetadataValue>(11, Allocator.Temp); batchMetadata[0] = CreateMetadataValue(objectToWorldID, localToWorldOffset * UnsafeUtility.SizeOf <Vector4>(), true); batchMetadata[1] = CreateMetadataValue(worldToObjectID, worldToLocalOffset * UnsafeUtility.SizeOf <Vector4>(), true); batchMetadata[2] = CreateMetadataValue(probesOcclusionID, probesOcclusionOffset * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[3] = CreateMetadataValue(specCubeID, specCubeOffset * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[4] = CreateMetadataValue(SHArID, (SHOffset + 0) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[5] = CreateMetadataValue(SHAgID, (SHOffset + 1) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[6] = CreateMetadataValue(SHAbID, (SHOffset + 2) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[7] = CreateMetadataValue(SHBrID, (SHOffset + 3) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[8] = CreateMetadataValue(SHBgID, (SHOffset + 4) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[9] = CreateMetadataValue(SHBbID, (SHOffset + 5) * UnsafeUtility.SizeOf <Vector4>(), false); batchMetadata[10] = CreateMetadataValue(SHCID, (SHOffset + 6) * UnsafeUtility.SizeOf <Vector4>(), false); // Register batch m_batchID = m_BatchRendererGroup.AddBatch(batchMetadata, m_GPUPersistentInstanceData.bufferHandle); m_initialized = true; }
// Start is called before the first frame update void Start() { m_BatchRendererGroup = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero); int itemCount = itemGridSize * itemGridSize; m_itemCount = itemCount; // Bounds UnityEngine.Bounds bounds = new Bounds(new Vector3(0, 0, 0), new Vector3(1048576.0f, 1048576.0f, 1048576.0f)); m_BatchRendererGroup.SetGlobalBounds(bounds); // Register mesh and material if (m_mesh) { m_meshID = m_BatchRendererGroup.RegisterMesh(m_mesh); } if (m_material) { m_materialID = m_BatchRendererGroup.RegisterMaterial(m_material); } // Batch metadata buffer int objectToWorldID = Shader.PropertyToID("unity_ObjectToWorld"); int matrixPreviousMID = Shader.PropertyToID("unity_MatrixPreviousM"); int worldToObjectID = Shader.PropertyToID("unity_WorldToObject"); int colorID = Shader.PropertyToID("_BaseColor"); // Generate a grid of objects... int bigDataBufferVector4Count = 4 + itemCount * (3 * 3 + 1); // 4xfloat4 zero + per instance = { 3x mat4x3, 1x float4 color } m_sysmemBuffer = new NativeArray <Vector4>(bigDataBufferVector4Count, Allocator.Persistent, NativeArrayOptions.ClearMemory); m_GPUPersistentInstanceData = new GraphicsBuffer(GraphicsBuffer.Target.Raw, (int)bigDataBufferVector4Count * 16 / 4, 4); // 64 bytes of zeroes, so loads from address 0 return zeroes. This is a BatchRendererGroup convention. int positionOffset = 4; m_sysmemBuffer[0] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[1] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[2] = new Vector4(0, 0, 0, 0); m_sysmemBuffer[3] = new Vector4(0, 0, 0, 0); // Matrices UpdatePositions(m_center); // Colors int colorOffset = positionOffset + itemCount * 3 * 3; for (int i = 0; i < itemCount; i++) { Color col = Color.HSVToRGB(((float)(i) / (float)itemCount) % 1.0f, 1.0f, 1.0f); // write colors right after the 4x3 matrices m_sysmemBuffer[colorOffset + i] = new Vector4(col.r, col.g, col.b, 1.0f); } m_GPUPersistentInstanceData.SetData(m_sysmemBuffer); var batchMetadata = new NativeArray <MetadataValue>(4, Allocator.Temp, NativeArrayOptions.UninitializedMemory); batchMetadata[0] = CreateMetadataValue(objectToWorldID, 64, true); // matrices batchMetadata[1] = CreateMetadataValue(matrixPreviousMID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3, true); // previous matrices batchMetadata[2] = CreateMetadataValue(worldToObjectID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3 * 2, true); // inverse matrices batchMetadata[3] = CreateMetadataValue(colorID, 64 + itemCount * UnsafeUtility.SizeOf <Vector4>() * 3 * 3, true); // colors // Register batch m_batchID = m_BatchRendererGroup.AddBatch(batchMetadata, m_GPUPersistentInstanceData.bufferHandle); m_initialized = true; }
public void TestComputeShader(Vector3 postion, float[] heightmap) { Init_perm(0); int f_sizeX = 10; int f_sizeZ = 10; int perMeterX = 4; int perMeterZ = 4; int voxelOffset_x = 10; int voxelOffset_y = 10; Heightmap = heightmap; intermediate = new Plant[f_sizeX * perMeterX * f_sizeZ * perMeterZ]; int indexBuff_size = f_sizeX * perMeterX * f_sizeZ * perMeterZ * 8 * 3; Debug.Log("indexBuff_size: " + indexBuff_size); vertexData = new VertexData[indexBuff_size]; indices = GenIndices(f_sizeX * perMeterX, f_sizeZ * perMeterZ); ComputeBuffer buffer = new ComputeBuffer(heightmap.Length, sizeof(float)); buffer.SetData(heightmap); ComputeBuffer output_buff = new ComputeBuffer(intermediate.Length, Plant.GetSize()); output_buff.SetData(intermediate); //ComputeBuffer g_buff = new ComputeBuffer(indexBuff_size, sizeof(int)); GraphicsBuffer g_buff = new GraphicsBuffer(GraphicsBuffer.Target.Index, indices.Length, sizeof(int)); g_buff.SetData(indices); ComputeBuffer v_buff = new ComputeBuffer(indexBuff_size, VertexData.GetSize()); v_buff.SetData(vertexData); int k = shader.FindKernel("CSMain"); int c_k = shader.FindKernel("CompileMesh"); shader.SetInt("sizeX", SmoothVoxelSettings.ChunkSizeX); shader.SetInt("sizeZ", SmoothVoxelSettings.ChunkSizeZ); shader.SetInt("f_sizeX", f_sizeX); shader.SetInt("f_sizeZ", f_sizeZ); shader.SetInt("perMeterX", perMeterX); shader.SetInt("perMeterZ", perMeterZ); shader.SetInt("voxel_offset_x", voxelOffset_x); shader.SetInt("voxel_offset_z", voxelOffset_y); shader.SetBuffer(k, "heightmap", buffer); shader.SetBuffer(k, "intermediate", output_buff); shader.SetBuffer(c_k, "intermediate", output_buff); //shader.SetBuffer(c_k, "indices", g_buff); shader.SetBuffer(c_k, "vertex", v_buff); shader.Dispatch(k, f_sizeX * 4, 1, f_sizeZ * 4); shader.Dispatch(c_k, 1, 1, 1); v_buff.GetData(vertexData); g_buff.GetData(indices); verts = new List <Vector3>(); uv = new List <Vector2>(); normals = new List <Vector3>(); for (int i = 0; i < indexBuff_size; i++) { verts.Add(vertexData[i].Vertex); uv.Add(vertexData[i].UV); normals.Add(vertexData[i].Normal); } rend = GetComponent <MeshRenderer>(); rend.material.SetPass(0); rend.material.SetBuffer("_Vertex", v_buff); rend.material.SetTexture("_permutation", perm_tex); MeshFilter filter = gameObject.GetComponent <MeshFilter>(); Mesh mesh = new Mesh(); mesh.vertices = new Vector3[indexBuff_size];//verts.ToArray(); mesh.triangles = indices; //mesh.uv = uv.ToArray(); Vector3 corner = postion; //new Bounds() Bounds b = new Bounds(corner + new Vector3(SmoothVoxelSettings.MeterSizeX / 2 - 0.5f, SmoothVoxelSettings.MeterSizeY / 2 - 0.5f, SmoothVoxelSettings.MeterSizeZ / 2 - 0.5f), new Vector3(SmoothVoxelSettings.MeterSizeX + 1, SmoothVoxelSettings.MeterSizeY + 1, SmoothVoxelSettings.MeterSizeZ + 1)); mesh.bounds = b; filter.sharedMesh = mesh; inited = true; //Vector3 corner = postion + new Vector3(voxelOffset_x, 0, voxelOffset_y); //Bounds b = new Bounds(corner + new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2), new Vector3(f_sizeX / 2, SmoothVoxelSettings.ChunkSizeY / 2, f_sizeZ / 2)); //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, indexBuff_size); // Graphics.DrawProceduralIndirect(rend.material, b, MeshTopology.Triangles, g_buff); //Graphics.DrawProcedural(rend.material, b, MeshTopology.Triangles, g_buff, indices.Length); return; output_buff.GetData(intermediate); List <int> tris = new List <int>(); for (int x = 0; x < f_sizeX * 4; x++) { for (int z = 0; z < f_sizeZ * 4; z++) { Plant res = intermediate[x * (f_sizeZ * 4) + z]; int offset = verts.Count; verts.AddRange(res.q1.GetVerts()); tris.AddRange(res.q1.GetTris(offset)); uv.AddRange(res.q1.GetUVs()); verts.AddRange(res.q2.GetVerts()); tris.AddRange(res.q2.GetTris(offset)); uv.AddRange(res.q2.GetUVs()); verts.AddRange(res.q3.GetVerts()); tris.AddRange(res.q3.GetTris(offset)); uv.AddRange(res.q3.GetUVs()); //Debug.DrawRay(verts[0], res.normal, Color.green, 1000000); //Debug.Log("|" + res.q1.ToString() + " " + res.q2.ToString() + " " + res.q3.ToString() + " | "); //Vector4 res = output[x * (20 * 4) + z]; //Vector3 normal = res; //float height = res.w; //Vector3 point = new Vector3(x / 4f, height, z / 4f); //Debug.DrawRay(point, normal, Color.green, 1000000); /*if (x % 8 == 0 && * z % 8 == 0) * { * Vector3 t1 = GetTangent(normal, Vector3.forward); * Vector3 t2 = GetTangent(normal, Vector3.right); * * Quaternion q1 = Quaternion.LookRotation(normal, Vector3.up); * //Quaternion q2 = Quaternion.LookRotation(t2, Vector3.up); * * * * Debug.DrawRay(point, normal, Color.green, 1000000); * //Debug.DrawRay(point, t1, Color.blue, 1000000); * //Debug.DrawRay(point, t2, Color.red, 1000000); * //Quaternion quat = q1 * q2; * //Instantiate(obj, point, q1); * }*/ } } Debug.Log("Num tris: " + tris.Count); mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.uv = uv.ToArray(); mesh.RecalculateNormals(); filter.sharedMesh = mesh; }