Beispiel #1
0
        private async Task ExecuteDispatch(int sideSize, int dispatchOffset, int slicesPerDispatch, RenderTexture texture, string kernelName)
        {
            var parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader computeShader =
                new MultistepComputeShader(ComputeShaderUtils.LoadComputeShader(_shaderName), new IntVector3(sideSize, sideSize, slicesPerDispatch));

            var kernel     = computeShader.AddKernel(kernelName);
            var allKernels = new List <MyKernelHandle>()
            {
                kernel
            };

            var newTextureId = parametersContainer.AddExistingComputeShaderTexture(texture);

            computeShader.SetGlobalUniform("g_SideSize", sideSize);
            computeShader.SetGlobalUniform("g_SlicesPerDispatch", slicesPerDispatch);
            computeShader.SetGlobalUniform("g_DispatchOffset", dispatchOffset);
            computeShader.SetTexture("_OutTexture3D", newTextureId, allKernels);

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(new List <MyComputeShaderTextureId>()
            {
                newTextureId
            }, new List <MyComputeBufferId> {
            });
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = computeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = allKernels
                            }
                        }
                    },
                }
            });
        }
Beispiel #2
0
        private void MoveSliceToBuffer(Texture buffer, Texture cube, int sideLength, int sliceIndex)
        {
            var parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader computeShader =
                new MultistepComputeShader(ComputeShaderUtils.LoadComputeShader("util_moveCubeSlice_comp"), new IntVector3(sideLength, sideLength, 1));

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

            var bufferTexId = parametersContainer.AddExistingComputeShaderTexture(buffer);
            var cubeTexId   = parametersContainer.AddExistingComputeShaderTexture(cube);

            computeShader.SetGlobalUniform("g_SliceIndex", sliceIndex);
            computeShader.SetTexture("_BufferTexture", bufferTexId, allKernels);
            computeShader.SetTexture("_CubeTexture", cubeTexId, allKernels);

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(new List <MyComputeShaderTextureId>()
            {
            }, new List <MyComputeBufferId> {
            });

            _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = computeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = allKernels
                            }
                        }
                    },
                }
            }).Wait();
        }
        public async Task <TextureWithCoords> ApplyFeatureAsync(TextureWithCoords texture,
                                                                TerrainCardinalResolution resolution, bool canMultistep)
        {
            ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer();
            IntVector2 textureSize = texture.TextureSize;

            var heightComputeBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4,
                Type   = ComputeBufferType.Default
            });
            var outRenderTexture = parametersContainer.AddComputeShaderTextureTemplate(
                new MyComputeShaderTextureTemplate()
            {
                Depth           = 24,
                EnableReadWrite = true,
                Format          = RenderTextureFormat.RFloat,
                Size            = textureSize,
                TexWrapMode     = TextureWrapMode.Clamp
            });

            MultistepComputeShader transferComputeShader =
                new MultistepComputeShader(_computeShaderContainer.HeightTransferShaderPlain, textureSize);
            var textureToBufferKernel = transferComputeShader.AddKernel("CSHeightTransform_InputTextureToBuffer");
            var bufferToTextureKernel = transferComputeShader.AddKernel("CSHeightTransform_BufferToOutputTexture");

            transferComputeShader.SetGlobalUniform("g_sideLength", textureSize.X);

            var transferInputHeightTexture = parametersContainer.AddExistingComputeShaderTexture(texture.Texture);

            transferComputeShader.SetTexture("InputHeightTexture", transferInputHeightTexture,
                                             new List <MyKernelHandle>()
            {
                textureToBufferKernel
            });

            transferComputeShader.SetTexture("OutputHeightTexture", outRenderTexture,
                                             new List <MyKernelHandle>()
            {
                bufferToTextureKernel
            });

            transferComputeShader.SetBuffer("HeightBuffer", heightComputeBuffer,
                                            new List <MyKernelHandle>()
            {
                textureToBufferKernel, bufferToTextureKernel
            });
            //////////////////////////////

            //var configuration =
            //    new HydraulicEroderConfiguration()
            //    {
            //        StepCount = 20,
            //        kr_ConstantWaterAddition = 0.000002f,  // 0.0001f,
            //        ks_GroundToSedimentFactor = 1f,
            //        ke_WaterEvaporationFactor = 0.05f,
            //        kc_MaxSedimentationFactor = 0.8f,
            //    };
            var configuration = _configurations[resolution];

            MultistepComputeShader computeShader =
                new MultistepComputeShader(_computeShaderContainer.HydraulicErosionShader, textureSize);
            var kernel_water                 = computeShader.AddKernel("CSHydraulicErosion_Water");
            var kernel_erostion              = computeShader.AddKernel("CSHydraulicErosion_Erosion");
            var kernel_deltaSum              = computeShader.AddKernel("CSHydraulicErosion_DeltaSum");
            var kernel_clearDelta            = computeShader.AddKernel("CSHydraulicErosion_ClearDelta");
            var kernel_evaporation           = computeShader.AddKernel("CSHydraulicErosion_Evaporation");
            var kernel_sedimentationToGround = computeShader.AddKernel("CSHydraulicErosion_SedimentationToGround");

            computeShader.SetGlobalUniform("g_sideLength", textureSize.X);
            computeShader.SetGlobalUniform("g_krParam", configuration.kr_ConstantWaterAddition);
            computeShader.SetGlobalUniform("g_ksParam", configuration.ks_GroundToSedimentFactor);
            computeShader.SetGlobalUniform("g_keParam", configuration.ke_WaterEvaporationFactor);
            computeShader.SetGlobalUniform("g_kcParam", configuration.kc_MaxSedimentationFactor);

            var allKernels =
                new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_deltaSum,
                kernel_clearDelta,
                kernel_evaporation,
                kernel_sedimentationToGround
            };

            computeShader.SetBuffer("HeightMap", heightComputeBuffer,
                                    new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_evaporation,
                kernel_sedimentationToGround
            });


            var waterMap = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4,
                Type   = ComputeBufferType.Default
            });

            computeShader.SetBuffer("WaterMap", waterMap,
                                    new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_deltaSum,
                kernel_evaporation,
            });

            var deltaBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4 * 2 * 9,
                Type   = ComputeBufferType.Default
            });

            computeShader.SetBuffer("DeltaBuffer", deltaBuffer,
                                    new List <MyKernelHandle>()
            {
                kernel_erostion,
                kernel_deltaSum,
                kernel_clearDelta
            });

            var sedimentMap = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4,
                Type   = ComputeBufferType.Default
            });

            computeShader.SetBuffer("SedimentMap", sedimentMap,
                                    new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_deltaSum,
                kernel_evaporation,
                kernel_sedimentationToGround
            });

            var debugTexture = parametersContainer.AddComputeShaderTextureTemplate(new MyComputeShaderTextureTemplate()
            {
                Depth           = 24,
                EnableReadWrite = true,
                Format          = RenderTextureFormat.ARGB32,
                Size            = textureSize,
                TexWrapMode     = TextureWrapMode.Clamp
            });

            computeShader.SetTexture("DebugTexture", debugTexture,
                                     new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_deltaSum,
                kernel_clearDelta,
                kernel_evaporation,
                kernel_sedimentationToGround
            });


            var loopedKernels = new List <MyKernelHandle>()
            {
                kernel_water,
                kernel_erostion,
                kernel_deltaSum,
                kernel_clearDelta,
                kernel_evaporation,
            };

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(
                new List <MyComputeShaderTextureId>()
            {
                outRenderTexture
            });
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = transferComputeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    textureToBufferKernel
                                }
                            }
                        }
                    },
                    new ComputeShaderWorkPack()
                    {
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = configuration.StepCount,
                                KernelHandles = loopedKernels,
                            },
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    kernel_sedimentationToGround
                                }
                            }
                        },
                        Shader = computeShader
                    },
                    new ComputeShaderWorkPack()
                    {
                        Shader        = transferComputeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    bufferToTextureKernel
                                }
                            }
                        }
                    },
                }
            });

            return(new TextureWithCoords(sizedTexture: new TextureWithSize()
            {
                Texture = outParameters.RetriveTexture(outRenderTexture),
                Size = texture.TextureSize
            }, coords: texture.Coords));
        }
        public async Task <TextureWithCoords> ApplyFeatureAsync(TextureWithCoords texture,
                                                                TerrainCardinalResolution resolution, bool canMultistep)
        {
            ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer();
            IntVector2 textureSize = texture.TextureSize;

            var heightComputeBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4,
                Type   = ComputeBufferType.Default
            });
            var outRenderTexture = parametersContainer.AddComputeShaderTextureTemplate(
                new MyComputeShaderTextureTemplate()
            {
                Size            = textureSize,
                Depth           = 24,
                EnableReadWrite = true,
                Format          = RenderTextureFormat.RFloat,
                TexWrapMode     = TextureWrapMode.Clamp,
            });

            MultistepComputeShader transferComputeShader =
                new MultistepComputeShader(_computeShaderContainer.HeightTransferShaderPlain, textureSize);
            var textureToBufferKernel = transferComputeShader.AddKernel("CSHeightTransform_InputTextureToBuffer");
            var bufferToTextureKernel = transferComputeShader.AddKernel("CSHeightTransform_BufferToOutputTexture");

            transferComputeShader.SetGlobalUniform("g_sideLength", textureSize.X);

            var inputHeightTexture = parametersContainer.AddExistingComputeShaderTexture(texture.Texture);

            transferComputeShader.SetTexture("InputHeightTexture", inputHeightTexture,
                                             new List <MyKernelHandle>()
            {
                textureToBufferKernel
            });

            transferComputeShader.SetTexture("OutputHeightTexture", outRenderTexture,
                                             new List <MyKernelHandle>()
            {
                bufferToTextureKernel
            });

            transferComputeShader.SetBuffer("HeightBuffer", heightComputeBuffer,
                                            new List <MyKernelHandle>()
            {
                textureToBufferKernel, bufferToTextureKernel
            });
            //////////////////////////////

            MultistepComputeShader thermalErosionComputeShader =
                new MultistepComputeShader(_computeShaderContainer.TweakedThermalErosionShader, textureSize);
            var kernel1 = thermalErosionComputeShader.AddKernel("CSTweakedThermal_Precalculation");
            var kernel2 = thermalErosionComputeShader.AddKernel("CSTweakedThermal_Erosion");

            var configuration = _configurations[resolution];

            thermalErosionComputeShader.SetGlobalUniform("g_tParam", configuration.TParam);
            thermalErosionComputeShader.SetGlobalUniform("g_cParam", configuration.CParam);
            thermalErosionComputeShader.SetGlobalUniform("g_sideLength", textureSize.X);

            thermalErosionComputeShader.SetTexture("InputHeightTexture", inputHeightTexture,
                                                   new List <MyKernelHandle>()
            {
                kernel1
            });

            thermalErosionComputeShader.SetBuffer("HeightBuffer0", heightComputeBuffer,
                                                  new List <MyKernelHandle>()
            {
                kernel1, kernel2
            });

            var MyHeightBuffer1 = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4,
                Type   = ComputeBufferType.Default
            });

            thermalErosionComputeShader.SetBuffer("HeightBuffer1", MyHeightBuffer1,
                                                  new List <MyKernelHandle>()
            {
                kernel1, kernel2
            });

            var MyMidTextureBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = textureSize.X * textureSize.Y,
                Stride = 4 * 2,
                Type   = ComputeBufferType.Default
            });

            thermalErosionComputeShader.SetBuffer("MidTextureBuffer", MyMidTextureBuffer,
                                                  new List <MyKernelHandle>()
            {
                kernel1, kernel2
            });

            var outParameters = new ComputeBufferRequestedOutParameters(new List <MyComputeShaderTextureId>()
            {
                outRenderTexture
            });
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                OutParameters       = outParameters,
                ParametersContainer = parametersContainer,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = transferComputeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    textureToBufferKernel
                                }
                            }
                        }
                    },
                    new ComputeShaderWorkPack()
                    {
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 30,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    kernel1, kernel2
                                }
                            },
                        },
                        Shader = thermalErosionComputeShader
                    },
                    new ComputeShaderWorkPack()
                    {
                        Shader        = transferComputeShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    bufferToTextureKernel
                                }
                            }
                        }
                    },
                }
            });

            return(new TextureWithCoords(sizedTexture: new TextureWithSize()
            {
                Texture = outParameters.RetriveTexture(outRenderTexture),
                Size = texture.TextureSize
            }, coords: texture.Coords));
        }
        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);
        }
        public async Task RenderWeld(WeldTextureDrawingOrder order)
        {
            var changedPixelsCount = order.WeldOnTextureInfo.WeldRange.Y - order.WeldOnTextureInfo.WeldRange.X;

            var parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader singleToDuoGrassBillboardShader =
                new MultistepComputeShader(_computeShaderContainer.WeldRenderingShader,
                                           new IntVector2(changedPixelsCount, 1));

            var kernel     = singleToDuoGrassBillboardShader.AddKernel("CSTerrainWelding_Main");
            var allKernels = new List <MyKernelHandle>()
            {
                kernel
            };
            var weldTextureInShader = parametersContainer.AddExistingComputeShaderTexture(_weldTexture);

            singleToDuoGrassBillboardShader.SetTexture("WeldTexture", weldTextureInShader, allKernels);

            var weldTextureChangesInfo         = CalculateWeldTextureChangedPixelsShaderRange(order.WeldOnTextureInfo);
            var weldTextureChangesInfoInShader = parametersContainer.AddComputeBufferTemplate(
                new MyComputeBufferTemplate()
            {
                BufferData = new WeldTexturePixelChangesInfo[]
                {
                    weldTextureChangesInfo
                },
                Count  = 1,
                Stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(WeldTexturePixelChangesInfo)),
                Type   = ComputeBufferType.Default
            });

            singleToDuoGrassBillboardShader.SetBuffer("WeldTextureChangesInfo", weldTextureChangesInfoInShader,
                                                      allKernels);

            var samplingDistance =
                Mathf.RoundToInt(Mathf.Pow(2, Mathf.Max(order.FirstSideInfo.LodLevel, order.SecondSideInfo.LodLevel)));

            var firstSideChangedPixelsShaderRange = CalculateSideChangedPixelsShaderRange(order.FirstSideInfo,
                                                                                          order.FirstSideInfo.SamplingDistance == 0 ? samplingDistance : order.FirstSideInfo.SamplingDistance);

            var secondSideChangedPixelsShaderRange = CalculateSideChangedPixelsShaderRange(order.SecondSideInfo,
                                                                                           order.SecondSideInfo.SamplingDistance == 0 ? samplingDistance : order.SecondSideInfo.SamplingDistance);
            var terrainSideChangesInfoInShader = parametersContainer.AddComputeBufferTemplate(
                new MyComputeBufferTemplate()
            {
                BufferData = new TerrainSidePixelChangesInfo[]
                {
                    firstSideChangedPixelsShaderRange,
                    secondSideChangedPixelsShaderRange
                },
                Count  = 2,
                Stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(TerrainSidePixelChangesInfo)),
                Type   = ComputeBufferType.Default
            });

            singleToDuoGrassBillboardShader.SetBuffer("TerrainSideChangesInfos", terrainSideChangesInfoInShader,
                                                      allKernels);

            singleToDuoGrassBillboardShader.SetTexture("FirstHeightTexture",
                                                       parametersContainer.AddExistingComputeShaderTexture(order.FirstSideInfo.HeightTexture.Texture),
                                                       allKernels);
            singleToDuoGrassBillboardShader.SetTexture("SecondHeightTexture",
                                                       parametersContainer.AddExistingComputeShaderTexture(order.SecondSideInfo.HeightTexture.Texture),
                                                       allKernels);


            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters();
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = singleToDuoGrassBillboardShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = allKernels
                            }
                        }
                    },
                }
            });
        }
