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); }
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 } } })); }; }