Can't get dFdx working with WebGL1 or 2

Hello,

I hope someone can help me with this. I am at the end of my rope, having gone through all of the discussions and examples I have found and still can’t get dFdx working, neither for WebGl1 or WebGL2. Partial code is shown below.

Thanks for you help.

The fragment shader uses:

#extension GL_OES_standard_derivatives : enable
precision highp float;

varying vec3 vNormal;
varying vec2 vUv;
varying vec3 vViewPosition;

uniform vec3 color;
uniform float animateRadius;
uniform float animateStrength;

vec3 faceNormal(vec3 pos) {
   vec3 fdx = vec3(dFdx(pos.x), dFdx(pos.y), dFdx(pos.z));	
   vec3 fdy = vec3(dFdy(pos.x), dFdy(pos.y), dFdy(pos.z));
   //vec3 fdx = dFdx(pos);
  //vec3 fdy = dFdy(pos);
  return normalize(cross(fdx, fdy));
}

The console shows the following:

THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog Must have an compiled fragment shader attached. <empty string> THREE.WebGLShader: gl.getShaderInfoLog() fragment
WARNING: 0:2: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:14: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:14: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:14: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:15: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:15: 'GL_OES_standard_derivatives' : extension is not supported
ERROR: 0:15: 'GL_OES_standard_derivatives' : extension is not supported1: #define lengthSegments 300.0
2: #extension GL_OES_standard_derivatives : enable
3: precision highp float;
4: 
5: varying vec3 vNormal;
6: varying vec2 vUv;
7: varying vec3 vViewPosition;

Here is also part of the Javascript:

module.exports = function (app) {
    const totalMeshes = isMobile ? 30 : 40;
    const isSquare = false;
    const subdivisions = isMobile ? 200 : 300;
    
    const numSides = isSquare ? 4 : 8;
    const openEnded = false;
    const geometry = createTubeGeometry(numSides, subdivisions, openEnded);
    // add to a parent container
    const container = new THREE.Object3D();
    const lines = [];
    //lines.length = 0;   
  
    ShaderLoader("scripts/Grp3D/Phys4646A2/tube.vert", "scripts/Grp3D/Phys4646A2/tube.frag", function (vertex, fragment) {
	const baseMaterial = new THREE.RawShaderMaterial({
	    vertexShader: vertex,
	    fragmentShader: fragment,
	    side: THREE.FrontSide,
	    extensions: {
		derivatives: true
	    },
	    defines: {
		lengthSegments: subdivisions.toFixed(1),
		ROBUST: false,
		ROBUST_NORMALS: false, 
		FLAT_SHADED: isSquare
	    },
	    uniforms: {
		thickness: { type: 'f', value: 1 },
		time: { type: 'f', value: 0 },
		color: { type: 'c', value: new THREE.Color('#303030') },
		animateRadius: { type: 'f', value: 0 },
		animateStrength: { type: 'f', value: 0 },
		index: { type: 'f', value: 0 },
		totalMeshes: { type: 'f', value: totalMeshes },
		radialSegments: { type: 'f', value: numSides },
		wavelength: { type: 'f', value: 2.0 }
	    }
	});

	for( var i = 0; i < totalMeshes; i++){
	    
	    var t = totalMeshes <= 1 ? 0 : i / (totalMeshes - 1);
	    
	    var material = baseMaterial.clone();
	    material.uniforms = THREE.UniformsUtils.clone(material.uniforms);
	    material.uniforms.index.value = t;
	    material.uniforms.thickness.value = randomFloat(0.005, 0.0075);
	    material.uniforms.wavelength.value = 2.0;
	    
	    var mesh = new THREE.Mesh(geometry, material);
	    mesh.frustumCulled = false; 
	    lines.push(mesh);
	    container.add(mesh);
	}	
    });
    
    return {
	object3d: container,
	update,
	setPalette
    };
        
    function update (dt,wvl) {
	dt = dt / 1000;
	lines.forEach(mesh => {
	    //console.log(dt);
	    mesh.material.uniforms.time.value += dt;
	    mesh.material.uniforms.wavelength.value = wvl;
	});
    }
};

...
   const canvas = document.getElementById('myCanvas');
    var gl = canvas.getContext( 'webgl2' );
    gl.hint(gl.FRAGMENT_SHADER_DERIVATIVE_HINT,gl.NICEST);
    const renderer = new THREE.WebGLRenderer(assign({
	alpha: false,
	stencil: false,
	context: gl,
	antialias: true // default enabled
    }, opt));

...

Did you try enabling the extension via the extensions property of ShaderMaterial instead of doing so in your GLSL code ?

1 Like

Do you mean

extensions: {
		derivatives: true
	    },

Yes, I did.

has there been any update with this?
I am also trying to get this to work but the derivatives property does not seem to help.

You shouldn’t need the extension if using WebGL2. Can you create a jsfiddle demonstrating the problem?

2 Likes