Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables WebGL 2 by default #10894

Merged
merged 42 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
b2229c9
Shader ugprade to GLSL 300
sanjeetsuhag Nov 8, 2022
d1f4570
JS Shader upgrade to GLSL 300
sanjeetsuhag Nov 8, 2022
48452e4
WIP ShaderSource mods
sanjeetsuhag Nov 8, 2022
a9e6aed
WIP demodernizeShader
sanjeetsuhag Nov 14, 2022
f052a02
Merge branch 'watched-files-fix' of https://github.com/CesiumGS/cesiu…
sanjeetsuhag Nov 14, 2022
4bb5854
Gets globe rendering with WebGL1 with demodernizeShader
sanjeetsuhag Nov 14, 2022
b2b5870
Fixes OIT.js shaders
sanjeetsuhag Nov 15, 2022
273b019
More JS fixes for OIT and MRT
sanjeetsuhag Nov 16, 2022
9cd404a
WebGL 1 spec fixes
Nov 16, 2022
e635196
More WebGL 2 shader migration
sanjeetsuhag Nov 16, 2022
1dd66d0
Gets WebGL 1 tests passing
sanjeetsuhag Nov 17, 2022
24ec5a5
WebGL2 Spec migration
sanjeetsuhag Nov 17, 2022
11c0970
Fixes CloudCollection shaders for WebGL2
sanjeetsuhag Nov 17, 2022
b38d3bd
More WebGL 2 spec fixes
sanjeetsuhag Nov 17, 2022
354ef3f
Shader spec compilation fixes
Nov 17, 2022
fd57848
More spec fixes
Nov 17, 2022
d474433
Spec cleanup
Nov 18, 2022
86ac727
Fix pickColorQualifier in ShadowVolumeAppearance.js
sanjeetsuhag Nov 18, 2022
51fcaa4
Fix accidental substitutions in I3SNodeSpec
sanjeetsuhag Nov 18, 2022
ce953c3
Merge branch 'main' of https://github.com/CesiumGS/cesium into webgl2…
sanjeetsuhag Dec 5, 2022
ee4fa0e
Removes WebGL 1 specs
sanjeetsuhag Dec 6, 2022
a5dc2ed
Merge branch 'main' of https://github.com/CesiumGS/cesium into webgl2…
sanjeetsuhag Dec 7, 2022
86bebe1
More Spec changes for WebGL2 specific specs
sanjeetsuhag Dec 7, 2022
566a0ee
More spec fixes
sanjeetsuhag Dec 8, 2022
6679cd7
Fixes ShaderSource functions
sanjeetsuhag Dec 8, 2022
33607ae
Fixes Sandcastles for WebGL2
sanjeetsuhag Dec 8, 2022
6e7cf1a
Fix spec failures for WebGL stub
sanjeetsuhag Dec 8, 2022
4a7a9b6
Feedback pass
sanjeetsuhag Dec 15, 2022
318283c
Merge branch 'main' of https://github.com/CesiumGS/cesium into webgl2…
sanjeetsuhag Jan 3, 2023
38de151
Upgrade voxel code to GLSL 300
sanjeetsuhag Jan 4, 2023
c5c4123
Merge branch 'main' of https://github.com/CesiumGS/cesium into webgl2…
sanjeetsuhag Jan 4, 2023
9001fdf
Removes modernizeShader
sanjeetsuhag Jan 5, 2023
1cec0d0
Spec fixes
sanjeetsuhag Jan 5, 2023
b8bddb3
Fix WebGL1 fallbacks for gl_FragDepth
Jan 10, 2023
ea0dda6
Add comments and clean up in OIT.js
Jan 11, 2023
48872d2
Fix out_FragData references in DebugInspector
Jan 12, 2023
04a6be0
Assume standard derivatives are supported
Jan 12, 2023
7a1b729
Restore fallbacks for no standard derivatives
Jan 13, 2023
ef1c287
Fix ElevationBandMaterial in WebGL2
Jan 13, 2023
350b017
Update error message in PostProcessStage
Jan 13, 2023
246631c
Fix pixelFormat in Megatexture.js
Jan 13, 2023
2302c48
Merge branch 'main' into webgl2-default
Jan 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Apps/Sandcastle/gallery/Custom Per-Feature Post Process.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@
// Shade selected model with highlight.
sanjeetsuhag marked this conversation as resolved.
Show resolved Hide resolved
sanjeetsuhag marked this conversation as resolved.
Show resolved Hide resolved
sanjeetsuhag marked this conversation as resolved.
Show resolved Hide resolved
sanjeetsuhag marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do both of these still work? I assume WebGL stub is fine b/c it's running in CI, but it's been a long time since I've tried WebGL validation.

