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

JavaScript support for additional shader generators #1771

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ if (MATERIALX_BUILD_IOS)
endif()

if (MATERIALX_BUILD_JS)
set(MATERIALX_BUILD_GEN_OSL OFF)
set(MATERIALX_BUILD_GEN_MSL OFF)
set(MATERIALX_BUILD_GEN_MDL OFF)
set(MATERIALX_BUILD_RENDER OFF)
set(MATERIALX_BUILD_TESTS OFF)
endif()
Expand Down
83 changes: 0 additions & 83 deletions javascript/MaterialXTest/browser/esslShaderGenerator.spec.js

This file was deleted.

104 changes: 104 additions & 0 deletions javascript/MaterialXTest/browser/shaderGenerator.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// MaterialX is served through a script tag in the test setup.

function createStandardSurfaceMaterial(mx)
{
const doc = mx.createDocument();
const ssName = 'SR_default';
const ssNode = doc.addChildOfCategory('standard_surface', ssName);
ssNode.setType('surfaceshader');
const smNode = doc.addChildOfCategory('surfacematerial', 'Default');
smNode.setType('material');
const shaderElement = smNode.addInput('surfaceshader');
shaderElement.setType('surfaceshader');
shaderElement.setNodeName(ssName);
expect(doc.validate()).to.be.true;
return doc;
}

describe('Generate Shaders', function ()
{
let mx;
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');

this.timeout(60000);

before(async function ()
{
mx = await MaterialX();
});

it('Compile Shaders', () =>
{
const doc = createStandardSurfaceMaterial(mx);

const generators = []
if (typeof mx.EsslShaderGenerator != 'undefined')
generators.push(new mx.EsslShaderGenerator());
if (typeof mx.GlslShaderGenerator != 'undefined')
generators.push(new mx.GlslShaderGenerator());
if (typeof mx.MslShaderGenerator != 'undefined')
generators.push(new mx.MslShaderGenerator());
if (typeof mx.OslShaderGenerator != 'undefined')
generators.push(new mx.OslShaderGenerator());
if (typeof mx.VkShaderGenerator != 'undefined')
generators.push(new mx.VkShaderGenerator());
if (typeof mx.MdlShaderGenerator != 'undefined')
generators.push(new mx.MdlShaderGenerator());

const elem = mx.findRenderableElement(doc);
for (let gen of generators)
{
console.log("Generating shader for " + gen.getTarget() + "...");

const genContext = new mx.GenContext(gen);
const stdlib = mx.loadStandardLibraries(genContext);
doc.importLibrary(stdlib);

try
{
const mxShader = gen.generate(elem.getNamePath(), elem, genContext);

const fShader = mxShader.getSourceCode("pixel");

if (gen.getTarget() == 'essl')
{
const vShader = mxShader.getSourceCode("vertex");

const glVertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(glVertexShader, vShader);
gl.compileShader(glVertexShader);
if (!gl.getShaderParameter(glVertexShader, gl.COMPILE_STATUS))
{
console.error("-------- VERTEX SHADER FAILED TO COMPILE: ----------------");
console.error("--- VERTEX SHADER LOG ---");
console.error(gl.getShaderInfoLog(glVertexShader));
console.error("--- VERTEX SHADER START ---");
console.error(fShader);
console.error("--- VERTEX SHADER END ---");
}
expect(gl.getShaderParameter(glVertexShader, gl.COMPILE_STATUS)).to.equal(true);

const glPixelShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(glPixelShader, fShader);
gl.compileShader(glPixelShader);
if (!gl.getShaderParameter(glPixelShader, gl.COMPILE_STATUS))
{
console.error("-------- PIXEL SHADER FAILED TO COMPILE: ----------------");
console.error("--- PIXEL SHADER LOG ---");
console.error(gl.getShaderInfoLog(glPixelShader));
console.error("--- PIXEL SHADER START ---");
console.error(fShader);
console.error("--- PIXEL SHADER END ---");
}
expect(gl.getShaderParameter(glPixelShader, gl.COMPILE_STATUS)).to.equal(true);
}
}
catch (errPtr)
{
console.error("-------- Failed code generation: ----------------");
console.error(mx.getExceptionMessage(errPtr));
}
}
});
});
37 changes: 37 additions & 0 deletions source/JsMaterialX/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ set(CORE ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXCore/)
set(FORMAT ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXFormat/)
set(GENSHADER ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenShader/)
set(GENESSL ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenEssl/)
set(GENOSL ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenOsl/)
set(GENGLSL ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenGlsl/)
set(GENMSL ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenMsl/)
set(GENVK ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenVk/)
set(GENMDL ${CMAKE_CURRENT_SOURCE_DIR}/JsMaterialXGenMdl/)

set(SOURCE_FOLDER ${CMAKE_SOURCE_DIR}/source)

Expand Down Expand Up @@ -38,6 +43,11 @@ set(GENSHADER_DEPS ${GENSHADER}JsGenContext.cpp
${GENSHADER}JsUtil.cpp)

set(GENESSL_DEPS ${GENESSL}JsEsslShaderGenerator.cpp)
set(GENOSL_DEPS ${GENOSL}JsOslShaderGenerator.cpp)
set(GENGLSL_DEPS ${GENGLSL}JsGlslShaderGenerator.cpp)
set(GENMSL_DEPS ${GENMSL}JsMslShaderGenerator.cpp)
set(GENVK_DEPS ${GENVK}JsVkShaderGenerator.cpp)
set(GENMDL_DEPS ${GENMDL}JsMdlShaderGenerator.cpp)

