Material Clustering Benchmark
ADispatcherRS.cs
Go to the documentation of this file.
1using UnityEngine;
2using System;
3
5{
6 public abstract class ADispatcherRS : DispatcherKM
7 {
8 [Serializable]
10 {
11 public int numIterationsKm;
12
14 {
15 this.numIterationsKm = numIterationsKm;
16 }
17
18 public static Parameters Default()
19 {
20 return new Parameters(numIterationsKm: 2);
21 }
22 }
23
24 protected readonly Parameters parameters;
26
27 public override abstract bool usesStopCondition { get; }
28
29 protected readonly int kernelHandleRandomSwap;
30 protected readonly int kernelHandleValidateCandidates;
31
32 private static ObjectPoolMaxAssert<RandomSwapResult> RandomSwapResultPool =
34 createFunc: () =>
36 stopConditionOverride: RandomSwapResult.StopConditionOverride.Default,
37 varianceReduction: 0,
38 swapFailed: false
39 ),
40 maxActive: 1
41 );
42
44 ComputeShader computeShader,
45 int numIterations,
50 )
51 : base(
57 )
58 {
59 this.parameters = parameters;
60 this.kernelHandleRandomSwap = this.computeShader.FindKernel("RandomSwap");
61 this.kernelHandleValidateCandidates = this.computeShader.FindKernel(
62 "ValidateCandidates"
63 );
64 }
65
66 public override string name => "RS";
67
68 /// <summary>
69 /// Call <see cref="Dispose" /> after using.
70 /// </summary>
71 public class RandomSwapResult : System.IDisposable
72 {
74 {
75 KeepRunning,
76 Stop,
77 Default
78 }
79
81 public float varianceReduction;
82 public bool swapFailed;
83
87 bool swapFailed
88 )
89 {
90 this.varianceReduction = varianceReduction;
91 this.stopConditionOverride = stopConditionOverride;
92 this.swapFailed = swapFailed;
93 }
94
95 public void Dispose()
96 {
97 RandomSwapResultPool.Release(this);
98 }
99 }
100
101 public abstract override void RunClustering(ClusteringTextures clusteringTextures);
102
103 /// <summary>
104 ///
105 /// </summary>
106 /// <returns>Must be disposed.</returns>
108 {
109 RandomSwapResult randomSwapResult = RandomSwapResultPool.Get();
110 randomSwapResult.varianceReduction = 0;
111 randomSwapResult.stopConditionOverride = RandomSwapResult.StopConditionOverride.Default;
112 randomSwapResult.swapFailed = false;
113
114 using (ClusterCenters clusterCenters = this.clusteringRTsAndBuffers.GetClusterCenters())
115 {
116 /*
117 variance = ...
118
119 positive number == valid variance
120 -1 == not a single pixel has sufficient chromatic component
121
122 |0 |numClusters |
123 |---------------|---------------|
124 | new centers | old centers |
125 */
126 if (clusterCenters.variance != null)
127 {
128 // In the new frame at least one pixel has sufficient chromatic portion, i.e. new variance is not null.
129
130 if (
131 clusterCenters.oldVariance == null
132 || clusterCenters.variance < clusterCenters.oldVariance
133 )
134 {
135 // Either in the previous run not a single pixel had sufficient chromatic portion, or variance improved.
136
137 if (clusterCenters.oldVariance != null)
138 {
139 /*
140 old variance and new variance are both not null
141 new variance < old variance
142 */
143
144 randomSwapResult.varianceReduction =
145 (float)clusterCenters.oldVariance - (float)clusterCenters.variance;
146 }
147 else
148 {
149 /*
150 old variance is null
151 new variance is not null
152 */
153
154 randomSwapResult.stopConditionOverride = RandomSwapResult
156 .KeepRunning;
157 }
158
159 // save new cluster centers as old
160 for (int i = 0; i < this.clusteringRTsAndBuffers.numClusters; i++)
161 {
162 clusterCenters.centers[i + this.clusteringRTsAndBuffers.numClusters] =
163 clusterCenters.centers[i];
164 }
165 }
166 else
167 {
168 // variance did not improve (failed swap)
169
170 randomSwapResult.swapFailed = true;
171
172 // restore old cluster centers as new
173 for (int i = 0; i < this.clusteringRTsAndBuffers.numClusters; i++)
174 {
175 clusterCenters.centers[i] = clusterCenters.centers[
176 i + this.clusteringRTsAndBuffers.numClusters
177 ];
178 }
179 }
180 }
181 else
182 {
183 // in the current frame not a single pixel has sufficient chromatic portion
184
185 randomSwapResult.stopConditionOverride = RandomSwapResult
187 .Stop;
188 }
190 }
191
192 return randomSwapResult;
193 }
194
195 protected void ValidateCandidatesGPU()
196 {
197 this.computeShader.SetInt("num_clusters", this.clusteringRTsAndBuffers.numClusters);
198
199 this.computeShader.SetBuffer(
200 this.kernelHandleValidateCandidates,
201 "cbuf_cluster_centers",
203 );
204
205 this.computeShader.Dispatch(this.kernelHandleValidateCandidates, 1, 1, 1);
206 }
207
208 protected void RandomSwap(ClusteringTextures clusteringTextures)
209 {
211
212 this.computeShader.SetBuffer(
213 this.kernelHandleRandomSwap,
214 "cbuf_cluster_centers",
216 );
217 this.computeShader.SetBuffer(
218 this.kernelHandleRandomSwap,
219 "cbuf_random_positions",
221 );
222 this.computeShader.SetTexture(
223 this.kernelHandleRandomSwap,
224 "tex_input",
225 clusteringTextures.rtInput
226 );
227 this.computeShader.SetInt(
228 "random_cluster_center",
230 this.clusteringRTsAndBuffers.numClusters
231 )
232 );
233 this.computeShader.Dispatch(this.kernelHandleRandomSwap, 1, 1, 1);
234 }
235 }
236}
ClusteringRTsAndBuffers clusteringRTsAndBuffers
Definition: ADispatcher.cs:11
readonly ComputeShader computeShader
Definition: ADispatcher.cs:28
RandomSwapResult(StopConditionOverride stopConditionOverride, float varianceReduction, bool swapFailed)
ADispatcherRS(ComputeShader computeShader, int numIterations, bool doRandomizeEmptyClusters, bool useFullResTexRef, Parameters parameters, ClusteringRTsAndBuffers clusteringRTsAndBuffers)
override DispatcherParameters abstractParameters
RandomSwapResult ValidateCandidatesReadback()
void RandomSwap(ClusteringTextures clusteringTextures)
abstract override void RunClustering(ClusteringTextures clusteringTextures)
abstract override bool usesStopCondition
Call Dispose after using.
Call Allocate before using and Dispose after using.
ClusterCenters GetClusterCenters()
Get a pooled instance of ClusterCenters with a copy of the data from ComputeBuffer....
void SetClusterCenters(Vector4[] clusterCentersBufferData)
Reads the cluster centers data from the array and loads it into the ComputeBuffer.
Call Dispose after using.
readonly RenderTexture rtInput