123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- 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(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(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;
|