image

sanjeetsuhag marked this conversation as resolved.
Show resolved Hide resolved
const fragmentShaderSource = `
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
in vec2 v_textureCoordinates;
uniform vec4 highlight;
void main() {
vec4 color = texture2D(colorTexture, v_textureCoordinates);
vec4 color = texture(colorTexture, v_textureCoordinates);
if (czm_selected()) {
vec3 highlighted = highlight.a * highlight.rgb + (1.0 - highlight.a) * color.rgb;
gl_FragColor = vec4(highlighted, 1.0);
out_FragColor = vec4(highlighted, 1.0);
} else {
gl_FragColor = color;
out_FragColor = color;
}
}
`;
Expand Down
6 changes: 3 additions & 3 deletions Apps/Sandcastle/gallery/Custom Post Process.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

const fragmentShaderSource = `
uniform sampler2D colorTexture;
varying vec2 v_textureCoordinates;
in vec2 v_textureCoordinates;
const int KERNEL_WIDTH = 16;
void main(void)
{
Expand All @@ -65,11 +65,11 @@
{
for (int j = 0; j < KERNEL_WIDTH; j++)
{
averageValue += texture2D(colorTexture, integralPos + step * vec2(i, j)).rgb;
averageValue += texture(colorTexture, integralPos + step * vec2(i, j)).rgb;
}
}
averageValue /= float(KERNEL_WIDTH * KERNEL_WIDTH);
gl_FragColor = vec4(averageValue, 1.0);
out_FragColor = vec4(averageValue, 1.0);
}
`;
viewer.scene.postProcessStages.add(
Expand Down
10 changes: 5 additions & 5 deletions Apps/Sandcastle/gallery/Custom Shaders Models.html
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
vec2 texCoord = fsInput.attributes.texCoord_0 + 0.1 * vec2(u_time, 0.0);
material.diffuse = texture2D(u_stripes, texCoord).rgb;
material.diffuse = texture(u_stripes, texCoord).rgb;
}
`,
});
Expand Down Expand Up @@ -156,7 +156,7 @@
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
vec2 texCoord = fsInput.attributes.texCoord_0;
vec4 checkerboard = texture2D(u_checkerboard, texCoord);
vec4 checkerboard = texture(u_checkerboard, texCoord);
material.diffuse = mix(material.diffuse, vec3(0.0), checkerboard.r);
}
`,
Expand All @@ -178,7 +178,7 @@
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
vec2 texCoord = fsInput.attributes.texCoord_0;
vec4 checkerboard = texture2D(u_checkerboard, texCoord);
vec4 checkerboard = texture(u_checkerboard, texCoord);
material.diffuse = checkerboard.rgb;
material.alpha = checkerboard.a;
}
Expand All @@ -197,7 +197,7 @@
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
vec2 texCoord = fsInput.attributes.texCoord_0;
vec4 checkerboard = texture2D(u_checkerboard, texCoord);
vec4 checkerboard = texture(u_checkerboard, texCoord);
if (checkerboard.r > 0.0) {
discard;
}
Expand Down Expand Up @@ -245,7 +245,7 @@
fragmentShaderText: `
void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material)
{
material.diffuse = texture2D(u_gradient, fsInput.attributes.texCoord_0).rgb;
material.diffuse = texture(u_gradient, fsInput.attributes.texCoord_0).rgb;
}
`,
});
Expand Down
8 changes: 4 additions & 4 deletions Apps/Sandcastle/gallery/Fog Post Process.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
const fragmentShaderSource = `
float getDistance(sampler2D depthTexture, vec2 texCoords)
{
float depth = czm_unpackDepth(texture2D(depthTexture, texCoords));
float depth = czm_unpackDepth(texture(depthTexture, texCoords));
if (depth == 0.0) {
return czm_infinity;
}
Expand All @@ -85,14 +85,14 @@
uniform sampler2D depthTexture;
uniform vec4 fogByDistance;
uniform vec4 fogColor;
varying vec2 v_textureCoordinates;
in vec2 v_textureCoordinates;
void main(void)
{
float distance = getDistance(depthTexture, v_textureCoordinates);
vec4 sceneColor = texture2D(colorTexture, v_textureCoordinates);
vec4 sceneColor = texture(colorTexture, v_textureCoordinates);
float blendAmount = interpolateByDistance(fogByDistance, distance);
vec4 finalFogColor = vec4(fogColor.rgb, fogColor.a * blendAmount);
gl_FragColor = alphaBlend(finalFogColor, sceneColor);
out_FragColor = alphaBlend(finalFogColor, sceneColor);
}
`;

Expand Down
3 changes: 0 additions & 3 deletions Apps/Sandcastle/gallery/MSAA.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
//Sandcastle_Begin
const viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain(),
contextOptions: {
requestWebgl1: false,
},
});

viewer.clock.currentTime = Cesium.JulianDate.fromIso8601(
Expand Down
4 changes: 2 additions & 2 deletions Apps/Sandcastle/gallery/Materials.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec4 color;
float heightValue = texture2D(heightField, materialInput.st).r;
float heightValue = texture(heightField, materialInput.st).r;
color.rgb = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);
color.a = (1.0 - texture2D(image, materialInput.st).r) * 0.7;
color.a = (1.0 - texture(image, materialInput.st).r) * 0.7;
color = czm_gammaCorrect(color);
material.diffuse = color.rgb;
material.alpha = color.a;
Expand Down
8 changes: 4 additions & 4 deletions Apps/Sandcastle/gallery/development/Custom Primitive.html
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@
// Inteference patterns made by two plane waves crossing each
// other at an angle. The color is based on the height.
const vertexShader = `
attribute vec3 a_position;
varying vec3 v_position;
in vec3 a_position;
out vec3 v_position;
uniform float u_time;
void main()
{
Expand All @@ -200,7 +200,7 @@
`;

const fragmentShader = `
varying vec3 v_position;
in vec3 v_position;
uniform float u_time;
uniform sampler2D u_texture;
void main()
Expand All @@ -214,7 +214,7 @@
z *= 0.5;
// signed -> unsigned
z = 0.5 + 0.5 * z;
gl_FragColor = texture2D(u_texture, vec2(z, 0.5));
out_FragColor = texture(u_texture, vec2(z, 0.5));
}
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@
source:
"czm_material czm_getMaterial(czm_materialInput materialInput) {" +
"czm_material material = czm_getDefaultMaterial(materialInput);" +
"float heightValue = texture2D(heightField, materialInput.st).r;" +
"float heightValue = texture(heightField, materialInput.st).r;" +
"material.diffuse = mix(vec3(0.2, 0.6, 0.2), vec3(1.0, 0.5, 0.2), heightValue);" +
"material.alpha = (1.0 - texture2D(image, materialInput.st).r) * 0.7;" +
"material.alpha = (1.0 - texture(image, materialInput.st).r) * 0.7;" +
"material.normal = bumpMap.normal;" +
"material.specular = step(0.1, heightValue);" + // Specular mountain tops
"material.shininess = 8.0;" + // Sharpen highlight
Expand Down
3 changes: 2 additions & 1 deletion Documentation/Contributors/CodingGuide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -994,10 +994,11 @@ fullscreenSubscription.dispose();
- Files for vertex shaders have a `VS` suffix; fragment shaders have an `FS` suffix. For example: `BillboardCollectionVS.glsl` and `BillboardCollectionFS.glsl`.
- Generally, identifiers, such as functions and variables, use `camelCase`.
- Cesium built-in identifiers start with `czm_`, for example, [`czm_material`](https://github.com/CesiumGS/cesium/blob/main/Source/Shaders/Builtin/Structs/material.glsl). Files have the same name without the `czm_` prefix, e.g., `material.glsl`.
- Use `czm_textureCube` when sampling a cube map instead of `texture`. This is to preserve backwards compatibility with WebGL 1.
- Varyings start with `v_`, e.g.,

```javascript
varying vec2 v_textureCoordinates;
in vec2 v_textureCoordinates;
```

- Uniforms start with `u_`, e.g.,
Expand Down
6 changes: 3 additions & 3 deletions Documentation/Contributors/TestingGuide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ Uniforms, the model matrix, and various depth options can be provided. In additi
it("can declare automatic uniforms", function () {
const fs =
"void main() { " +
" gl_FragColor = vec4((czm_viewport.x == 0.0) && (czm_viewport.y == 0.0) && (czm_viewport.z == 1.0) && (czm_viewport.w == 1.0)); " +
" out_FragColor = vec4((czm_viewport.x == 0.0) && (czm_viewport.y == 0.0) && (czm_viewport.z == 1.0) && (czm_viewport.w == 1.0)); " +
"}";
expect({
context: context,
Expand Down Expand Up @@ -573,7 +573,7 @@ it("has czm_transpose (2x2)", function () {
"void main() { " +
" mat2 m = mat2(1.0, 2.0, 3.0, 4.0); " +
" mat2 mt = mat2(1.0, 3.0, 2.0, 4.0); " +
" gl_FragColor = vec4(czm_transpose(m) == mt); " +
" out_FragColor = vec4(czm_transpose(m) == mt); " +
"}";

context.verifyDrawForSpecs(fs);
Expand All @@ -586,7 +586,7 @@ it("has czm_transpose (2x2)", function () {
expect(context.readPixels()).toEqual([255, 255, 255, 255]);
```

