The OpenGL Shading Language Bill Licea-Kane ATI Research, Inc. 1 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples 2 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples 3 Brief History 1968 “As far as generating pictures from data is concerned, we feel the display processor should be a specialized device, capable only of generating pictures from readonly representations in core.” [Myer, Sutherland] On the Design of Display Processors. Communications of the ACM, Volume 11 Number 6, June, 1968 4 Brief History 1978 THE PROGRAMMING LANGUAGE [Kernighan, Ritchie] The C Programming Language 1978 5 Brief History 1984 “Shading is an important part of computer imagery, but shaders have been based on fixed models to which all surfaces must conform. As computer imagery becomes more sophisticated, surfaces have more complex shading characteristics and thus require a less rigid shading model." [Cook] Shade Trees SIGGRAPH 1984 6 Brief History 1985 “We introduce the concept of a Pixel Stream Editor. This forms the basis for an interactive synthesizer for designing highly realistic Computer Generated Imagery. The designer works in an interactive Very High Level programming environment which provides a very fast concept/implement/view iteration cycle." [Perlin] An Image Synthesizer SIGGRAPH 1985 7 Brief History 1990 “A shading language provides a means to extend the shading and lighting formulae used by a rendering system." … "…because it is based on a simple subset of C, it is easy to parse and implement, but, because it has many high-level features that customize it for shading and lighting calulations, it is easy to use." [Hanrahan, Lawson] A Language for Shading and Lighting Calculations SIGGRAPH 1990 8 Brief History June 30, 1992 “This document describes the OpenGL graphics system: what it is, how it acts, and what is required to implement it.” “OpenGL does not provide a programming language. … Programmability would conflict with keeping the API close to the hardware and thus with the goal of maximum performance.” [Segal, Akeley] The OpenGL Graphics System: A Specification (V 1.0) June 30, 1992 [Segal, Akeley] The Design of the OpenGL Graphics Interface, 1994 9 Brief History August 23, 1993 Digital Equipment will begin shipping its first OpenGL product next Monday as part of the Open3D 2.0 layered product for Alpha AXP OSF/1. ... -John Dennis – OpenGL Project Lead [Dennis] comp.graphics.opengl 1993-08-19 10 Brief History October 1993 [email protected] (William C. Archibald) writes: |> 1)Quite a few modern rendering techniques and renderers |> support shader function calls at arbitrary points |> across a surface being rendered. ... What I would |> _like_ to do is call the shader at visible |> (front-facing) points. Is there _any_ way to do |> this kind of thing in OpenGL? Not with the current API. manner... One could extend OpenGL in this [Akeley] comp.graphics.opengl 1993-10-13 11 Brief History Recent • August 2001, SIGGRAPH OpenGL BOF – 3DLabs calls for "programmable" OpenGL • June 2002, OpenGL ARB – ATI chairs arb-gl2 workgroup 12 Brief History Recent • June 2003, OpenGL ARB – ARB approves OpenGL Shading Language • March 2004, OpenGL ARB – Unanimous roadmap to core OpenGL 2.0 13 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples 14 [Kempf, Frazier] OpenGL Reference Manual (2nd Edition) www.opengl.org 15 OpenGL Fixed Function Vertex Vertex (object) Normal Vertex (clip) Transform [MVP],[MV],[MV]-T Color SecondaryColor Vertex (eye) [0,1] Lighting [0,1] TexCoordn EdgeFlag Texgen Texture Matrixn FrontColor BackColor FrontSecondaryColor BackSecondaryColor TexCoordn EdgeFlag 16 OpenGL Vertex Shader Attribute0 Uniform Texture Position Attribute1 ClipVertex Attribute2 PointSize … Vertex Shader Attributen Varying0 Varying1 Varying2 … Temporaries EdgeFlag Varyingn EdgeFlag 17 Post Vertex Shader "After lighting" Clamp Position Position ClipVertex ClipVertex PointSize PointSize FrontColor BackColor [0,1] FrontColor BackColor FrontSecondaryColor BackSecondaryColor [0,1] FrontSecondaryColor BackSecondaryColor Varyingn Varyingn EdgeFlag EdgeFlag 18 OpenGL Fixed Function Rasterization Position Primitive Assembly ClipVertex Flatshade Varyingn EdgeFlag Culling or Clipping Face Processing RasterPos Varyingn Point Line Polygon Rasterization Pixel Rectangle Bitmap Rasterization Varyingn Coord 19 OpenGL Fixed Function Fragment Color SecondaryColor TexCoord[n] Tex n TE n Sum [0,1] Fog Color z (|ze|,f ) Depth Depth Coord Coord FrontFacing FrontFacing 20 OpenGL Fragment Shader Varying0 Uniform Texture Varying1 Varying2 … Varyingn Fragment Shader FragData[n] FragDepth FragCoord FrontFacing FragColor FragDepth Temporaries FragCoord FrontFacing 21 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples 22 Simple Program helloshader int main ( int argc, char **argv ) { GLhandleARB VShader, FShader, PObject; GLint VStatus, VStatus, PStatus; GLint myColorLocation; GLfloat myColor[4] = { 0.0, 0.5, 1.0, 1.0 }; GLcharARB GLcharARB *VSource; *FSource[2]; VSource = "void main( void ){ gl_Position = ftransform(); }" FSource[0] = "uniform vec4 myColor;" FSource[1] = "void main( void ){ gl_FragColor = myColor; }" // Initialize OpenGL context, etc... 23 Simple Program helloshader // Create objects VShader = glCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); FShader = glCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); PObject = glCreateProgramOjbectARB(); // Attach shader objects to program (even empty objects) glAttachObjectARB( PObject, VShader ); glAttachObjectARB( PObject, FShader ); 24 Simple Program helloshader // Load source glShaderSourceARB( VShader, 1, VSource, NULL ); glShaderSourceARB( FShader, 2, FSource, NULL ); // And compile glCompileShaderARB( VShader ); glCompileShaderARB( FShader ); // Check compile status glGetObjectParameterARB( VShader, &VStatus ); glGetObjectParameterARB( FShader, &FStatus ); if ( !VStatus || !FStatus ) return 0; 25 Simple Program helloshader glLinkProgramARB( PObject ); glGetObjectParameterARB( PObject, &PStatus ); if ( !PStatus ) return 0; myColorLocation = glGetUniformLocation( PObject, "myColor" ); glUseProgramObjectARB( PObject ); if ( myColorLocation != -1 ) // existing behavior INVALID_OPERATION glUniform4fvARB( myColorLocation, myColor ); // Draw Stuff } 26 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples 27 OpenGL Shading Language Preprocessor directives # #define defined() #undef #if #ifdef #ifndef #else #elif #endif #error #pragma optimize(on|off) #pragma debug(on|off) #line line file __LINE__ __FILE__ __VERSION__ // comment /* comment */ 28 OpenGL Shading Language Types • void • float vec2 vec3 vec4 • mat2 mat3 mat4 • int ivec2 ivec3 ivec4 • bool bvec2 bvec3 bvec4 29 OpenGL Shading Language Reserved Types • double dvec2 dvec3 dvec4 • half hvec2 hvec3 hvec4 • fixed fvec2 fvec3 fvec4 30 OpenGL Shading Language Sampler Types • samplernD • samplerCube • samplernDShadow 31 OpenGL Shading Language Reserved Sampler Types • samplernDRect • samplernDRect__EXT • samplernDRectShadow • samplernDRectShadow__EXT 32 OpenGL Shading Language struct Types • some minor restrictions – no qualifiers – no bit fields – no forward references – no in-place definitions – no anonymous structures 33 OpenGL Shading Language array Types • some minor restrictions – one dimensional – size is integral constant expression – can declare unsized array, but… – specificy size and type of array ONCE – any basic type and struct – no initialization at declaration 34 OpenGL Shading Language Scope of Types • global – Outside function – Shared globals must be same type • local (nested) – within function definition – within function 35 OpenGL Shading Language type qualifiers • const • attribute • uniform • varying • in out • default 36 OpenGL Shading Language operators • grouping: () • array subscript: [] • function call and constructor: () • field selector and swizzle: . • postfix: ++ -• prefix: ++ -- + - ! 37 OpenGL Shading Language operators • binary: * / + • relational: < <= > >= • equality: == != • logical: && ^^ || • selection: ?: • assignment: = *= /= += -= 38 OpenGL Shading Language reserved operators • prefix: ~ • binary: % • bitwise: << >> & ^ | • assignment: %= <<= >>= &= ^= |= 39 OpenGL Shading Language constructors • float( ) • int( ) • bool( ) • vec2( ) vec3( ) vec4( ) • mat2( ) mat3( ) mat4 ( ) 40 OpenGL Shading Language scalar constructors float f; int i; bool b; float( b) int( b) bool( b) float( i) int( i) bool( i) float( f) int( f) bool( f) // // // // // // // // // b=true?1.0:0.0; b=true?1:0; identity int to float identity i!=0?true:false; identity float to int f!=0.0?true:false; 41 OpenGL Shading Language vector constructors vec2 v2; vec3 v3; vec4 v4; vec2( 1.0 ,2.0) vec3( 0.0 ,0.0 ,1.0) vec4( 1.0 ,0.5 ,0.0 ,1.0) vec4( 1.0) vec4( v2 ,v2) vec4( v3 ,1) vec2( v4) float( v4) // all 1.0 // different... // ...types 42 OpenGL Shading Language matrix constructors vec4 v4; mat4 m4; mat4( 1.0, 2.0, 3.0, 4.0, // column major 5.0, 6.0, 7.0, 8.0, 9.0, 10., 11., 12., 13., 14., 15., 16.) mat4( v4, v4, v4, v4) mat4( 1.0) // identity matrix mat3( m4) // NOT! upper 3x3 vec4( m4) // upper 4x1 float( m4) // upper 1x1 43 OpenGL Shading Language struct constructors struct light { float intensity; vec3 position; }; light headLight = light( 0.2 ,vec3( 0.0 ,0.0, 1.0)); // same as light headLight; headLight.intensity = 0.2; headLight.position = vec3( 0.0 ,0.0, 1.0); 44 OpenGL Shading Language components • component accessor for vectors – xyzw rgba stpq [i] • component accessor for matrices – [i] [i][j] 45 OpenGL Shading Language vector components vec2 v2; vec3 v3; vec4 v4; v2.x v2.z v4.rgba v4.stp v4.b v4.xy v4.xgp // // // // // // // is a float wrong: component undefined for type is a vec4 is a vec3 is a float is a vec2 wrong: mismatched component sets 46 OpenGL Shading Language vector components (rvalue) vec2 v2; vec3 v3; vec4 v4; v4.wzyx v4.bgra v4.xxxx v4.xxx v4.yyxx v2.yyyy // // // // // // swizzles, is a vec4 swizzles, is a vec4 smears x, is a vec4 smears x, is a vec3 duplicates x and y, is a vec4 wrong: too many components for type 47 OpenGL Shading Language vector components (lvalue) vec4 v4 = vec4 (1.0, 2.0, 3.0, 4.0); v4.xw v4.wx v4.xx v4.yz v4.yz = = = = = vec2( vec2( vec2( 11.0; vec2( 5.0, 6.0); 7.0, 8.0); 9.0,10.0); 12.0); // // // // // (5.0, 2.0, 3.0, 6.0) (8.0, 2.0, 3.0, 7.0) wrong: x used twice wrong: type mismatch (8.0,12.0,12.0, 7.0) 48 OpenGL Shading Language vector components [] vec4 v4 = vec4( 1.0, 2.0, 3.0, 4.0); float f; int i; f = v4[0]; f = v4[3]; f = v4[4]; // ... f = v4[i+1]; // 1.0 // 4.0 // undefined // defined for -1<i<3 49 OpenGL Shading Language matrix components [] mat4 m4; m4[1] = vec4( 2.0); m4[0][0] = 1.0; m4[4][4] = 3.0; // // // 2nd column = 2.0 upper 1x1 = 1.0 undefined 50 OpenGL Shading Language components and arrays [] vec3 v3[2]; mat3 m3[2]; v3[0] v3[0][0] V3[0].x // // // is is is a a a m3[0] m3[0][0] m3[0][0][0] // // // // is a is a is a :-( vec3 float float mat3 vec3, 1st column float, upper 1x1 51 OpenGL Shading Language vector matrix ops mat4 m4,n4; vec4 v4 m4 v4 m4 * * * v4 m4 n4 // // // is is is a a a vec4 vec4 mat4 52 OpenGL Shading Language flow control (scalar) • expression ? tExpression : fExpression • if, if-else • for, while, do-while • return, break, continue • discard (fragment only) 53 OpenGL Shading Language user-defined functions • call by value-return • in out inout keywords • function overloading • one return value (can be any type) • scope rules same as C 54 OpenGL Shading Language built-in vertex vec4 gl_Position; vec4 gl_ClipPosition; float gl_PointSize; // must be written // may be written // may be written 55 OpenGL Shading Language built-in fragment bool vec4 vec4 vec4 float gl_FrontFacing; gl_FragCoord; gl_FragColor; gl_FragData[n]; gl_FragDepth; // // // // // may may may may may be be be be be read read read/written read/written read/written 56 OpenGL Shading Language built-in attributes // Vertex attribute attribute attribute attribute attribute attribute Attributes, p. 19 vec4 gl_Vertex; vec3 gl_Normal; vec4 gl_Color; vec4 gl_SecondaryColor; vec4 gl_MultiTexCoordn; float gl_FogCoord; 57 OpenGL Shading Language user-defined attributes // Vertex attribute attribute attribute attribute attribute attribute // etc... Attributes, p. 19 vec3 myTangent; vec3 myBinormal; float myTempture; float myPressure; float myRainfall; float myTime; 58 OpenGL Shading Language built-in varying varying varying varying varying vec4 vec4 vec4 vec4 gl_FrontColor; gl_BackColor; gl_FrontSecondaryColor; gl_BackSecondaryColor; // // // // vertex vertex vertex vertex varying varying vec4 vec4 gl_Color; gl_SecondaryColor; // fragment // fragment varying varying vec4 gl_TexCoord[]; float gl_FogFragCoord; // both // both 59 OpenGL Shading Language user-defined varying varying vec3 varying vec3 varying vec3 varying float // etc... myNormalPrime; myTangentPrime; myBinormalPrime; myPressurePrime; 60 OpenGL Shading Language built-in uniforms // Matrix uniform uniform uniform uniform uniform // Normal uniform state, p. 31, 32, 37, 39, 40 mat4 gl_ModelViewMatrix; mat4 gl_ProjectionMatrix; mat4 gl_ModelViewProjectionMatrix; mat3 gl_NormalMatrix; mat4 gl_TextureMatrix[n]; scaling, p. 33 float gl_NormalScale; 61 OpenGL Shading Language built-in uniforms // Light State, p. 50, 53, 55 struct gl_LightSourceParameters { vec4 ambient; // Acli vec4 diffuse; // Dcli vec4 specular; // Scli vec4 position; // Ppli vec4 halfVector; // Derived: Hi 62 OpenGL Shading Language built-in uniforms vec3 spotDirection; // Sdli float spotExponent; // Srli float spotCutoff; // Crli float spotCosCutoff; // Derived: cos(Crli) float constantAttenuation // K0 float linearAttenuation // K1 float quadraticAttenuation// K2 }; uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; 63 OpenGL Shading Language user-defined uniforms uniform uniform uniform uniform uniform uniform uniform uniform // etc... mat4 vec4 vec4 vec4 float vec4 vec4 float myGlobalMatrix; myAmbient; myDiffuseMatLight; mySpecularMatLight; myGlow; myWarm; myCool; myCurrentTime; 64 Built-in Functions angles & trigonometry genType genType genType genType genType genType genType genType genType radians( genType degrees) degrees( genType radians) sin( genType angle) // radians cos( genType angle) tan( genType angle) asin( genType angle) acos( genType angle) atan( genType y ,genType x) atan( genType y_over_x) 65 Built-in Functions exponential genType genType genType genType genType pow( genType x ,genType y) exp2( genType x) log2( genType x) sqrt( genType x) inversesqrt( genType x) 66 Built-in Functions common genType genType genType genType genType genType genType genType genType genType genType abs( genType x) sign( genType x) floor( genType x) ceil( genType x) fract( genType x) mod( genType x ,float y) mod( genType x ,genType y) min( genType x ,genType y) max( genType x ,genType y) clamp( genType x ,float v0, float v1) clamp( genType x ,genType v0, genType v1) 67 Built-in Functions interpolations // return x*(1.0-a) + y*a genType mix( genType x ,genType y ,float a) genType mix( genType x ,genType y ,genType a) // x <= edge ? 0.0 : 1.0 genType step( float edge ,genType x) genType step( genType edge ,genType x) 68 Built-in Functions interpolations // genType t; // t = (x-edge0)/(edge1-edge0); // t = clamp( t, 0.0, 1.0 ); // return t*t*(3.0-2.0*t); genType smoothstep( float edge0 ,float edge1 ,genType x) genType smoothstep( genType edge0 ,genType edge1 ,genType x) 69 Built-in Functions geometric float float float vec3 genType genType length( genType x) distance( genType p0 ,genType p1) dot( genType x ,genType y) cross( vec3 x ,vec3 y) normalize( genType x) faceforward( genType N ,genType I ,genType Nref) genType reflect( genType I ,genType N) 70 Built-in Functions vector relational bGenType lessThan( genType x ,genType y) bGenType lessThanEqual( genType x ,genType y) bGenType greaterThan( genType x ,genType y) bGenType greaterThanEqual( genType x ,genType y) bGenType equal( genType x ,genType y) bGenType notEqual( genType x , genType y) bool any( bGenType x) bool all( bGenType x) 71 Built-in Functions texture vec4 vec4 vec4 vec4 texture1D( sampler1D sampler ,float coord ,float bias) texture2D( sampler2D sampler ,vec2 coord ,float bias) texture3D( sampler3D sampler ,vec3 coord ,float bias) textureCube( samplerCube sampler ,vec3 coord ,float bias) 72 Built-in Functions texture (projective) vec4 vec4 vec4 vec4 texture1DProj( sampler1D sampler ,vec2 coord ,float bias) texture2DProj( sampler2D sampler ,vec3 coord ,float bias) texture3DProj( sampler3D sampler ,vec4 coord ,float bias) textureCubeProj( samplerCube sampler ,vec4 coord ,float bias) 73 Built-in Functions texture (projective) vec4 vec4 texture1DProj( sampler1D ,vec4 coord texture2DProj( sampler2D ,vec4 coord sampler ,float bias) sampler ,float bias) 74 Built-in Functions texture rectangle #define GL__EXT_texture_rectangle vec4 texture2DRectEXT( sampler2DRect__EXT ,vec2 coord) vec4 texture2DRectProjEXT( sampler2DRect__EXT ,vec3 coord) vec4 texture2DRectProjEXT( sampler2DRect__EXT ,vec4 coord) sampler sampler sampler 75 Built-in Functions shadow vec4 vec4 vec4 shadow2D( sampler2DShadow sampler ,vec3 coord ,float bias) shadow1DProj( sampler1DShadow sampler ,vec4 coord ,float bias) shadow2DProj( sampler2DShadow sampler ,vec4 coord ,float bias) 76 Built-in Functions shadow rectangle #ifndef #define #endif vec4 vec4 GL__EXT_texture_rectangle GL__EXT_texture_rectangle shadow2DRectEXT( sampler2DRectShadow__EXT sampler ,vec3 coord) shadow2DRectProjEXT( sampler2DRectShadow__EXT sampler ,vec4 coord) 77 Built-in Functions noise float vec2 vec3 vec4 noise1( noise2( noise3( noise4( genType genType genType genType coord) coord) coord) coord) 78 Built-in Functions vertex vec4 ftransform( void ) // Example usage: gl_Position = ftransform(); // user-defined function, may be variant vec4 ftransform( void ) { vec4 p; p = gl_ModelViewProjectionMatrix * gl_Vertex; return p; } 79 Built-in Functions fragment genType dFdx( genType p) genType dFdy( genType p) genType fwidth( genType p) 80 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples – Example 1 81 Trivial Shader vertex varying vec3 Normal; // output void main( void) { gl_Position = ftransform(); Normal = normalize( gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; } 82 Trivial Shader fragment varying vec3 Normal; // input uniform vec3 LightColor; // Light Color uniform vec3 LightPos; // Light Position void main( void) { vec3 color = LightColor; color *= clamp( dot( normalize( Normal),LightPos) ,0.0, 1.0); gl_FragColor = vec4( color, 1.0); } 83 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples – Example 1 – Hints and Kinks 84 Hints and Kinks no casts float Function( vec4 { float f; f = (float)p; p ) // C assumptions // // WRONG no casts return f; } 85 Hints and Kinks no casts float Function( { float f; f = float( p vec4 ); p ) // C assumptions // // OK constructor return f; } 86 Hints and Kinks no casts float Function( vec4 { float f; f = p.x; p ) // C assumptions // // OK swizzle return f; } 87 Hints and Kinks no vec4-centricism vec4 Function( vec4 p ) // // ARB_*_program assumptions // // OK valid swizzle { vec4 f; f = p.xxxx; return f; } 88 Hints and Kinks no vec4-centricism vec4 Function( float p ) // // ARB_*_program assumptions { vec4 f; f = p.xxxx; // // WRONG invalid swizzle return f; } 89 Hints and Kinks no vec4-centricism vec4 Function( float p ) // // ARB_*_program assumptions { vec4 f; f = vec4( p.x ); // // OK explicit constructor return f; } 90 Hints and Kinks no implicit casts vec4 Function( vec4 p ) // // C or RenderMan assumptions { vec4 f = 2 f; * p; // // WRONG no implicit casts return f; } 91 Hints and Kinks no implicit casts vec4 Function( vec4 p ) // // C or RenderMan assumptions { vec4 f; f = 2.0 * p; // // OK float * vec4 return f; } 92 Hints and Kinks no implicit casts vec4 Function( vec4 p ) // // C or RenderMan assumptions { vec4 f; f = float( 2 ) * p; // // OK float * vec2 return f; } 93 Hints and Kinks declare before use vec4 Function( vec3 p ) // // Shading Language assumptions { vec4 f.a = 1.0; // // Wrong declared after use f.rgb = p; return f; } 94 Hints and Kinks declare before use vec4 Function( vec3 p ) // // Shading Language assumptions { vec4 f[3] = 1.0; // // Wrong declared after use f.rgb = p; return f; } 95 Hints and Kinks declare before use vec4 Function( vec3 p ) // // Shading Language assumptions { vec4 f; // // OK declared before use f.rgb = p; f.a = 1.0; return f; } 96 Hints and Kinks declare before use vec4 Function( vec3 p ) // // Shading Language assumptions { vec4 f = vec4( p, 1 );// // return f; OK declared before use } 97 Hints and Kinks no vector scalar assignment vec4 Function( vec4 { vec4 f = 0.0; p ) // HLSL assumptions // // WRONG lvalue rvalue mismatch f += p.x; return f; } 98 Hints and Kinks no vector scalar assignment vec4 Function( vec4 { vec4 f = vec4( 0.0 f += p.x; p ) // HLSL assumptions ); // // // // OK constructor OK f = f + p.x; return f; } 99 Hints and Kinks transpose built-in? vec4 Function( vec4 p ) // // ARB_*_program assumptions { vec4 f; f = transpose( gl_ModelViewMatrix ) * p; return f; } 100 Hints and Kinks transpose built-in? vec4 Function( vec4 p ) // // ARB_*_program assumptions { vec4 f; f = p * gl_ModelViewMatrix; return f; } 101 Hints and Kinks extensions #ifndef GL__EXT_cool_extension #error "GL__EXT_cool_extension required" #endif vec4 Function( vec4 p ) { vec4 color; color = coolFunctionEXT( p ); color.rgb *= color.a; return color; } 102 Hints and Kinks extensions #ifndef GL__EXT_cool_extension vec4 coolFunctionEXT( vec4 p ); // emulate #endif vec4 Function( vec4 p ) { vec4 color; color = coolFunctionEXT( p ); color.rgb *= color.a; return color; } 103 OpenGL Shading Language Today • • • • • Brief History How we replace Fixed Function OpenGL Programmer View OpenGL Shaderwriter View Examples – Example 1 – Hints and Kinks – Example 2 104 Porting Shaders example (with optimizations) [Segal, Akeley, Leech] The OpenGL Graphics System: A Specification (V 1.5) p. 47 105 Porting Shaders teaching example vec2 SphereMap( in vec3 p, in vec3 N ) { vec3 R, U; float M; U = normalize( p ); R = reflect( U, N ); M = 2.0 * sqrt( R.x*R.x + R.y*R.y + (R.z+1.0)*(R.z+1.0) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } [Rost] OpenGL Shading Language ("Orange Book" ) p. 229 106 Porting Shaders argument normalization vec2 SphereMap( in vec3 p, in vec3 N ) { vec3 R, U; float M; U = normalize( p ); R = reflect( U, N ); M = 2.0 * sqrt( R.x*R.x + R.y*R.y + (R.z+1.0)*(R.z+1.0) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 107 Porting Shaders let caller normalize vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); M = 2.0 * sqrt( R.x*R.x + R.y*R.y + (R.z+1.0)*(R.z+1.0) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 108 Porting Shaders (z+1) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); M = 2.0 * sqrt( R.x*R.x + R.y*R.y + (R.z+1.0)*(R.z+1.0) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 109 Porting Shaders cse (exception proves rule) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * sqrt( R.x*R.x + R.y*R.y + R.z*R.z ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 110 Porting Shaders x2+y2+z2 vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * sqrt( R.x*R.x + R.y*R.y + R.z*R.z ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 111 Porting Shaders vectorize scalar expression vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * sqrt( dot( R, R ) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 112 Porting Shaders built-in function? vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * sqrt( dot( R, R ) ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 113 Porting Shaders length vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * length( R ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 114 Porting Shaders M is denominator only vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float M; R = reflect( U, N ); R.z += 1.0; M = 2.0 * length( R ); return vec2( R.x/M + 0.5, R.y/M + 0.5 ); } 115 Porting Shaders pre-invert M vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 1.0/( 2.0 * length( R ) ); return vec2( R.x*inverseM + 0.5, R.y*inverseM + 0.5 ); } 116 Porting Shaders 1.0/2.0 vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 1.0/( 2.0 * length( R ) ); return vec2( R.x*inverseM + 0.5, R.y*inverseM + 0.5 ); } 117 Porting Shaders constant folding (epr) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 / length( R ); return vec2( R.x*inverseM + 0.5, R.y*inverseM + 0.5 ); } 118 Porting Shaders scale and bias vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 / length( R ); return vec2( R.x*inverseM + 0.5, R.y*inverseM + 0.5 ); } 119 Porting Shaders vectorize scale and bias vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 / length( R ); return R.xy*inverseM + 0.5; } 120 Porting Shaders built-in function? vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 / length( R ); return R.xy*inverseM + 0.5; } 121 Porting Shaders user-defined function float inverselength( const in vec3 p ); vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 * inverselength( R ); return R.xy*inverseM + 0.5; } float inverselength( vec3 p ) { return inversesqrt( dot( p, p ) ); } 122 Porting Shaders scalar temporary float inverselength( const in vec3 p ); vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; float inverseM; R = reflect( U, N ); R.z += 1.0; inverseM = 0.5 * inverselength( R ); return R.xy*inverseM + 0.5; } float inverselength( const in vec3 p ) { return inversesqrt( dot( p, p ) ); } 123 Porting Shaders reorder to vectorize float inverselength( const in vec3 p ) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R.xy *= inverselength( R ); return R.xy*0.5 + 0.5; } float inverselength( const in vec3 p ) { return inversesqrt( dot( p, p ) ); } 124 Porting Shaders built-in? float inverselength( const in vec3 p ) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R.xy *= inverselength( R ); return R.xy*0.5 + 0.5; } float inverselength( const in vec3 p ) { return inversesqrt( dot( p, p ) ); } 125 Porting Shaders normalize (readable but slow?) vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R = normalize( R ); return R.xy*0.5 + 0.5; } 126 Porting Shaders function parameters vec2 SphereMap( in vec3 U, in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R = normalize( R ); return R.xy*0.5 + 0.5; } 127 Porting Shaders const vec2 SphereMap( const in vec3 U, const in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R = normalize( R ); return R.xy*0.5 + 0.5; } 128 Porting Shaders add terse comments // prenormalize parameters vec2 SphereMap( const in vec3 U, const in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R = normalize( R ); return R.xy*0.5 + 0.5; // half-angle // [-1.0,1.0]->[0.0,1.0] } 129 Porting Shaders fin vec2 SphereMap( const in vec3 U, const in vec3 N ) { vec3 R; R = reflect( U, N ); R.z += 1.0; R = normalize( R ); return R.xy*0.5 + 0.5; // half-angle // [-1.0,1.0]->[0.0,1.0] } // example usage vec2 tc = SphereMap( normalize( p ), normalize( n ) ); 130