| // Copyright 2024 Google LLC. | |
| // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | |
| #include "tools/fiddle/examples.h" | |
| REG_FIDDLE(SkSL_LinearSRGB, 256, 128, false, 0) { | |
| void draw(SkCanvas* canvas) { | |
| // Make a simple lighting effect: | |
| auto litEffect = SkRuntimeEffect::MakeForShader(SkString(R"( | |
| layout(color) uniform vec3 surfaceColor; | |
| uniform int doLinearLighting; | |
| vec3 normal_at(vec2 p) { | |
| p = (p / 128) * 2 - 1; | |
| float len2 = dot(p, p); | |
| vec3 n = (len2 > 1) ? vec3(0, 0, 1) : vec3(p, sqrt(1 - len2)); | |
| return normalize(n); | |
| } | |
| vec4 main(vec2 p) { | |
| vec3 n = normal_at(p); | |
| vec3 l = normalize(vec3(-1, -1, 0.5)); | |
| vec3 C = surfaceColor; | |
| if (doLinearLighting != 0) { C = toLinearSrgb(C); } | |
| C *= saturate(dot(n, l)); | |
| if (doLinearLighting != 0) { C = fromLinearSrgb(C); } | |
| return C.rgb1; | |
| })")).effect; | |
| SkRuntimeShaderBuilder builder(litEffect); | |
| builder.uniform("surfaceColor") = SkV3{0.8, 0.8, 0.8}; | |
| SkPaint paint; | |
| // FIRST: Draw the lit sphere without converting to linear sRGB. | |
| // This produces INCORRECT light falloff. | |
| builder.uniform("doLinearLighting") = 0; | |
| paint.setShader(builder.makeShader()); | |
| canvas->drawRect({0,0,128,128}, paint); | |
| // SECOND: Draw the lit sphere with math done in linear sRGB. | |
| // This produces sharper falloff, which is CORRECT. | |
| builder.uniform("doLinearLighting") = 1; | |
| paint.setShader(builder.makeShader()); | |
| canvas->translate(128, 0); | |
| canvas->drawRect({0,0,128,128}, paint); | |
| } | |
| } // END FIDDLE |