public async Task <float[]> Generate(Mesh mesh, string outBufferName, int outBufferStrideInFloat, int outBufferCount, Dictionary <string, ComputeBuffer> additionalComputeBuffers = null, bool meshMustbeUniquefied = true)
        {
            // UWAGA. Program shadera uruchamiany po raz dla każdego trójkąta
            if (meshMustbeUniquefied)
            {
                Preconditions.Assert(mesh.vertices.Length == mesh.triangles.Length,
                                     $"Vertices count (${mesh.vertices.Length}) is not equal to triangles array count (${mesh.triangles.Length}). Vertices are most propably shared. Uniquefy them!");
            }

            if (additionalComputeBuffers == null)
            {
                additionalComputeBuffers = new Dictionary <string, ComputeBuffer>();
            }

            var parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader barycentricGeneratorShader =
                new MultistepComputeShader(ComputeShaderUtils.LoadComputeShader(_shaderName), new IntVector2(mesh.triangles.Length / 3, 1));

            var kernel     = barycentricGeneratorShader.AddKernel("CS_Main");
            var allKernels = new List <MyKernelHandle>()
            {
                kernel
            };

            var triangleBufferTemplate = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                BufferData = mesh.triangles,
                Count      = mesh.triangles.Length,
                Stride     = sizeof(int),
                Type       = ComputeBufferType.Default
            });

            barycentricGeneratorShader.SetBuffer("Triangles", triangleBufferTemplate, allKernels);

            var vertexBufferTemplate = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                BufferData = mesh.vertices,
                Count      = mesh.vertices.Length,
                Stride     = sizeof(float) * 3,
                Type       = ComputeBufferType.Default
            });

            barycentricGeneratorShader.SetBuffer("Vertices", vertexBufferTemplate, allKernels);

            var normalsBufferTemplate = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                BufferData = mesh.normals,
                Count      = mesh.normals.Length,
                Stride     = sizeof(float) * 3,
                Type       = ComputeBufferType.Default
            });

            barycentricGeneratorShader.SetBuffer("Normals", normalsBufferTemplate, allKernels);

            var outBarycentricBufferTemplate = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = outBufferCount,
                Stride = sizeof(float) * outBufferStrideInFloat,
                Type   = ComputeBufferType.Default
            });

            barycentricGeneratorShader.SetBuffer(outBufferName, outBarycentricBufferTemplate, allKernels);

            foreach (var pair in additionalComputeBuffers)
            {
                var id = parametersContainer.AddExistingComputeBuffer(pair.Value);
                barycentricGeneratorShader.SetBuffer(pair.Key, id, allKernels);
            }

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(new List <MyComputeBufferId> {
                outBarycentricBufferTemplate
            });
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = barycentricGeneratorShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = allKernels
                            }
                        }
                    },
                }
            });

            DebugCheckVariables.Check(outParameters);
            float[] outArray = new float[outBufferStrideInFloat * outBufferCount];
            outParameters.CreatedBuffers[outBarycentricBufferTemplate].GetData(outArray);
            return(outArray);
        }
