/* * Mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ // // From Shader Spec, ver. 1.10, rev. 59 // //bp: XXX these will probably go away since the value needs to be //determined at runtime and may vary from one GLcontext to another... const int gl_MaxLights = 8; const int gl_MaxClipPlanes = 6; const int gl_MaxTextureUnits = 8; const int gl_MaxTextureCoords = 8; const int gl_MaxVertexAttribs = 16; const int gl_MaxVertexUniformComponents = 512; const int gl_MaxVaryingFloats = 32; const int gl_MaxVertexTextureImageUnits = 0; const int gl_MaxCombinedTextureImageUnits = 2; const int gl_MaxTextureImageUnits = 2; const int gl_MaxFragmentUniformComponents = 64; const int gl_MaxDrawBuffers = 1; uniform mat4 gl_ModelViewMatrix; uniform mat4 gl_ProjectionMatrix; uniform mat4 gl_ModelViewProjectionMatrix; uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; uniform mat3 gl_NormalMatrix; uniform mat3 __NormalMatrixTranspose; // Mesa only uniform mat4 gl_ModelViewMatrixInverse; uniform mat4 gl_ProjectionMatrixInverse; uniform mat4 gl_ModelViewProjectionMatrixInverse; uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords]; uniform mat4 gl_ModelViewMatrixTranspose; uniform mat4 gl_ProjectionMatrixTranspose; uniform mat4 gl_ModelViewProjectionMatrixTranspose; uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords]; uniform mat4 gl_ModelViewMatrixInverseTranspose; uniform mat4 gl_ProjectionMatrixInverseTranspose; uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose; uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords]; uniform float gl_NormalScale; struct gl_DepthRangeParameters { float near; float far; float diff; }; uniform gl_DepthRangeParameters gl_DepthRange; uniform vec4 gl_ClipPlane[gl_MaxClipPlanes]; struct gl_PointParameters { float size; float sizeMin; float sizeMax; float fadeThresholdSize; float distanceConstantAttenuation; float distanceLinearAttenuation; float distanceQuadraticAttenuation; }; uniform gl_PointParameters gl_Point; struct gl_MaterialParameters { vec4 emission; vec4 ambient; vec4 diffuse; vec4 specular; float shininess; }; uniform gl_MaterialParameters gl_FrontMaterial; uniform gl_MaterialParameters gl_BackMaterial; struct gl_LightSourceParameters { vec4 ambient; vec4 diffuse; vec4 specular; vec4 position; vec4 halfVector; vec3 spotDirection; float spotExponent; float spotCutoff; float spotCosCutoff; float constantAttenuation; float linearAttenuation; float quadraticAttenuation; }; uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; struct gl_LightModelParameters { vec4 ambient; }; uniform gl_LightModelParameters gl_LightModel; struct gl_LightModelProducts { vec4 sceneColor; }; uniform gl_LightModelProducts gl_FrontLightModelProduct; uniform gl_LightModelProducts gl_BackLightModelProduct; struct gl_LightProducts { vec4 ambient; vec4 diffuse; vec4 specular; }; uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits]; uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords]; struct gl_FogParameters { vec4 color; float density; float start; float end; float scale; }; uniform gl_FogParameters gl_Fog; // // 8.1 Angle and Trigonometry Functions // //// radians float radians(const float deg) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal.x, deg, c; } vec2 radians(const vec2 deg) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal.xy, deg.xy, c.xx; } vec3 radians(const vec3 deg) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx; } vec4 radians(const vec4 deg) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal, deg, c.xxxx; } //// degrees float degrees(const float rad) { const float c = 180.0 / 3.1415926; __asm vec4_multiply __retVal.x, rad, c; } vec2 degrees(const vec2 rad) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal.xy, rad.xy, c.xx; } vec3 degrees(const vec3 rad) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx; } vec4 degrees(const vec4 rad) { const float c = 3.1415926 / 180.0; __asm vec4_multiply __retVal, rad, c.xxxx; } //// sin float sin(const float radians) { __asm float_sine __retVal.x, radians; } vec2 sin(const vec2 radians) { __asm float_sine __retVal.x, radians.x; __asm float_sine __retVal.y, radians.y; } vec3 sin(const vec3 radians) { __asm float_sine __retVal.x, radians.x; __asm float_sine __retVal.y, radians.y; __asm float_sine __retVal.z, radians.z; } vec4 sin(const vec4 radians) { __asm float_sine __retVal.x, radians.x; __asm float_sine __retVal.y, radians.y; __asm float_sine __retVal.z, radians.z; __asm float_sine __retVal.w, radians.w; } //// cos float cos(const float radians) { __asm float_cosine __retVal.x, radians; } vec2 cos(const vec2 radians) { __asm float_cosine __retVal.x, radians.x; __asm float_cosine __retVal.y, radians.y; } vec3 cos(const vec3 radians) { __asm float_cosine __retVal.x, radians.x; __asm float_cosine __retVal.y, radians.y; __asm float_cosine __retVal.z, radians.z; } vec4 cos(const vec4 radians) { __asm float_cosine __retVal.x, radians.x; __asm float_cosine __retVal.y, radians.y; __asm float_cosine __retVal.z, radians.z; __asm float_cosine __retVal.w, radians.w; } //// tan float tan(const float angle) { const float s = sin(angle); const float c = cos(angle); return s / c; } vec2 tan(const vec2 angle) { const vec2 s = sin(angle); const vec2 c = cos(angle); return s / c; } vec3 tan(const vec3 angle) { const vec3 s = sin(angle); const vec3 c = cos(angle); return s / c; } vec4 tan(const vec4 angle) { const vec4 s = sin(angle); const vec4 c = cos(angle); return s / c; } float asin(const float x) { const float a0 = 1.5707288; // PI/2? const float a1 = -0.2121144; const float a2 = 0.0742610; //const float a3 = -0.0187293; const float halfPi = 3.1415926 * 0.5; const float y = abs(x); // three terms seem to be enough: __retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + a2 * y))) * sign(x); // otherwise, try four: //__retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + y * (a2 + y * a3)))) * sign(x); } vec2 asin(const vec2 v) { __retVal.x = asin(v.x); __retVal.y = asin(v.y); } vec3 asin(const vec3 v) { __retVal.x = asin(v.x); __retVal.y = asin(v.y); __retVal.z = asin(v.z); } vec4 asin(const vec4 v) { __retVal.x = asin(v.x); __retVal.y = asin(v.y); __retVal.z = asin(v.z); } float acos(const float x) { const float halfPi = 3.1415926 * 0.5; __retVal = halfPi - asin(x); } vec2 acos(const vec2 v) { __retVal.x = acos(v.x); __retVal.y = acos(v.y); } vec3 acos(const vec3 v) { __retVal.x = acos(v.x); __retVal.y = acos(v.y); __retVal.z = acos(v.z); } vec4 acos(const vec4 v) { __retVal.x = acos(v.x); __retVal.y = acos(v.y); __retVal.z = acos(v.z); __retVal.w = acos(v.w); } float atan(const float x) { __retVal = asin(x * inversesqrt(x * x + 1.0)); } vec2 atan(const vec2 y_over_x) { __retVal.x = atan(y_over_x.x); __retVal.y = atan(y_over_x.y); } vec3 atan(const vec3 y_over_x) { __retVal.x = atan(y_over_x.x); __retVal.y = atan(y_over_x.y); __retVal.z = atan(y_over_x.z); } vec4 atan(const vec4 y_over_x) { __retVal.x = atan(y_over_x.x); __retVal.y = atan(y_over_x.y); __retVal.z = atan(y_over_x.z); __retVal.w = atan(y_over_x.w); } float atan(const float y, const float x) { if (x == 0.0) return 0.0; float z = atan(y / x); if (x < 0.0) { if (y < 0.0) return z - 3.141593; return z + 3.141593; } return z; } vec2 atan(const vec2 u, const vec2 v) { __retVal.x = atan(u.x, v.x); __retVal.y = atan(u.y, v.y); } vec3 atan(const vec3 u, const vec3 v) { __retVal.x = atan(u.x, v.x); __retVal.y = atan(u.y, v.y); __retVal.z = atan(u.z, v.z); } vec4 atan(const vec4 u, const vec4 v) { __retVal.x = atan(u.x, v.x); __retVal.y = atan(u.y, v.y); __retVal.z = atan(u.z, v.z); __retVal.w = atan(u.w, v.w); } // // 8.2 Exponential Functions // //// pow float pow(const float a, const float b) { __asm float_power __retVal.x, a, b; } vec2 pow(const vec2 a, const vec2 b) { __asm float_power __retVal.x, a.x, b.x; __asm float_power __retVal.y, a.y, b.y; } vec3 pow(const vec3 a, const vec3 b) { __asm float_power __retVal.x, a.x, b.x; __asm float_power __retVal.y, a.y, b.y; __asm float_power __retVal.z, a.z, b.z; } vec4 pow(const vec4 a, const vec4 b) { __asm float_power __retVal.x, a.x, b.x; __asm float_power __retVal.y, a.y, b.y; __asm float_power __retVal.z, a.z, b.z; __asm float_power __retVal.w, a.w, b.w; } //// exp float exp(const float a) { const float e = 2.71828; __asm float_power __retVal, e, a; } vec2 exp(const vec2 a) { const float e = 2.71828; __asm float_power __retVal.x, e, a.x; __asm float_power __retVal.y, e, a.y; } vec3 exp(const vec3 a) { const float e = 2.71828; __asm float_power __retVal.x, e, a.x; __asm float_power __retVal.y, e, a.y; __asm float_power __retVal.z, e, a.z; } vec4 exp(const vec4 a) { const float e = 2.71828; __asm float_power __retVal.x, e, a.x; __asm float_power __retVal.y, e, a.y; __asm float_power __retVal.z, e, a.z; __asm float_power __retVal.w, e, a.w; } //// log2 float log2(const float x) { __asm float_log2 __retVal.x, x; } vec2 log2(const vec2 v) { __asm float_log2 __retVal.x, v.x; __asm float_log2 __retVal.y, v.y; } vec3 log2(const vec3 v) { __asm float_log2 __retVal.x, v.x; __asm float_log2 __retVal.y, v.y; __asm float_log2 __retVal.z, v.z; } vec4 log2(const vec4 v) { __asm float_log2 __retVal.x, v.x; __asm float_log2 __retVal.y, v.y; __asm float_log2 __retVal.z, v.z; __asm float_log2 __retVal.w, v.w; } //// log (natural log) float log(const float x) { // note: logBaseB(x) = logBaseN(x) / logBaseN(B) // compute log(x) = log2(x) / log2(e) // c = 1.0 / log2(e) = 0.693147181 const float c = 0.693147181; return log2(x) * c; } vec2 log(const vec2 v) { const float c = 0.693147181; return log2(v) * c; } vec3 log(const vec3 v) { const float c = 0.693147181; return log2(v) * c; } vec4 log(const vec4 v) { const float c = 0.693147181; return log2(v) * c; } //// exp2 float exp2(const float a) { __asm float_exp2 __retVal.x, a; } vec2 exp2(const vec2 a) { __asm float_exp2 __retVal.x, a.x; __asm float_exp2 __retVal.y, a.y; } vec3 exp2(const vec3 a) { __asm float_exp2 __retVal.x, a.x; __asm float_exp2 __retVal.y, a.y; __asm float_exp2 __retVal.z, a.z; } vec4 exp2(const vec4 a) { __asm float_exp2 __retVal.x, a.x; __asm float_exp2 __retVal.y, a.y; __asm float_exp2 __retVal.z, a.z; __asm float_exp2 __retVal.w, a.w; } //// sqrt float sqrt(const float x) { float r; __asm float_rsq r, x; __asm float_rcp __retVal.x, r; } vec2 sqrt(const vec2 v) { float r; __asm float_rsq r, v.x; __asm float_rcp __retVal.x, r; __asm float_rsq r, v.y; __asm float_rcp __retVal.y, r; } vec3 sqrt(const vec3 v) { float r; __asm float_rsq r, v.x; __asm float_rcp __retVal.x, r; __asm float_rsq r, v.y; __asm float_rcp __retVal.y, r; __asm float_rsq r, v.z; __asm float_rcp __retVal.z, r; } vec4 sqrt(const vec4 v) { float r; __asm float_rsq r, v.x; __asm float_rcp __retVal.x, r; __asm float_rsq r, v.y; __asm float_rcp __retVal.y, r; __asm float_rsq r, v.z; __asm float_rcp __retVal.z, r; __asm float_rsq r, v.w; __asm float_rcp __retVal.w, r; } //// inversesqrt float inversesqrt(const float x) { __asm float_rsq __retVal.x, x; } vec2 inversesqrt(const vec2 v) { __asm float_rsq __retVal.x, v.x; __asm float_rsq __retVal.y, v.y; } vec3 inversesqrt(const vec3 v) { __asm float_rsq __retVal.x, v.x; __asm float_rsq __retVal.y, v.y; __asm float_rsq __retVal.z, v.z; } vec4 inversesqrt(const vec4 v) { __asm float_rsq __retVal.x, v.x; __asm float_rsq __retVal.y, v.y; __asm float_rsq __retVal.z, v.z; __asm float_rsq __retVal.w, v.w; } //// normalize float normalize(const float x) { __retVal.x = 1.0; } vec2 normalize(const vec2 v) { const float s = inversesqrt(dot(v, v)); __asm vec4_multiply __retVal.xy, v, s.xx; } vec3 normalize(const vec3 v) { // const float s = inversesqrt(dot(v, v)); // __retVal = v * s; // XXX note, we _could_ use __retVal.w instead of tmp and and save a // register, but that's actually a compilation error because v is a vec3 // and the .w suffix is illegal. Oh well. float tmp; __asm vec3_dot tmp, v, v; __asm float_rsq tmp, tmp; __asm vec4_multiply __retVal.xyz, v, tmp.xxx; } vec4 normalize(const vec4 v) { float tmp; __asm vec4_dot tmp, v, v; __asm float_rsq tmp, tmp; __asm vec4_multiply __retVal.xyz, v, tmp.xxx; } // // 8.3 Common Functions // //// abs float abs(const float a) { __asm vec4_abs __retVal.x, a; } vec2 abs(const vec2 a) { __asm vec4_abs __retVal.xy, a; } vec3 abs(const vec3 a) { __asm vec4_abs __retVal.xyz, a; } vec4 abs(const vec4 a) { __asm vec4_abs __retVal, a; } //// sign float sign(const float x) { float p, n; __asm vec4_sgt p.x, x, 0.0; // p = (x > 0) __asm vec4_sgt n.x, 0.0, x; // n = (x < 0) __asm vec4_subtract __retVal.x, p, n; // sign = p - n } vec2 sign(const vec2 v) { vec2 p, n; __asm vec4_sgt p.xy, v, 0.0; __asm vec4_sgt n.xy, 0.0, v; __asm vec4_subtract __retVal.xy, p, n; } vec3 sign(const vec3 v) { vec3 p, n; __asm vec4_sgt p.xyz, v, 0.0; __asm vec4_sgt n.xyz, 0.0, v; __asm vec4_subtract __retVal.xyz, p, n; } vec4 sign(const vec4 v) { vec4 p, n; __asm vec4_sgt p, v, 0.0; __asm vec4_sgt n, 0.0, v; __asm vec4_subtract __retVal, p, n; } //// floor float floor(const float a) { __asm vec4_floor __retVal.x, a; } vec2 floor(const vec2 a) { __asm vec4_floor __retVal.xy, a; } vec3 floor(const vec3 a) { __asm vec4_floor __retVal.xyz, a; } vec4 floor(const vec4 a) { __asm vec4_floor __retVal, a; } //// ceil float ceil(const float a) { // XXX this could be improved float b = -a; __asm vec4_floor b, b; __retVal.x = -b; } vec2 ceil(const vec2 a) { vec2 b = -a; __asm vec4_floor b, b; __retVal.xy = -b; } vec3 ceil(const vec3 a) { vec3 b = -a; __asm vec4_floor b, b; __retVal.xyz = -b; } vec4 ceil(const vec4 a) { vec4 b = -a; __asm vec4_floor b, b; __retVal = -b; } //// fract float fract(const float a) { __asm vec4_frac __retVal.x, a; } vec2 fract(const vec2 a) { __asm vec4_frac __retVal.xy, a; } vec3 fract(const vec3 a) { __asm vec4_frac __retVal.xyz, a; } vec4 fract(const vec4 a) { __asm vec4_frac __retVal, a; } //// mod (very untested!) float mod(const float a, const float b) { float oneOverB; __asm float_rcp oneOverB, b; __retVal.x = a - b * floor(a * oneOverB); } vec2 mod(const vec2 a, const float b) { float oneOverB; __asm float_rcp oneOverB, b; __retVal.xy = a - b * floor(a * oneOverB); } vec3 mod(const vec3 a, const float b) { float oneOverB; __asm float_rcp oneOverB, b; __retVal.xyz = a - b * floor(a * oneOverB); } vec4 mod(const vec4 a, const float b) { float oneOverB; __asm float_rcp oneOverB, b; __retVal = a - b * floor(a * oneOverB); } vec2 mod(const vec2 a, const vec2 b) { float oneOverBx, oneOverBy; __asm float_rcp oneOverBx, b.x; __asm float_rcp oneOverBy, b.y; __retVal.x = a.x - b.x * floor(a.x * oneOverBx); __retVal.y = a.y - b.y * floor(a.y * oneOverBy); } vec3 mod(const vec3 a, const vec3 b) { float oneOverBx, oneOverBy, oneOverBz; __asm float_rcp oneOverBx, b.x; __asm float_rcp oneOverBy, b.y; __asm float_rcp oneOverBz, b.z; __retVal.x = a.x - b.x * floor(a.x * oneOverBx); __retVal.y = a.y - b.y * floor(a.y * oneOverBy); __retVal.z = a.z - b.z * floor(a.z * oneOverBz); } vec4 mod(const vec4 a, const vec4 b) { float oneOverBx, oneOverBy, oneOverBz, oneOverBw; __asm float_rcp oneOverBx, b.x; __asm float_rcp oneOverBy, b.y; __asm float_rcp oneOverBz, b.z; __asm float_rcp oneOverBw, b.w; __retVal.x = a.x - b.x * floor(a.x * oneOverBx); __retVal.y = a.y - b.y * floor(a.y * oneOverBy); __retVal.z = a.z - b.z * floor(a.z * oneOverBz); __retVal.w = a.w - b.w * floor(a.w * oneOverBw); } //// min float min(const float a, const float b) { __asm vec4_min __retVal.x, a.x, b.x; } vec2 min(const vec2 a, const vec2 b) { __asm vec4_min __retVal.xy, a.xy, b.xy; } vec3 min(const vec3 a, const vec3 b) { __asm vec4_min __retVal.xyz, a.xyz, b.xyz; } vec4 min(const vec4 a, const vec4 b) { __asm vec4_min __retVal, a, b; } vec2 min(const vec2 a, const float b) { __asm vec4_min __retVal, a.xy, b.xx; } vec3 min(const vec3 a, const float b) { __asm vec4_min __retVal, a.xyz, b.xxx; } vec4 min(const vec4 a, const float b) { __asm vec4_min __retVal, a, b.xxxx; } //// max float max(const float a, const float b) { __asm vec4_max __retVal.x, a.x, b.x; } vec2 max(const vec2 a, const vec2 b) { __asm vec4_max __retVal.xy, a.xy, b.xy; } vec3 max(const vec3 a, const vec3 b) { __asm vec4_max __retVal.xyz, a.xyz, b.xyz; } vec4 max(const vec4 a, const vec4 b) { __asm vec4_max __retVal, a, b; } vec2 max(const vec2 a, const float b) { __asm vec4_max __retVal, a.xy, b.xx; } vec3 max(const vec3 a, const float b) { __asm vec4_max __retVal, a.xyz, b.xxx; } vec4 max(const vec4 a, const float b) { __asm vec4_max __retVal, a, b.xxxx; } //// clamp float clamp(const float val, const float minVal, const float maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec2 clamp(const vec2 val, const float minVal, const float maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec3 clamp(const vec3 val, const float minVal, const float maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec4 clamp(const vec4 val, const float minVal, const float maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal) { __asm vec4_clamp __retVal, val, minVal, maxVal; } //// mix float mix(const float x, const float y, const float a) { __asm vec4_lrp __retVal, a, y, x; } vec2 mix(const vec2 x, const vec2 y, const float a) { __asm vec4_lrp __retVal, a, y, x; } vec3 mix(const vec3 x, const vec3 y, const float a) { __asm vec4_lrp __retVal, a, y, x; } vec4 mix(const vec4 x, const vec4 y, const float a) { __asm vec4_lrp __retVal, a, y, x; } vec2 mix(const vec2 x, const vec2 y, const vec2 a) { __asm vec4_lrp __retVal, a, y, x; } vec3 mix(const vec3 x, const vec3 y, const vec3 a) { __asm vec4_lrp __retVal, a, y, x; } vec4 mix(const vec4 x, const vec4 y, const vec4 a) { __asm vec4_lrp __retVal, a, y, x; } //// step (untested) float step(const float edge, const float x) { __asm vec4_sgt __retVal.x, x, edge; } vec2 step(const vec2 edge, const vec2 x) { __asm vec4_sgt __retVal.xy, x, edge; } vec3 step(const vec3 edge, const vec3 x) { __asm vec4_sgt __retVal.xyz, x, edge; } vec4 step(const vec4 edge, const vec4 x) { __asm vec4_sgt __retVal, x, edge; } vec2 step(const float edge, const vec2 v) { __asm vec4_sgt __retVal.xy, v, edge.xx; } vec3 step(const float edge, const vec3 v) { __asm vec4_sgt __retVal.xyz, v, edge.xxx; } vec4 step(const float edge, const vec4 v) { __asm vec4_sgt __retVal, v, edge.xxxx; } //// smoothstep (untested) float smoothstep(const float edge0, const float edge1, const float x) { float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec2 smoothstep(const vec2 edge0, const vec2 edge1, const vec2 v) { vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec3 smoothstep(const vec3 edge0, const vec3 edge1, const vec3 v) { vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec4 smoothstep(const vec4 edge0, const vec4 edge1, const vec4 v) { vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec2 smoothstep(const float edge0, const float edge1, const vec2 v) { vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec3 smoothstep(const float edge0, const float edge1, const vec3 v) { vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } vec4 smoothstep(const float edge0, const float edge1, const vec4 v) { vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } // // 8.4 Geometric Functions // //// length float length(const float x) { return abs(x); } float length(const vec2 v) { float r; const float p = dot(v, v); // p = v.x * v.x + v.y * v.y __asm float_rsq r, p; // r = 1 / sqrt(p) __asm float_rcp __retVal.x, r; // retVal = 1 / r } float length(const vec3 v) { float r; const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + v.z * v.z __asm float_rsq r, p; // r = 1 / sqrt(p) __asm float_rcp __retVal.x, r; // retVal = 1 / r } float length(const vec4 v) { float r; const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + ... __asm float_rsq r, p; // r = 1 / sqrt(p) __asm float_rcp __retVal.x, r; // retVal = 1 / r } //// distance float distance(const float x, const float y) { const float d = x - y; __retVal = length(d); } float distance(const vec2 v, const vec2 u) { const vec2 d2 = v - u; __retVal = length(d2); } float distance(const vec3 v, const vec3 u) { const vec3 d3 = v - u; __retVal = length(d3); } float distance(const vec4 v, const vec4 u) { const vec4 d4 = v - u; __retVal = length(d4); } //// cross vec3 cross(const vec3 v, const vec3 u) { __asm vec3_cross __retVal.xyz, v, u; } //// faceforward float faceforward(const float N, const float I, const float Nref) { // this could probably be done better const float d = dot(Nref, I); float s; __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 return mix(-N, N, s); } vec2 faceforward(const vec2 N, const vec2 I, const vec2 Nref) { // this could probably be done better const float d = dot(Nref, I); float s; __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 return mix(-N, N, s); } vec3 faceforward(const vec3 N, const vec3 I, const vec3 Nref) { // this could probably be done better const float d = dot(Nref, I); float s; __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 return mix(-N, N, s); } vec4 faceforward(const vec4 N, const vec4 I, const vec4 Nref) { // this could probably be done better const float d = dot(Nref, I); float s; __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 return mix(-N, N, s); } //// reflect float reflect(const float I, const float N) { return I - 2.0 * dot(N, I) * N; } vec2 reflect(const vec2 I, const vec2 N) { return I - 2.0 * dot(N, I) * N; } vec3 reflect(const vec3 I, const vec3 N) { return I - 2.0 * dot(N, I) * N; } vec4 reflect(const vec4 I, const vec4 N) { return I - 2.0 * dot(N, I) * N; } //// refract float refract(const float I, const float N, const float eta) { float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); if (k < 0.0) return 0.0; return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } vec2 refract(const vec2 I, const vec2 N, const float eta) { float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); if (k < 0.0) return 0.0; return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } vec3 refract(const vec3 I, const vec3 N, const float eta) { float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); if (k < 0.0) return 0.0; return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } vec4 refract(const vec4 I, const vec4 N, const float eta) { float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); if (k < 0.0) return 0.0; return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } // // 8.5 Matrix Functions // mat2 matrixCompMult (mat2 m, mat2 n) { return mat2 (m[0] * n[0], m[1] * n[1]); } mat3 matrixCompMult (mat3 m, mat3 n) { return mat3 (m[0] * n[0], m[1] * n[1], m[2] * n[2]); } mat4 matrixCompMult (mat4 m, mat4 n) { return mat4 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]); } // // 8.6 Vector Relational Functions // //// lessThan bvec2 lessThan(const vec2 u, const vec2 v) { __asm vec4_slt __retVal.xy, u, v; } bvec3 lessThan(const vec3 u, const vec3 v) { __asm vec4_slt __retVal.xyz, u, v; } bvec4 lessThan(const vec4 u, const vec4 v) { __asm vec4_slt __retVal, u, v; } bvec2 lessThan(const ivec2 u, const ivec2 v) { __asm vec4_slt __retVal.xy, u, v; } bvec3 lessThan(const ivec3 u, const ivec3 v) { __asm vec4_slt __retVal.xyz, u, v; } bvec4 lessThan(const ivec4 u, const ivec4 v) { __asm vec4_slt __retVal, u, v; } //// lessThanEqual bvec2 lessThanEqual(const vec2 u, const vec2 v) { __asm vec4_sle __retVal.xy, u, v; } bvec3 lessThanEqual(const vec3 u, const vec3 v) { __asm vec4_sle __retVal.xyz, u, v; } bvec4 lessThanEqual(const vec4 u, const vec4 v) { __asm vec4_sle __retVal, u, v; } bvec2 lessThanEqual(const ivec2 u, const ivec2 v) { __asm vec4_sle __retVal.xy, u, v; } bvec3 lessThanEqual(const ivec3 u, const ivec3 v) { __asm vec4_sle __retVal.xyz, u, v; } bvec4 lessThanEqual(const ivec4 u, const ivec4 v) { __asm vec4_sle __retVal, u, v; } //// greaterThan bvec2 greaterThan(const vec2 u, const vec2 v) { __asm vec4_sgt __retVal.xy, u, v; } bvec3 greaterThan(const vec3 u, const vec3 v) { __asm vec4_sgt __retVal.xyz, u, v; } bvec4 greaterThan(const vec4 u, const vec4 v) { __asm vec4_sgt __retVal, u, v; } bvec2 greaterThan(const ivec2 u, const ivec2 v) { __asm vec4_sgt __retVal.xy, u, v; } bvec3 greaterThan(const ivec3 u, const ivec3 v) { __asm vec4_sgt __retVal.xyz, u, v; } bvec4 greaterThan(const ivec4 u, const ivec4 v) { __asm vec4_sgt __retVal, u, v; } //// greaterThanEqual bvec2 greaterThanEqual(const vec2 u, const vec2 v) { __asm vec4_sge __retVal.xy, u, v; } bvec3 greaterThanEqual(const vec3 u, const vec3 v) { __asm vec4_sge __retVal.xyz, u, v; } bvec4 greaterThanEqual(const vec4 u, const vec4 v) { __asm vec4_sge __retVal, u, v; } bvec2 greaterThanEqual(const ivec2 u, const ivec2 v) { __asm vec4_sge __retVal.xy, u, v; } bvec3 greaterThanEqual(const ivec3 u, const ivec3 v) { __asm vec4_sge __retVal.xyz, u, v; } bvec4 greaterThanEqual(const ivec4 u, const ivec4 v) { __asm vec4_sge __retVal, u, v; } //// equal bvec2 equal(const vec2 u, const vec2 v) { __asm vec4_seq __retVal.xy, u, v; } bvec3 equal(const vec3 u, const vec3 v) { __asm vec4_seq __retVal.xyz, u, v; } bvec4 equal(const vec4 u, const vec4 v) { __asm vec4_seq __retVal, u, v; } bvec2 equal(const ivec2 u, const ivec2 v) { __asm vec4_seq __retVal.xy, u, v; } bvec3 equal(const ivec3 u, const ivec3 v) { __asm vec4_seq __retVal.xyz, u, v; } bvec4 equal(const ivec4 u, const ivec4 v) { __asm vec4_seq __retVal, u, v; } //// notEqual bvec2 notEqual(const vec2 u, const vec2 v) { __asm vec4_sne __retVal.xy, u, v; } bvec3 notEqual(const vec3 u, const vec3 v) { __asm vec4_sne __retVal.xyz, u, v; } bvec4 notEqual(const vec4 u, const vec4 v) { __asm vec4_sne __retVal, u, v; } bvec2 notEqual(const ivec2 u, const ivec2 v) { __asm vec4_sne __retVal.xy, u, v; } bvec3 notEqual(const ivec3 u, const ivec3 v) { __asm vec4_sne __retVal.xyz, u, v; } bvec4 notEqual(const ivec4 u, const ivec4 v) { __asm vec4_sne __retVal, u, v; } //// any bool any(const bvec2 v) { float sum; __asm vec4_add sum.x, v.x, v.y; __asm vec4_sne __retVal.x, sum.x, 0.0; } bool any(const bvec3 v) { float sum; __asm vec4_add sum.x, v.x, v.y; __asm vec4_add sum.x, sum.x, v.z; __asm vec4_sne __retVal.x, sum.x, 0.0; } bool any(const bvec4 v) { float sum; __asm vec4_add sum.x, v.x, v.y; __asm vec4_add sum.x, sum.x, v.z; __asm vec4_add sum.x, sum.x, v.w; __asm vec4_sne __retVal.x, sum.x, 0.0; } //// all bool all (const vec2 v) { float prod; __asm vec4_multiply prod.x, v.x, v.y; __asm vec4_sne __retVal.x, prod.x, 0.0; return v.x && v.y; } bool all (const bvec3 v) { float prod; __asm vec4_multiply prod.x, v.x, v.y; __asm vec4_multiply prod.x, prod.x, v.z; __asm vec4_sne __retVal.x, prod.x, 0.0; } bool all (const bvec4 v) { float prod; __asm vec4_multiply prod.x, v.x, v.y; __asm vec4_multiply prod.x, prod.x, v.z; __asm vec4_multiply prod.x, prod.x, v.w; __asm vec4_sne __retVal.x, prod.x, 0.0; } //// not bvec2 not (const bvec2 v) { __asm vec4_seq __retVal.xy, v, 0.0; } bvec3 not (const bvec3 v) { __asm vec4_seq __retVal.xyz, v, 0.0; } bvec4 not (const bvec4 v) { __asm vec4_seq __retVal, v, 0.0; } //// Texture Lookup Functions (for both fragment and vertex shaders) vec4 texture1D(const sampler1D sampler, const float coord) { __asm vec4_tex1d __retVal, sampler, coord; } vec4 texture1DProj(const sampler1D sampler, const vec2 coord) { // need to swizzle .y into .w __asm vec4_texp1d __retVal, sampler, coord.xyyy; } vec4 texture1DProj(const sampler1D sampler, const vec4 coord) { __asm vec4_texp1d __retVal, sampler, coord; } vec4 texture2D(const sampler2D sampler, const vec2 coord) { __asm vec4_tex2d __retVal, sampler, coord; } vec4 texture2DProj(const sampler2D sampler, const vec3 coord) { // need to swizzle 'z' into 'w'. __asm vec4_texp2d __retVal, sampler, coord.xyzz; } vec4 texture2DProj(const sampler2D sampler, const vec4 coord) { __asm vec4_texp2d __retVal, sampler, coord; } vec4 texture3D(const sampler3D sampler, const vec3 coord) { __asm vec4_tex3d __retVal, sampler, coord; } vec4 texture3DProj(const sampler3D sampler, const vec4 coord) { __asm vec4_texp3d __retVal, sampler, coord; } vec4 textureCube(const samplerCube sampler, const vec3 coord) { __asm vec4_texcube __retVal, sampler, coord; } vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord) { __asm vec4_tex1d __retVal, sampler, coord; } vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord) { // .s and .p will be divided by .q __asm vec4_texp1d __retVal, sampler, coord; } vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord) { __asm vec4_tex2d __retVal, sampler, coord; } vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord) { // .s, .t and .p will be divided by .q __asm vec4_texp2d __retVal, sampler, coord; } //// GL_ARB_texture_rectangle: vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord) { __asm vec4_tex_rect __retVal, sampler, coord; } vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord) { // need to swizzle .y into .w __asm vec4_texp_rect __retVal, sampler, coord.xyzz; } vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord) { __asm vec4_texp_rect __retVal, sampler, ccoord; } vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord) { __asm vec4_tex_rect __retVal, sampler, coord; } vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord) { __asm vec4_texp_rect __retVal, sampler, coord; } // // 8.9 Noise Functions // // AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005 // float noise1(const float x) { __asm float_noise1 __retVal, x; } float noise1(const vec2 x) { __asm float_noise2 __retVal, x; } float noise1(const vec3 x) { __asm float_noise3 __retVal, x; } float noise1(const vec4 x) { __asm float_noise4 __retVal, x; } vec2 noise2(const float x) { __retVal.x = noise1(x); __retVal.y = noise1(x + 19.34); } vec2 noise2(const vec2 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec2(19.34, 7.66)); } vec2 noise2(const vec3 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); } vec2 noise2(const vec4 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); } vec3 noise3(const float x) { __retVal.x = noise1(x); __retVal.y = noise1(x + 19.34); __retVal.z = noise1(x + 5.47); } vec3 noise3(const vec2 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec2(19.34, 7.66)); __retVal.z = noise1(x + vec2(5.47, 17.85)); } vec3 noise3(const vec3 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); } vec3 noise3(const vec4 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); } vec4 noise4(const float x) { __retVal.x = noise1(x); __retVal.y = noise1(x + 19.34); __retVal.z = noise1(x + 5.47); __retVal.w = noise1(x + 23.54); } vec4 noise4(const vec2 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec2 (19.34, 7.66)); __retVal.z = noise1(x + vec2 (5.47, 17.85)); __retVal.w = noise1(x + vec2 (23.54, 29.11)); } vec4 noise4(const vec3 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91)); } vec4 noise4(const vec4 x) { __retVal.x = noise1(x); __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48)); }