shaders: Tetrahedral 3D LUT implementation
This commit is contained in:
parent
e806d790f0
commit
aaaff2cb16
3 changed files with 142 additions and 2 deletions
33
LICENSE
33
LICENSE
|
@ -24,3 +24,36 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
========================================================
|
||||
|
||||
Tetrahedal 3D LUT code from OpenColorIO
|
||||
|
||||
Licensed under BSD 3-Clause "New" or "Revised" License:
|
||||
|
||||
Copyright Contributors to the OpenColorIO Project.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
@ -1774,7 +1774,7 @@ void CVulkanCmdBuffer::dispatch(uint32_t x, uint32_t y, uint32_t z)
|
|||
// I need to change this, it's so utterly stupid and confusing.
|
||||
shaperLutDescriptor[i].imageView = m_shaperLut[i] ? m_shaperLut[i]->srgbView() : nullptr;
|
||||
|
||||
lut3DDescriptor[i].sampler = m_device->sampler(linearState);
|
||||
lut3DDescriptor[i].sampler = m_device->sampler(nearestState);
|
||||
lut3DDescriptor[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
lut3DDescriptor[i].imageView = m_lut3D[i] ? m_lut3D[i]->srgbView() : nullptr;
|
||||
}
|
||||
|
|
|
@ -413,10 +413,117 @@ vec3 perform_1dlut(vec3 color, sampler1D shaperLUT) {
|
|||
textureLod(shaperLUT, half_texel_scale(color.b, offset), 0.0f).b);
|
||||
}
|
||||
|
||||
vec3 perform_3dlut(vec3 color, sampler3D lut3D) {
|
||||
vec3 perform_3dlut_native(vec3 color, sampler3D lut3D) {
|
||||
ivec3 size = textureSize(lut3D, 0);
|
||||
vec3 offset = 0.5f / vec3(float(size.x), float(size.y), float(size.z));
|
||||
|
||||
return textureLod(lut3D, half_texel_scale(color.rgb, offset), 0.0f).rgb;
|
||||
}
|
||||
|
||||
// Adapted from:
|
||||
// https://github.com/AcademySoftwareFoundation/OpenColorIO/ops/lut3d/Lut3DOpGPU.cpp
|
||||
// License available in their repo and in our LICENSE file.
|
||||
vec3 perform_3dlut_tetrahedral(vec3 color, sampler3D lut3D) {
|
||||
ivec3 size_i = textureSize(lut3D, 0);
|
||||
// We only support uniform lut sizes so take .x's dim
|
||||
float size = float(size_i.x);
|
||||
float incr = 1.0f / size;
|
||||
|
||||
vec3 outColor = color.bgr;
|
||||
|
||||
vec3 coords = outColor.rgb * (vec3(size - 1.0f));
|
||||
vec3 baseInd = floor(coords);
|
||||
vec3 frac = coords - baseInd;
|
||||
vec3 f1, f4;
|
||||
baseInd = (baseInd.zyx + vec3(0.5)) / vec3(size);
|
||||
vec3 v1 = textureLod(lut3D, baseInd, 0).rgb;
|
||||
vec3 nextInd = baseInd + vec3(incr);
|
||||
vec3 v4 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
if (frac.r >= frac.g)
|
||||
{
|
||||
if (frac.g >= frac.b)
|
||||
{
|
||||
nextInd = baseInd + vec3(0, 0, incr);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(0, incr, incr);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.r);
|
||||
f4 = vec3(frac.b);
|
||||
vec3 f2 = vec3(frac.r - frac.g);
|
||||
vec3 f3 = vec3(frac.g - frac.b);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
else if (frac.r >= frac.b)
|
||||
{
|
||||
nextInd = baseInd + vec3(0, 0, incr);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(incr, 0, incr);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.r);
|
||||
f4 = vec3(frac.g);
|
||||
vec3 f2 = vec3(frac.r - frac.b);
|
||||
vec3 f3 = vec3(frac.b - frac.g);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextInd = baseInd + vec3(incr, 0, 0);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(incr, 0, incr);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.b);
|
||||
f4 = vec3(frac.g);
|
||||
vec3 f2 = vec3(frac.b - frac.r);
|
||||
vec3 f3 = vec3(frac.r - frac.g);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (frac.g <= frac.b)
|
||||
{
|
||||
nextInd = baseInd + vec3(incr, 0, 0);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(incr, incr, 0);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.b);
|
||||
f4 = vec3(frac.r);
|
||||
vec3 f2 = vec3(frac.b - frac.g);
|
||||
vec3 f3 = vec3(frac.g - frac.r);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
else if (frac.r >= frac.b)
|
||||
{
|
||||
nextInd = baseInd + vec3(0, incr, 0);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(0, incr, incr);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.g);
|
||||
f4 = vec3(frac.b);
|
||||
vec3 f2 = vec3(frac.g - frac.r);
|
||||
vec3 f3 = vec3(frac.r - frac.b);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextInd = baseInd + vec3(0, incr, 0);
|
||||
vec3 v2 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
nextInd = baseInd + vec3(incr, incr, 0);
|
||||
vec3 v3 = textureLod(lut3D, nextInd, 0).rgb;
|
||||
f1 = vec3(1.0f - frac.g);
|
||||
f4 = vec3(frac.r);
|
||||
vec3 f2 = vec3(frac.g - frac.b);
|
||||
vec3 f3 = vec3(frac.b - frac.r);
|
||||
outColor.rgb = (f2 * v2) + (f3 * v3);
|
||||
}
|
||||
}
|
||||
outColor.rgb = outColor.rgb + (f1 * v1) + (f4 * v4);
|
||||
|
||||
return outColor.rgb;
|
||||
}
|
||||
|
||||
vec3 perform_3dlut(vec3 color, sampler3D lut3D)
|
||||
{
|
||||
return perform_3dlut_tetrahedral(color, lut3D);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue