diff --git a/doc/filters.texi b/doc/filters.texi
index a38f9b4124..52458c116d 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -13868,6 +13868,8 @@ Interpolate values using the 8 points defining a cube.
 Interpolate values using a tetrahedron.
 @item pyramid
 Interpolate values using a pyramid.
+@item prism
+Interpolate values using a prism.
 @end table
 @end table
 
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index 12eb15fe67..fb33c93c34 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -50,6 +50,7 @@ enum interp_mode {
     INTERPOLATE_TRILINEAR,
     INTERPOLATE_TETRAHEDRAL,
     INTERPOLATE_PYRAMID,
+    INTERPOLATE_PRISM,
     NB_INTERP_MODE
 };
 
@@ -105,6 +106,7 @@ typedef struct ThreadData {
         { "trilinear",   "interpolate values using the 8 points defining a cube", 0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TRILINEAR},   INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
         { "tetrahedral", "interpolate values using a tetrahedron",                0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_TETRAHEDRAL}, INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
         { "pyramid",     "interpolate values using a pyramid",                    0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PYRAMID},     INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
+        { "prism",       "interpolate values using a prism",                      0, AV_OPT_TYPE_CONST, {.i64=INTERPOLATE_PRISM},       INT_MIN, INT_MAX, FLAGS, "interp_mode" }, \
     { NULL }
 
 #define EXPONENT_MASK 0x7F800000
@@ -237,6 +239,51 @@ static inline struct rgbvec interp_pyramid(const LUT3DContext *lut3d,
     return c;
 }
 
+static inline struct rgbvec interp_prism(const LUT3DContext *lut3d,
+                                         const struct rgbvec *s)
+{
+    const int lutsize2 = lut3d->lutsize2;
+    const int lutsize  = lut3d->lutsize;
+    const int prev[] = {PREV(s->r), PREV(s->g), PREV(s->b)};
+    const int next[] = {NEXT(s->r), NEXT(s->g), NEXT(s->b)};
+    const struct rgbvec d = {s->r - prev[0], s->g - prev[1], s->b - prev[2]};
+    const struct rgbvec c000 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + prev[2]];
+    const struct rgbvec c010 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + prev[2]];
+    const struct rgbvec c101 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + next[2]];
+    const struct rgbvec c111 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + next[2]];
+    struct rgbvec c;
+
+    if (d.b > d.r) {
+        const struct rgbvec c001 = lut3d->lut[prev[0] * lutsize2 + prev[1] * lutsize + next[2]];
+        const struct rgbvec c011 = lut3d->lut[prev[0] * lutsize2 + next[1] * lutsize + next[2]];
+
+        c.r = c000.r + (c001.r - c000.r) * d.b + (c101.r - c001.r) * d.r + (c010.r - c000.r) * d.g +
+              (c000.r - c010.r - c001.r + c011.r) * d.b * d.g +
+              (c001.r - c011.r - c101.r + c111.r) * d.r * d.g;
+        c.g = c000.g + (c001.g - c000.g) * d.b + (c101.g - c001.g) * d.r + (c010.g - c000.g) * d.g +
+              (c000.g - c010.g - c001.g + c011.g) * d.b * d.g +
+              (c001.g - c011.g - c101.g + c111.g) * d.r * d.g;
+        c.b = c000.b + (c001.b - c000.b) * d.b + (c101.b - c001.b) * d.r + (c010.b - c000.b) * d.g +
+              (c000.b - c010.b - c001.b + c011.b) * d.b * d.g +
+              (c001.b - c011.b - c101.b + c111.b) * d.r * d.g;
+    } else {
+        const struct rgbvec c110 = lut3d->lut[next[0] * lutsize2 + next[1] * lutsize + prev[2]];
+        const struct rgbvec c100 = lut3d->lut[next[0] * lutsize2 + prev[1] * lutsize + prev[2]];
+
+        c.r = c000.r + (c101.r - c100.r) * d.b + (c100.r - c000.r) * d.r + (c010.r - c000.r) * d.g +
+              (c100.r - c110.r - c101.r + c111.r) * d.b * d.g +
+              (c000.r - c010.r - c100.r + c110.r) * d.r * d.g;
+        c.g = c000.g + (c101.g - c100.g) * d.b + (c100.g - c000.g) * d.r + (c010.g - c000.g) * d.g +
+              (c100.g - c110.g - c101.g + c111.g) * d.b * d.g +
+              (c000.g - c010.g - c100.g + c110.g) * d.r * d.g;
+        c.b = c000.b + (c101.b - c100.b) * d.b + (c100.b - c000.b) * d.r + (c010.b - c000.b) * d.g +
+              (c100.b - c110.b - c101.b + c111.b) * d.b * d.g +
+              (c000.b - c010.b - c100.b + c110.b) * d.r * d.g;
+    }
+
+    return c;
+}
+
 /**
  * Tetrahedral interpolation. Based on code found in Truelight Software Library paper.
  * @see http://www.filmlight.ltd.uk/pdf/whitepapers/FL-TL-TN-0057-SoftwareLib.pdf
@@ -390,31 +437,37 @@ DEFINE_INTERP_FUNC_PLANAR(nearest,     8, 8)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   8, 8)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 8, 8)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     8, 8)
+DEFINE_INTERP_FUNC_PLANAR(prism,       8, 8)
 
 DEFINE_INTERP_FUNC_PLANAR(nearest,     16, 9)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   16, 9)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 9)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     16, 9)
+DEFINE_INTERP_FUNC_PLANAR(prism,       16, 9)
 
 DEFINE_INTERP_FUNC_PLANAR(nearest,     16, 10)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   16, 10)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 10)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     16, 10)
+DEFINE_INTERP_FUNC_PLANAR(prism,       16, 10)
 
 DEFINE_INTERP_FUNC_PLANAR(nearest,     16, 12)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   16, 12)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 12)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     16, 12)
+DEFINE_INTERP_FUNC_PLANAR(prism,       16, 12)
 
 DEFINE_INTERP_FUNC_PLANAR(nearest,     16, 14)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   16, 14)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 14)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     16, 14)
+DEFINE_INTERP_FUNC_PLANAR(prism,       16, 14)
 
 DEFINE_INTERP_FUNC_PLANAR(nearest,     16, 16)
 DEFINE_INTERP_FUNC_PLANAR(trilinear,   16, 16)
 DEFINE_INTERP_FUNC_PLANAR(tetrahedral, 16, 16)
 DEFINE_INTERP_FUNC_PLANAR(pyramid,     16, 16)
+DEFINE_INTERP_FUNC_PLANAR(prism,       16, 16)
 
 #define DEFINE_INTERP_FUNC_PLANAR_FLOAT(name, depth)                                                   \
 static int interp_##name##_pf##depth(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)          \
@@ -481,6 +534,7 @@ DEFINE_INTERP_FUNC_PLANAR_FLOAT(nearest,     32)
 DEFINE_INTERP_FUNC_PLANAR_FLOAT(trilinear,   32)
 DEFINE_INTERP_FUNC_PLANAR_FLOAT(tetrahedral, 32)
 DEFINE_INTERP_FUNC_PLANAR_FLOAT(pyramid,     32)
+DEFINE_INTERP_FUNC_PLANAR_FLOAT(prism,       32)
 
 #define DEFINE_INTERP_FUNC(name, nbits)                                                             \
 static int interp_##nbits##_##name(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)         \
@@ -535,11 +589,13 @@ DEFINE_INTERP_FUNC(nearest,     8)
 DEFINE_INTERP_FUNC(trilinear,   8)
 DEFINE_INTERP_FUNC(tetrahedral, 8)
 DEFINE_INTERP_FUNC(pyramid,     8)
+DEFINE_INTERP_FUNC(prism,       8)
 
 DEFINE_INTERP_FUNC(nearest,     16)
 DEFINE_INTERP_FUNC(trilinear,   16)
 DEFINE_INTERP_FUNC(tetrahedral, 16)
 DEFINE_INTERP_FUNC(pyramid,     16)
+DEFINE_INTERP_FUNC(prism,       16)
 
 #define MAX_LINE_SIZE 512
 
@@ -1148,6 +1204,7 @@ static int config_input(AVFilterLink *inlink)
     case INTERPOLATE_TRILINEAR:   SET_FUNC(trilinear);      break;
     case INTERPOLATE_TETRAHEDRAL: SET_FUNC(tetrahedral);    break;
     case INTERPOLATE_PYRAMID:     SET_FUNC(pyramid);        break;
+    case INTERPOLATE_PRISM:       SET_FUNC(prism);          break;
     default:
         av_assert0(0);
     }
