├── .clang-format ├── .gitignore ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── applications ├── CMakeLists.txt └── vsgpoints_example │ ├── CMakeLists.txt │ ├── ConvertMeshToPoints.cpp │ ├── ConvertMeshToPoints.h │ └── vsgpoints_example.cpp ├── data └── shaders │ ├── brick.vert │ ├── brick_flat_shaded.frag │ └── brick_phong.frag ├── include └── vsgPoints │ ├── AsciiPoints.h │ ├── BIN.h │ ├── Brick.h │ ├── BrickShaderSet.h │ ├── Bricks.h │ ├── Export.h │ ├── Settings.h │ └── create.h └── src ├── CMakeLists.txt └── vsgPoints ├── AsciiPoints.cpp ├── BIN.cpp ├── Brick.cpp ├── BrickShaderSet.cpp ├── Bricks.cpp ├── CMakeLists.txt ├── create.cpp ├── shaders ├── brick_flat_shaded_frag.cpp ├── brick_phong_frag.cpp └── brick_vert.cpp └── vsgPointsConfig.cmake.in /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Right 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: true 13 | AllowShortCaseLabelsOnASingleLine: true 14 | AllowShortFunctionsOnASingleLine: InlineOnly 15 | AllowShortIfStatementsOnASingleLine: true 16 | AllowShortLoopsOnASingleLine: true 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: true 25 | AfterControlStatement: true 26 | AfterEnum: true 27 | AfterFunction: true 28 | AfterNamespace: true 29 | AfterObjCDeclaration: true 30 | AfterStruct: true 31 | AfterUnion: true 32 | AfterExternBlock: true 33 | BeforeCatch: true 34 | BeforeElse: true 35 | IndentBraces: false 36 | SplitEmptyFunction: true 37 | SplitEmptyRecord: true 38 | SplitEmptyNamespace: true 39 | BreakBeforeBinaryOperators: None 40 | BreakBeforeBraces: Custom 41 | BreakBeforeInheritanceComma: false 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializersBeforeComma: true 44 | BreakConstructorInitializers: AfterColon 45 | BreakAfterJavaFieldAnnotations: false 46 | BreakStringLiterals: true 47 | ColumnLimit: 0 48 | CommentPragmas: '^ IWYU pragma:' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 4 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: true 58 | ForEachMacros: 59 | - foreach 60 | - Q_FOREACH 61 | - BOOST_FOREACH 62 | IncludeBlocks: Preserve 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: false 72 | IndentPPDirectives: AfterHash 73 | IndentWidth: 4 74 | IndentWrappedFunctionNames: false 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: true 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: All 82 | ObjCBlockIndentWidth: 4 83 | ObjCSpaceAfterProperty: false 84 | ObjCSpaceBeforeProtocolList: true 85 | PenaltyBreakAssignment: 2 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Left 93 | ReflowComments: false 94 | SortIncludes: true 95 | SortUsingDeclarations: true 96 | SpaceAfterCStyleCast: false 97 | SpaceAfterTemplateKeyword: false 98 | SpaceBeforeAssignmentOperators: true 99 | SpaceBeforeParens: ControlStatements 100 | SpaceInEmptyParentheses: false 101 | SpacesBeforeTrailingComments: 1 102 | SpacesInAngles: false 103 | SpacesInContainerLiterals: true 104 | SpacesInCStyleCastParentheses: false 105 | SpacesInParentheses: false 106 | SpacesInSquareBrackets: false 107 | Standard: Cpp11 108 | TabWidth: 8 109 | UseTab: Never 110 | ... 111 | 112 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | cmake_uninstall.cmake 3 | 4 | lib/ 5 | bin/ 6 | 7 | # Autogenerated files 8 | # include/vsgPoints/Version.h 9 | 10 | *.pc 11 | *.conf 12 | *.backup 13 | CMakeCache.txt 14 | CMakeFiles 15 | CMakeScripts 16 | Makefile 17 | cmake_install.cmake 18 | install_manifest.txt 19 | CMakeDoxyfile.in 20 | CMakeDoxygenDefaults.cmake 21 | Doxyfile.docs 22 | Doxyfile.docs-vsgPoints 23 | vsgPointsConfig.cmake 24 | vsgPointsConfigVersion.cmake 25 | 26 | 27 | # Compiled Object files 28 | *.slo 29 | *.lo 30 | *.o 31 | *.obj 32 | 33 | # Precompiled Headers 34 | *.gch 35 | *.pch 36 | 37 | # Compiled Dynamic libraries 38 | *.so 39 | *.dylib 40 | *.dll 41 | 42 | # Fortran module files 43 | *.mod 44 | 45 | # Compiled Static libraries 46 | *.lai 47 | *.la 48 | *.a 49 | *.lib 50 | 51 | # Executables 52 | *.exe 53 | *.out 54 | *.app 55 | 56 | # Visual Studio files 57 | *.sln 58 | *.vcxproj 59 | *.vcxproj.filters 60 | *.vcxproj.user 61 | .vs/ 62 | x64/ 63 | src/vsgPoints/vsgPoints.dir/ 64 | *.pdb 65 | *.tlog 66 | *.log 67 | 68 | # Xcode 69 | DerivedData/ 70 | *.build 71 | *.xcodeproj 72 | 73 | # Gradle 74 | .gradle/ 75 | .idea/ 76 | .externalNativeBuild/ 77 | *.iml 78 | build/ 79 | local.properties 80 | 81 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | project(vsgPoints 4 | VERSION 0.6.0 5 | DESCRIPTION "VulkanSceneGraph Point Cloud rendering." 6 | LANGUAGES CXX 7 | ) 8 | set(VSGPOINTS_SOVERSION 0) 9 | SET(VSGPOINTS_RELEASE_CANDIDATE 0) 10 | 11 | set(VSGPOINTS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Root source directory of vsgPoints") 12 | set(VSGPOINTS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "Root binary directory of vsgPoints") 13 | 14 | # set the use of C++17 globally as all examples require it 15 | set(CMAKE_CXX_STANDARD 17) 16 | 17 | # Find Vulkan and the VSG 18 | if (VULKAN_SDK) 19 | set(ENV{VULKAN_SDK} ${VULKAN_SDK}) 20 | endif() 21 | 22 | find_package(vsg 1.1.4 REQUIRED) 23 | find_package(vsgXchange 1.0.5 REQUIRED) 24 | 25 | vsg_setup_build_vars() 26 | vsg_setup_dir_vars() 27 | 28 | vsg_add_target_clang_format( 29 | FILES 30 | include/vsgPoints/*.h 31 | src/vsgPoints/*.cpp 32 | ) 33 | vsg_add_target_clobber() 34 | vsg_add_target_cppcheck( 35 | FILES 36 | ${CMAKE_SOURCE_DIR}/src/vsgPoints/*.cpp 37 | ${CMAKE_SOURCE_DIR}/include/vsgPoints/*.h 38 | ) 39 | vsg_add_target_docs( 40 | FILES 41 | include 42 | ) 43 | vsg_add_target_uninstall() 44 | 45 | if (${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}) 46 | 47 | vsg_add_option_maintainer( 48 | PREFIX v 49 | RCLEVEL ${VSGPOINTS_RELEASE_CANDIDATE} 50 | ) 51 | 52 | endif() 53 | 54 | # source directories for vsgPoints library 55 | add_subdirectory(src) 56 | add_subdirectory(applications) 57 | 58 | vsg_add_feature_summary() 59 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Robert Osfield 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vsgPoints - VulkanSceneGraph Point Cloud rendering 2 | 3 | Cross platform, open source (MIT license) C++17 library and example set for rendering large point cloud data using VulkanSceneGraph. vsgPoints provides support for generating hierarchical LOD and paged LOD scene graph hierarchies to provide excellent performance and scalability. The support for database paging enables handling of very large point databases - over a billion point datasets run at a solid 60fps even on integrated GPUs. 4 | 5 | To enable efficient use of main and GPU memory, point data is segmented into bricks and the source x, y, z values are quantized to 8bit, 10bit or 16bit values. Using the vsgPoints::Settings structure users can select the precision (default of 1mm) and bit representation they require, the higher precision and lower the brick count the smaller the bricks that will be used. The quantized data is packed into formats supported by graphics hardware enabling the vertex shaders to compute the final positions without any intermediate conversions. 6 | 7 | To enable handling of point data with very large world coordinates, the data is translated to a local origin with a vsg::MatrixTransform used to place the rendered points in their proper world coordinate system. 8 | 9 | The vsgPoints project contains a vsgPoints library that applications may link to if they wish to add point cloud loading and scene graph creation capabilities to their applications, and a vsgpoints_example utility program. 10 | 11 | ## System requirements/constraints 12 | 13 | vsgPoints is usable, but still early in its development. Currently the reading and building of scene graphs is single threaded, and no attempt is made to minimize memory footprint, beyond quantization to 8/10/16bit. During read and scene graph generation of very large datasets you will need sufficient main memory, for billion points datasets you'll need 32GB+ main memory in order to build the scene graph. 14 | 15 | For flat or LOD scene graphs, the GPU memory requirement loosely tracks the size of the scene graph in main memory/on disk so the larger it is, the more likely it will hit limits of available GPU memory. For very large point datasets it will be necessary to generate PagedLOD scene graphs which will result in creation of a hierarchy of PagedLOD nodes and associated files on disk, which can number in millions of files. Paged databases perform very well, reducing the memory requirement substantially and enabling much larger datasets to be viewed at high framerates with the VulkanSceneGraph's multi-threaded database pager seamlessly handling the file loading as well as load balancing. 16 | 17 | The downside with paged databases can be they stress the filesystem/OS more when you want to delete or move the directory hierarchy that has been generated by vsgPoints. In particular Windows can struggle when handling millions of files even on fast solid state disks, in particular if virus scanners are invoked during file operations. 18 | 19 | ## Roadmap 20 | 21 | Possible features for future development: 22 | 23 | * Multi-thread the reading of data and scene graph building, 24 | * Saving intermediate results to avoid overloading main memory when building large point datasets and reduce memory footprint. 25 | * Features like picking would also be nice features to add. 26 | 27 | vsgPoints is open source, if you wish to see features developed then you are welcome to contribute time or funding to help make this happen. 28 | 29 | ## Dependencies 30 | 31 | 3rd party dependencies: 32 | 33 | C++17 34 | CMake 35 | VulkanSDK 36 | GLslang 37 | VulkanSceneGraph 38 | vsgXchange 39 | 40 | ## Building vsgPoints 41 | 42 | Unix in source build: 43 | 44 | cd vsgPoints 45 | cmake . 46 | make -j 8 47 | make install 48 | 49 | # vsgpoints_example application usage 50 | 51 | To view .3dc or .asc point clouds, or .BIN (double x,y,z; uint8_t r, g, b) data : 52 | 53 | ~~~ sh 54 | vsgpoints_example mydata.asc 55 | ~~~~ 56 | 57 | To convert point cloud data to VulkanSceneGraph native format: 58 | 59 | ~~~ sh 60 | vsgpoints_example mydata.BIN -o mydata.vsgb 61 | ~~~~ 62 | 63 | Once you have converted to native .vsgb format you can load the data in any VulkanSceneGraph application: 64 | 65 | ~~~ sh 66 | vsgviewer mydata.vsgb 67 | ~~~ 68 | 69 | vsgpoints_example supports generating scene graphs in three ways, the command line options for these are: 70 | 71 | | command line option | technique | 72 | | --lod | using LOD's (the default) | 73 | | --plod | Generation of paged databases | 74 | | --flat | flat group of point bricks | 75 | 76 | ~~~ sh 77 | # create vsg::LOD scene graph 78 | vsgpoints_example mydata.BIN --lod 79 | # or just rely upon the default being vsg::LOD scene graph 80 | vsgpoints_example mydata.BIN 81 | 82 | # create a flat group of point bricks 83 | vsgpoints_example mydata.BIN --flat 84 | 85 | # create a paged database, requires specification of output file 86 | vsgpoints_example mydata.BIN -o paged.vsgb --plod 87 | ~~~ 88 | 89 | vsgpoints_example also supports generating points from meshed models, which can be enabled with --mesh 90 | 91 | ~~~ sh 92 | # load a mesh model and convert to points as input rather than required loading of points data. 93 | vsgpoints_example mymodel.gltf --mesh 94 | ~~~ 95 | 96 | If you don't include an output filename using ~ -o filename.vsgb ~ then vsgpoints_example will automatically create a viewer to view the created scene graph, but if you output to a file no viewer will be created. If you still want the viewer to appear then add the -v option to force the viewer to be created. 97 | 98 | To alter the precision and point size you can use the -p size_in_metres and --ps multiplier to control the precision (defaults to 0.001) and point size (defaults to 4 x precision). 99 | 100 | ~~~ sh 101 | # choose 5mm precision and ~50mm rendered point size (10 x 0.005) 102 | vsgpoints_example mydata.3dc -p 0.005 --ps 10 103 | ~~~ 104 | -------------------------------------------------------------------------------- /applications/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(vsgpoints_example) 2 | -------------------------------------------------------------------------------- /applications/vsgpoints_example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(SOURCES 2 | ConvertMeshToPoints.cpp 3 | vsgpoints_example.cpp 4 | ) 5 | 6 | add_executable(vsgpoints_example ${SOURCES}) 7 | 8 | target_link_libraries(vsgpoints_example vsg::vsg vsgPoints::vsgPoints) 9 | 10 | if (vsgXchange_FOUND) 11 | target_compile_definitions(vsgpoints_example PRIVATE vsgXchange_FOUND) 12 | target_link_libraries(vsgpoints_example vsgXchange::vsgXchange) 13 | endif() 14 | 15 | install(TARGETS vsgpoints_example RUNTIME DESTINATION bin) 16 | -------------------------------------------------------------------------------- /applications/vsgpoints_example/ConvertMeshToPoints.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "ConvertMeshToPoints.h" 4 | 5 | #include 6 | 7 | ConvertMeshToPoints::ConvertMeshToPoints(vsg::ref_ptr settings) : 8 | bricks(vsgPoints::Bricks::create(settings)) 9 | { 10 | arrayStateStack.reserve(4); 11 | arrayStateStack.emplace_back(vsg::ArrayState::create()); 12 | } 13 | 14 | 15 | void ConvertMeshToPoints::applyDraw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount) 16 | { 17 | auto& arrayState = *arrayStateStack.back(); 18 | uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1; 19 | uint32_t endVertex = firstVertex + vertexCount; 20 | auto matrix = localToWorld(); 21 | 22 | vsg::ubvec4 color(255,255,255,255); 23 | 24 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex) 25 | { 26 | if (auto vertices = arrayState.vertexArray(instanceIndex)) 27 | { 28 | for (uint32_t i = firstVertex; i < endVertex; ++i) 29 | { 30 | bricks->add(matrix * vsg::dvec3(vertices->at(i)), color); 31 | } 32 | } 33 | } 34 | } 35 | 36 | void ConvertMeshToPoints::applyDrawIndexed(uint32_t firstIndex, uint32_t indexCount, uint32_t firstInstance, uint32_t instanceCount) 37 | { 38 | auto& arrayState = *arrayStateStack.back(); 39 | uint32_t lastIndex = instanceCount > 1 ? (firstInstance + instanceCount) : firstInstance + 1; 40 | uint32_t endIndex = firstIndex + indexCount; 41 | auto matrix = localToWorld(); 42 | 43 | vsg::ubvec4 color(255,255,255,255); 44 | 45 | if (ushort_indices) 46 | { 47 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex) 48 | { 49 | if (auto vertices = arrayState.vertexArray(instanceIndex)) 50 | { 51 | for (uint32_t i = firstIndex; i < endIndex; ++i) 52 | { 53 | bricks->add(matrix * vsg::dvec3(vertices->at(ushort_indices->at(i))), color); 54 | } 55 | } 56 | } 57 | } 58 | else if (uint_indices) 59 | { 60 | for (uint32_t instanceIndex = firstInstance; instanceIndex < lastIndex; ++instanceIndex) 61 | { 62 | if (auto vertices = arrayState.vertexArray(instanceIndex)) 63 | { 64 | for (uint32_t i = firstIndex; i < endIndex; ++i) 65 | { 66 | bricks->add(matrix * vsg::dvec3(vertices->at(uint_indices->at(i))), color); 67 | } 68 | } 69 | } 70 | } 71 | } 72 | 73 | void ConvertMeshToPoints::apply(const vsg::Node& node) 74 | { 75 | node.traverse(*this); 76 | } 77 | 78 | void ConvertMeshToPoints::apply(const vsg::StateGroup& stategroup) 79 | { 80 | auto arrayState = stategroup.prototypeArrayState ? stategroup.prototypeArrayState->cloneArrayState(arrayStateStack.back()) : arrayStateStack.back()->cloneArrayState(); 81 | 82 | for (auto& statecommand : stategroup.stateCommands) 83 | { 84 | statecommand->accept(*arrayState); 85 | } 86 | 87 | arrayStateStack.emplace_back(arrayState); 88 | 89 | stategroup.traverse(*this); 90 | 91 | arrayStateStack.pop_back(); 92 | } 93 | 94 | void ConvertMeshToPoints::apply(const vsg::Transform& transform) 95 | { 96 | auto& l2wStack = localToWorldStack(); 97 | 98 | vsg::dmat4 localToWorld = l2wStack.empty() ? transform.transform({}) : transform.transform(l2wStack.back()); 99 | l2wStack.push_back(localToWorld); 100 | 101 | transform.traverse(*this); 102 | 103 | l2wStack.pop_back(); 104 | } 105 | 106 | void ConvertMeshToPoints::apply(const vsg::LOD& lod) 107 | { 108 | if (!lod.children.empty() && lod.children[0].node) lod.children[0].node->accept(*this); 109 | } 110 | 111 | void ConvertMeshToPoints::apply(const vsg::PagedLOD& plod) 112 | { 113 | if (plod.children[0].node) plod.children[0].node->accept(*this); 114 | else if (plod.children[1].node) plod.children[1].node->accept(*this); 115 | } 116 | 117 | void ConvertMeshToPoints::apply(const vsg::VertexDraw& vid) 118 | { 119 | auto& arrayState = *arrayStateStack.back(); 120 | arrayState.apply(vid); 121 | if (!arrayState.vertices) return; 122 | 123 | applyDraw(vid.firstVertex, vid.vertexCount, vid.firstInstance, vid.instanceCount); 124 | } 125 | 126 | void ConvertMeshToPoints::apply(const vsg::VertexIndexDraw& vid) 127 | { 128 | auto& arrayState = *arrayStateStack.back(); 129 | arrayState.apply(vid); 130 | if (!arrayState.vertices) return; 131 | 132 | if (vid.indices) vid.indices->accept(*this); 133 | 134 | applyDrawIndexed(vid.firstIndex, vid.indexCount, vid.firstInstance, vid.instanceCount); 135 | } 136 | 137 | void ConvertMeshToPoints::apply(const vsg::Geometry& geometry) 138 | { 139 | auto& arrayState = *arrayStateStack.back(); 140 | arrayState.apply(geometry); 141 | if (!arrayState.vertices) return; 142 | 143 | if (geometry.indices) geometry.indices->accept(*this); 144 | 145 | for (auto& command : geometry.commands) 146 | { 147 | command->accept(*this); 148 | } 149 | } 150 | 151 | void ConvertMeshToPoints::apply(const vsg::BindVertexBuffers& bvb) 152 | { 153 | arrayStateStack.back()->apply(bvb); 154 | } 155 | 156 | void ConvertMeshToPoints::apply(const vsg::BindIndexBuffer& bib) 157 | { 158 | bib.indices->accept(*this); 159 | } 160 | 161 | void ConvertMeshToPoints::apply(const vsg::BufferInfo& bufferInfo) 162 | { 163 | if (bufferInfo.data) bufferInfo.data->accept(*this); 164 | } 165 | 166 | void ConvertMeshToPoints::apply(const vsg::ushortArray& array) 167 | { 168 | ushort_indices = &array; 169 | uint_indices = nullptr; 170 | } 171 | 172 | void ConvertMeshToPoints::apply(const vsg::uintArray& array) 173 | { 174 | ushort_indices = nullptr; 175 | uint_indices = &array; 176 | } 177 | 178 | void ConvertMeshToPoints::apply(const vsg::Draw& draw) 179 | { 180 | applyDraw(draw.firstVertex, draw.vertexCount, draw.firstInstance, draw.instanceCount); 181 | } 182 | 183 | void ConvertMeshToPoints::apply(const vsg::DrawIndexed& drawIndexed) 184 | { 185 | applyDrawIndexed(drawIndexed.firstIndex, drawIndexed.indexCount, drawIndexed.firstInstance, drawIndexed.instanceCount); 186 | } 187 | -------------------------------------------------------------------------------- /applications/vsgpoints_example/ConvertMeshToPoints.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | class ConvertMeshToPoints : public vsg::Inherit 6 | { 7 | public: 8 | 9 | ConvertMeshToPoints(vsg::ref_ptr settings); 10 | 11 | vsg::ref_ptr bricks = vsgPoints::Bricks::create(); 12 | 13 | using ArrayStateStack = std::vector>; 14 | ArrayStateStack arrayStateStack; 15 | vsg::ref_ptr ushort_indices; 16 | vsg::ref_ptr uint_indices; 17 | 18 | /// get the current local to world matrix stack 19 | std::vector& localToWorldStack() { return arrayStateStack.back()->localToWorldStack; } 20 | vsg::dmat4 localToWorld() const { auto matrixStack = arrayStateStack.back()->localToWorldStack; return matrixStack.empty() ? vsg::dmat4{} : matrixStack.back(); } 21 | 22 | void applyDraw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount); 23 | void applyDrawIndexed(uint32_t firstIndex, uint32_t indexCount, uint32_t firstInstance, uint32_t instanceCount); 24 | 25 | void apply(const vsg::Node& node) override; 26 | void apply(const vsg::StateGroup& stategroup) override; 27 | void apply(const vsg::Transform& transform) override; 28 | void apply(const vsg::LOD& lod) override; 29 | void apply(const vsg::PagedLOD& plod) override; 30 | void apply(const vsg::VertexDraw& vid) override; 31 | void apply(const vsg::VertexIndexDraw& vid) override; 32 | void apply(const vsg::Geometry& geometry) override; 33 | void apply(const vsg::BindVertexBuffers& bvb) override; 34 | void apply(const vsg::BindIndexBuffer& bib) override; 35 | void apply(const vsg::BufferInfo& bufferInfo) override; 36 | void apply(const vsg::ushortArray& array) override; 37 | void apply(const vsg::uintArray& array) override; 38 | void apply(const vsg::Draw& draw) override; 39 | void apply(const vsg::DrawIndexed& drawIndexed) override; 40 | }; 41 | -------------------------------------------------------------------------------- /applications/vsgpoints_example/vsgpoints_example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef vsgXchange_FOUND 4 | # include 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "ConvertMeshToPoints.h" 12 | 13 | #include 14 | #include 15 | 16 | template 17 | std::string format_number(T v) 18 | { 19 | std::vector parts; 20 | do 21 | { 22 | parts.push_back(v % 1000); 23 | v /= 1000; 24 | } while (v > 0); 25 | 26 | std::stringstream s; 27 | auto itr = parts.rbegin(); 28 | s << *(itr++); 29 | while(itr != parts.rend()) 30 | { 31 | s << ','; 32 | s << std::setfill('0') << std::setw(3) << *(itr++); 33 | } 34 | 35 | return s.str(); 36 | } 37 | 38 | int main(int argc, char** argv) 39 | { 40 | // set up defaults and read command line arguments to override them 41 | vsg::CommandLine arguments(&argc, argv); 42 | 43 | auto options = vsg::Options::create(); 44 | options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); 45 | options->sharedObjects = vsg::SharedObjects::create(); 46 | 47 | options->add(vsgPoints::BIN::create()); 48 | options->add(vsgPoints::AsciiPoints::create()); 49 | 50 | #ifdef vsgXchange_all 51 | // add vsgXchange's support for reading and writing 3rd party file formats 52 | options->add(vsgXchange::all::create()); 53 | #endif 54 | 55 | options->readOptions(arguments); 56 | 57 | if (int type; arguments.read("--allocator", type)) vsg::Allocator::instance()->allocatorType = vsg::AllocatorType(type); 58 | if (size_t objectsBlockSize; arguments.read("--objects", objectsBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_OBJECTS, objectsBlockSize); 59 | if (size_t nodesBlockSize; arguments.read("--nodes", nodesBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_NODES, nodesBlockSize); 60 | if (size_t dataBlockSize; arguments.read("--data", dataBlockSize)) vsg::Allocator::instance()->setBlockSize(vsg::ALLOCATOR_AFFINITY_DATA, dataBlockSize); 61 | 62 | auto windowTraits = vsg::WindowTraits::create(); 63 | windowTraits->windowTitle = "vsgpoints"; 64 | windowTraits->debugLayer = arguments.read({"--debug", "-d"}); 65 | windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); 66 | if (arguments.read("--test")) 67 | { 68 | windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; 69 | windowTraits->fullscreen = true; 70 | } 71 | if (arguments.read({"--st", "--small-test"})) 72 | { 73 | windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; 74 | windowTraits->width = 192, windowTraits->height = 108; 75 | windowTraits->decoration = false; 76 | } 77 | 78 | // set up the Settings used to guide how point clouds are setup in the scene graph 79 | auto settings = vsgPoints::Settings::create(); 80 | options->setObject("settings", settings); 81 | settings->options = vsg::Options::create(*options); 82 | 83 | arguments.read("-b", settings->numPointsPerBlock); 84 | arguments.read("-p", settings->precision); 85 | arguments.read("-t", settings->transition); 86 | arguments.read("--ps", settings->pointSize); 87 | arguments.read("--bits", settings->bits); 88 | auto maxPagedLOD = arguments.value(0, "--maxPagedLOD"); 89 | bool convert_mesh = arguments.read("--mesh"); 90 | bool add_model = !arguments.read("--no-model"); 91 | 92 | if (arguments.read("--plod")) settings->createType = vsgPoints::CREATE_PAGEDLOD; 93 | else if (arguments.read("--lod")) settings->createType = vsgPoints::CREATE_LOD; 94 | else if (arguments.read("--flat")) settings->createType = vsgPoints::CREATE_FLAT; 95 | 96 | bool writeOnly = false; 97 | auto outputFilename = arguments.value("", "-o"); 98 | if (outputFilename) 99 | { 100 | settings->path = vsg::filePath(outputFilename)/vsg::simpleFilename(outputFilename); 101 | settings->extension = vsg::fileExtension(outputFilename); 102 | writeOnly = !arguments.read({"-v", "--viewer"}); 103 | } 104 | else 105 | { 106 | if (settings->createType == vsgPoints::CREATE_PAGEDLOD) 107 | { 108 | std::cout<<"PagedLOD generation not possible without output filename. Please specify ouput filename using: -o filename.vsgb"<(vsg::clock::now() - before_read).count(); 122 | std::cout<<"Time to read points = "<()) 125 | { 126 | if (convert_mesh) 127 | { 128 | ConvertMeshToPoints convert(settings); 129 | node->accept(convert); 130 | auto bricks = convert.bricks; 131 | 132 | std::cout<<"Converted mesh to "<count())<<" points."<addChild(scene); 136 | } 137 | } 138 | 139 | if (add_model) 140 | { 141 | group->addChild(node); 142 | } 143 | } 144 | else if (auto bricks = object.cast()) 145 | { 146 | std::cout<<"Read "<count())<<" points."<addChild(scene); 151 | } 152 | double time_to_create = std::chrono::duration(vsg::clock::now() - before_create).count(); 153 | std::cout<<"Time to create scene graph = "<children.empty()) 158 | { 159 | std::cout<<"Error: no data loaded."< vsg_scene; 164 | if (group->children.size()==1) vsg_scene = group->children[0]; 165 | else vsg_scene = group; 166 | 167 | if (outputFilename) 168 | { 169 | vsg::write(vsg_scene, outputFilename, options); 170 | 171 | std::cout<<"Written scene graph to "<addWindow(window); 186 | 187 | // compute the bounds of the scene graph to help position camera 188 | vsg::dbox bounds = vsg::visit(vsg_scene).bounds; 189 | 190 | vsg::dvec3 center = (bounds.min + bounds.max) * 0.5; 191 | double radius = vsg::length(bounds.max - bounds.min) * 0.6; 192 | double nearFarRatio = 0.001; 193 | 194 | auto lookAt = vsg::LookAt::create(center + vsg::dvec3(0.0, -radius * 3.5, 0.0), center, vsg::dvec3(0.0, 0.0, 1.0)); 195 | auto perspective = vsg::Perspective::create(30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 4.5); 196 | 197 | auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D())); 198 | 199 | // add close handler to respond to the close window button and pressing escape 200 | viewer->addEventHandler(vsg::CloseHandler::create(viewer)); 201 | viewer->addEventHandler(vsg::Trackball::create(camera)); 202 | 203 | auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); 204 | viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); 205 | 206 | viewer->compile(); 207 | 208 | if (maxPagedLOD > 0) 209 | { 210 | // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required. 211 | for(auto& task : viewer->recordAndSubmitTasks) 212 | { 213 | if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD; 214 | } 215 | } 216 | 217 | viewer->start_point() = vsg::clock::now(); 218 | 219 | // rendering main loop 220 | while (viewer->advanceToNextFrame()) 221 | { 222 | // pass any events into EventHandlers assigned to the Viewer 223 | viewer->handleEvents(); 224 | 225 | viewer->update(); 226 | 227 | viewer->recordAndSubmit(); 228 | 229 | viewer->present(); 230 | } 231 | 232 | auto fs = viewer->getFrameStamp(); 233 | double fps = static_cast(fs->frameCount) / std::chrono::duration(vsg::clock::now() - viewer->start_point()).count(); 234 | std::cout<<"Average frame rate = "< 0.0) 98 | { 99 | vec3 halfDir = normalize(ld + vd); 100 | color.rgb += specularColor * pow(max(dot(halfDir, nd), 0.0), shininess); 101 | } 102 | 103 | vec3 result = color + emissiveColor; 104 | result *= ambientOcclusion; 105 | 106 | return result; 107 | } 108 | 109 | 110 | void main() 111 | { 112 | float brightnessCutoff = 0.001; 113 | 114 | #ifdef VSG_POINT_SPRITE 115 | vec2 texCoord0 = gl_PointCoord.xy; 116 | #endif 117 | 118 | vec4 diffuseColor = vertexColor * material.diffuseColor; 119 | #ifdef VSG_DIFFUSE_MAP 120 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP 121 | float v = texture(diffuseMap, texCoord0.st).s; 122 | diffuseColor *= vec4(v, v, v, 1.0); 123 | #else 124 | diffuseColor *= texture(diffuseMap, texCoord0.st); 125 | #endif 126 | #endif 127 | 128 | vec4 ambientColor = diffuseColor * material.ambientColor * material.ambientColor.a; 129 | vec4 specularColor = material.specularColor; 130 | vec4 emissiveColor = material.emissiveColor; 131 | float shininess = material.shininess; 132 | float ambientOcclusion = 1.0; 133 | 134 | if (material.alphaMask == 1.0f) 135 | { 136 | if (diffuseColor.a < material.alphaMaskCutoff) 137 | discard; 138 | } 139 | 140 | #ifdef VSG_EMISSIVE_MAP 141 | emissiveColor *= texture(emissiveMap, texCoord0.st); 142 | #endif 143 | 144 | #ifdef VSG_LIGHTMAP_MAP 145 | ambientOcclusion *= texture(aoMap, texCoord0.st).r; 146 | #endif 147 | 148 | #ifdef VSG_SPECULAR_MAP 149 | specularColor *= texture(specularMap, texCoord0.st); 150 | #endif 151 | 152 | vec3 nd = getNormal(); 153 | vec3 vd = normalize(viewDir); 154 | 155 | vec3 color = vec3(0.0, 0.0, 0.0); 156 | 157 | vec4 lightNums = lightData.values[0]; 158 | int numAmbientLights = int(lightNums[0]); 159 | int numDirectionalLights = int(lightNums[1]); 160 | int numPointLights = int(lightNums[2]); 161 | int numSpotLights = int(lightNums[3]); 162 | int index = 1; 163 | 164 | if (numAmbientLights>0) 165 | { 166 | // ambient lights 167 | for(int i = 0; i0) 178 | { 179 | // directional lights 180 | for(int i = 0; i 0.0 && brightness > brightnessCutoff) && !matched) 191 | { 192 | mat4 sm_matrix = mat4(lightData.values[index++], 193 | lightData.values[index++], 194 | lightData.values[index++], 195 | lightData.values[index++]); 196 | 197 | vec4 sm_tc = (sm_matrix) * vec4(eyePos, 1.0); 198 | 199 | 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*/) 200 | { 201 | matched = true; 202 | 203 | float coverage = texture(shadowMaps, vec4(sm_tc.st, shadowMapIndex, sm_tc.z)).r; 204 | brightness *= (1.0-coverage); 205 | 206 | #ifdef SHADOWMAP_DEBUG 207 | if (shadowMapIndex==0) color = vec3(1.0, 0.0, 0.0); 208 | else if (shadowMapIndex==1) color = vec3(0.0, 1.0, 0.0); 209 | else if (shadowMapIndex==2) color = vec3(0.0, 0.0, 1.0); 210 | else if (shadowMapIndex==3) color = vec3(1.0, 1.0, 0.0); 211 | else if (shadowMapIndex==4) color = vec3(0.0, 1.0, 1.0); 212 | else color = vec3(1.0, 1.0, 1.0); 213 | #endif 214 | } 215 | 216 | ++shadowMapIndex; 217 | shadowMapSettings.r -= 1.0; 218 | } 219 | 220 | if (shadowMapSettings.r > 0.0) 221 | { 222 | // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light 223 | // so subsequent light pointions are correct. 224 | index += 4 * int(shadowMapSettings.r); 225 | shadowMapIndex += int(shadowMapSettings.r); 226 | } 227 | 228 | // if light is too dim/shadowed to effect the rendering skip it 229 | if (brightness <= brightnessCutoff ) continue; 230 | 231 | float unclamped_LdotN = dot(direction, nd); 232 | 233 | float diff = max(unclamped_LdotN, 0.0); 234 | color.rgb += (diffuseColor.rgb * lightColor.rgb) * (diff * brightness); 235 | 236 | if (shininess > 0.0 && diff > 0.0) 237 | { 238 | vec3 halfDir = normalize(direction + vd); 239 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * brightness); 240 | } 241 | } 242 | } 243 | 244 | if (numPointLights>0) 245 | { 246 | // point light 247 | for(int i = 0; i 0.0 && diff > 0.0) 268 | { 269 | vec3 halfDir = normalize(direction + vd); 270 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale); 271 | } 272 | } 273 | } 274 | 275 | if (numSpotLights>0) 276 | { 277 | // spot light 278 | for(int i = 0; i 0.0 && diff > 0.0) 301 | { 302 | vec3 halfDir = normalize(direction + vd); 303 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale); 304 | } 305 | } 306 | } 307 | 308 | 309 | outColor.rgb = (color * ambientOcclusion) + emissiveColor.rgb; 310 | outColor.a = diffuseColor.a; 311 | } 312 | -------------------------------------------------------------------------------- /include/vsgPoints/AsciiPoints.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace vsgPoints 20 | { 21 | 22 | class VSGPOINTS_DECLSPEC AsciiPoints : public vsg::Inherit 23 | { 24 | public: 25 | AsciiPoints(); 26 | 27 | vsg::ref_ptr read(const vsg::Path& filename, vsg::ref_ptr options) const override; 28 | 29 | std::set supportedExtensions; 30 | }; 31 | 32 | } // namespace vsgPoints 33 | -------------------------------------------------------------------------------- /include/vsgPoints/BIN.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace vsgPoints 20 | { 21 | 22 | class VSGPOINTS_DECLSPEC BIN : public vsg::Inherit 23 | { 24 | public: 25 | BIN(); 26 | 27 | vsg::ref_ptr read(const vsg::Path& filename, vsg::ref_ptr options) const override; 28 | 29 | std::set supportedExtensions; 30 | }; 31 | 32 | } // namespace vsgPoints 33 | -------------------------------------------------------------------------------- /include/vsgPoints/Brick.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | namespace vsgPoints 18 | { 19 | #pragma pack(1) 20 | 21 | struct PackedPoint 22 | { 23 | vsg::usvec3 v; 24 | vsg::ubvec4 c; 25 | }; 26 | 27 | #pragma pack() 28 | 29 | using Key = vsg::ivec4; 30 | 31 | class VSGPOINTS_DECLSPEC Brick : public vsg::Inherit 32 | { 33 | public: 34 | Brick(); 35 | 36 | std::vector points; 37 | 38 | vsg::ref_ptr createRendering(const Settings& settings, const vsg::vec4& positionScale, const vsg::vec2& pointSize); 39 | vsg::ref_ptr createRendering(const Settings& settings, Key key, vsg::dbox& bound); 40 | 41 | protected: 42 | virtual ~Brick(); 43 | }; 44 | 45 | } // namespace vsgPoints 46 | 47 | EVSG_type_name(vsgPoints::Brick) 48 | -------------------------------------------------------------------------------- /include/vsgPoints/BrickShaderSet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2022 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace vsgPoints 20 | { 21 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createParticleImage(uint32_t dim); 22 | 23 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPointsFlatShadedShaderSet(vsg::ref_ptr options); 24 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPointsPhongShaderSet(vsg::ref_ptr options); 25 | } // namespace vsgPoints 26 | -------------------------------------------------------------------------------- /include/vsgPoints/Bricks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace vsgPoints 22 | { 23 | class VSGPOINTS_DECLSPEC Bricks : public vsg::Inherit 24 | { 25 | public: 26 | Bricks(vsg::ref_ptr in_settings = {}); 27 | 28 | using BrickMap = std::map>; 29 | using key_type = BrickMap::key_type; 30 | using mapped_type = BrickMap::mapped_type; 31 | using value_type = BrickMap::value_type; 32 | using iterator = BrickMap::iterator; 33 | using const_iterator = BrickMap::const_iterator; 34 | 35 | vsg::ref_ptr settings; 36 | BrickMap bricks; 37 | 38 | void add(const vsg::dvec3& v, const vsg::ubvec4& c); 39 | 40 | iterator find(Key key) { return bricks.find(key); } 41 | const_iterator find(Key key) const { return bricks.find(key); } 42 | 43 | mapped_type& operator[](Key key) { return bricks[key]; } 44 | 45 | iterator begin() { return bricks.begin(); } 46 | iterator end() { return bricks.end(); } 47 | 48 | const_iterator begin() const { return bricks.begin(); } 49 | const_iterator end() const { return bricks.end(); } 50 | 51 | bool empty() const { return bricks.empty(); } 52 | 53 | size_t size() const { return bricks.size(); } 54 | 55 | // number of points 56 | size_t count() const; 57 | }; 58 | 59 | using Levels = std::list>; 60 | 61 | } // namespace vsgPoints 62 | 63 | EVSG_type_name(vsgPoints::Bricks) 64 | -------------------------------------------------------------------------------- /include/vsgPoints/Export.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2022 Robert Osfield 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software is furnished to do so, 12 | subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 19 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 20 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 21 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | */ 25 | 26 | #if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)) 27 | # if defined(vsgPoints_EXPORTS) 28 | # define VSGPOINTS_DECLSPEC __declspec(dllexport) 29 | # elif defined(VSGPOINTS_SHARED_LIBRARY) 30 | # define VSGPOINTS_DECLSPEC __declspec(dllimport) 31 | # else 32 | # define VSGPOINTS_DECLSPEC 33 | # endif 34 | #else 35 | # define VSGPOINTS_DECLSPEC 36 | #endif 37 | -------------------------------------------------------------------------------- /include/vsgPoints/Settings.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace vsgPoints 20 | { 21 | 22 | enum CreateType 23 | { 24 | CREATE_FLAT, /// generate a flat scene graph with no LOD/PagedLOD, only suitable for small datasets 25 | CREATE_LOD, /// generate a hierarchical LOD scene graph, suitable for small to moderate sized datasets that can entirely fit in GPU memory 26 | CREATE_PAGEDLOD, /// generate a PagedLOD scene graph, suitable for large datasets that can't fit entirely in GPU memory 27 | }; 28 | 29 | struct Settings : public vsg::Inherit 30 | { 31 | size_t numPointsPerBlock = 10000; 32 | double precision = 0.001; 33 | uint32_t bits = 10; 34 | float pointSize = 4.0f; 35 | float transition = 0.125f; 36 | 37 | CreateType createType = CREATE_LOD; 38 | 39 | vsg::Path path; 40 | vsg::Path extension = ".vsgb"; 41 | vsg::ref_ptr options; 42 | vsg::dvec3 offset; 43 | vsg::dbox bound; 44 | }; 45 | 46 | } // namespace vsgPoints 47 | 48 | EVSG_type_name(vsgPoints::Settings) 49 | -------------------------------------------------------------------------------- /include/vsgPoints/create.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | 5 | Copyright(c) 2023 Robert Osfield 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. 12 | 13 | */ 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace vsgPoints 20 | { 21 | 22 | /// create a scene graph from Bricks using the Setttings as a guide to the type of scene graph to create. 23 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createSceneGraph(vsg::ref_ptr bricks, vsg::ref_ptr settings); 24 | 25 | extern VSGPOINTS_DECLSPEC bool generateLevel(vsgPoints::Bricks& source, vsgPoints::Bricks& destination, const vsgPoints::Settings& settings); 26 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createStateGroup(const vsgPoints::Settings& settings); 27 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr subtile(vsgPoints::Settings& settings, vsgPoints::Levels::reverse_iterator level_itr, vsgPoints::Levels::reverse_iterator end_itr, vsgPoints::Key key, vsg::dbox& bound, bool root = false); 28 | extern VSGPOINTS_DECLSPEC vsg::ref_ptr createPagedLOD(vsgPoints::Levels& levels, vsgPoints::Settings& settings); 29 | 30 | } // namespace vsgPoints 31 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(vsgPoints) 2 | -------------------------------------------------------------------------------- /src/vsgPoints/AsciiPoints.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2023 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | #include 24 | 25 | using namespace vsgPoints; 26 | 27 | AsciiPoints::AsciiPoints() : 28 | supportedExtensions{".3dc", ".asc"} 29 | { 30 | } 31 | 32 | vsg::ref_ptr AsciiPoints::read(const vsg::Path& filename, vsg::ref_ptr options) const 33 | { 34 | if (!vsg::compatibleExtension(filename, options, supportedExtensions)) return {}; 35 | 36 | auto filenameToUse = vsg::findFile(filename, options); 37 | if (!filenameToUse) return {}; 38 | 39 | vsg::ref_ptr settings; 40 | if (options) settings = const_cast(options.get())->getRefObject("settings"); 41 | if (!settings) settings = vsgPoints::Settings::create(); 42 | 43 | if (settings->bits != 8 && settings->bits != 10 && settings->bits != 16) 44 | { 45 | std::cout << "Error: " << settings->bits << " not supported, valid values are 8, 10 and 16." << std::endl; 46 | return {}; 47 | } 48 | 49 | auto bricks = vsgPoints::Bricks::create(settings); 50 | 51 | auto values = vsg::doubleArray::create(10); 52 | uint8_t alpha = 255; 53 | 54 | std::ifstream fin(filenameToUse); 55 | while (fin) 56 | { 57 | if (auto numValuesRead = vsg::read_line(fin, values->data(), values->size())) 58 | { 59 | if (numValuesRead >= 6) 60 | { 61 | bricks->add(vsg::dvec3(values->at(0), values->at(1), values->at(2)), vsg::ubvec4(values->at(3), values->at(4), values->at(5), alpha)); 62 | } 63 | } 64 | } 65 | 66 | if (bricks->empty()) return {}; 67 | 68 | return bricks; 69 | } 70 | -------------------------------------------------------------------------------- /src/vsgPoints/BIN.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2023 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include 23 | 24 | using namespace vsgPoints; 25 | 26 | #pragma pack(1) 27 | 28 | struct VsgIOPoint 29 | { 30 | vsg::dvec3 v; 31 | vsg::ubvec3 c; 32 | }; 33 | 34 | #pragma pack() 35 | 36 | BIN::BIN() : 37 | supportedExtensions{".bin"} 38 | { 39 | } 40 | 41 | vsg::ref_ptr BIN::read(const vsg::Path& filename, vsg::ref_ptr options) const 42 | { 43 | if (!vsg::compatibleExtension(filename, options, supportedExtensions)) return {}; 44 | 45 | auto found_filename = vsg::findFile(filename, options); 46 | if (!found_filename) return {}; 47 | 48 | vsg::ref_ptr settings; 49 | if (options) settings = const_cast(options.get())->getRefObject("settings"); 50 | if (!settings) settings = vsgPoints::Settings::create(); 51 | 52 | if (settings->bits != 8 && settings->bits != 10 && settings->bits != 16) 53 | { 54 | std::cout << "Error: " << settings->bits << " not supported, valid values are 8, 10 and 16." << std::endl; 55 | return {}; 56 | } 57 | 58 | auto bricks = Bricks::create(settings); 59 | 60 | std::ifstream fin(found_filename, std::ios::in | std::ios::binary); 61 | if (!fin) return {}; 62 | 63 | auto points = vsg::Array::create(settings->numPointsPerBlock); 64 | uint8_t alpha = 255; 65 | 66 | while (fin) 67 | { 68 | size_t bytesToRead = settings->numPointsPerBlock * sizeof(VsgIOPoint); 69 | fin.read(reinterpret_cast(points->dataPointer()), bytesToRead); 70 | 71 | size_t numPointsRead = static_cast(fin.gcount()) / sizeof(VsgIOPoint); 72 | if (numPointsRead == 0) break; 73 | 74 | for (size_t i = 0; i < numPointsRead; ++i) 75 | { 76 | auto& point = (*points)[i]; 77 | bricks->add(point.v, vsg::ubvec4(point.c.r, point.c.g, point.c.b, alpha)); 78 | } 79 | } 80 | 81 | if (bricks->empty()) 82 | { 83 | std::cout << "Waring: unable to read file." << std::endl; 84 | return {}; 85 | } 86 | else 87 | { 88 | return bricks; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/vsgPoints/Brick.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2023 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | using namespace vsgPoints; 29 | 30 | //////////////////////////////////////////////////////////////////////////////////////////////////// 31 | // 32 | // Brick 33 | // 34 | Brick::Brick() 35 | { 36 | } 37 | 38 | Brick::~Brick() 39 | { 40 | } 41 | 42 | vsg::ref_ptr Brick::createRendering(const Settings& settings, const vsg::vec4& positionScale, const vsg::vec2& pointSize) 43 | { 44 | vsg::ref_ptr vertices; 45 | 46 | auto normals = vsg::vec3Value::create(vsg::vec3(0.0f, 0.0f, 1.0f)); 47 | auto colors = vsg::ubvec4Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R8G8B8A8_UNORM)); 48 | auto positionScaleValue = vsg::vec4Value::create(positionScale); 49 | auto pointSizeValue = vsg::vec2Value::create(pointSize); 50 | 51 | normals->properties.format = VK_FORMAT_R32G32B32_SFLOAT; 52 | positionScaleValue->properties.format = VK_FORMAT_R32G32B32A32_SFLOAT; 53 | pointSizeValue->properties.format = VK_FORMAT_R32G32_SFLOAT; 54 | 55 | if (settings.bits == 8) 56 | { 57 | auto vertices_8bit = vsg::ubvec3Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R8G8B8_UNORM)); 58 | auto vertex_itr = vertices_8bit->begin(); 59 | auto color_itr = colors->begin(); 60 | for (auto& point : points) 61 | { 62 | (vertex_itr++)->set(static_cast(point.v.x), static_cast(point.v.y), static_cast(point.v.z)); 63 | *(color_itr++) = point.c; 64 | } 65 | 66 | vertices = vertices_8bit; 67 | } 68 | else if (settings.bits == 10) 69 | { 70 | auto vertices_10bit = vsg::uintArray::create(points.size(), vsg::Data::Properties(VK_FORMAT_A2R10G10B10_UNORM_PACK32)); 71 | auto vertex_itr = vertices_10bit->begin(); 72 | auto color_itr = colors->begin(); 73 | for (auto& point : points) 74 | { 75 | *(vertex_itr++) = 3 << 30 | (static_cast(point.v.x) << 20) | (static_cast(point.v.y) << 10) | (static_cast(point.v.z)); 76 | *(color_itr++) = point.c; 77 | } 78 | 79 | vertices = vertices_10bit; 80 | } 81 | else if (settings.bits == 16) 82 | { 83 | auto vertices_16bit = vsg::usvec3Array::create(points.size(), vsg::Data::Properties(VK_FORMAT_R16G16B16_UNORM)); 84 | auto vertex_itr = vertices_16bit->begin(); 85 | auto color_itr = colors->begin(); 86 | for (auto& point : points) 87 | { 88 | (vertex_itr++)->set(static_cast(point.v.x), static_cast(point.v.y), static_cast(point.v.z)); 89 | *(color_itr++) = point.c; 90 | } 91 | 92 | vertices = vertices_16bit; 93 | } 94 | else 95 | { 96 | return {}; 97 | } 98 | 99 | // set up vertexDraw that will do the rendering. 100 | auto vertexDraw = vsg::VertexDraw::create(); 101 | vertexDraw->assignArrays({vertices, normals, colors, positionScaleValue, pointSizeValue}); 102 | vertexDraw->vertexCount = points.size(); 103 | vertexDraw->instanceCount = 1; 104 | 105 | return vertexDraw; 106 | } 107 | 108 | vsg::ref_ptr Brick::createRendering(const Settings& settings, Key key, vsg::dbox& bound) 109 | { 110 | double brickPrecision = settings.precision * static_cast(key.w); 111 | double brickSize = brickPrecision * pow(2.0, static_cast(settings.bits)); 112 | 113 | vsg::dvec3 position(static_cast(key.x) * brickSize, static_cast(key.y) * brickSize, static_cast(key.z) * brickSize); 114 | position -= settings.offset; 115 | 116 | for (auto& point : points) 117 | { 118 | auto& v = point.v; 119 | bound.add(position.x + brickPrecision * static_cast(v.x), 120 | position.y + brickPrecision * static_cast(v.y), 121 | position.z + brickPrecision * static_cast(v.z)); 122 | } 123 | 124 | vsg::vec2 pointSize(brickPrecision * settings.pointSize, brickPrecision); 125 | vsg::vec4 positionScale(position.x, position.y, position.z, brickSize); 126 | 127 | return createRendering(settings, positionScale, pointSize); 128 | } 129 | -------------------------------------------------------------------------------- /src/vsgPoints/BrickShaderSet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2022 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | 15 | #include "shaders/brick_flat_shaded_frag.cpp" 16 | #include "shaders/brick_phong_frag.cpp" 17 | #include "shaders/brick_vert.cpp" 18 | 19 | #include 20 | #include 21 | 22 | using namespace vsgPoints; 23 | 24 | #define VIEW_DESCRIPTOR_SET 0 25 | #define MATERIAL_DESCRIPTOR_SET 1 26 | 27 | vsg::ref_ptr vsgPoints::createParticleImage(uint32_t dim) 28 | { 29 | auto data = vsg::ubvec4Array2D::create(dim, dim); 30 | data->properties.format = VK_FORMAT_R8G8B8A8_UNORM; 31 | float div = 2.0f / static_cast(dim - 1); 32 | float distance_at_one = 0.5f; 33 | float distance_at_zero = 1.0f; 34 | 35 | vsg::vec2 v; 36 | for (uint32_t r = 0; r < dim; ++r) 37 | { 38 | v.y = static_cast(r) * div - 1.0f; 39 | for (uint32_t c = 0; c < dim; ++c) 40 | { 41 | v.x = static_cast(c) * div - 1.0f; 42 | float distance_from_center = vsg::length(v); 43 | float intensity = 1.0f - (distance_from_center - distance_at_one) / (distance_at_zero - distance_at_one); 44 | if (intensity > 1.0f) intensity = 1.0f; 45 | if (intensity < 0.0f) intensity = 0.0f; 46 | uint8_t alpha = static_cast(intensity * 255); 47 | data->set(c, r, vsg::ubvec4(255, 255, 255, alpha)); 48 | } 49 | } 50 | return data; 51 | } 52 | 53 | vsg::ref_ptr vsgPoints::createPointsFlatShadedShaderSet(vsg::ref_ptr options) 54 | { 55 | if (options) 56 | { 57 | // check if a ShaderSet has already been assigned to the options object, if so return it 58 | if (auto itr = options->shaderSets.find("points_flat"); itr != options->shaderSets.end()) return itr->second; 59 | } 60 | 61 | auto vertexShader = vsg::read_cast("shaders/brick.vert", options); 62 | if (!vertexShader) vertexShader = brick_vert(); // fallback to shaders/brick_vert.cpp 63 | 64 | auto fragmentShader = vsg::read_cast("shaders/brick_flat_shaded.frag", options); 65 | if (!fragmentShader) fragmentShader = brick_flat_shaded_frag(); 66 | 67 | auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); 68 | 69 | shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); 70 | shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); 71 | shaderSet->addAttributeBinding("vsg_Color", "", 2, VK_FORMAT_R8G8B8A8_UNORM, vsg::ubvec4Array::create(1)); 72 | shaderSet->addAttributeBinding("vsg_PositionScale", "VSG_POSITION_SCALE", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Value::create(0.0f, 0.0f, 0.0, 1.0f)); 73 | shaderSet->addAttributeBinding("vsg_PointSize", "", 4, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Value::create(0.0035f, 0.001f)); 74 | 75 | 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})); 76 | shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create()); 77 | 78 | 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)); 79 | shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0, 0, 1280, 1024)); 80 | 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})); 81 | 82 | shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128); 83 | 84 | shaderSet->optionalDefines = {"VSG_POINT_SPRITE", "VSG_GREYSCALE_DIFFUSE_MAP"}; 85 | 86 | shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); 87 | 88 | return shaderSet; 89 | } 90 | 91 | vsg::ref_ptr vsgPoints::createPointsPhongShaderSet(vsg::ref_ptr options) 92 | { 93 | if (options) 94 | { 95 | // check if a ShaderSet has already been assigned to the options object, if so return it 96 | if (auto itr = options->shaderSets.find("points_phong"); itr != options->shaderSets.end()) return itr->second; 97 | } 98 | 99 | auto vertexShader = vsg::read_cast("shaders/brick.vert", options); 100 | if (!vertexShader) vertexShader = brick_vert(); // fallback to shaders/brick_vert.cpp 101 | 102 | auto fragmentShader = vsg::read_cast("shaders/brick_phong.frag", options); 103 | if (!fragmentShader) fragmentShader = brick_phong_frag(); 104 | 105 | auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); 106 | 107 | shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); 108 | shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); 109 | shaderSet->addAttributeBinding("vsg_Color", "", 2, VK_FORMAT_R8G8B8A8_UNORM, vsg::ubvec4Array::create(1)); 110 | shaderSet->addAttributeBinding("vsg_PositionScale", "VSG_POSITION_SCALE", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Value::create(0.0f, 0.0f, 0.0, 1.0f)); 111 | shaderSet->addAttributeBinding("vsg_PointSize", "", 4, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Value::create(0.0035f, 0.001f)); 112 | 113 | 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})); 114 | shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PhongMaterialValue::create()); 115 | 116 | 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)); 117 | 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)); 118 | 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})); 119 | 120 | shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_VERTEX_BIT, 0, 128); 121 | 122 | shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_POINT_SPRITE"}; 123 | 124 | shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); 125 | 126 | return shaderSet; 127 | } 128 | -------------------------------------------------------------------------------- /src/vsgPoints/Bricks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2023 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | using namespace vsgPoints; 20 | 21 | Bricks::Bricks(vsg::ref_ptr in_settings) : 22 | settings(in_settings) 23 | { 24 | } 25 | 26 | void Bricks::add(const vsg::dvec3& v, const vsg::ubvec4& c) 27 | { 28 | settings->bound.add(v); 29 | 30 | auto divide_round = [](int64_t value, int64_t divisor) -> int64_t { 31 | if (value < 0) 32 | return -1 - (-value / divisor); 33 | else 34 | return value / divisor; 35 | }; 36 | 37 | double multiplier = 1.0 / settings->precision; 38 | int64_t divisor = 1 << settings->bits; 39 | 40 | vsg::dvec3 scaled_v = v * multiplier; 41 | vsg::dvec3 rounded_v = {std::round(scaled_v.x), std::round(scaled_v.y), std::round(scaled_v.z)}; 42 | vsg::t_vec3 int64_v = {static_cast(rounded_v.x), static_cast(rounded_v.y), static_cast(rounded_v.z)}; 43 | vsg::t_vec3 int64_key = {divide_round(int64_v.x, divisor), divide_round(int64_v.y, divisor), divide_round(int64_v.z, divisor)}; 44 | Key key = {static_cast(int64_key.x), static_cast(int64_key.y), static_cast(int64_key.z), 1}; 45 | 46 | PackedPoint packedPoint; 47 | packedPoint.v.set(int64_v.x - key.x * divisor, int64_v.y - key.y * divisor, int64_v.z - key.z * divisor); 48 | packedPoint.c.set(c.r, c.g, c.b, c.a); 49 | 50 | auto& brick = bricks[key]; 51 | if (!brick) 52 | { 53 | brick = Brick::create(); 54 | } 55 | 56 | brick->points.push_back(packedPoint); 57 | } 58 | 59 | size_t Bricks::count() const 60 | { 61 | size_t num = 0; 62 | for (auto& [key, brick] : bricks) 63 | { 64 | num += brick->points.size(); 65 | } 66 | return num; 67 | } 68 | -------------------------------------------------------------------------------- /src/vsgPoints/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # vars used to enable subdirectories to extend the build of the vsgPoints library in a loosely coupled way 3 | set(EXTRA_DEFINES) 4 | set(EXTRA_INCLUDES) 5 | 6 | SET(HEADER_PATH ${VSGPOINTS_SOURCE_DIR}/include/vsgPoints) 7 | 8 | set(HEADERS 9 | ${HEADER_PATH}/Export.h 10 | ${HEADER_PATH}/AsciiPoints.h 11 | ${HEADER_PATH}/BIN.h 12 | ${HEADER_PATH}/Brick.h 13 | ${HEADER_PATH}/Bricks.h 14 | ${HEADER_PATH}/BrickShaderSet.h 15 | ${HEADER_PATH}/Settings.h 16 | ${HEADER_PATH}/create.h 17 | ) 18 | 19 | set(SOURCES 20 | AsciiPoints.cpp 21 | BIN.cpp 22 | Brick.cpp 23 | Bricks.cpp 24 | BrickShaderSet.cpp 25 | create.cpp 26 | ) 27 | 28 | add_library(vsgPoints ${HEADERS} ${SOURCES}) 29 | 30 | # add definitions to enable building vsgPoints as part of submodule 31 | add_library(vsgPoints::vsgPoints ALIAS vsgPoints) 32 | set(vsgPoints_FOUND TRUE CACHE INTERNAL "vsgPoints found.") 33 | set(CMAKE_DISABLE_FIND_PACKAGE_vsgPoints TRUE CACHE INTERNAL "Disable find_package(vsgPoints) as it's not necessary.") 34 | 35 | set_property(TARGET vsgPoints PROPERTY VERSION ${VSGPOINTS_VERSION_MAJOR}.${VSGPOINTS_VERSION_MINOR}.${VSGPOINTS_VERSION_PATCH}) 36 | set_property(TARGET vsgPoints PROPERTY SOVERSION ${VSGPOINTS_SOVERSION}) 37 | set_property(TARGET vsgPoints PROPERTY POSITION_INDEPENDENT_CODE ON) 38 | set_property(TARGET vsgPoints PROPERTY CXX_STANDARD 17) 39 | 40 | target_compile_definitions(vsgPoints PRIVATE ${EXTRA_DEFINES}) 41 | 42 | target_include_directories(vsgPoints PUBLIC 43 | $ 44 | $ 45 | $ 46 | ${EXTRA_INCLUDES} 47 | ) 48 | 49 | target_link_libraries(vsgPoints 50 | PUBLIC 51 | vsg::vsg 52 | PRIVATE 53 | ${EXTRA_LIBRARIES} 54 | ) 55 | 56 | install(TARGETS vsgPoints ${INSTALL_TARGETS_DEFAULT_FLAGS}) 57 | 58 | if (BUILD_SHARED_LIBS) 59 | target_compile_definitions(vsgPoints INTERFACE VSGPOINTS_SHARED_LIBRARY) 60 | endif() 61 | 62 | 63 | install(DIRECTORY ${VSGPOINTS_SOURCE_DIR}/include/vsgPoints DESTINATION include) 64 | 65 | vsg_add_cmake_support_files( 66 | CONFIG_TEMPLATE 67 | vsgPointsConfig.cmake.in 68 | ) 69 | -------------------------------------------------------------------------------- /src/vsgPoints/create.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Copyright(c) 2023 Robert Osfield 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | 11 | */ 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | using namespace vsgPoints; 31 | 32 | vsg::ref_ptr vsgPoints::createSceneGraph(vsg::ref_ptr bricks, vsg::ref_ptr settings) 33 | { 34 | if (bricks->empty()) 35 | { 36 | vsg::warn("createSceneGraph(", bricks, ", ", settings, ") bricks is empty(), cannot create scene graph."); 37 | return {}; 38 | } 39 | 40 | if (settings->createType == vsgPoints::CREATE_FLAT) 41 | { 42 | 43 | auto cullGroup = vsg::CullGroup::create(); 44 | cullGroup->bound.center = (settings->bound.max + settings->bound.min) * 0.5; 45 | cullGroup->bound.radius = vsg::length(settings->bound.max - settings->bound.min) * 0.5; 46 | 47 | if (settings->bound.valid()) 48 | { 49 | settings->offset = (settings->bound.max + settings->bound.min) * 0.5; 50 | } 51 | 52 | auto transform = vsg::MatrixTransform::create(); 53 | transform->matrix = vsg::translate(settings->offset); 54 | cullGroup->addChild(transform); 55 | 56 | auto group = vsgPoints::createStateGroup(*settings); 57 | transform->addChild(group); 58 | 59 | vsg::dbox bound; 60 | for (auto& [key, brick] : *bricks) 61 | { 62 | if (auto node = brick->createRendering(*(bricks->settings), key, bound)) 63 | { 64 | group->addChild(node); 65 | } 66 | } 67 | 68 | return cullGroup; 69 | } 70 | else 71 | { 72 | auto transform = vsg::MatrixTransform::create(); 73 | 74 | vsg::t_box keyBounds; 75 | for (auto& [key, brick] : *bricks) 76 | { 77 | keyBounds.add(key.x, key.y, key.z); 78 | } 79 | 80 | auto key_origin = keyBounds.min; 81 | auto translated_bricks = Bricks::create(); 82 | for (auto& [key, brick] : *bricks) 83 | { 84 | (*translated_bricks)[Key{key.x - key_origin.x, key.y - key_origin.y, key.z - key_origin.z, key.w}] = brick; 85 | } 86 | 87 | bricks = translated_bricks; 88 | 89 | double brickPrecision = settings->precision; 90 | double brickSize = brickPrecision * pow(2.0, static_cast(settings->bits)); 91 | 92 | vsg::dvec3 offset(static_cast(key_origin.x) * brickSize, 93 | static_cast(key_origin.y) * brickSize, 94 | static_cast(key_origin.z) * brickSize); 95 | 96 | settings->offset = vsg::dvec3(0.0, 0.0, 0.0); 97 | 98 | transform->matrix = vsg::translate(offset); 99 | 100 | vsgPoints::Levels levels; 101 | levels.push_back(bricks); 102 | 103 | while (levels.back()->size() > 1) 104 | { 105 | auto& source = levels.back(); 106 | 107 | levels.push_back(vsgPoints::Bricks::create()); 108 | auto& destination = levels.back(); 109 | 110 | if (!vsgPoints::generateLevel(*source, *destination, *settings)) break; 111 | } 112 | 113 | vsg::debug("levels = ", levels.size()); 114 | 115 | if (auto model = createPagedLOD(levels, *settings)) 116 | { 117 | transform->addChild(model); 118 | } 119 | 120 | return transform; 121 | } 122 | } 123 | 124 | bool vsgPoints::generateLevel(vsgPoints::Bricks& source, vsgPoints::Bricks& destination, const vsgPoints::Settings& settings) 125 | { 126 | int32_t bits = settings.bits; 127 | for (auto& [source_key, source_brick] : source) 128 | { 129 | vsgPoints::Key destination_key = {source_key.x / 2, source_key.y / 2, source_key.z / 2, source_key.w * 2}; 130 | vsg::ivec3 offset = {(source_key.x & 1) << bits, (source_key.y & 1) << bits, (source_key.z & 1) << bits}; 131 | 132 | auto& destination_brick = destination[destination_key]; 133 | if (!destination_brick) destination_brick = vsgPoints::Brick::create(); 134 | 135 | auto& source_points = source_brick->points; 136 | auto& destination_points = destination_brick->points; 137 | size_t count = source_points.size(); 138 | for (size_t i = 0; i < count; i += 4) 139 | { 140 | auto& p = source_points[i]; 141 | 142 | vsgPoints::PackedPoint new_p; 143 | new_p.v.x = static_cast((static_cast(p.v.x) + offset.x) / 2); 144 | new_p.v.y = static_cast((static_cast(p.v.y) + offset.y) / 2); 145 | new_p.v.z = static_cast((static_cast(p.v.z) + offset.z) / 2); 146 | new_p.c = p.c; 147 | 148 | destination_points.push_back(new_p); 149 | } 150 | } 151 | return !destination.empty(); 152 | } 153 | 154 | vsg::ref_ptr vsgPoints::createStateGroup(const vsgPoints::Settings& settings) 155 | { 156 | auto textureData = vsgPoints::createParticleImage(64); 157 | auto shaderSet = vsgPoints::createPointsFlatShadedShaderSet(settings.options); 158 | auto config = vsg::GraphicsPipelineConfig::create(shaderSet); 159 | bool blending = false; 160 | 161 | if (settings.options) config->assignInheritedState(settings.options->inheritedState); 162 | 163 | auto& defines = config->shaderHints->defines; 164 | defines.insert("VSG_POINT_SPRITE"); 165 | 166 | if (settings.bits == 8) 167 | { 168 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::ubvec3), VK_FORMAT_R8G8B8_UNORM); 169 | } 170 | else if (settings.bits == 10) 171 | { 172 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, 4, VK_FORMAT_A2R10G10B10_UNORM_PACK32); 173 | } 174 | else if (settings.bits == 16) 175 | { 176 | config->enableArray("vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::usvec3), VK_FORMAT_R16G16B16_UNORM); 177 | } 178 | else 179 | { 180 | vsg::info("Unsupported number of bits ", settings.bits); 181 | return {}; 182 | } 183 | 184 | config->enableArray("vsg_Normal", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec3), VK_FORMAT_R32G32B32_SFLOAT); 185 | config->enableArray("vsg_Color", VK_VERTEX_INPUT_RATE_VERTEX, sizeof(vsg::ubvec4), VK_FORMAT_R8G8B8A8_UNORM); 186 | config->enableArray("vsg_PositionScale", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec4), VK_FORMAT_R32G32B32A32_SFLOAT); 187 | config->enableArray("vsg_PointSize", VK_VERTEX_INPUT_RATE_INSTANCE, sizeof(vsg::vec2), VK_FORMAT_R32G32_SFLOAT); 188 | 189 | if (textureData) 190 | { 191 | auto sampler = vsg::Sampler::create(); 192 | sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 193 | sampler->addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; 194 | config->assignTexture("diffuseMap", textureData, sampler); 195 | } 196 | 197 | auto mat = vsg::PhongMaterialValue::create(); 198 | mat->value().alphaMask = 1.0f; 199 | mat->value().alphaMaskCutoff = 0.0025f; 200 | config->assignDescriptor("material", mat); 201 | 202 | struct SetPipelineStates : public vsg::Visitor 203 | { 204 | bool blending = false; 205 | SetPipelineStates(bool in_blending) { blending = in_blending; } 206 | 207 | void apply(vsg::Object& object) { object.traverse(*this); } 208 | void apply(vsg::InputAssemblyState& ias) { ias.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; } 209 | void apply(vsg::ColorBlendState& cbs) { cbs.configureAttachments(blending); } 210 | } sps(blending); 211 | 212 | config->accept(sps); 213 | 214 | config->init(); 215 | 216 | // create StateGroup as the root of the scene/command graph to hold the GraphicsPipeline, and binding of Descriptors to decorate the whole graph 217 | auto stateGroup = vsg::StateGroup::create(); 218 | 219 | config->copyTo(stateGroup); 220 | 221 | return stateGroup; 222 | } 223 | 224 | vsg::ref_ptr vsgPoints::subtile(vsgPoints::Settings& settings, vsgPoints::Levels::reverse_iterator level_itr, vsgPoints::Levels::reverse_iterator end_itr, vsgPoints::Key key, vsg::dbox& bound, bool root) 225 | { 226 | if (level_itr == end_itr) return {}; 227 | 228 | auto& bricks = *level_itr; 229 | auto itr = bricks->find(key); 230 | if (itr == bricks->end()) 231 | { 232 | //std::cout<<" "<second); 237 | auto next_itr = level_itr; 238 | ++next_itr; 239 | 240 | if (next_itr != end_itr) 241 | { 242 | std::array, 8> children; 243 | size_t num_children = 0; 244 | 245 | vsgPoints::Key subkey{key.x * 2, key.y * 2, key.z * 2, key.w / 2}; 246 | 247 | vsg::dbox subtiles_bound; 248 | 249 | if (auto child = subtile(settings, next_itr, end_itr, subkey, subtiles_bound)) children[num_children++] = child; 250 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 0, 0, 0), subtiles_bound)) children[num_children++] = child; 251 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 1, 0, 0), subtiles_bound)) children[num_children++] = child; 252 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 1, 0, 0), subtiles_bound)) children[num_children++] = child; 253 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 0, 1, 0), subtiles_bound)) children[num_children++] = child; 254 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 0, 1, 0), subtiles_bound)) children[num_children++] = child; 255 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(0, 1, 1, 0), subtiles_bound)) children[num_children++] = child; 256 | if (auto child = subtile(settings, next_itr, end_itr, subkey + vsgPoints::Key(1, 1, 1, 0), subtiles_bound)) children[num_children++] = child; 257 | 258 | vsg::dbox local_bound; 259 | auto brick_node = brick->createRendering(settings, key, local_bound); 260 | 261 | if (num_children == 0) 262 | { 263 | //vsg::info("Warning: unable to set PagedLOD bounds, key = ",key,", num_children = ", num_children, ", brick_node = ", brick_node, ", brick->points.size() = ", brick->points.size()); 264 | return brick_node; 265 | } 266 | 267 | double transition = settings.transition; 268 | vsg::dsphere bs; 269 | 270 | if (subtiles_bound.valid()) 271 | { 272 | bound.add(subtiles_bound); 273 | bs.center = (subtiles_bound.min + subtiles_bound.max) * 0.5; 274 | bs.radius = vsg::length(subtiles_bound.max - subtiles_bound.min) * 0.5; 275 | 276 | double brickPrecision = settings.precision * static_cast(key.w); 277 | double brickSize = brickPrecision * pow(2.0, static_cast(settings.bits)); 278 | 279 | vsg::dvec3 subtilesSize = (subtiles_bound.max - subtiles_bound.min); 280 | double maxSize = std::max(brickPrecision, std::max(std::max(subtilesSize.x, subtilesSize.y), subtilesSize.z)); 281 | 282 | transition *= (maxSize / brickSize); 283 | 284 | // vsg::info("maxSize = ", maxSize,", brickSize = ",brickSize,", ratio = ",maxSize/brickSize); 285 | } 286 | else 287 | { 288 | vsg::warn("unable to set PagedLOD bounds, num_children = ", num_children); 289 | bs.center = (local_bound.min + local_bound.max) * 0.5; 290 | bs.radius = vsg::length(local_bound.max - local_bound.max) * 0.5; 291 | } 292 | 293 | if (settings.createType == CREATE_PAGEDLOD) 294 | { 295 | vsg::Path path = vsg::make_string(settings.path, "/", key.w, "/", key.z, "/", key.y); 296 | vsg::Path filename = vsg::make_string(key.x, settings.extension); 297 | vsg::Path full_path = path / filename; 298 | 299 | vsg::makeDirectory(path); 300 | 301 | if (num_children == 1) 302 | { 303 | vsg::write(children[0], full_path); 304 | } 305 | else 306 | { 307 | auto group = vsg::Group::create(); 308 | for (size_t i = 0; i < num_children; ++i) 309 | { 310 | group->addChild(children[i]); 311 | } 312 | vsg::write(group, full_path); 313 | } 314 | 315 | auto plod = vsg::PagedLOD::create(); 316 | plod->bound = bs; 317 | plod->children[0] = vsg::PagedLOD::Child{transition, {}}; // external child visible when its bound occupies more than ~1/4 of the height of the window 318 | plod->children[1] = vsg::PagedLOD::Child{0.0, brick_node}; // visible always 319 | 320 | if (root) 321 | { 322 | plod->filename = full_path; 323 | } 324 | else 325 | { 326 | plod->filename = vsg::Path("../../../..") / full_path; 327 | } 328 | 329 | //vsg::info("plod ", key, " ", brick, " plod ", plod, ", brick->points.size() = ", brick->points.size()); 330 | 331 | return plod; 332 | } 333 | else 334 | { 335 | vsg::ref_ptr child_node; 336 | if (num_children == 1) 337 | { 338 | child_node = children[0]; 339 | } 340 | else 341 | { 342 | auto group = vsg::Group::create(); 343 | for (size_t i = 0; i < num_children; ++i) 344 | { 345 | group->addChild(children[i]); 346 | } 347 | 348 | child_node = group; 349 | } 350 | 351 | auto lod = vsg::LOD::create(); 352 | lod->bound = bs; 353 | lod->addChild(vsg::LOD::Child{transition, child_node}); // high res child 354 | lod->addChild(vsg::LOD::Child{0.0, brick_node}); // lower res child 355 | 356 | //vsg::info("lod ", key, " ", brick, " lod ", lod, ", brick->points.size() = ", brick->points.size()); 357 | 358 | return lod; 359 | } 360 | } 361 | else 362 | { 363 | auto leaf = brick->createRendering(settings, key, bound); 364 | //vsg::info("leaf key ",key, " ", brick, " leaf ", leaf, ", bound ", bound, ", brick->points.size() = ", brick->points.size()); 365 | return leaf; 366 | } 367 | 368 | return vsg::Node::create(); 369 | } 370 | 371 | vsg::ref_ptr vsgPoints::createPagedLOD(vsgPoints::Levels& levels, vsgPoints::Settings& settings) 372 | { 373 | if (levels.empty()) return {}; 374 | 375 | auto stateGroup = createStateGroup(settings); 376 | 377 | std::basic_ostringstream str; 378 | 379 | double brickSize = settings.precision * pow(2.0, static_cast(settings.bits)); 380 | double rootBrickSize = brickSize * std::pow(2.0, levels.size() - 1); 381 | 382 | vsg::debug("rootBrickSize = ", rootBrickSize); 383 | 384 | // If only one level is present then PagedLOD is not required so just add all the levels bricks to the StateGroup 385 | if (levels.size() == 1) 386 | { 387 | vsg::dbox bound; 388 | for (auto& [key, brick] : *(levels.back())) 389 | { 390 | auto tile = brick->createRendering(settings, key, bound); 391 | stateGroup->addChild(tile); 392 | } 393 | 394 | return stateGroup; 395 | } 396 | 397 | // more than 1 level so create a PagedLOD hierarchy. 398 | 399 | auto current_itr = levels.rbegin(); 400 | 401 | // root tile 402 | auto& root_level = *current_itr; 403 | vsg::debug("root level ", root_level->size()); 404 | 405 | for (auto& [key, brick] : *root_level) 406 | { 407 | vsg::debug("root key = ", key, " ", brick); 408 | vsg::dbox bound; 409 | if (auto child = subtile(settings, current_itr, levels.rend(), key, bound, true)) 410 | { 411 | vsg::debug("root child ", child); 412 | stateGroup->addChild(child); 413 | } 414 | } 415 | 416 | return stateGroup; 417 | } 418 | -------------------------------------------------------------------------------- /src/vsgPoints/shaders/brick_flat_shaded_frag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static auto brick_flat_shaded_frag = []() { 4 | static const char str[] = 5 | R"(#vsga 1.1.2 6 | Root id=1 vsg::ShaderStage 7 | { 8 | userObjects 0 9 | mask 18446744073709551615 10 | stage 16 11 | entryPointName "main" 12 | module id=2 vsg::ShaderModule 13 | { 14 | userObjects 0 15 | hints id=0 16 | source "#version 450 17 | #extension GL_ARB_separate_shader_objects : enable 18 | #pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP) 19 | 20 | #define VIEW_DESCRIPTOR_SET 0 21 | #define MATERIAL_DESCRIPTOR_SET 1 22 | 23 | #ifdef VSG_DIFFUSE_MAP 24 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; 25 | #endif 26 | 27 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData 28 | { 29 | vec4 ambientColor; 30 | vec4 diffuseColor; 31 | vec4 specularColor; 32 | vec4 emissiveColor; 33 | float shininess; 34 | float alphaMask; 35 | float alphaMaskCutoff; 36 | } material; 37 | 38 | layout(location = 2) in vec4 vertexColor; 39 | 40 | #ifndef VSG_POINT_SPRITE 41 | layout(location = 3) in vec2 texCoord0; 42 | #endif 43 | 44 | layout(location = 0) out vec4 outColor; 45 | 46 | void main() 47 | { 48 | #ifdef VSG_POINT_SPRITE 49 | vec2 texCoord0 = gl_PointCoord.xy; 50 | #endif 51 | 52 | vec4 diffuseColor = vertexColor * material.diffuseColor; 53 | 54 | #ifdef VSG_DIFFUSE_MAP 55 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP 56 | float v = texture(diffuseMap, texCoord0.st).s; 57 | diffuseColor *= vec4(v, v, v, 1.0); 58 | #else 59 | diffuseColor *= texture(diffuseMap, texCoord0.st); 60 | #endif 61 | #endif 62 | 63 | if (material.alphaMask == 1.0f) 64 | { 65 | if (diffuseColor.a < material.alphaMaskCutoff) 66 | discard; 67 | } 68 | 69 | outColor = diffuseColor; 70 | } 71 | " 72 | code 386 73 | 119734787 65536 524299 49 0 131089 1 393227 1 1280527431 1685353262 808793134 74 | 0 196622 0 1 524303 4 4 1852399981 0 11 44 48 75 | 196624 4 7 196611 2 450 589828 1096764487 1935622738 1918988389 1600484449 1684105331 76 | 1868526181 1667590754 29556 262149 4 1852399981 0 393221 9 1717987684 1130722165 1919904879 77 | 0 327685 11 1953654134 1866692709 7499628 393221 13 1702125901 1818323314 1635017028 0 78 | 458758 13 0 1768058209 1131703909 1919904879 0 458758 13 1 1717987684 1130722165 79 | 1919904879 0 458758 13 2 1667592307 1918987381 1869377347 114 458758 13 3 80 | 1936289125 1702259059 1869377347 114 393222 13 4 1852401779 1936027241 115 393222 13 81 | 5 1752198241 1935756641 107 458758 13 6 1752198241 1935756641 1953842027 6710895 327685 82 | 15 1702125933 1818323314 0 327685 44 1131705711 1919904879 0 327685 48 1131963764 83 | 1685221231 48 262215 11 30 2 327752 13 0 35 0 327752 84 | 13 1 35 16 327752 13 2 35 32 327752 13 3 85 | 35 48 327752 13 4 35 64 327752 13 5 35 68 86 | 327752 13 6 35 72 196679 13 2 262215 15 34 1 87 | 262215 15 33 10 262215 44 30 0 262215 48 30 3 88 | 131091 2 196641 3 2 196630 6 32 262167 7 6 4 89 | 262176 8 7 7 262176 10 1 7 262203 10 11 1 90 | 589854 13 7 7 7 7 6 6 6 262176 14 2 91 | 13 262203 14 15 2 262165 16 32 1 262187 16 17 92 | 1 262176 18 2 7 262187 16 22 5 262176 23 2 93 | 6 262187 6 26 1065353216 131092 27 262165 31 32 0 262187 94 | 31 32 3 262176 33 7 6 262187 16 36 6 262176 95 | 43 3 7 262203 43 44 3 262167 46 6 2 262176 96 | 47 1 46 262203 47 48 1 327734 2 4 0 3 97 | 131320 5 262203 8 9 7 262205 7 12 11 327745 18 98 | 19 15 17 262205 7 20 19 327813 7 21 12 20 99 | 196670 9 21 327745 23 24 15 22 262205 6 25 24 100 | 327860 27 28 25 26 196855 30 0 262394 28 29 30 101 | 131320 29 327745 33 34 9 32 262205 6 35 34 327745 102 | 23 37 15 36 262205 6 38 37 327864 27 39 35 103 | 38 196855 41 0 262394 39 40 41 131320 40 65788 131320 104 | 41 131321 30 131320 30 262205 7 45 9 196670 44 45 105 | 65789 65592 106 | } 107 | NumSpecializationConstants 0 108 | } 109 | )"; 110 | vsg::VSG io; 111 | return io.read_cast(reinterpret_cast(str), sizeof(str)); 112 | }; 113 | -------------------------------------------------------------------------------- /src/vsgPoints/shaders/brick_phong_frag.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static auto brick_phong_frag = []() { 4 | static const char str[] = 5 | R"(#vsga 1.1.2 6 | Root id=1 vsg::ShaderStage 7 | { 8 | userObjects 0 9 | mask 18446744073709551615 10 | stage 16 11 | entryPointName "main" 12 | module id=2 vsg::ShaderModule 13 | { 14 | userObjects 0 15 | hints id=0 16 | source "#version 450 17 | #extension GL_ARB_separate_shader_objects : enable 18 | #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) 19 | 20 | #define VIEW_DESCRIPTOR_SET 0 21 | #define MATERIAL_DESCRIPTOR_SET 1 22 | 23 | #ifdef VSG_DIFFUSE_MAP 24 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 0) uniform sampler2D diffuseMap; 25 | #endif 26 | 27 | #ifdef VSG_NORMAL_MAP 28 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 2) uniform sampler2D normalMap; 29 | #endif 30 | 31 | #ifdef VSG_LIGHTMAP_MAP 32 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 3) uniform sampler2D aoMap; 33 | #endif 34 | 35 | #ifdef VSG_EMISSIVE_MAP 36 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 4) uniform sampler2D emissiveMap; 37 | #endif 38 | 39 | #ifdef VSG_SPECULAR_MAP 40 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 5) uniform sampler2D specularMap; 41 | #endif 42 | 43 | layout(set = MATERIAL_DESCRIPTOR_SET, binding = 10) uniform MaterialData 44 | { 45 | vec4 ambientColor; 46 | vec4 diffuseColor; 47 | vec4 specularColor; 48 | vec4 emissiveColor; 49 | float shininess; 50 | float alphaMask; 51 | float alphaMaskCutoff; 52 | } material; 53 | 54 | layout(set = VIEW_DESCRIPTOR_SET, binding = 0) uniform LightData 55 | { 56 | vec4 values[2048]; 57 | } lightData; 58 | 59 | 60 | layout(set = VIEW_DESCRIPTOR_SET, binding = 2) uniform sampler2DArrayShadow shadowMaps; 61 | 62 | layout(location = 0) in vec3 eyePos; 63 | layout(location = 1) in vec3 normalDir; 64 | layout(location = 2) in vec4 vertexColor; 65 | #ifndef VSG_POINT_SPRITE 66 | layout(location = 3) in vec2 texCoord0; 67 | #endif 68 | layout(location = 5) in vec3 viewDir; 69 | 70 | layout(location = 0) out vec4 outColor; 71 | 72 | // Find the normal for this fragment, pulling either from a predefined normal map 73 | // or from the interpolated mesh normal and tangent attributes. 74 | vec3 getNormal() 75 | { 76 | vec3 result; 77 | #ifdef VSG_NORMAL_MAP 78 | // Perturb normal, see http://www.thetenthplanet.de/archives/1180 79 | vec3 tangentNormal = texture(normalMap, texCoord0).xyz * 2.0 - 1.0; 80 | 81 | //tangentNormal *= vec3(2,2,1); 82 | 83 | vec3 q1 = dFdx(eyePos); 84 | vec3 q2 = dFdy(eyePos); 85 | vec2 st1 = dFdx(texCoord0); 86 | vec2 st2 = dFdy(texCoord0); 87 | 88 | vec3 N = normalize(normalDir); 89 | vec3 T = normalize(q1 * st2.t - q2 * st1.t); 90 | vec3 B = -normalize(cross(N, T)); 91 | mat3 TBN = mat3(T, B, N); 92 | 93 | result = normalize(TBN * tangentNormal); 94 | #else 95 | result = normalize(normalDir); 96 | #endif 97 | #ifdef VSG_TWO_SIDED_LIGHTING 98 | if (!gl_FrontFacing) 99 | result = -result; 100 | #endif 101 | return result; 102 | } 103 | 104 | vec3 computeLighting(vec3 ambientColor, vec3 diffuseColor, vec3 specularColor, vec3 emissiveColor, float shininess, float ambientOcclusion, vec3 ld, vec3 nd, vec3 vd) 105 | { 106 | vec3 color = vec3(0.0); 107 | color.rgb += ambientColor; 108 | 109 | float diff = max(dot(ld, nd), 0.0); 110 | color.rgb += diffuseColor * diff; 111 | 112 | if (diff > 0.0) 113 | { 114 | vec3 halfDir = normalize(ld + vd); 115 | color.rgb += specularColor * pow(max(dot(halfDir, nd), 0.0), shininess); 116 | } 117 | 118 | vec3 result = color + emissiveColor; 119 | result *= ambientOcclusion; 120 | 121 | return result; 122 | } 123 | 124 | 125 | void main() 126 | { 127 | float brightnessCutoff = 0.001; 128 | 129 | #ifdef VSG_POINT_SPRITE 130 | vec2 texCoord0 = gl_PointCoord.xy; 131 | #endif 132 | 133 | vec4 diffuseColor = vertexColor * material.diffuseColor; 134 | #ifdef VSG_DIFFUSE_MAP 135 | #ifdef VSG_GREYSCALE_DIFFUSE_MAP 136 | float v = texture(diffuseMap, texCoord0.st).s; 137 | diffuseColor *= vec4(v, v, v, 1.0); 138 | #else 139 | diffuseColor *= texture(diffuseMap, texCoord0.st); 140 | #endif 141 | #endif 142 | 143 | vec4 ambientColor = diffuseColor * material.ambientColor * material.ambientColor.a; 144 | vec4 specularColor = material.specularColor; 145 | vec4 emissiveColor = material.emissiveColor; 146 | float shininess = material.shininess; 147 | float ambientOcclusion = 1.0; 148 | 149 | if (material.alphaMask == 1.0f) 150 | { 151 | if (diffuseColor.a < material.alphaMaskCutoff) 152 | discard; 153 | } 154 | 155 | #ifdef VSG_EMISSIVE_MAP 156 | emissiveColor *= texture(emissiveMap, texCoord0.st); 157 | #endif 158 | 159 | #ifdef VSG_LIGHTMAP_MAP 160 | ambientOcclusion *= texture(aoMap, texCoord0.st).r; 161 | #endif 162 | 163 | #ifdef VSG_SPECULAR_MAP 164 | specularColor *= texture(specularMap, texCoord0.st); 165 | #endif 166 | 167 | vec3 nd = getNormal(); 168 | vec3 vd = normalize(viewDir); 169 | 170 | vec3 color = vec3(0.0, 0.0, 0.0); 171 | 172 | vec4 lightNums = lightData.values[0]; 173 | int numAmbientLights = int(lightNums[0]); 174 | int numDirectionalLights = int(lightNums[1]); 175 | int numPointLights = int(lightNums[2]); 176 | int numSpotLights = int(lightNums[3]); 177 | int index = 1; 178 | 179 | if (numAmbientLights>0) 180 | { 181 | // ambient lights 182 | for(int i = 0; i0) 193 | { 194 | // directional lights 195 | for(int i = 0; i 0.0 && brightness > brightnessCutoff) && !matched) 206 | { 207 | mat4 sm_matrix = mat4(lightData.values[index++], 208 | lightData.values[index++], 209 | lightData.values[index++], 210 | lightData.values[index++]); 211 | 212 | vec4 sm_tc = (sm_matrix) * vec4(eyePos, 1.0); 213 | 214 | 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*/) 215 | { 216 | matched = true; 217 | 218 | float coverage = texture(shadowMaps, vec4(sm_tc.st, shadowMapIndex, sm_tc.z)).r; 219 | brightness *= (1.0-coverage); 220 | 221 | #ifdef SHADOWMAP_DEBUG 222 | if (shadowMapIndex==0) color = vec3(1.0, 0.0, 0.0); 223 | else if (shadowMapIndex==1) color = vec3(0.0, 1.0, 0.0); 224 | else if (shadowMapIndex==2) color = vec3(0.0, 0.0, 1.0); 225 | else if (shadowMapIndex==3) color = vec3(1.0, 1.0, 0.0); 226 | else if (shadowMapIndex==4) color = vec3(0.0, 1.0, 1.0); 227 | else color = vec3(1.0, 1.0, 1.0); 228 | #endif 229 | } 230 | 231 | ++shadowMapIndex; 232 | shadowMapSettings.r -= 1.0; 233 | } 234 | 235 | if (shadowMapSettings.r > 0.0) 236 | { 237 | // skip lightData and shadowMap entries for shadow maps that we haven't visited for this light 238 | // so subsequent light pointions are correct. 239 | index += 4 * int(shadowMapSettings.r); 240 | shadowMapIndex += int(shadowMapSettings.r); 241 | } 242 | 243 | // if light is too dim/shadowed to effect the rendering skip it 244 | if (brightness <= brightnessCutoff ) continue; 245 | 246 | float unclamped_LdotN = dot(direction, nd); 247 | 248 | float diff = max(unclamped_LdotN, 0.0); 249 | color.rgb += (diffuseColor.rgb * lightColor.rgb) * (diff * brightness); 250 | 251 | if (shininess > 0.0 && diff > 0.0) 252 | { 253 | vec3 halfDir = normalize(direction + vd); 254 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * brightness); 255 | } 256 | } 257 | } 258 | 259 | if (numPointLights>0) 260 | { 261 | // point light 262 | for(int i = 0; i 0.0 && diff > 0.0) 283 | { 284 | vec3 halfDir = normalize(direction + vd); 285 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale); 286 | } 287 | } 288 | } 289 | 290 | if (numSpotLights>0) 291 | { 292 | // spot light 293 | for(int i = 0; i 0.0 && diff > 0.0) 316 | { 317 | vec3 halfDir = normalize(direction + vd); 318 | color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale); 319 | } 320 | } 321 | } 322 | 323 | 324 | outColor.rgb = (color * ambientOcclusion) + emissiveColor.rgb; 325 | outColor.a = diffuseColor.a; 326 | } 327 | " 328 | code 3794 329 | 119734787 65536 524299 632 0 131089 1 393227 1 1280527431 1685353262 808793134 330 | 0 196622 0 1 720911 4 4 1852399981 0 14 27 83 331 | 242 613 631 196624 4 7 196611 2 450 589828 1096764487 1935622738 332 | 1918988389 1600484449 1684105331 1868526181 1667590754 29556 262149 4 1852399981 0 327685 9 333 | 1316250983 1634562671 10348 262149 12 1970496882 29804 327685 14 1836216174 1766091873 114 334 | 458757 21 1734963810 1701737576 1967354739 1717989236 0 393221 25 1717987684 1130722165 1919904879 335 | 0 327685 27 1953654134 1866692709 7499628 393221 29 1702125901 1818323314 1635017028 0 336 | 458758 29 0 1768058209 1131703909 1919904879 0 458758 29 1 1717987684 1130722165 337 | 1919904879 0 458758 29 2 1667592307 1918987381 1869377347 114 458758 29 3 338 | 1936289125 1702259059 1869377347 114 393222 29 4 1852401779 1936027241 115 393222 29 339 | 5 1752198241 1935756641 107 458758 29 6 1752198241 1935756641 1953842027 6710895 327685 340 | 31 1702125933 1818323314 0 393221 38 1768058209 1131703909 1919904879 0 393221 50 341 | 1667592307 1918987381 1869377347 114 393221 54 1936289125 1702259059 1869377347 114 327685 58 342 | 1852401779 1936027241 115 458757 62 1768058209 1333030501 1970037603 1852795251 0 196613 80 343 | 25710 196613 82 25718 262149 83 2003134838 7498052 262149 86 1869377379 114 344 | 327685 89 1751607660 1836404340 115 327685 92 1751607628 1952531572 97 327686 92 345 | 0 1970037110 29541 327685 94 1751607660 1952531572 97 458757 98 1097692526 1701405293 346 | 1766618222 1937008743 0 524293 103 1148024174 1667592809 1852795252 1766616161 1937008743 0 393221 347 | 108 1349350766 1953393007 1751607628 29556 393221 113 1399682414 1282699120 1952999273 115 262149 348 | 117 1701080681 120 196613 122 105 327685 131 1751607660 1819231092 29295 393221 349 | 148 1684105331 1632466799 1684949360 30821 196613 153 105 327685 162 1751607660 1819231092 350 | 29295 327685 167 1701996900 1869182051 110 458757 174 1684105331 1632466799 1952797552 1735289204 351 | 115 327685 179 1734963810 1701737576 29555 262149 183 1668571501 6579560 327685 202 352 | 1834970483 1769108577 120 262149 240 1952410995 99 262149 242 1348827493 29551 327685 353 | 279 1702260579 1701273970 0 327685 283 1684105331 1632466799 29552 393221 329 1818455669 354 | 1701866849 1682726756 5141615 262149 333 1717987684 0 262149 354 1718378856 7498052 196613 355 | 378 105 327685 387 1751607660 1819231092 29295 327685 392 1769172848 1852795252 0 356 | 327685 398 1734963810 1701737576 29555 262149 407 1953260900 97 327685 411 1953720676 357 | 1701015137 50 327685 429 1701996900 1869182051 110 262149 435 1818321779 101 393221 358 | 439 1818455669 1701866849 1682726756 5141615 262149 443 1717987684 0 262149 464 1718378856 359 | 7498052 196613 488 105 327685 497 1751607660 1819231092 29295 524293 502 1769172848 360 | 1852795252 1936679775 1701736009 1735278962 25964 655365 507 1751607660 1919501428 1769235301 1667198575 1968141167 361 | 1098016116 1701603182 0 327685 512 1734963810 1701737576 29555 262149 521 1953260900 97 362 | 327685 526 1953720676 1701015137 50 327685 544 1701996900 1869182051 110 458757 550 363 | 1601466212 1751607660 1919509620 1769235301 28271 262149 556 1818321779 101 393221 567 1818455669 364 | 1701866849 1682726756 5141615 262149 571 1717987684 0 262149 592 1718378856 7498052 327685 365 | 613 1131705711 1919904879 0 327685 631 1131963764 1685221231 48 262215 14 30 366 | 1 262215 27 30 2 327752 29 0 35 0 327752 29 367 | 1 35 16 327752 29 2 35 32 327752 29 3 35 368 | 48 327752 29 4 35 64 327752 29 5 35 68 327752 369 | 29 6 35 72 196679 29 2 262215 31 34 1 262215 370 | 31 33 10 262215 83 30 5 262215 91 6 16 327752 371 | 92 0 35 0 196679 92 2 262215 94 34 0 262215 372 | 94 33 0 262215 242 30 0 262215 283 34 0 262215 373 | 283 33 2 262215 613 30 0 262215 631 30 3 131091 374 | 2 196641 3 2 196630 6 32 262167 7 6 3 196641 375 | 8 7 262176 11 7 7 262176 13 1 7 262203 13 376 | 14 1 262176 20 7 6 262187 6 22 981668463 262167 23 377 | 6 4 262176 24 7 23 262176 26 1 23 262203 26 378 | 27 1 589854 29 23 23 23 23 6 6 6 262176 379 | 30 2 29 262203 30 31 2 262165 32 32 1 262187 380 | 32 33 1 262176 34 2 23 262187 32 40 0 262165 381 | 44 32 0 262187 44 45 3 262176 46 2 6 262187 382 | 32 51 2 262187 32 55 3 262187 32 59 4 262187 383 | 6 63 1065353216 262187 32 64 5 131092 67 262187 32 73 384 | 6 262203 13 83 1 262187 6 87 0 393260 7 88 385 | 87 87 87 262187 44 90 2048 262172 91 23 90 196638 386 | 92 91 262176 93 2 92 262203 93 94 2 262176 97 387 | 7 32 262187 44 99 0 262187 44 104 1 262187 44 388 | 109 2 262176 182 7 67 196650 67 184 262168 200 23 389 | 4 262176 201 7 200 262203 13 242 1 196649 67 278 390 | 589849 280 6 1 1 1 0 1 0 196635 281 280 391 | 262176 282 0 281 262203 282 283 0 262167 285 6 2 392 | 262176 612 3 23 262203 612 613 3 262176 620 3 6 393 | 262176 630 1 285 262203 630 631 1 327734 2 4 0 394 | 3 131320 5 262203 20 21 7 262203 24 25 7 262203 395 | 24 38 7 262203 24 50 7 262203 24 54 7 262203 396 | 20 58 7 262203 20 62 7 262203 11 80 7 262203 397 | 11 82 7 262203 11 86 7 262203 24 89 7 262203 398 | 97 98 7 262203 97 103 7 262203 97 108 7 262203 399 | 97 113 7 262203 97 117 7 262203 97 122 7 262203 400 | 24 131 7 262203 97 148 7 262203 97 153 7 262203 401 | 24 162 7 262203 11 167 7 262203 24 174 7 262203 402 | 20 179 7 262203 182 183 7 262203 201 202 7 262203 403 | 24 240 7 262203 20 279 7 262203 20 329 7 262203 404 | 20 333 7 262203 11 354 7 262203 97 378 7 262203 405 | 24 387 7 262203 11 392 7 262203 20 398 7 262203 406 | 11 407 7 262203 20 411 7 262203 11 429 7 262203 407 | 20 435 7 262203 20 439 7 262203 20 443 7 262203 408 | 11 464 7 262203 97 488 7 262203 24 497 7 262203 409 | 24 502 7 262203 24 507 7 262203 20 512 7 262203 410 | 11 521 7 262203 20 526 7 262203 11 544 7 262203 411 | 20 550 7 262203 20 556 7 262203 20 567 7 262203 412 | 20 571 7 262203 11 592 7 196670 21 22 262205 23 413 | 28 27 327745 34 35 31 33 262205 23 36 35 327813 414 | 23 37 28 36 196670 25 37 262205 23 39 25 327745 415 | 34 41 31 40 262205 23 42 41 327813 23 43 39 416 | 42 393281 46 47 31 40 45 262205 6 48 47 327822 417 | )" 418 | R"( 23 49 43 48 196670 38 49 327745 34 52 31 51 419 | 262205 23 53 52 196670 50 53 327745 34 56 31 55 420 | 262205 23 57 56 196670 54 57 327745 46 60 31 59 421 | 262205 6 61 60 196670 58 61 196670 62 63 327745 46 422 | 65 31 64 262205 6 66 65 327860 67 68 66 63 423 | 196855 70 0 262394 68 69 70 131320 69 327745 20 71 424 | 25 45 262205 6 72 71 327745 46 74 31 73 262205 425 | 6 75 74 327864 67 76 72 75 196855 78 0 262394 426 | 76 77 78 131320 77 65788 131320 78 131321 70 131320 70 427 | 262201 7 81 9 196670 80 81 262205 7 84 83 393228 428 | 7 85 1 69 84 196670 82 85 196670 86 88 393281 429 | 34 95 94 40 40 262205 23 96 95 196670 89 96 430 | 327745 20 100 89 99 262205 6 101 100 262254 32 102 431 | 101 196670 98 102 327745 20 105 89 104 262205 6 106 432 | 105 262254 32 107 106 196670 103 107 327745 20 110 89 433 | 109 262205 6 111 110 262254 32 112 111 196670 108 112 434 | 327745 20 114 89 45 262205 6 115 114 262254 32 116 435 | 115 196670 113 116 196670 117 33 262205 32 118 98 327853 436 | 67 119 118 40 196855 121 0 262394 119 120 121 131320 437 | 120 196670 122 40 131321 123 131320 123 262390 125 126 0 438 | 131321 127 131320 127 262205 32 128 122 262205 32 129 98 439 | 327857 67 130 128 129 262394 130 124 125 131320 124 262205 440 | 32 132 117 327808 32 133 132 33 196670 117 133 393281 441 | 34 134 94 40 132 262205 23 135 134 196670 131 135 442 | 262205 23 136 38 524367 7 137 136 136 0 1 2 443 | 262205 23 138 131 524367 7 139 138 138 0 1 2 444 | 327813 7 140 137 139 327745 20 141 131 45 262205 6 445 | 142 141 327822 7 143 140 142 262205 7 144 86 327809 446 | 7 145 144 143 196670 86 145 131321 126 131320 126 262205 447 | 32 146 122 327808 32 147 146 33 196670 122 147 131321 448 | 123 131320 125 131321 121 131320 121 196670 148 40 262205 32 449 | 149 103 327853 67 150 149 40 196855 152 0 262394 150 450 | 151 152 131320 151 196670 153 40 131321 154 131320 154 262390 451 | 156 157 0 131321 158 131320 158 262205 32 159 153 262205 452 | 32 160 103 327857 67 161 159 160 262394 161 155 156 453 | 131320 155 262205 32 163 117 327808 32 164 163 33 196670 454 | 117 164 393281 34 165 94 40 163 262205 23 166 165 455 | 196670 162 166 262205 32 168 117 327808 32 169 168 33 456 | 196670 117 169 393281 34 170 94 40 168 262205 23 171 457 | 170 524367 7 172 171 171 0 1 2 262271 7 173 458 | 172 196670 167 173 262205 32 175 117 327808 32 176 175 459 | 33 196670 117 176 393281 34 177 94 40 175 262205 23 460 | 178 177 196670 174 178 327745 20 180 162 45 262205 6 461 | 181 180 196670 179 181 196670 183 184 131321 185 131320 185 462 | 262390 187 188 0 131321 189 131320 189 327745 20 190 174 463 | 99 262205 6 191 190 327866 67 192 191 87 262205 6 464 | 193 179 262205 6 194 21 327866 67 195 193 194 327847 465 | 67 196 192 195 262205 67 197 183 262312 67 198 197 466 | 327847 67 199 196 198 262394 199 186 187 131320 186 262205 467 | 32 203 117 327808 32 204 203 33 196670 117 204 393281 468 | 34 205 94 40 203 262205 23 206 205 262205 32 207 469 | 117 327808 32 208 207 33 196670 117 208 393281 34 209 470 | 94 40 207 262205 23 210 209 262205 32 211 117 327808 471 | 32 212 211 33 196670 117 212 393281 34 213 94 40 472 | 211 262205 23 214 213 262205 32 215 117 327808 32 216 473 | 215 33 196670 117 216 393281 34 217 94 40 215 262205 474 | 23 218 217 327761 6 219 206 0 327761 6 220 206 475 | 1 327761 6 221 206 2 327761 6 222 206 3 327761 476 | 6 223 210 0 327761 6 224 210 1 327761 6 225 477 | 210 2 327761 6 226 210 3 327761 6 227 214 0 478 | 327761 6 228 214 1 327761 6 229 214 2 327761 6 479 | 230 214 3 327761 6 231 218 0 327761 6 232 218 480 | 1 327761 6 233 218 2 327761 6 234 218 3 458832 481 | 23 235 219 220 221 222 458832 23 236 223 224 225 482 | 226 458832 23 237 227 228 229 230 458832 23 238 231 483 | 232 233 234 458832 200 239 235 236 237 238 196670 202 484 | 239 262205 200 241 202 262205 7 243 242 327761 6 244 485 | 243 0 327761 6 245 243 1 327761 6 246 243 2 486 | 458832 23 247 244 245 246 63 327825 23 248 241 247 487 | 196670 240 248 327745 20 249 240 99 262205 6 250 249 488 | 327870 67 251 250 87 196855 253 0 262394 251 252 253 489 | 131320 252 327745 20 254 240 99 262205 6 255 254 327868 490 | 67 256 255 63 131321 253 131320 253 458997 67 257 251 491 | 186 256 252 196855 259 0 262394 257 258 259 131320 258 492 | 327745 20 260 240 104 262205 6 261 260 327870 67 262 493 | 261 87 131321 259 131320 259 458997 67 263 257 253 262 494 | 258 196855 265 0 262394 263 264 265 131320 264 327745 20 495 | 266 240 104 262205 6 267 266 327868 67 268 267 63 496 | 131321 265 131320 265 458997 67 269 263 259 268 264 196855 497 | 271 0 262394 269 270 271 131320 270 327745 20 272 240 498 | 109 262205 6 273 272 327870 67 274 273 87 131321 271 499 | 131320 271 458997 67 275 269 265 274 270 196855 277 0 500 | 262394 275 276 277 131320 276 196670 183 278 262205 281 284 501 | 283 262205 23 286 240 458831 285 287 286 286 0 1 502 | 262205 32 288 148 262255 6 289 288 327745 20 290 240 503 | 109 262205 6 291 290 327761 6 292 287 0 327761 6 504 | 293 287 1 458832 23 294 292 293 289 291 327761 6 505 | 295 294 3 393305 6 296 284 294 295 196670 279 296 506 | 262205 6 297 279 327811 6 298 63 297 262205 6 299 507 | 179 327813 6 300 299 298 196670 179 300 131321 277 131320 508 | 277 262205 32 301 148 327808 32 302 301 33 196670 148 509 | 302 327745 20 303 174 99 262205 6 304 303 327811 6 510 | 305 304 63 327745 20 306 174 99 196670 306 305 131321 511 | 188 131320 188 131321 185 131320 187 327745 20 307 174 99 512 | 262205 6 308 307 327866 67 309 308 87 196855 311 0 513 | 262394 309 310 311 131320 310 327745 20 312 174 99 262205 514 | 6 313 312 262254 32 314 313 327812 32 315 59 314 515 | 262205 32 316 117 327808 32 317 316 315 196670 117 317 516 | 327745 20 318 174 99 262205 6 319 318 262254 32 320 517 | 319 262205 32 321 148 327808 32 322 321 320 196670 148 518 | 322 131321 311 131320 311 262205 6 323 179 262205 6 324 519 | 21 327868 67 325 323 324 196855 327 0 262394 325 326 520 | 327 131320 326 131321 157 131320 327 262205 7 330 167 262205 521 | 7 331 80 327828 6 332 330 331 196670 329 332 262205 522 | 6 334 329 458764 6 335 1 40 334 87 196670 333 523 | 335 262205 23 336 25 524367 7 337 336 336 0 1 524 | 2 262205 23 338 162 524367 7 339 338 338 0 1 525 | 2 327813 7 340 337 339 262205 6 341 333 262205 6 526 | 342 179 327813 6 343 341 342 327822 7 344 340 343 527 | 262205 7 345 86 327809 7 346 345 344 196670 86 346 528 | 262205 6 347 58 327866 67 348 347 87 262205 6 349 529 | 333 327866 67 350 349 87 327847 67 351 348 350 196855 530 | 353 0 262394 351 352 353 131320 352 262205 7 355 167 531 | 262205 7 356 82 327809 7 357 355 356 393228 7 358 532 | 1 69 357 196670 354 358 262205 23 359 50 524367 7 533 | 360 359 359 0 1 2 262205 7 361 354 262205 7 534 | 362 80 327828 6 363 361 362 458764 6 364 1 40 535 | 363 87 262205 6 365 58 458764 6 366 1 26 364 536 | 365 262205 6 367 179 327813 6 368 366 367 327822 7 537 | 369 360 368 262205 7 370 86 327809 7 371 370 369 538 | 196670 86 371 131321 353 131320 353 131321 157 131320 157 262205 539 | 32 372 153 327808 32 373 372 33 196670 153 373 131321 540 | 154 131320 156 131321 152 131320 152 262205 32 374 108 327853 541 | 67 375 374 40 196855 377 0 262394 375 376 377 131320 542 | 376 196670 378 40 131321 379 131320 379 262390 381 382 0 543 | 131321 383 131320 383 262205 32 384 378 262205 32 385 108 544 | 327857 67 386 384 385 262394 386 380 381 131320 380 262205 545 | 32 388 117 327808 32 389 388 33 196670 117 389 393281 546 | 34 390 94 40 388 262205 23 391 390 196670 387 391 547 | 262205 32 393 117 327808 32 394 393 33 196670 117 394 548 | 393281 34 395 94 40 393 262205 23 396 395 524367 7 549 | 397 396 396 0 1 2 196670 392 397 327745 20 399 550 | 387 45 262205 6 400 399 196670 398 400 262205 6 401 551 | 398 262205 6 402 21 327868 67 403 401 402 196855 405 552 | 0 262394 403 404 405 131320 404 131321 382 131320 405 262205 553 | 7 408 392 262205 7 409 242 327811 7 410 408 409 554 | 196670 407 410 327745 20 412 407 99 262205 6 413 412 555 | 327745 20 414 407 99 262205 6 415 414 327813 6 416 556 | 413 415 327745 20 417 407 104 262205 6 418 417 327745 557 | 20 419 407 104 262205 6 420 419 327813 6 421 418 558 | 420 327809 6 422 416 421 327745 20 423 407 109 262205 559 | 6 424 423 327745 20 425 407 109 262205 6 426 425 560 | 327813 6 427 424 426 327809 6 428 422 427 196670 411 561 | 428 262205 7 430 407 262205 6 431 411 393228 6 432 562 | 1 31 431 393296 7 433 432 432 432 327816 7 434 563 | 430 433 196670 429 434 262205 6 436 398 262205 6 437 564 | 411 327816 6 438 436 437 196670 435 438 262205 7 440 565 | 429 262205 7 441 80 327828 6 442 440 441 196670 439 566 | 442 262205 6 444 435 262205 6 445 439 458764 6 446 567 | 1 40 445 87 327813 6 447 444 446 196670 443 447 568 | 262205 23 448 25 524367 7 449 448 448 0 1 2 569 | 262205 23 450 387 524367 7 451 450 450 0 1 2 570 | 327813 7 452 449 451 262205 6 453 443 327822 7 454 571 | 452 453 262205 7 455 86 327809 7 456 455 454 196670 572 | 86 456 262205 6 457 58 327866 67 458 457 87 262205 573 | 6 459 443 327866 67 460 459 87 327847 67 461 458 574 | 460 196855 463 0 262394 461 462 463 131320 462 262205 7 575 | 465 429 262205 7 466 82 327809 7 467 465 466 393228 576 | 7 468 1 69 467 196670 464 468 262205 23 469 50 577 | 524367 7 470 469 469 0 1 2 262205 7 471 464 578 | 262205 7 472 80 327828 6 473 471 472 458764 6 474 579 | 1 40 473 87 262205 6 475 58 458764 6 476 1 580 | 26 474 475 262205 6 477 435 327813 6 478 476 477 581 | 327822 7 479 470 478 262205 7 480 86 327809 7 481 582 | 480 479 196670 86 481 131321 463 131320 463 131321 382 131320 583 | 382 262205 32 482 378 327808 32 483 482 33 196670 378 584 | 483 131321 379 131320 381 131321 377 131320 377 262205 32 484 585 | 113 327853 67 485 484 40 196855 487 0 262394 485 486 586 | 487 131320 486 196670 488 40 131321 489 131320 489 262390 491 587 | 492 0 131321 493 131320 493 262205 32 494 488 262205 32 588 | 495 113 327857 67 496 494 495 262394 496 490 491 131320 589 | 490 262205 32 498 117 327808 32 499 498 33 196670 117 590 | 499 393281 34 500 94 40 498 262205 23 501 500 196670 591 | 497 501 262205 32 503 117 327808 32 504 503 33 196670 592 | 117 504 393281 34 505 94 40 503 262205 23 506 505 593 | 196670 502 506 262205 32 508 117 327808 32 509 508 33 594 | 196670 117 509 393281 34 510 94 40 508 262205 23 511 595 | 510 196670 507 511 327745 20 513 497 45 262205 6 514 596 | 513 196670 512 514 262205 6 515 512 262205 6 516 21 597 | 327868 67 517 515 516 196855 519 0 262394 517 518 519 598 | 131320 518 131321 492 131320 519 262205 23 522 502 524367 7 599 | 523 522 522 0 1 2 262205 7 524 242 327811 7 600 | 525 523 524 196670 521 525 327745 20 527 521 99 262205 601 | 6 528 527 327745 20 529 521 99 262205 6 530 529 602 | 327813 6 531 528 530 327745 20 532 521 104 262205 6 603 | 533 532 327745 20 534 521 104 262205 6 535 534 327813 604 | 6 536 533 535 327809 6 537 531 536 327745 20 538 605 | 521 109 262205 6 539 538 327745 20 540 521 109 262205 606 | 6 541 540 327813 6 542 539 541 327809 6 543 537 607 | 542 196670 526 543 262205 7 545 521 262205 6 546 526 608 | 393228 6 547 1 31 546 393296 7 548 547 547 547 609 | 327816 7 549 545 548 196670 544 549 262205 23 551 507 610 | 524367 7 552 551 551 0 1 2 262205 7 553 544 611 | 262271 7 554 553 327828 6 555 552 554 196670 550 555 612 | 262205 6 557 512 327745 20 558 507 45 262205 6 559 613 | 558 327745 20 560 502 45 262205 6 561 560 262205 6 614 | 562 550 524300 6 563 1 49 559 561 562 327813 6 615 | 564 557 563 262205 6 565 526 327816 6 566 564 565 616 | 196670 556 566 262205 7 568 544 262205 7 569 80 327828 617 | 6 570 568 569 196670 567 570 262205 6 572 556 262205 618 | 6 573 567 458764 6 574 1 40 573 87 327813 6 619 | 575 572 574 196670 571 575 262205 23 576 25 524367 7 620 | 577 576 576 0 1 2 262205 23 578 497 524367 7 621 | 579 578 578 0 1 2 327813 7 580 577 579 262205 622 | 6 581 571 327822 7 582 580 581 262205 7 583 86 623 | 327809 7 584 583 582 196670 86 584 262205 6 585 58 624 | 327866 67 586 585 87 262205 6 587 571 327866 67 588 625 | 587 87 327847 67 589 586 588 196855 591 0 262394 589 626 | 590 591 131320 590 262205 7 593 544 262205 7 594 82 627 | 327809 7 595 593 594 393228 7 596 1 69 595 196670 628 | 592 596 262205 23 597 50 524367 7 598 597 597 0 629 | 1 2 262205 7 599 592 262205 7 600 80 327828 6 630 | 601 599 600 458764 6 602 1 40 601 87 262205 6 631 | 603 58 458764 6 604 1 26 602 603 262205 6 605 632 | 556 327813 6 606 604 605 327822 7 607 598 606 262205 633 | 7 608 86 327809 7 609 608 607 196670 86 609 131321 634 | 591 131320 591 131321 492 131320 492 262205 32 610 488 327808 635 | 32 611 610 33 196670 488 611 131321 489 131320 491 131321 636 | 487 131320 487 262205 7 614 86 262205 6 615 62 327822 637 | 7 616 614 615 262205 23 617 54 524367 7 618 617 638 | 617 0 1 2 327809 7 619 616 618 327745 620 621 639 | 613 99 327761 6 622 619 0 196670 621 622 327745 620 640 | 623 613 104 327761 6 624 619 1 196670 623 624 327745 641 | 620 625 613 109 327761 6 626 619 2 196670 625 626 642 | 327745 20 627 25 45 262205 6 628 627 327745 620 629 643 | 613 45 196670 629 628 65789 65592 327734 7 9 0 8 644 | 131320 10 262203 11 12 7 262205 7 15 14 393228 7 645 | 16 1 69 15 196670 12 16 262205 7 17 12 131326 646 | 17 65592 647 | } 648 | NumSpecializationConstants 0 649 | } 650 | )"; 651 | vsg::VSG io; 652 | return io.read_cast(reinterpret_cast(str), sizeof(str)); 653 | }; 654 | -------------------------------------------------------------------------------- /src/vsgPoints/shaders/brick_vert.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static auto brick_vert = []() { 4 | static const char str[] = 5 | R"(#vsga 1.1.2 6 | Root id=1 vsg::ShaderStage 7 | { 8 | userObjects 0 9 | mask 18446744073709551615 10 | stage 1 11 | entryPointName "main" 12 | module id=2 vsg::ShaderModule 13 | { 14 | userObjects 0 15 | hints id=0 16 | source "#version 450 17 | #extension GL_ARB_separate_shader_objects : enable 18 | #pragma import_defines (VSG_POSITION_SCALE) 19 | 20 | #define VIEW_DESCRIPTOR_SET 0 21 | #define MATERIAL_DESCRIPTOR_SET 1 22 | 23 | layout(push_constant) uniform PushConstants { 24 | mat4 projection; 25 | mat4 modelView; 26 | } pc; 27 | 28 | 29 | layout(location = 0) in vec3 vsg_Vertex; 30 | layout(location = 1) in vec3 vsg_Normal; 31 | layout(location = 2) in vec4 vsg_Color; 32 | 33 | #ifdef VSG_POSITION_SCALE 34 | layout(location = 3) in vec4 vsg_PositionScale; 35 | #endif 36 | 37 | layout(location = 4) in vec2 vsg_PointSize; 38 | 39 | layout(location = 0) out vec3 eyePos; 40 | layout(location = 1) out vec3 normalDir; 41 | layout(location = 2) out vec4 vertexColor; 42 | 43 | layout(location = 5) out vec3 viewDir; 44 | 45 | layout(set = VIEW_DESCRIPTOR_SET, binding = 1) buffer ViewportData 46 | { 47 | vec4 values[]; 48 | } viewportData; 49 | 50 | out gl_PerVertex{ 51 | vec4 gl_Position; 52 | float gl_PointSize; 53 | }; 54 | 55 | void main() 56 | { 57 | 58 | #ifdef VSG_POSITION_SCALE 59 | vec4 vertex = vec4(vsg_PositionScale.xyz + vsg_Vertex * vsg_PositionScale.w, 1.0); 60 | #else 61 | vec4 vertex = vec4(vsg_Vertex, 1.0); 62 | #endif 63 | 64 | vec4 normal = vec4(vsg_Normal, 0.0); 65 | 66 | gl_Position = (pc.projection * pc.modelView) * vertex; 67 | 68 | eyePos = vec4(pc.modelView * vertex).xyz; 69 | viewDir = -eyePos;//normalize(-eyePos); 70 | normalDir = (pc.modelView * normal).xyz; 71 | vertexColor = vsg_Color; 72 | 73 | float dist = max(vsg_PointSize[1], abs(eyePos.z)); 74 | vec4 viewport = viewportData.values[0]; 75 | gl_PointSize = viewport[3] * (vsg_PointSize[0] / dist); 76 | } 77 | 78 | " 79 | code 749 80 | 119734787 65536 524299 106 0 131089 1 393227 1 1280527431 1685353262 808793134 81 | 0 196622 0 1 917519 0 4 1852399981 0 12 20 29 82 | 48 59 62 68 70 76 196611 2 450 589828 1096764487 1935622738 83 | 1918988389 1600484449 1684105331 1868526181 1667590754 29556 262149 4 1852399981 0 262149 9 84 | 1953654134 30821 327685 12 1600615286 1953654102 30821 262149 19 1836216174 27745 327685 85 | 20 1600615286 1836216142 27745 393221 27 1348430951 1700164197 2019914866 0 393222 27 86 | 0 1348430951 1953067887 7237481 458758 27 1 1348430951 1953393007 1702521171 0 196613 87 | 29 0 393221 33 1752397136 1936617283 1953390964 115 393222 33 0 1785688688 88 | 1769235301 28271 393222 33 1 1701080941 1701402220 119 196613 35 25456 262149 89 | 48 1348827493 29551 262149 59 2003134838 7498052 327685 62 1836216174 1766091873 114 90 | 327685 68 1953654134 1866692709 7499628 327685 70 1600615286 1869377347 114 262149 73 91 | 1953720676 0 393221 76 1600615286 1852403536 2053722996 101 327685 88 2003134838 1953656688 92 | 0 393221 90 2003134806 1953656688 1635017028 0 327686 90 0 1970037110 29541 93 | 393221 92 2003134838 1953656688 1635017028 0 262215 12 30 0 262215 20 94 | 30 1 327752 27 0 11 0 327752 27 1 11 1 95 | 196679 27 2 262216 33 0 5 327752 33 0 35 0 96 | 327752 33 0 7 16 262216 33 1 5 327752 33 1 97 | 35 64 327752 33 1 7 16 196679 33 2 262215 48 98 | 30 0 262215 59 30 5 262215 62 30 1 262215 68 99 | 30 2 262215 70 30 2 262215 76 30 4 262215 89 100 | 6 16 327752 90 0 35 0 196679 90 3 262215 92 101 | 34 0 262215 92 33 1 131091 2 196641 3 2 196630 102 | 6 32 262167 7 6 4 262176 8 7 7 262167 10 103 | 6 3 262176 11 1 10 262203 11 12 1 262187 6 104 | 14 1065353216 262203 11 20 1 262187 6 22 0 262174 27 105 | 7 6 262176 28 3 27 262203 28 29 3 262165 30 106 | 32 1 262187 30 31 0 262168 32 7 4 262174 33 107 | 32 32 262176 34 9 33 262203 34 35 9 262176 36 108 | 9 32 262187 30 39 1 262176 45 3 7 262176 47 109 | 3 10 262203 47 48 3 262203 47 59 3 262203 47 110 | 62 3 262203 45 68 3 262176 69 1 7 262203 69 111 | 70 1 262176 72 7 6 262167 74 6 2 262176 75 112 | 1 74 262203 75 76 1 262165 77 32 0 262187 77 113 | 78 1 262176 79 1 6 262187 77 82 2 262176 83 114 | 3 6 196637 89 7 196638 90 89 262176 91 2 90 115 | 262203 91 92 2 262176 93 2 7 262187 77 96 3 116 | 262187 77 99 0 327734 2 4 0 3 131320 5 262203 117 | 8 9 7 262203 8 19 7 262203 72 73 7 262203 118 | 8 88 7 262205 10 13 12 327761 6 15 13 0 119 | 327761 6 16 13 1 327761 6 17 13 2 458832 7 120 | 18 15 16 17 14 196670 9 18 262205 10 21 20 121 | 327761 6 23 21 0 327761 6 24 21 1 327761 6 122 | 25 21 2 458832 7 26 23 24 25 22 196670 19 123 | 26 327745 36 37 35 31 262205 32 38 37 327745 36 124 | 40 35 39 262205 32 41 40 327826 32 42 38 41 125 | 262205 7 43 9 327825 7 44 42 43 327745 45 46 126 | 29 31 196670 46 44 327745 36 49 35 39 262205 32 127 | 50 49 262205 7 51 9 327825 7 52 50 51 327761 128 | 6 53 52 0 327761 6 54 52 1 327761 6 55 129 | 52 2 327761 6 56 52 3 458832 7 57 53 54 130 | 55 56 524367 10 58 57 57 0 1 2 196670 48 131 | 58 262205 10 60 48 262271 10 61 60 196670 59 61 132 | 327745 36 63 35 39 262205 32 64 63 262205 7 65 133 | 19 327825 7 66 64 65 524367 10 67 66 66 0 134 | 1 2 196670 62 67 262205 7 71 70 196670 68 71 135 | 327745 79 80 76 78 262205 6 81 80 327745 83 84 136 | 48 82 262205 6 85 84 393228 6 86 1 4 85 137 | 458764 6 87 1 40 81 86 196670 73 87 393281 93 138 | 94 92 31 31 262205 7 95 94 196670 88 95 327745 139 | 72 97 88 96 262205 6 98 97 327745 79 100 76 140 | 99 262205 6 101 100 262205 6 102 73 327816 6 103 141 | 101 102 327813 6 104 98 103 327745 83 105 29 39 142 | 196670 105 104 65789 65592 143 | } 144 | NumSpecializationConstants 0 145 | } 146 | )"; 147 | vsg::VSG io; 148 | return io.read_cast(reinterpret_cast(str), sizeof(str)); 149 | }; 150 | -------------------------------------------------------------------------------- /src/vsgPoints/vsgPointsConfig.cmake.in: -------------------------------------------------------------------------------- 1 | include(CMakeFindDependencyMacro) 2 | 3 | find_dependency(vsg) 4 | 5 | include("${CMAKE_CURRENT_LIST_DIR}/vsgPointsTargets.cmake") 6 | --------------------------------------------------------------------------------