0

I'm using SDL 2.0 with OpenGL 2.1 on android (5.1 lollipop on a Moto G).

I have essentially this code:

vec3 norm = normalize(var_normal);
vec3 sun = normalize(sun_position-var_position);
float diff = max(dot(norm,sun),0.);

in my fragment shader.

diff should always be a value between 0. and 1., right?

unfortunately, due to the difficulties of debugging specifics of glsl I'm not sure exactly the value that diff gets, but it seems to be vastly blown out. if I set gl_FragColor = vec4(diff,diff,diff,1.); for debugging, I get straight white for 90% of pixels- the only ones that aren't white are those with normals just shy of orthogonal to the camera.

Here's the interesting bit- when I run it on my computer (OSX El Capitan), it works as expected.

So, instead of maxing the dot with 0., I clamp it to 0. and 1.. Then everything starts to look more reasonable, but with a visibly small diffuse range.

Any ideas moving forward regarding the differences?

genpfault
  • 51,148
  • 11
  • 85
  • 139
Phildo
  • 986
  • 2
  • 20
  • 36
  • yep the `vec3` is nowhere near for precision needed for our Solar system when using real units ... The shifting helps see [GLSL ray ellipsoid intersection](http://stackoverflow.com/q/25470493/2521214) but it must be done outside interpolators and sometimes even outside GLSL itself. The best is to have separate matrices for vector transforms so the position is not reducing the accuracy of transformation. but yes the `diff` should be in `<0.0,1.0>` range so either it is a driver bug or you have something wrong in your code elsewhere. (are you absolutely sure you are outside range? – Spektre Dec 15 '15 at 09:54
  • Also I think this [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](http://stackoverflow.com/a/28020934/2521214) might be interesting for you – Spektre Dec 15 '15 at 10:07
  • @Spektre wait- I'm confused. First, I'm not making a solar system model. Just using sun position as "outdoor light position". Wasn't using real units, just used "99999999" or something for it. Anywho- what I assume is happening is that "normalize" takes sqrt(x^2+y^2+z^2) and divides x, y, and z by the result. if fp precision yields smaller answer for sqrt than reality, the normalize divide will yield a vec > 1. dot of non-normalized vecs can be > 1. Interesting side effect- rather than bring sun closer, I could have done normalize(normalize()) to "solve" (inaccurately, of course). :) – Phildo Dec 17 '15 at 17:38
  • Sorry my bad When I saw the `sun_position` and precision problems I assumed you are into solar system rendering :). By the real units thing I meant I am rendering big range of distances/sizes from `0.1m` up to `1000.0AU = 149597871000000m` which bring a ton of problems ... Of coarse if you got just simple scene then you can ignore all of that ... – Spektre Dec 18 '15 at 09:44

1 Answers1

0

Shucks. Should have known.

My problem was floating point precision. My "sun_position" variable was set veeeerry far away. I just brought it closer and everything works fine.

I would have expected errors in precision to result in a less precise direction (as in, the sun_pos-frag_pos vector would "snap" to the various allowances given by such low precision at such a distance), but normalize should have brought that vector down to unit size? right? so I'd expect any precision errors to result in a "wrong" direction, not a blown out normal? (Clearly I'm wrong about this. I guess my understanding of IEEE floating point still needs some work...)

Phildo
  • 986
  • 2
  • 20
  • 36