In the test above, the expectation is implicit in the GLSL string for the fragment shader, `fs`, which assigns white to `gl_FragColor` if `czm_transpose` correctly transposes the matrix.
In the test above, the expectation is implicit in the GLSL string for the fragment shader, `fs`, which assigns white to `out_FragColor` if `czm_transpose` correctly transposes the matrix.

### Spies

Expand Down
4 changes: 2 additions & 2 deletions Documentation/CustomShaderGuide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ const textureWithSampler = new Cesium.TextureUniform({
## Varyings

Varyings are declared in the `CustomShader` constructor. This automatically
adds a line such as `varying float v_userDefinedVarying;` to the top of the
GLSL shader.
adds lines such as `out float v_userDefinedVarying;` and `in float v_userDefinedVarying;` to the top of the
GLSL vertex and fragment shaders respectively.

The user is responsible for assigning a value to this varying in
`vertexShaderText` and using it in `fragmentShaderText`. For example:
Expand Down
4 changes: 2 additions & 2 deletions Documentation/FabricGuide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ A slightly more complicated example adds a specular component so that the materi
}
```

The `components` property contains sub-properties that define the appearance of the material. The value of each sub-property is a GLSL code snippet, hence the `vec3(0.5)` above, which creates a 3D vector with each component set to `0.5`. These have access to all GLSL functions like `mix`, `cos`, `texture2D`, etc. There are five sub-properties.
The `components` property contains sub-properties that define the appearance of the material. The value of each sub-property is a GLSL code snippet, hence the `vec3(0.5)` above, which creates a 3D vector with each component set to `0.5`. These have access to all GLSL functions like `mix`, `cos`, `texture`, etc. There are five sub-properties.

| Name | Default | Description |
| :---------- | :------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
Expand Down Expand Up @@ -358,7 +358,7 @@ We can implement our own `DiffuseMap` material by using an image uniform:
image : 'czm_defaultImage'
},
components : {
diffuse : 'texture2D(image, materialInput.st).rgb'
diffuse : 'texture(image, materialInput.st).rgb'
}
}
```
Expand Down
4 changes: 2 additions & 2 deletions Documentation/Schemas/Fabric/Examples/MaterialHierarchy2.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
"hot": "hot.jpg"
},
"components" : {
"diffuse" : "texture2D(hot, materialInput.st).rgb"
"diffuse" : "texture(hot, materialInput.st).rgb"
}
},
"cold" : {
"uniforms" : {
"cold": "cold.jpg"
},
"components" : {
"diffuse" : "texture2D(cold, materialInput.st).rgb"
"diffuse" : "texture(cold, materialInput.st).rgb"
}
}
},
Expand Down
6 changes: 3 additions & 3 deletions Documentation/Schemas/Fabric/Examples/TextureUniforms.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
}
},
"components": {
"diffuse" : "textureCube(mycubemap, normalize(vec3(1.0))).rgb /* not an interesting reflection */",
"specular" : "texture2D(myothertexture2D, materialInput.st).r",
"emission" : "texture2D(mytexture2D, materialInput.st).rgb"
"diffuse" : "czm_textureCube(mycubemap, normalize(vec3(1.0))).rgb /* not an interesting reflection */",
"specular" : "texture(myothertexture2D, materialInput.st).r",
"emission" : "texture(mytexture2D, materialInput.st).rgb"
}
}
4 changes: 2 additions & 2 deletions Specs/ShaderBuilderTester.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ ShaderBuilderTester.expectHasVaryings = function (
) {
expectEqualUnordered(
shaderBuilder._vertexShaderParts.varyingLines,
expectedVaryings
expectedVaryings.map((varying) => `out ${varying}`)
);
expectEqualUnordered(
shaderBuilder._fragmentShaderParts.varyingLines,
expectedVaryings
expectedVaryings.map((varying) => `in ${varying}`)
);
};

