Question

The following R code generates an HTML file and opens it in the browser:

library(rgl)
M <- rbind(
  c(0,0,0),
  c(-1,4,0),
  c(4,9,0),
  c(6,3,0)
  )
  quads3d(M,col='red')
browseURL(paste("file://", writeWebGL(dir=file.path(tempdir(), "webGL"), 
          width=500), sep=""))

The rendering is an interactive planar polyhedron in the 3D space.

With the latest version of the rgl package (0.93.935), the HTML rendering does not work for Windows users (as well as iOS users, I think) with default configuration browser. With the older version 0.93.928, it works.

I have posted the html output of rgl 0.93.928 and the html output of rgl 0.93.935.

I have reported this issue to Duncan Murdoch (author of rgl) and he has given me the following solution for Firefox: type and run "about: config" in the address bar, and turn the parameters webgl.prefer-native-gl and webgl.force-enabled to true. Then the HTML rendering works.

My questions:

  • How to do with Google Chrome?

  • Is it possible to change something in the HTML code in order that the HTML rendering works with the default configuration? (as for the 0.93.928 version).

Was it helpful?

Solution

As difficult as the getting to the problem was as easy is the solution to it.

As of latest version of rgl I could acquire the problem resides inside the fragment shader of the html output:

varying vec4 vCol; // carries alpha
varying vec4 vPosition;
varying vec3 vNormal;

vec3 eye = normalize(-vPosition.xyz);
const vec3 emission = vec3(0., 0., 0.);
const vec3 ambient1 = vec3(0., 0., 0.);
const vec3 specular1 = vec3(1., 1., 1.);// light*material
const float shininess1 = 50.;
vec4 colDiff1 = vec4(vCol.rgb * vec3(1., 1., 1.), vCol.a);
const vec3 lightDir1 = vec3(0., 0., 1.);
vec3 halfVec1 = normalize(lightDir1 + eye);

void main(void) {
    vec4 lighteffect = vec4(emission, 0.);
    vec3 n = normalize(vNormal);
    n = -faceforward(n, n, eye);
    vec3 col1 = ambient1;
    float nDotL1 = dot(n, lightDir1);
    col1 = col1 + max(nDotL1, 0.) * colDiff1.rgb;
    col1 = col1 + pow(max(dot(halfVec1, n), 0.), shininess1) * specular1;
    lighteffect = lighteffect + vec4(col1, colDiff1.a);
    gl_FragColor = lighteffect;
}

it defines variables outside on the main function which skips value assignments and thus fails to compile with division-by-zero failures. The solution is to move the start of the main function above the definition block directly after the varying values:

varying vec4 vCol; // carries alpha
varying vec4 vPosition;
varying vec3 vNormal;

void main(void) {
    vec3 eye = normalize(-vPosition.xyz);
    const vec3 emission = vec3(0., 0., 0.);
    const vec3 ambient1 = vec3(0., 0., 0.);
    const vec3 specular1 = vec3(1., 1., 1.);// light*material
    const float shininess1 = 50.;
    vec4 colDiff1 = vec4(vCol.rgb * vec3(1., 1., 1.), vCol.a);
    const vec3 lightDir1 = vec3(0., 0., 1.);
    vec3 halfVec1 = normalize(lightDir1 + eye);

    vec4 lighteffect = vec4(emission, 0.);
    vec3 n = normalize(vNormal);
    n = -faceforward(n, n, eye);
    vec3 col1 = ambient1;
    float nDotL1 = dot(n, lightDir1);
    col1 = col1 + max(nDotL1, 0.) * colDiff1.rgb;
    col1 = col1 + pow(max(dot(halfVec1, n), 0.), shininess1) * specular1;
    lighteffect = lighteffect + vec4(col1, colDiff1.a);
    gl_FragColor = lighteffect;
}

This will show the object as desired.

You may want to contact Duncan Murdoch again and send him a link to this post if as you said you're not versed in html and webgl.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top