Beispiel #7
0
        private async Task <Grass2BakedBillboardClan> GenerateBakedBillboardTextures(
            List <DetailedGrass2SingleBillboard> singleBillboards)
        {
            var textureSize = new IntVector2(singleBillboards.First().Texture.width,
                                             singleBillboards.First().Texture.height);
            var inputBillboardsTextureArray = new Texture2DArray(textureSize.X, textureSize.Y, singleBillboards.Count,
                                                                 TextureFormat.ARGB32, false, false);

            for (int i = 0; i < singleBillboards.Count; i++)
            {
                var tex = singleBillboards[i].Texture;
                inputBillboardsTextureArray.SetPixels(tex.GetPixels(), i);
            }
            inputBillboardsTextureArray.Apply(false);

            var parametersContainer   = new ComputeShaderParametersContainer();
            var bladeSeedTextureArray = parametersContainer.AddComputeShaderTextureTemplate(
                new MyComputeShaderTextureTemplate()
            {
                Depth           = 0,
                EnableReadWrite = true,
                Format          = RenderTextureFormat.R8,
                Size            = textureSize,
                TexWrapMode     = TextureWrapMode.Clamp,
                Dimension       = TextureDimension.Tex2DArray,
                VolumeDepth     = singleBillboards.Count
            });

            var detailTextureArray = parametersContainer.AddComputeShaderTextureTemplate(
                new MyComputeShaderTextureTemplate()
            {
                Depth           = 0,
                EnableReadWrite = true,
                Format          = RenderTextureFormat.RG16,
                Size            = textureSize,
                TexWrapMode     = TextureWrapMode.Clamp,
                Dimension       = TextureDimension.Tex2DArray,
                VolumeDepth     = singleBillboards.Count
            });


            MultistepComputeShader singleToDuoGrassBillboardShader =
                new MultistepComputeShader(_computeShaderContainer.SingleToDuoBillboardShader, textureSize);

            singleToDuoGrassBillboardShader.SetGlobalUniform("g_ArrayLength", singleBillboards.Count);

            var transferKernel = singleToDuoGrassBillboardShader.AddKernel("CSSingleToDuoBillboard_Transfer");

            var inputSingleTextureArray =
                parametersContainer.AddExistingComputeShaderTexture(inputBillboardsTextureArray);

            singleToDuoGrassBillboardShader.SetTexture("InputSingleTextureArray", inputSingleTextureArray,
                                                       new List <MyKernelHandle>()
            {
                transferKernel
            });

            singleToDuoGrassBillboardShader.SetTexture("OutputBladeSeedTextureArray", bladeSeedTextureArray,
                                                       new List <MyKernelHandle>()
            {
                transferKernel
            });
            singleToDuoGrassBillboardShader.SetTexture("OutputDetailTextureArray", detailTextureArray,
                                                       new List <MyKernelHandle>()
            {
                transferKernel
            });

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(
                new List <MyComputeShaderTextureId>()
            {
                bladeSeedTextureArray,
                detailTextureArray
            });
            await _shaderExecutorObject.AddOrder(new ComputeShaderOrder()
            {
                ParametersContainer = parametersContainer,
                OutParameters       = outParameters,
                WorkPacks           = new List <ComputeShaderWorkPack>()
                {
                    new ComputeShaderWorkPack()
                    {
                        Shader        = singleToDuoGrassBillboardShader,
                        DispatchLoops = new List <ComputeShaderDispatchLoop>()
                        {
                            new ComputeShaderDispatchLoop()
                            {
                                DispatchCount = 1,
                                KernelHandles = new List <MyKernelHandle>()
                                {
                                    transferKernel
                                }
                            }
                        }
                    },
                }
            });

            var outBladeSeedTexture = outParameters.RetriveTexture(bladeSeedTextureArray);

            outBladeSeedTexture.filterMode = FilterMode.Point;
            outBladeSeedTexture.wrapMode   = TextureWrapMode.Clamp;

            var outDetailTexture = outParameters.RetriveTexture(detailTextureArray);

            outDetailTexture.filterMode = FilterMode.Trilinear;
            outDetailTexture.wrapMode   = TextureWrapMode.Clamp;

            return(new Grass2BakedBillboardClan(singleBillboards.Select(c => c.BladesCount).ToList(),
                                                outBladeSeedTexture, outDetailTexture));
        }
        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
                        }
                    }
                }));
            };
        }
