123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import Cartesian2 from "../Core/Cartesian2.js";
- import Check from "../Core/Check.js";
- import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
- var textureResolutionScratch = new Cartesian2();
- /**
- * Gets the GLSL functions needed to retrieve clipping planes from a ClippingPlaneCollection's texture.
- *
- * @param {ClippingPlaneCollection} clippingPlaneCollection ClippingPlaneCollection with a defined texture.
- * @param {Context} context The current rendering context.
- * @returns {String} A string containing GLSL functions for retrieving clipping planes.
- * @private
- */
- function getClippingFunction(clippingPlaneCollection, context) {
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.object("clippingPlaneCollection", clippingPlaneCollection);
- Check.typeOf.object("context", context);
- //>>includeEnd('debug');
- var unionClippingRegions = clippingPlaneCollection.unionClippingRegions;
- var clippingPlanesLength = clippingPlaneCollection.length;
- var usingFloatTexture = ClippingPlaneCollection.useFloatTexture(context);
- var textureResolution = ClippingPlaneCollection.getTextureResolution(
- clippingPlaneCollection,
- context,
- textureResolutionScratch
- );
- var width = textureResolution.x;
- var height = textureResolution.y;
- var functions = usingFloatTexture
- ? getClippingPlaneFloat(width, height)
- : getClippingPlaneUint8(width, height);
- functions += "\n";
- functions += unionClippingRegions
- ? clippingFunctionUnion(clippingPlanesLength)
- : clippingFunctionIntersect(clippingPlanesLength);
- return functions;
- }
- function clippingFunctionUnion(clippingPlanesLength) {
- var functionString =
- "float clip(vec4 fragCoord, sampler2D clippingPlanes, mat4 clippingPlanesMatrix)\n" +
- "{\n" +
- " vec4 position = czm_windowToEyeCoordinates(fragCoord);\n" +
- " vec3 clipNormal = vec3(0.0);\n" +
- " vec3 clipPosition = vec3(0.0);\n" +
- " float clipAmount;\n" + // For union planes, we want to get the min distance. So we set the initial value to the first plane distance in the loop below.
- " float pixelWidth = czm_metersPerPixel(position);\n" +
- " bool breakAndDiscard = false;\n" +
- " for (int i = 0; i < " +
- clippingPlanesLength +
- "; ++i)\n" +
- " {\n" +
- " vec4 clippingPlane = getClippingPlane(clippingPlanes, i, clippingPlanesMatrix);\n" +
- " clipNormal = clippingPlane.xyz;\n" +
- " clipPosition = -clippingPlane.w * clipNormal;\n" +
- " float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n" +
- " clipAmount = czm_branchFreeTernary(i == 0, amount, min(amount, clipAmount));\n" +
- " if (amount <= 0.0)\n" +
- " {\n" +
- " breakAndDiscard = true;\n" +
- " break;\n" + // HLSL compiler bug if we discard here: https://bugs.chromium.org/p/angleproject/issues/detail?id=1945#c6
- " }\n" +
- " }\n" +
- " if (breakAndDiscard) {\n" +
- " discard;\n" +
- " }\n" +
- " return clipAmount;\n" +
- "}\n";
- return functionString;
- }
- function clippingFunctionIntersect(clippingPlanesLength) {
- var functionString =
- "float clip(vec4 fragCoord, sampler2D clippingPlanes, mat4 clippingPlanesMatrix)\n" +
- "{\n" +
- " bool clipped = true;\n" +
- " vec4 position = czm_windowToEyeCoordinates(fragCoord);\n" +
- " vec3 clipNormal = vec3(0.0);\n" +
- " vec3 clipPosition = vec3(0.0);\n" +
- " float clipAmount = 0.0;\n" +
- " float pixelWidth = czm_metersPerPixel(position);\n" +
- " for (int i = 0; i < " +
- clippingPlanesLength +
- "; ++i)\n" +
- " {\n" +
- " vec4 clippingPlane = getClippingPlane(clippingPlanes, i, clippingPlanesMatrix);\n" +
- " clipNormal = clippingPlane.xyz;\n" +
- " clipPosition = -clippingPlane.w * clipNormal;\n" +
- " float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n" +
- " clipAmount = max(amount, clipAmount);\n" +
- " clipped = clipped && (amount <= 0.0);\n" +
- " }\n" +
- " if (clipped)\n" +
- " {\n" +
- " discard;\n" +
- " }\n" +
- " return clipAmount;\n" +
- "}\n";
- return functionString;
- }
- function getClippingPlaneFloat(width, height) {
- var pixelWidth = 1.0 / width;
- var pixelHeight = 1.0 / height;
- var pixelWidthString = pixelWidth + "";
- if (pixelWidthString.indexOf(".") === -1) {
- pixelWidthString += ".0";
- }
- var pixelHeightString = pixelHeight + "";
- if (pixelHeightString.indexOf(".") === -1) {
- pixelHeightString += ".0";
- }
- var functionString =
- "vec4 getClippingPlane(highp sampler2D packedClippingPlanes, int clippingPlaneNumber, mat4 transform)\n" +
- "{\n" +
- " int pixY = clippingPlaneNumber / " +
- width +
- ";\n" +
- " int pixX = clippingPlaneNumber - (pixY * " +
- width +
- ");\n" +
- " float u = (float(pixX) + 0.5) * " +
- pixelWidthString +
- ";\n" + // sample from center of pixel
- " float v = (float(pixY) + 0.5) * " +
- pixelHeightString +
- ";\n" +
- " vec4 plane = texture2D(packedClippingPlanes, vec2(u, v));\n" +
- " return czm_transformPlane(plane, transform);\n" +
- "}\n";
- return functionString;
- }
- function getClippingPlaneUint8(width, height) {
- var pixelWidth = 1.0 / width;
- var pixelHeight = 1.0 / height;
- var pixelWidthString = pixelWidth + "";
- if (pixelWidthString.indexOf(".") === -1) {
- pixelWidthString += ".0";
- }
- var pixelHeightString = pixelHeight + "";
- if (pixelHeightString.indexOf(".") === -1) {
- pixelHeightString += ".0";
- }
- var functionString =
- "vec4 getClippingPlane(highp sampler2D packedClippingPlanes, int clippingPlaneNumber, mat4 transform)\n" +
- "{\n" +
- " int clippingPlaneStartIndex = clippingPlaneNumber * 2;\n" + // clipping planes are two pixels each
- " int pixY = clippingPlaneStartIndex / " +
- width +
- ";\n" +
- " int pixX = clippingPlaneStartIndex - (pixY * " +
- width +
- ");\n" +
- " float u = (float(pixX) + 0.5) * " +
- pixelWidthString +
- ";\n" + // sample from center of pixel
- " float v = (float(pixY) + 0.5) * " +
- pixelHeightString +
- ";\n" +
- " vec4 oct32 = texture2D(packedClippingPlanes, vec2(u, v)) * 255.0;\n" +
- " vec2 oct = vec2(oct32.x * 256.0 + oct32.y, oct32.z * 256.0 + oct32.w);\n" +
- " vec4 plane;\n" +
- " plane.xyz = czm_octDecode(oct, 65535.0);\n" +
- " plane.w = czm_unpackFloat(texture2D(packedClippingPlanes, vec2(u + " +
- pixelWidthString +
- ", v)));\n" +
- " return czm_transformPlane(plane, transform);\n" +
- "}\n";
- return functionString;
- }
- export default getClippingFunction;
|