CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.73k stars 3.45k forks source link

Point Cloud attenuation/EDL + custom post processing stage : WEBGL error :cannot use both gl_FragData and gl_FragColor #7429

Open ppoulainpro opened 5 years ago

ppoulainpro commented 5 years ago

When a custom post processing stage based on "highlight" sandcastle example is applied, if a point cloud 3D tile with an active pointcloudshading attenuation is loaded, a WEBGL issue is raised :

_[Cesium WebGL] Fragment shader compile log: ERROR: cannot use both gl_FragData and glFragColor

Release: 1.52 OS : Windows8.1 / Chrome 71

The sandcastle example to reproduce it. https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/#c=jVTbbhoxEP2VES8sDfXmqkoBokZElSKlKgq0L90qMt4B3HptZHtJCOLfO14vZEl5qKW92D5z5sx4xmk6MlJ7GCpT5jBdw8iaGYMRerRwqxTqLgyNKoup5PBdyxVaJ/0aHs3UeCkcPPApg7HgWks9DwS3Cn9znVsDE2uEMEoCTeEr9yhhKI3gVklkmV5xCyuJz+RoABqfYYhOlgX7Ua0lbVFNh0Z7LjXadqeX6WjlpUKH/tAsfi7uJnEz2UBp1fVu997oR3SmtALZzJri1hHmPk+uPp1ddmAbuWtetgwpqTIyXvCc4mLce9Ql99Jo8uptiVFMJZU5gRrZ0spCesqQYzzPk5osMmc6TSGQIThUKDzmUJgcFTxLv4CFnC8UPb5Oy8zyeYHaVxZ2XMmGQaaBRrvUcmZsAY4XS4X2/A4oycZO8MWXlnRlug0nNZbI1uFcVijOYfXkI2ZojKWw6ETcIXxHTfDLN1HvKI0k7XQkSQc2BzvhVVlWekKeorvzu6SpsHtUSKf3D5ecQSJei6ddxpLOMY+114s3vZTbQSOlHD40ZnY+hRNIztgpfGyCOoSqVAZE76iXuXr6QgczrKMLoSYNp10g0iNhbAGVQ9jA/5BWEo5w7Ffa1W8v1onzfI5BykEdGuepi6l93Djsx3JsdMroHSDZRE+HVQfXR8uwG7F1pThC1dZh7LMRjEstQr9UZbJHhGGRzl4f9G6IOpxJF04br6vQPDurbfylz7YT1qvY2b6bBvDzV91q+758NaaYmGYntrqtvvNrhTeR7bMslsb6cFUkjKUeqaVCNabTUvyhm0C4UJi6n+6M+rlcgcwHWevd9ZS1QCjuHO3MSqXG8hWz1k0/JfyBmTLVjfKNLlLF1wGyOLt5iIuMsX5K053VXw

Quick analysis (To be confirmed by CESIUM Team) EDL is switching from gl_FragColor to gl_FragData[0] and updates shader source stack but when it is done, the pick shader is not in the list, it is added after.

void czm_log_depth_main() { czm_point_cloud_post_process_main(); gl_FragData[1] = czm_packDepth(gl_FragCoord.z); }

line 0

ifdef GL_EXT_frag_depth

endif

void czm_non_pick_main() { czm_log_depth_main(); czm_writeLogDepth(); }

line 0

void main() { czm_non_pick_main(); if (gl_FragColor.a == 0.0) { discard; } gl_FragColor = czm_pickColor; }

Attempt to quick fix it Setting a #define (see below) makes successful the compilation but it introduces a border effect: The point cloud with attenuation is flicking, only briefly visible at update or during view transition if :

So potentially not the best way to solve it.

define PointCloudEDL

void main() { czm_point_cloud_post_process_main(); gl_FragData[1] = czm_packDepth(gl_FragCoord.z); }

void main() { czm_non_pick_main();

ifdef PointCloudEDL

if (gl_FragData[0].a == 0.0) { discard; } gl_FragData[0] = ...

else

if (gl_FragColor.a == 0.0) { discard; } gl_FragColor = ....

endif

}

hpinkos commented 5 years ago

@lilleyse @likangning93

lilleyse commented 5 years ago

Ideally PointCloudEyeDomeLighting shouldn't be part of the post processing ID pass at all. It will be tough to fix due the current design where ID commands come from derived commands from the render pass.

So unless we can figure out a way around that, setting a #define seems like the way to go. Maybe getDepthOnlyShaderProgram should add a define like DEPTH_ONLY and PointCloudEyeDomeLighting can use that to cut out the gl_FragData calls, similar to what you have.