0

I am trying to compute the surface normal for a height map in GLSL. I basically copied the code from a SO answer here with minor changes to match my vars:

77:                 float s01 = textureOffset(uTexture, uv, off.xy).x;
78:                 float s21 = textureOffset(uTexture, uv, off.zy).x;
79:                 float s10 = textureOffset(uTexture, uv, off.yx).x;
80:                 float s12 = textureOffset(uTexture, uv, off.yz).x;
81:                 vec3 va = normalize(vec3(size.xy, s21-s01));
82:                 vec3 vb = normalize(vec3(size.yx, s12-s10));
83:                 vec3 vNormal = cross(va,vb);

where

uniform sampler2D   uTexture;
attribute vec2      uv;
const vec2          size = vec2(2.0, 0.0);
const ivec3         off = ivec3(-1, 0, 1);

The problem is that the compiler returns the errors:

THREE.WebGLProgram: shader error:  0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders ERROR: 0:77: 'textureOffset' : no matching overloaded function found
ERROR: 0:77: 'x' :  field selection requires structure or vector on left hand side
ERROR: 0:78: 'textureOffset' : no matching overloaded function found
ERROR: 0:78: 'x' :  field selection requires structure or vector on left hand side
ERROR: 0:79: 'textureOffset' : no matching overloaded function found
ERROR: 0:79: 'x' :  field selection requires structure or vector on left hand side
ERROR: 0:80: 'textureOffset' : no matching overloaded function found
ERROR: 0:80: 'x' :  field selection requires structure or vector on left hand side

The compiler is apparently choosing the wrong overload of textureOffset, but looking at the spec here, it looks like it should work fine. So... what am I missing? I'm still researching, but any tips for a GLSL newbie would be appreciated. TIA.

Note: This is on OSX with three.js r85

rkwright
  • 447
  • 6
  • 21
  • What does the definition of your overloaded `textureOffset` look like? – TheJim01 Jun 02 '17 at 14:03
  • Well, the signature shown on the Khronos site (link above) is gvec4 textureOffset( gsampler2D sampler, vec2 P, ivec2 offset, [float bias]); where my call (see code above) seems to match. But I'm wondering if perhaps the WebGL compiler for the shader language used by three.js doesn't support the full GLSL-ES set of functions as listed on the Khronos site. BTW, I have worked around this problem by unrolling the code but I'd like to know the answer here. – rkwright Jun 02 '17 at 15:08
  • Sorry, I missed your spec link, and misunderstood that you were using the built-in method. I thought you had written your own overload. It's probably complaining about the const-ness of your `off` parameter. Try removing `const` from your definition, or [cast it non-const](http://en.cppreference.com/w/cpp/language/const_cast) in your function call. – TheJim01 Jun 02 '17 at 16:17
  • Sigh. Thanks, it was a nice idea. But I still get the same errors. Worse, I thought I had a way around it by doing the offset myself, but then (head-slap) realized that the uv coordinates are in 0..1 and the offset is in texel space, which I can't do myself (or at least not obvious to me). If this were C++ I would go dig into the binaries and linker innards to see what's wrong, but with GLSL compiler I don't know where to start. – rkwright Jun 02 '17 at 16:52
  • Try casting ALL of the arguments. Force it to pick the right one. If that doesn't work, or something else breaks, you data/values might be bad. – TheJim01 Jun 02 '17 at 17:21
  • Well, I can't "cast" the sampler2D, but I tried the others. No better. And the data values are good because they are used earlier in the shader and work fine. Still poking at it, but I'm pretty much stumped. I wonder if the error message is correct in that the WebGL compiler invoked by the GL instance in the Chrome browser DOESN'T have all the various textureOffset overloads? – rkwright Jun 02 '17 at 18:06
  • OK, according to the spec, `textureOffset` was made available in GLSL 1.3. So I made a shader, and set it to `#version 130`. Running it gave me: `ERROR: 0:2: '130' : version number not supported`. So while Khronos seems to have tests that run up to `glsl-es3`, it must not have full browser support. You could try upgrading to `THREE.WebGL2Renderer`, but I throw my hands up at that point and wish you luck. :) – TheJim01 Jun 02 '17 at 19:34
  • You do not have `textureOffset` defined anywhere. It is not available in WebGL1 – pailhead Jun 05 '17 at 21:09

1 Answers1

2

Looking at the spec for webgl 1.0 shaders are explicitly restricted to the shader glsl spec Es 1.0 which doesn't include textureOffset.

WebGL 2.0 can use ES 3.0 shaders which do include textureOffset.

I.e. The restriction you are hitting is mandated by the Webgl 1.0 spec, rather than a browser/three.js/platform fault.

AardAngus
  • 36
  • 1