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