Flutter Engine
The Flutter Engine
SkSL_RawImageShaders.cpp
Go to the documentation of this file.
1// Copyright 2024 Google LLC.
2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4REG_FIDDLE(SkSL_RawImageShaders, 384, 128, false, 0) {
6 const SkImageInfo& info) {
8 SkCanvas* canvas = surface->getCanvas();
9 auto shader = effect->makeShader(/*uniforms=*/ nullptr, /*children=*/ {});
10 if (!shader) {
11 return nullptr;
12 }
14 paint.setShader(std::move(shader));
15 paint.setBlendMode(SkBlendMode::kSrc);
16 canvas->drawPaint(paint);
17 return surface->makeImageSnapshot();
18}
19
20void draw(SkCanvas* canvas) {
21 // Make a hemispherical normal map image:
22 auto imageInfo = SkImageInfo::MakeN32Premul(128, 128);
23 auto imageShader = SkRuntimeEffect::MakeForShader(SkString(R"(
24 vec4 main(vec2 p) {
25 p = (p / 128) * 2 - 1;
26 float len2 = dot(p, p);
27 vec3 v = (len2 > 1) ? vec3(0, 0, 1) : vec3(p, sqrt(1 - len2));
28 return (v * 0.5 + 0.5).xyz1;
29 })")).effect;
30 auto normalImage = make_image(imageShader, imageInfo);
31
32 // Make a simple lighting effect:
33 auto litEffect = SkRuntimeEffect::MakeForShader(SkString(R"(
34 uniform shader normals;
35 vec4 main(vec2 p) {
36 vec3 n = normalize(normals.eval(p).xyz * 2 - 1);
37 vec3 l = normalize(vec3(-1, -1, 0.5));
38 return saturate(dot(n, l)).xxx1;
39 })")).effect;
42
43 // FIRST: Draw the lighting to our (not color managed) canvas.
44 // This is our CORRECT, reference result:
45 builder.child("normals") = normalImage->makeShader(SkSamplingOptions{});
46 paint.setShader(builder.makeShader());
47 canvas->drawRect({0,0,128,128}, paint);
48
49 // Make an offscreen surface with a wide gamut:
55
56 // SECOND: Draw the lighting to the offscreen surface. Color management
57 // changes the normals, producing INCORRECT (wrong direction) lighting:
58 surface->getCanvas()->drawPaint(paint);
59 canvas->drawImage(surface->makeImageSnapshot(), 128, 0);
60
61 // THIRD: Convert the normals to a raw image shader. This ignores color
62 // management for that image, so we get CORRECT lighting again:
63 builder.child("normals") = normalImage->makeRawShader(SkSamplingOptions{});
64 paint.setShader(builder.makeShader());
65 surface->getCanvas()->drawPaint(paint);
66 canvas->drawImage(surface->makeImageSnapshot(), 256, 0);
67}} // END FIDDLE
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
static sk_sp< SkColorSpace > rec2020()
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
REG_FIDDLE(SkSL_RawImageShaders, 384, 128, false, 0)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
static sk_sp< SkImage > make_image(SkCanvas *destCanvas)
Definition: bitmaprect.cpp:31
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
sk_sp< SkShader > makeShader(sk_sp< const SkData > uniforms, sk_sp< SkShader > children[], size_t childCount, const SkMatrix *localMatrix=nullptr) const
static Result MakeForShader(SkString sksl, const Options &)
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
static constexpr skcms_Matrix3x3 kRec2020
Definition: SkColorSpace.h:93
static constexpr skcms_TransferFunction kSRGB
Definition: SkColorSpace.h:45
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
sk_sp< SkRuntimeEffect > effect