Beispiel #9
0
        public async Task <List <Grass2TypeWithIntensity> > GenerateGrassIntenstiyAsync(
            MyRectangle generationArea,
            Dictionary <HabitatType, Texture2D> habitatTexturesDict,
            IntVector2 habitatTexturesSize,
            UvdSizedTexture pathProximityTexture)
        {
            var generatedGrassTypes = _configuration.GrassTypeToSourceHabitats
                                      .Where(c => c.Value.Any(k => habitatTexturesDict.ContainsKey(k))).Select(c => c.Key).ToList();

            if (!generatedGrassTypes.Any())
            {
                Debug.Log("W34 Returning empty grass intensity, Because of OutGrassTypes from habitats: " +
                          StringUtils.ToString(habitatTexturesDict.Keys));
                return(new List <Grass2TypeWithIntensity>());
            }
////////
            var usedGrassTypesPositions = CreateUsedGrassTypesPositions(generatedGrassTypes);

            var usedHabitatTypesPositions = CreateUsedHabitatTypesPositions(habitatTexturesDict);

            if (!usedHabitatTypesPositions.Any())
            {
                Debug.Log("W34 Returning empty grass intensity, Because of In habitatTypes, from habitats: " +
                          StringUtils.ToString(habitatTexturesDict.Keys));
                return(new List <Grass2TypeWithIntensity>());
            }
//////
            var habitatTextureArray = await CreateHabitatTexture2DArrayAsync(habitatTexturesDict, habitatTexturesSize);

//////

            var outFigureSize = new IntVector2(
                Mathf.CeilToInt(generationArea.Width * _configuration.OutputPixelsPerUnit),
                Mathf.CeilToInt(generationArea.Height * _configuration.OutputPixelsPerUnit)
                );

            ComputeShaderParametersContainer parametersContainer = new ComputeShaderParametersContainer();

            MultistepComputeShader habitatToGrassShader =
                new MultistepComputeShader(_computeShaderContainer.HabitatToGrassTypeShader, outFigureSize);

            var usedKernelNames = generatedGrassTypes.Select(c => HabitatToGrassUtils.GrassTypeToKernelName[c])
                                  .ToList();

            var usedKernels = usedKernelNames.Select(c => habitatToGrassShader.AddKernel(c)).ToList();

            var usedGrassTypesPositionsBuffer =
                parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count      = usedGrassTypesPositions.Length,
                BufferData = usedGrassTypesPositions,
                Stride     = 4,
                Type       = ComputeBufferType.Default
            });

            habitatToGrassShader.SetBuffer("OutputGrassTypePositions", usedGrassTypesPositionsBuffer, usedKernels);

            var usedHabitatTypesPositionsBuffer =
                parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count      = usedHabitatTypesPositions.Length,
                BufferData = usedHabitatTypesPositions,
                Stride     = 4,
                Type       = ComputeBufferType.Default
            });

            habitatToGrassShader.SetBuffer("InputHabitatTypePositions", usedHabitatTypesPositionsBuffer, usedKernels);

            var outIntensitiesBuffer = parametersContainer.AddComputeBufferTemplate(new MyComputeBufferTemplate()
            {
                Count  = outFigureSize.X * outFigureSize.Y * generatedGrassTypes.Count,
                Type   = ComputeBufferType.Default,
                Stride = 4
            });

            habitatToGrassShader.SetBuffer("OutIntensityBuffer", outIntensitiesBuffer, usedKernels);

            var habitatTextureArrayInShader = parametersContainer.AddExistingComputeShaderTexture(habitatTextureArray);

            habitatToGrassShader.SetTexture("HabitatTexturesArray", habitatTextureArrayInShader, usedKernels);

            var pathProximityTextureInShader =
                parametersContainer.AddExistingComputeShaderTexture(pathProximityTexture.TextureWithSize.Texture);

            habitatToGrassShader.SetTexture("PathProximityTexture", pathProximityTextureInShader, usedKernels);

            habitatToGrassShader.SetGlobalUniform("g_Coords", generationArea.ToVector4());
            habitatToGrassShader.SetGlobalUniform("g_PathProximityUv", pathProximityTexture.Uv.ToVector4());
            habitatToGrassShader.SetGlobalUniform("g_OutTextureSize", outFigureSize.ToFloatVec());
            habitatToGrassShader.SetGlobalUniform("g_MaxProximity", _configuration.MaxProximity);

            ComputeBufferRequestedOutParameters outParameters = new ComputeBufferRequestedOutParameters(
                requestedBufferIds: new List <MyComputeBufferId>()
            {
                outIntensitiesBuffer
            });

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


            var outIntensitiesNativeArray = await _commonExecutor.AddAction(() =>
            {
                var array = new float[outFigureSize.X *outFigureSize.Y *generatedGrassTypes.Count];
                outParameters.RetriveBuffer(outIntensitiesBuffer).GetData(array);
                //DebugCreateTexture(array, generationArea, outFigureSize, generatedGrassTypes.Count);

                return(array);
            });

            return(RetriveIntensityFiguresFromTextureArray(outIntensitiesNativeArray, generatedGrassTypes,
                                                           outFigureSize));
        }