/*
All material copyright ESRI, All Rights Reserved, unless otherwise specified.
See https://js.arcgis.com/4.24/esri/copyright.txt for details.
*/
define(["exports","../views/3d/webgl-engine/core/shaderLibrary/ShaderOutputOptions","../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl","../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl","../views/3d/webgl-engine/core/shaderLibrary/util/RgbaFloatEncoding.glsl","../views/3d/webgl-engine/core/shaderModules/Float2PassUniform","../views/3d/webgl-engine/core/shaderModules/Float2Uniform","../views/3d/webgl-engine/core/shaderModules/Float3Uniform","../views/3d/webgl-engine/core/shaderModules/interfaces","../views/3d/webgl-engine/core/shaderModules/Matrix4PassUniform","../views/3d/webgl-engine/core/shaderModules/Matrix4Uniform","../views/3d/webgl-engine/core/shaderModules/ShaderBuilder","../views/3d/webgl-engine/lib/VertexAttribute"],(function(e,i,o,r,t,a,n,l,s,d,c,p,g){"use strict";function u(e){const u=new p.ShaderBuilder,f=e.output===i.ShaderOutput.Color,m=e.output===i.ShaderOutput.Depth,v=e.output===i.ShaderOutput.Highlight,{vertex:w,fragment:h}=u;return u.extensions.add("GL_OES_standard_derivatives"),u.include(o.SliceDraw,e),u.attributes.add(g.VertexAttribute.POSITION,"vec3"),u.attributes.add(g.VertexAttribute.COLOR,"vec3"),w.uniforms.add(new c.Matrix4Uniform("modelView")),w.uniforms.add(new d.Matrix4PassUniform("proj",((e,i)=>i.camera.projectionMatrix))),w.uniforms.add(new n.Float2Uniform("screenMinMaxSize")),w.uniforms.add(new n.Float2Uniform("pointScale")),w.uniforms.add(new l.Float3Uniform("clipMin")),w.uniforms.add(new l.Float3Uniform("clipMax")),m?(w.uniforms.add(new a.Float2PassUniform("nearFar",((e,i)=>i.camera.nearFar))),u.varyings.add("depth","float")):e.output!==i.ShaderOutput.Highlight&&u.varyings.add("vColor","vec3"),w.code.add(s.glsl`
    void main(void) {
      // Move clipped points outside of clipspace
      if (position.x < clipMin.x || position.y < clipMin.y || position.z < clipMin.z ||
        position.x > clipMax.x || position.y > clipMax.y || position.z > clipMax.z) {
        gl_Position = vec4(0.0,0.0,0.0,2.0);
        gl_PointSize = 0.0;
        return;
      }

      if (rejectBySlice(position)) {
        gl_Position = vec4(0.0,0.0,0.0,2.0);
        gl_PointSize = 0.0;
        return;
      }

      // Position in camera space
      vec4 camera = modelView * vec4(position, 1.0);

      float pointSize = pointScale.x;
      vec4 position = proj * camera;
     ${e.drawScreenSize?s.glsl`
      float clampedScreenSize = pointSize;`:s.glsl`
      float pointRadius = 0.5 * pointSize;
      vec4 cameraOffset = camera + vec4(0.0, pointRadius, 0.0, 0.0);
      vec4 positionOffset = proj * cameraOffset;
      float radius = abs(positionOffset.y - position.y);
      float viewHeight = pointScale.y;
      // screen diameter = (2 * r / w) * (h / 2)
      float screenPointSize = (radius / position.w) * viewHeight;
      float clampedScreenSize = clamp(screenPointSize, screenMinMaxSize.x, screenMinMaxSize.y);
      // Shift towards camera, to move rendered point out of terrain i.e. to
      // the camera-facing end of the virtual point when considering it as a
      // 3D sphere.
      camera.xyz -= normalize(camera.xyz) * pointRadius * clampedScreenSize / screenPointSize;
      position = proj * camera;`}

     gl_PointSize = clampedScreenSize;
     gl_Position = position;

     ${m?s.glsl`depth = (-camera.z - nearFar[0]) / (nearFar[1] - nearFar[0]);`:""}
     ${f?s.glsl`vColor = color;`:""}
    }
  `),h.include(t.RgbaFloatEncoding,e),v&&u.include(r.OutputHighlight),h.code.add(s.glsl`
    void main(void) {
      vec2 vOffset = gl_PointCoord - vec2(0.5, 0.5);
      float r2 = dot(vOffset, vOffset);

      if (r2 > 0.25) {
        discard;
      }
      ${m?s.glsl`gl_FragColor = float2rgba(depth);`:""}
      ${v?s.glsl`outputHighlight();`:""}
      ${f?s.glsl`gl_FragColor = vec4(vColor, 1.0);`:""}
    }
  `),u}const f=Object.freeze(Object.defineProperty({__proto__:null,build:u},Symbol.toStringTag,{value:"Module"}));e.PointRendererShader=f,e.build=u}));
