GPU Shading and Rendering Open GL Shading Language

  • Slides: 39
Download presentation

GPU Shading and Rendering: Open. GL Shading Language Marc Olano UMBC

GPU Shading and Rendering: Open. GL Shading Language Marc Olano UMBC

Open. GL Shading • High level language – Open. GL Shading Language = GLslang

Open. GL Shading • High level language – Open. GL Shading Language = GLslang = GLSL • Integrated into Open. GL API (no extra run-time)

Organization • API • Vertex Shading • Fragment Shading • Lots of demos. –

Organization • API • Vertex Shading • Fragment Shading • Lots of demos. – 2 -year old Apple Power. Book G 4/1. 5 GHz – ATI Mobility Radeon 9700

API-integrated • Compiler built into driver – Presumably they know your card best –

API-integrated • Compiler built into driver – Presumably they know your card best – IHV’s must produce (good) compilers • Use built-in parameters (gl. Color, gl. Normal, …) – Add your own • Other options can still produce low-level code – Cg, ASHLI, Rapid. Mind, … – With loss of integration

Using High-level Code • Create shader object S = gl. Create. Shader(GL_VERTEX_SHADER) S =

Using High-level Code • Create shader object S = gl. Create. Shader(GL_VERTEX_SHADER) S = gl. Create. Shader. Object. ARB(GL_VERTEX_SHADER_ARB) – Vertex or Fragment • Load shader into object gl. Shader. Source(S, n, shader. Array, len. Array) gl. Shader. Source. ARB(S, n, shader. Array, len. Array) – Array of strings • Compile object gl. Compile. Shader(S) gl. Compile. Shader. ARB(S)

Loading Shaders • gl. Shader. Source(S, n, shader. Array, len. Array) – One string

Loading Shaders • gl. Shader. Source(S, n, shader. Array, len. Array) – One string containing entire mmap’d file – Strings as #includes • Varying variables between vertex and fragment – Strings as lines • Null-terminated if len. Array is Null or length=-1

Using High-level Code (2) • Create program object P = gl. Create. Program() P

Using High-level Code (2) • Create program object P = gl. Create. Program() P = gl. Create. Program. Object. ARB() • Attach all shader objects gl. Attach. Shader(P, S) gl. Attach. Object. ARB(P, S) – Vertex, Fragment or both • Link together gl. Link. Program(P) gl. Link. Program. ARB(P) • Use gl. Use. Program. Object(P) gl. Use. Program. Object. ARB(P)

Using High-level Code (3) • Where is my attributes/uniforms parameter? i=gl. Get. Attrib. Location(P,

Using High-level Code (3) • Where is my attributes/uniforms parameter? i=gl. Get. Attrib. Location(P, ”my. Attrib”) i=gl. Get. Uniform. Location(P, ”my. Attrib”) • Set them gl. Vertex. Attrib 1 f(i, value) gl. Vertex. Attrib. Pointer(i, …) gl. Uniform 1 f(i, value)

Using Low-level Code • Load shader gl. Program. String. ARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, length, shader) –

Using Low-level Code • Load shader gl. Program. String. ARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, length, shader) – Vertex or fragment – Single string (vs. array) • Enable gl. Enable(GL_VERTEX_PROGRAM_ARB)

Useful Tools • Shader debugger • Open. GL debugger – Immediate updates – Trace

Useful Tools • Shader debugger • Open. GL debugger – Immediate updates – Trace of calls made – Choose model/texture – Examine resources – Tweak parameters – Breakpoints/actions – Examine/dump frames – Graph performance • Several available – Not hard to build • A couple of choices

g. DEBugger – A Professional Open. GL Debugger and Profiler • Provides graphic pipeline

g. DEBugger – A Professional Open. GL Debugger and Profiler • Provides graphic pipeline information needed to find bugs and to optimize application performance: – Shortens debugging and profiling time – Improves application quality – Optimizes application performance

Free g. DEBugger License for Academic Users! • Open. GL ARB and Graphic Remedy

