| // 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 |