xref: /aosp_15_r20/external/skia/docs/examples/SkSL_LinearSRGB.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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.
3 #include "tools/fiddle/examples.h"
4 REG_FIDDLE(SkSL_LinearSRGB, 256, 128, false, 0) {
draw(SkCanvas * canvas)5 void draw(SkCanvas* canvas) {
6   // Make a simple lighting effect:
7   auto litEffect = SkRuntimeEffect::MakeForShader(SkString(R"(
8     layout(color) uniform vec3 surfaceColor;
9     uniform int doLinearLighting;
10 
11     vec3 normal_at(vec2 p) {
12       p = (p / 128) * 2 - 1;
13       float len2 = dot(p, p);
14       vec3 n = (len2 > 1) ? vec3(0, 0, 1) : vec3(p, sqrt(1 - len2));
15       return normalize(n);
16     }
17 
18     vec4 main(vec2 p) {
19       vec3 n = normal_at(p);
20       vec3 l = normalize(vec3(-1, -1, 0.5));
21       vec3 C = surfaceColor;
22 
23       if (doLinearLighting != 0) { C = toLinearSrgb(C); }
24       C *= saturate(dot(n, l));
25       if (doLinearLighting != 0) { C = fromLinearSrgb(C); }
26 
27       return C.rgb1;
28     })")).effect;
29   SkRuntimeShaderBuilder builder(litEffect);
30   builder.uniform("surfaceColor") = SkV3{0.8, 0.8, 0.8};
31   SkPaint paint;
32 
33   // FIRST: Draw the lit sphere without converting to linear sRGB.
34   // This produces INCORRECT light falloff.
35   builder.uniform("doLinearLighting") = 0;
36   paint.setShader(builder.makeShader());
37   canvas->drawRect({0,0,128,128}, paint);
38 
39   // SECOND: Draw the lit sphere with math done in linear sRGB.
40   // This produces sharper falloff, which is CORRECT.
41   builder.uniform("doLinearLighting") = 1;
42   paint.setShader(builder.makeShader());
43   canvas->translate(128, 0);
44   canvas->drawRect({0,0,128,128}, paint);
45 }
46 }  // END FIDDLE
47