You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
6.6 KiB
JavaScript
178 lines
6.6 KiB
JavaScript
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;
|