How does EEVEE work?
EEVEE is an engine that does rasterization (like Blender Internal or like game-engines), the key difference to ray-tracing (Cycles) is this:


rasterization is a technique where the scene's geometry is projected onto a raster of pixels:



Every pixel's color is determined with shader code based on surface normals and light positions (generally Blinn-Phong &amp; Lambertian shading), edges are anti-aliased, occlusion is determined by using z-buffer values. To make the output look nice, additional "trickery" is needed: light maps, light probes, screen space ambient occlusion, shadow maps, blurred shadows, screen space reflections, distance-sorted transparency, ...
raytracing shoots multiple rays into the scene per pixel from camera, lets them bounce around the scene, rays obey laws of physics and if they reach light source they shade every surface they went through or bounced off with the light's color and energy:



Occlusion, soft shadows, anti-aliased edges, reflections/refraction, global-illumination, caustics, ... It all happens naturally, because light itself is being simulated (to some degree, spectral phenomenon of light is not simulated in Cycles for example, but in some other renderers it is implemented).




Eevee uses OpenGL 3.3 API to do its rendering, which is a set of functions that through drivers use GPU hardware to accelerate its computation (Blender Internal uses same way of rendering the scene as Eevee does, but does use its own code that runs on CPU and is not GPU accelerated).

This is how the rendering pipeline works (from top to bottom, non-programable steps in italics):


Vertex specification - takes input data (vertices with vertex colors, locations, UV coordinates, which vertices make polygons, etc.) and puts them into buffers on which next parts of pipeline operates (the GPU hardware can efficiently operate on these buffers in a parallel way).
Vertex processing


Vertex Shader - vertices go in, altered vertices go out. Here they are for example transformed in space (object transforms), code works on each vertex individually for efficient parallelization
Tessellation (optional) - patches of vertex data are subdivided into smaller primitives in 3 stages: 


Tessellation Control Shader determines how much tessellation to do on each patch (face)
Tessellation Primitive Generator subdivides the input patch
Tessellation Evaluation Shader takes the subdivided patch and computes new vertices values (displaces them for example)

Geometry Shader (optional) - can create new vertices or delete them. Instancing is handled here, generation of multiple levels-of-detail for meshes or  outputting primitives in places of single points (particles) happens here.

Vertex post-processing - output of previous stages is collected and prepared for primitive assembly and rasterization. This includes:


Transform Feedback - output from vertex processing is stored into buffers so it is easy to re-use the transformed data multiple times.
Culling geometry outside the view frustum and by near-far clipping camera planes.
Viewport transform happens here - vertices are transformed into window-space - these are the coords that are rasterized.

Primitive assembly - meshes are divided into a sequence of triangles and sorted in such a way that it is efficient to rasterize.


Face culling is performed, faces that do not face the camera are discarded.

Rasterization - projects the geometry onto a raster of pixels and outputs a collection of fragments. Each fragment represents a segment (fragment) of a rasterized triangle (like grabbing french-fry cutter and slicing triangles into fragments with it) - the fragment size is related to the pixel area. Multiple fragments can come out each pixel (multi-sampling). Each fragment has a (x,y) window-space position, interpolated per-vertex output values (interpolated normal and UVs, vertex colors,..) and can hold other attributes.
Fragment Shader (sometimes called Pixel shader) - takes the fragments and samples colors and computes z-depth value for each of them. Takes care of how pixels between the vertices look.


takes single fragment as input and single fragment is put out (efficient parallelization)
colors are sampled from textures (albedo, roughness, transparency, normal, masks,...)
normal of each fragment is finalized (normal maps or bump maps)
fragment is shaded, see Blinn-Phong and Lambert shading models

Per-sample operations - fragments from Fragment shader are processed and written to frame buffer(s). These operations also include:


determining blending (transparency)
z-depth culling / depth test (it is performed per sample). This can be done before Fragment Shader too.
culling with Stencil buffer happens here - a stencil can be specified and fragments outside stencil are discarded (like the ones hiding behind UI elements). Also can be done before Fragment Shader.



A special stage that does not fit particularly somewhere in the pipeline are Compute shaders. They are generally not directly responsible for drawing triangles and pixels - they generate arbitrary data anywhere they are invoked in the pipeline. Current GPUs can run main pipeline and several compute workloads at the same time. Effects like screen-space ambient occlusion, soft-particles, volumetric effects, blur and depth-of-field and many others are usually implemented with Compute shaders.