Description Usage Arguments Details Value Author(s) See Also Examples
View source: R/setUserShaders.R
Sets user-defined shaders (programs written in GLSL) for customized display of rgl objects. Currently only supported in WebGL displays, as the regular displays do not support GLSL.
1 2 3 | setUserShaders(ids, vertexShader = NULL, fragmentShader = NULL,
attributes = NULL, uniforms = NULL,
scene = scene3d(minimal), minimal = TRUE)
|
ids |
Which objects should receive the shaders. |
vertexShader, fragmentShader |
The vertex and fragment shader source code. If |
attributes |
A named list of “attributes” to attach to each vertex. |
uniforms |
A named list of “uniforms”. |
scene |
A |
minimal |
See |
Modern versions of OpenGL work with “shaders”, programs written to run on the graphics processor. The vertex shader does the calculations to move vertices and set their intrinsic colours. The fragment shader computes how each pixel in the display will be shown, taking into account lighting, material properties, etc. (More precisely, it does the computation for each “fragment”; a fragment is a pixel within an object to display. There may be many objects at a particular location, and each will result in a fragment calculation unless culled by z-buffering or being discarded in some other way.)
Normally the WebGL code automatically generates shaders for each object. This function allows them to be written by hand, for testing new features, hand optimization, etc. Currently it is not easy to get copies of the default shaders; they need to be obtained from a Javascript debugger while displaying the scene.
A modified version of the scene
.
Duncan Murdoch
rglwidget
for display of the scene in WebGL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | id <- shade3d(octahedron3d(), col = "red")
# For each triangle, set weights on the 3 vertices.
# This will be replicated to the appropriate size in Javascript.
wts <- diag(3)
# This leaves out the centres of each face
vs <- "
attribute vec3 aPos;
attribute vec4 aCol;
uniform mat4 mvMatrix;
uniform mat4 prMatrix;
varying vec4 vCol;
varying vec4 vPosition;
attribute vec3 aNorm;
uniform mat4 normMatrix;
varying vec3 vNormal;
attribute vec3 wts;
varying vec3 vwts;
void main(void) {
vPosition = mvMatrix * vec4(aPos, 1.);
gl_Position = prMatrix * vPosition;
vCol = aCol;
vNormal = normalize((normMatrix * vec4(aNorm, 1.)).xyz);
vwts = wts;
}
"
fs <- "
#ifdef GL_ES
precision highp float;
#endif
varying vec4 vCol; // carries alpha
varying vec4 vPosition;
varying vec3 vNormal;
uniform mat4 mvMatrix;
uniform vec3 emission;
uniform float shininess;
uniform vec3 ambient0;
uniform vec3 specular0; // light*material
uniform vec3 diffuse0;
uniform vec3 lightDir0;
uniform bool viewpoint0;
uniform bool finite0;
varying vec3 vwts;
uniform vec2 wtrange;
void main(void) {
float minwt = min(vwts.x, min(vwts.y, vwts.z));
if (minwt < wtrange.x || minwt > wtrange.y) discard;
vec3 eye = normalize(-vPosition.xyz);
vec3 lightdir;
vec4 colDiff;
vec3 halfVec;
vec4 lighteffect = vec4(emission, 0.);
vec3 col;
float nDotL;
vec3 n = normalize(vNormal);
n = -faceforward(n, n, eye);
colDiff = vec4(vCol.rgb * diffuse0, vCol.a);
lightdir = lightDir0;
if (!viewpoint0)
lightdir = (mvMatrix * vec4(lightdir, 1.)).xyz;
if (!finite0) {
halfVec = normalize(lightdir + eye);
} else {
lightdir = normalize(lightdir - vPosition.xyz);
halfVec = normalize(lightdir + eye);
}
col = ambient0;
nDotL = dot(n, lightdir);
col = col + max(nDotL, 0.) * colDiff.rgb;
col = col + pow(max(dot(halfVec, n), 0.), shininess) * specular0;
lighteffect = lighteffect + vec4(col, colDiff.a);
gl_FragColor = lighteffect;
}
"
x <- setUserShaders(id, vs, fs, attributes = list(wts=wts),
uniforms = list(wtrange = c(-0.01, 0.15)))
if (interactive())
rglwidget(x)
|
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.