Skip to content

Commit

Permalink
Merge c6e76ba into 745df52
Browse files Browse the repository at this point in the history
  • Loading branch information
tsherif committed Feb 20, 2020
2 parents 745df52 + c6e76ba commit de77f14
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 6 deletions.
22 changes: 17 additions & 5 deletions modules/shadertools/src/lib/assemble-shaders.js
Expand Up @@ -5,6 +5,7 @@ import injectShader, {DECLARATION_INJECT_MARKER} from './inject-shader';
import transpileShader from './transpile-shader';
import {assert} from '../utils';

const REGEX_FIRST_FUNCTION = /^[ \t]*\w+[ \t]+\w+\s*\(/;
const INJECT_SHADER_DECLARATIONS = `\n\n${DECLARATION_INJECT_MARKER}\n\n`;

const SHADER_TYPE = {
Expand Down Expand Up @@ -52,20 +53,29 @@ function assembleShader(

const isVertex = type === VERTEX_SHADER;

const sourceLines = source.split('\n');
let sourceLines = source.split('\n');
let glslVersion = 100;
let versionLine = '';
let coreSource = source;

// Extract any version directive string from source.
// TODO : keep all pre-processor statements at the begining of the shader.
if (sourceLines[0].indexOf('#version ') === 0) {
glslVersion = 300; // TODO - regexp that matches atual version number
versionLine = sourceLines[0];
coreSource = sourceLines.slice(1).join('\n');
sourceLines = sourceLines.slice(1);
} else {
versionLine = `#version ${glslVersion}`;
}

let functionIndex = sourceLines.findIndex(l => l.match(REGEX_FIRST_FUNCTION));

if (functionIndex === -1) {
functionIndex = 0;
}

const corePreamble = sourceLines.slice(0, functionIndex).join('\n');
const coreMain = sourceLines.slice(functionIndex).join('\n');

// Combine Module and Application Defines
const allDefines = {};
modules.forEach(module => {
Expand All @@ -85,8 +95,10 @@ ${getPlatformShaderDefines(gl)}
${getVersionDefines(gl, glslVersion, !isVertex)}
${getApplicationDefines(allDefines)}
${isVertex ? '' : FRAGMENT_SHADER_PROLOGUE}
${corePreamble}
`
: `${versionLine}
${corePreamble}
`;

hookFunctions = normalizeHookFunctions(hookFunctions);
Expand All @@ -112,7 +124,7 @@ ${isVertex ? '' : FRAGMENT_SHADER_PROLOGUE}

for (const module of modules) {
if (log) {
module.checkDeprecations(coreSource, log);
module.checkDeprecations(source, log);
}
const moduleSource = module.getModuleSource(type, glslVersion);
// Add the module source, and a #define that declares it presence
Expand All @@ -136,7 +148,7 @@ ${isVertex ? '' : FRAGMENT_SHADER_PROLOGUE}
assembledSource += getHookFunctions(hookFunctions[type], hookInjections);

// Add the version directive and actual source of this shader
assembledSource += coreSource;
assembledSource += coreMain;

// Apply any requested shader injections
assembledSource = injectShader(assembledSource, type, mainInjections);
Expand Down
2 changes: 1 addition & 1 deletion modules/shadertools/src/lib/inject-shader.js
Expand Up @@ -10,7 +10,7 @@ const MODULE_INJECTORS = {

export const DECLARATION_INJECT_MARKER = '__LUMA_INJECT_DECLARATIONS__'; // Uniform/attribute declarations

const REGEX_START_OF_MAIN = /void main\s*\([^)]*\)\s*\{\n?/; // Beginning of main
const REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/; // Beginning of main
const REGEX_END_OF_MAIN = /}\n?[^{}]*$/; // End of main, assumes main is last function
const fragments = [];

Expand Down
80 changes: 80 additions & 0 deletions modules/shadertools/test/lib/assemble-shaders.spec.js
Expand Up @@ -211,6 +211,54 @@ const FS_GLSL_300_GLTF = `#version 300 es
}
`;

const TEST_MODULE = {
name: 'TEST_MODULE',
// Module function has access to shader attributes
vs: `
float getFloat() {
return 1.0 + floatAttribute;
}
`,
// Module function has access to shader varyings
fs: `
vec4 getVec4() {
return vec4(floatVarying);
}
`,
inject: {
// Hook function has access to shader attributes and module functions
'vs:HOOK_FUNCTION': 'value = getFloat() + floatAttribute;',

// Hook function has access to shader varyings and module functions
'fs:HOOK_FUNCTION': 'value = getVec4() + floatVarying;'
}
};

const VS_GLSL_300_MODULES = `\
#version 300 es
in float floatAttribute;
out float floatVarying;
void main(void) {
HOOK_FUNCTION(floatVarying);
}
`;

const FS_GLSL_300_MODULES = `\
#version 300 es
precision highp float;
in float floatVarying;
out vec4 fragmentColor;
void main(void) {
HOOK_FUNCTION(fragmentColor);
}
`;

test('assembleShaders#import', t => {
t.ok(assembleShaders !== undefined, 'assembleShaders import successful');
t.end();
Expand Down Expand Up @@ -414,6 +462,38 @@ test('assembleShaders#shaderhooks', t => {
t.end();
});

test('assembleShaders#injection order', t => {
const gl = fixture.gl1;

const assembleResult = assembleShaders(gl, {
vs: VS_GLSL_300_MODULES,
fs: FS_GLSL_300_MODULES,
modules: [TEST_MODULE],
transpileToGLSL100: true,
hookFunctions: ['vs:HOOK_FUNCTION(inout float value)', 'fs:HOOK_FUNCTION(inout vec4 value)']
});

const vShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vShader, assembleResult.vs);
gl.compileShader(vShader);

const fShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fShader, assembleResult.fs);
gl.compileShader(fShader);

const program = gl.createProgram();
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
gl.linkProgram(program);

t.ok(
gl.getProgramParameter(program, gl.LINK_STATUS),
'Modules and injections have access to variables and functions'
);

t.end();
});

test('assembleShaders#transpilation', t => {
const gl = fixture.gl1;
let assembleResult = assembleShaders(gl, {
Expand Down

0 comments on commit de77f14

Please sign in to comment.