When I picked up a 3Dtile, an error occurred
What happened?
[Cesium WebGL] Vertex shader compile log: ERROR: 0:72: 'selectedFeature' : undeclared identifier ERROR: 0:72: 'id' : field selection requires structure, vector, or interface block on left hand side ERROR: 0:72: '<' : wrong operand types - no operation '<' exists that takes a left-hand operand of type 'const highp float' and a right operand of type 'highp int' (or there is no acceptable conversion) ERROR: 0:72: 'model_pickTexture' : undeclared identifier ERROR: 0:72: 'selectedFeature' : undeclared identifier ERROR: 0:72: 'st' : field selection requires structure, vector, or interface block on left hand side ERROR: 0:72: 'texture' : no matching overloaded function found ERROR: 0:72: '?:' : mismatching ternary operator operand types 'const mediump float and 'const 4-component vector of float'
Reproduction steps
...
Sandcastle example
No response
Environment
[Cesium WebGL] Vertex shader source: #version 300 es #define HAS_ATMOSPHERE #define COMPUTE_POSITION_WC_ATMOSPHERE #define HAS_NORMALS #define HAS_TEXCOORD_0 #define HAS_FEATURE_ID_0 #define HAS_SELECTED_FEATURE_ID #define SELECTED_FEATURE_ID featureId_0 #define HAS_SELECTED_FEATURE_ID_ATTRIBUTE #define USE_CPU_STYLING #define LOG_DEPTH #define OES_texture_float_linear
#define OES_texture_float
#line 0
const float czm_infinity = 5906376272000.0;
struct czm_ray { vec3 origin; vec3 direction; };
struct czm_raySegment { float start; float stop; };
const czm_raySegment czm_emptyRaySegment = czm_raySegment(-czm_infinity, -czm_infinity);
const czm_raySegment czm_fullRaySegment = czm_raySegment(0.0, czm_infinity);
uniform vec3 czm_atmosphereRayleighCoefficient; uniform vec3 czm_atmosphereMieCoefficient; uniform float czm_atmosphereMieScaleHeight; uniform float czm_atmosphereRayleighScaleHeight;
float czm_approximateTanh(float x) { float x2 = x * x; return max(-1.0, min(1.0, x * (27.0 + x2) / (27.0 + 9.0 * x2))); }
czm_raySegment czm_raySphereIntersectionInterval(czm_ray ray, vec3 center, float radius) { vec3 o = ray.origin; vec3 d = ray.direction;
vec3 oc = o - center;
float a = dot(d, d);
float b = 2.0 * dot(d, oc);
float c = dot(oc, oc) - (radius * radius);
float det = (b * b) - (4.0 * a * c);
if (det < 0.0) {
return czm_emptyRaySegment;
}
float sqrtDet = sqrt(det);
float t0 = (-b - sqrtDet) / (2.0 * a);
float t1 = (-b + sqrtDet) / (2.0 * a);
czm_raySegment result = czm_raySegment(t0, t1);
return result;
}
uniform vec2 czm_currentFrustum; uniform mat4 czm_inverseProjection;
void czm_computeScattering( czm_ray primaryRay, float primaryRayLength, vec3 lightDirection, float atmosphereInnerRadius, out vec3 rayleighColor, out vec3 mieColor, out float opacity ) { const float ATMOSPHERE_THICKNESS = 111e3; const int PRIMARY_STEPS_MAX = 16; const int LIGHT_STEPS_MAX = 4;
rayleighColor = vec3(0.0);
mieColor = vec3(0.0);
opacity = 0.0;
float atmosphereOuterRadius = atmosphereInnerRadius + ATMOSPHERE_THICKNESS;
vec3 origin = vec3(0.0);
czm_raySegment primaryRayAtmosphereIntersect = czm_raySphereIntersectionInterval(primaryRay, origin, atmosphereOuterRadius);
if (primaryRayAtmosphereIntersect == czm_emptyRaySegment) {
rayleighColor = vec3(1.0, 0.0, 1.0);
return;
}
float x = 1e-7 * primaryRayAtmosphereIntersect.stop / length(primaryRayLength);
float w_stop_gt_lprl = 0.5 * (1.0 + czm_approximateTanh(x));
float start_0 = primaryRayAtmosphereIntersect.start;
primaryRayAtmosphereIntersect.start = max(primaryRayAtmosphereIntersect.start, 0.0);
primaryRayAtmosphereIntersect.stop = min(primaryRayAtmosphereIntersect.stop, length(primaryRayLength));
float x_o_a = start_0 - ATMOSPHERE_THICKNESS;
float w_inside_atmosphere = 1.0 - 0.5 * (1.0 + czm_approximateTanh(x_o_a));
int PRIMARY_STEPS = PRIMARY_STEPS_MAX - int(w_inside_atmosphere * 12.0);
int LIGHT_STEPS = LIGHT_STEPS_MAX - int(w_inside_atmosphere * 2.0);
float rayPositionLength = primaryRayAtmosphereIntersect.start;
float totalRayLength = primaryRayAtmosphereIntersect.stop - rayPositionLength;
float rayStepLengthIncrease = w_inside_atmosphere * ((1.0 - w_stop_gt_lprl) * totalRayLength / (float(PRIMARY_STEPS * (PRIMARY_STEPS + 1)) / 2.0));
float rayStepLength = max(1.0 - w_inside_atmosphere, w_stop_gt_lprl) * totalRayLength / max(7.0 * w_inside_atmosphere, float(PRIMARY_STEPS));
vec3 rayleighAccumulation = vec3(0.0);
vec3 mieAccumulation = vec3(0.0);
vec2 opticalDepth = vec2(0.0);
vec2 heightScale = vec2(czm_atmosphereRayleighScaleHeight, czm_atmosphereMieScaleHeight);
for (int i = 0; i < PRIMARY_STEPS_MAX; ++i) {
if (i >= PRIMARY_STEPS) {
break;
}
vec3 samplePosition = primaryRay.origin + primaryRay.direction * (rayPositionLength + rayStepLength);
float sampleHeight = length(samplePosition) - atmosphereInnerRadius;
vec2 sampleDensity = exp(-sampleHeight / heightScale) * rayStepLength;
opticalDepth += sampleDensity;
czm_ray lightRay = czm_ray(samplePosition, lightDirection);
czm_raySegment lightRayAtmosphereIntersect = czm_raySphereIntersectionInterval(lightRay, origin, atmosphereOuterRadius);
float lightStepLength = lightRayAtmosphereIntersect.stop / float(LIGHT_STEPS);
float lightPositionLength = 0.0;
vec2 lightOpticalDepth = vec2(0.0);
for (int j = 0; j < LIGHT_STEPS_MAX; ++j) {
if (j >= LIGHT_STEPS) {
break;
}
vec3 lightPosition = samplePosition + lightDirection * (lightPositionLength + lightStepLength * 0.5);
float lightHeight = length(lightPosition) - atmosphereInnerRadius;
lightOpticalDepth += exp(-lightHeight / heightScale) * lightStepLength;
lightPositionLength += lightStepLength;
}
vec3 attenuation = exp(-((czm_atmosphereMieCoefficient * (opticalDepth.y + lightOpticalDepth.y)) + (czm_atmosphereRayleighCoefficient * (opticalDepth.x + lightOpticalDepth.x))));
rayleighAccumulation += sampleDensity.x * attenuation;
mieAccumulation += sampleDensity.y * attenuation;
rayPositionLength += (rayStepLength += rayStepLengthIncrease);
}
rayleighColor = czm_atmosphereRayleighCoefficient * rayleighAccumulation;
mieColor = czm_atmosphereMieCoefficient * mieAccumulation;
opacity = length(exp(-((czm_atmosphereMieCoefficient * opticalDepth.y) + (czm_atmosphereRayleighCoefficient * opticalDepth.x))));
}
uniform vec3 czm_viewerPositionWC; uniform vec3 czm_sunDirectionWC; uniform vec3 czm_lightDirectionWC; #ifdef LOG_DEPTH
out float v_depthFromNearPlusOne; #ifdef SHADOW_MAP out vec3 v_logPositionEC; #endif #endif
vec4 czm_updatePositionDepth(vec4 coords) { #if defined(LOG_DEPTH)
#ifdef SHADOW_MAP vec3 logPositionEC = (czm_inverseProjection * coords).xyz; v_logPositionEC = logPositionEC; #endif
coords.z = clamp(coords.z / coords.w, -1.0, 1.0) * coords.w;
#endif
return coords;
}
void czm_vertexLogDepth() { #ifdef LOG_DEPTH v_depthFromNearPlusOne = (gl_Position.w - czm_currentFrustum.x) + 1.0; gl_Position = czm_updatePositionDepth(gl_Position); #endif }
void czm_vertexLogDepth(vec4 clipCoords) { #ifdef LOG_DEPTH v_depthFromNearPlusOne = (clipCoords.w - czm_currentFrustum.x) + 1.0; czm_updatePositionDepth(clipCoords); #endif }
uniform mat3 czm_normal; uniform mat4 czm_modelView; uniform mat3 czm_normal3D; uniform mat4 czm_modelView3D;
struct czm_modelVertexOutput { vec3 positionMC; float pointSize; };
const float czm_passTranslucent = 8.0;
uniform float czm_pass; uniform mat4 czm_model; uniform mat4 czm_projection;
void czm_computeGroundAtmosphereScattering(vec3 positionWC, vec3 lightDirection, out vec3 rayleighColor, out vec3 mieColor, out float opacity) { vec3 cameraToPositionWC = positionWC - czm_viewerPositionWC; vec3 cameraToPositionWCDirection = normalize(cameraToPositionWC); czm_ray primaryRay = czm_ray(czm_viewerPositionWC, cameraToPositionWCDirection);
float atmosphereInnerRadius = length(positionWC);
czm_computeScattering(
primaryRay,
length(cameraToPositionWC),
lightDirection,
atmosphereInnerRadius,
rayleighColor,
mieColor,
opacity
);
}
uniform float czm_atmosphereDynamicLighting;
vec3 czm_getDynamicAtmosphereLightDirection(vec3 positionWC, float lightEnum) { const float NONE = 0.0; const float SCENE_LIGHT = 1.0; const float SUNLIGHT = 2.0;
vec3 lightDirection =
positionWC * float(lightEnum == NONE) +
czm_lightDirectionWC * float(lightEnum == SCENE_LIGHT) +
czm_sunDirectionWC * float(lightEnum == SUNLIGHT);
return normalize(lightDirection);
}
float czm_round(float value) { return floor(value + 0.5); }
vec2 czm_round(vec2 value) { return floor(value + 0.5); }
vec3 czm_round(vec3 value) { return floor(value + 0.5); }
vec4 czm_round(vec4 value) { return floor(value + 0.5); }
#line 0 in vec3 a_positionMC; in vec3 a_normalMC; in vec2 a_texCoord_0; in float a_featureId_0; uniform int model_featuresLength; uniform sampler2D model_batchTexture; uniform vec4 model_textureStep; uniform bool model_commandTranslucent; out vec3 v_atmosphereRayleighColor; out vec3 v_atmosphereMieColor; out float v_atmosphereOpacity; out vec3 v_positionWC; out vec3 v_positionEC; out vec3 v_positionMC; out vec3 v_normalEC; out vec2 v_texCoord_0; out float v_featureId_0; struct ProcessedAttributes { vec3 positionMC; vec3 normalMC; vec2 texCoord_0; float featureId_0; }; struct SelectedFeature { int id; vec2 st; vec4 color; }; struct FeatureIds { int featureId_0; }; struct Metadata { float _empty; }; struct MetadataClass { float _empty; }; struct MetadataStatistics { float _empty; }; void initializeAttributes(out ProcessedAttributes attributes) { attributes.positionMC = a_positionMC; attributes.normalMC = a_normalMC; attributes.texCoord_0 = a_texCoord_0; attributes.featureId_0 = a_featureId_0; } void setDynamicVaryings(inout ProcessedAttributes attributes) { v_texCoord_0 = attributes.texCoord_0; v_featureId_0 = attributes.featureId_0; } void initializeFeatureIds(out FeatureIds featureIds, ProcessedAttributes attributes) { featureIds.featureId_0 = int(czm_round(attributes.featureId_0)); } void initializeFeatureIdAliases(inout FeatureIds featureIds) { } void setFeatureIdVaryings() { } void initializeMetadata(out Metadata metadata, out MetadataClass metadataClass, out MetadataStatistics metadataStatistics, ProcessedAttributes attributes) { } void setMetadataVaryings() { } void atmosphereStage(ProcessedAttributes attributes) { vec3 lightDirection = czm_getDynamicAtmosphereLightDirection(v_positionWC, czm_atmosphereDynamicLighting);
czm_computeGroundAtmosphereScattering(
v_positionWC,
lightDirection,
v_atmosphereRayleighColor,
v_atmosphereMieColor,
v_atmosphereOpacity
);
}
vec4 geometryStage(inout ProcessedAttributes attributes, mat4 modelView, mat3 normal) { vec4 computedPosition;
vec3 positionMC = attributes.positionMC;
v_positionMC = positionMC;
v_positionEC = (modelView * vec4(positionMC, 1.0)).xyz;
#if defined(USE_2D_POSITIONS) || defined(USE_2D_INSTANCING)
vec3 position2D = attributes.position2D;
vec3 positionEC = (u_modelView2D * vec4(position2D, 1.0)).xyz;
computedPosition = czm_projection * vec4(positionEC, 1.0);
#else
computedPosition = czm_projection * vec4(v_positionEC, 1.0);
#endif
#if defined(COMPUTE_POSITION_WC_CUSTOM_SHADER) || defined(COMPUTE_POSITION_WC_STYLE) || defined(COMPUTE_POSITION_WC_ATMOSPHERE)
v_positionWC = (czm_model * vec4(positionMC, 1.0)).xyz;
#endif
#ifdef HAS_NORMALS
v_normalEC = normalize(normal * attributes.normalMC);
#endif
#ifdef HAS_TANGENTS
v_tangentEC = normalize(normal * attributes.tangentMC);
#endif
#ifdef HAS_BITANGENTS
v_bitangentEC = normalize(normal * attributes.bitangentMC);
#endif
setDynamicVaryings(attributes);
return computedPosition;
}
void featureIdStage(out FeatureIds featureIds, ProcessedAttributes attributes) { initializeFeatureIds(featureIds, attributes); initializeFeatureIdAliases(featureIds); setFeatureIdVaryings(); }
void metadataStage( out Metadata metadata, out MetadataClass metadataClass, out MetadataStatistics metadataStatistics, ProcessedAttributes attributes ) { initializeMetadata(metadata, metadataClass, metadataStatistics, attributes); setMetadataVaryings(); }
vec2 computeSt(float featureId) { float stepX = model_textureStep.x; float centerX = model_textureStep.y;
#ifdef MULTILINE_BATCH_TEXTURE
float stepY = model_textureStep.z;
float centerY = model_textureStep.w;
float xId = mod(featureId, model_textureDimensions.x);
float yId = floor(featureId / model_textureDimensions.x);
return vec2(centerX + (xId * stepX), centerY + (yId * stepY));
#else
return vec2(centerX + (featureId * stepX), 0.5);
#endif
}
void selectedFeatureIdStage(out SelectedFeature feature, FeatureIds featureIds)
{
int featureId = featureIds.SELECTED_FEATURE_ID;
if (featureId < model_featuresLength)
{
vec2 featureSt = computeSt(float(featureId));
feature.id = featureId;
feature.st = featureSt;
feature.color = texture(model_batchTexture, featureSt);
}
else
{
feature.id = model_featuresLength + 1;
feature.st = vec2(0.0);
feature.color = vec4(1.0);
}
#ifdef HAS_NULL_FEATURE_ID
if (featureId == model_nullFeatureId) {
feature.id = featureId;
feature.st = vec2(0.0);
feature.color = vec4(1.0);
}
#endif
}
void filterByPassType(inout vec3 positionMC, vec4 featureColor) { bool styleTranslucent = (featureColor.a != 1.0);
if (czm_pass == czm_passTranslucent && !styleTranslucent && !model_commandTranslucent)
{
#ifdef HAS_SILHOUETTE
positionMC *= float(model_silhouettePass);
#else
positionMC *= 0.0;
#endif
}
else if (czm_pass != czm_passTranslucent && styleTranslucent)
{
positionMC *= 0.0;
}
}
void cpuStylingStage(inout vec3 positionMC, inout SelectedFeature feature) { float show = ceil(feature.color.a); positionMC *= show;
#if defined(HAS_SELECTED_FEATURE_ID_ATTRIBUTE) && !defined(HAS_CLASSIFICATION)
filterByPassType(positionMC, feature.color);
#endif
}
czm_modelVertexOutput defaultVertexOutput(vec3 positionMC) { czm_modelVertexOutput vsOutput; vsOutput.positionMC = positionMC; vsOutput.pointSize = 1.0; return vsOutput; }
void czm_log_depth_main() {
ProcessedAttributes attributes;
initializeAttributes(attributes);
#ifdef USE_DEQUANTIZATION
dequantizationStage(attributes);
#endif
#ifdef HAS_MORPH_TARGETS
morphTargetsStage(attributes);
#endif
#ifdef HAS_SKINNING
skinningStage(attributes);
#endif
#ifdef HAS_PRIMITIVE_OUTLINE
primitiveOutlineStage();
#endif
#ifdef HAS_BITANGENTS
attributes.bitangentMC = normalize(cross(attributes.normalMC, attributes.tangentMC) * attributes.tangentSignMC);
#endif
FeatureIds featureIds;
featureIdStage(featureIds, attributes);
#ifdef HAS_SELECTED_FEATURE_ID
SelectedFeature feature;
selectedFeatureIdStage(feature, featureIds);
cpuStylingStage(attributes.positionMC, feature);
#endif
#if defined(USE_2D_POSITIONS) || defined(USE_2D_INSTANCING)
mat4 modelView = czm_modelView3D;
mat3 normal = czm_normal3D;
#else
mat4 modelView = czm_modelView;
mat3 normal = czm_normal;
#endif
#ifdef HAS_INSTANCING
#ifdef USE_LEGACY_INSTANCING
mat4 instanceModelView;
mat3 instanceModelViewInverseTranspose;
legacyInstancingStage(attributes, instanceModelView, instanceModelViewInverseTranspose);
modelView = instanceModelView;
normal = instanceModelViewInverseTranspose;
#else
instancingStage(attributes);
#endif
#ifdef USE_PICKING
v_pickColor = a_pickColor;
#endif
#endif
Metadata metadata;
MetadataClass metadataClass;
MetadataStatistics metadataStatistics;
metadataStage(metadata, metadataClass, metadataStatistics, attributes);
#ifdef HAS_VERTICAL_EXAGGERATION
verticalExaggerationStage(attributes);
#endif
#ifdef HAS_CUSTOM_VERTEX_SHADER
czm_modelVertexOutput vsOutput = defaultVertexOutput(attributes.positionMC);
customShaderStage(vsOutput, attributes, featureIds, metadata, metadataClass, metadataStatistics);
#endif
vec4 positionClip = geometryStage(attributes, modelView, normal);
#ifdef HAS_ATMOSPHERE
atmosphereStage(attributes);
#endif
#ifdef HAS_SILHOUETTE
silhouetteStage(attributes, positionClip);
#endif
#ifdef HAS_POINT_CLOUD_SHOW_STYLE
float show = pointCloudShowStylingStage(attributes, metadata);
#else
float show = 1.0;
#endif
#ifdef HAS_POINT_CLOUD_BACK_FACE_CULLING
show *= pointCloudBackFaceCullingStage();
#endif
#ifdef HAS_POINT_CLOUD_COLOR_STYLE
v_pointCloudColor = pointCloudColorStylingStage(attributes, metadata);
#endif
#ifdef PRIMITIVE_TYPE_POINTS
#ifdef HAS_CUSTOM_VERTEX_SHADER
gl_PointSize = vsOutput.pointSize;
#elif defined(HAS_POINT_CLOUD_POINT_SIZE_STYLE) || defined(HAS_POINT_CLOUD_ATTENUATION)
gl_PointSize = pointCloudPointSizeStylingStage(attributes, metadata);
#else
gl_PointSize = 1.0;
#endif
gl_PointSize *= show;
#endif
gl_Position = show * positionClip;
}
#line 0
void czm_non_renderPass_OutlineEffectPass_main() { czm_log_depth_main(); czm_vertexLogDepth(); }
#line 0
vec3 packNormalToRGB(const in vec3 normal) { return normalize(normal) * 0.5 + 0.5; }
vec3 unpackRGBToNormal(const in vec3 rgb) { return 2.0 * rgb.xyz - 1.0; }
const float PackUpscale = 256. / 255.; const float UnpackDownscale = 255. / 256.;
const vec3 PackFactors = vec3(256. * 256. * 256., 256. * 256., 256.); const vec4 UnpackFactors = UnpackDownscale / vec4(PackFactors, 1.);
const float ShiftRight8 = 1. / 256.;
vec4 packDepthToRGBA(const in float v) { vec4 r = vec4(fract(v * PackFactors), v); r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale; }
float unpackRGBAToDepth(const in vec4 v) { return dot(v, UnpackFactors); }
vec4 pack2HalfToRGBA(vec2 v) { vec4 r = vec4(v.x, fract(v.x * 255.0), v.y, fract(v.y * 255.0)); return vec4(r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w); } vec2 unpackRGBATo2Half(vec4 v) { return vec2(v.x + (v.y / 255.0), v.z + (v.w / 255.0)); }
float viewZToOrthographicDepth(const in float viewZ, const in float near, const in float far) { return (viewZ + near) / (near - far); } float orthographicDepthToViewZ(const in float linearClipZ, const in float near, const in float far) { return linearClipZ * (near - far) - near; }
float viewZToPerspectiveDepth(const in float viewZ, const in float near, const in float far) { return ((near + viewZ) * far) / ((far - near) * viewZ); } float perspectiveDepthToViewZ(const in float invClipZ, const in float near, const in float far) { return (near * far) / ((far - near) * invClipZ - far); }
uniform sampler2D czm_selectedIdTexture; uniform float czm_selectedIdTextureStep; uniform float czm_selectedIdTextureWidth;
bool czm_selected(vec4 id) { bool selected = false; for (int i = 0; i < 1024000; i++) { vec4 selectedId = texture(czm_selectedIdTexture, vec2((float(i) + 0.5) * czm_selectedIdTextureStep, 0.5)); if(all(equal(id, selectedId))) { return true; } if(float(i) > czm_selectedIdTextureWidth) break; } return false; } out float me_isSelected; bool czm_selected() { return czm_selected(((selectedFeature.id < int(model_featuresLength)) ? texture(model_pickTexture, selectedFeature.st) : vec4(0.0))); }
out vec3 vOutlineNormal;
void czm_renderPass_OutlineEffectPass_main() {
#ifdef HAS_NORMAL
vOutlineNormal = normal;
#else
#ifdef HAS_V_NORMAL
vOutlineNormal = v_normal;
#else
vOutlineNormal = vec3(0.);
#endif
#endif
}
void main()
{ czm_non_renderPass_OutlineEffectPass_main(); me_isSelected = czm_selected() ? 1. : 0.; czm_renderPass_OutlineEffectPass_main(); }
Hi @HKEFU , please supplement the version information, and then provide relevant sandcastle or tileset to help you better track the issue.
It seems that the issue lies in this piece of code: https://github.com/CesiumGS/cesium/blob/db62d077950f4fad4fc73ed50c08144ae724fa90/packages/engine/Source/Scene/Model/PickingPipelineStage.js#L158-L161
The cesium version is 1.116.0。 tileset.zip Please refer to this article。 https://zhuanlan.zhihu.com/p/407871786 @syzdev
Hi @HKEFU. As @syzdev suggested, would you be able to include a Sandcastle example that replicates the issue? That would help us give us more context to determine the issue. Thanks!
Hi @ggetz. This zip file is the sample code, and the video shows this error message.Thanks! example.zip
video url: https://github.com/CesiumGS/cesium/assets/169979994/e3f4f705-2d14-41ce-9865-a533a4fe191f
Hi @HKEFU, I identified a few errors with the linked tileset using the 3D Tiles Validator tool. I'd suggest running the tool and fixing any errors.