# Linker flags
set(JS_LINK_FLAGS_CORE "")
Expand Down Expand Up @@ -87,6 +97,23 @@ add_executable(JsMaterialXGenShader MaterialXLib.cpp
${GENSHADER_DEPS}
${GENESSL_DEPS})

if (MATERIALX_BUILD_GEN_GLSL)
message("JS: Building JsMaterialXGenShader with GLSL, VK support")
target_sources(JsMaterialXGenShader PRIVATE ${GENGLSL_DEPS} ${GENVK_DEPS})
endif()
if (MATERIALX_BUILD_GEN_OSL)
message("JS: Building JsMaterialXGenShader with OSL support")
target_sources(JsMaterialXGenShader PRIVATE ${GENOSL_DEPS})
endif()
if (MATERIALX_BUILD_GEN_MDL)
message("JS: Building JsMaterialXGenShader with MDL support")
target_sources(JsMaterialXGenShader PRIVATE ${GENMDL_DEPS})
endif()
if (MATERIALX_BUILD_GEN_MSL)
message("JS: Building JsMaterialXGenShader with MSL support")
target_sources(JsMaterialXGenShader PRIVATE ${GENMSL_DEPS})
endif()

set_target_properties(JsMaterialXCore
PROPERTIES
OUTPUT_NAME JsMaterialXCore
Expand Down Expand Up @@ -115,6 +142,16 @@ target_link_libraries(JsMaterialXGenShader
PUBLIC MaterialXGenGlsl
PRIVATE ${CMAKE_DL_LIBS})

if (MATERIALX_BUILD_GEN_OSL)
target_link_libraries(JsMaterialXGenShader PUBLIC MaterialXGenOsl)
endif()
if (MATERIALX_BUILD_GEN_MDL)
target_link_libraries(JsMaterialXGenShader PRIVATE MaterialXGenMdl)
endif()
if (MATERIALX_BUILD_GEN_MSL)
target_link_libraries(JsMaterialXGenShader PUBLIC MaterialXGenMsl)
endif()

# Install the JavaScript output
install(TARGETS JsMaterialXCore DESTINATION "JavaScript/MaterialX")
install(TARGETS JsMaterialXGenShader DESTINATION "JavaScript/MaterialX")
Expand Down
19 changes: 19 additions & 0 deletions source/JsMaterialX/JsMaterialXGenGlsl/JsGlslShaderGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenGlsl/GlslShaderGenerator.h>
#include <MaterialXGenShader/Util.h>

#include <emscripten/bind.h>

namespace ems = emscripten;
namespace mx = MaterialX;

EMSCRIPTEN_BINDINGS(GlslShaderGenerator)
{
ems::class_<mx::GlslShaderGenerator, ems::base<mx::ShaderGenerator>>("GlslShaderGenerator")
.smart_ptr_constructor("GlslShaderGenerator", &std::make_shared<mx::GlslShaderGenerator>)
;
}
19 changes: 19 additions & 0 deletions source/JsMaterialX/JsMaterialXGenMdl/JsMdlShaderGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenMdl/MdlShaderGenerator.h>
#include <MaterialXGenShader/Util.h>

#include <emscripten/bind.h>

namespace ems = emscripten;
namespace mx = MaterialX;

EMSCRIPTEN_BINDINGS(MdlShaderGenerator)
{
ems::class_<mx::MdlShaderGenerator, ems::base<mx::ShaderGenerator>>("MdlShaderGenerator")
.smart_ptr_constructor("MdlShaderGenerator", &std::make_shared<mx::MdlShaderGenerator>)
;
}
19 changes: 19 additions & 0 deletions source/JsMaterialX/JsMaterialXGenMsl/JsMslShaderGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenMsl/MslShaderGenerator.h>
#include <MaterialXGenShader/Util.h>

#include <emscripten/bind.h>

namespace ems = emscripten;
namespace mx = MaterialX;

EMSCRIPTEN_BINDINGS(MslShaderGenerator)
{
ems::class_<mx::MslShaderGenerator, ems::base<mx::ShaderGenerator>>("MslShaderGenerator")
.smart_ptr_constructor("MslShaderGenerator", &std::make_shared<mx::MslShaderGenerator>)
;
}
19 changes: 19 additions & 0 deletions source/JsMaterialX/JsMaterialXGenOsl/JsOslShaderGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenOsl/OslShaderGenerator.h>
#include <MaterialXGenShader/Util.h>

#include <emscripten/bind.h>

namespace ems = emscripten;
namespace mx = MaterialX;

EMSCRIPTEN_BINDINGS(OslShaderGenerator)
{
ems::class_<mx::OslShaderGenerator, ems::base<mx::ShaderGenerator>>("OslShaderGenerator")
.smart_ptr_constructor("OslShaderGenerator", &std::make_shared<mx::OslShaderGenerator>)
;
}
19 changes: 19 additions & 0 deletions source/JsMaterialX/JsMaterialXGenVk/JsVkShaderGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//

#include <MaterialXGenGlsl/VkShaderGenerator.h>
#include <MaterialXGenShader/Util.h>

#include <emscripten/bind.h>

namespace ems = emscripten;
namespace mx = MaterialX;

EMSCRIPTEN_BINDINGS(VkShaderGenerator)
{
ems::class_<mx::VkShaderGenerator, ems::base<mx::ShaderGenerator>>("VkShaderGenerator")
.smart_ptr_constructor("VkShaderGenerator", &std::make_shared<mx::VkShaderGenerator>)
;
}