跳到主要内容

运行时着色器

RuntimeShader 图像滤镜允许您将自己的 Skia 着色器 作为图像滤镜编写。 此组件接收当前过滤后的图像作为着色器 uniform(如果未提供子元素,则为隐式源图像)。

信息

由于 RuntimeShader 不考虑像素密度缩放,我们建议应用一种称为超采样技术。 请参见下文

名称类型描述
sourceSkRuntimeEffect用作图像滤镜的着色器
children?ImageFilter可选的先应用的图像滤镜

示例

下面的示例生成一个绿薄荷色的圆圈。 圆圈首先用浅蓝色 #add8e6 绘制,运行时着色器将蓝色通道与绿色通道切换:我们得到薄荷绿色 #ade6d8

tsx
import {Canvas, Text, RuntimeShader, Skia, Group, Circle} from "@shopify/react-native-skia";
 
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
 
half4 main(float2 xy) {
return image.eval(xy).rbga;
}
`)!;
 
export const RuntimeShaderDemo = () => {
const r = 128;
return (
<Canvas style={{ flex: 1 }}>
<Group>
<RuntimeShader source={source} />
<Circle cx={r} cy={r} r={r} color="lightblue" />
</Group>
</Canvas>
);
};
tsx
import {Canvas, Text, RuntimeShader, Skia, Group, Circle} from "@shopify/react-native-skia";
 
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
 
half4 main(float2 xy) {
return image.eval(xy).rbga;
}
`)!;
 
export const RuntimeShaderDemo = () => {
const r = 128;
return (
<Canvas style={{ flex: 1 }}>
<Group>
<RuntimeShader source={source} />
<Circle cx={r} cy={r} r={r} color="lightblue" />
</Group>
</Canvas>
);
};
Runtime Shader

像素密度

RuntimeShader 不考虑像素密度缩放(了解更多原因)。 为了保持图像滤镜输出的清晰度,我们将过滤后的绘图放大到 应用程序的像素密度。 过滤绘图后,我们将其缩放回原始大小。 这可以在下面的示例中看到。 这些操作必须通过 layer 属性在 Skia 图层上执行。

tsx
import {Canvas, Text, RuntimeShader, Skia, Group, Circle, Paint, Fill, useFont} from "@shopify/react-native-skia";
import {PixelRatio} from "react-native";
 
const pd = PixelRatio.get();
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
 
half4 main(float2 xy) {
if (xy.x < 256 * ${pd}/2) {
return color;
}
return image.eval(xy).rbga;
}
`)!;
 
export const RuntimeShaderDemo = () => {
const r = 128;
const font = useFont(require("./SF-Pro.ttf"), 24);
return (
<Canvas style={{ flex: 1 }}>
<Group transform={[{ scale: 1 / pd }]}>
<Group
layer={
<Paint>
<RuntimeShader source={source} />
</Paint>
}
transform={[{ scale: pd }]}
>
<Fill color="#b7c9e2" />
<Text
text="Hello World"
x={16}
y={32}
color="#e38ede"
font={font}
/>
</Group>
</Group>
</Canvas>
);
};
tsx
import {Canvas, Text, RuntimeShader, Skia, Group, Circle, Paint, Fill, useFont} from "@shopify/react-native-skia";
import {PixelRatio} from "react-native";
 
const pd = PixelRatio.get();
const source = Skia.RuntimeEffect.Make(`
uniform shader image;
 
half4 main(float2 xy) {
if (xy.x < 256 * ${pd}/2) {
return color;
}
return image.eval(xy).rbga;
}
`)!;
 
export const RuntimeShaderDemo = () => {
const r = 128;
const font = useFont(require("./SF-Pro.ttf"), 24);
return (
<Canvas style={{ flex: 1 }}>
<Group transform={[{ scale: 1 / pd }]}>
<Group
layer={
<Paint>
<RuntimeShader source={source} />
</Paint>
}
transform={[{ scale: pd }]}
>
<Fill color="#b7c9e2" />
<Text
text="Hello World"
x={16}
y={32}
color="#e38ede"
font={font}
/>
</Group>
</Group>
</Canvas>
);
};
使用超采样不使用超采样
Runtime Shader
Runtime Shader