private void DispatchComputeShader(IRayCastingCamera camera) { var width = camera.Width; var height = camera.Height; var threadGroupSizeX = width / (int)threadsPerThreadGroup.x; var threadGroupSizeY = height / (int)threadsPerThreadGroup.y; // We diving from THREAD_PER_GROUP, because here we specify not the total thread count, but thread group count. shaderForRayCasting.Dispatch(kernelIndexOfMain, threadGroupSizeX, threadGroupSizeY, 1); }
// TODO: Cache. private void SetAllPropertiesForShader(IRayCastingCamera camera) { var bodyManager = RayCastingBodyManager.Instance; // All this data came from body manager. shaderForRayCasting.SetBuffer(kernelIndexOfMain, "vertexDataBuffer", vertexDataBuffer); shaderForRayCasting.SetBuffer(kernelIndexOfMain, "triangleDataBuffer", triangleDataBuffer); shaderForRayCasting.SetBuffer(kernelIndexOfMain, "meshDataBuffer", meshDataBuffer); shaderForRayCasting.SetBuffer(kernelIndexOfMain, "bodyDataBuffer", bodyDataBuffer); shaderForRayCasting.SetInt("bodyDataCount", bodyManager.BodyCount); // This data came from camera. shaderForRayCasting.SetBuffer(kernelIndexOfMain, "rayDataBuffer", rayDataBuffer); shaderForRayCasting.SetInt("width", camera.Width); shaderForRayCasting.SetInt("height", camera.Height); shaderForRayCasting.SetTexture(kernelIndexOfMain, "renderTarget", camera.RenderTarget); shaderForRayCasting.SetVector("backgroundColor", camera.BackgroundColor); }
private void SetDataForRayDataBuffer(IRayCastingCamera camera) { // There could be multiple resolution cameras, so in this function we decide if we need bigger buffer. var width = camera.Width; var height = camera.Height; var totalPixelCount = width * height; if (rayDataBuffer == null || rayDataBuffer.count < totalPixelCount) { rayDataBuffer = new ComputeBuffer(totalPixelCount, Marshal.SizeOf(typeof(RayCastingRayData))); } if (rayDataBuffer != null && rayDataBuffer.count < totalPixelCount) { rayDataBuffer.Release(); rayDataBuffer = new ComputeBuffer(totalPixelCount, Marshal.SizeOf(typeof(RayCastingRayData))); } rayDataBuffer.SetData(camera.RayDatas); }
public void Render(IRayCastingCamera camera) { Debug.Assert(camera != null); // TODO: Execute in different threads, these tasks area really cpu-heavy. // Update all compute buffers with mesh data. var bodyManager = RayCastingBodyManager.Instance; // We use singleton, because unity allows only one scene at the time. bodyManager.CalculateBodies(); // Update all rays that will be used for casting. camera.CalculateRays(); // Update all compute buffers with calulcate information on GPU. UpdateComputeBuffers(camera); // Update shader properties, with updated compute buffers. SetAllPropertiesForShader(camera); // Run shader on gpu. DispatchComputeShader(camera); }
private void UpdateComputeBuffers(IRayCastingCamera camera) { var bodyManager = RayCastingBodyManager.Instance; // Lets check if we don't exceed the buffer capcities. Debug.Assert(bodyDataBuffer.count >= bodyManager.BodyDataList.Count, "There is to many bodies, you can change the maximum value in this script"); Debug.Assert(vertexDataBuffer.count >= bodyManager.VertexDataList.Count, "There is to many vertices, you can change the maximum value in this script"); Debug.Assert(triangleDataBuffer.count >= bodyManager.TriangleDataList.Count, "There is to many triangles, you can change the maximum value in this script"); Debug.Assert(meshDataBuffer.count >= bodyManager.MeshDataList.Count, "There is to many meshes, you can change the maximum value in this script"); // Update the buffers on gpu. SetDataForRayDataBuffer(camera); // TODO: make other buffers resizable too. bodyDataBuffer.SetData(bodyManager.BodyDataList.ToArray()); vertexDataBuffer.SetData(bodyManager.VertexDataList.ToArray()); triangleDataBuffer.SetData(bodyManager.TriangleDataList.ToArray()); meshDataBuffer.SetData(bodyManager.MeshDataList.ToArray()); }