blob: d0b62c0b6a5cbfb7faeb73a6fef89887d0f21cf4 [file] [log] [blame]
 // Intrinsics that are available to public SkSL (SkRuntimeEffect) // See "The OpenGL ES Shading Language, Section 8" // 8.1 : Angle and Trigonometry Functions \$genType radians(\$genType degrees); \$genHType radians(\$genHType degrees); \$genType degrees(\$genType radians); \$genHType degrees(\$genHType radians); \$genType sin(\$genType angle); \$genHType sin(\$genHType angle); \$genType cos(\$genType angle); \$genHType cos(\$genHType angle); \$genType tan(\$genType angle); \$genHType tan(\$genHType angle); \$genType asin(\$genType x); \$genHType asin(\$genHType x); \$genType acos(\$genType x); \$genHType acos(\$genHType x); \$genType atan(\$genType y, \$genType x); \$genHType atan(\$genHType y, \$genHType x); \$genType atan(\$genType y_over_x); \$genHType atan(\$genHType y_over_x); // 8.1 : Angle and Trigonometry Functions (GLSL ES 3.0) \$es3 \$genType sinh(\$genType x); \$es3 \$genHType sinh(\$genHType x); \$es3 \$genType cosh(\$genType x); \$es3 \$genHType cosh(\$genHType x); \$es3 \$genType tanh(\$genType x); \$es3 \$genHType tanh(\$genHType x); \$es3 \$genType asinh(\$genType x); \$es3 \$genHType asinh(\$genHType x); \$es3 \$genType acosh(\$genType x); \$es3 \$genHType acosh(\$genHType x); \$es3 \$genType atanh(\$genType x); \$es3 \$genHType atanh(\$genHType x); // 8.2 : Exponential Functions \$genType pow(\$genType x, \$genType y); \$genHType pow(\$genHType x, \$genHType y); \$genType exp(\$genType x); \$genHType exp(\$genHType x); \$genType log(\$genType x); \$genHType log(\$genHType x); \$genType exp2(\$genType x); \$genHType exp2(\$genHType x); \$genType log2(\$genType x); \$genHType log2(\$genHType x); \$genType sqrt(\$genType x); \$genHType sqrt(\$genHType x); \$genType inversesqrt(\$genType x); \$genHType inversesqrt(\$genHType x); // 8.3 : Common Functions \$genType abs(\$genType x); \$genHType abs(\$genHType x); \$genType sign(\$genType x); \$genHType sign(\$genHType x); \$genType floor(\$genType x); \$genHType floor(\$genHType x); \$genType ceil(\$genType x); \$genHType ceil(\$genHType x); \$genType fract(\$genType x); \$genHType fract(\$genHType x); \$genType mod(\$genType x, float y); \$genType mod(\$genType x, \$genType y); \$genHType mod(\$genHType x, half y); \$genHType mod(\$genHType x, \$genHType y); \$genType min(\$genType x, \$genType y); \$genType min(\$genType x, float y); \$genHType min(\$genHType x, \$genHType y); \$genHType min(\$genHType x, half y); \$genType max(\$genType x, \$genType y); \$genType max(\$genType x, float y); \$genHType max(\$genHType x, \$genHType y); \$genHType max(\$genHType x, half y); \$genType clamp(\$genType x, \$genType minVal, \$genType maxVal); \$genType clamp(\$genType x, float minVal, float maxVal); \$genHType clamp(\$genHType x, \$genHType minVal, \$genHType maxVal); \$genHType clamp(\$genHType x, half minVal, half maxVal); \$genType saturate(\$genType x); // SkSL extension \$genHType saturate(\$genHType x); // SkSL extension \$genType mix(\$genType x, \$genType y, \$genType a); \$genType mix(\$genType x, \$genType y, float a); \$genHType mix(\$genHType x, \$genHType y, \$genHType a); \$genHType mix(\$genHType x, \$genHType y, half a); \$genType step(\$genType edge, \$genType x); \$genType step(float edge, \$genType x); \$genHType step(\$genHType edge, \$genHType x); \$genHType step(half edge, \$genHType x); \$genType smoothstep(\$genType edge0, \$genType edge1, \$genType x); \$genType smoothstep(float edge0, float edge1, \$genType x); \$genHType smoothstep(\$genHType edge0, \$genHType edge1, \$genHType x); \$genHType smoothstep(half edge0, half edge1, \$genHType x); // 8.3 : Common Functions (GLSL ES 3.0) \$es3 \$genIType abs(\$genIType x); \$es3 \$genIType sign(\$genIType x); \$es3 \$genIType floatBitsToInt (\$genType value); \$es3 \$genUType floatBitsToUint(\$genType value); \$es3 \$genType intBitsToFloat (\$genIType value); \$es3 \$genType uintBitsToFloat(\$genUType value); \$es3 \$genType trunc(\$genType x); \$es3 \$genHType trunc(\$genHType x); \$es3 \$genType round(\$genType x); \$es3 \$genHType round(\$genHType x); \$es3 \$genType roundEven(\$genType x); \$es3 \$genHType roundEven(\$genHType x); \$es3 \$genIType min(\$genIType x, \$genIType y); \$es3 \$genIType min(\$genIType x, int y); \$es3 \$genIType max(\$genIType x, \$genIType y); \$es3 \$genIType max(\$genIType x, int y); \$es3 \$genIType clamp(\$genIType x, \$genIType minVal, \$genIType maxVal); \$es3 \$genIType clamp(\$genIType x, int minVal, int maxVal); \$es3 \$genUType clamp(\$genUType x, \$genUType minVal, \$genUType maxVal); \$es3 \$genUType clamp(\$genUType x, uint minVal, uint maxVal); \$es3 \$genType mix(\$genType x, \$genType y, \$genBType a); \$es3 \$genHType mix(\$genHType x, \$genHType y, \$genBType a); // 8.3 : Common Functions (GLSL ES 3.0) -- cannot be used in constant-expressions \$es3 \$genBType isnan(\$genType x); \$es3 \$genBType isnan(\$genHType x); \$es3 \$genBType isinf(\$genType x); \$es3 \$genBType isinf(\$genHType x); \$es3 \$genType modf(\$genType x, out \$genType i); \$es3 \$genHType modf(\$genHType x, out \$genHType i); // 8.4 : Floating-Point Pack and Unpack Functions (GLSL ES 3.0) \$es3 uint packUnorm2x16(float2 v); \$es3 float2 unpackUnorm2x16(uint p); // 8.5 : Geometric Functions float length(\$genType x); half length(\$genHType x); float distance(\$genType p0, \$genType p1); half distance(\$genHType p0, \$genHType p1); float dot(\$genType x, \$genType y); half dot(\$genHType x, \$genHType y); float3 cross(float3 x, float3 y); half3 cross(half3 x, half3 y); \$genType normalize(\$genType x); \$genHType normalize(\$genHType x); \$genType faceforward(\$genType N, \$genType I, \$genType Nref); \$genHType faceforward(\$genHType N, \$genHType I, \$genHType Nref); \$genType reflect(\$genType I, \$genType N); \$genHType reflect(\$genHType I, \$genHType N); \$genType refract(\$genType I, \$genType N, float eta); \$genHType refract(\$genHType I, \$genHType N, half eta); // 8.6 : Matrix Functions \$squareMat matrixCompMult(\$squareMat x, \$squareMat y); \$squareHMat matrixCompMult(\$squareHMat x, \$squareHMat y); \$es3 \$mat matrixCompMult(\$mat x, \$mat y); \$es3 \$hmat matrixCompMult(\$hmat x, \$hmat y); // 8.6 : Matrix Functions (GLSL 1.4, poly-filled by SkSL as needed) \$squareMat inverse(\$squareMat m); \$squareHMat inverse(\$squareHMat m); // 8.6 : Matrix Functions (GLSL ES 3.0) \$es3 float determinant(\$squareMat m); \$es3 half determinant(\$squareHMat m); \$es3 \$squareMat transpose(\$squareMat m); \$es3 \$squareHMat transpose(\$squareHMat m); \$es3 float2x3 transpose(float3x2 m); \$es3 half2x3 transpose(half3x2 m); \$es3 float2x4 transpose(float4x2 m); \$es3 half2x4 transpose(half4x2 m); \$es3 float3x2 transpose(float2x3 m); \$es3 half3x2 transpose(half2x3 m); \$es3 float3x4 transpose(float4x3 m); \$es3 half3x4 transpose(half4x3 m); \$es3 float4x2 transpose(float2x4 m); \$es3 half4x2 transpose(half2x4 m); \$es3 float4x3 transpose(float3x4 m); \$es3 half4x3 transpose(half3x4 m); \$es3 \$squareMat outerProduct(\$vec c, \$vec r); \$es3 \$squareHMat outerProduct(\$hvec c, \$hvec r); \$es3 float2x3 outerProduct(float3 c, float2 r); \$es3 half2x3 outerProduct(half3 c, half2 r); \$es3 float3x2 outerProduct(float2 c, float3 r); \$es3 half3x2 outerProduct(half2 c, half3 r); \$es3 float2x4 outerProduct(float4 c, float2 r); \$es3 half2x4 outerProduct(half4 c, half2 r); \$es3 float4x2 outerProduct(float2 c, float4 r); \$es3 half4x2 outerProduct(half2 c, half4 r); \$es3 float3x4 outerProduct(float4 c, float3 r); \$es3 half3x4 outerProduct(half4 c, half3 r); \$es3 float4x3 outerProduct(float3 c, float4 r); \$es3 half4x3 outerProduct(half3 c, half4 r); // 8.7 : Vector Relational Functions \$bvec lessThan(\$vec x, \$vec y); \$bvec lessThan(\$hvec x, \$hvec y); \$bvec lessThan(\$ivec x, \$ivec y); \$bvec lessThanEqual(\$vec x, \$vec y); \$bvec lessThanEqual(\$hvec x, \$hvec y); \$bvec lessThanEqual(\$ivec x, \$ivec y); \$bvec greaterThan(\$vec x, \$vec y); \$bvec greaterThan(\$hvec x, \$hvec y); \$bvec greaterThan(\$ivec x, \$ivec y); \$bvec greaterThanEqual(\$vec x, \$vec y); \$bvec greaterThanEqual(\$hvec x, \$hvec y); \$bvec greaterThanEqual(\$ivec x, \$ivec y); \$bvec equal(\$vec x, \$vec y); \$bvec equal(\$hvec x, \$hvec y); \$bvec equal(\$ivec x, \$ivec y); \$bvec equal(\$bvec x, \$bvec y); \$bvec notEqual(\$vec x, \$vec y); \$bvec notEqual(\$hvec x, \$hvec y); \$bvec notEqual(\$ivec x, \$ivec y); \$bvec notEqual(\$bvec x, \$bvec y); bool any(\$bvec x); bool all(\$bvec x); \$bvec not(\$bvec x); // 8.9 : Fragment Processing Functions (GLSL ES 3.0) \$es3 \$genType dFdx(\$genType p); \$es3 \$genType dFdy(\$genType p); \$es3 \$genHType dFdx(\$genHType p); \$es3 \$genHType dFdy(\$genHType p); \$es3 \$genType fwidth(\$genType p); \$es3 \$genHType fwidth(\$genHType p); // SkSL utility functions // The max() guards against division by zero when the incoming color is transparent black half4 unpremul(half4 color) { return half4 (color.rgb / max(color.a, 0.0001), color.a); } float4 unpremul(float4 color) { return float4(color.rgb / max(color.a, 0.0001), color.a); } // Convert RGBA -> HSLA (including unpremul). // // Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3]. High-level ideas: // // - minimize the number of branches by sorting and computing the hue phase in parallel (vec4s) // // - trade the third sorting branch for a potentially faster std::min and leaving 2nd/3rd // channels unsorted (based on the observation that swapping both the channels and the bias sign // has no effect under abs) // // - use epsilon offsets for denominators, to avoid explicit zero-checks // // An additional trick we employ is deferring premul->unpremul conversion until the very end: the // alpha factor gets naturally simplified for H and S, and only L requires a dedicated unpremul // division (so we trade three divs for one). // // [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv // [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl // [3] http://www.chilliant.com/rgb2hsv.html half4 \$rgb_to_hsl(half3 c, half a) { half4 p = (c.g < c.b) ? half4(c.bg, -1, 2/3.0) : half4(c.gb, 0, -1/3.0); half4 q = (c.r < p.x) ? half4(p.x, c.r, p.yw) : half4(c.r, p.x, p.yz); // q.x -> max channel value // q.yz -> 2nd/3rd channel values (unsorted) // q.w -> bias value dependent on max channel selection const half kEps = 0.0001; half pmV = q.x; half pmC = pmV - min(q.y, q.z); half pmL = pmV - pmC * 0.5; half H = abs(q.w + (q.y - q.z) / (pmC * 6 + kEps)); half S = pmC / (a + kEps - abs(pmL * 2 - a)); half L = pmL / (a + kEps); return half4(H, S, L, a); } // Convert HSLA -> RGBA (including clamp and premul). // // Based on work by Sam Hocevar, Emil Persson, and Ian Taylor [1][2][3]. // // [1] http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv // [2] http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl // [3] http://www.chilliant.com/rgb2hsv.html half3 \$hsl_to_rgb(half3 hsl) { half C = (1 - abs(2 * hsl.z - 1)) * hsl.y; half3 p = hsl.xxx + half3(0, 2/3.0, 1/3.0); half3 q = saturate(abs(fract(p) * 6 - 3) - 1); return (q - 0.5) * C + hsl.z; } half4 \$hsl_to_rgb(half3 hsl, half a) { return saturate(half4(\$hsl_to_rgb(hsl) * a, a)); }