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

Remove extensions in shaders when upgrading to WebGL 2.0 #8969

Merged
merged 11 commits into from
Jun 19, 2020
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
- Fixed artifact for skinned model when log depth is enabled. [#6447](https://github.com/CesiumGS/cesium/issues/6447)
- Fixed a bug where certain rhumb arc polylines would lead to a crash. [#8787](https://github.com/CesiumGS/cesium/pull/8787)
- Fixed handling of Label's backgroundColor and backgroundPadding option [#8949](https://github.com/CesiumGS/cesium/8949)
- Fixed log depth artifacts when running CesiumJS in a WebGL2 context. [#8969](https://github.com/CesiumGS/cesium/pull/8969)
- Fixed a bug where the camera goes through the geometry instead of stopping in front of it in WebGL 2. [#747](https://github.com/CesiumGS/cesium/issues/797#issuecomment-645660881)
- Fixed a bug where silhouette postprocess doesn't work in WebGL 2. [#7952](https://github.com/CesiumGS/cesium/issues/7952)
- Fixed an error of applying clip planes to globe when enabling WebGL 2.0 [#7712](https://github.com/CesiumGS/cesium/issues/7712)
- Fixed a bug where half-float texture doesn't have correct WebGL 2.0 parameter [#8975](https://github.com/CesiumGS/cesium/pull/8975)

Expand Down
14 changes: 11 additions & 3 deletions Source/Renderer/Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ Object.defineProperties(Texture.prototype, {
set: function (sampler) {
var minificationFilter = sampler.minificationFilter;
var magnificationFilter = sampler.magnificationFilter;
var context = this._context;
var pixelFormat = this._pixelFormat;
var pixelDatatype = this._pixelDatatype;

var mipmap =
minificationFilter ===
Expand All @@ -505,9 +508,6 @@ Object.defineProperties(Texture.prototype, {
TextureMinificationFilter.LINEAR_MIPMAP_NEAREST ||
minificationFilter === TextureMinificationFilter.LINEAR_MIPMAP_LINEAR;

var context = this._context;
var pixelDatatype = this._pixelDatatype;

// float textures only support nearest filtering unless the linear extensions are supported, so override the sampler's settings
if (
(pixelDatatype === PixelDatatype.FLOAT &&
Expand All @@ -521,6 +521,14 @@ Object.defineProperties(Texture.prototype, {
magnificationFilter = TextureMagnificationFilter.NEAREST;
}

// WebGL 2 depth texture only support nearest filtering. See section 3.8.13 OpenGL ES 3 spec
if (context.webgl2) {
if (PixelFormat.isDepthFormat(pixelFormat)) {
minificationFilter = TextureMinificationFilter.NEAREST;
magnificationFilter = TextureMagnificationFilter.NEAREST;
}
}

var gl = context._gl;
var target = this._textureTarget;

Expand Down
14 changes: 11 additions & 3 deletions Source/Renderer/modernizeShader.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,21 +99,26 @@ function modernizeShader(source, isFragmentShader) {
}
}

var webgl2UniqueID = "WEBGL_2";
var webgl2DefineMacro = "#define " + webgl2UniqueID;
var versionThree = "#version 300 es";
var foundVersion = false;
for (i = 0; i < splitSource.length; i++) {
if (/#version/.test(splitSource[i])) {
splitSource[i] = versionThree;
foundVersion = true;
break;
}
}

if (!foundVersion) {
splitSource.splice(0, 0, versionThree);
}

removeExtension("EXT_draw_buffers", splitSource);
removeExtension("EXT_frag_depth", splitSource);
splitSource.splice(1, 0, webgl2DefineMacro);

removeExtension("EXT_draw_buffers", webgl2UniqueID, splitSource);
removeExtension("EXT_frag_depth", webgl2UniqueID, splitSource);

replaceInSourceString("texture2D", "texture", splitSource);
replaceInSourceString("texture3D", "texture", splitSource);
Expand Down Expand Up @@ -224,8 +229,11 @@ function getVariablePreprocessorBranch(layoutVariables, splitSource) {
return variableMap;
}

function removeExtension(name, splitSource) {
function removeExtension(name, webgl2UniqueID, splitSource) {
var regex = "#extension\\s+GL_" + name + "\\s+:\\s+[a-zA-Z0-9]+\\s*$";
replaceInSourceRegex(new RegExp(regex, "g"), "", splitSource);

// replace any possible directive #ifdef (GL_EXT_extension) with WEBGL_2 unique directive
replaceInSourceString("GL_" + name, webgl2UniqueID, splitSource);
}
export default modernizeShader;
38 changes: 36 additions & 2 deletions Specs/Renderer/modernizeShaderSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,20 @@ describe("Renderer/modernizeShader", function () {
var simple =
"#define OUTPUT_DECLARATION \n" + "void main() \n" + "{ \n" + "} \n";
var output = modernizeShader(simple, true);
var expected = "#version 300 es";
expect(output.split("\n")[0]).toEqual(expected);
var expected = "#version 300 es\n#define WEBGL_2";
expect(output.startsWith(expected)).toBe(true);
});

it("replace existing version string", function () {
var simple =
"#version 200 es" +
"#define OUTPUT_DECLARATION \n" +
"void main() \n" +
"{ \n" +
"} \n";
var output = modernizeShader(simple, true);
var expected = "#version 300 es\n#define WEBGL_2";
expect(output.startsWith(expected)).toBe(true);
});

it("removes extensions", function () {
Expand All @@ -21,6 +33,28 @@ describe("Renderer/modernizeShader", function () {
expect(output).not.toContain(notExpected);
});

it("replace extension macro check with WEBGL_2", function () {
var extensions =
"#define OUTPUT_DECLARATION \n" +
"#extension GL_EXT_draw_buffers : enable \n" +
"void main() \n" +
"{ \n" +
" #ifdef GL_EXT_draw_buffers\n" +
" #endif //GL_EXT_draw_buffers\n" +
" #if defined(GL_EXT_draw_buffers)\n" +
" #endif //GL_EXT_draw_buffers\n" +
"} \n";
var output = modernizeShader(extensions, true);
var notExpected = "#extension GL_EXT_draw_buffers : enable \n";
var expected =
" #ifdef WEBGL_2\n" +
" #endif //WEBGL_2\n" +
" #if defined(WEBGL_2)\n" +
" #endif //WEBGL_2\n";
expect(output).not.toContain(notExpected);
expect(output).toContain(expected);
});

it("throws exception if no output declaration", function () {
var noOutputDeclaration = "void main() \n" + "{ \n" + "} \n";
var runFunc = function () {
Expand Down