Skip to content

Commit

Permalink
Merge pull request #8608 from CesiumGS/spector-editor
Browse files Browse the repository at this point in the history
Make Cesium's shaders editable with the SpectorJS shader editor
  • Loading branch information
lilleyse authored Mar 27, 2020
2 parents bf91215 + 58ceea3 commit 51485d2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Change Log

* Added basic underground rendering support. When the camera is underground the globe will be rendered as a solid surface and underground entities will not be culled. [#8572](https://github.com/AnalyticalGraphicsInc/cesium/pull/8572)
* The `CesiumUnminified` build now includes sourcemaps.
* Added the ability to edit CesiumJS shaders on-the-fly using the [SpectorJS](https://spector.babylonjs.com/) Shader Editor.

##### Fixes :wrench:

Expand Down
60 changes: 59 additions & 1 deletion Source/Renderer/ShaderProgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ import createUniformArray from './createUniformArray.js';
* @private
*/
function ShaderProgram(options) {
var modifiedFS = handleUniformPrecisionMismatches(options.vertexShaderText, options.fragmentShaderText);
var vertexShaderText = options.vertexShaderText;
var fragmentShaderText = options.fragmentShaderText;

if (typeof spector !== 'undefined') {
// The #line statements common in Cesium shaders interfere with the ability of the
// SpectorJS to show errors on the correct line. So remove them when SpectorJS
// is active.
vertexShaderText = vertexShaderText.replace(/^#line/mg, '//#line');
fragmentShaderText = fragmentShaderText.replace(/^#line/mg, '//#line');
}

var modifiedFS = handleUniformPrecisionMismatches(vertexShaderText, fragmentShaderText);

this._gl = options.gl;
this._logShaderCompilation = options.logShaderCompilation;
Expand Down Expand Up @@ -432,6 +443,12 @@ import createUniformArray from './createUniformArray.js';
return;
}

reinitialize(shader);
}

function reinitialize(shader) {
var oldProgram = shader._program;

var gl = shader._gl;
var program = createAndLinkProgram(gl, shader, shader._debugShaders);
var numberOfVertexAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
Expand All @@ -447,6 +464,47 @@ import createUniformArray from './createUniformArray.js';
shader._manualUniforms = partitionedUniforms.manualUniforms;

shader.maximumTextureUnitIndex = setSamplerUniforms(gl, program, uniforms.samplerUniforms);

if (oldProgram) {
shader._gl.deleteProgram(oldProgram);
}

// If SpectorJS is active, add the hook to make the shader editor work.
// https://github.com/BabylonJS/Spector.js/blob/master/documentation/extension.md#shader-editor
if (typeof spector !== 'undefined') {
shader._program.__SPECTOR_rebuildProgram = function(
vertexSourceCode, // The new vertex shader source
fragmentSourceCode, // The new fragment shader source
onCompiled, // Callback triggered by your engine when the compilation is successful. It needs to send back the new linked program.
onError // Callback triggered by your engine in case of error. It needs to send the WebGL error to allow the editor to display the error in the gutter.
) {
var originalVS = shader._vertexShaderText;
var originalFS = shader._fragmentShaderText;

// SpectorJS likes to replace `!=` with `! =` for unknown reasons,
// and that causes glsl compile failures. So fix that up.
var regex = / ! = /g;
shader._vertexShaderText = vertexSourceCode.replace(regex, ' != ');
shader._fragmentShaderText = fragmentSourceCode.replace(regex, ' != ');

try {
reinitialize(shader);
onCompiled(shader._program);
} catch (e) {
shader._vertexShaderText = originalVS;
shader._fragmentShaderText = originalFS;

// Only pass on the WebGL error:
var errorMatcher = /(?:Compile|Link) error: ([^]*)/;
var match = errorMatcher.exec(e.message);
if (match) {
onError(match[1]);
} else {
onError(e.message);
}
}
};
}
}

ShaderProgram.prototype._bind = function() {
Expand Down

0 comments on commit 51485d2

Please sign in to comment.