void UpdateComputeShader() { computeShader.SetVector("cmrPos", transform.position); if (dispatchIndirectMode == false) { computeShader.Dispatch(kernelCSClear, rtSize / 8, rtSize / 8, 1); } else { computeShader.DispatchIndirect(kernelCSClear, indirectArguments); } computeShader.SetFloat("WaterHeight", waterHeight); var m = Camera.main.projectionMatrix * Camera.main.worldToCameraMatrix; //高版本 可用 computeShader.SetMatrix("matrix_VP", m); 代替 下面数组传入 float[] mlist = new float[] { m.m00, m.m10, m.m20, m.m30, m.m01, m.m11, m.m21, m.m31, m.m02, m.m12, m.m22, m.m32, m.m03, m.m13, m.m23, m.m33 }; computeShader.SetFloats("matrix_VP", mlist); if (dispatchIndirectMode == false) { computeShader.Dispatch(kernelMain, rtSize / 8, rtSize / 8, 1); } else { computeShader.DispatchIndirect(kernelMain, indirectArguments); } }
private void DispatchInit() { var initKernel = m_compute.FindKernel("Init"); m_compute.SetBuffer(initKernel, "_particles", m_particlesBuffer); m_compute.SetBuffer(initKernel, "_kernelArgs", m_kernelArgs); m_compute.SetBuffer(initKernel, "_deadList", m_particlePoolBuffer); m_compute.DispatchIndirect(initKernel, m_kernelArgs); }
/// <summary> /// Executed by Unity on every first frame <see cref="https://docs.unity3d.com/Manual/ExecutionOrder.html"/> /// </summary> private void OnRenderObject() { material.SetMatrix("vertexTransform", gameObject.transform.localToWorldMatrix); material.SetFloat("TIME", Time.time / 10.0f); _generator.SetFloat("TIME", Time.time / 10.0f); for (int step = 0; step < STEPS; step++) { _outPointsCount.SetData(new int[] { 0, 1, 0, 0 }); _generator.SetInt("LAYER_OFFSET", (FACTOR / STEPS) * step); _generator.DispatchIndirect(_marchCubes, _indirectSizeMarch); material.SetPass(0); if (isIndirectAvailable) { Graphics.DrawProceduralIndirectNow(MeshTopology.Triangles, _outPointsCount, 0); } else { int[] nPointsData = new int[1]; _outPointsCount.GetData(nPointsData, 0, 0, 1); int nPoints = nPointsData[0]; Graphics.DrawProceduralNow(MeshTopology.Triangles, nPoints, 1); } } }
private void Update() { //Make filter change, so that we see different result //if (!staticTest) { if (_filter >= _amount) { _filter = 0; } else { _filter++; } } //Reset count cbPoints.SetCounterValue(0); //Direct dispatch to do filter shader.SetFloat("_Time", Time.time); shader.SetFloat("_Filter", _filter); shader.Dispatch(_kernelDirect, _amount * (int)_threadsizeX, (int)_threadsizeY, (int)_threadsizeZ); //Copy Count ComputeBuffer.CopyCount(cbPoints, cbDrawArgs, 0); //Indirect dispatch to only execute kernel on filtered data shader.DispatchIndirect(_kernelIndirect, cbDrawArgs, 0); //Read data from GPU int[] ff = new int[cbPoints.count]; cbPoints.GetData(ff); int[] aa = new int[args.Length]; cbDrawArgs.GetData(aa); //Output tx.text = "Indirect compute \n cbDrawArgs \n [0]:" + aa[0] + "\n [1]:" + aa[1] + "\n [2]:" + aa[2] + "\n [3]:" + aa[3] + " \n cbPoints (total data count) = " + cbPoints.count; for (int i = 0; i < ff.Length; i++) { tx.text += "\n" + "ff[" + i + "] = " + ff[i]; } }
public void DeleteRun() { PipelineResources resources = RenderPipeline.current.resources; PipelineBaseBuffer baseBuffer = SceneController.baseBuffer; int result = baseBuffer.clusterCount - property.clusterCount; ComputeShader shader = resources.shaders.streamingShader; if (result > 0) { NativeArray <int> indirectArgs = new NativeArray <int>(5, Allocator.Temp, NativeArrayOptions.UninitializedMemory); indirectArgs[0] = 0; indirectArgs[1] = 1; indirectArgs[2] = 1; indirectArgs[3] = result; indirectArgs[4] = propertyCount; baseBuffer.moveCountBuffer.SetData(indirectArgs); ComputeBuffer indexBuffer = SceneController.GetTempPropertyBuffer(property.clusterCount, 8); indirectArgs.Dispose(); shader.SetBuffer(0, ShaderIDs.instanceCountBuffer, baseBuffer.moveCountBuffer); shader.SetBuffer(0, ShaderIDs.clusterBuffer, baseBuffer.clusterBuffer); shader.SetBuffer(0, ShaderIDs._IndexBuffer, indexBuffer); shader.SetBuffer(1, ShaderIDs._IndexBuffer, indexBuffer); shader.SetBuffer(1, ShaderIDs.verticesBuffer, baseBuffer.verticesBuffer); ComputeShaderUtility.Dispatch(shader, 0, result); shader.DispatchIndirect(1, baseBuffer.moveCountBuffer); } baseBuffer.clusterCount = result; loading = false; state = State.Unloaded; }
//dispatches the 'setup dispatch' shader to configer the dispatch args for a given //dispatch type, then does an actual dispatch indirect on the requested kernel void DispatchIndirect(int kernel, int dispatchIndex) { _asteroidsShader.SetInt("_kernelIdRequested", dispatchIndex); DispatchOne(kernelSetupDispatch); BindEverything(kernel); _asteroidsShader.SetInt("_threadCount", -1); _asteroidsShader.DispatchIndirect(kernel, _dispatchBuffer); }
private void SortParticles() { initSortKernel = particleSortCS.FindKernel("ParticleSort"); particleSortCS.SetBuffer(initSortKernel, "drawArgsBuffer", indirectdrawbuffer); particleSortCS.SetBuffer(initSortKernel, "inputs", m_pingpongBuffer[m_currentBufferIndex]); particleSortCS.SetBuffer(initSortKernel, "indexBuffer", indexBuffer); particleSortCS.SetBuffer(initSortKernel, "vertexCounterBuffer", vertexCounterBuffer); particleSortCS.DispatchIndirect(initSortKernel, dispatchArgsBuffer); bool hizEnable = enableHizCulling && hizBuffer.Valid; particleSortCS.SetBool("enableHizCulling", hizEnable); if (hizEnable) { particleSortCS.SetTexture(initSortKernel, "depthTexture", hizBuffer.HizDepthTexture); particleSortCS.SetFloats("RTSize", new float[2] { m_screenWidth, m_screenHeight }); particleSortCS.SetInt("max_level", hizBuffer.Lodlevel); } if (bufferSize > 2048) { outerSortKernel = particleSortCS.FindKernel("OuterSort"); innerSortKernel = particleSortCS.FindKernel("InnerSort"); particleSortCS.SetBuffer(outerSortKernel, "indexBuffer", indexBuffer); particleSortCS.SetBuffer(outerSortKernel, "drawArgsBuffer", indirectdrawbuffer); particleSortCS.SetBuffer(innerSortKernel, "drawArgsBuffer", indirectdrawbuffer); particleSortCS.SetBuffer(outerSortKernel, "vertexCounterBuffer", vertexCounterBuffer); particleSortCS.SetBuffer(innerSortKernel, "vertexCounterBuffer", vertexCounterBuffer); particleSortCS.SetBuffer(innerSortKernel, "indexBuffer", indexBuffer); int alignedMaxNumElements = Mathf.NextPowerOfTwo(bufferSize); for (int k = 4096; k <= alignedMaxNumElements; k *= 2) { particleSortCS.SetInt("k", k); for (int j = k / 2; j >= 2048; j /= 2) { particleSortCS.SetInt("j", j); particleSortCS.DispatchIndirect(outerSortKernel, dispatchArgsBuffer); } particleSortCS.DispatchIndirect(innerSortKernel, dispatchArgsBuffer); } } }
public async Task Insert(Vector3[] data) { uint gx, gy, gz; shader.GetKernelThreadGroupSizes(computeLeavesKernel, out gx, out gy, out gz); int numGroupsX = Mathf.CeilToInt((float)data.Length / gx); using (var leaves = new StructuredBuffer <int>(data.Length)) using (var leafCount = new RawBuffer <uint>(1)) using (var keys = new CounterBuffer <int>(data.Length)) using (var points = new StructuredBuffer <Vector3>(data.Length)) { points.SetData(data); shader.SetFloats("size", bounds.size.x, bounds.size.y, bounds.size.z); shader.SetFloats("min_corner", bounds.min.x, bounds.min.y, bounds.min.z); shader.SetInt("max_depth", maxDepth); shader.SetInt("point_count", data.Length); shader.SetBuffer(computeLeavesKernel, "leaves", leaves.Buffer); shader.SetBuffer(computeLeavesKernel, "points", points.Buffer); shader.Dispatch(computeLeavesKernel, numGroupsX, 1, 1); sorter.Sort(leaves, data.Length); shader.SetBuffer(markUniqueLeavesKernel, "leaves", leaves.Buffer); shader.SetBuffer(markUniqueLeavesKernel, "unique", keys.Buffer); shader.Dispatch(markUniqueLeavesKernel, numGroupsX, 1, 1); compactor.Compact(leaves, keys, data.Length); keys.CopyCount(indirectArgs); shader.SetBuffer(computeArgsKernel, "args", indirectArgs.Buffer); shader.Dispatch(computeArgsKernel, 1, 1, 1); keys.CopyCount(leafCount); shader.SetBuffer(subdivideKernel, "leaf_count", leafCount.Buffer); shader.SetBuffer(subdivideKernel, "leaves", leaves.Buffer); shader.SetBuffer(subdivideKernel, "nodes", nodes.Buffer); for (int i = 0; i < maxDepth; i++) { shader.SetInt("current_level", i); shader.DispatchIndirect(subdivideKernel, indirectArgs.Buffer); } nodeData = await nodes.GetDataAsync(); nodeCount = (int)nodes.GetCounterValue(); } }
public static int DispatchIndirect(IntPtr l) { int result; try { int num = LuaDLL.lua_gettop(l); if (num == 3) { ComputeShader computeShader = (ComputeShader)LuaObject.checkSelf(l); int kernelIndex; LuaObject.checkType(l, 2, out kernelIndex); ComputeBuffer argsBuffer; LuaObject.checkType <ComputeBuffer>(l, 3, out argsBuffer); computeShader.DispatchIndirect(kernelIndex, argsBuffer); LuaObject.pushValue(l, true); result = 1; } else if (num == 4) { ComputeShader computeShader2 = (ComputeShader)LuaObject.checkSelf(l); int kernelIndex2; LuaObject.checkType(l, 2, out kernelIndex2); ComputeBuffer argsBuffer2; LuaObject.checkType <ComputeBuffer>(l, 3, out argsBuffer2); uint argsOffset; LuaObject.checkType(l, 4, out argsOffset); computeShader2.DispatchIndirect(kernelIndex2, argsBuffer2, argsOffset); LuaObject.pushValue(l, true); result = 1; } else { LuaObject.pushValue(l, false); LuaDLL.lua_pushstring(l, "No matched override function DispatchIndirect to call"); result = 2; } } catch (Exception e) { result = LuaObject.error(l, e); } return(result); }
void Pass_AssignLightsToClusts() { ClearLightGirdIndexCounter(); int kernel = cs_AssignLightsToClusts.FindKernel("CSMain"); //Output cs_AssignLightsToClusts.SetBuffer(kernel, "RWPointLightIndexCounter_Cluster", cb_ClusterPointLightIndexCounter); cs_AssignLightsToClusts.SetBuffer(kernel, "RWPointLightGrid_Cluster", cb_ClusterPointLightGrid); cs_AssignLightsToClusts.SetBuffer(kernel, "RWPointLightIndexList_Cluster", cb_ClusterPointLightIndexList); //Input cs_AssignLightsToClusts.SetInt("PointLightCount", lst_Light.Count); cs_AssignLightsToClusts.SetMatrix("_CameraLastViewMatrix", _camera.worldToCameraMatrix); cs_AssignLightsToClusts.SetBuffer(kernel, "PointLights", cb_PointLightPosRadius); cs_AssignLightsToClusts.SetBuffer(kernel, "ClusterAABBs", cb_ClusterAABBs); cs_AssignLightsToClusts.SetBuffer(kernel, "UniqueClusters", cb_UniqueClusters); //cs_AssignLightsToClusts.Dispatch(kernel, m_DimData.clusterDimXYZ, 1, 1); cs_AssignLightsToClusts.DispatchIndirect(kernel, cb_IAB_AssignLightsToClusters); }
public override void OnUpdateSystem(bool rebuildSDF, RenderTexture sourceRT, RenderTexture boundRT) { if (!rebuildSDF) { return; } rts[READ] = sourceRT; rts[WRITE] = anotherTex; // clear list buffer // resolutionX and resolutionY should be odd, otherwise it will cause symchronized problem iterateListBuffer.SetCounterValue(0); // kernel0: just need bound tex BOUND_TEX_IS_BOUNDARY, init grid val and surface grid val, build first queue, init complete tag LevelSet2DFSMComputeShader.SetTexture(InitSDFKernel, "_BoundTex", boundRT); LevelSet2DFSMComputeShader.SetTexture(InitSDFKernel, "_SDFRead", rts[READ]); LevelSet2DFSMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFSMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFSMComputeShader.SetBuffer(InitSDFKernel, "_ItrateListBuffer", iterateListBuffer); LevelSet2DFSMComputeShader.Dispatch(InitSDFKernel, resolutionX, resolutionY, 1); for (int dilate = 0; dilate < dilateTime; ++dilate) { ComputeBuffer.CopyCount(iterateListBuffer, iterateListArgBuffer, 0); iterateListBufferTo.SetCounterValue(0); // kernel2: SweepingKernel, sweeping, build next queue LevelSet2DFSMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFSMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFSMComputeShader.SetTexture(SweepingKernel, "_BoundTex", boundRT); LevelSet2DFSMComputeShader.SetTexture(SweepingKernel, "_SDFRead", rts[READ]); LevelSet2DFSMComputeShader.SetBuffer(SweepingKernel, "_ItrateListBufferNew", iterateListBufferTo); LevelSet2DFSMComputeShader.SetBuffer(SweepingKernel, "_ItrateListBufferRead", iterateListBuffer); LevelSet2DFSMComputeShader.DispatchIndirect(SweepingKernel, iterateListArgBuffer); Liquid2DUtils.Swap(ref iterateListBuffer, ref iterateListBufferTo); } }
void RenderHeatmap() { if (pointsBuffer == null || propsBuffer == null || renderTexture == null || composite == null || HeatmapViewModel.videoPlayer == null || HeatmapViewModel.videoPlayer.targetTexture == null || gradient == null || videoMaterial == null || gradientSize == 0) { return; } shader.SetBuffer(kernelHeatmap, "_points", pointsBuffer); shader.SetBuffer(kernelHeatmap, "_properties", propsBuffer); shader.SetInt("_numPoints", currPoints); shader.SetFloat("_decay", decay); shader.SetTexture(kernelHeatmap, "_result", renderTexture); shader.SetTexture(kernelHeatmap, "_composite", composite); shader.SetTexture(kernelHeatmap, "_video", HeatmapViewModel.videoPlayer.targetTexture); shader.SetTexture(kernelHeatmap, "_gradient", gradient); if (videoMaterial != null) { videoMaterial.SetTexture("_HeatmapTex", renderTexture); videoMaterial.SetTexture("_HeatmapGradient", gradient); } if (points != null && props != null && pointsBuffer != null && propsBuffer != null && argsBuffer != null) { pointsBuffer.SetData(points); propsBuffer.SetData(props); argsBuffer.SetData(new int[3] { heatMapWidth / 8, heatMapHeight / 8, 1 }); } if (argsBuffer != null) { shader.DispatchIndirect(kernelHeatmap, argsBuffer, 0); } EditorUtility.SetDirty(this); }
public void DispatchIndirect(ComputeBuffer args) { PreDispatch(); m_Shader.DispatchIndirect(m_KernelId, args); }
void DrawSurface() { triangulatedCells.SetCounterValue(0); cellsToTriangulate.SetCounterValue(0); int kernel = surfaceReconstruction.FindKernel("ConvertCellTags"); surfaceReconstruction.SetBuffer(kernel, "cell_tags", cellTags); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate", cellsToTriangulate); Profiler.BeginSample("Convert Cell Tags"); surfaceReconstruction.Dispatch(kernel, (int)math.ceil(marchingCubeGridPointCount / 1024.0f), 1, 1); Profiler.EndSample(); ComputeBuffer.CopyCount(cellsToTriangulate, cellsToTriangulateArgs, 0); kernel = surfaceReconstruction.FindKernel("SetTriangulateArgs"); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate_args", cellsToTriangulateArgs); Profiler.BeginSample("Set Triangulate Args"); surfaceReconstruction.Dispatch(kernel, 1, 1, 1); Profiler.EndSample(); kernel = surfaceReconstruction.FindKernel("CalculateScalarField"); surfaceReconstruction.SetBuffer(kernel, "cell_tags", cellTags); surfaceReconstruction.SetBuffer(kernel, "bins", bins); surfaceReconstruction.SetBuffer(kernel, "prefix_sums", prefixSums); surfaceReconstruction.SetBuffer(kernel, "positions", positions); surfaceReconstruction.SetBuffer(kernel, "scalar_field", scalarField); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate_read", cellsToTriangulate); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate_args", cellsToTriangulateArgs); Profiler.BeginSample("Calculate Scalar"); surfaceReconstruction.DispatchIndirect(kernel, cellsToTriangulateArgs, 0); Profiler.EndSample(); kernel = surfaceReconstruction.FindKernel("TriangulateCells"); surfaceReconstruction.SetBuffer(kernel, "cell_tags", cellTags); surfaceReconstruction.SetBuffer(kernel, "scalar_field", scalarField); surfaceReconstruction.SetBuffer(kernel, "edge_table", edgeTableBuffer); surfaceReconstruction.SetBuffer(kernel, "triangle_connection_table", triangleConnectionTableBuffer); surfaceReconstruction.SetBuffer(kernel, "triangulated_cells", triangulatedCells); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate_read", cellsToTriangulate); surfaceReconstruction.SetBuffer(kernel, "cells_to_triangulate_args", cellsToTriangulateArgs); Profiler.BeginSample("Triangulate Cells"); surfaceReconstruction.DispatchIndirect(kernel, cellsToTriangulateArgs, 0); Profiler.EndSample(); ComputeBuffer.CopyCount(triangulatedCells, drawProceduralIndirectArgs, 0); kernel = surfaceReconstruction.FindKernel("FillIndirectArgs"); surfaceReconstruction.SetBuffer(kernel, "draw_procedural_indirect_args", drawProceduralIndirectArgs); Profiler.BeginSample("Fill Indirect Args"); surfaceReconstruction.Dispatch(kernel, 1, 1, 1); Profiler.EndSample(); MaterialPropertyBlock properties = new MaterialPropertyBlock(); properties.SetFloat("visualScale", visualScale); properties.SetBuffer("vertices", triangulatedCells); Graphics.DrawProceduralIndirect( surfaceMaterial, new Bounds(transform.position, transform.lossyScale * 10000), MeshTopology.Triangles, drawProceduralIndirectArgs, 0, null, properties, ShadowCastingMode.Off ); }
public static void DispatchIndirect(ComputeShader shader, int kernel, ComputeBuffer indirectArgs) { Assert.True(s_activeShaderSet.Contains(shader), $"Compute shader {shader} not active."); shader.DispatchIndirect(kernel, indirectArgs); }
void Update() { Vector2 mousePos = new Vector2 { x = Input.mousePosition.x / (float)Screen.width, y = Input.mousePosition.y / (float)Screen.height }; Vector2 resolution = new Vector2 { x = _doubleBuffer.width, y = _doubleBuffer.height }; Shader.SetGlobalVector("_Resolution", new Vector4 { x = resolution.x, y = resolution.y, z = 1f / resolution.x, w = 1f / resolution.y }); Shader.SetGlobalVector("_Mouse", mousePos); Shader.SetGlobalFloat("_Time", Time.time); Shader.SetGlobalFloat("_DeltaTime", Time.deltaTime); if (Input.GetMouseButton(0)) { particleShader.SetInt("_MaxParticles", maxParticles); particleShader.SetBuffer(particleSeedKernel, "_CounterBuf", indirectArgsBuf); particleShader.SetBuffer(particleSeedKernel, "_WriteParticles", pBufA); particleShader.Dispatch(particleSeedKernel, 1, 1, 1); } ComputeBuffer.CopyCount(pBufA, indirectArgsBuf, 0); indirectArgsShader.SetBuffer(0, "_IndirectArgsBuf", indirectArgsBuf); indirectArgsShader.Dispatch(0, 1, 1, 1); particleShader.SetBuffer(particleSimKernel, "_CounterBuf", indirectArgsBuf); particleShader.SetBuffer(particleSimKernel, "_ReadParticles", pBufA); particleShader.SetBuffer(particleSimKernel, "_WriteParticles", pBufB); particleShader.SetTexture(particleSimKernel, "_ReadTexture", _doubleBuffer.read); particleShader.SetTexture(particleSimKernel, "_WriteTexture", _doubleBuffer.write); uniforms.Bind(particleShader); particleShader.DispatchIndirect(particleSimKernel, indirectArgsBuf, sizeof(int)); ComputeBuffer.CopyCount(pBufB, indirectArgsBuf, 0); // flip buffers var tmp = pBufA; pBufA = pBufB; pBufB = tmp; _doubleBuffer.Flip(); { colorDiffuseShader.SetFloat("_DecayRate", decayRate); colorDiffuseShader.SetTexture(0, "_ReadTexture", _doubleBuffer.read); colorDiffuseShader.SetTexture(0, "_WriteTexture", _doubleBuffer.write); colorDiffuseShader.GetKernelThreadGroupSizes(0, out var threadsX, out var threadsY, out var threadsZ); var threadGroupsX = _doubleBuffer.width / (int)threadsX; var threadGroupsY = _doubleBuffer.height / (int)threadsY; colorDiffuseShader.Dispatch(0, threadGroupsX, threadGroupsY, 1); } renderer.material.SetTexture("_MainTex", _doubleBuffer.write); }
public override void OnUpdateSystem(bool rebuildSDF, RenderTexture sourceRT, RenderTexture boundRT) { if (!rebuildSDF) { return; } rts[READ] = sourceRT; rts[WRITE] = anotherTex; // clear list buffer iterateListBuffer.SetCounterValue(0); // kernel0: init bound texture and other buffers LevelSet2DFIMComputeShader.SetTexture(BuildInitBoundTex, "_BoundTex", boundRT); LevelSet2DFIMComputeShader.SetTexture(BuildInitBoundTex, "_SDFRead", rts[READ]); LevelSet2DFIMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFIMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFIMComputeShader.Dispatch(BuildInitBoundTex, resolutionX, resolutionY, 1); // kernel1: mark known point LevelSet2DFIMComputeShader.SetTexture(MarkSurface, "_BoundTex", boundRT); LevelSet2DFIMComputeShader.SetTexture(MarkSurface, "_SDFRead", rts[READ]); LevelSet2DFIMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFIMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFIMComputeShader.Dispatch(MarkSurface, resolutionX, resolutionY, 1); // kernel2: build first queue, copy read to write tex LevelSet2DFIMComputeShader.SetBuffer(BuildFirstQueue, "_ItrateListBuffer", iterateListBuffer); LevelSet2DFIMComputeShader.SetTexture(BuildFirstQueue, "_BoundTex", boundRT); LevelSet2DFIMComputeShader.SetTexture(BuildFirstQueue, "_SDFRead", rts[READ]); LevelSet2DFIMComputeShader.SetTexture(BuildFirstQueue, "_SDFWrite", rts[WRITE]); LevelSet2DFIMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFIMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFIMComputeShader.Dispatch(BuildFirstQueue, resolutionX, resolutionY, 1); // kernel3: debug queue // LevelSet2DFMMStarComputeShader.SetBuffer(DebugKernel, "_ItrateListBufferRead", iterateListBuffer); // LevelSet2DFMMStarComputeShader.SetTexture(DebugKernel, "_SDFWrite", rts[WRITE]); // LevelSet2DFMMStarComputeShader.DispatchIndirect(DebugKernel, iterateListArgBuffer); // loop: // 1、 dispatchIndirect our list, calc SDF val due to BOUND_TEX_IS_KNOWN pixel, set BOUND_TEX_IS_KNOWN, build next list, generate next queue, swap listbuffer for (int dilate = 0; dilate < dilateTime; ++dilate) { Liquid2DUtils.Swap(ref READ, ref WRITE); // kernel4: FIMCopyKernel, copy read to write tex LevelSet2DFIMComputeShader.SetTexture(FIMCopyKernel, "_SDFRead", rts[READ]); LevelSet2DFIMComputeShader.SetTexture(FIMCopyKernel, "_SDFWrite", rts[WRITE]); LevelSet2DFIMComputeShader.Dispatch(FIMCopyKernel, resolutionX + 2, resolutionY + 2, 1); ComputeBuffer.CopyCount(iterateListBuffer, iterateListArgBuffer, 0); iterateListBufferTo.SetCounterValue(0); // kernel5: FIMLoopKernel, require blit between two textures LevelSet2DFIMComputeShader.SetInt("_ResolutionX", resolutionX); LevelSet2DFIMComputeShader.SetInt("_ResolutionY", resolutionY); LevelSet2DFIMComputeShader.SetTexture(FIMLoopKernel, "_BoundTex", boundRT); LevelSet2DFIMComputeShader.SetTexture(FIMLoopKernel, "_SDFRead", rts[READ]); LevelSet2DFIMComputeShader.SetTexture(FIMLoopKernel, "_SDFWrite", rts[WRITE]); LevelSet2DFIMComputeShader.SetBuffer(FIMLoopKernel, "_ItrateListBufferRead", iterateListBuffer); LevelSet2DFIMComputeShader.SetBuffer(FIMLoopKernel, "_ItrateListBufferNew", iterateListBufferTo); LevelSet2DFIMComputeShader.DispatchIndirect(FIMLoopKernel, iterateListArgBuffer); ComputeBuffer.CopyCount(iterateListBufferTo, iterateListArgBufferTo, 0); Liquid2DUtils.Swap(ref iterateListBuffer, ref iterateListBufferTo); Liquid2DUtils.Swap(ref iterateListArgBuffer, ref iterateListArgBufferTo); } }