Home Reference Source

viewer/shaders/fragment.glsl.js

export const FRAGMENT_SHADER_SOURCE = `

precision highp int;
precision highp float;

in vec3 worldCoords;

#ifdef WITH_PICKING
flat in uvec4 color;
layout(location = 0) out uvec4 myOutputColor;
#ifdef QUANTIZE_COLOR_BUFFER
layout(location = 1) out uvec4 myOutputDepth;
layout(location = 2) out uvec4 myOutputNormal;
#else
layout(location = 1) out float myOutputDepth;
layout(location = 2) out vec4 myOutputNormal;
#endif
#else
in vec4 color;
layout(location = 0) out vec4 myOutputColor;
#endif

#ifndef WITH_PICKING
layout(location=1) out float myOutputAlpha;
#endif

uniform vec4 sectionPlane[6];

#define VIEW_THRESHOLD (200. * 1000.)

void main(void) {
#ifndef WITH_LINEPRIMITIVES
   // Lines are never rendered with the section plane enabled. So this is an
   // optimization measure rather than anything else.
   for (int i = 0; i < 6; ++i) {
      if (dot(worldCoords, sectionPlane[i].xyz) >= sectionPlane[i].w) {
         discard;
      }
   }

   float L = length(worldCoords.xy);
   // To give the geospatial context a more natural falloff.
   if (L > VIEW_THRESHOLD)  {
     discard;
   }
#else
   const float L = 1.;
#endif

#ifdef WITH_PICKING
	#ifdef QUANTIZE_COLOR_BUFFER
	myOutputColor = color;
   // TODO probably should check whether 24 bits of precision are available
   uint intDepth = uint(gl_FragCoord.z * float(uint(1) << uint(24)));
   myOutputDepth = uvec4(intDepth >> 24, intDepth >> 16, intDepth >> 8, 0);
   // The picking program does not have normal attributes, so we *have* to
   // use the shader derivatives. @todo reevaluate
   vec3 normalizedNormal = normalize(cross(dFdx(worldCoords), dFdy(worldCoords))); 
   myOutputNormal = uvec4(int(normalizedNormal.x * 127.0), int(normalizedNormal.y * 127.0), int(normalizedNormal.z * 127.0), 0);
	#else
   myOutputColor = color;
   myOutputDepth = gl_FragCoord.z;
  // The picking program does not have normal attributes, so we *have* to
   // use the shader derivatives. @todo reevaluate
   myOutputNormal.xyz = normalize(cross(dFdx(worldCoords), dFdy(worldCoords)));

  // The next bit is disabled for now because precision was not ok
   // TODO probably should check whether 24 bits of precision are available
//   uint intDepth = uint(gl_FragCoord.z * float(uint(1) << uint(24)));
//   myOutputDepth = uvec4(intDepth >> 24, intDepth >> 16, intDepth >> 8, 0);
   // The picking program does not have normal attributes, so we *have* to
   // use the shader derivatives. @todo reevaluate
//   vec3 normalizedNormal = normalize(cross(dFdx(worldCoords), dFdy(worldCoords))); 
//   myOutputNormal = uvec4(int(normalizedNormal.x * 127.0), int(normalizedNormal.y * 127.0), int(normalizedNormal.z * 127.0), 0);
	
	#endif
#else
  // TODO if we move the lighting to the fragment shader, we can enable back-face-culling (for those objects that can handle it) and use gl_FrontFacing to decide to invert the normal)

//   float mist = 1. - L / (VIEW_THRESHOLD * 0.9);
//   mist = pow(mist, 0.5);

//   myOutputColor = vec4(color.rgb, color.a * mist);
   myOutputColor = color;
   myOutputAlpha = 1.;
#endif
}
`