着色语言
Skia 提供了一种着色语言。你可以在这里进行尝试。它的语法与 GLSL 非常相似。如果你已经熟悉 GLSL,或者想将 GLSL 着色器转换为 SKSL,你可以在这里查看它们的差异列表。
第一步是创建着色器并使用 RuntimeEffect.Make
编译它。
tsx
import {Skia } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`vec4 main(vec2 pos) {// The canvas is 256x256vec2 canvas = vec2(256);// normalized x,y values go from 0 to 1vec2 normalized = pos/canvas;return vec4(normalized.x, normalized.y, 0.5, 1);}`);if (!source ) {throw newError ("Couldn't compile the shader")}
tsx
import {Skia } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`vec4 main(vec2 pos) {// The canvas is 256x256vec2 canvas = vec2(256);// normalized x,y values go from 0 to 1vec2 normalized = pos/canvas;return vec4(normalized.x, normalized.y, 0.5, 1);}`);if (!source ) {throw newError ("Couldn't compile the shader")}
着色器
从源代码创建着色器。着色器可以相互嵌套。
名称 | 类型 | 描述 |
---|---|---|
source | RuntimeEffect | 已编译的着色器 |
uniforms | { [name: string]: number|矢量|矢量[]|数字[]|数字[][] } | uniform 值 |
children | 着色器 | 用作 uniform 的着色器 |
简单着色器
tsx
import {Skia ,Canvas ,Shader ,Fill } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`vec4 main(vec2 pos) {// normalized x,y values go from 0 to 1, the canvas is 256x256vec2 normalized = pos/vec2(256);return vec4(normalized.x, normalized.y, 0.5, 1);}`)!;constSimpleShader = () => {return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source } /></Fill ></Canvas >);};
tsx
import {Skia ,Canvas ,Shader ,Fill } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`vec4 main(vec2 pos) {// normalized x,y values go from 0 to 1, the canvas is 256x256vec2 normalized = pos/vec2(256);return vec4(normalized.x, normalized.y, 0.5, 1);}`)!;constSimpleShader = () => {return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source } /></Fill ></Canvas >);};
使用 Uniforms
Uniforms 是用于参数化着色器的变量。支持以下 uniform 类型:float
、float2
、float3
、float4
、float2x2
、float3x3
、float4x4
、int
、int2
、int3
和 int4
。这些类型也可以用作数组,例如 uniform float3 colors[12]
。
tsx
import {Canvas ,Skia ,Shader ,Fill ,vec } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`uniform vec2 c;uniform float r;uniform float blue;vec4 main(vec2 pos) {vec2 normalized = pos/vec2(2 * r);return distance(pos, c) > r ? vec4(1) : vec4(normalized, blue, 1);}`)!;constUniformShader = () => {constr = 128;constc =vec (2 *r ,r );constblue = 1.0;return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source }uniforms ={{c ,r ,blue }} /></Fill ></Canvas >);};
tsx
import {Canvas ,Skia ,Shader ,Fill ,vec } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`uniform vec2 c;uniform float r;uniform float blue;vec4 main(vec2 pos) {vec2 normalized = pos/vec2(2 * r);return distance(pos, c) > r ? vec4(1) : vec4(normalized, blue, 1);}`)!;constUniformShader = () => {constr = 128;constc =vec (2 *r ,r );constblue = 1.0;return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source }uniforms ={{c ,r ,blue }} /></Fill ></Canvas >);};
嵌套着色器
tsx
import {Canvas ,Skia ,ImageShader ,Shader ,Fill ,useImage } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`uniform shader image;half4 main(float2 xy) {xy.x += sin(xy.y / 3) * 4;return image.eval(xy).rbga;}`)!;constNestedShader = () => {constimage =useImage (require ("./assets/oslo.jpg"));if (!image ) {return null;}return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source }><ImageShader image ={image }fit ="cover"rect ={{x : 0,y : 0,width : 256,height : 256 }}/></Shader ></Fill ></Canvas >);};
tsx
import {Canvas ,Skia ,ImageShader ,Shader ,Fill ,useImage } from "@shopify/react-native-skia";constsource =Skia .RuntimeEffect .Make (`uniform shader image;half4 main(float2 xy) {xy.x += sin(xy.y / 3) * 4;return image.eval(xy).rbga;}`)!;constNestedShader = () => {constimage =useImage (require ("./assets/oslo.jpg"));if (!image ) {return null;}return (<Canvas style ={{width : 256,height : 256 }}><Fill ><Shader source ={source }><ImageShader image ={image }fit ="cover"rect ={{x : 0,y : 0,width : 256,height : 256 }}/></Shader ></Fill ></Canvas >);};