Expand Down
2 changes: 1 addition & 1 deletion Specs/addDefaultMatchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@ function contextRenderAndReadPixels(options) {
if (!defined(sp)) {
if (!defined(vs)) {
vs =
"attribute vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
"in vec4 position; void main() { gl_PointSize = 1.0; gl_Position = position; }";
}
sp = ShaderProgram.fromCache({
context: context,
Expand Down
24 changes: 22 additions & 2 deletions packages/engine/Source/Core/PixelFormat.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ const PixelFormat = {
*/
ALPHA: WebGLConstants.ALPHA,

/**
* A pixel format containing a red channel
*
* @type {Number}
* @constant
*/
RED: WebGLConstants.RED,

/**
* A pixel format containing red and green channels.
*
* @type {Number}
* @constant
*/
RG: WebGLConstants.RG,

/**
* A pixel format containing red, green, and blue channels.
*
Expand Down Expand Up @@ -178,8 +194,10 @@ PixelFormat.componentsLength = function (pixelFormat) {
case PixelFormat.RGBA:
return 4;
case PixelFormat.LUMINANCE_ALPHA:
case PixelFormat.RG:
return 2;
case PixelFormat.ALPHA:
case PixelFormat.RED:
case PixelFormat.LUMINANCE:
return 1;
default:
Expand All @@ -195,6 +213,8 @@ PixelFormat.validate = function (pixelFormat) {
pixelFormat === PixelFormat.DEPTH_COMPONENT ||
pixelFormat === PixelFormat.DEPTH_STENCIL ||
pixelFormat === PixelFormat.ALPHA ||
pixelFormat === PixelFormat.RED ||
pixelFormat === PixelFormat.RG ||
pixelFormat === PixelFormat.RGB ||
pixelFormat === PixelFormat.RGBA ||
pixelFormat === PixelFormat.LUMINANCE ||
Expand Down Expand Up @@ -469,7 +489,7 @@ PixelFormat.toInternalFormat = function (pixelFormat, pixelDatatype, context) {
return WebGLConstants.RGB32F;
case PixelFormat.RG:
return WebGLConstants.RG32F;
case PixelFormat.R:
case PixelFormat.RED:
return WebGLConstants.R32F;
}
}
Expand All @@ -482,7 +502,7 @@ PixelFormat.toInternalFormat = function (pixelFormat, pixelDatatype, context) {
return WebGLConstants.RGB16F;
case PixelFormat.RG:
return WebGLConstants.RG16F;
case PixelFormat.R:
case PixelFormat.RED:
return WebGLConstants.R16F;
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/engine/Source/Renderer/AutomaticUniforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ const AutomaticUniforms = {
*
* // Get the depth at the current fragment
* vec2 coords = gl_FragCoord.xy / czm_viewport.zw;
* float depth = czm_unpackDepth(texture2D(czm_globeDepthTexture, coords));
* float depth = czm_unpackDepth(texture(czm_globeDepthTexture, coords));
*/
czm_globeDepthTexture: new AutomaticUniform({
size: 1,
Expand Down Expand Up @@ -1400,7 +1400,7 @@ const AutomaticUniforms = {
* // Example: For a given roughness and NdotV value, find the material's BRDF information in the red and green channels
* float roughness = 0.5;
* float NdotV = dot(normal, view);
* vec2 brdfLut = texture2D(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;
* vec2 brdfLut = texture(czm_brdfLut, vec2(NdotV, 1.0 - roughness)).rg;
*/
czm_brdfLut: new AutomaticUniform({
size: 1,
Expand All @@ -1419,7 +1419,7 @@ const AutomaticUniforms = {
*
* // Example: Create a perfect reflection of the environment map on a model
* float reflected = reflect(view, normal);
* vec4 reflectedColor = textureCube(czm_environmentMap, reflected);
* vec4 reflectedColor = texture(czm_environmentMap, reflected);
*/
czm_environmentMap: new AutomaticUniform({
size: 1,
Expand Down
Loading