Runtime effect implementation of color cube filter
Bug: skia:10274 Change-Id: Ifb2ef8bf031e74d9d5c8183efe5aff4e6f3d2e7c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292562 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
afd4113bc3
commit
9c3eccd5d7
@ -237,3 +237,89 @@ class SpiralRT : public skiagm::GM {
|
||||
}
|
||||
};
|
||||
DEF_GM(return new SpiralRT;)
|
||||
|
||||
class ColorCubeRT : public skiagm::GM {
|
||||
sk_sp<SkImage> fMandrill, fMandrillSepia, fIdentityCube, fSepiaCube;
|
||||
sk_sp<SkRuntimeEffect> fEffect;
|
||||
|
||||
void onOnceBeforeDraw() override {
|
||||
fMandrill = GetResourceAsImage("images/mandrill_256.png");
|
||||
fMandrillSepia = GetResourceAsImage("images/mandrill_sepia.png");
|
||||
fIdentityCube = GetResourceAsImage("images/lut_identity.png");
|
||||
fSepiaCube = GetResourceAsImage("images/lut_sepia.png");
|
||||
|
||||
const char code[] = R"(
|
||||
in shader input;
|
||||
in shader color_cube;
|
||||
|
||||
uniform float size;
|
||||
uniform float size_minus_1;
|
||||
|
||||
void main(float2 xy, inout half4 color) {
|
||||
float4 c = float4(unpremul(sample(input, xy)));
|
||||
|
||||
// Map to cube coords:
|
||||
float3 cubeCoords = float3(c.rg * size_minus_1 + 0.5, c.b * size_minus_1);
|
||||
|
||||
// Compute slice coordinate
|
||||
float2 coords1 = float2(floor(cubeCoords.b) * size + cubeCoords.r, cubeCoords.g);
|
||||
float2 coords2 = float2( ceil(cubeCoords.b) * size + cubeCoords.r, cubeCoords.g);
|
||||
|
||||
// Two bilinear fetches, plus a manual lerp for the third axis:
|
||||
color = mix(sample(color_cube, coords1), sample(color_cube, coords2),
|
||||
half(fract(cubeCoords.b)));
|
||||
|
||||
// Premul again
|
||||
color.rgb *= color.a;
|
||||
}
|
||||
)";
|
||||
auto [effect, error] = SkRuntimeEffect::Make(SkString(code));
|
||||
if (!effect) {
|
||||
SkDebugf("runtime error %s\n", error.c_str());
|
||||
}
|
||||
fEffect = effect;
|
||||
}
|
||||
|
||||
SkString onShortName() override { return SkString("color_cube_rt"); }
|
||||
|
||||
SkISize onISize() override { return {256 * 3, 256}; }
|
||||
|
||||
DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
|
||||
if (canvas->getGrContext() == nullptr) {
|
||||
// until SkSL can handle child processors on the raster backend
|
||||
return DrawResult::kSkip;
|
||||
}
|
||||
|
||||
// First we draw the unmodified image, and a copy that was sepia-toned in Photoshop:
|
||||
canvas->drawImage(fMandrill, 0, 0);
|
||||
canvas->drawImage(fMandrillSepia, 0, 256);
|
||||
|
||||
// LUT dimensions should be (kSize^2, kSize)
|
||||
constexpr float kSize = 16.0f;
|
||||
|
||||
SkRuntimeShaderBuilder builder(fEffect);
|
||||
builder.input("size") = kSize;
|
||||
builder.input("size_minus_1") = kSize - 1;
|
||||
builder.child("input") = fMandrill->makeShader();
|
||||
|
||||
// TODO: Move filter quality to the shader itself. We need to enforce at least kLow here
|
||||
// so that we bilerp the color cube image.
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
|
||||
// Now draw the image with an identity color cube - it should look like the original
|
||||
builder.child("color_cube") = fIdentityCube->makeShader();
|
||||
paint.setShader(builder.makeShader(nullptr, true));
|
||||
canvas->translate(256, 0);
|
||||
canvas->drawRect({ 0, 0, 256, 256 }, paint);
|
||||
|
||||
// ... and with a sepia-tone color cube. This should match the sepia-toned image.
|
||||
builder.child("color_cube") = fSepiaCube->makeShader();
|
||||
paint.setShader(builder.makeShader(nullptr, true));
|
||||
canvas->translate(0, 256);
|
||||
canvas->drawRect({ 0, 0, 256, 256 }, paint);
|
||||
|
||||
return DrawResult::kOk;
|
||||
}
|
||||
};
|
||||
DEF_GM(return new ColorCubeRT;)
|
||||
|
BIN
resources/images/lut_identity.png
Normal file
BIN
resources/images/lut_identity.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 286 B |
BIN
resources/images/lut_sepia.png
Normal file
BIN
resources/images/lut_sepia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
resources/images/mandrill_sepia.png
Normal file
BIN
resources/images/mandrill_sepia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
Loading…
Reference in New Issue
Block a user