Free g. DEBugger License for Academic Users! • Open. GL ARB and Graphic Remedy Academic Program: – Annual program for all Open. GL Academic users – License of the full feature version for one year – Includes all software updates – A limited number of free licenses available for non-commercial developers who are not in academia • More details: http: //academic. gremedy. com

Non-windows OS • Linux – g. DEBugger in progress • Apple Open. GL Profiler

Non-windows OS • Linux – g. DEBugger in progress • Apple Open. GL Profiler and Driver Monitor – Free part of OS / Developer tools

Vertex Demo: Blend Positions

Vertex Demo: Blend Positions

High-level Code void main() { float Kin = gl_Color. r; // key input //

High-level Code void main() { float Kin = gl_Color. r; // key input // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); }

Main Function void main() { float Kin = gl_Color. r; // key input //

Main Function void main() { float Kin = gl_Color. r; // key input // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); }

Use Standard Open. GL State void main() { float Kin = gl_Color. r; //

Use Standard Open. GL State void main() { float Kin = gl_Color. r; // key input gl_Color // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); gl_Multi. Tex. Coord 0 // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); gl_Position // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord gl_Multi. Tex. Coord 0 gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); gl_Tex. Coord }

Built-in Types void main() { float Kin = gl_Color. r; // key input float

Built-in Types void main() { float Kin = gl_Color. r; // key input float // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); vec 4 // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; [0] gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); }

Swizzle / Channel Selection void main() { float Kin = gl_Color. r; // key

Swizzle / Channel Selection void main() { float Kin = gl_Color. r; // key input. r // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); xy // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); }

Vector Construction void main() { float Kin = gl_Color. r; // key input //

Vector Construction void main() { float Kin = gl_Color. r; // key input // screen position from vertex and texture vec 4 Vp = ftransform(); vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); vec 4(Kin) }

Built-in Functions void main() { float Kin = gl_Color. r; // key input //

Built-in Functions void main() { float Kin = gl_Color. r; // key input // screen position from vertex and texture vec 4 Vp = ftransform(); () vec 4 Tp = vec 4(gl_Multi. Tex. Coord 0. xy*1. 8 -. 9, 0. , 1. ); // interpolate between Vp and Tp gl_Position = mix(Tp, Vp, pow(1. -Kin, 8. )); mix( )) // copy to output gl_Tex. Coord[0] = gl_Multi. Tex. Coord 0; gl_Tex. Coord[1] = Vp; gl_Tex. Coord[3] = vec 4(Kin); }

Vertex + Fragment Demo: Fresnel Environment Map

Vertex + Fragment Demo: Fresnel Environment Map

Trick #1: Where is the Eye Object Space • Model. View Matrix Eye Space

Trick #1: Where is the Eye Object Space • Model. View Matrix Eye Space Projection Matrix Clip Space Where is the Eye in Eye Space? – (0, 0, 0)? Not necessarily! • Know where it is in Clip Space – (0, 0, -1, 0), looking in the (0, 0, 1, 0) direction • Assuming GL_LESS depth test – Invert projection to find the eye! – Works for any eye position, or even parallel projection.

Trick #2: Subtract Homogeneous Points • Homogeneous point: vec 4(V. xyz, V. w) –

Trick #2: Subtract Homogeneous Points • Homogeneous point: vec 4(V. xyz, V. w) – 3 D equivalent: V. xyz/V. w – Defers division, makes perspective, translation, and many things happy • Vector subtraction: V–E – V. xyz/V. w – E. xyz/E. w – (V. xyz*E. w – E. xyz*V. w)/(V. w*E. w)

Trick #3: Skip Division for Normalize • normalize(V. xyz/V. w) = normalize(V. xyz) –

Trick #3: Skip Division for Normalize • normalize(V. xyz/V. w) = normalize(V. xyz) – If V. w isn’t negative • Put it all together: – normalize(V-E) – = normalize(V. xyz*E. w - E. xyz*V. w)

Open. GL State Demo: Vertex Lighting

Open. GL State Demo: Vertex Lighting

Lighting Vectors in Eye Space void main() { // convert shading-related vectors to eye

Lighting Vectors in Eye Space void main() { // convert shading-related vectors to eye space vec 4 P = gl_Model. View. Matrix*gl_Vertex; vec 4 E = gl_Projection. Matrix. Inverse*vec 4(0, 0, -1, 0); vec 3 V = normalize(E. xyz*P. w-P. xyz*E. w); vec 3 N = normalize(�� gl_Normal. Matrix*gl_Normal)�� ; …

Accumulate Each Light … // accumulate contribution from each light gl_Front. Color = vec

Accumulate Each Light … // accumulate contribution from each light gl_Front. Color = vec 4(0); for(int i=0; i<gl_Max. Lights; i++) { vec 3 L = normalize(gl_Light. Source[i]. position. xyz*P. w - P. xyz*gl_Light. Source[i]. position. w); vec 3 H = normalize(L+V); float diff = dot(N, L); �� gl_Front. Color += gl_Light. Source[i]. ambient; if (diff > 0. ) {�� gl_Front. Color �+=���� gl_Light. Source[i]. diffuse * diff; gl_Front. Color �+=���� gl_Light. Source[i]. specular * max(pow(dot(N, H), gl_Front. Material. Shininess), 0. ); }� } …

Standard Vertex Shader Stuff … // standard texture coordinate and position stuff gl_Tex. Coord[0]

Standard Vertex Shader Stuff … // standard texture coordinate and position stuff gl_Tex. Coord[0] = gl_Texture. Matrix[0]*gl_Multi. Tex. Coord 0; gl_Position = ftransform(); }

Noise • Controlled, repeatable randomness – Still spotty implementation – Can use texture or

Noise • Controlled, repeatable randomness – Still spotty implementation – Can use texture or compute

Noise Characteristics • Repeatable • Locally continuous but distant points uncorrolated • values [-1,

Noise Characteristics • Repeatable • Locally continuous but distant points uncorrolated • values [-1, 1], average 0 • 1/2 – 1 cycle per unit • Versions for n-D input

Noise Subtleties • Many noise functions based on a lattice – Like a spline

Noise Subtleties • Many noise functions based on a lattice – Like a spline between integer coordinates – Hash of integer coordinates control points • Interpolating values easy but poor – Even with higher-order interpolation • Perlin’s noise – Passes through 0 at each integer – Hash gives gradient

Modified Noise [Olano 2005] • Three relatively independent modifications – New computable hash –

Modified Noise [Olano 2005] • Three relatively independent modifications – New computable hash – Change gradient computation – Reorder computation • Variety of computation/texture options – Can just store in a texture – Can compute with some texture accesses – Can compute with no texture accesses

Computable Hash • Normal hash chains access to permutation texture • Want totally computable

Computable Hash • Normal hash chains access to permutation texture • Want totally computable hash – mod(k*x 2, m) – Still chain for higher-D • hash(floor(P. x) + hash(floor(P. y))) – Not quite as good, but cheap & computable • Noise usually not used alone

Gradient • 3 D Gradient = (±fract(P. x), ±fract(P. y)) – Each sign from

Gradient • 3 D Gradient = (±fract(P. x), ±fract(P. y)) – Each sign from one bit of hash • Made slightly more difficult without bitwise ops – Allows noise(x) = noise(x, 0) • If 2 D noise is stored in a texture • Can share the same texture for 1 D noise as well – Not normally true!

Reordered Computation • Refactor to be able to build n-D noise from two shifted

Reordered Computation • Refactor to be able to build n-D noise from two shifted calls to n-1 D noise – If 2 D noise is stored in a texture – Can build 3 D noise from 2 texture accesses – Can build 4 D noise from 4 texture accesses

Shader Design Strategies • Learn and adapt from Render. Man – Noise – Layers

Shader Design Strategies • Learn and adapt from Render. Man – Noise – Layers • Multiple Passes • Baked computation