1 / 113

95.4501

95.4501. Water. Water. Four properties that engines either control or fake... Waves Reflection Refraction Flow. Techniques. Environment mapping via static cube maps are often used to provide simple reflection and refraction without needing to draw the world in multiple passes.

cheung
Download Presentation

95.4501

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 95.4501 Water

  2. Water • Four properties that engines either control or fake... • Waves • Reflection • Refraction • Flow

  3. Techniques • Environment mapping via static cube maps are often used to provide simple reflection and refraction without needing to draw the world in multiple passes. • Dynamic cube maps are also used to provide more locally correct environment mapping. • Multiple world drawing passes and frame buffers can be used instead of cube maps to provide more accurate results. • Wave simulation provides even better results.

  4. 95.4501 Environment Mapping + Cube Maps

  5. Environment Mapping • Environment mapping is a technique that encodes the environment in a map (most simply a cube map); also called a skybox. • Works well under the assumption that the environment is infinitely far. • Typical applications • Skybox (can never get to the box). • Vehicle shine (give it a chrome appearance); works best on curved surfaces. • Water shine to reflect fuzzy sky.

  6. Cube Maps T L F R B B Humus viewer

  7. Building Cube Maps • Via pictures taken by camera and stitched with special software. • Drawn or assembled by artists. • Built by the game engine by taking 6 pictures with 90 degrees field of view and square aspect ratio... • Halflife worlds are filled with boxes that say “make static cube map here” or “make dynamic cube map when near here”

  8. Sampling Cube Maps • Cube maps are sampled with an unnormalized 3D direction vector (the pixels are conceptually at infinity). • e.g., texCUBE (sample, direction) • The primitive deals with making the corners LOOK smoothly rounded... So don’t need to bother normalizing vector if sampling cube map

  9. Reflection/Refraction Shader Primitives • Reflection/refraction are built in shader primitives... • Snell's Law • 1 sin 1 = 2 sin 2 • = index of refraction • Air (1), Water (1.33), Glass (1.5) N N In In R 1 1 2 2 R R = reflect (In, N)For N normalized is mirror reflection R = refract (In, N, r)For N normalized and r is ratio 2 / 1

  10. Simultaneous Reflection/Refraction • The fresnel effect dictates the proportion of reflection to refraction via a reflection coefficientt (In is incident ray, N is normal) • t = clamp01 (bias + scale * (1 + In.N)power)) • So you can interpolate via • lerp (refraction, reflection, t) When looking straight down, I is aligned against N (to give -1), so with no bias, t = 0 for no reflectionj. shiny car: bias=0.05 scale=0.95 power=3.0glass: bias=0.04 scale=1.0 power=2.0water: bias=0.6 scale=0.8 power=6.0

  11. Chromatic Dispersion • Chromatic dispersion dictates that red, green, blue components have decreasing index of refraction ratios; e.g., 1.33, 1.27, 1.2 resp. for water. N I 1 1 2 2 red green blue

  12. Shader Functions float fresnelRatio (float bias, float scale, float power, float3 incidentRay, float3 normal) { return clamp01 (bias + scale * pow (1.0 + dot (incidentRay, normal), power)); } float waterFresnelRatio (float3 incidentRay, float3 normal) { return fresnelRatio (0.6, 0.8, 6.0, incidentRay, normal);} float3 refract (float3 incidentRay, float3normal, float3 indexOfRefractionRatio) { //This is chromatic refract. The compiler will choose this “refract” method if a //float3 index of refraction ratio is provided instead of a single float... return float3 ( refract (incidentRay, normal, indexOfRefractionRatio .x), refract (incidentRay, normal, indexOfRefractionRatio .y), refract (incidentRay, normal, indexOfRefractionRatio .z));} shiny car: bias=0.05 scale=0.95 power=3.0glass: bias=0.04 scale=1.0 power=2.0water: bias=0.6 scale=0.8 power=6.0

  13. Skyboxes • Skyboxes are inward facing cubes with 6 pictures of very far objects that surround you (left/right, top/down, front/back); e.g., mountains. • They can be drawn in 2 ways (a face is a quad). • By drawing 6 faces of a large cube taking special care that the pixels at the borders touch at the mid point (pixel perfect drawing). • By drawing 1 face via 1 cube texture that contains the 6 2D texture in a special way.

  14. Cube Textures or Maps T L F R B back B bottom

  15. Loading textures in OpenGL • GLbooleanmipmap = GL_TRUE); //or GL_FALSEglTexParameteri (GL_TEXTURE_2D, GL_GENERATE_MIPMAP, mipmap); • glTexImage2D (GL_TEXTURE_2D, 0,GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE , data); • glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE , data); • glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X , 0, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); internal format external format cube map has 6 pieces (so do this 6 times) Older OpenGL style uses extra call gluBuild2DMipmapsafterglTexImage2D(with similar parameters) if you want mipmaps GL_TEXTURE_CUBE_MAP_POSITIVE_X GL_TEXTURE_CUBE_MAP_POSITIVE_Y GL_TEXTURE_CUBE_MAP_POSITIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_X GL_TEXTURE_CUBE_MAP_NEGATIVE_Y GL_TEXTURE_CUBE_MAP_NEGATIVE_Z

  16. Pseudo Code for Drawing Skybox void Renderer::DrawSkybox () { • glDepthMask (GL_FALSE);glEnable (GL_TEXTURE_CUBE_MAP_SEAMLESS );SetCurrentShader (skyboxShader); UpdateShaderMatrices (); quad -> Draw (); //At [0,0,0]; It’s units are -0.5 to +0.5 glUseProgram (0); glDisable (GL_TEXTURE_CUBE_MAP_SEAMLESS ); glDepthMask (GL_TRUE); } But you need to do something special in the SHADERS to make it work...

  17. Drawing the Skybox • Note that if the camera is at an arbitrary spot in the world, drawing a quad at [0,0,0] in the standard way could draw nothing (e.g., if [0,0,0] is behind the camera). • Issue 1: We need to make sure the quad is on the screen and NOT clipped by the camera’s “NEAR” plane. • Issue 2: We also need to make sure that even with a wide field of view (e.g, 100 degrees instead of a more traditional 60 degrees), we can’t see any part OUTSIDE the quad. So we may need to scale the quad...

  18. Step 1: Understanding How To Draw The Cube Map With a Quad • Claim 1: If F were the matrix for a flying bird, and we want to see from the bird’s point of view, the view matrix would be F-1. • In our case, we’ll use C instead of F to denote the camera. Hence the view matrix would be C-1. Why? Explained on the next slide...

  19. Step 1: Understanding How To Draw The Cube Map With a Quad • Experiment: Suppose we have a point [-1,0.0] on our left and the camera is at the origin facing straight ahead. • So clearly, we can’t see it... Let’s changeC to the matrix ROTATE LEFT (by 90 degrees). So the view matrix V changes in such a way that the point in view space is [0,0, -1]; i.e., one meter in front of us. What’s V? Camera C = Identity (at [0,0,0] looking straight ahead) [-1,0,0] [0,0,0]

  20. If C is the camera matrix, the view matrix V = C-1 • So far, [-1,0,0] in world space is [0,0,-1] in view space. • What’s V? Clearly, [-1,0, 0] * V = [0,0, -1]. What did V do to [-1,0, 0]? [-1,0,0] [0,0,0] [0,0,-1] V rotated [-1,0,0] RIGHT to produce [0,0,-1] If C = ROTATE LEFT, V = ROTATE RIGHT [-1,0,0] [0,0,0]

  21. So what do we Do? • Although V = C-1, let’s not use V to draw the quad at [0,0,0]... What if we use I (the identity) instead. • It will get clipped by the near clipping plane... Typical values for near plane distance is 0.01, 0.1, 0.2 (let’s assume 1 is way past the clipping plane). Far plane (far away) Quad at [0,0,0] with units in range -0.5 to +0.5 Near plane [0,0,0]

  22. So what do we Do? • If we move it ahead by one, it will NOT completely cover the screen if a wide-angle field of view is used... • So scale the quad by a huge amount; e.g., 10. The draw routine will clip it to the screen. • What we need to do. If p is a point on the quad, • transform it by p * 10 - 1 Far plane (far away) Normal FOV Wide angle FOV Near plane [0,0,0] scale by 10, move ahead by 1

  23. What uv do we use to index into the cube map? • We want to be able to take a point p on the screen and convert it to a uv coordinate (for cube maps, we need 3D directions, not points). • Note that “p - [0,0,0]” is a vector. But is it the correct one... To figure out what we need, lets consider the vector for the point right in front of us... d = [0, 0, -1]. • Recall that our camera was ROTATED LEFT. So the d we want is [-1,0,0]. How do we get it? [0,0,-1] Near plane [0,0,0]

  24. What uv do we use to index into the cube map? • Recall that our camera was ROTATED LEFT. So the d we want is [-1,0,0]. How do we get it from [0,0,-1]? • All we need is d * C. Use V3x3 * d instead... [0,0,-1] Near plane Vectors only need the 3x3 part of the matrix (no translation) A right multiply is a multiply by “transpose (V3x3)” WHICH IS its INVERSE of V3x3 if there is no scale... But Cameras don’t have scale

  25. Summary • A point p is transformed via • p * 10 - 1 • A point p is reinterpreted as a uvxyz direction and transformed via • V3x3 * p scale by 10, move ahead by 1 This is p * C BUT USING V which is C-1.

  26. Vertex Shader For Drawing a Skybox in OpenGL... # version 150 core //Transform position via “* 10 - 1” and direction via “* inverse (viewMatrix)”.uniform mat4 viewMatrix ;uniform mat4 projectionMatrix ; struct INPUT { vec3 position;}; struct OUTPUT { vec3 uvw;}; INPUT input; OUTPUT output; void main () { vec3 position = input.position * 10.0 - vec3 (0 ,0 ,1); vec3 direction = input.position; output.uvw = direction * mat3 (viewMatrix); //direction * inverse (viewMatrix)gl_Position = projectionMatrix * vec4 (position, 1.0); } Warning: OpenGL Conventions are flipped. M * p is the standard left multiplyp * M is the right multiply (left multiply by transpose)

  27. Pixel Shader For Drawing a Skybox in OpenGL... # version 150 core //Sample the cube map with the UNNORMALIZED uvw vector.uniform samplerCubecubeTexture; struct INPUT { vec3 uvw;}; struct OUTPUT { vec4 color;}; INPUT input; OUTPUT output; void main ( void ) { • output.color = texture (cubeTexture , input.uvw); } Warning: OpenGL Conventions are flipped. M * p is the standard left multiplyp * M is the rightmultiply (left multiply by transpose)

  28. Drawing a large flat water body Reflecting The Skybox • Assume the game world draws a quad for a lake or ocean that is scaled and positioned in the world... via a modelMatrix. • The following texture is supplied. • The vertex shader provides 3D world space “position” (by multiplying by modelMatrix) and 2D “textureCoordinate” (by passing it through).

  29. Pixel Shader For Drawing Skybox Reflecting Water # version 150 core //Sample the cube map with the UNNORMALIZED uvw vector. uniform sampler2D waterTexture;uniform samplerCubecubeTexture;uniform vec3 cameraWorldPosition; struct INPUT { vec4 worldPosition; vec3 textureCoordinate;}; INPUT input; OUTPUT output; void main ( void ) {vec3 toWater = normalize (input.worldPosition.xyz -cameraWorldPosition); vec3 waterNormal = vec3 (0.0, 1.0, 0.0); //Up... vec3 waterReflection = reflect (towater, waterNormal); vec4 skyboxColor = texture (cubeTexture, waterReflection); vec4 waterColor = texture (waterTexture, input. textureCoordinate; const boolapplyFresnel = true; //or false to disable... float reflectionT = applyFresnel ? fresnelRatio (0.6, 0.8, 6.0, toWater, normal) //bias, scale, power : 0.3;output.color = lerp (waterColor, skyBoxColor, reflectionT);} But it won’t reflect terrain or buildingsnor will the water move... struct OUTPUT { vec4 color;}; Use fresnel t to interpolate between water color and skybox color

  30. 95.4501 Flat Jiggling Water

  31. Ruins Island Demo • AuthorsHelena Duchaussoy Fabien Kapala Franck LetellierBaptiste Malaga • Where IMAC engineering school. Marne-la-Vallée, Paris, FRANCE • What Programming course Demo

  32. A Note About OpenGL Matrices OpenGL uses a right to left system... So if you are used to writing a * A * B or a * (A * B) to transform a to space A and then further transform the result to space B where A and B are row based matrices with the bottom row denoting a translation, everything will seem flipped to you. Technically, you have to write B' * A' * a or (B' * A') * a where A' is built by saying "here are the 4 columns" of A when in fact "they are actually your rows". They will get stored in such a way that everything will work from right to left as they intend...We can prove that but we would need a short discussion... Although a point p can be tranformed into view space via viewMatrix * p, it's a little inaccurate for vectors IF the modelMatrix has non-uniform scaling such as [1, 2, 0,5]... The more correct matrix to use on normals and vectors is actually the transpose of the inverse of the viewMatrixwhich is equal to viewMatrix if the scale is [1,1,1]. OpenGL calls this matrix "gl_NormalMatrix"; i.e., the viewMatrix for normals...

  33. Mirrors For The Game Engine • For reflection, consider the water as a mirror... Can you draw with a reflected camera? DO YOU SEE RED ON YOUR LEFT OR YOUR RIGHT?CAN YOU SEE BLUE? reflected camera mirror camera

  34. How To Mirror Properly causes winding order to be backward (see next slide) • Do not touch the camera... • Reflect the world about the mirror... • Clip away the objects that used to be on the back side of the mirror... requires clippling plane Reflect the world about this PLANE of the mirror camera

  35. 2 Issued For The Game Engine • To deal with reflection, the water is considered to be a mirror... SO A TECHNIQUE IS NEEDED TO PERFORM THE REFLECTION which makes front faces back faces (see next slide). • Also Reflected camera camera

  36. A Side-Effect of the “Reflect” Transformation • A front-facing face becomes back facing (and vice-versa). Will this be afront or backface? 2 1 1 2 front tnorf 4 4 3 3 This must be counteracted via command “if front face winding order is counter clockwise, make then clockwise else make then counter clockwise”

  37. Clipping Planes • A clipping plane pointing in the direction of normal N at a point P looks like [Nx,Ny,Nz,-P.N] • A point Q is on the positive side of the plane if N.Q > 0 • To transform a plane by M, you actually need to transform the 4D point by (M-1)t. a 4D point Clipping planes are a problem for shaders because YOU HAVE TO ADD THE TEST TO ALL PIXEL SHADERS YOU DRAW WITH“if fails positive test, discard pixel”

  38. There is a trick to AVOIDING clipping planes in Shader • Lengyel wrote a paper describing how to modify the standard built-in clipping plane that is automatically part of the perspective matrix so it clips with your plane instead of front plane. • Careful: OpenGL versus DirectX use slightly different math and Lengyel derives it for a right to left system. • I personally was not able to make it work in general (only in simple cases)

  39. Ruins Island Demo • What the demo from France does... Creates a reflection matrix of the form “scale by [1,-1,1]”; i.e. flip y. Uses the Lengyelapproach to clipping which if you look at in the code appears to be random mutilations of the perspective matrix. Works only for horizontal water at [0,0,0] No attempt to abstract it into a nice routine or to explain it

  40. The Water Quad • The water (see WILF NOTE NORMAL) is a 1X1 VERTICAL quad with width and height 400 meters built via“water = new Plan (1,400,400);”. How to rotate around an arbitrary axis 1. Grab the axis with the right hand (thumb pointing in the axis direction) 2. Positive rotation is in the direction you CLOSE YOUR HAND. model space How do you rotate it so it’s horizontal and it’s normal is UP? world space

  41. The Water Quad • The water (see WILF NOTE NORMAL) is a 1X1 quad with width and height 400 meters built as follows “water = new Plan (1,400,400);”. -90 model space Use -90 rotation around x-axis OR +90 rotation around negative x-axis world space

  42. Tangent Space • T, B, N are supposed to indicate where the tangent space x-/y-/z- axes are IN MODEL SPACE... T = [1,0,0]B = [0,1,0]N = [0,0,1] -90 THIS is what it looks like in model space Search “WILF NOTE NORMAL” to see what they are using. TBNMS= mat3 (T,B,N) maps from tangent space to model spaceTBNCS= mat3 (T,B,N) * ModelViewMatrix maps to camera space

  43. Inputs to the Vertex Shader gl_Vertex – gl_Vertex is in model space. gl_MultiTexCoord0.xy – the texture coordinate. gl_LightSource [0].position.xyz – lights in OpenGL are always stored in camera space. uniform float timer; //Time in millisecond#define time timer Shader version #120 (so no structs allowed)

  44. Outputs from the Vertex Shader varying vec3 toLightTS;varying vec3 toCameraTS; varying vec2 flowTextureCoordinate1; //NOT USEDvarying vec2 flowTextureCoordinate2; //NOT USED varying vec2 textureCoordinate;varying vec4 positionPS;

  45. The Vertex Shader “water.vert” //Compute tbnCS... //Compute toLightTS... //Compute toCameraTS... //Pass the texture coordinates through... //Transform the pixel position to projection space.

  46. The Vertex Shader “water.vert” //Compute tbnCS... //Compute the TBN matrix to convert from tangent space to view space. We'll want the //inverse meaning we'll uses it via vector * TBN (which operates on the transpose) //rather than TBN * vector (which operates on it directly). //Note that the transpose of a 3x3 matrix without scale is its inverse... //Let TBN represent uvw axes in model space... Recall the water model is a quad built on a //vertical plane with the normal coming into your eye, //we need T, B, N vectors saying where u,v,w are in model space... vec3 T = vec3 (1.0, 0.0, 0.0); //Let u be the x coordinate (right). vec3 B = vec3 (0.0, 1.0, 0.0); //Let v be the y coordinate (up). vec3 N = vec3 (0.0, 0.0, 1.0); //Let w be the z coordinate (back). mat3 modelViewMatrix = gl_NormalMatrix; //This maps from model space to view space //but is more accurate for normals... //Note: mat3 tbnMS = mat3 (T,B,N); mat3 tbnCS = tbnMS * modelViewMatrix; //But OpenGL is right to left... mat3 tbnCS = modelViewMatrix * mat3 (T,B,N); //Maps from tangent to camera space...

  47. The Vertex Shader “water.vert” //Compute toLightTS... //Built-in OpenGL lights are given in view (also called camera space) positions... vec3 pixelPositionCS = vec3 (gl_ModelViewMatrix * gl_Vertex); //gl_Vertex is in model space. vec3 lightPositionCS = gl_LightSource[0].position.xyz; vec3 toLightCS = pixelPositionCS - lightPositionCS; SHADER_OUTPUT toLightTS = toLightCS * tbnCS; //Premultiply for inverse (tbnCS) * toLightCS; //Compute toCameraTS... vec3 toCameraCS = /* [0,0,0] */ - pixelPositionCS; SHADER_OUTPUT toCameraTS = toCameraCS * tbnCS; //Premultiply for inverse (tbnCS) * toCameraCS; //Pass the texture coordinates through... SHADER_OUTPUT textureCoordinate = gl_MultiTexCoord0.xy; //Transform the pixel position to projection space. SHADER_OUTPUT positionPS = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = SHADER_OUTPUT positionPS; #define SHADER_OUTPUT

  48. The Pixel Shader “water.frag” varying vec3 toLightTS;varying vec3 toCameraTS;varying vec2 textureCoordinate;varying vec4 positionPS; #define SHADER_INPUT //Experiments #define drawOriginal 0#define drawWilfOpaquepPurple 1#define drawWilfTransparentPurple 2#define drawWilfCycleTransparentWaterColors 3#define drawWilfCycleWaterRefractionReflectionPerlin 4#define drawWilfCycleWaterReflectionRefractionPerlin1Perlin2 5#define drawWilfStraightReflect 6#define drawWilfStraightReflectButLessIfStraightDown 7#define drawWilfJiggleReflection1 8#define drawWilfJiggleReflection2 9#define drawWilfColorize 10 //#define experiment drawOriginal

  49. The Pixel Shader “water.frag” varying vec3 toLightTS;varying vec3 toCameraTS;varying vec2 textureCoordinate;varying vec4 positionPS; #define SHADER_INPUT //Experiments #define drawOriginal 0#define drawWilfOpaquePurple 1#define drawWilfTransparentPurple 2#define drawWilfCycleTransparentWaterColors 3#define drawWilfCycleWaterRefractionReflectionPerlin 4#define drawWilfCycleWaterReflectionRefractionPerlin1Perlin2 5#define drawWilfStraightReflect 6#define drawWilfStraightReflectButLessIfStraightDown 7#define drawWilfJiggleReflection1 8#define drawWilfJiggleReflection2 9#define drawWilfColorize 10 //#define experiment drawOriginal

  50. Original Shader

More Related