Esempio n. 2
0
        private void GenerateShaderOrderTemplates(ComputeBuffer ePyramidPerFrameParametersBuffer, ComputeBuffer ePyramidConfigurationBuffer,
                                                  Texture heightmapArray)
        {
            _localeBufferUpdaterShaderOrderGenerator = (ordersCount, travellerPositionWorldSpace) =>
            {
                MultistepComputeShader localeBufferUpdateShader = new MultistepComputeShader(_eTerrainComputeShader, new IntVector2(ordersCount, 1));

                ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer()
                {
                };
                var scopesUpdateOrdersBufferId = parametersContainer.AddExistingComputeBuffer(_scopesUpdateOrdersBuffer);
                var ePropLocalBufferId         = parametersContainer.AddExistingComputeBuffer(_ePropLocaleBuffer);
                var ePropIdsBuffer             = parametersContainer.AddExistingComputeBuffer(_ePropIdsBuffer);

                var kernel        = localeBufferUpdateShader.AddKernel("CSETerrain_LocaleBufferUpdater");
                var kernelHandles = new List <MyKernelHandle>()
                {
                    kernel
                };
                localeBufferUpdateShader.SetBuffer("_ScopesUpdateOrdersBuffer", scopesUpdateOrdersBufferId, kernelHandles);
                localeBufferUpdateShader.SetBuffer("_EPropLocaleBuffer", ePropLocalBufferId, kernelHandles);
                localeBufferUpdateShader.SetBuffer("_EPropIdsBuffer", ePropIdsBuffer, kernelHandles);

                var ePyramidPerFrameParametersBufferId = parametersContainer.AddExistingComputeBuffer(ePyramidPerFrameParametersBuffer);
                localeBufferUpdateShader.SetBuffer("_EPyramidPerFrameConfigurationBuffer", ePyramidPerFrameParametersBufferId, kernelHandles);

                var ePyramidConfigurationBufferId = parametersContainer.AddExistingComputeBuffer(ePyramidConfigurationBuffer);
                localeBufferUpdateShader.SetBuffer("_EPyramidConfigurationBuffer", ePyramidConfigurationBufferId, kernelHandles);

                localeBufferUpdateShader.SetGlobalUniform("g_ringsPerLevelCount", _constantPyramidParameters.RingsPerLevelCount);
                localeBufferUpdateShader.SetGlobalUniform("g_levelsCount", _constantPyramidParameters.LevelsCount);
                localeBufferUpdateShader.SetGlobalUniform("g_ScopeLength", _configuration.ScopeLength);
                localeBufferUpdateShader.SetGlobalUniform("g_heightScale", _constantPyramidParameters.HeightScale);

                var mapId = parametersContainer.AddExistingComputeShaderTexture(heightmapArray);
                localeBufferUpdateShader.SetTexture($"_HeightMap", mapId, kernelHandles); //todo parametrize HeightMap name

                localeBufferUpdateShader.SetGlobalUniform("g_travellerPositionWorldSpace", travellerPositionWorldSpace);

                return(_shaderExecutorObject.AddOrder(new ComputeShaderOrder()
                {
                    OutParameters = new ComputeBufferRequestedOutParameters(),
                    ParametersContainer = parametersContainer,
                    WorkPacks = new List <ComputeShaderWorkPack>()
                    {
                        new ComputeShaderWorkPack()
                        {
                            DispatchLoops = new List <ComputeShaderDispatchLoop>()
                            {
                                new ComputeShaderDispatchLoop()
                                {
                                    DispatchCount = 1,
                                    KernelHandles = kernelHandles
                                }
                            },
                            Shader = localeBufferUpdateShader
                        }
                    }
                }));
            };

            _localesCopyShaderOrderGenerator = (ordersCount) =>
            {
                MultistepComputeShader localeBufferUpdateShader =
                    new MultistepComputeShader(_eTerrainComputeShader, new IntVector2(ordersCount, 1));

                ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer()
                {
                };
                var localesCopyOrdersBufferId = parametersContainer.AddExistingComputeBuffer(_localesCopyOrdersBuffer);
                var ePropLocalBufferId        = parametersContainer.AddExistingComputeBuffer(_ePropLocaleBuffer);
                var ePropIdsBuffer            = parametersContainer.AddExistingComputeBuffer(_ePropIdsBuffer);

                var kernel        = localeBufferUpdateShader.AddKernel("CSETerrain_LocalesCopy");
                var kernelHandles = new List <MyKernelHandle>()
                {
                    kernel
                };
                localeBufferUpdateShader.SetBuffer("_LocalesCopyOrdersBuffer", localesCopyOrdersBufferId, kernelHandles);
                localeBufferUpdateShader.SetBuffer("_EPropLocaleBuffer", ePropLocalBufferId, kernelHandles);
                localeBufferUpdateShader.SetBuffer("_EPropIdsBuffer", ePropIdsBuffer, kernelHandles);

                localeBufferUpdateShader.SetGlobalUniform("g_ringsPerLevelCount", _constantPyramidParameters.RingsPerLevelCount);
                localeBufferUpdateShader.SetGlobalUniform("g_levelsCount", _constantPyramidParameters.LevelsCount);
                localeBufferUpdateShader.SetGlobalUniform("g_ScopeLength", _configuration.ScopeLength);
                localeBufferUpdateShader.SetGlobalUniform("g_heightScale", _constantPyramidParameters.HeightScale);

                return(_shaderExecutorObject.AddOrder(new ComputeShaderOrder()
                {
                    OutParameters = new ComputeBufferRequestedOutParameters(),
                    ParametersContainer = parametersContainer,
                    WorkPacks = new List <ComputeShaderWorkPack>()
                    {
                        new ComputeShaderWorkPack()
                        {
                            DispatchLoops = new List <ComputeShaderDispatchLoop>()
                            {
                                new ComputeShaderDispatchLoop()
                                {
                                    DispatchCount = 1,
                                    KernelHandles = kernelHandles
                                }
                            },
                            Shader = localeBufferUpdateShader
                        }
                    }
                }));
            };

            _localeRecalculationShaderOrderGenerator = (ordersCount, travellerPositionWorldSpace) =>
            {
                MultistepComputeShader localeBufferUpdateShader =
                    new MultistepComputeShader(_eTerrainComputeShader, new IntVector2(ordersCount, 1));

                ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer()
                {
                };

                var kernel = localeBufferUpdateShader.AddKernel("CSETerrain_LocaleRecalculate");

                var scopesUpdateOrdersBufferId = parametersContainer.AddExistingComputeBuffer(_scopesUpdateOrdersBuffer);
                var kernelHandles = new List <MyKernelHandle>()
                {
                    kernel
                };
                localeBufferUpdateShader.SetBuffer("_ScopesUpdateOrdersBuffer", scopesUpdateOrdersBufferId, kernelHandles);

                var ePropLocalBufferId = parametersContainer.AddExistingComputeBuffer(_ePropLocaleBuffer);
                localeBufferUpdateShader.SetBuffer("_EPropLocaleBuffer", ePropLocalBufferId, kernelHandles);

                var ePyramidPerFrameParametersBufferId = parametersContainer.AddExistingComputeBuffer(ePyramidPerFrameParametersBuffer);
                localeBufferUpdateShader.SetBuffer("_EPyramidPerFrameConfigurationBuffer", ePyramidPerFrameParametersBufferId, kernelHandles);

                var ePyramidConfigurationBufferId = parametersContainer.AddExistingComputeBuffer(ePyramidConfigurationBuffer);
                localeBufferUpdateShader.SetBuffer("_EPyramidConfigurationBuffer", ePyramidConfigurationBufferId, kernelHandles);

                var scopesToRecalculateBufferId = parametersContainer.AddExistingComputeBuffer(_scopesToRecalculateBuffer);
                localeBufferUpdateShader.SetBuffer("_ScopesToRecalculateBuffer", scopesToRecalculateBufferId, kernelHandles);

                localeBufferUpdateShader.SetGlobalUniform("g_ringsPerLevelCount", _constantPyramidParameters.RingsPerLevelCount);
                localeBufferUpdateShader.SetGlobalUniform("g_levelsCount", _constantPyramidParameters.LevelsCount);
                localeBufferUpdateShader.SetGlobalUniform("g_ScopeLength", _configuration.ScopeLength);
                localeBufferUpdateShader.SetGlobalUniform("g_heightScale", _constantPyramidParameters.HeightScale);

                var mapId = parametersContainer.AddExistingComputeShaderTexture(heightmapArray);
                localeBufferUpdateShader.SetTexture($"_HeightMap", mapId, kernelHandles); //todo parametrize HeightMap name

                localeBufferUpdateShader.SetGlobalUniform("g_travellerPositionWorldSpace", travellerPositionWorldSpace);

                return(_shaderExecutorObject.AddOrder(new ComputeShaderOrder()
                {
                    OutParameters = new ComputeBufferRequestedOutParameters(),
                    ParametersContainer = parametersContainer,
                    WorkPacks = new List <ComputeShaderWorkPack>()
                    {
                        new ComputeShaderWorkPack()
                        {
                            DispatchLoops = new List <ComputeShaderDispatchLoop>()
                            {
                                new ComputeShaderDispatchLoop()
                                {
                                    DispatchCount = 1,
                                    KernelHandles = kernelHandles
                                }
                            },
                            Shader = localeBufferUpdateShader
                        }
                    }
                }));
            };
        }