From a744a2b3ff4e1ea8a25d1901547aea20414805e7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2023 17:44:35 +0100 Subject: [PATCH 01/21] Added begninnings of new vsgcustomshaderset example --- examples/utils/CMakeLists.txt | 1 + .../utils/vsgcustomshaderset/CMakeLists.txt | 15 + .../utils/vsgcustomshaderset/custom_pbr.cpp | 69 ++++ .../vsgcustomshaderset/vsgcustomshaderset.cpp | 47 +++ .../utils/vsgcustomshaderset/vsgshaderset.cpp | 334 ++++++++++++++++++ 5 files changed, 466 insertions(+) create mode 100644 examples/utils/vsgcustomshaderset/CMakeLists.txt create mode 100644 examples/utils/vsgcustomshaderset/custom_pbr.cpp create mode 100644 examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp create mode 100644 examples/utils/vsgcustomshaderset/vsgshaderset.cpp diff --git a/examples/utils/CMakeLists.txt b/examples/utils/CMakeLists.txt index 2f89ec85..e5cf8c4c 100644 --- a/examples/utils/CMakeLists.txt +++ b/examples/utils/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(vsggraphicspipelineconfigurator) add_subdirectory(vsgshaderset) add_subdirectory(vsgintersection) add_subdirectory(vsgstoragebuffer) +add_subdirectory(vsgcustomshaderset) diff --git a/examples/utils/vsgcustomshaderset/CMakeLists.txt b/examples/utils/vsgcustomshaderset/CMakeLists.txt new file mode 100644 index 00000000..32b7a4b8 --- /dev/null +++ b/examples/utils/vsgcustomshaderset/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SOURCES + custom_pbr.cpp + vsgcustomshaderset.cpp +) + +add_executable(vsgcustomshaderset ${SOURCES}) + +target_link_libraries(vsgcustomshaderset vsg::vsg) + +if (vsgXchange_FOUND) + target_compile_definitions(vsgcustomshaderset PRIVATE vsgXchange_FOUND) + target_link_libraries(vsgcustomshaderset vsgXchange::vsgXchange) +endif() + +install(TARGETS vsgcustomshaderset RUNTIME DESTINATION bin) diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp new file mode 100644 index 00000000..6818bd4b --- /dev/null +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -0,0 +1,69 @@ +/* + +Copyright(c) 2020 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include +#include +#include +#include +#include +#include + +vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options) +{ + vsg::info("Local pbr_ShaderSet(",options,")"); + + auto vertexShader = vsg::read_cast("shaders/standard.vert", options); + auto fragmentShader = vsg::read_cast("shaders/standard_pbr.frag", options); + + if (!vertexShader || !fragmentShader) + { + vsg::error("pbr_ShaderSet(...) could not find shaders."); + return {}; + } + + auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); + + shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_TexCoord0", "", 2, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Array::create(1)); + shaderSet->addAttributeBinding("vsg_Color", "", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); + + shaderSet->addAttributeBinding("vsg_position", "VSG_INSTANCE_POSITIONS", 4, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_position_scaleDistance", "VSG_BILLBOARD", 4, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); + + shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", 0, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); + shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", 0, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", 0, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", 0, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", 0, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", 0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + + shaderSet->addDescriptorBinding("lightData", "", 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("shadowMaps", "", 1, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + + // additional defines + shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; + + shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128); + + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_INSTANCE_POSITIONS", "VSG_DISPLACEMENT_MAP"}, vsg::PositionAndDisplacementMapArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_INSTANCE_POSITIONS"}, vsg::PositionArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_DISPLACEMENT_MAP"}, vsg::DisplacementMapArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_BILLBOARD"}, vsg::BillboardArrayState::create()}); + + shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(1)); + + return shaderSet; +} diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp new file mode 100644 index 00000000..29c5586b --- /dev/null +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -0,0 +1,47 @@ +#include +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); + + +int main(int argc, char** argv) +{ + // use the vsg::Options object to pass the ReaderWriter_all to use when reading files. + auto options = vsg::Options::create(); +#ifdef vsgXchange_FOUND + options->add(vsgXchange::all::create()); +#endif + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + options->sharedObjects = vsg::SharedObjects::create(); + + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + // read any command line options that the ReaderWriters support + arguments.read(options); + if (argc <= 1) return 0; + + auto inputFilename = arguments.value("", "-i"); + auto outputFilename = arguments.value("", "-o"); + + vsg::ref_ptr shaderSet = pbr_ShaderSet(options); + options->shaderSets["pbr"] = shaderSet; + + std::cout<<"shaderSet = "< +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +// functions provided by text.cpp, flat.cpp +extern vsg::ref_ptr text_ShaderSet(vsg::ref_ptr options); +extern vsg::ref_ptr flat_ShaderSet(vsg::ref_ptr options); +extern vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr options); +extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); + +void print(const vsg::ShaderSet& shaderSet, std::ostream& out) +{ + out<<"stages.size() = "<defines) out< definesArrayStates; // put more constrained ArrayState matches first so they are matched first. +#endif +} + +std::set supportedDefines(const vsg::ShaderSet& shaderSet) +{ + std::set defines; + + for(auto& ab : shaderSet.attributeBindings) + { + if (!ab.define.empty()) defines.insert(ab.define); + } + + for(auto& ub : shaderSet.descriptorBindings) + { + if (!ub.define.empty()) defines.insert(ub.define); + } + + for(auto& pcr : shaderSet.pushConstantRanges) + { + if (!pcr.define.empty()) defines.insert(pcr.define); + } + + for(auto& define : shaderSet.optionalDefines) + { + defines.insert(define); + } + + return defines; +} + +int main(int argc, char** argv) +{ + // use the vsg::Options object to pass the ReaderWriter_all to use when reading files. + auto options = vsg::Options::create(); +#ifdef vsgXchange_FOUND + options->add(vsgXchange::all::create()); +#endif + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + options->sharedObjects = vsg::SharedObjects::create(); + + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + // read any command line options that the ReaderWriters support + arguments.read(options); + if (argc <= 1) return 0; + + auto inputFilename = arguments.value("", "-i"); + auto outputFilename = arguments.value("", "-o"); + bool binary = arguments.read("--binary"); + bool vsgShaderSet = arguments.read("--vsg"); + bool stripShaderSetBeforeWrite = arguments.read({"-s", "--strip"}); + bool compileShaders = !arguments.read({"--nc","--no-compile"}); + + vsg::ref_ptr shaderSet; + if (inputFilename) + { + shaderSet = vsg::read_cast(inputFilename, options); + } + + if (arguments.read("--text")) + { + if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createTextShaderSet(options) : text_ShaderSet(options); + options->shaderSets["text"] = shaderSet; + } + + if (arguments.read("--flat")) + { + if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createFlatShadedShaderSet(options) : flat_ShaderSet(options); + options->shaderSets["flat"] = shaderSet; + } + if (arguments.read("--phong")) + { + if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createPhongShaderSet(options) : phong_ShaderSet(options); + options->shaderSets["phong"] = shaderSet; + } + + if (arguments.read("--pbr")) + { + if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createPhysicsBasedRenderingShaderSet(options) : pbr_ShaderSet(options); + options->shaderSets["pbr"] = shaderSet; + } + + std::cout<<"shaderSet = "<> s; + if (!s.empty()) + { + if (defines.count(s)==0) + { + std::cout<<"variant define [ "<defines.insert(s); + } + } + + // assign the variant + shaderSet->getShaderStages(scs); + + std::cout<> existing_stages; + + auto shaderCompiler = vsg::ShaderCompiler::create(); + if (shaderCompiler->supported()) + { + std::cout<<"\ncompiling shaderSet->variants.size() = "<variants.size()<variants) + { + std::cout<<" "<defines) std::cout<module->code.empty() && !stage->module->source.empty()) ++numShadersWithSource; + } + + // no need to compile so skip compilation + if (numShadersWithSource == stagesToCompile.size()) + { + shaderCompiler->compile(stagesToCompile, {}, options); + } + + for(auto& stage : stagesToCompile) + { + stage->module->source.clear(); + } + + for(auto& stage : stagesToCompile) + { + vsg::ref_ptr match; + for(auto& existing_stage : existing_stages) + { + bool module_matched = stage->module->code == existing_stage->module->code; + if (module_matched) + { + // share the matched ShaderModule + stage->module = existing_stage->module; + + if (vsg::compare_pointer(stage, existing_stage)==0) + { + match = existing_stage; + } + break; + } + } + if (match) + { + // share the whole ShaderStage + stage = match; + } + else + { + existing_stages.push_back(stage); + } + } + + std::cout<module<<" "<module->code.size()<stages.clear(); + shaderSet->attributeBindings.clear(); + shaderSet->descriptorBindings.clear(); + shaderSet->pushConstantRanges.clear(); + shaderSet->definesArrayStates.clear(); + shaderSet->optionalDefines.clear(); + shaderSet->defaultGraphicsPipelineStates.clear(); + } + + if (outputFilename) + { + if (binary) options->extensionHint = ".vsgb"; + vsg::write(shaderSet, outputFilename, options); + } + + return 0; +} From 5a34849c299cc840e59be5929c35ef80f6ffcde1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2023 11:59:57 +0000 Subject: [PATCH 02/21] Added loading and rendering of models --- .../vsgcustomshaderset/vsgcustomshaderset.cpp | 111 +++++++++++++++++- 1 file changed, 108 insertions(+), 3 deletions(-) diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 29c5586b..7a1bcfaf 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -23,10 +23,19 @@ int main(int argc, char** argv) // read any command line options that the ReaderWriters support arguments.read(options); - if (argc <= 1) return 0; - auto inputFilename = arguments.value("", "-i"); + auto windowTraits = vsg::WindowTraits::create(); + windowTraits->windowTitle = "vscustomshaderset"; + windowTraits->debugLayer = arguments.read({"--debug", "-d"}); + windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); + windowTraits->synchronizationLayer = arguments.read("--sync"); + + auto numFrames = arguments.value(-1, "-f"); auto outputFilename = arguments.value("", "-o"); + auto outputShaderSetFilename = arguments.value("", "--os"); + auto horizonMountainHeight = arguments.value(0.0, "--hmh"); + auto nearFarRatio = arguments.value(0.001, "--nfr"); + bool reportAverageFrameRate = arguments.read("--fps"); vsg::ref_ptr shaderSet = pbr_ShaderSet(options); options->shaderSets["pbr"] = shaderSet; @@ -38,10 +47,106 @@ int main(int argc, char** argv) return 1; } + if (outputShaderSetFilename) + { + vsg::write(shaderSet, outputShaderSetFilename, options); + } + + auto group = vsg::Group::create(); + + vsg::Path path; + + // read any vsg files + for (int i = 1; i < argc; ++i) + { + vsg::Path filename = arguments[i]; + if (auto node = vsg::read_cast(filename, options)) + { + group->addChild(node); + } + else + { + std::cout << "Unable to load file " << filename << std::endl; + } + } + + if (group->children.empty()) + { + return 1; + } + + vsg::ref_ptr vsg_scene; + if (group->children.size() == 1) + vsg_scene = group->children[0]; + else + vsg_scene = group; + if (outputFilename) { - vsg::write(shaderSet, outputFilename, options); + vsg::write(vsg_scene, outputFilename, options); + } + + // create the viewer and assign window(s) to it + auto viewer = vsg::Viewer::create(); + auto window = vsg::Window::create(windowTraits); + if (!window) + { + std::cout << "Could not create window." << std::endl; + return 1; } + viewer->addWindow(window); + + // compute the bounds of the scene graph to help position camera + auto bounds = vsg::visit(vsg_scene).bounds; + vsg::dvec3 centre = (bounds.min + bounds.max) * 0.5; + double radius = vsg::length(bounds.max - bounds.min) * 0.6; + + // set up the camera + auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); + + vsg::ref_ptr perspective; + auto ellipsoidModel = vsg_scene->getRefObject("EllipsoidModel"); + if (ellipsoidModel) + { + perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio, horizonMountainHeight); + } + else + { + perspective = vsg::Perspective::create(30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 4.5); + } + + auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D())); + + // add close handler to respond to the close window button and pressing escape + viewer->addEventHandler(vsg::CloseHandler::create(viewer)); + viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + + auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); + viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + + viewer->compile(); + + viewer->start_point() = vsg::clock::now(); + + // rendering main loop + while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) + { + // pass any events into EventHandlers assigned to the Viewer + viewer->handleEvents(); + + viewer->update(); + + viewer->recordAndSubmit(); + + viewer->present(); + } + + if (reportAverageFrameRate) + { + auto fs = viewer->getFrameStamp(); + double fps = static_cast(fs->frameCount) / std::chrono::duration(vsg::clock::now() - viewer->start_point()).count(); + std::cout<<"Average frame rate = "< Date: Wed, 1 Nov 2023 12:04:19 +0000 Subject: [PATCH 03/21] Added custom_pbr shaders --- data/shaders/custom_pbr.frag | 523 ++++++++++++++++++ data/shaders/custom_pbr.vert | 107 ++++ .../utils/vsgcustomshaderset/custom_pbr.cpp | 4 +- 3 files changed, 632 insertions(+), 2 deletions(-) create mode 100644 data/shaders/custom_pbr.frag create mode 100644 data/shaders/custom_pbr.vert diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag new file mode 100644 index 00000000..2ee88610 --- /dev/null +++ b/data/shaders/custom_pbr.frag @@ -0,0 +1,523 @@ +#version 450 +#extension GL_ARB_separate_shader_objects : enable +#pragma import_defines (VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, SHADOWMAP_DEBUG) + +const float PI = 3.14159265359; +const float RECIPROCAL_PI = 0.31830988618; +const float RECIPROCAL_PI2 = 0.15915494; +const float EPSILON = 1e-6; +const float c_MinRoughness = 0.04; + +#ifdef VSG_DIFFUSE_MAP +layout(binding = 0) uniform sampler2D diffuseMap; +#endif + +#ifdef VSG_METALLROUGHNESS_MAP +layout(binding = 1) uniform sampler2D mrMap; +#endif + +#ifdef VSG_NORMAL_MAP +layout(binding = 2) uniform sampler2D normalMap; +#endif + +#ifdef VSG_LIGHTMAP_MAP +layout(binding = 3) uniform sampler2D aoMap; +#endif + +#ifdef VSG_EMISSIVE_MAP +layout(binding = 4) uniform sampler2D emissiveMap; +#endif + +#ifdef VSG_SPECULAR_MAP +layout(binding = 5) uniform sampler2D specularMap; +#endif + +layout(binding = 10) uniform PbrData +{ + vec4 baseColorFactor; + vec4 emissiveFactor; + vec4 diffuseFactor; + vec4 specularFactor; + float metallicFactor; + float roughnessFactor; + float alphaMask; + float alphaMaskCutoff; +} pbr; + +layout(set = 1, binding = 0) uniform LightData +{ + vec4 values[2048]; +} lightData; + +layout(set = 1, binding = 2) uniform sampler2DArrayShadow shadowMaps; + +layout(location = 0) in vec3 eyePos; +layout(location = 1) in vec3 normalDir; +layout(location = 2) in vec4 vertexColor; +layout(location = 3) in vec2 texCoord0; +layout(location = 5) in vec3 viewDir; + +layout(location = 0) out vec4 outColor; + + +// Encapsulate the various inputs used by the various functions in the shading equation +// We store values in this struct to simplify the integration of alternative implementations +// of the shading terms, outlined in the Readme.MD Appendix. +struct PBRInfo +{ + float NdotL; // cos angle between normal and light direction + float NdotV; // cos angle between normal and view direction + float NdotH; // cos angle between normal and half vector + float LdotH; // cos angle between light direction and half vector + float VdotH; // cos angle between view direction and half vector + float VdotL; // cos angle between view direction and light direction + float perceptualRoughness; // roughness value, as authored by the model creator (input to shader) + float metalness; // metallic value at the surface + vec3 reflectance0; // full reflectance color (normal incidence angle) + vec3 reflectance90; // reflectance color at grazing angle + float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2]) + vec3 diffuseColor; // color contribution from diffuse lighting + vec3 specularColor; // color contribution from specular lighting +}; + + +vec4 SRGBtoLINEAR(vec4 srgbIn) +{ + vec3 linOut = pow(srgbIn.xyz, vec3(2.2)); + return vec4(linOut,srgbIn.w); +} + +vec4 LINEARtoSRGB(vec4 srgbIn) +{ + vec3 linOut = pow(srgbIn.xyz, vec3(1.0 / 2.2)); + return vec4(linOut, srgbIn.w); +} + +float rcp(const in float value) +{ + return 1.0 / value; +} + +float pow5(const in float value) +{ + return value * value * value * value * value; +} + +// Find the normal for this fragment, pulling either from a predefined normal map +// or from the interpolated mesh normal and tangent attributes. +vec3 getNormal() +{ + vec3 result; +#ifdef VSG_NORMAL_MAP + // Perturb normal, see http://www.thetenthplanet.de/archives/1180 + vec3 tangentNormal = texture(normalMap, texCoord0).xyz * 2.0 - 1.0; + + //tangentNormal *= vec3(2,2,1); + + vec3 q1 = dFdx(eyePos); + vec3 q2 = dFdy(eyePos); + vec2 st1 = dFdx(texCoord0); + vec2 st2 = dFdy(texCoord0); + + vec3 N = normalize(normalDir); + vec3 T = normalize(q1 * st2.t - q2 * st1.t); + vec3 B = -normalize(cross(N, T)); + mat3 TBN = mat3(T, B, N); + + result = normalize(TBN * tangentNormal); +#else + result = normalize(normalDir); +#endif +#ifdef VSG_TWO_SIDED_LIGHTING + if (!gl_FrontFacing) + result = -result; +#endif + return result; +} + +// Basic Lambertian diffuse +// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog +// See also [1], Equation 1 +vec3 BRDF_Diffuse_Lambert(PBRInfo pbrInputs) +{ + return pbrInputs.diffuseColor * RECIPROCAL_PI; +} + +vec3 BRDF_Diffuse_Custom_Lambert(PBRInfo pbrInputs) +{ + return pbrInputs.diffuseColor * RECIPROCAL_PI * pow(pbrInputs.NdotV, 0.5 + 0.3 * pbrInputs.perceptualRoughness); +} + +// [Gotanda 2012, "Beyond a Simple Physically Based Blinn-Phong Model in Real-Time"] +vec3 BRDF_Diffuse_OrenNayar(PBRInfo pbrInputs) +{ + float a = pbrInputs.alphaRoughness; + float s = a;// / ( 1.29 + 0.5 * a ); + float s2 = s * s; + float VoL = 2 * pbrInputs.VdotH * pbrInputs.VdotH - 1; // double angle identity + float Cosri = pbrInputs.VdotL - pbrInputs.NdotV * pbrInputs.NdotL; + float C1 = 1 - 0.5 * s2 / (s2 + 0.33); + float C2 = 0.45 * s2 / (s2 + 0.09) * Cosri * ( Cosri >= 0 ? 1.0 / max(pbrInputs.NdotL, pbrInputs.NdotV) : 1 ); + return pbrInputs.diffuseColor / PI * ( C1 + C2 ) * ( 1 + pbrInputs.perceptualRoughness * 0.5 ); +} + +// [Gotanda 2014, "Designing Reflectance Models for New Consoles"] +vec3 BRDF_Diffuse_Gotanda(PBRInfo pbrInputs) +{ + float a = pbrInputs.alphaRoughness; + float a2 = a * a; + float F0 = 0.04; + float VoL = 2 * pbrInputs.VdotH * pbrInputs.VdotH - 1; // double angle identity + float Cosri = VoL - pbrInputs.NdotV * pbrInputs.NdotL; + float a2_13 = a2 + 1.36053; + float Fr = ( 1 - ( 0.542026*a2 + 0.303573*a ) / a2_13 ) * ( 1 - pow( 1 - pbrInputs.NdotV, 5 - 4*a2 ) / a2_13 ) * ( ( -0.733996*a2*a + 1.50912*a2 - 1.16402*a ) * pow( 1 - pbrInputs.NdotV, 1 + rcp(39*a2*a2+1) ) + 1 ); + //float Fr = ( 1 - 0.36 * a ) * ( 1 - pow( 1 - NoV, 5 - 4*a2 ) / a2_13 ) * ( -2.5 * Roughness * ( 1 - NoV ) + 1 ); + float Lm = ( max( 1 - 2*a, 0 ) * ( 1 - pow5( 1 - pbrInputs.NdotL ) ) + min( 2*a, 1 ) ) * ( 1 - 0.5*a * (pbrInputs.NdotL - 1) ) * pbrInputs.NdotL; + float Vd = ( a2 / ( (a2 + 0.09) * (1.31072 + 0.995584 * pbrInputs.NdotV) ) ) * ( 1 - pow( 1 - pbrInputs.NdotL, ( 1 - 0.3726732 * pbrInputs.NdotV * pbrInputs.NdotV ) / ( 0.188566 + 0.38841 * pbrInputs.NdotV ) ) ); + float Bp = Cosri < 0 ? 1.4 * pbrInputs.NdotV * pbrInputs.NdotL * Cosri : Cosri; + float Lr = (21.0 / 20.0) * (1 - F0) * ( Fr * Lm + Vd + Bp ); + return pbrInputs.diffuseColor * RECIPROCAL_PI * Lr; +} + +vec3 BRDF_Diffuse_Burley(PBRInfo pbrInputs) +{ + float energyBias = mix(pbrInputs.perceptualRoughness, 0.0, 0.5); + float energyFactor = mix(pbrInputs.perceptualRoughness, 1.0, 1.0 / 1.51); + float fd90 = energyBias + 2.0 * pbrInputs.VdotH * pbrInputs.VdotH * pbrInputs.perceptualRoughness; + float f0 = 1.0; + float lightScatter = f0 + (fd90 - f0) * pow(1.0 - pbrInputs.NdotL, 5.0); + float viewScatter = f0 + (fd90 - f0) * pow(1.0 - pbrInputs.NdotV, 5.0); + + return pbrInputs.diffuseColor * lightScatter * viewScatter * energyFactor; +} + +vec3 BRDF_Diffuse_Disney(PBRInfo pbrInputs) +{ + float Fd90 = 0.5 + 2.0 * pbrInputs.perceptualRoughness * pbrInputs.VdotH * pbrInputs.VdotH; + vec3 f0 = vec3(0.1); + vec3 invF0 = vec3(1.0, 1.0, 1.0) - f0; + float dim = min(invF0.r, min(invF0.g, invF0.b)); + float result = ((1.0 + (Fd90 - 1.0) * pow(1.0 - pbrInputs.NdotL, 5.0 )) * (1.0 + (Fd90 - 1.0) * pow(1.0 - pbrInputs.NdotV, 5.0 ))) * dim; + return pbrInputs.diffuseColor * result; +} + +// The following equation models the Fresnel reflectance term of the spec equation (aka F()) +// Implementation of fresnel from [4], Equation 15 +vec3 specularReflection(PBRInfo pbrInputs) +{ + //return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); + return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance90*pbrInputs.reflectance0) * exp2((-5.55473 * pbrInputs.VdotH - 6.98316) * pbrInputs.VdotH); +} + +// This calculates the specular geometric attenuation (aka G()), +// where rougher material will reflect less light back to the viewer. +// This implementation is based on [1] Equation 4, and we adopt their modifications to +// alphaRoughness as input as originally proposed in [2]. +float geometricOcclusion(PBRInfo pbrInputs) +{ + float NdotL = pbrInputs.NdotL; + float NdotV = pbrInputs.NdotV; + float r = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; + + float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r + (1.0 - r) * (NdotL * NdotL))); + float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r + (1.0 - r) * (NdotV * NdotV))); + return attenuationL * attenuationV; +} + +// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D()) +// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz +// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3. +float microfacetDistribution(PBRInfo pbrInputs) +{ + float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness; + float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0; + return roughnessSq / (PI * f * f); +} + +vec3 BRDF(vec3 u_LightColor, vec3 v, vec3 n, vec3 l, vec3 h, float perceptualRoughness, float metallic, vec3 specularEnvironmentR0, vec3 specularEnvironmentR90, float alphaRoughness, vec3 diffuseColor, vec3 specularColor, float ao) +{ + float unclmapped_NdotL = dot(n, l); + + vec3 reflection = -normalize(reflect(v, n)); + reflection.y *= -1.0f; + + float NdotL = clamp(unclmapped_NdotL, 0.001, 1.0); + float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0); + float NdotH = clamp(dot(n, h), 0.0, 1.0); + float LdotH = clamp(dot(l, h), 0.0, 1.0); + float VdotH = clamp(dot(v, h), 0.0, 1.0); + float VdotL = clamp(dot(v, l), 0.0, 1.0); + + PBRInfo pbrInputs = PBRInfo(NdotL, + NdotV, + NdotH, + LdotH, + VdotH, + VdotL, + perceptualRoughness, + metallic, + specularEnvironmentR0, + specularEnvironmentR90, + alphaRoughness, + diffuseColor, + specularColor); + + // Calculate the shading terms for the microfacet specular shading model + vec3 F = specularReflection(pbrInputs); + float G = geometricOcclusion(pbrInputs); + float D = microfacetDistribution(pbrInputs); + + // Calculation of analytical lighting contribution + vec3 diffuseContrib = (1.0 - F) * BRDF_Diffuse_Disney(pbrInputs); + vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV); + // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law) + vec3 color = NdotL * u_LightColor * (diffuseContrib + specContrib); + + color *= ao; + +#ifdef VSG_EMISSIVE_MAP + vec3 emissive = SRGBtoLINEAR(texture(emissiveMap, texCoord0)).rgb * pbr.emissiveFactor.rgb; +#else + vec3 emissive = pbr.emissiveFactor.rgb; +#endif + color += emissive; + + return color; +} + +float convertMetallic(vec3 diffuse, vec3 specular, float maxSpecular) +{ + float perceivedDiffuse = sqrt(0.299 * diffuse.r * diffuse.r + 0.587 * diffuse.g * diffuse.g + 0.114 * diffuse.b * diffuse.b); + float perceivedSpecular = sqrt(0.299 * specular.r * specular.r + 0.587 * specular.g * specular.g + 0.114 * specular.b * specular.b); + + if (perceivedSpecular < c_MinRoughness) + { + return 0.0; + } + + float a = c_MinRoughness; + float b = perceivedDiffuse * (1.0 - maxSpecular) / (1.0 - c_MinRoughness) + perceivedSpecular - 2.0 * c_MinRoughness; + float c = c_MinRoughness - perceivedSpecular; + float D = max(b * b - 4.0 * a * c, 0.0); + return clamp((-b + sqrt(D)) / (2.0 * a), 0.0, 1.0); +} + +void main() +{ + float brightnessCutoff = 0.001; + + float perceptualRoughness = 0.0; + float metallic; + vec3 diffuseColor; + vec4 baseColor; + + float ambientOcclusion = 1.0; + + vec3 f0 = vec3(0.04); + +#ifdef VSG_DIFFUSE_MAP + #ifdef VSG_GREYSCALE_DIFFUSE_MAP + float v = texture(diffuseMap, texCoord0.st).s * pbr.baseColorFactor; + baseColor = vertexColor * vec4(v, v, v, 1.0); + #else + baseColor = vertexColor * SRGBtoLINEAR(texture(diffuseMap, texCoord0)) * pbr.baseColorFactor; + #endif +#else + baseColor = vertexColor * pbr.baseColorFactor; +#endif + + if (pbr.alphaMask == 1.0f) + { + if (baseColor.a < pbr.alphaMaskCutoff) + discard; + } + +#ifdef VSG_WORKFLOW_SPECGLOSS + #ifdef VSG_DIFFUSE_MAP + vec4 diffuse = SRGBtoLINEAR(texture(diffuseMap, texCoord0)); + #else + vec4 diffuse = vec4(1.0); + #endif + + #ifdef VSG_SPECULAR_MAP + vec4 specular_texel = texture(specularMap, texCoord0); + vec3 specular = SRGBtoLINEAR(specular_texel).rgb; + perceptualRoughness = 1.0 - specular_texel.a; + #else + vec3 specular = vec3(0.0); + perceptualRoughness = 0.0; + #endif + + float maxSpecular = max(max(specular.r, specular.g), specular.b); + + // Convert metallic value from specular glossiness inputs + metallic = convertMetallic(diffuse.rgb, specular, maxSpecular); + + const float epsilon = 1e-6; + vec3 baseColorDiffusePart = diffuse.rgb * ((1.0 - maxSpecular) / (1 - c_MinRoughness) / max(1 - metallic, epsilon)) * pbr.diffuseFactor.rgb; + vec3 baseColorSpecularPart = specular - (vec3(c_MinRoughness) * (1 - metallic) * (1 / max(metallic, epsilon))) * pbr.specularFactor.rgb; + baseColor = vec4(mix(baseColorDiffusePart, baseColorSpecularPart, metallic * metallic), diffuse.a); +#else + perceptualRoughness = pbr.roughnessFactor; + metallic = pbr.metallicFactor; + + #ifdef VSG_METALLROUGHNESS_MAP + vec4 mrSample = texture(mrMap, texCoord0); + perceptualRoughness = mrSample.g * perceptualRoughness; + metallic = mrSample.b * metallic; + #endif +#endif + +#ifdef VSG_LIGHTMAP_MAP + ambientOcclusion = texture(aoMap, texCoord0).r; +#endif + + diffuseColor = baseColor.rgb * (vec3(1.0) - f0); + diffuseColor *= 1.0 - metallic; + + float alphaRoughness = perceptualRoughness * perceptualRoughness; + + vec3 specularColor = mix(f0, baseColor.rgb, metallic); + + // Compute reflectance. + float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b); + + // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect. + // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%. + float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0); + vec3 specularEnvironmentR0 = specularColor.rgb; + vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90; + + vec3 n = getNormal(); + vec3 v = normalize(viewDir); // Vector from surface point to camera + + float shininess = 100.0f; + + vec3 color = vec3(0.0, 0.0, 0.0); + + vec4 lightNums = lightData.values[0]; + int numAmbientLights = int(lightNums[0]); + int numDirectionalLights = int(lightNums[1]); + int numPointLights = int(lightNums[2]); + int numSpotLights = int(lightNums[3]); + int index = 1; + + if (numAmbientLights>0) + { + // ambient lights + for(int i = 0; i0) + { + // directional lights + for(int i = 0; i 0.0 && brightness > brightnessCutoff) && !matched) + { + mat4 sm_matrix = mat4(lightData.values[index++], + lightData.values[index++], + lightData.values[index++], + lightData.values[index++]); + + vec4 sm_tc = (sm_matrix) * vec4(eyePos, 1.0); + + if (sm_tc.x >= 0.0 && sm_tc.x <= 1.0 && sm_tc.y >= 0.0 && sm_tc.y <= 1.0 && sm_tc.z >= 0.0 /* && sm_tc.z <= 1.0*/) + { + matched = true; + + float coverage = texture(shadowMaps, vec4(sm_tc.st, shadowMapIndex, sm_tc.z)).r; + brightness *= (1.0-coverage); + +#ifdef SHADOWMAP_DEBUG + if (shadowMapIndex==0) color = vec3(1.0, 0.0, 0.0); + else if (shadowMapIndex==1) color = vec3(0.0, 1.0, 0.0); + else if (shadowMapIndex==2) color = vec3(0.0, 0.0, 1.0); + else if (shadowMapIndex==3) color = vec3(1.0, 1.0, 0.0); + else if (shadowMapIndex==4) color = vec3(0.0, 1.0, 1.0); + else color = vec3(1.0, 1.0, 1.0); +#endif + } + + ++shadowMapIndex; + shadowMapSettings.r -= 1.0; + } + + if (shadowMapSettings.r > 0.0) + { + // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light + // so subsequent light pointions are correct. + index += 4 * int(shadowMapSettings.r); + shadowMapIndex += int(shadowMapSettings.r); + } + + // if light is too dim/shadowed to effect the rendering skip it + if (brightness <= brightnessCutoff ) continue; + + vec3 l = direction; // Vector from surface point to light + vec3 h = normalize(l+v); // Half vector between both l and v + float scale = brightness; + + color.rgb += BRDF(lightColor.rgb * scale, v, n, l, h, perceptualRoughness, metallic, specularEnvironmentR0, specularEnvironmentR90, alphaRoughness, diffuseColor, specularColor, ambientOcclusion); + } + } + + if (numPointLights>0) + { + // point light + for(int i = 0; i0) + { + // spot light + for(int i = 0; i pbr_ShaderSet(vsg::ref_ptr opti { vsg::info("Local pbr_ShaderSet(",options,")"); - auto vertexShader = vsg::read_cast("shaders/standard.vert", options); - auto fragmentShader = vsg::read_cast("shaders/standard_pbr.frag", options); + auto vertexShader = vsg::read_cast("shaders/custom_pbr.vert", options); + auto fragmentShader = vsg::read_cast("shaders/custom_pbr.frag", options); if (!vertexShader || !fragmentShader) { From 247aaa0fbecb7e85e270aa7342424bc55ef9389a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2023 12:51:55 +0000 Subject: [PATCH 04/21] Added define's for MATERIAL_DESCRIPTOR_SET and VIEW_DESCRIPTOR_SET in prep for changing these from the default of 0 and 1 locations --- data/shaders/custom_pbr.frag | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 2ee88610..ce689ba3 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -8,31 +8,34 @@ const float RECIPROCAL_PI2 = 0.15915494; const float EPSILON = 1e-6; const float c_MinRoughness = 0.04; +#define VIEW_DESCRIPTOR_SET 1 +#define MATERIAL_DESCRIPTOR_SET 0 + #ifdef VSG_DIFFUSE_MAP -layout(binding = 0) uniform sampler2D diffuseMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; #endif #ifdef VSG_METALLROUGHNESS_MAP -layout(binding = 1) uniform sampler2D mrMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 1) uniform sampler2D mrMap; #endif #ifdef VSG_NORMAL_MAP -layout(binding = 2) uniform sampler2D normalMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 2) uniform sampler2D normalMap; #endif #ifdef VSG_LIGHTMAP_MAP -layout(binding = 3) uniform sampler2D aoMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 3) uniform sampler2D aoMap; #endif #ifdef VSG_EMISSIVE_MAP -layout(binding = 4) uniform sampler2D emissiveMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap; #endif #ifdef VSG_SPECULAR_MAP -layout(binding = 5) uniform sampler2D specularMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap; #endif -layout(binding = 10) uniform PbrData +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData { vec4 baseColorFactor; vec4 emissiveFactor; @@ -44,12 +47,12 @@ layout(binding = 10) uniform PbrData float alphaMaskCutoff; } pbr; -layout(set = 1, binding = 0) uniform LightData +layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData { vec4 values[2048]; } lightData; -layout(set = 1, binding = 2) uniform sampler2DArrayShadow shadowMaps; +layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; From 4baf7ba23289311b2f153ea47721b8390d10f075 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2023 13:02:28 +0000 Subject: [PATCH 05/21] Added preliminary ShaderSet use of VIEW_DESCRIPTOR_SET & MATERIAL_DESCRIPTOR_SET --- .../utils/vsgcustomshaderset/custom_pbr.cpp | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index fb90fbc2..0fffe09d 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -31,6 +31,9 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti return {}; } + #define VIEW_DESCRIPTOR_SET 1 + #define MATERIAL_DESCRIPTOR_SET 0 + auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); @@ -41,17 +44,17 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addAttributeBinding("vsg_position", "VSG_INSTANCE_POSITIONS", 4, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_position_scaleDistance", "VSG_BILLBOARD", 4, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); - shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", 0, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); - shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", 0, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); - shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", 0, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", 0, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", 0, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("material", "", 0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", MATERIAL_DESCRIPTOR_SET, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", MATERIAL_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); + shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", MATERIAL_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); - shaderSet->addDescriptorBinding("lightData", "", 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); - shaderSet->addDescriptorBinding("shadowMaps", "", 1, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); // additional defines shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; @@ -63,7 +66,7 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_DISPLACEMENT_MAP"}, vsg::DisplacementMapArrayState::create()}); shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_BILLBOARD"}, vsg::BillboardArrayState::create()}); - shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(1)); + shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); return shaderSet; } From 45b4ba02dc04afe6936061e2de08de50b8bb0e1c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 1 Nov 2023 18:02:56 +0000 Subject: [PATCH 06/21] Changed VIEW_DESCRIPTOR_SET and MATERIAL_DESCRIPTOR_SET to 0 and 1 respectively. --- data/shaders/custom_pbr.frag | 4 ++-- examples/utils/vsgcustomshaderset/custom_pbr.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index ce689ba3..c242fa80 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -8,8 +8,8 @@ const float RECIPROCAL_PI2 = 0.15915494; const float EPSILON = 1e-6; const float c_MinRoughness = 0.04; -#define VIEW_DESCRIPTOR_SET 1 -#define MATERIAL_DESCRIPTOR_SET 0 +#define VIEW_DESCRIPTOR_SET 0 +#define MATERIAL_DESCRIPTOR_SET 1 #ifdef VSG_DIFFUSE_MAP layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index 0fffe09d..dcbce487 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -31,8 +31,8 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti return {}; } - #define VIEW_DESCRIPTOR_SET 1 - #define MATERIAL_DESCRIPTOR_SET 0 + #define VIEW_DESCRIPTOR_SET 0 + #define MATERIAL_DESCRIPTOR_SET 1 auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); From 16084e33f20c2112955db4de84482be956473c19 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Nov 2023 10:09:10 +0000 Subject: [PATCH 07/21] Added ColorModulator uniform to test out custom ShaderSet --- data/shaders/custom_pbr.frag | 10 +- .../utils/vsgcustomshaderset/custom_pbr.cpp | 3 + .../vsgcustomshaderset/vsgcustomshaderset.cpp | 14 +- .../utils/vsgcustomshaderset/vsgshaderset.cpp | 334 ------------------ 4 files changed, 25 insertions(+), 336 deletions(-) delete mode 100644 examples/utils/vsgcustomshaderset/vsgshaderset.cpp diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index c242fa80..7dccf866 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -10,6 +10,7 @@ const float c_MinRoughness = 0.04; #define VIEW_DESCRIPTOR_SET 0 #define MATERIAL_DESCRIPTOR_SET 1 +#define CUSTOM_DESCRIPTOR_SET 4 #ifdef VSG_DIFFUSE_MAP layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; @@ -47,6 +48,7 @@ layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData float alphaMaskCutoff; } pbr; +// ViewDependentState layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData { vec4 values[2048]; @@ -54,6 +56,12 @@ layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; +// Custom state +layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform ColorModulation +{ + vec4 value; +} colorModulation; + layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; layout(location = 2) in vec4 vertexColor; @@ -522,5 +530,5 @@ void main() } } - outColor = LINEARtoSRGB(vec4(color, baseColor.a)); + outColor = LINEARtoSRGB(vec4(color, baseColor.a)) * colorModulation.value; } diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index dcbce487..b6491787 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -33,6 +33,7 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti #define VIEW_DESCRIPTOR_SET 0 #define MATERIAL_DESCRIPTOR_SET 1 + #define CUSTOM_DESCRIPTOR_SET 4 auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); @@ -56,6 +57,8 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(1.0, 1.0, 0.0, 1.0)); + // additional defines shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 7a1bcfaf..32c8231e 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -36,6 +36,7 @@ int main(int argc, char** argv) auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); bool reportAverageFrameRate = arguments.read("--fps"); + bool inheritState = arguments.read("--inherit"); vsg::ref_ptr shaderSet = pbr_ShaderSet(options); options->shaderSets["pbr"] = shaderSet; @@ -52,7 +53,18 @@ int main(int argc, char** argv) vsg::write(shaderSet, outputShaderSetFilename, options); } - auto group = vsg::Group::create(); + auto group = vsg::StateGroup::create(); + if (inheritState) + { + uint32_t set = 0; + auto layout = shaderSet->createPipelineLayout({}); + auto bvds = vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, set); + group->add(bvds); + + options->setObject("inherited", bvds); + + vsg::info("Added ", bvds, " to root node."); + } vsg::Path path; diff --git a/examples/utils/vsgcustomshaderset/vsgshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgshaderset.cpp deleted file mode 100644 index 4d67ce5e..00000000 --- a/examples/utils/vsgcustomshaderset/vsgshaderset.cpp +++ /dev/null @@ -1,334 +0,0 @@ -#include -#include - -#ifdef vsgXchange_FOUND -# include -#endif - -// functions provided by text.cpp, flat.cpp -extern vsg::ref_ptr text_ShaderSet(vsg::ref_ptr options); -extern vsg::ref_ptr flat_ShaderSet(vsg::ref_ptr options); -extern vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr options); -extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); - -void print(const vsg::ShaderSet& shaderSet, std::ostream& out) -{ - out<<"stages.size() = "<defines) out< definesArrayStates; // put more constrained ArrayState matches first so they are matched first. -#endif -} - -std::set supportedDefines(const vsg::ShaderSet& shaderSet) -{ - std::set defines; - - for(auto& ab : shaderSet.attributeBindings) - { - if (!ab.define.empty()) defines.insert(ab.define); - } - - for(auto& ub : shaderSet.descriptorBindings) - { - if (!ub.define.empty()) defines.insert(ub.define); - } - - for(auto& pcr : shaderSet.pushConstantRanges) - { - if (!pcr.define.empty()) defines.insert(pcr.define); - } - - for(auto& define : shaderSet.optionalDefines) - { - defines.insert(define); - } - - return defines; -} - -int main(int argc, char** argv) -{ - // use the vsg::Options object to pass the ReaderWriter_all to use when reading files. - auto options = vsg::Options::create(); -#ifdef vsgXchange_FOUND - options->add(vsgXchange::all::create()); -#endif - options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); - options->sharedObjects = vsg::SharedObjects::create(); - - // set up defaults and read command line arguments to override them - vsg::CommandLine arguments(&argc, argv); - - // read any command line options that the ReaderWriters support - arguments.read(options); - if (argc <= 1) return 0; - - auto inputFilename = arguments.value("", "-i"); - auto outputFilename = arguments.value("", "-o"); - bool binary = arguments.read("--binary"); - bool vsgShaderSet = arguments.read("--vsg"); - bool stripShaderSetBeforeWrite = arguments.read({"-s", "--strip"}); - bool compileShaders = !arguments.read({"--nc","--no-compile"}); - - vsg::ref_ptr shaderSet; - if (inputFilename) - { - shaderSet = vsg::read_cast(inputFilename, options); - } - - if (arguments.read("--text")) - { - if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createTextShaderSet(options) : text_ShaderSet(options); - options->shaderSets["text"] = shaderSet; - } - - if (arguments.read("--flat")) - { - if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createFlatShadedShaderSet(options) : flat_ShaderSet(options); - options->shaderSets["flat"] = shaderSet; - } - if (arguments.read("--phong")) - { - if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createPhongShaderSet(options) : phong_ShaderSet(options); - options->shaderSets["phong"] = shaderSet; - } - - if (arguments.read("--pbr")) - { - if (!shaderSet) shaderSet = vsgShaderSet ? vsg::createPhysicsBasedRenderingShaderSet(options) : pbr_ShaderSet(options); - options->shaderSets["pbr"] = shaderSet; - } - - std::cout<<"shaderSet = "<> s; - if (!s.empty()) - { - if (defines.count(s)==0) - { - std::cout<<"variant define [ "<defines.insert(s); - } - } - - // assign the variant - shaderSet->getShaderStages(scs); - - std::cout<> existing_stages; - - auto shaderCompiler = vsg::ShaderCompiler::create(); - if (shaderCompiler->supported()) - { - std::cout<<"\ncompiling shaderSet->variants.size() = "<variants.size()<variants) - { - std::cout<<" "<defines) std::cout<module->code.empty() && !stage->module->source.empty()) ++numShadersWithSource; - } - - // no need to compile so skip compilation - if (numShadersWithSource == stagesToCompile.size()) - { - shaderCompiler->compile(stagesToCompile, {}, options); - } - - for(auto& stage : stagesToCompile) - { - stage->module->source.clear(); - } - - for(auto& stage : stagesToCompile) - { - vsg::ref_ptr match; - for(auto& existing_stage : existing_stages) - { - bool module_matched = stage->module->code == existing_stage->module->code; - if (module_matched) - { - // share the matched ShaderModule - stage->module = existing_stage->module; - - if (vsg::compare_pointer(stage, existing_stage)==0) - { - match = existing_stage; - } - break; - } - } - if (match) - { - // share the whole ShaderStage - stage = match; - } - else - { - existing_stages.push_back(stage); - } - } - - std::cout<module<<" "<module->code.size()<stages.clear(); - shaderSet->attributeBindings.clear(); - shaderSet->descriptorBindings.clear(); - shaderSet->pushConstantRanges.clear(); - shaderSet->definesArrayStates.clear(); - shaderSet->optionalDefines.clear(); - shaderSet->defaultGraphicsPipelineStates.clear(); - } - - if (outputFilename) - { - if (binary) options->extensionHint = ".vsgb"; - vsg::write(shaderSet, outputFilename, options); - } - - return 0; -} From 547e0e99544047d3a60c7413e80d6c3027320570 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Nov 2023 13:46:46 +0000 Subject: [PATCH 08/21] Implement test of providing the ColorModulation paramaters via root StateGroup. --- data/shaders/custom_pbr.frag | 6 ++-- .../utils/vsgcustomshaderset/custom_pbr.cpp | 10 ++++-- .../vsgcustomshaderset/vsgcustomshaderset.cpp | 34 +++++++++++-------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 7dccf866..152ded18 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -8,9 +8,9 @@ const float RECIPROCAL_PI2 = 0.15915494; const float EPSILON = 1e-6; const float c_MinRoughness = 0.04; -#define VIEW_DESCRIPTOR_SET 0 -#define MATERIAL_DESCRIPTOR_SET 1 -#define CUSTOM_DESCRIPTOR_SET 4 +#define VIEW_DESCRIPTOR_SET 1 +#define MATERIAL_DESCRIPTOR_SET 2 +#define CUSTOM_DESCRIPTOR_SET 0 #ifdef VSG_DIFFUSE_MAP layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index b6491787..3e6440de 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -31,9 +31,9 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti return {}; } - #define VIEW_DESCRIPTOR_SET 0 - #define MATERIAL_DESCRIPTOR_SET 1 - #define CUSTOM_DESCRIPTOR_SET 4 + #define VIEW_DESCRIPTOR_SET 1 + #define MATERIAL_DESCRIPTOR_SET 2 + #define CUSTOM_DESCRIPTOR_SET 0 auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); @@ -57,7 +57,11 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); +#if 0 shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(1.0, 1.0, 0.0, 1.0)); +#else + shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, {}); +#endif // additional defines shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 32c8231e..72dd3937 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -53,17 +53,28 @@ int main(int argc, char** argv) vsg::write(shaderSet, outputShaderSetFilename, options); } - auto group = vsg::StateGroup::create(); + auto vsg_scene = vsg::StateGroup::create(); if (inheritState) { - uint32_t set = 0; - auto layout = shaderSet->createPipelineLayout({}); - auto bvds = vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, set); - group->add(bvds); + auto layout = shaderSet->createPipelineLayout({}, {0, 2}); - options->setObject("inherited", bvds); + uint32_t vds_set = 1; + vsg_scene->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); - vsg::info("Added ", bvds, " to root node."); + uint32_t cm_set = 0; + auto colorModifier = vsg::vec4Value::create(1.0, 0.0, 1.0, 1.0); + auto cm_dsl = shaderSet->createDescriptorSetLayout({}, cm_set); + auto cm_db = vsg::DescriptorBuffer::create(colorModifier); + auto cm_ds = vsg::DescriptorSet::create(cm_dsl, vsg::Descriptors{cm_db}); + auto cm_bds = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, cm_ds); + vsg_scene->add(cm_bds); + + vsg::info("Added state to inherit "); + + for(auto& sc : vsg_scene->stateCommands) + { + vsg::info(" ", sc); + } } vsg::Path path; @@ -74,7 +85,7 @@ int main(int argc, char** argv) vsg::Path filename = arguments[i]; if (auto node = vsg::read_cast(filename, options)) { - group->addChild(node); + vsg_scene->addChild(node); } else { @@ -82,16 +93,11 @@ int main(int argc, char** argv) } } - if (group->children.empty()) + if (vsg_scene->children.empty()) { return 1; } - vsg::ref_ptr vsg_scene; - if (group->children.size() == 1) - vsg_scene = group->children[0]; - else - vsg_scene = group; if (outputFilename) { From 8ef72c54cf7d594cd98ae59ed11825f7dd604332 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 3 Nov 2023 14:17:18 +0000 Subject: [PATCH 09/21] Added --samples and --d32 command line options --- examples/nodes/vsgshadow/vsgshadow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/nodes/vsgshadow/vsgshadow.cpp b/examples/nodes/vsgshadow/vsgshadow.cpp index 6c323dca..a2304c5b 100644 --- a/examples/nodes/vsgshadow/vsgshadow.cpp +++ b/examples/nodes/vsgshadow/vsgshadow.cpp @@ -159,6 +159,8 @@ int main(int argc, char** argv) if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true; if (arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height)) { windowTraits->fullscreen = false; } if (arguments.read("--IMMEDIATE")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + if (arguments.read("--d32")) windowTraits->depthFormat = VK_FORMAT_D32_SFLOAT; + arguments.read("--samples", windowTraits->samples); if (arguments.read({"-t", "--test"})) { windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; From 4945201e2fdd4772eee5fbfa41397736e1477b3c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 4 Nov 2023 17:08:59 +0000 Subject: [PATCH 10/21] Fixed setup of ViewDependentState related bindings --- examples/utils/vsgcustomshaderset/custom_pbr.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index 3e6440de..51c6c3ef 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -54,10 +54,11 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); - shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); -#if 0 +#if 1 shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(1.0, 1.0, 0.0, 1.0)); #else shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, {}); From 0efa526ac20d418dc636cf948a6a8de6c6da4989 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 4 Nov 2023 17:09:22 +0000 Subject: [PATCH 11/21] Added passing of the root StateGroup's state onto the loader via vsg::Options "inherited" entry. --- examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 72dd3937..246f0d9c 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -71,8 +71,12 @@ int main(int argc, char** argv) vsg::info("Added state to inherit "); + auto objects = vsg::Objects::create(); + options->setObject("inherited", objects); + for(auto& sc : vsg_scene->stateCommands) { + objects->addChild(sc); vsg::info(" ", sc); } } From 1569117dc32df1d751105a69f011ac182131b9e8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Nov 2023 17:02:07 +0000 Subject: [PATCH 12/21] Changed to using #define's for setting the DescriptorSet set to use --- examples/utils/vsgshaderset/flat.cpp | 7 +++++++ examples/utils/vsgshaderset/pbr.cpp | 26 +++++++++++++++----------- examples/utils/vsgshaderset/phong.cpp | 24 +++++++++++++++--------- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/examples/utils/vsgshaderset/flat.cpp b/examples/utils/vsgshaderset/flat.cpp index b9b80eab..1027e28a 100644 --- a/examples/utils/vsgshaderset/flat.cpp +++ b/examples/utils/vsgshaderset/flat.cpp @@ -37,6 +37,9 @@ vsg::ref_ptr flat_ShaderSet(vsg::ref_ptr opt return {}; } + #define VIEW_DESCRIPTOR_SET 0 + #define MATERIAL_DESCRIPTOR_SET 1 + auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); @@ -51,6 +54,10 @@ vsg::ref_ptr flat_ShaderSet(vsg::ref_ptr opt shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); shaderSet->addDescriptorBinding("material", "", 0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create()); + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); + shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128); shaderSet->optionalDefines = {"VSG_POINT_SPRITE", "VSG_GREYSCALE_DIFFUSE_MAP"}; diff --git a/examples/utils/vsgshaderset/pbr.cpp b/examples/utils/vsgshaderset/pbr.cpp index 6818bd4b..5a631849 100644 --- a/examples/utils/vsgshaderset/pbr.cpp +++ b/examples/utils/vsgshaderset/pbr.cpp @@ -33,6 +33,9 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); + #define VIEW_DESCRIPTOR_SET 0 + #define MATERIAL_DESCRIPTOR_SET 1 + shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_TexCoord0", "", 2, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Array::create(1)); @@ -41,17 +44,18 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addAttributeBinding("vsg_position", "VSG_INSTANCE_POSITIONS", 4, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_position_scaleDistance", "VSG_BILLBOARD", 4, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); - shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", 0, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", 0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); - shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", 0, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); - shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", 0, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", 0, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", 0, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("material", "", 0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); - - shaderSet->addDescriptorBinding("lightData", "", 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); - shaderSet->addDescriptorBinding("shadowMaps", "", 1, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", MATERIAL_DESCRIPTOR_SET, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", MATERIAL_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); + shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", MATERIAL_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); + shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); // additional defines shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; diff --git a/examples/utils/vsgshaderset/phong.cpp b/examples/utils/vsgshaderset/phong.cpp index bb70ba70..330b6eba 100644 --- a/examples/utils/vsgshaderset/phong.cpp +++ b/examples/utils/vsgshaderset/phong.cpp @@ -30,6 +30,9 @@ vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr op return {}; } + #define VIEW_DESCRIPTOR_SET 0 + #define MATERIAL_DESCRIPTOR_SET 1 + auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); @@ -40,15 +43,18 @@ vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr op shaderSet->addAttributeBinding("vsg_position", "VSG_INSTANCE_POSITIONS", 4, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); shaderSet->addAttributeBinding("vsg_position_scaleDistance", "VSG_BILLBOARD", 4, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); - shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", 0, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", 0, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); - shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", 0, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", 0, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("material", "", 0, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create()); - - shaderSet->addDescriptorBinding("lightData", "", 1, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); - shaderSet->addDescriptorBinding("shadowMaps", "", 1, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", MATERIAL_DESCRIPTOR_SET, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", MATERIAL_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); + shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", MATERIAL_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); + shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128); From e470615db64ab57d88c4aea2b5c1d798140ff10f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 6 Nov 2023 17:47:16 +0000 Subject: [PATCH 13/21] Adopted use of Options::inhertiedState --- .../utils/vsgcustomshaderset/vsgcustomshaderset.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 246f0d9c..6bf2fe92 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -70,15 +70,7 @@ int main(int argc, char** argv) vsg_scene->add(cm_bds); vsg::info("Added state to inherit "); - - auto objects = vsg::Objects::create(); - options->setObject("inherited", objects); - - for(auto& sc : vsg_scene->stateCommands) - { - objects->addChild(sc); - vsg::info(" ", sc); - } + options->inheritedState = vsg_scene->stateCommands; } vsg::Path path; From b2278b9dc3377a17e55cbd7ead97acd673425445 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 7 Nov 2023 18:06:40 +0000 Subject: [PATCH 14/21] Added --inherit support to test the vsg::Builder new Options::inheritedState support. --- examples/utils/vsgbuilder/vsgbuilder.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/examples/utils/vsgbuilder/vsgbuilder.cpp b/examples/utils/vsgbuilder/vsgbuilder.cpp index 83774a93..184aa18b 100644 --- a/examples/utils/vsgbuilder/vsgbuilder.cpp +++ b/examples/utils/vsgbuilder/vsgbuilder.cpp @@ -93,6 +93,7 @@ int main(int argc, char** argv) bool sphere = arguments.read("--sphere"); bool heightfield = arguments.read("--hf"); bool billboard = arguments.read("--billboard"); + bool inherit = arguments.read("--inherit"); if (!(box || sphere || cone || capsule || quad || cylinder || disk || heightfield)) { @@ -198,9 +199,22 @@ int main(int argc, char** argv) if (box) { - scene->addChild(builder->createBox(geomInfo, stateInfo)); - bound.add(geomInfo.position); - geomInfo.position += geomInfo.dx * 1.5f; + auto node = builder->createBox(geomInfo, stateInfo); + auto sg = node.cast(); + + if (sg && inherit) + { + options->inheritedState = sg->stateCommands; + scene = sg; + vsg::info("assigned = ", options->inheritedState.size()); + } + else + { + scene->addChild(node); + bound.add(geomInfo.position); + geomInfo.position += geomInfo.dx * 1.5f; + + } } if (sphere) From 142d11ebfd7b502a5239e82779bc72f2621f55d0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 9 Nov 2023 17:44:51 +0000 Subject: [PATCH 15/21] Standaized --inherit implementation --- examples/nodes/vsgshadow/vsgshadow.cpp | 25 ++++++++++++++++++- examples/utils/vsgbuilder/vsgbuilder.cpp | 9 ++++--- .../vsgcustomshaderset/vsgcustomshaderset.cpp | 4 +-- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/examples/nodes/vsgshadow/vsgshadow.cpp b/examples/nodes/vsgshadow/vsgshadow.cpp index a2304c5b..fc530693 100644 --- a/examples/nodes/vsgshadow/vsgshadow.cpp +++ b/examples/nodes/vsgshadow/vsgshadow.cpp @@ -295,12 +295,28 @@ int main(int argc, char** argv) } } - auto direction = arguments.value(vsg::dvec3(0.0, 0.0, -1.0), "--direction"); auto insertCullNode = arguments.read("--cull"); + auto inherit = arguments.read("--inherit"); + auto direction = arguments.value(vsg::dvec3(0.0, 0.0, -1.0), "--direction"); auto location = arguments.value({0.0, 0.0, 0.0}, "--location"); auto scale = arguments.value(1.0, "--scale"); double viewingDistance = scale; + vsg::ref_ptr stateGroup; + if (inherit) + { + auto shaderSet = vsg::createPhongShaderSet(options); + auto layout = shaderSet->createPipelineLayout({}, {0, 1}); + + stateGroup = vsg::StateGroup::create(); + + uint32_t vds_set = 0; + stateGroup->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); + + vsg::info("Added state to inherit "); + options->inheritedState = stateGroup->stateCommands; + } + vsg::ref_ptr scene; if (arguments.read("--large")) { @@ -323,6 +339,13 @@ int main(int argc, char** argv) scene = createTestScene(options, textureFile, requiresBase, insertCullNode); } + if (stateGroup) + { + // if setup place the StateGroup at the root of the scene graph + stateGroup->addChild(scene); + scene = stateGroup; + } + // compute the bounds of the scene graph to help position camera auto bounds = vsg::visit(scene).bounds; viewingDistance = vsg::length(bounds.max - bounds.min) * 2.0; diff --git a/examples/utils/vsgbuilder/vsgbuilder.cpp b/examples/utils/vsgbuilder/vsgbuilder.cpp index 184aa18b..e55f01ca 100644 --- a/examples/utils/vsgbuilder/vsgbuilder.cpp +++ b/examples/utils/vsgbuilder/vsgbuilder.cpp @@ -178,6 +178,7 @@ int main(int argc, char** argv) { if (floatColors) { + stateInfo.instance_colors_vec4 = true; auto colors = vsg::vec4Array::create(numVertices); geomInfo.colors = colors; for (auto& c : *(colors)) @@ -187,6 +188,7 @@ int main(int argc, char** argv) } else { + stateInfo.instance_colors_vec4 = false; auto colors = vsg::ubvec4Array::create(numVertices); geomInfo.colors = colors; for (auto& c : *(colors)) @@ -200,9 +202,10 @@ int main(int argc, char** argv) if (box) { auto node = builder->createBox(geomInfo, stateInfo); - auto sg = node.cast(); + bound.add(geomInfo.position); + geomInfo.position += geomInfo.dx * 1.5f; - if (sg && inherit) + if (auto sg = node.cast(); sg && inherit) { options->inheritedState = sg->stateCommands; scene = sg; @@ -211,8 +214,6 @@ int main(int argc, char** argv) else { scene->addChild(node); - bound.add(geomInfo.position); - geomInfo.position += geomInfo.dx * 1.5f; } } diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 6bf2fe92..61cf5de9 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -36,7 +36,7 @@ int main(int argc, char** argv) auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); bool reportAverageFrameRate = arguments.read("--fps"); - bool inheritState = arguments.read("--inherit"); + bool inherit = arguments.read("--inherit"); vsg::ref_ptr shaderSet = pbr_ShaderSet(options); options->shaderSets["pbr"] = shaderSet; @@ -54,7 +54,7 @@ int main(int argc, char** argv) } auto vsg_scene = vsg::StateGroup::create(); - if (inheritState) + if (inherit) { auto layout = shaderSet->createPipelineLayout({}, {0, 2}); From d7e0df51b05c5b6fdf619f91714a5d31a32240a1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 9 Nov 2023 17:45:38 +0000 Subject: [PATCH 16/21] Updated pbr, phong and flat shadeed ShaderSets and their shaders to use new DescriptorSet layot with view dependent state on set = 0. and materials on set = 1. --- data/shaders/custom_pbr.frag | 8 ++++---- data/shaders/standard_flat_shaded.frag | 18 ++++++++++-------- data/shaders/standard_pbr.frag | 22 +++++++++++++--------- data/shaders/standard_phong.frag | 19 +++++++++++-------- examples/utils/vsgshaderset/pbr.cpp | 2 +- examples/utils/vsgshaderset/phong.cpp | 2 +- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 152ded18..93e4a2b1 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -2,16 +2,16 @@ #extension GL_ARB_separate_shader_objects : enable #pragma import_defines (VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, SHADOWMAP_DEBUG) +#define VIEW_DESCRIPTOR_SET 1 +#define MATERIAL_DESCRIPTOR_SET 2 +#define CUSTOM_DESCRIPTOR_SET 0 + const float PI = 3.14159265359; const float RECIPROCAL_PI = 0.31830988618; const float RECIPROCAL_PI2 = 0.15915494; const float EPSILON = 1e-6; const float c_MinRoughness = 0.04; -#define VIEW_DESCRIPTOR_SET 1 -#define MATERIAL_DESCRIPTOR_SET 2 -#define CUSTOM_DESCRIPTOR_SET 0 - #ifdef VSG_DIFFUSE_MAP layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; #endif diff --git a/data/shaders/standard_flat_shaded.frag b/data/shaders/standard_flat_shaded.frag index 5a7dda76..cc83d412 100644 --- a/data/shaders/standard_flat_shaded.frag +++ b/data/shaders/standard_flat_shaded.frag @@ -2,17 +2,14 @@ #extension GL_ARB_separate_shader_objects : enable #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP) -#ifdef VSG_DIFFUSE_MAP -layout(binding = 0) uniform sampler2D diffuseMap; -#endif - -layout(location = 2) in vec4 vertexColor; +#define VIEW_DESCRIPTOR_SET 0 +#define MATERIAL_DESCRIPTOR_SET 1 -#ifndef VSG_POINT_SPRITE -layout(location = 3) in vec2 texCoord0; +#ifdef VSG_DIFFUSE_MAP +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; #endif -layout(binding = 10) uniform MaterialData +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData { vec4 ambientColor; vec4 diffuseColor; @@ -23,6 +20,11 @@ layout(binding = 10) uniform MaterialData float alphaMaskCutoff; } material; +layout(location = 2) in vec4 vertexColor; +#ifndef VSG_POINT_SPRITE +layout(location = 3) in vec2 texCoord0; +#endif + layout(location = 0) out vec4 outColor; void main() diff --git a/data/shaders/standard_pbr.frag b/data/shaders/standard_pbr.frag index 2ee88610..b0a8475d 100644 --- a/data/shaders/standard_pbr.frag +++ b/data/shaders/standard_pbr.frag @@ -2,6 +2,9 @@ #extension GL_ARB_separate_shader_objects : enable #pragma import_defines (VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, SHADOWMAP_DEBUG) +#define VIEW_DESCRIPTOR_SET 0 +#define MATERIAL_DESCRIPTOR_SET 1 + const float PI = 3.14159265359; const float RECIPROCAL_PI = 0.31830988618; const float RECIPROCAL_PI2 = 0.15915494; @@ -9,30 +12,30 @@ const float EPSILON = 1e-6; const float c_MinRoughness = 0.04; #ifdef VSG_DIFFUSE_MAP -layout(binding = 0) uniform sampler2D diffuseMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; #endif #ifdef VSG_METALLROUGHNESS_MAP -layout(binding = 1) uniform sampler2D mrMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 1) uniform sampler2D mrMap; #endif #ifdef VSG_NORMAL_MAP -layout(binding = 2) uniform sampler2D normalMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 2) uniform sampler2D normalMap; #endif #ifdef VSG_LIGHTMAP_MAP -layout(binding = 3) uniform sampler2D aoMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 3) uniform sampler2D aoMap; #endif #ifdef VSG_EMISSIVE_MAP -layout(binding = 4) uniform sampler2D emissiveMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap; #endif #ifdef VSG_SPECULAR_MAP -layout(binding = 5) uniform sampler2D specularMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap; #endif -layout(binding = 10) uniform PbrData +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform PbrData { vec4 baseColorFactor; vec4 emissiveFactor; @@ -44,12 +47,13 @@ layout(binding = 10) uniform PbrData float alphaMaskCutoff; } pbr; -layout(set = 1, binding = 0) uniform LightData +// ViewDependentState +layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData { vec4 values[2048]; } lightData; -layout(set = 1, binding = 2) uniform sampler2DArrayShadow shadowMaps; +layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; diff --git a/data/shaders/standard_phong.frag b/data/shaders/standard_phong.frag index 59b8c52f..901bda6e 100644 --- a/data/shaders/standard_phong.frag +++ b/data/shaders/standard_phong.frag @@ -2,27 +2,30 @@ #extension GL_ARB_separate_shader_objects : enable #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, SHADOWMAP_DEBUG) +#define VIEW_DESCRIPTOR_SET 0 +#define MATERIAL_DESCRIPTOR_SET 1 + #ifdef VSG_DIFFUSE_MAP -layout(set = 0, binding = 0) uniform sampler2D diffuseMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; #endif #ifdef VSG_NORMAL_MAP -layout(set = 0, binding = 2) uniform sampler2D normalMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 2) uniform sampler2D normalMap; #endif #ifdef VSG_LIGHTMAP_MAP -layout(set = 0, binding = 3) uniform sampler2D aoMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 3) uniform sampler2D aoMap; #endif #ifdef VSG_EMISSIVE_MAP -layout(set = 0, binding = 4) uniform sampler2D emissiveMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap; #endif #ifdef VSG_SPECULAR_MAP -layout(set = 0, binding = 5) uniform sampler2D specularMap; +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap; #endif -layout(set = 0, binding = 10) uniform MaterialData +layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData { vec4 ambientColor; vec4 diffuseColor; @@ -33,13 +36,13 @@ layout(set = 0, binding = 10) uniform MaterialData float alphaMaskCutoff; } material; -layout(set = 1, binding = 0) uniform LightData +layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData { vec4 values[2048]; } lightData; -layout(set = 1, binding = 2) uniform sampler2DArrayShadow shadowMaps; +layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; diff --git a/examples/utils/vsgshaderset/pbr.cpp b/examples/utils/vsgshaderset/pbr.cpp index 5a631849..08af12ae 100644 --- a/examples/utils/vsgshaderset/pbr.cpp +++ b/examples/utils/vsgshaderset/pbr.cpp @@ -67,7 +67,7 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_DISPLACEMENT_MAP"}, vsg::DisplacementMapArrayState::create()}); shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_BILLBOARD"}, vsg::BillboardArrayState::create()}); - shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(1)); + shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); return shaderSet; } diff --git a/examples/utils/vsgshaderset/phong.cpp b/examples/utils/vsgshaderset/phong.cpp index 330b6eba..ceaa370e 100644 --- a/examples/utils/vsgshaderset/phong.cpp +++ b/examples/utils/vsgshaderset/phong.cpp @@ -65,7 +65,7 @@ vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr op shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_DISPLACEMENT_MAP"}, vsg::DisplacementMapArrayState::create()}); shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_BILLBOARD"}, vsg::BillboardArrayState::create()}); - shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(1)); + shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); return shaderSet; } From 73fc1cf772875c2772cc57fb782b13e19f62e955 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Nov 2023 15:22:39 +0000 Subject: [PATCH 17/21] Fixed Phong ShaderSet setup --- examples/utils/vsgshaderset/phong.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/utils/vsgshaderset/phong.cpp b/examples/utils/vsgshaderset/phong.cpp index ceaa370e..2e5073f0 100644 --- a/examples/utils/vsgshaderset/phong.cpp +++ b/examples/utils/vsgshaderset/phong.cpp @@ -45,12 +45,10 @@ vsg::ref_ptr phong_ShaderSet(vsg::ref_ptr op shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", MATERIAL_DESCRIPTOR_SET, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", MATERIAL_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", MATERIAL_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); - shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); - shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); - shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create()); shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); From 0c34e61dac214821f18d73b01ece1115af056c72 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 10 Nov 2023 18:46:21 +0000 Subject: [PATCH 18/21] Removed debug message --- examples/utils/vsgbuilder/vsgbuilder.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/utils/vsgbuilder/vsgbuilder.cpp b/examples/utils/vsgbuilder/vsgbuilder.cpp index e55f01ca..0ecb188d 100644 --- a/examples/utils/vsgbuilder/vsgbuilder.cpp +++ b/examples/utils/vsgbuilder/vsgbuilder.cpp @@ -209,7 +209,6 @@ int main(int argc, char** argv) { options->inheritedState = sg->stateCommands; scene = sg; - vsg::info("assigned = ", options->inheritedState.size()); } else { From adcbfc39040832709884b85c9ec6b8831d5d56b5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2023 11:09:00 +0000 Subject: [PATCH 19/21] Introduced a Fog structure to provide a more instructive example of extendeding state/shders along with serialization support --- data/shaders/custom_pbr.frag | 12 ++++++++---- examples/utils/vsgcustomshaderset/custom_pbr.cpp | 8 ++++++-- .../utils/vsgcustomshaderset/vsgcustomshaderset.cpp | 12 +++++++----- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 93e4a2b1..798890f1 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -57,10 +57,14 @@ layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; // Custom state -layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform ColorModulation +layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform Fog { - vec4 value; -} colorModulation; + vec3 color; + float density; + float start; + float end; + float exponent; +} fog; layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; @@ -530,5 +534,5 @@ void main() } } - outColor = LINEARtoSRGB(vec4(color, baseColor.a)) * colorModulation.value; + outColor = LINEARtoSRGB(vec4(color * fog.color, baseColor.a)) ; } diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index 51c6c3ef..07f5de0f 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -18,7 +18,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #include #include -vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options) +#include "custom_pbr.h" + +vsg::RegisterWithObjectFactoryProxy s_Register_FogValue; + +vsg::ref_ptr custom::pbr_ShaderSet(vsg::ref_ptr options) { vsg::info("Local pbr_ShaderSet(",options,")"); @@ -59,7 +63,7 @@ vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr opti shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); #if 1 - shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(1.0, 1.0, 0.0, 1.0)); + shaderSet->addDescriptorBinding("Fog", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, custom::FogValue::create()); #else shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, {}); #endif diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 61cf5de9..6a774e77 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -5,8 +5,7 @@ # include #endif -extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); - +#include "custom_pbr.h" int main(int argc, char** argv) { @@ -38,7 +37,7 @@ int main(int argc, char** argv) bool reportAverageFrameRate = arguments.read("--fps"); bool inherit = arguments.read("--inherit"); - vsg::ref_ptr shaderSet = pbr_ShaderSet(options); + vsg::ref_ptr shaderSet = custom::pbr_ShaderSet(options); options->shaderSets["pbr"] = shaderSet; std::cout<<"shaderSet = "< fog; + auto vsg_scene = vsg::StateGroup::create(); if (inherit) { @@ -62,9 +63,10 @@ int main(int argc, char** argv) vsg_scene->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); uint32_t cm_set = 0; - auto colorModifier = vsg::vec4Value::create(1.0, 0.0, 1.0, 1.0); + fog = custom::FogValue::create(); + fog->value().color.set(1.0, 1.0, 0.0); auto cm_dsl = shaderSet->createDescriptorSetLayout({}, cm_set); - auto cm_db = vsg::DescriptorBuffer::create(colorModifier); + auto cm_db = vsg::DescriptorBuffer::create(fog); auto cm_ds = vsg::DescriptorSet::create(cm_dsl, vsg::Descriptors{cm_db}); auto cm_bds = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, cm_ds); vsg_scene->add(cm_bds); From fbf771eb33e7232eb3fb6fc3ce3d6810a1ae5789 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2023 14:10:24 +0000 Subject: [PATCH 20/21] Added exponential fog --- data/shaders/custom_pbr.frag | 27 +++++++++++++- .../utils/vsgcustomshaderset/custom_pbr.cpp | 4 --- .../vsgcustomshaderset/vsgcustomshaderset.cpp | 35 +++++++++++++++---- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 798890f1..5e8c7bf3 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -534,5 +534,30 @@ void main() } } - outColor = LINEARtoSRGB(vec4(color * fog.color, baseColor.a)) ; + if (fog.exponent != 0.0) + { + float fogCoord = -eyePos.z; + const float e = 2.71828; + float f = pow(e, -fog.density * pow(fogCoord, fog.exponent)); + color = mix(fog.color, color, f); + } + else + { + // linear + float fogCoord = -eyePos.z; + if (fogCoord > fog.start) + { + if (fogCoord < fog.end) + { + float f = (fog.end - fogCoord) / (fog.end - fog.start); + color = mix(fog.color, color, f); + } + else + { + color = fog.color; + } + } + } + + outColor = LINEARtoSRGB(vec4(color, baseColor.a)) ; } diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.cpp b/examples/utils/vsgcustomshaderset/custom_pbr.cpp index 07f5de0f..679cf83d 100644 --- a/examples/utils/vsgcustomshaderset/custom_pbr.cpp +++ b/examples/utils/vsgcustomshaderset/custom_pbr.cpp @@ -62,11 +62,7 @@ vsg::ref_ptr custom::pbr_ShaderSet(vsg::ref_ptraddDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0,0, 1280, 1024)); shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); -#if 1 shaderSet->addDescriptorBinding("Fog", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, custom::FogValue::create()); -#else - shaderSet->addDescriptorBinding("ColorModulation", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, {}); -#endif // additional defines shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; diff --git a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp index 6a774e77..0280aeb6 100644 --- a/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp +++ b/examples/utils/vsgcustomshaderset/vsgcustomshaderset.cpp @@ -39,34 +39,53 @@ int main(int argc, char** argv) vsg::ref_ptr shaderSet = custom::pbr_ShaderSet(options); options->shaderSets["pbr"] = shaderSet; - - std::cout<<"shaderSet = "<value(); + fogSet = arguments.read("--color", fog.color) | fogSet; + fogSet = arguments.read("--start", fog.start) | fogSet; + fogSet = arguments.read("--end", fog.end) | fogSet; + fogSet = arguments.read("--exponent", fog.exponent) | fogSet; + fogSet = arguments.read("--density", fog.density) | fogSet; + + if (fogSet && !inherit) + { + // change the default data to the local fogValue we've been assigning values to + auto& fogBinding = shaderSet->getDescriptorBinding("Fog"); + if (fogBinding.name == "Fog") + { + fogBinding.data = fogValue; + vsg::info("Setting default fog to ", fogValue); + } + } + if (outputShaderSetFilename) { vsg::write(shaderSet, outputShaderSetFilename, options); } - vsg::ref_ptr fog; - auto vsg_scene = vsg::StateGroup::create(); if (inherit) { + // + // place the FogValue DescriptorSet at the root of the scene graph + // and tell the loader via vsg::Options::inheritedState that it doesn't need to assign + // it to subgraphs that loader will create + // auto layout = shaderSet->createPipelineLayout({}, {0, 2}); uint32_t vds_set = 1; vsg_scene->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); uint32_t cm_set = 0; - fog = custom::FogValue::create(); - fog->value().color.set(1.0, 1.0, 0.0); auto cm_dsl = shaderSet->createDescriptorSetLayout({}, cm_set); - auto cm_db = vsg::DescriptorBuffer::create(fog); + auto cm_db = vsg::DescriptorBuffer::create(fogValue); auto cm_ds = vsg::DescriptorSet::create(cm_dsl, vsg::Descriptors{cm_db}); auto cm_bds = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, cm_ds); vsg_scene->add(cm_bds); @@ -118,6 +137,8 @@ int main(int argc, char** argv) vsg::dvec3 centre = (bounds.min + bounds.max) * 0.5; double radius = vsg::length(bounds.max - bounds.min) * 0.6; + vsg::info("scene bounds ", bounds); + // set up the camera auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); From 065414ef9168d9de47d01b59f776b5ac769f2a7f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 13 Nov 2023 14:53:27 +0000 Subject: [PATCH 21/21] Added header --- .../utils/vsgcustomshaderset/custom_pbr.h | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 examples/utils/vsgcustomshaderset/custom_pbr.h diff --git a/examples/utils/vsgcustomshaderset/custom_pbr.h b/examples/utils/vsgcustomshaderset/custom_pbr.h new file mode 100644 index 00000000..1b065a7c --- /dev/null +++ b/examples/utils/vsgcustomshaderset/custom_pbr.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +namespace custom +{ + // OpenGL style fog struct to pass to the GPU + struct Fog + { + vsg::vec3 color = {1.0, 1.0, 1.0}; + float density = 0.05; // OpenGL default is 1.0! + float start = 0.0; + float end = 1.0; + float exponent = 1.0; + + void read(vsg::Input& input) + { + input.read("color", color); + input.read("density", density); + input.read("start", start); + input.read("end", end); + input.read("exponent", exponent); + } + + void write(vsg::Output& output) const + { + output.write("color", color); + output.write("density", density); + output.write("start", start); + output.write("end", end); + output.write("exponent", exponent); + } + }; + + using FogValue = vsg::Value; + + extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); +} + +template<> +constexpr bool vsg::has_read_write() { return true; } + +EVSG_type_name(custom::FogValue);