@@ -48,6 +48,11 @@ void CreatePaddedLutChannels(unsigned long width,
48
48
leftover -= step;
49
49
}
50
50
51
+ // Skip the duplicate entry if the last value is the last pixel on a row
52
+ if ((currWidth + (height -1 )) % width == 0 ) {
53
+ leftover -= 1 ;
54
+ }
55
+
51
56
// If there are still texels to fill, add them to the texture data.
52
57
if (leftover > 0 )
53
58
{
@@ -111,6 +116,11 @@ void CreatePaddedRedChannel(unsigned long width,
111
116
leftover -= step;
112
117
}
113
118
119
+ // Skip the duplicate entry if the last value is the last pixel on a row
120
+ if ((currWidth + (height -1 )) % width == 0 ) {
121
+ leftover -= 1 ;
122
+ }
123
+
114
124
// If there are still texels to fill, add them to the texture data.
115
125
if (leftover > 0 )
116
126
{
@@ -154,13 +164,27 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
154
164
155
165
const unsigned long length = lutData->getArray ().getLength ();
156
166
const unsigned long width = std::min (length, defaultMaxWidth);
157
- const unsigned long height = (length / defaultMaxWidth) + 1 ;
167
+ const unsigned long heightWithDuplicates = (length - 1 ) / (defaultMaxWidth - 1 ) + 1 ;
168
+
169
+ // The height is calculated based on the amount of rows without duplicate data.
170
+ // ceil(length / defaultMaxWidth)
171
+ const unsigned long heightWithoutDuplicates = (std::max (2UL , length) - 1 ) / defaultMaxWidth + 1 ;
172
+
173
+ // The result of this determines how many duplicate values are really needed.
174
+ // When the amount of rows is one, the amount of duplicate entries will be zero.
175
+ // ceil(length / defaultMaxWidth) -1)
176
+ const unsigned long numDuplicateEntries = heightWithoutDuplicates - 1 ;
177
+
178
+ // Once we know the amount of duplicate entries, we can calculate if the last
179
+ // value ends on the same scanline, if that is the case we won't need an extra line.
180
+ // ((ceil(length / defaultMaxWidth) -1 + length) % defaultMaxWidth == 0)
181
+ const unsigned long height = heightWithDuplicates - ((numDuplicateEntries + length) % defaultMaxWidth == 0 );
158
182
const unsigned long numChannels = lutData->getArray ().getNumColorComponents ();
159
183
160
- // Note: The 1D LUT needs a GPU texture for the Look-up table implementation.
184
+ // Note: The 1D LUT needs a GPU texture for the Look-up table implementation.
161
185
// However, the texture type & content may vary based on the number of channels
162
186
// i.e. when all channels are identical a F32 Red GPU texture is enough.
163
-
187
+
164
188
const bool singleChannel = (numChannels == 1 );
165
189
166
190
// Adjust LUT texture to allow for correct 2d linear interpolation, if needed.
@@ -335,13 +359,13 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
335
359
{
336
360
const std::string str = name + " _computePos(" + shaderCreator->getPixelName ();
337
361
338
- ss.newLine () << shaderCreator->getPixelName () << " .r = "
362
+ ss.newLine () << shaderCreator->getPixelName () << " .r = "
339
363
<< ss.sampleTex2D (name, str + " .r)" ) << " .r;" ;
340
364
341
365
ss.newLine () << shaderCreator->getPixelName () << " .g = "
342
366
<< ss.sampleTex2D (name, str + " .g)" ) << (singleChannel ? " .r;" : " .g;" );
343
367
344
- ss.newLine () << shaderCreator->getPixelName () << " .b = "
368
+ ss.newLine () << shaderCreator->getPixelName () << " .b = "
345
369
<< ss.sampleTex2D (name, str + " .b)" ) << (singleChannel ? " .r;" : " .b;" );
346
370
}
347
371
else
@@ -387,4 +411,3 @@ void GetLut1DGPUShaderProgram(GpuShaderCreatorRcPtr & shaderCreator,
387
411
}
388
412
389
413
} // namespace OCIO_NAMESPACE
390
-
0 commit comments