Re: [svgwg] Photoreal gradienting: Alternatives to mesh gradient

**Relationship with WebGL - Triangle meshes**
This is fortunately about as simple as it gets; triangles are "the" 
primitive for 3D rendering and vertex colours are universal too. 
Essentially in order to draw an SVG path on the GPU at the moment, the
 path is typically triangulated first anyway _(except in cases where 
specific path rendering extensions are available on the underlying 
hardware such as Nvidia's "NV_path_rendering")_ so GPU-based 
implementers have the functionality needed already. I.e. drop in 
additional vertices during the triangulation stage or directly pipe 
through a raw triangle mesh.

As a quick example, Skia, the graphics library used in both Chrome and
 Firefox for SVG rendering, can draw triangle meshes with both the CPU
 and GPU already. The implementers who would need to do the most work 
are other CPU renderers; they'd need to perform bilinear interpolation
 on a triangle but fortunately that's something which is extensively 
documented due to it's ubiquity in 3D graphics.

**Noise based textures**
For some clarity, "shader" here will be referring to a GPU shader; a 
user written program (in WebGL, they're the ones that go in script 
tags). Noise functions are very commonly implemented in shaders and as
 a result, hardware is starting to get native implementations too. 
Some of the underlying noise functions (from the experimental library)
 as shaders being displayed on a sphere looks like this:

![noise-functions](https://cloud.githubusercontent.com/assets/2579753/18232794/5231e422-72cf-11e6-8a0c-9f8dd38001f8.png)

Each node has it's own shader (Skia would implement these in HLSL and 
GLSL; mine are in Unity3D's ShaderLab language). Rendering it is 
simply a case of drawing a quad (2 triangles as a square) for each 
node using its associated shader. Some nodes, such as a mathematical 
'add', require two sources - these require secondary off screen render
 contexts (also common in WebGL). Importantly, as the quads are just 
ordinary triangle arrays, they are also compatible with triangulated 
SVG paths (as used by GPU implementers). To help with visualising 
this, here's a quick example:

- We'll be doing this will a 100% x 100% shape; i.e. it fills the 
viewbox
- We'll be taking three perlin noise functions at different 
frequencies and adding them together to form fractal noise:

![3levelnoise](https://cloud.githubusercontent.com/assets/2579753/18232919/df43e7a0-72d1-11e6-978e-1b58c801f9c3.jpg)
(Image from 
http://www.neilblevins.com/cg_education/fractal_noise/fractal_noise.html)

GPU implementation:
1. Draw a quad _(or a triangulated path)_ using the perlin shader in 
the "target" render context
2. Draw the second quad using the perlin shader to a second render 
context*
3. Draw an 'add' quad in the target context, referencing the second 
context
 - Add reads from the context it's being drawn to, adds, the 
referenced one and outputs the result
4. The second render context is now junk; reuse it for the next draw
5. Draw the third quad using the perlin shader to the second render 
context
6. Draw a second 'add' quad over the first, referencing the second 
context (as before)

* In this example, a second render context isn't actually necessary - 
we could draw everything in just the one context and alpha blending 
would do the addition "for us". However, in more complex examples like
 the tiles above, noise isn't often directly combined - trees of 
operations are being combined. In short, that requires each branch to 
be drawn to it's own context first.

This "stacking" approach has some distinctively nice properties:
- It works with any general path (i.e. anything that is representable 
as triangles)
- Easy to replicate on a CPU with libraries like libnoise
- Uses universal functionality
- The individual shaders are very simplistic allowing them to work on 
old hardware (rather than relying on compute shaders or a single 
monsterous shader)

-- 
GitHub Notification of comment by Bablakeluke
Please view or discuss this issue at 
https://github.com/w3c/svgwg/issues/257#issuecomment-244620647 using 
your GitHub account

Received on Sunday, 4 September 2016 18:29:42 UTC