├── .gitattributes ├── .gitignore ├── LICENSE ├── Qt5Ogre21 ├── Qt5Ogre21.pri ├── Qt5Ogre21.pro ├── qogreviewport.cpp ├── qogreviewport.h ├── qtogre21.cpp ├── qtogre21.h ├── somecustomwidget.cpp ├── somecustomwidget.h └── test.cpp ├── README.md ├── Screenshot.png └── testMedia ├── HLMS └── Hlms │ ├── Common │ ├── Any │ │ ├── ShadowCaster_piece_ps.any │ │ └── ShadowCaster_piece_vs.any │ ├── GLSL │ │ ├── CrossPlatformSettings_piece_all.glsl │ │ ├── Matrix_piece_all.glsl │ │ └── QuaternionCode_piece_all.glsl │ └── HLSL │ │ ├── CrossPlatformSettings_piece_all.hlsl │ │ ├── Matrix_piece_all.hlsl │ │ └── QuaternionCode_piece_all.hlsl │ ├── Pbs │ ├── Any │ │ ├── PlanarReflections_piece_all.any │ │ ├── PlanarReflections_piece_ps.any │ │ ├── ShadowMapping_piece_ps.any │ │ └── ShadowMapping_piece_vs.any │ ├── GLSL │ │ ├── BRDFs_piece_ps.glsl │ │ ├── BlendModes_piece_ps.glsl │ │ ├── DetailMaps_piece_ps.glsl │ │ ├── Forward3D_piece_ps.glsl │ │ ├── PixelShader_ps.glsl │ │ ├── Structs_piece_vs_piece_ps.glsl │ │ ├── Textures_piece_ps.glsl │ │ └── VertexShader_vs.glsl │ └── HLSL │ │ ├── BRDFs_piece_ps.hlsl │ │ ├── BlendModes_piece_ps.hlsl │ │ ├── DetailMaps_piece_ps.hlsl │ │ ├── Forward3D_piece_ps.hlsl │ │ ├── PixelShader_ps.hlsl │ │ ├── Structs_piece_vs_piece_ps.hlsl │ │ ├── Textures_piece_ps.hlsl │ │ └── VertexShader_vs.hlsl │ ├── PbsMobile │ └── GLSL │ │ ├── BlendModes_piece_ps.glsl │ │ ├── PixelShader_ps.glsl │ │ └── VertexShader_vs.glsl │ ├── Unlit │ ├── Any │ │ └── StructsUnlit_piece_all.any │ ├── GLSL │ │ ├── BlendModes_piece_ps.glsl │ │ ├── PixelShader_ps.glsl │ │ ├── Structs_piece_vs_piece_ps.glsl │ │ └── VertexShader_vs.glsl │ └── HLSL │ │ ├── BlendModes_piece_ps.hlsl │ │ ├── PixelShader_ps.hlsl │ │ ├── Structs_piece_vs_piece_ps.hlsl │ │ └── VertexShader_vs.hlsl │ └── UnlitMobile │ └── GLSL │ ├── BlendModes_piece_ps.glsl │ ├── CrossPlatformSettings_piece_ps.glsl │ ├── CrossPlatformSettings_piece_vs.glsl │ ├── PixelShader_ps.glsl │ └── VertexShader_vs.glsl ├── Suzanne.mesh ├── hlms └── Hlms │ ├── Common │ ├── Any │ │ └── Cubemap_piece_all.any │ ├── GLSL │ │ └── RenderDepthOnly_piece_ps.glsl │ ├── HLSL │ │ └── RenderDepthOnly_piece_ps.hlsl │ └── Metal │ │ ├── CrossPlatformSettings_piece_all.metal │ │ ├── Matrix_piece_all.metal │ │ ├── QuaternionCode_piece_all.metal │ │ └── RenderDepthOnly_piece_ps.metal │ ├── Pbs │ ├── GLSL │ │ └── IrradianceVolume_piece_ps.glsl │ ├── HLSL │ │ └── IrradianceVolume_piece_ps.hlsl │ └── Metal │ │ ├── BRDFs_piece_ps.metal │ │ ├── BlendModes_piece_ps.metal │ │ ├── DetailMaps_piece_ps.metal │ │ ├── Forward3D_piece_ps.metal │ │ ├── IrradianceVolume_piece_ps.metal │ │ ├── PixelShader_ps.metal │ │ ├── Structs_piece_vs_piece_ps.metal │ │ ├── Textures_piece_ps.metal │ │ └── VertexShader_vs.metal │ ├── Terra │ ├── GLSL │ │ ├── PbsTerraShadows │ │ │ └── PbsTerraShadows_piece_vs_piece_ps.glsl │ │ ├── PixelShader_ps.glsl │ │ ├── Structs_piece_vs_piece_ps.glsl │ │ ├── Textures_piece_ps.glsl │ │ └── VertexShader_vs.glsl │ └── HLSL │ │ ├── PbsTerraShadows │ │ └── PbsTerraShadows_piece_vs_piece_ps.hlsl │ │ ├── PixelShader_ps.hlsl │ │ ├── Structs_piece_vs_piece_ps.hlsl │ │ ├── Textures_piece_ps.hlsl │ │ └── VertexShader_vs.hlsl │ └── Unlit │ └── Metal │ ├── BlendModes_piece_ps.metal │ ├── PixelShader_ps.metal │ ├── Structs_piece_vs_piece_ps.metal │ └── VertexShader_vs.metal └── knot.mesh /.gitattributes: -------------------------------------------------------------------------------- 1 | *.glsl linguist-vendored 2 | *.hlsl linguist-vendored 3 | *.metal linguist-vendored 4 | 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | 15 | /.qmake.cache 16 | /.qmake.stash 17 | *.pro.user 18 | *.pro.user.* 19 | *.qbs.user 20 | *.qbs.user.* 21 | *.moc 22 | moc_*.cpp 23 | qrc_*.cpp 24 | ui_*.h 25 | Makefile* 26 | *build-* 27 | 28 | # QtCreator 29 | 30 | *.autosave 31 | 32 | # QtCtreator Qml 33 | *.qmlproject.user 34 | *.qmlproject.user.* 35 | 36 | # QtCtreator CMake 37 | CMakeLists.txt.user 38 | 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Arthur Brainville 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 | -------------------------------------------------------------------------------- /Qt5Ogre21/Qt5Ogre21.pri: -------------------------------------------------------------------------------- 1 | 2 | message("The .pri for QtOgre has been found!"); 3 | 4 | #------------------------------------------------- 5 | # 6 | # Project created by QtCreator 2016-11-16T12:28:05 7 | # 8 | # For Qt5 and up only 9 | #------------------------------------------------- 10 | 11 | #QT += core gui widgets 12 | 13 | #TARGET = Qt5Ogre21 14 | #TEMPLATE = app 15 | 16 | #CONFIG += c++14 precompile_header 17 | 18 | #VARIABLE TO BE SET BY THE USER WITH PATH TO THE OGRE SDK 19 | #OGRE21SDK = "C:\YbalridSoftware\Ogre21\build\sdk" 20 | 21 | message("Ogre21 SDK is $$OGRE21SDK"); 22 | 23 | 24 | OGRELIBPATH = $$OGRE21SDK\\lib\\ 25 | 26 | 27 | #include QtOgre pri here 28 | #for now we're doing this by hand 29 | message("QTOGRE IS : $$QTOGRE") 30 | INCLUDEPATH += $$QTOGRE 31 | 32 | win32:INCLUDEPATH += $$OGRE21SDK\\include 33 | win32:INCLUDEPATH += $$OGRE21SDK\\include\\OGRE 34 | unix:INCLUDEPATH += /usr/local/include/OGRE 35 | unix:INCLUDEPATH += /usr/include/OGRE 36 | 37 | CONFIG(debug, debug|release) { 38 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreMain_d.lib 39 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreOverlay_d.lib 40 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreMeshLodGenerator_d.lib 41 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreHlmsPbs_d.lib 42 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreHlmsUnlit_d.lib 43 | unix:LIBS += -lOgreMain_d 44 | unix:LIBS += -lOgreHlmsPbs_d 45 | unix:LIBS += -lOgreHlmsUnlit_d 46 | unix:LIBS += -lOgreOverlay_d 47 | unix:LIBS += -lOgreMeshLodGenerator_d 48 | 49 | } else { 50 | win32:LIBS += $$OGRELIBPATH\\release\\OgreMain.lib 51 | win32:LIBS += $$OGRELIBPATH\\release\\OgreOverlay.lib 52 | win32:LIBS += $$OGRELIBPATH\\release\\OgreMeshLodGenerator.lib 53 | win32:LIBS += $$OGRELIBPATH\\release\\OgreHlmsPbs.lib 54 | win32:LIBS += $$OGRELIBPATH\\release\\OgreHlmsUnlit.lib 55 | unix:LIBS += -lOgreMain 56 | unix:LIBS += -lOgreHlmsPbs 57 | unix:LIBS += -lOgreHlmsUnlit 58 | unix:LIBS += -lOgreOverlay 59 | unix:LIBS += -lOgreMeshLodGenerator 60 | } 61 | win32:LIBS += opengl32.lib 62 | 63 | SOURCES += $$QTOGRE/qogreviewport.cpp \ 64 | $$QTOGRE/qtogre21.cpp \ 65 | 66 | HEADERS += $$QTOGRE/qogreviewport.h \ 67 | $$QTOGRE/qtogre21.h \ 68 | -------------------------------------------------------------------------------- /Qt5Ogre21/Qt5Ogre21.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2016-11-16T12:28:05 4 | # 5 | # For Qt5 and up only 6 | #------------------------------------------------- 7 | 8 | QT += core gui widgets 9 | 10 | TARGET = Qt5Ogre21 11 | TEMPLATE = app 12 | 13 | CONFIG += c++14 precompile_header 14 | 15 | #VARIABLE TO BE SET BY THE USER WITH PATH TO THE OGRE SDK 16 | OGRE21SDK = "C:\Users\arthu\ogre\build\sdk" 17 | 18 | OGRELIBPATH = $$OGRE21SDK\\lib\\ 19 | 20 | #include QtOgre pri here 21 | #for now we're doing this by hand 22 | 23 | win32:INCLUDEPATH += $$OGRE21SDK\\include 24 | win32:INCLUDEPATH += $$OGRE21SDK\\include\\OGRE 25 | linux:INCLUDEPATH += /usr/local/include/OGRE 26 | linux:LIBS += -L/usr/local/lib 27 | 28 | CONFIG(debug, debug|release) { 29 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreMain_d.lib 30 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreOverlay_d.lib 31 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreMeshLodGenerator_d.lib 32 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreHlmsPbs_d.lib 33 | win32:LIBS += $$OGRELIBPATH\\debug\\OgreHlmsUnlit_d.lib 34 | 35 | linux:LIBS += -lOgreMain_d 36 | linux:LIBS += -lOgreOverlay_d 37 | linux:LIBS += -lOgreMeshLodGenerator_d 38 | linux:LIBS += -lOgreHlmsPbs_d 39 | linux:LIBS += -lOgreHlmsUnlit_d 40 | 41 | } else { 42 | win32:LIBS += $$OGRELIBPATH\\release\\OgreMain.lib 43 | win32:LIBS += $$OGRELIBPATH\\release\\OgreOverlay.lib 44 | win32:LIBS += $$OGRELIBPATH\\release\\OgreMeshLodGenerator.lib 45 | win32:LIBS += $$OGRELIBPATH\\release\\OgreHlmsPbs.lib 46 | win32:LIBS += $$OGRELIBPATH\\release\\OgreHlmsUnlit.lib 47 | 48 | linux:LIBS += -lOgreMain 49 | linux:LIBS += -lOgreOverlay 50 | linux:LIBS += -lOgreMeshLodGenerator 51 | linux:LIBS += -lOgreHlmsPbs 52 | linux:LIBS += -lOgreHlmsUnlit 53 | 54 | } 55 | win32:LIBS += opengl32.lib 56 | 57 | SOURCES += test.cpp\ 58 | qogreviewport.cpp \ 59 | qtogre21.cpp \ 60 | somecustomwidget.cpp 61 | 62 | HEADERS += qogreviewport.h \ 63 | qtogre21.h \ 64 | somecustomwidget.h 65 | -------------------------------------------------------------------------------- /Qt5Ogre21/qogreviewport.cpp: -------------------------------------------------------------------------------- 1 | #include "qogreviewport.h" 2 | 3 | size_t QOgreViewport::windowNumber{0}; 4 | 5 | QOgreViewport::QOgreViewport(size_t SceneManagerIndex, QWidget *parent) 6 | : QWidget(parent), 7 | smgrIndex{SceneManagerIndex}, 8 | Window{nullptr} 9 | { 10 | //We need QtOgre21 to exist 11 | if(!QtOgre21::instance()) 12 | throw std::runtime_error("Cannot create QOgreViewport widgets if QtOgre21 is not initialized!"); 13 | 14 | //Permit Ogre to draw manually on that window 15 | setAttribute(Qt::WA_OpaquePaintEvent); 16 | setAttribute(Qt::WA_PaintOnScreen); 17 | 18 | //Set the title of that window 19 | setWindowTitle(QString("Window") + QString(std::to_string(windowNumber).c_str())); 20 | 21 | //Confirugation for Ogre 22 | Ogre::NameValuePairList misc; 23 | misc["FSAA"] = std::to_string(QtOgre21::instance()->getAALevel()); 24 | misc["vsync"] = "false"; 25 | misc["externalWindowHandle"] = std::to_string(winId()); 26 | 27 | //This permit to handle some weirdness on window creations 28 | QtOgre21::instance()->willCreateWindowHint(); 29 | 30 | //When using the GL3+ renderer, by default the RenderWindow creation create a GL Context. 31 | //Ogre expect to use only one GL Context, so subsequent window need to use the context of the 1st one. 32 | if(QtOgre21::instance()->getAPI() == QtOgre21::RenderAPI::OpenGL) 33 | //Get the context. This pointer is nullptr if there's no context created yet 34 | if(auto context = QtOgre21::instance()->getContext()) 35 | //At this point, everything will go bad if this window don't use the same GL context 36 | misc["externalGLContext"] = std::to_string(size_t(context)); 37 | 38 | //Create the RenderWindow 39 | Window = Ogre::Root::getSingleton().createRenderWindow(std::string("Window") + std::to_string(windowNumber++), width(), height(), false, &misc); 40 | 41 | //We have to do this callback. This initialize the scene and the compositor for the rendering, and return a bunch of pointers in a tuple 42 | auto result = QtOgre21::instance()->WidgetCreatedCallback(Window, SceneManagerIndex); 43 | 44 | //Extract the "bunch of usefull pointers" from the tuple 45 | SceneManager = std::get<0>(result); 46 | Camera = std::get<1>(result); 47 | Workspace = std::get<2>(result); 48 | WorkspaceDefName = std::get<3>(result); 49 | 50 | //Configure the camera to a state where it will be able to draw something... 51 | Camera->setNearClipDistance(0.1f); 52 | Camera->setFarClipDistance(500); 53 | Camera->setPosition(0, 0, 0); 54 | Camera->lookAt(0, 0, 0); 55 | //Camera->setFOVy(Ogre::Degree(45)); 56 | Camera->setAutoAspectRatio(true); 57 | 58 | Camera->detachFromParent(); 59 | CameraNode = SceneManager->getRootSceneNode()->createChildSceneNode(); 60 | CameraNode->attachObject(Camera); 61 | } 62 | 63 | Ogre::SceneNode* QOgreViewport::getCameraNode() 64 | { 65 | return CameraNode; 66 | } 67 | 68 | QOgreViewport::~QOgreViewport() 69 | { 70 | 71 | } 72 | 73 | void QOgreViewport::paintEvent(QPaintEvent *event) 74 | { 75 | //Call the refresh of Ogre when the viewport's window is called 76 | //qDebug() << "paint event"; 77 | Ogre::Root::getSingleton().renderOneFrame(); 78 | Window->windowMovedOrResized(); 79 | 80 | event->accept(); 81 | } 82 | 83 | //Tell Ogre the window has been resized and redraw 84 | void QOgreViewport::resizeEvent(QResizeEvent *event) 85 | { 86 | QWidget::resizeEvent(event); 87 | if(event->isAccepted()) 88 | { 89 | Window->windowMovedOrResized(); 90 | #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX 91 | //Need to override the actual size of the window, for some reason. Only on Linux. 92 | Window->resize(width(), height()); 93 | #endif 94 | this->update(); 95 | } 96 | } 97 | 98 | //Same as above, but for movement. 99 | void QOgreViewport::moveEvent(QMoveEvent *event) 100 | { 101 | QWidget::moveEvent(event); 102 | if(event->isAccepted()) 103 | { 104 | Window->windowMovedOrResized(); 105 | this->update(); 106 | } 107 | } 108 | 109 | //Return the camera of this viewport 110 | Ogre::Camera* QOgreViewport::getCamera() 111 | { 112 | return Camera; 113 | } 114 | 115 | Ogre::SceneManager* QOgreViewport::getSmgr() 116 | { 117 | return SceneManager; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /Qt5Ogre21/qogreviewport.h: -------------------------------------------------------------------------------- 1 | #ifndef QOGREVIEWPORT_H 2 | #define QOGREVIEWPORT_H 3 | 4 | #include 5 | #include 6 | #include "qtogre21.h" 7 | 8 | class QOgreViewport : public QWidget 9 | { 10 | Q_OBJECT 11 | 12 | public: 13 | ///Construct the viewport, give the index of the scene manager to use. 14 | /// If there's no created scene and the index is 0, will automatically create the 1st scene manager 15 | QOgreViewport(size_t SceneManagerIndex = 0, QWidget *parent = 0); 16 | 17 | ~QOgreViewport(); 18 | 19 | ///Neutralize the paintEngine by returning nullptr 20 | QPaintEngine* paintEngine() const {return nullptr;} 21 | 22 | ///When the widget is repainted 23 | virtual void paintEvent(QPaintEvent *event) override; 24 | 25 | ///When the widget is resized 26 | virtual void resizeEvent(QResizeEvent *event) override; 27 | 28 | ///When the widget is moved 29 | virtual void moveEvent(QMoveEvent *event) override; 30 | 31 | ///Return the camera used 32 | Ogre::Camera* getCamera(); 33 | Ogre::SceneNode* getCameraNode(); 34 | 35 | ///Return the SceneManager used 36 | Ogre::SceneManager* getSmgr(); 37 | 38 | private: 39 | ///Couner of windows 40 | static size_t windowNumber; 41 | 42 | ///Index of the scene manager used 43 | size_t smgrIndex; 44 | 45 | protected: 46 | ///The RenderWindow that ogre knows 47 | Ogre::RenderWindow* Window; 48 | 49 | ///The Camera 50 | Ogre::Camera* Camera; 51 | Ogre::SceneNode* CameraNode; 52 | 53 | ///The SMGR 54 | Ogre::SceneManager* SceneManager; 55 | 56 | ///The Compositor workspace used 57 | Ogre::CompositorWorkspace* Workspace; 58 | 59 | ///The name of the compositor workspace definition 60 | Ogre::IdString WorkspaceDefName; 61 | 62 | 63 | }; 64 | 65 | #endif // QOGREVIEWPORT_H 66 | -------------------------------------------------------------------------------- /Qt5Ogre21/qtogre21.cpp: -------------------------------------------------------------------------------- 1 | #include "qtogre21.h" 2 | 3 | using namespace std; 4 | 5 | 6 | QtOgre21* QtOgre21::self(nullptr); 7 | size_t QtOgre21::cameraCounter(0); 8 | size_t QtOgre21::workspaceCounter(0); 9 | 10 | QtOgre21::QtOgre21(RenderAPI API, Ogre::String HlmsLibraryPath) : 11 | root{ nullptr }, 12 | glContext{ 0 }, 13 | hlmsPath{ HlmsLibraryPath }, 14 | AALevel{ 8 }, 15 | defaultBackgroundColor{0.2f, 0.4f, 0.6f} 16 | { 17 | if(self) 18 | throw std::runtime_error("Cannot instanciate 2 QtOgre21 objects. This is a singleton class."); 19 | 20 | 21 | threads = uint8_t(std::thread::hardware_concurrency()); 22 | qDebug() << "Detected " << threads << " hardware threads"; 23 | 24 | //Using half the threads for graphics only 25 | threads /= 2; 26 | 27 | qDebug() << "Scene Manager will have " << threads << "worker threads"; 28 | qDebug() << "Init of Ogre for Qt5...\n"; 29 | 30 | //Initialize Ogre Root 31 | root = make_unique("", "ogre.cfg", "ogre.log"); 32 | 33 | 34 | 35 | Ogre::RenderSystem* renderSystem{nullptr}; 36 | 37 | //Register the HLMS 38 | switch(API) 39 | { 40 | case RenderAPI::OpenGL: 41 | qDebug() << "Rendering with OpenGL. Will use GLSL shaders"; 42 | #ifdef QT_DEBUG 43 | root->loadPlugin("./RenderSystem_GL3Plus_d"); 44 | #else 45 | root->loadPlugin("./RenderSystem_GL3Plus"); 46 | #endif 47 | renderSystem = root->getRenderSystemByName(GL3PLUS_RENDERSYSTEM); 48 | shadingLanguage = "GLSL"; 49 | break; 50 | case RenderAPI::DirectX11: 51 | qDebug() << "Rendering with DirectX11. Will use HLSL shaders"; 52 | #ifdef QT_DEBUG 53 | root->loadPlugin("./RenderSystem_DX11_d"); 54 | #else 55 | root->loadPlugin("./RenderSystem_DX11"); 56 | #endif 57 | renderSystem = root->getRenderSystemByName(DIREXTX11_RENDERSYSTEM); 58 | shadingLanguage = "HLSL"; 59 | break; 60 | } 61 | 62 | if(!renderSystem) throw std::runtime_error("Render System is NULLPTR"); 63 | 64 | root->setRenderSystem(renderSystem); 65 | renderSystem->setConfigOption("sRGB Gamma Conversion", "Yes"); 66 | root->initialise(false); 67 | 68 | //Store the singleton address 69 | self = this; 70 | usedAPI = API; 71 | } 72 | 73 | void QtOgre21::createNewScene() 74 | { 75 | scenes.push_back(Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, threads, Ogre::INSTANCING_CULLING_THREADED)); 76 | } 77 | 78 | QtOgre21::WidgetCreationCallbackTuple 79 | QtOgre21::WidgetCreatedCallback(Ogre::RenderWindow *virtualWindow, size_t sceneIndex) 80 | { 81 | Ogre::SceneManager* smgr{nullptr}; 82 | if(scenes.empty()) 83 | { 84 | scenes.push_back(smgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, threads, Ogre::INSTANCING_CULLING_THREADED)); 85 | logToOgre("Just created a scene manager"); 86 | } 87 | else 88 | { 89 | smgr = getScene(sceneIndex); 90 | logToOgre(std::string("Retreived the ") + std::to_string(sceneIndex) +"th scene manager"); 91 | } 92 | 93 | Ogre::Camera* camera = smgr->createCamera("MyCamera" + std::to_string(cameraCounter++)); 94 | 95 | auto compositorManager = root->getCompositorManager2(); 96 | Ogre::String workspaceNameStr; 97 | Ogre::IdString workspaceName; 98 | if(customCompositor.empty()) 99 | { 100 | workspaceNameStr = "MyWorkspace" + std::to_string(workspaceCounter); 101 | workspaceName = workspaceNameStr; 102 | if(!compositorManager->hasWorkspaceDefinition(workspaceName)) 103 | compositorManager->createBasicWorkspaceDef(workspaceNameStr, defaultBackgroundColor); //here I set a background color. The thing I would like to change later. 104 | } 105 | else 106 | { 107 | workspaceNameStr = customCompositor; 108 | workspaceName = customCompositor; 109 | } 110 | 111 | auto workspace = compositorManager->addWorkspace(smgr, virtualWindow, camera, workspaceName, true, int(workspaceCounter++)); 112 | 113 | //if(workspaceCounter == 0) declareHlmsLibrary(hlmsPath.c_str()); 114 | 115 | return std::tie(smgr, camera, workspace, workspaceName); 116 | } 117 | 118 | QtOgre21::~QtOgre21() 119 | { 120 | //Forget the singleton address, because we're destructing 121 | self = nullptr; 122 | } 123 | 124 | QtOgre21* QtOgre21::instance() 125 | { 126 | return self; 127 | } 128 | 129 | Ogre::MeshPtr QtOgre21::loadFromV1Mesh(Ogre::String name) 130 | { 131 | return loadFromV1Mesh(Ogre::v1::MeshManager::getSingleton().load 132 | (name, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, 133 | Ogre::v1::HardwareBuffer::HBU_STATIC, Ogre::v1::HardwareBuffer::HBU_STATIC )); 134 | } 135 | 136 | Ogre::MeshPtr QtOgre21::loadFromV1Mesh(Ogre::v1::MeshPtr v1Mesh) 137 | { 138 | Ogre::MeshPtr v2Mesh; 139 | v2Mesh = Ogre::MeshManager::getSingletonPtr()->createManual(v1Mesh->getName() + "v2", 140 | Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); 141 | 142 | v2Mesh->importV1(v1Mesh.get(), true, true, true); 143 | v1Mesh->unload(); 144 | v1Mesh.setNull(); 145 | 146 | return v2Mesh; 147 | } 148 | 149 | Ogre::SceneManager* QtOgre21::getScene(size_t index) 150 | { 151 | if(index < scenes.size()) 152 | return scenes[index]; 153 | return nullptr; 154 | } 155 | 156 | void QtOgre21::declareHlmsLibrary() 157 | { 158 | Ogre::String hlmsFolder = hlmsPath; 159 | qDebug() << "Loading " << hlmsFolder.c_str() << " as HLMS"; 160 | 161 | if(hlmsFolder.empty()) hlmsFolder = "./"; 162 | else if (hlmsFolder[hlmsFolder.size() - 1] != '/') hlmsFolder += "/"; 163 | 164 | auto hlmsManager = Ogre::Root::getSingleton().getHlmsManager(); 165 | 166 | //Define the shader library to use for HLMS 167 | auto library = Ogre::ArchiveVec(); 168 | auto archiveLibrary = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Common/" + shadingLanguage, "FileSystem", true); 169 | auto archiveLibraryAny = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Common/Any", "FileSystem", true); 170 | library.push_back(archiveLibrary); 171 | library.push_back(archiveLibraryAny); 172 | 173 | auto archiveUnlitAny = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Unlit/Any", "FileSystem", true); 174 | auto archivePbsAny = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Pbs/Any", "FileSystem", true); 175 | 176 | //Define "unlit" and "PBS" (physics based shader) HLMS 177 | auto archiveUnlit = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Unlit/" + shadingLanguage, "FileSystem", true); 178 | auto archivePbs = Ogre::ArchiveManager::getSingleton().load(hlmsFolder + "Hlms/Pbs/" + shadingLanguage, "FileSystem", true); 179 | 180 | library.push_back(archiveUnlitAny); 181 | auto hlmsUnlit = OGRE_NEW Ogre::HlmsUnlit(archiveUnlit, &library); 182 | library.pop_back(); 183 | library.push_back(archivePbsAny); 184 | auto hlmsPbs = OGRE_NEW Ogre::HlmsPbs(archivePbs, &library); 185 | hlmsManager->registerHlms(hlmsUnlit); 186 | hlmsManager->registerHlms(hlmsPbs); 187 | } 188 | 189 | void QtOgre21::willCreateWindowHint() 190 | { 191 | if(workspaceCounter == 0) return; 192 | //Here one window has allready been created 193 | #ifdef _WIN32 194 | if(usedAPI == RenderAPI::OpenGL) 195 | glContext = wglGetCurrentContext(); 196 | else 197 | #endif 198 | glContext = nullptr; 199 | } 200 | 201 | HGLRC QtOgre21::getContext() 202 | { 203 | return glContext; 204 | } 205 | 206 | QtOgre21::RenderAPI QtOgre21::getAPI() 207 | { 208 | return usedAPI; 209 | } 210 | 211 | void QtOgre21::logToOgre(string message) 212 | { 213 | Ogre::LogManager::getSingleton().logMessage(message); 214 | } 215 | 216 | void QtOgre21::setAALevel(uint8_t AA) 217 | { 218 | AALevel = AA; 219 | } 220 | 221 | uint8_t QtOgre21::getAALevel() 222 | { 223 | return AALevel; 224 | } 225 | 226 | void QtOgre21::setDefaultBackgroundColor(const Ogre::ColourValue& c) 227 | { 228 | defaultBackgroundColor = c; 229 | } 230 | 231 | void QtOgre21::setCustomCompositor(const Ogre::String &name) 232 | { 233 | customCompositor = name; 234 | } 235 | -------------------------------------------------------------------------------- /Qt5Ogre21/qtogre21.h: -------------------------------------------------------------------------------- 1 | #ifndef QTOGRE21_H 2 | #define QTOGRE21_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | //Necessary on Non windows platform : 28 | #ifndef _WIN32 29 | using HGLRC = void*; 30 | #endif 31 | 32 | class QtOgre21 33 | { 34 | public: 35 | 36 | using WidgetCreationCallbackTuple = std::tuple; 37 | ///Usable Rendering APIs 38 | enum class RenderAPI{OpenGL, DirectX11}; 39 | 40 | ///Class constructor. this class is singleton 41 | QtOgre21(RenderAPI API, Ogre::String HlmsLibraryPath = "HLMS"); 42 | 43 | ///Class destructor 44 | ~QtOgre21(); 45 | 46 | ///Return the instance of this singleton class 47 | static QtOgre21* instance(); 48 | 49 | ///Helper function that return a V2 mesh from a V1 mesh. V1 mesh will be unallocated 50 | Ogre::MeshPtr loadFromV1Mesh(Ogre::v1::MeshPtr v1Mesh); 51 | 52 | ///Helper function that load the V1 mesh with the given name of a .mesh file known to the resource manager 53 | Ogre::MeshPtr loadFromV1Mesh(Ogre::String name); 54 | 55 | ///Get the `index` scene 56 | Ogre::SceneManager* getScene(size_t index); 57 | 58 | ///Create a Scene and append it to the Scene List 59 | void createNewScene(); 60 | 61 | ///Method called by each viewport widget when it is showed. 62 | WidgetCreationCallbackTuple 63 | WidgetCreatedCallback(Ogre::RenderWindow* virtualWindow, size_t sceneIndex = 0); 64 | 65 | ///Methdo called just before creating a window 66 | void willCreateWindowHint(); 67 | 68 | ///Return the selected API. OpenGL or DirextX 11 69 | RenderAPI getAPI(); 70 | 71 | ///For Windows OpenGL only, return the context of the 1st window. Return null pointer if not relevent 72 | HGLRC getContext(); 73 | 74 | ///Declare to the engine the location of the HLMS library 75 | void declareHlmsLibrary(); 76 | 77 | ///Write a message to Ogre's log 78 | static void logToOgre(std::string message); 79 | 80 | ///Set the AA level 81 | void setAALevel(uint8_t AA); 82 | 83 | ///Get the AA level 84 | uint8_t getAALevel(); 85 | 86 | ///Set the default background color for viewports created after this one: 87 | void setDefaultBackgroundColor(const Ogre::ColourValue &c); 88 | 89 | ///Set the name of a compositor to use. You are responsible for actually loading that compositor resources 90 | void setCustomCompositor(const Ogre::String& name); 91 | 92 | private: 93 | 94 | Ogre::String customCompositor; 95 | 96 | ///The AA level 97 | uint8_t AALevel; 98 | 99 | ///Singleton pointer 100 | static QtOgre21* self; 101 | 102 | ///Name of the SL to use (for finding the correct HLMS to use) 103 | Ogre::String shadingLanguage; 104 | 105 | ///Smart pointer to the Ogre::Root, for automatic Ogre cleanup 106 | std::unique_ptr root; 107 | 108 | ///Name of the OpenGL RenderSystem 109 | static constexpr const char* const GL3PLUS_RENDERSYSTEM{ "OpenGL 3+ Rendering Subsystem" }; 110 | 111 | ///Name of the DirectX 11 RenderSystem 112 | static constexpr const char* const DIREXTX11_RENDERSYSTEM{ "Direct3D11 Rendering Subsystem" }; 113 | 114 | ///Number of threads the SMGRs will use to traverse and cull the geometry 115 | uint8_t threads; 116 | 117 | ///List of the scenes to use 118 | std::vector scenes; 119 | 120 | ///Static counters for uniques names 121 | static size_t cameraCounter, workspaceCounter; 122 | 123 | ///The API we were requested to use. 124 | RenderAPI usedAPI; 125 | 126 | ///Windows OpenGL context 127 | HGLRC glContext; 128 | 129 | ///Path to the HLMS library folder 130 | std::string hlmsPath; 131 | 132 | ///Defautl background color for new viewports 133 | Ogre::ColourValue defaultBackgroundColor; 134 | 135 | }; 136 | 137 | #endif // QTOGRE21_H 138 | -------------------------------------------------------------------------------- /Qt5Ogre21/somecustomwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "somecustomwidget.h" 2 | 3 | SomeCustomWidget::SomeCustomWidget(QWidget *parent) : QWidget(parent) 4 | { 5 | setWindowTitle("Some Window"); 6 | setMinimumSize(100, 100); 7 | resize(1024,768); 8 | 9 | mainLayout = new QVBoxLayout(); 10 | 11 | w = new QOgreViewport; 12 | QtOgre21::instance()->createNewScene(); 13 | w2 = new QOgreViewport(1); 14 | 15 | mainLayout->addWidget(w, 0); 16 | mainLayout->addWidget(w2, 0); 17 | 18 | mainLayout->setContentsMargins(0, 0, 0, 0); 19 | mainLayout->setMargin(0); 20 | mainLayout->setSpacing(0); 21 | 22 | setLayout(mainLayout); 23 | } 24 | -------------------------------------------------------------------------------- /Qt5Ogre21/somecustomwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef SOMECUSTOMWIDGET_H 2 | #define SOMECUSTOMWIDGET_H 3 | 4 | #include 5 | #include 6 | #include "qogreviewport.h" 7 | 8 | class SomeCustomWidget : public QWidget 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit SomeCustomWidget(QWidget *parent = 0); 13 | 14 | QOgreViewport *w, *w2; 15 | 16 | signals: 17 | 18 | public slots: 19 | private: 20 | QVBoxLayout* mainLayout; 21 | }; 22 | 23 | #endif // SOMECUSTOMWIDGET_H 24 | -------------------------------------------------------------------------------- /Qt5Ogre21/test.cpp: -------------------------------------------------------------------------------- 1 | #include "qogreviewport.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "somecustomwidget.h" 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | //Initialize the Qt Application 11 | QApplication a(argc, argv); 12 | 13 | //Initialize the QtOgre system 14 | QtOgre21 qtOgre(QtOgre21::RenderAPI::OpenGL); 15 | 16 | //Create the widget 17 | SomeCustomWidget widget; widget.show(); 18 | auto w = widget.w; 19 | auto w2 = widget.w2; 20 | 21 | //Resource locations 22 | Ogre::ResourceGroupManager::getSingleton().addResourceLocation(".", "FileSystem"); 23 | 24 | //HighLevelMaterialSystem shader libraries 25 | qtOgre.declareHlmsLibrary(); 26 | 27 | //Initialize the resources 28 | Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(true); 29 | 30 | //Setup 1st scene (that is in 1st widget 31 | auto scene = qtOgre.getScene(0); 32 | auto suzanneItem = scene->createItem(qtOgre.loadFromV1Mesh("Suzanne.mesh")); 33 | auto suzanneNode = scene->getRootSceneNode()->createChildSceneNode(); 34 | suzanneNode->attachObject(suzanneItem); 35 | auto sunlight = scene->createLight(); 36 | auto sunNode = scene->getRootSceneNode()->createChildSceneNode(); 37 | sunNode->attachObject(sunlight); 38 | sunlight->setType(Ogre::Light::LT_DIRECTIONAL); 39 | sunlight->setDirection(Ogre::Vector3(-1, -1, -0.5f).normalisedCopy()); 40 | sunlight->setPowerScale(Ogre::Math::PI); 41 | auto Camera = w->getCamera(); 42 | Camera->setPosition(0, 1, 3.5f); 43 | Camera->setAutoAspectRatio(true); 44 | 45 | //Setup 2nd scene (2nd widget) 46 | auto scene2 = qtOgre.getScene(1); 47 | auto knotItem = scene2->createItem(qtOgre.loadFromV1Mesh("knot.mesh")); 48 | auto knotNode = scene2->getRootSceneNode()->createChildSceneNode(); 49 | knotNode->attachObject(knotItem); 50 | knotNode->setScale(0.01f, 0.01f, 0.01f); 51 | auto sunlight2 = scene2->createLight(); 52 | auto sunNode2 = scene2->getRootSceneNode()->createChildSceneNode(); 53 | sunNode2->attachObject(sunlight2); 54 | sunlight2->setType(Ogre::Light::LT_DIRECTIONAL); 55 | sunlight2->setDirection(Ogre::Vector3(-1, -1, -0.5f).normalisedCopy()); 56 | sunlight2->setPowerScale(Ogre::Math::PI); 57 | auto Camera2 = w2->getCamera(); 58 | Camera2->setPosition(0, 2.5, 0); 59 | Camera2->setOrientation(Ogre::Quaternion(Ogre::Degree(-90), 60 | Ogre::Vector3::UNIT_X)); 61 | Camera2->setAutoAspectRatio(true); 62 | 63 | 64 | return a.exec(); 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Qt5Ogre21 2 | Qt 5 integration of Ogre 2.1 3 | 4 | You will need a C++11 complient compier. This code was tested with Visual Studio 2015 on Windows, and with GCC 7 on Linux. 5 | 6 | ![Screenshot](/Screenshot.png) 7 | 8 | The goal is to have multiple viewports of Ogre either running separate or multiple different scenes. 9 | 10 | Design idea 11 | - Initialization of Ogre Root object, and of the HLMS with lifetime tied to a sigle singleton object 12 | - Integration of Qt window events with Ogre 13 | - a QOgreViewport widget class containing an Ogre "external render window", but behave as a simple window. 14 | - Possibility to refresh the viewport at repaint, or at a "user chosen" framerate (30, 60fps) 15 | 16 | *this project is not intended to render games, but to provide an usefull utility for integrating a 3D view to a desktop application, like an editor* 17 | 18 | Since Ogre2 is fairly new, some Ogre1->Ogre2 transition facilities have to be in place, like the runtime convertion of v1 .mesh `MeshSerializer` objects to the new .mesh format. 19 | 20 | ## How to use 21 | 22 | ### Easy integration of Ogre2 into a Qt project via QMake 23 | 24 | This small library is suitable to be put inside your project via [git submodule](https://git-scm.com/book/en/v2/Git-Tools-Submodules) 25 | 26 | Here's what you need to add to the `.pro` file of your application. You just need to specify where Ogre is installed, and the relative path between your project and the folder containing the `.pri` of Qt5Ogre21. 27 | 28 | ```QMake 29 | # Path to Ogre SDK. You can use a OGRE_HOME env var if you want. Check QMake documentation about environement variables 30 | OGRE21SDK = "C:\YbalridSoftware\Ogre21\build\sdk" 31 | 32 | #Path to where the QtOgre project files are. You can use $PWD to get the path of the folder of this .pro 33 | QTOGRE = $${PWD}/../external/Qt5Ogre21/Qt5Ogre21/ 34 | 35 | #The magic include 36 | include($$QTOGRE/Qt5Ogre21.pri) 37 | ``` 38 | 39 | ### What to do in your code 40 | 41 | Create an instance of the QtOgre21 object along side your QApplication. If you don't you can't create QOgreViewport widgets. 42 | 43 | The QtOgre21 constructor takes 2 arguments : 44 | 45 | - The rendering API to use, currently OpenGL or D3D11 46 | - The location of the HLMS library you are using. By defautl it's ./HLMS, meaning that you need to copy the Hlms folder from your ogre sdk there. Only "FileSystem" HLMS libs are supported right now, and it will try to load the PBS and the Unlit ones from the sample. If you're using a custom HLMS, you probably know how to load it and you can go and add that to the code of `QtOgre21::declareHlms()` 47 | 48 | This object is a singleton class, you can access it via calling `QtOgre21::instance()` 49 | 50 | Use QOgreViewport widgets as any other widget in Qt. You can have different scenes. Creating a new scene is done via the QtOgre21 object. 51 | 52 | If you want to do that in your `main()` it would look a little like this: 53 | 54 | ```C++ 55 | int main(int argc, char *argv[]) 56 | { 57 | //Initialize the Qt Application 58 | QApplication a(argc, argv); 59 | 60 | //Initialize the QtOgre system 61 | QtOgre21 qtOgre(QtOgre21::RenderAPI::OpenGL); 62 | 63 | //Here you can create widget with viewports (this is actually needed for initializing the rendering API) 64 | //and .show() them! 65 | 66 | //Resource locations 67 | Ogre::ResourceGroupManager::getSingleton().addResourceLocation(".", "FileSystem"); 68 | 69 | //HighLevelMaterialSystem shader libraries 70 | qtOgre.declareHlmsLibrary(); 71 | 72 | //Initialize the resources 73 | Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(true); 74 | 75 | //get the scene manager 76 | auto scene = qtOgre.getScene(0); 77 | 78 | //here you can do whatever you would do with an Ogre::SceneManager 79 | 80 | return a.exec() 81 | } 82 | ``` 83 | 84 | More explicitely: When creating a first QOgreViewport the 1st time, Ogre will finish the RenderSystem intialization, because it needs a "window" object existing to setup the rendering pipeline. (For Ogre it's "a window" but for you it's just a Qt widget.) 85 | 86 | Also, when doing that, it will create a first scene manager that will serve as the default one. 87 | 88 | An additional scene can be created when calling `QtOgre21::instance()->createNewScene();`. QtOgre21 store them as an array, and you will be able to get the scene by their index. 89 | 90 | The default scene is index `0`, the 1st additional one is `1`, etc... 91 | 92 | When calling the QOgreViewport constructor, you can specify a "scene manager index" as an argument, when doing this, it will render that scene. 93 | 94 | A viewport is automatically attached to a camera via an Ogre2.1 "basic" compositor, and ready to render. I'm planning to add a way to specify a compositor to use, but it's not done yet. For now this is suitable for all your classic rendering needs without post-processing (Donw worry, Anti Aliasing *is* supported) 95 | 96 | Viewports have 2 important methods for you : getCamera() and getSmgr(). Everything esle is usable as any Ogre feature. For everything else, they behave just like bare QWidgets. 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ybalrid/Qt5Ogre21/68d48f3c155b5e71c86ba869e43e1b28a8801f7e/Screenshot.png -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/Any/ShadowCaster_piece_ps.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | 4 | ///-------------------------------------------------------------------------------------- 5 | /// Caster 6 | ///-------------------------------------------------------------------------------------- 7 | 8 | @piece( DeclShadowCasterMacros ) 9 | @property( syntax == glsl ) 10 | @property( !hlms_render_depth_only ) 11 | @property( GL3+ ) 12 | #define outDepth outColour 13 | @end 14 | @property( !GL3+ ) 15 | #define outDepth gl_FragColor 16 | @end 17 | @end 18 | @property( hlms_render_depth_only ) 19 | #define outDepth gl_FragDepth 20 | @end 21 | @end 22 | 23 | @property( syntax == hlsl || syntax == metal ) 24 | #define outDepth outPs.colour0 25 | @end 26 | @end 27 | 28 | @piece( DoShadowCastPS ) 29 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 30 | outDepth = inPs.depth; 31 | @end 32 | @property( hlms_shadowcaster_point ) 33 | float distanceToCamera = length( inPs.toCameraWS ); 34 | @property( !exponential_shadow_maps ) 35 | outDepth = (distanceToCamera - passBuf.depthRange.x) * passBuf.depthRange.y + inPs.constBias; 36 | @end @property( exponential_shadow_maps ) 37 | outDepth = (distanceToCamera - passBuf.depthRange.x) * passBuf.depthRange.y; 38 | @end 39 | @end 40 | @end 41 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/Any/ShadowCaster_piece_vs.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | 4 | @property( hlms_shadowcaster ) 5 | @piece( DoShadowCasterVS ) 6 | @property( syntax == glsl ) 7 | float shadowConstantBias = uintBitsToFloat( instance.worldMaterialIdx[drawId].y ); 8 | @end 9 | @property( syntax == hlsl ) 10 | float shadowConstantBias = asfloat( worldMaterialIdx[input.drawId].y ); 11 | @end 12 | @property( syntax == metal ) 13 | float shadowConstantBias = as_type( worldMaterialIdx[drawId].y ); 14 | @end 15 | 16 | @property( !hlms_shadow_uses_depth_texture && !hlms_shadowcaster_point && !exponential_shadow_maps ) 17 | //Linear depth 18 | outVs.depth = (outVs_Position.z + shadowConstantBias * passBuf.depthRange.y) * passBuf.depthRange.y; 19 | @property( syntax == glsl )outVs.depth = (outVs.depth * 0.5) + 0.5;@end 20 | @end 21 | 22 | @property( hlms_shadowcaster_point ) 23 | outVs.toCameraWS = worldPos.xyz - passBuf.cameraPosWS.xyz; 24 | @property( !exponential_shadow_maps ) 25 | outVs.constBias = shadowConstantBias * passBuf.depthRange.y * passBuf.depthRange.y; 26 | @end 27 | @end 28 | 29 | @property( !exponential_shadow_maps ) 30 | //We can't make the depth buffer linear without Z out in the fragment shader; 31 | //however we can use a cheap approximation ("pseudo linear depth") 32 | //see http://www.yosoygames.com.ar/wp/2014/01/linear-depth-buffer-my-ass/ 33 | outVs_Position.z = (outVs_Position.z + shadowConstantBias * passBuf.depthRange.y) * passBuf.depthRange.y * outVs_Position.w; 34 | @end 35 | 36 | @property( exponential_shadow_maps && !hlms_shadowcaster_point ) 37 | //It's the same as (float4( worldPos.xyz, 1 ) * viewMatrix).z 38 | float linearZ = -(dot( worldPos.xyz, passBuf.viewZRow.xyz ) + passBuf.viewZRow.w); 39 | //linearZ += (shadowConstantBias * passBuf.depthRange.y); 40 | outVs.depth = (linearZ - passBuf.depthRange.x) * passBuf.depthRange.y; 41 | @end 42 | @end 43 | @end 44 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/GLSL/CrossPlatformSettings_piece_all.glsl: -------------------------------------------------------------------------------- 1 | @piece( SetCrossPlatformSettings ) 2 | @property( GL3+ >= 430 )#version 430 core 3 | @end @property( GL3+ < 430 ) 4 | #version 330 core 5 | #extension GL_ARB_shading_language_420pack: require 6 | @end 7 | 8 | #define float2 vec2 9 | #define float3 vec3 10 | #define float4 vec4 11 | 12 | #define int2 ivec2 13 | #define int3 ivec3 14 | #define int4 ivec4 15 | 16 | #define uint2 uvec2 17 | #define uint3 uvec3 18 | #define uint4 uvec4 19 | 20 | #define float3x3 mat3 21 | #define float4x4 mat4 22 | 23 | #define mul( x, y ) ((x) * (y)) 24 | #define saturate(x) clamp( (x), 0.0, 1.0 ) 25 | #define lerp mix 26 | #define INLINE 27 | 28 | #define outVs_Position gl_Position 29 | #define OGRE_SampleLevel( tex, sampler, uv, lod ) textureLod( tex, uv.xy, lod ) 30 | @end 31 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/GLSL/Matrix_piece_all.glsl: -------------------------------------------------------------------------------- 1 | @piece( Common_Matrix_DeclUnpackMatrix4x4 ) 2 | mat4 UNPACK_MAT4( samplerBuffer matrixBuf, uint pixelIdx ) 3 | { 4 | vec4 row0 = texelFetch( matrixBuf, int((pixelIdx) << 2u) ); 5 | vec4 row1 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 1u) ); 6 | vec4 row2 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 2u) ); 7 | vec4 row3 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 3u) ); 8 | return mat4( row0, row1, row2, row3 ); 9 | } 10 | @end 11 | 12 | @piece( Common_Matrix_DeclUnpackMatrix3x4 ) 13 | mat3x4 UNPACK_MAT3x4( samplerBuffer matrixBuf, uint pixelIdx ) 14 | { 15 | vec4 row0 = texelFetch( matrixBuf, int((pixelIdx) << 2u) ); 16 | vec4 row1 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 1u) ); 17 | vec4 row2 = texelFetch( matrixBuf, int(((pixelIdx) << 2u) + 2u) ); 18 | return mat3x4( row0, row1, row2 ); 19 | } 20 | @end 21 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/GLSL/QuaternionCode_piece_all.glsl: -------------------------------------------------------------------------------- 1 | @piece( DeclQuat_xAxis ) 2 | vec3 xAxis( vec4 qQuat ) 3 | { 4 | float fTy = 2.0 * qQuat.y; 5 | float fTz = 2.0 * qQuat.z; 6 | float fTwy = fTy * qQuat.w; 7 | float fTwz = fTz * qQuat.w; 8 | float fTxy = fTy * qQuat.x; 9 | float fTxz = fTz * qQuat.x; 10 | float fTyy = fTy * qQuat.y; 11 | float fTzz = fTz * qQuat.z; 12 | 13 | return vec3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); 14 | } 15 | @end 16 | 17 | @piece( DeclQuat_yAxis ) 18 | vec3 yAxis( vec4 qQuat ) 19 | { 20 | float fTx = 2.0 * qQuat.x; 21 | float fTy = 2.0 * qQuat.y; 22 | float fTz = 2.0 * qQuat.z; 23 | float fTwx = fTx * qQuat.w; 24 | float fTwz = fTz * qQuat.w; 25 | float fTxx = fTx * qQuat.x; 26 | float fTxy = fTy * qQuat.x; 27 | float fTyz = fTz * qQuat.y; 28 | float fTzz = fTz * qQuat.z; 29 | 30 | return vec3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); 31 | } 32 | @end 33 | 34 | @piece( DeclQuat_zAxis ) 35 | vec3 zAxis( vec4 qQuat ) 36 | { 37 | float fTx = 2.0 * qQuat.x; 38 | float fTy = 2.0 * qQuat.y; 39 | float fTz = 2.0 * qQuat.z; 40 | float fTwx = fTx * qQuat.w; 41 | float fTwy = fTy * qQuat.w; 42 | float fTxx = fTx * qQuat.x; 43 | float fTxz = fTz * qQuat.x; 44 | float fTyy = fTy * qQuat.y; 45 | float fTyz = fTz * qQuat.y; 46 | 47 | return vec3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); 48 | } 49 | @end 50 | 51 | @piece( DeclQuat_AllAxis ) 52 | @insertpiece( DeclQuat_xAxis ) 53 | @insertpiece( DeclQuat_yAxis ) 54 | @insertpiece( DeclQuat_zAxis ) 55 | @end 56 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/HLSL/CrossPlatformSettings_piece_all.hlsl: -------------------------------------------------------------------------------- 1 | @piece( SetCrossPlatformSettings ) 2 | #define INLINE 3 | #define outVs_Position outVs.gl_Position 4 | #define OGRE_SampleLevel( tex, sampler, uv, lod ) tex.SampleLevel( sampler, uv.xy, lod ) 5 | @end 6 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/HLSL/Matrix_piece_all.hlsl: -------------------------------------------------------------------------------- 1 | @piece( Common_Matrix_DeclUnpackMatrix4x4 ) 2 | float4x4 UNPACK_MAT4( Buffer matrixBuf, uint pixelIdx ) 3 | { 4 | float4 row1 = matrixBuf.Load( int((pixelIdx) << 2u) ); 5 | float4 row2 = matrixBuf.Load( int(((pixelIdx) << 2u) + 1u) ); 6 | float4 row3 = matrixBuf.Load( int(((pixelIdx) << 2u) + 2u) ); 7 | float4 row4 = matrixBuf.Load( int(((pixelIdx) << 2u) + 3u) ); 8 | 9 | return transpose( float4x4( row1, row2, row3, row4 ) ); 10 | } 11 | @end 12 | 13 | @piece( Common_Matrix_DeclUnpackMatrix4x3 ) 14 | float4x3 UNPACK_MAT4x3( Buffer matrixBuf, uint pixelIdx ) 15 | { 16 | float4 row1 = matrixBuf.Load( int((pixelIdx) << 2u) ); 17 | float4 row2 = matrixBuf.Load( int(((pixelIdx) << 2u) + 1u) ); 18 | float4 row3 = matrixBuf.Load( int(((pixelIdx) << 2u) + 2u) ); 19 | 20 | return transpose( float3x4( row1, row2, row3 ) ); 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Common/HLSL/QuaternionCode_piece_all.hlsl: -------------------------------------------------------------------------------- 1 | @piece( DeclQuat_xAxis ) 2 | float3 xAxis( float4 qQuat ) 3 | { 4 | float fTy = 2.0 * qQuat.y; 5 | float fTz = 2.0 * qQuat.z; 6 | float fTwy = fTy * qQuat.w; 7 | float fTwz = fTz * qQuat.w; 8 | float fTxy = fTy * qQuat.x; 9 | float fTxz = fTz * qQuat.x; 10 | float fTyy = fTy * qQuat.y; 11 | float fTzz = fTz * qQuat.z; 12 | 13 | return float3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); 14 | } 15 | @end 16 | 17 | @piece( DeclQuat_yAxis ) 18 | float3 yAxis( float4 qQuat ) 19 | { 20 | float fTx = 2.0 * qQuat.x; 21 | float fTy = 2.0 * qQuat.y; 22 | float fTz = 2.0 * qQuat.z; 23 | float fTwx = fTx * qQuat.w; 24 | float fTwz = fTz * qQuat.w; 25 | float fTxx = fTx * qQuat.x; 26 | float fTxy = fTy * qQuat.x; 27 | float fTyz = fTz * qQuat.y; 28 | float fTzz = fTz * qQuat.z; 29 | 30 | return float3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); 31 | } 32 | @end 33 | 34 | @piece( DeclQuat_zAxis ) 35 | float3 zAxis( float4 qQuat ) 36 | { 37 | float fTx = 2.0 * qQuat.x; 38 | float fTy = 2.0 * qQuat.y; 39 | float fTz = 2.0 * qQuat.z; 40 | float fTwx = fTx * qQuat.w; 41 | float fTwy = fTy * qQuat.w; 42 | float fTxx = fTx * qQuat.x; 43 | float fTxz = fTz * qQuat.x; 44 | float fTyy = fTy * qQuat.y; 45 | float fTyz = fTz * qQuat.y; 46 | 47 | return float3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); 48 | } 49 | @end 50 | 51 | @piece( DeclQuat_AllAxis ) 52 | @insertpiece( DeclQuat_xAxis ) 53 | @insertpiece( DeclQuat_yAxis ) 54 | @insertpiece( DeclQuat_zAxis ) 55 | @end 56 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/Any/PlanarReflections_piece_all.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | 4 | @property( !has_planar_reflections ) 5 | @set( use_planar_reflections, 0 ) 6 | @end 7 | 8 | @property( has_planar_reflections ) 9 | 10 | @piece( DeclPlanarReflUniforms ) 11 | float4 planarReflections[@value(has_planar_reflections)]; 12 | float4x4 planarReflProjectionMat; 13 | float4 invMaxDistanceToPlanarRefl; 14 | @end 15 | 16 | @end ///has_planar_reflections 17 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/Any/PlanarReflections_piece_ps.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | 4 | @property( use_planar_reflections ) 5 | 6 | @property( syntax == glsl ) 7 | @piece( DeclPlanarReflTextures ) 8 | uniform sampler2D planarReflectionTex; 9 | @end 10 | @end 11 | @property( syntax == hlsl ) 12 | @piece( DeclPlanarReflTextures ) 13 | Texture2D planarReflectionTex : register(t@value(planarReflectionTexUnit)); 14 | SamplerState planarReflectionSampler : register(s@value(planarReflectionTexUnit)); 15 | @end 16 | @end 17 | @property( syntax == metal ) 18 | @piece( DeclPlanarReflTextures ) 19 | , texture2d planarReflectionTex [[texture(@value(planarReflectionTexUnit))]] 20 | , sampler planarReflectionSampler [[sampler(@value(planarReflectionTexUnit))]] 21 | @end 22 | @end 23 | 24 | @piece( DoPlanarReflectionsPS ) 25 | @property( syntax == glsl ) 26 | uint planarReflectionIdx = instance.worldMaterialIdx[inPs.drawId].w; 27 | @end 28 | @property( syntax == hlsl ) 29 | uint planarReflectionIdx = worldMaterialIdx[inPs.drawId].w; 30 | @end 31 | @property( syntax == metal ) 32 | ushort planarReflectionIdx = inPs.planarReflectionIdx; 33 | @end 34 | 35 | float4 planarReflection = passBuf.planarReflections[planarReflectionIdx]; 36 | float distanceToPlanarReflPlane = dot( planarReflection.xyz, inPs.pos.xyz ) + planarReflection.w; 37 | float3 pointInPlane = inPs.pos.xyz - nNormal * distanceToPlanarReflPlane; 38 | float3 projPointInPlane = mul( float4( pointInPlane.xyz, 1.0 ), passBuf.planarReflProjectionMat ).xyw; 39 | float2 planarReflUVs = projPointInPlane.xy / projPointInPlane.z; 40 | 41 | float3 planarReflectionS = OGRE_SampleLevel( planarReflectionTex, planarReflectionSampler, 42 | planarReflUVs.xy, ROUGHNESS * 12.0 ).xyz; 43 | 44 | //Fade out as our surface gets away from the reflection plane (planarWeight = 0 means fully faded out) 45 | float planarWeight = max( 1.0 - abs( distanceToPlanarReflPlane ) * passBuf.invMaxDistanceToPlanarRefl.x, 0.0 ); 46 | planarWeight = sqrt( planarWeight ); 47 | planarWeight = smoothstep( 0.0, 1.0, planarWeight ); 48 | //Fade out if projecting pointInPlane failed (we landed outside the screen, we have no information) 49 | float2 boundary = abs( planarReflUVs.xy - float2(0.5, 0.5) ) * 2.0; 50 | float fadeOnBorder = 1.0 - saturate( (boundary.x - 0.975) * 40 ); 51 | fadeOnBorder *= 1.0 - saturate( (boundary.y - 0.975) * 40 ); 52 | fadeOnBorder = smoothstep( 0.0, 1.0, fadeOnBorder ); 53 | planarWeight *= lerp( fadeOnBorder, 1.0, 1.0 - min( abs(distanceToPlanarReflPlane) * 1000.0, 1.0 ) ); 54 | //Fade out across a 20° tolerance between surface normal and reflection plane. 55 | // (x - cos20) / (1-cos20); 56 | // x/(1-cos20) - cos20/(1-cos20); 57 | // x * 16.581718739 - 15.581718739; 58 | planarWeight *= saturate( dot( planarReflection.xyz, nNormal.xyz ) * 16.581718739 - 15.581718739 ); 59 | @property( hlms_use_ssr || ((envprobe_map && envprobe_map != target_envprobe_map) || parallax_correct_cubemaps) ) 60 | envColourS = lerp( envColourS, planarReflectionS, planarWeight ); 61 | @end @property( !hlms_use_ssr && !((envprobe_map && envprobe_map != target_envprobe_map) || parallax_correct_cubemaps) ) 62 | float3 envColourS = planarReflectionS * planarWeight; 63 | float3 envColourD = float3( 0, 0, 0 ); 64 | @end 65 | @end 66 | 67 | @end ///use_planar_reflections 68 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/Any/ShadowMapping_piece_vs.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | 4 | @property( !hlms_shadowcaster ) 5 | @property( !exponential_shadow_maps ) 6 | @piece( DoShadowReceiveVS ) 7 | @foreach( hlms_num_shadow_map_lights, n ) 8 | @property( !hlms_shadowmap@n_is_point_light ) 9 | outVs.posL@n = mul( float4(worldPos.xyz, 1.0f), passBuf.shadowRcv[@n].texViewProj );@end @end 10 | 11 | @foreach( hlms_num_shadow_map_lights, n ) 12 | @property( !hlms_shadowmap@n_is_point_light ) 13 | outVs.posL@n.z = outVs.posL@n.z * passBuf.shadowRcv[@n].shadowDepthRange.y; 14 | @property( syntax == glsl )outVs.posL@n.z = (outVs.posL@n.z * 0.5) + 0.5;@end 15 | @end 16 | @end 17 | 18 | @property( hlms_pssm_splits )outVs.depth = outVs_Position.z;@end 19 | @end 20 | @end 21 | @property( exponential_shadow_maps ) 22 | @piece( DoShadowReceiveVS ) 23 | @foreach( hlms_num_shadow_map_lights, n ) 24 | @property( !hlms_shadowmap@n_is_point_light ) 25 | outVs.posL@n = mul( float4(worldPos.xyz, 1.0f), passBuf.shadowRcv[@n].texViewProj );@end @end 26 | 27 | @foreach( hlms_num_shadow_map_lights, n ) 28 | @property( !hlms_shadowmap@n_is_point_light ) 29 | //It's the same as (float4( worldPos.xyz, 1 ) * texViewMatrix).z 30 | outVs.posL@n.z = -(dot( worldPos.xyz, passBuf.shadowRcv[@n].texViewZRow.xyz ) + passBuf.shadowRcv[@n].texViewZRow.w); 31 | outVs.posL@n.z = (outVs.posL@n.z - passBuf.shadowRcv[@n].shadowDepthRange.x) 32 | * passBuf.shadowRcv[@n].shadowDepthRange.y; 33 | @end 34 | @end 35 | 36 | @property( hlms_pssm_splits )outVs.depth = outVs_Position.z;@end 37 | @end 38 | @end 39 | @end 40 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/GLSL/BlendModes_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @property( !hlms_shadowcaster ) 5 | @piece( NormalNonPremul ) 6 | //Normal Non Premultiplied @value(t) 7 | diffuseCol.xyz = mix( diffuseCol.xyz, detailCol@value(t).xyz, detailCol@value(t).a ); 8 | diffuseCol.w = mix( diffuseCol.w, 1.0, detailCol@value(t).w ); 9 | @end 10 | 11 | @piece( NormalPremul ) 12 | //Normal Premultiplied @value(t) 13 | diffuseCol.xyz = (1.0 - detailCol@value(t).a) * diffuseCol.xyz + detailCol@value(t).xyz; 14 | diffuseCol.w = mix( diffuseCol.w, 1.0, detailCol@value(t).w ); 15 | @end 16 | 17 | @piece( Add ) 18 | //Add @value(t) 19 | diffuseCol.xyz = mix( diffuseCol.xyz, 20 | min( diffuseCol.xyz + detailCol@value(t).xyz, vec3(1.0, 1.0, 1.0) ), 21 | detailCol@value(t).a ); 22 | @end 23 | 24 | @piece( Subtract ) 25 | //Subtract @value(t) 26 | diffuseCol.xyz = mix( diffuseCol.xyz, 27 | max( diffuseCol.xyz - detailCol@value(t).xyz, vec3(0.0, 0.0, 0.0) ), 28 | detailCol@value(t).a ); 29 | @end 30 | 31 | @piece( Multiply ) 32 | //Multiply @value(t) 33 | diffuseCol.xyz = mix( diffuseCol.xyz, 34 | diffuseCol.xyz * detailCol@value(t).xyz, 35 | detailCol@value(t).a ); 36 | @end 37 | 38 | @piece( Multiply2x ) 39 | //Multiply2x @value(t) 40 | diffuseCol.xyz = mix( diffuseCol.xyz, 41 | min( diffuseCol.xyz * detailCol@value(t).xyz * 2.0, vec3(1.0, 1.0, 1.0) ), 42 | detailCol@value(t).a ); 43 | @end 44 | 45 | @piece( Screen ) 46 | //Screen @value(t) 47 | diffuseCol.xyz = mix( diffuseCol.xyz, 48 | 1.0 - (1.0 - diffuseCol.xyz) * (1.0 - detailCol@value(t).xyz), 49 | detailCol@value(t).a ); 50 | @end 51 | 52 | @piece( Overlay ) 53 | //Overlay @value(t) 54 | diffuseCol.xyz = mix( diffuseCol.xyz, 55 | diffuseCol.xyz * ( diffuseCol.xyz + 2.0 * detailCol@value(t).xyz * (1.0 - diffuseCol.xyz) ), 56 | detailCol@value(t).a ); 57 | @end 58 | 59 | @piece( Lighten ) 60 | //Lighten @value(t) 61 | diffuseCol.xyz = mix( diffuseCol.xyz, 62 | max( diffuseCol.xyz, detailCol@value(t).xyz ), 63 | detailCol@value(t).a ); 64 | @end 65 | 66 | @piece( Darken ) 67 | //Darken @value(t) 68 | diffuseCol.xyz = mix( diffuseCol.xyz, 69 | min( diffuseCol.xyz, detailCol@value(t).xyz ), 70 | detailCol@value(t).a ); 71 | @end 72 | 73 | @piece( GrainExtract ) 74 | //GrainExtract @value(t) 75 | diffuseCol.xyz = mix( diffuseCol.xyz, 76 | (diffuseCol.xyz - detailCol@value(t).xyz) + 0.5f, 77 | detailCol@value(t).a ); 78 | @end 79 | 80 | @piece( GrainMerge ) 81 | //GrainMerge @value(t) 82 | diffuseCol.xyz = mix( diffuseCol.xyz, 83 | (diffuseCol.xyz + detailCol@value(t).xyz) - 0.5f, 84 | detailCol@value(t).a ); 85 | @end 86 | 87 | @piece( Difference ) 88 | //Difference @value(t) 89 | diffuseCol.xyz = mix( diffuseCol.xyz, 90 | abs(diffuseCol.xyz - detailCol@value(t).xyz), 91 | detailCol@value(t).a ); 92 | @end 93 | @end @property( hlms_shadowcaster ) 94 | 95 | @piece( NormalNonPremul ) 96 | //Normal Non Premultiplied @value(t) 97 | diffuseCol = mix( diffuseCol, 1.0, detailCol@value(t) ); 98 | @end 99 | 100 | @piece( NormalPremul ) 101 | //Normal Premultiplied @value(t) 102 | diffuseCol = mix( diffuseCol, 1.0, detailCol@value(t) ); 103 | @end 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/GLSL/DetailMaps_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | // detail_maps_diffuse & detail_maps_normal are either 0 or 4 2 | 3 | @foreach( detail_maps_diffuse, n ) 4 | @property( detail_offsetsD@n ) 5 | @piece( offsetDetailD@n ) * material.detailOffsetScaleD[@value(currOffsetDetailD)].zw + material.detailOffsetScaleD[@counter(currOffsetDetailD)].xy@end 6 | @end 7 | @end 8 | @foreach( detail_maps_normal, n ) 9 | @property( detail_offsetsN@n ) 10 | @piece( offsetDetailN@n ) * material.detailOffsetScaleN[@value(currOffsetDetailN)].zw + material.detailOffsetScaleN[@counter(currOffsetDetailN)].xy@end 11 | @end 12 | @end 13 | 14 | @piece( detail_swizzle0 )x@end; 15 | @piece( detail_swizzle1 )y@end; 16 | @piece( detail_swizzle2 )z@end; 17 | @piece( detail_swizzle3 )w@end; 18 | 19 | /* 20 | Down below we perform: 21 | if( detail_maps_normal ) 22 | second_valid_detail_map_nm = first_valid_detail_map_nm + 1; 23 | else 24 | second_valid_detail_map_nm = 0; 25 | */ 26 | @property( detail_maps_normal ) 27 | @add( second_valid_detail_map_nm, first_valid_detail_map_nm, 1 ) 28 | @end @property( !detail_maps_normal ) 29 | @set( second_valid_detail_map_nm, 0 ) 30 | @end 31 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/GLSL/Structs_piece_vs_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @piece( PassDecl ) 2 | struct ShadowReceiverData 3 | { 4 | mat4 texViewProj; 5 | @property( exponential_shadow_maps ) 6 | vec4 texViewZRow; 7 | @end 8 | vec2 shadowDepthRange; 9 | vec4 invShadowMapSize; 10 | }; 11 | 12 | struct Light 13 | { 14 | vec4 position; //.w contains the objLightMask 15 | vec3 diffuse; 16 | vec3 specular; 17 | @property( hlms_num_shadow_map_lights ) 18 | vec3 attenuation; 19 | vec3 spotDirection; 20 | vec3 spotParams; 21 | @end 22 | }; 23 | 24 | @insertpiece( DeclCubemapProbeStruct ) 25 | 26 | //Uniforms that change per pass 27 | layout(binding = 0) uniform PassBuffer 28 | { 29 | //Vertex shader (common to both receiver and casters) 30 | mat4 viewProj; 31 | 32 | @property( hlms_global_clip_distances ) 33 | vec4 clipPlane0; 34 | @end 35 | 36 | @property( hlms_shadowcaster_point ) 37 | vec4 cameraPosWS; //Camera position in world space 38 | @end 39 | 40 | @property( !hlms_shadowcaster ) 41 | //Vertex shader 42 | mat4 view; 43 | @property( hlms_num_shadow_map_lights )ShadowReceiverData shadowRcv[@value(hlms_num_shadow_map_lights)];@end 44 | 45 | //------------------------------------------------------------------------- 46 | 47 | //Pixel shader 48 | mat3 invViewMatCubemap; 49 | 50 | 51 | @property( hlms_use_prepass ) 52 | vec4 windowHeight; 53 | @end 54 | 55 | @property( ambient_hemisphere || ambient_fixed || envmap_scale ) 56 | vec4 ambientUpperHemi; 57 | @end 58 | @property( ambient_hemisphere ) 59 | vec4 ambientLowerHemi; 60 | vec4 ambientHemisphereDir; 61 | @end 62 | 63 | @property( irradiance_volumes ) 64 | vec4 irradianceOrigin; //.w = maxPower 65 | vec4 irradianceSize; //.w = 1.0f / irradianceTexture->getHeight() 66 | mat4 invView; 67 | @end 68 | 69 | @property( hlms_pssm_splits )@foreach( hlms_pssm_splits, n ) 70 | float pssmSplitPoints@n;@end @end 71 | @property( hlms_lights_spot )Light lights[@value(hlms_lights_spot)];@end 72 | @end @property( hlms_shadowcaster ) 73 | //Vertex shader 74 | @property( exponential_shadow_maps )vec4 viewZRow;@end 75 | vec2 depthRange; 76 | @end 77 | 78 | @property( hlms_forwardplus ) 79 | //Forward3D 80 | //f3dData.x = minDistance; 81 | //f3dData.y = invMaxDistance; 82 | //f3dData.z = f3dNumSlicesSub1; 83 | //f3dData.w = uint cellsPerTableOnGrid0 (floatBitsToUint); 84 | 85 | //Clustered Forward: 86 | //f3dData.x = minDistance; 87 | //f3dData.y = invExponentK; 88 | //f3dData.z = f3dNumSlicesSub1; 89 | //f3dData.w = renderWindow->getHeight(); 90 | vec4 f3dData; 91 | @property( hlms_forwardplus == forward3d ) 92 | vec4 f3dGridHWW[@value( forward3d_num_slices )]; 93 | @end 94 | @property( hlms_forwardplus != forward3d ) 95 | vec4 fwdScreenToGrid; 96 | @end 97 | @end 98 | 99 | @insertpiece( DeclPlanarReflUniforms ) 100 | 101 | @property( parallax_correct_cubemaps ) 102 | CubemapProbe autoProbe; 103 | @end 104 | 105 | @insertpiece( custom_passBuffer ) 106 | } passBuf; 107 | @end 108 | 109 | @property( fresnel_scalar )@piece( FresnelType )vec3@end @piece( FresnelSwizzle )xyz@end @end 110 | @property( !fresnel_scalar )@piece( FresnelType )float@end @piece( FresnelSwizzle )x@end @end 111 | 112 | @piece( MaterialDecl ) 113 | //Uniforms that change per Item/Entity, but change very infrequently 114 | struct Material 115 | { 116 | /* kD is already divided by PI to make it energy conserving. 117 | (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) 118 | */ 119 | vec4 bgDiffuse; 120 | vec4 kD; //kD.w is alpha_test_threshold 121 | vec4 kS; //kS.w is roughness 122 | //Fresnel coefficient, may be per colour component (vec3) or scalar (float) 123 | //F0.w is transparency 124 | vec4 F0; 125 | vec4 normalWeights; 126 | vec4 cDetailWeights; 127 | vec4 detailOffsetScaleD[4]; 128 | vec4 detailOffsetScaleN[4]; 129 | 130 | uvec4 indices0_3; 131 | //uintBitsToFloat( indices4_7.w ) contains mNormalMapWeight. 132 | uvec4 indices4_7; 133 | }; 134 | 135 | layout(binding = 1) uniform MaterialBuf 136 | { 137 | Material m[@value( materials_per_buffer )]; 138 | } materialArray; 139 | @end 140 | 141 | @piece( InstanceDecl ) 142 | //Uniforms that change per Item/Entity 143 | layout(binding = 2) uniform InstanceBuffer 144 | { 145 | //.x = 146 | //The lower 9 bits contain the material's start index. 147 | //The higher 23 bits contain the world matrix start index. 148 | // 149 | //.y = 150 | //shadowConstantBias. Send the bias directly to avoid an 151 | //unnecessary indirection during the shadow mapping pass. 152 | //Must be loaded with uintBitsToFloat 153 | // 154 | //.z = 155 | //lightMask. Ogre must have been compiled with OGRE_NO_FINE_LIGHT_MASK_GRANULARITY 156 | uvec4 worldMaterialIdx[4096]; 157 | } instance; 158 | @end 159 | 160 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 161 | @piece( PccManualProbeDecl ) 162 | layout(binding = 3) uniform ManualProbe 163 | { 164 | CubemapProbe probe; 165 | } manualProbe; 166 | @end 167 | @end 168 | 169 | @piece( VStoPS_block ) 170 | @property( !hlms_shadowcaster ) 171 | @property( !lower_gpu_overhead ) 172 | flat uint drawId; 173 | @end 174 | @property( hlms_normal || hlms_qtangent ) 175 | vec3 pos; 176 | vec3 normal; 177 | @property( normal_map )vec3 tangent; 178 | @property( hlms_qtangent )flat float biNormalReflection;@end 179 | @end 180 | @end 181 | @foreach( hlms_uv_count, n ) 182 | vec@value( hlms_uv_count@n ) uv@n;@end 183 | 184 | @foreach( hlms_num_shadow_map_lights, n ) 185 | @property( !hlms_shadowmap@n_is_point_light ) 186 | vec4 posL@n;@end @end 187 | @property( hlms_pssm_splits )float depth;@end 188 | @property( hlms_use_prepass_msaa > 1 ) 189 | float2 zwDepth; 190 | @end 191 | @end 192 | @property( hlms_shadowcaster ) 193 | @property( alpha_test ) 194 | flat uint drawId; 195 | @foreach( hlms_uv_count, n ) 196 | vec@value( hlms_uv_count@n ) uv@n;@end 197 | @end 198 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 199 | float depth; 200 | @end 201 | @property( hlms_shadowcaster_point ) 202 | vec3 toCameraWS; 203 | @property( !exponential_shadow_maps ) 204 | flat float constBias; 205 | @end 206 | @end 207 | @end 208 | @insertpiece( custom_VStoPS ) 209 | @end 210 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/GLSL/Textures_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @property( diffuse_map ) 2 | @property( !hlms_shadowcaster ) 3 | @piece( SampleDiffuseMap ) diffuseCol = texture( textureMaps[@value( diffuse_map_idx )], vec3( inPs.uv@value(uv_diffuse).xy, diffuseIdx ) ); 4 | @property( !hw_gamma_read ) diffuseCol = diffuseCol * diffuseCol;@end @end 5 | @end @property( hlms_shadowcaster ) 6 | @piece( SampleDiffuseMap ) diffuseCol = texture( textureMaps[@value( diffuse_map_idx )], vec3( inPs.uv@value(uv_diffuse).xy, diffuseIdx ) ).w;@end 7 | @end 8 | @end 9 | 10 | //diffuseCol always has some colour and is multiplied against material.kD in PixelShader_ps. 11 | @piece( kD )diffuseCol@end 12 | 13 | @property( !hlms_prepass ) 14 | @property( !metallic_workflow ) 15 | @property( specular_map && !fresnel_workflow ) 16 | @piece( SampleSpecularMap ) specularCol = texture( textureMaps[@value( specular_map_idx )], vec3(inPs.uv@value(uv_specular).xy, specularIdx) ).xyz * material.kS.xyz;@end 17 | @piece( kS )specularCol@end 18 | @end 19 | @property( specular_map && fresnel_workflow ) 20 | @piece( SampleSpecularMap ) F0 = texture( textureMaps[@value( specular_map_idx )], vec3(inPs.uv@value(uv_specular).xy, specularIdx) ).@insertpiece( FresnelSwizzle ) * material.F0.@insertpiece( FresnelSwizzle );@end 21 | @end 22 | @property( !specular_map || fresnel_workflow ) 23 | @piece( kS )material.kS@end 24 | @end 25 | @end @property( metallic_workflow ) 26 | @piece( SampleSpecularMap ) 27 | @property( specular_map ) 28 | float metalness = texture( textureMaps[@value( specular_map_idx )], vec3(inPs.uv@value(uv_specular).xy, specularIdx) ).x * material.F0.x; 29 | F0 = mix( vec3( 0.03f ), @insertpiece( kD ).xyz * 3.14159f, metalness ); 30 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * metalness; 31 | @end @property( !specular_map ) 32 | F0 = mix( vec3( 0.03f ), @insertpiece( kD ).xyz * 3.14159f, material.F0.x ); 33 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * material.F0.x; 34 | @end 35 | @property( hlms_alphablend )F0 *= material.F0.w;@end 36 | @property( transparent_mode )F0 *= diffuseCol.w;@end 37 | @end /// SampleSpecularMap 38 | 39 | @piece( kS )material.kS.xyz@end 40 | @end 41 | @end 42 | 43 | @property( roughness_map ) 44 | @piece( SampleRoughnessMap )ROUGHNESS = material.kS.w * texture( textureMaps[@value( roughness_map_idx )], vec3(inPs.uv@value(uv_roughness).xy, roughnessIdx) ).x; 45 | ROUGHNESS = max( ROUGHNESS, 0.001f );@end 46 | @end 47 | 48 | @foreach( detail_maps_normal, n ) 49 | @piece( SampleDetailMapNm@n )getTSDetailNormal( textureMaps[@value(detail_map_nm@n_idx)], vec3( inPs.uv@value(uv_detail_nm@n).xy@insertpiece( offsetDetailN@n ), detailNormMapIdx@n ) ) * detailWeights.@insertpiece(detail_swizzle@n) @insertpiece( detail@n_nm_weight_mul )@end 50 | @end 51 | 52 | @property( detail_weight_map ) 53 | @piece( SamplerDetailWeightMap )texture( textureMaps[@value(detail_weight_map_idx)], vec3(inPs.uv@value(uv_detail_weight).xy, weightMapIdx) )@end 54 | @end 55 | 56 | @property( envmap_scale ) 57 | @piece( ApplyEnvMapScale )* passBuf.ambientUpperHemi.w@end 58 | @end 59 | 60 | @property( (envprobe_map && envprobe_map != target_envprobe_map) || parallax_correct_cubemaps ) 61 | @set( use_envprobe_map, 1 ) 62 | 63 | @property( !envprobe_map || envprobe_map == target_envprobe_map ) 64 | /// "No cubemap"? Then we're in auto mode or... 65 | /// We're rendering to the cubemap probe we're using as manual. Use the auto mode as fallback. 66 | @piece( pccProbeSource )passBuf.autoProbe@end 67 | @set( use_parallax_correct_cubemaps, 1 ) 68 | @end 69 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 70 | @piece( pccProbeSource )manualProbe.probe@end 71 | @end 72 | @end 73 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/GLSL/VertexShader_vs.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | out gl_PerVertex 4 | { 5 | vec4 gl_Position; 6 | @property( hlms_global_clip_distances ) 7 | float gl_ClipDistance[1]; 8 | @end 9 | }; 10 | 11 | layout(std140) uniform; 12 | 13 | @insertpiece( Common_Matrix_DeclUnpackMatrix4x4 ) 14 | @insertpiece( Common_Matrix_DeclUnpackMatrix3x4 ) 15 | 16 | in vec4 vertex; 17 | 18 | @property( hlms_normal )in vec3 normal;@end 19 | @property( hlms_qtangent )in vec4 qtangent;@end 20 | 21 | @property( normal_map && !hlms_qtangent ) 22 | in vec3 tangent; 23 | @property( hlms_binormal )in vec3 binormal;@end 24 | @end 25 | 26 | @property( hlms_skeleton ) 27 | in uvec4 blendIndices; 28 | in vec4 blendWeights;@end 29 | 30 | @foreach( hlms_uv_count, n ) 31 | in vec@value( hlms_uv_count@n ) uv@n;@end 32 | 33 | in uint drawId; 34 | 35 | @insertpiece( custom_vs_attributes ) 36 | 37 | @property( !hlms_shadowcaster || !hlms_shadow_uses_depth_texture || alpha_test || exponential_shadow_maps ) 38 | out block 39 | { 40 | @insertpiece( VStoPS_block ) 41 | } outVs; 42 | @end 43 | 44 | // START UNIFORM DECLARATION 45 | @insertpiece( PassDecl ) 46 | @property( hlms_skeleton || hlms_shadowcaster )@insertpiece( InstanceDecl )@end 47 | layout(binding = 0) uniform samplerBuffer worldMatBuf; 48 | @insertpiece( custom_vs_uniformDeclaration ) 49 | // END UNIFORM DECLARATION 50 | 51 | @property( hlms_qtangent ) 52 | @insertpiece( DeclQuat_xAxis ) 53 | @property( normal_map ) 54 | @insertpiece( DeclQuat_yAxis ) 55 | @end @end 56 | 57 | @property( !hlms_skeleton ) 58 | @piece( local_vertex )vertex@end 59 | @piece( local_normal )normal@end 60 | @piece( local_tangent )tangent@end 61 | @end 62 | @property( hlms_skeleton ) 63 | @piece( local_vertex )worldPos@end 64 | @piece( local_normal )worldNorm@end 65 | @piece( local_tangent )worldTang@end 66 | @end 67 | 68 | @property( hlms_skeleton )@piece( SkeletonTransform ) 69 | uint _idx = (blendIndices[0] << 1u) + blendIndices[0]; //blendIndices[0] * 3u; a 32-bit int multiply is 4 cycles on GCN! (and mul24 is not exposed to GLSL...) 70 | uint matStart = instance.worldMaterialIdx[drawId].x >> 9u; 71 | vec4 worldMat[3]; 72 | worldMat[0] = texelFetch( worldMatBuf, int(matStart + _idx + 0u) ); 73 | worldMat[1] = texelFetch( worldMatBuf, int(matStart + _idx + 1u) ); 74 | worldMat[2] = texelFetch( worldMatBuf, int(matStart + _idx + 2u) ); 75 | vec4 worldPos; 76 | worldPos.x = dot( worldMat[0], vertex ); 77 | worldPos.y = dot( worldMat[1], vertex ); 78 | worldPos.z = dot( worldMat[2], vertex ); 79 | worldPos.xyz *= blendWeights[0]; 80 | @property( hlms_normal || hlms_qtangent )vec3 worldNorm; 81 | worldNorm.x = dot( worldMat[0].xyz, normal ); 82 | worldNorm.y = dot( worldMat[1].xyz, normal ); 83 | worldNorm.z = dot( worldMat[2].xyz, normal ); 84 | worldNorm *= blendWeights[0];@end 85 | @property( normal_map )vec3 worldTang; 86 | worldTang.x = dot( worldMat[0].xyz, tangent ); 87 | worldTang.y = dot( worldMat[1].xyz, tangent ); 88 | worldTang.z = dot( worldMat[2].xyz, tangent ); 89 | worldTang *= blendWeights[0];@end 90 | 91 | @psub( NeedsMoreThan1BonePerVertex, hlms_bones_per_vertex, 1 ) 92 | @property( NeedsMoreThan1BonePerVertex )vec4 tmp; 93 | tmp.w = 1.0;@end //!NeedsMoreThan1BonePerVertex 94 | @foreach( hlms_bones_per_vertex, n, 1 ) 95 | _idx = (blendIndices[@n] << 1u) + blendIndices[@n]; //blendIndices[@n] * 3; a 32-bit int multiply is 4 cycles on GCN! (and mul24 is not exposed to GLSL...) 96 | worldMat[0] = texelFetch( worldMatBuf, int(matStart + _idx + 0u) ); 97 | worldMat[1] = texelFetch( worldMatBuf, int(matStart + _idx + 1u) ); 98 | worldMat[2] = texelFetch( worldMatBuf, int(matStart + _idx + 2u) ); 99 | tmp.x = dot( worldMat[0], vertex ); 100 | tmp.y = dot( worldMat[1], vertex ); 101 | tmp.z = dot( worldMat[2], vertex ); 102 | worldPos.xyz += (tmp * blendWeights[@n]).xyz; 103 | @property( hlms_normal || hlms_qtangent ) 104 | tmp.x = dot( worldMat[0].xyz, normal ); 105 | tmp.y = dot( worldMat[1].xyz, normal ); 106 | tmp.z = dot( worldMat[2].xyz, normal ); 107 | worldNorm += tmp.xyz * blendWeights[@n];@end 108 | @property( normal_map ) 109 | tmp.x = dot( worldMat[0].xyz, tangent ); 110 | tmp.y = dot( worldMat[1].xyz, tangent ); 111 | tmp.z = dot( worldMat[2].xyz, tangent ); 112 | worldTang += tmp.xyz * blendWeights[@n];@end 113 | @end 114 | 115 | worldPos.w = 1.0; 116 | @end @end //SkeletonTransform // !hlms_skeleton 117 | 118 | @property( hlms_skeleton ) 119 | @piece( worldViewMat )passBuf.view@end 120 | @end @property( !hlms_skeleton ) 121 | @piece( worldViewMat )worldView@end 122 | @end 123 | 124 | @piece( CalculatePsPos )(@insertpiece(local_vertex) * @insertpiece( worldViewMat )).xyz@end 125 | 126 | @piece( VertexTransform ) 127 | //Lighting is in view space 128 | @property( hlms_normal || hlms_qtangent )outVs.pos = @insertpiece( CalculatePsPos );@end 129 | @property( hlms_normal || hlms_qtangent )outVs.normal = @insertpiece(local_normal) * mat3(@insertpiece( worldViewMat ));@end 130 | @property( normal_map )outVs.tangent = @insertpiece(local_tangent) * mat3(@insertpiece( worldViewMat ));@end 131 | @property( !hlms_dual_paraboloid_mapping ) 132 | gl_Position = worldPos * passBuf.viewProj;@end 133 | @property( hlms_dual_paraboloid_mapping ) 134 | //Dual Paraboloid Mapping 135 | gl_Position.w = 1.0f; 136 | @property( hlms_normal || hlms_qtangent )gl_Position.xyz = outVs.pos;@end 137 | @property( !hlms_normal && !hlms_qtangent )gl_Position.xyz = @insertpiece( CalculatePsPos );@end 138 | float L = length( gl_Position.xyz ); 139 | gl_Position.z += 1.0f; 140 | gl_Position.xy /= gl_Position.z; 141 | gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end 142 | @end 143 | 144 | void main() 145 | { 146 | @insertpiece( custom_vs_preExecution ) 147 | @property( !hlms_skeleton ) 148 | mat3x4 worldMat = UNPACK_MAT3x4( worldMatBuf, drawId @property( !hlms_shadowcaster )<< 1u@end ); 149 | @property( hlms_normal || hlms_qtangent ) 150 | mat4 worldView = UNPACK_MAT4( worldMatBuf, (drawId << 1u) + 1u ); 151 | @end 152 | 153 | vec4 worldPos = vec4( (vertex * worldMat).xyz, 1.0f ); 154 | @end 155 | 156 | @property( hlms_qtangent ) 157 | //Decode qTangent to TBN with reflection 158 | vec3 normal = xAxis( normalize( qtangent ) ); 159 | @property( normal_map ) 160 | vec3 tangent = yAxis( qtangent ); 161 | outVs.biNormalReflection = sign( qtangent.w ); //We ensure in C++ qtangent.w is never 0 162 | @end 163 | @end 164 | 165 | @insertpiece( SkeletonTransform ) 166 | @insertpiece( VertexTransform ) 167 | 168 | @insertpiece( DoShadowReceiveVS ) 169 | @insertpiece( DoShadowCasterVS ) 170 | 171 | /// hlms_uv_count will be 0 on shadow caster passes w/out alpha test 172 | @foreach( hlms_uv_count, n ) 173 | outVs.uv@n = uv@n;@end 174 | 175 | @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) 176 | outVs.drawId = drawId;@end 177 | 178 | @property( hlms_use_prepass_msaa > 1 ) 179 | outVs.zwDepth.xy = outVs.gl_Position.zw; 180 | @end 181 | 182 | @property( hlms_global_clip_distances ) 183 | gl_ClipDistance[0] = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); 184 | @end 185 | 186 | @insertpiece( custom_vs_posExecution ) 187 | } 188 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/HLSL/BlendModes_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @property( !hlms_shadowcaster ) 5 | @piece( NormalNonPremul ) 6 | //Normal Non Premultiplied @value(t) 7 | diffuseCol.xyz = lerp( diffuseCol.xyz, detailCol@value(t).xyz, detailCol@value(t).a ); 8 | diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol@value(t).w ); 9 | @end 10 | 11 | @piece( NormalPremul ) 12 | //Normal Premultiplied @value(t) 13 | diffuseCol.xyz = (1.0 - detailCol@value(t).a) * diffuseCol.xyz + detailCol@value(t).xyz; 14 | diffuseCol.w = lerp( diffuseCol.w, 1.0, detailCol@value(t).w ); 15 | @end 16 | 17 | @piece( Add ) 18 | //Add @value(t) 19 | diffuseCol.xyz = lerp( diffuseCol.xyz, 20 | min( diffuseCol.xyz + detailCol@value(t).xyz, float3(1.0, 1.0, 1.0) ), 21 | detailCol@value(t).a ); 22 | @end 23 | 24 | @piece( Subtract ) 25 | //Subtract @value(t) 26 | diffuseCol.xyz = lerp( diffuseCol.xyz, 27 | max( diffuseCol.xyz - detailCol@value(t).xyz, float3(0.0, 0.0, 0.0) ), 28 | detailCol@value(t).a ); 29 | @end 30 | 31 | @piece( Multiply ) 32 | //Multiply @value(t) 33 | diffuseCol.xyz = lerp( diffuseCol.xyz, 34 | diffuseCol.xyz * detailCol@value(t).xyz, 35 | detailCol@value(t).a ); 36 | @end 37 | 38 | @piece( Multiply2x ) 39 | //Multiply2x @value(t) 40 | diffuseCol.xyz = lerp( diffuseCol.xyz, 41 | min( diffuseCol.xyz * detailCol@value(t).xyz * 2.0, float3(1.0, 1.0, 1.0) ), 42 | detailCol@value(t).a ); 43 | @end 44 | 45 | @piece( Screen ) 46 | //Screen @value(t) 47 | diffuseCol.xyz = lerp( diffuseCol.xyz, 48 | 1.0 - (1.0 - diffuseCol.xyz) * (1.0 - detailCol@value(t).xyz), 49 | detailCol@value(t).a ); 50 | @end 51 | 52 | @piece( Overlay ) 53 | //Overlay @value(t) 54 | diffuseCol.xyz = lerp( diffuseCol.xyz, 55 | diffuseCol.xyz * ( diffuseCol.xyz + 2.0 * detailCol@value(t).xyz * (1.0 - diffuseCol.xyz) ), 56 | detailCol@value(t).a ); 57 | @end 58 | 59 | @piece( Lighten ) 60 | //Lighten @value(t) 61 | diffuseCol.xyz = lerp( diffuseCol.xyz, 62 | max( diffuseCol.xyz, detailCol@value(t).xyz ), 63 | detailCol@value(t).a ); 64 | @end 65 | 66 | @piece( Darken ) 67 | //Darken @value(t) 68 | diffuseCol.xyz = lerp( diffuseCol.xyz, 69 | min( diffuseCol.xyz, detailCol@value(t).xyz ), 70 | detailCol@value(t).a ); 71 | @end 72 | 73 | @piece( GrainExtract ) 74 | //GrainExtract @value(t) 75 | diffuseCol.xyz = lerp( diffuseCol.xyz, 76 | (diffuseCol.xyz - detailCol@value(t).xyz) + 0.5f, 77 | detailCol@value(t).a ); 78 | @end 79 | 80 | @piece( GrainMerge ) 81 | //GrainMerge @value(t) 82 | diffuseCol.xyz = lerp( diffuseCol.xyz, 83 | (diffuseCol.xyz + detailCol@value(t).xyz) - 0.5f, 84 | detailCol@value(t).a ); 85 | @end 86 | 87 | @piece( Difference ) 88 | //Difference @value(t) 89 | diffuseCol.xyz = lerp( diffuseCol.xyz, 90 | abs(diffuseCol.xyz - detailCol@value(t).xyz), 91 | detailCol@value(t).a ); 92 | @end 93 | @end @property( hlms_shadowcaster ) 94 | 95 | @piece( NormalNonPremul ) 96 | //Normal Non Premultiplied @value(t) 97 | diffuseCol = lerp( diffuseCol, 1.0, detailCol@value(t) ); 98 | @end 99 | 100 | @piece( NormalPremul ) 101 | //Normal Premultiplied @value(t) 102 | diffuseCol = lerp( diffuseCol, 1.0, detailCol@value(t) ); 103 | @end 104 | 105 | @end -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/HLSL/DetailMaps_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | // detail_maps_diffuse & detail_maps_normal are either 0 or 4 2 | 3 | @foreach( detail_maps_diffuse, n ) 4 | @property( detail_offsetsD@n ) 5 | @piece( offsetDetailD@n ) * material.detailOffsetScaleD[@value(currOffsetDetailD)].zw + material.detailOffsetScaleD[@counter(currOffsetDetailD)].xy@end 6 | @end 7 | @end 8 | @foreach( detail_maps_normal, n ) 9 | @property( detail_offsetsN@n ) 10 | @piece( offsetDetailN@n ) * material.detailOffsetScaleN[@value(currOffsetDetailN)].zw + material.detailOffsetScaleN[@counter(currOffsetDetailN)].xy@end 11 | @end 12 | @end 13 | 14 | @piece( detail_swizzle0 )x@end; 15 | @piece( detail_swizzle1 )y@end; 16 | @piece( detail_swizzle2 )z@end; 17 | @piece( detail_swizzle3 )w@end; 18 | 19 | /* 20 | Down below we perform: 21 | if( detail_maps_normal ) 22 | second_valid_detail_map_nm = first_valid_detail_map_nm + 1; 23 | else 24 | second_valid_detail_map_nm = 0; 25 | */ 26 | @property( detail_maps_normal ) 27 | @add( second_valid_detail_map_nm, first_valid_detail_map_nm, 1 ) 28 | @end @property( !detail_maps_normal ) 29 | @set( second_valid_detail_map_nm, 0 ) 30 | @end 31 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/HLSL/Structs_piece_vs_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | @piece( PassDecl ) 2 | struct ShadowReceiverData 3 | { 4 | float4x4 texViewProj; 5 | @property( exponential_shadow_maps ) 6 | float4 texViewZRow; 7 | @end 8 | float2 shadowDepthRange; 9 | float2 padding; 10 | float4 invShadowMapSize; 11 | }; 12 | 13 | struct Light 14 | { 15 | float4 position; //.w contains the objLightMask 16 | float3 diffuse; 17 | float3 specular; 18 | @property( hlms_num_shadow_map_lights ) 19 | float3 attenuation; 20 | float3 spotDirection; 21 | float3 spotParams; 22 | @end 23 | }; 24 | 25 | @insertpiece( DeclCubemapProbeStruct ) 26 | 27 | //Uniforms that change per pass 28 | cbuffer PassBuffer : register(b0) 29 | { 30 | struct PassData 31 | { 32 | //Vertex shader (common to both receiver and casters) 33 | float4x4 viewProj; 34 | 35 | @property( hlms_global_clip_distances ) 36 | float4 clipPlane0; 37 | @end 38 | 39 | @property( hlms_shadowcaster_point ) 40 | float4 cameraPosWS; //Camera position in world space 41 | @end 42 | 43 | @property( !hlms_shadowcaster ) 44 | //Vertex shader 45 | float4x4 view; 46 | @property( hlms_num_shadow_map_lights )ShadowReceiverData shadowRcv[@value(hlms_num_shadow_map_lights)];@end 47 | 48 | //------------------------------------------------------------------------- 49 | 50 | //Pixel shader 51 | float3x3 invViewMatCubemap; 52 | float padding; //Compatibility with GLSL. 53 | 54 | @property( hlms_use_prepass ) 55 | float4 windowHeight; 56 | @end 57 | 58 | @property( ambient_hemisphere || ambient_fixed || envmap_scale ) 59 | float4 ambientUpperHemi; 60 | @end 61 | @property( ambient_hemisphere ) 62 | float4 ambientLowerHemi; 63 | float4 ambientHemisphereDir; 64 | @end 65 | @property( irradiance_volumes ) 66 | float4 irradianceOrigin; //.w = maxPower 67 | float4 irradianceSize; //.w = 1.0f / irradianceTexture->getHeight() 68 | float4x4 invView; 69 | @end 70 | @property( hlms_pssm_splits )@foreach( hlms_pssm_splits, n ) 71 | float pssmSplitPoints@n;@end @end 72 | @property( hlms_lights_spot )Light lights[@value(hlms_lights_spot)];@end 73 | @end @property( hlms_shadowcaster ) 74 | //Vertex shader 75 | @property( exponential_shadow_maps )float4 viewZRow;@end 76 | float2 depthRange; 77 | @end 78 | 79 | @property( hlms_forwardplus ) 80 | //Forward3D 81 | //f3dData.x = minDistance; 82 | //f3dData.y = invMaxDistance; 83 | //f3dData.z = f3dNumSlicesSub1; 84 | //f3dData.w = uint cellsPerTableOnGrid0 (floatBitsToUint); 85 | 86 | //Clustered Forward: 87 | //f3dData.x = minDistance; 88 | //f3dData.y = invExponentK; 89 | //f3dData.z = f3dNumSlicesSub1; 90 | //f3dData.w = renderWindow->getHeight(); 91 | float4 f3dData; 92 | @property( hlms_forwardplus == forward3d ) 93 | float4 f3dGridHWW[@value( forward3d_num_slices )]; 94 | @end 95 | @property( hlms_forwardplus != forward3d ) 96 | float4 fwdScreenToGrid; 97 | @end 98 | @end 99 | 100 | @insertpiece( DeclPlanarReflUniforms ) 101 | 102 | @property( parallax_correct_cubemaps ) 103 | CubemapProbe autoProbe; 104 | @end 105 | 106 | @insertpiece( custom_passBuffer ) 107 | } passBuf; 108 | }; 109 | @end 110 | 111 | @property( fresnel_scalar )@piece( FresnelType )float3@end @piece( FresnelSwizzle )xyz@end @end 112 | @property( !fresnel_scalar )@piece( FresnelType )float@end @piece( FresnelSwizzle )x@end @end 113 | 114 | @piece( MaterialDecl ) 115 | //Uniforms that change per Item/Entity, but change very infrequently 116 | struct Material 117 | { 118 | /* kD is already divided by PI to make it energy conserving. 119 | (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) 120 | */ 121 | float4 bgDiffuse; 122 | float4 kD; //kD.w is alpha_test_threshold 123 | float4 kS; //kS.w is roughness 124 | //Fresnel coefficient, may be per colour component (float3) or scalar (float) 125 | //F0.w is transparency 126 | float4 F0; 127 | float4 normalWeights; 128 | float4 cDetailWeights; 129 | float4 detailOffsetScaleD[4]; 130 | float4 detailOffsetScaleN[4]; 131 | 132 | uint4 indices0_3; 133 | //asfloat( indices4_7.w ) contains mNormalMapWeight. 134 | uint4 indices4_7; 135 | }; 136 | 137 | cbuffer MaterialBuf : register(b1) 138 | { 139 | Material materialArray[@value( materials_per_buffer )]; 140 | }; 141 | @end 142 | 143 | 144 | @piece( InstanceDecl ) 145 | //Uniforms that change per Item/Entity 146 | cbuffer InstanceBuffer : register(b2) 147 | { 148 | //.x = 149 | //The lower 9 bits contain the material's start index. 150 | //The higher 23 bits contain the world matrix start index. 151 | // 152 | //.y = 153 | //shadowConstantBias. Send the bias directly to avoid an 154 | //unnecessary indirection during the shadow mapping pass. 155 | //Must be loaded with uintBitsToFloat 156 | @property( fast_shader_build_hack ) 157 | uint4 worldMaterialIdx[2]; 158 | @end @property( !fast_shader_build_hack ) 159 | uint4 worldMaterialIdx[4096]; 160 | @end 161 | }; 162 | @end 163 | 164 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 165 | @piece( PccManualProbeDecl ) 166 | cbuffer ManualProbe : register(b3) 167 | { 168 | CubemapProbe manualProbe; 169 | }; 170 | @end 171 | @end 172 | 173 | //Reset texcoord to 0 for every shader stage (since values are preserved). 174 | @pset( texcoord, 0 ) 175 | 176 | @piece( VStoPS_block ) 177 | @property( !hlms_shadowcaster ) 178 | @property( !lower_gpu_overhead ) 179 | nointerpolation uint drawId : TEXCOORD@counter(texcoord); 180 | @end 181 | @property( hlms_normal || hlms_qtangent ) 182 | float3 pos : TEXCOORD@counter(texcoord); 183 | float3 normal : TEXCOORD@counter(texcoord); 184 | @property( normal_map )float3 tangent : TEXCOORD@counter(texcoord); 185 | @property( hlms_qtangent )nointerpolation float biNormalReflection : TEXCOORD@counter(texcoord);@end 186 | @end 187 | @end 188 | @foreach( hlms_uv_count, n ) 189 | float@value( hlms_uv_count@n ) uv@n : TEXCOORD@counter(texcoord);@end 190 | 191 | @foreach( hlms_num_shadow_map_lights, n ) 192 | @property( !hlms_shadowmap@n_is_point_light ) 193 | float4 posL@n : TEXCOORD@counter(texcoord);@end @end 194 | 195 | @property( hlms_pssm_splits )float depth : TEXCOORD@counter(texcoord);@end 196 | 197 | @property( hlms_use_prepass_msaa > 1 ) 198 | float2 zwDepth : TEXCOORD@counter(texcoord); 199 | @end 200 | @end 201 | 202 | @property( hlms_shadowcaster ) 203 | @property( alpha_test ) 204 | nointerpolation uint drawId : TEXCOORD@counter(texcoord); 205 | @foreach( hlms_uv_count, n ) 206 | float@value( hlms_uv_count@n ) uv@n : TEXCOORD@counter(texcoord);@end 207 | @end 208 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 209 | float depth : TEXCOORD@counter(texcoord); 210 | @end 211 | @property( hlms_shadowcaster_point ) 212 | float3 toCameraWS : TEXCOORD@counter(texcoord); 213 | @property( !exponential_shadow_maps ) 214 | nointerpolation float constBias : TEXCOORD@counter(texcoord); 215 | @end 216 | @end 217 | @end 218 | 219 | @insertpiece( custom_VStoPS ) 220 | @end 221 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/HLSL/Textures_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | 2 | //Set the sampler starts. Note that 'padd' get calculated before _any_ 'add' 3 | @set( texUnit, 1 ) 4 | 5 | @property( hlms_forwardplus ) 6 | @add( texUnit, 2 ) 7 | @end 8 | 9 | @property( hlms_use_prepass ) 10 | @set( gBuf_normals, texUnit ) 11 | @add( gBuf_shadowRoughness, texUnit, 1 ) 12 | @add( texUnit, 2 ) 13 | 14 | @property( hlms_use_prepass_msaa ) 15 | @set( gBuf_depthTexture, texUnit ) 16 | @add( texUnit, 1 ) 17 | @end 18 | 19 | @property( hlms_use_ssr ) 20 | @set( ssrTexture, texUnit ) 21 | @add( texUnit, 1 ) 22 | @end 23 | @end 24 | 25 | @property( irradiance_volumes ) 26 | @set( irradianceVolumeTexUnit, texUnit ) 27 | @add( texUnit, 1 ) 28 | @end 29 | 30 | @set( textureRegShadowMapStart, texUnit ) 31 | @add( texUnit, hlms_num_shadow_map_textures ) 32 | 33 | @property( parallax_correct_cubemaps ) 34 | @set( globaPccTexUnit, texUnit ) 35 | @add( texUnit, 1 ) 36 | @end 37 | 38 | @property( has_planar_reflections ) 39 | @set( planarReflectionTexUnit, texUnit ) 40 | @add( texUnit, 1 ) 41 | @end 42 | 43 | @set( textureRegStart, texUnit ) 44 | @set( samplerStateStart, texUnit ) 45 | @set( numSamplerStates, num_textures ) 46 | @add( texUnit, num_textures ) 47 | 48 | @set( envMapReg, texUnit ) 49 | 50 | @property( (envprobe_map && envprobe_map != target_envprobe_map) || parallax_correct_cubemaps ) 51 | @set( use_envprobe_map, 1 ) 52 | 53 | @property( !envprobe_map || envprobe_map == target_envprobe_map ) 54 | /// "No cubemap"? Then we're in auto mode or... 55 | /// We're rendering to the cubemap probe we're using as manual. Use the auto mode as fallback. 56 | @piece( pccProbeSource )passBuf.autoProbe@end 57 | @set( use_parallax_correct_cubemaps, 1 ) 58 | /// Auto cubemap textures are set at the beginning. Manual cubemaps are the end. 59 | @set( envMapReg, globaPccTexUnit ) 60 | @end 61 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 62 | @piece( pccProbeSource )manualProbe@end 63 | @end 64 | @end 65 | 66 | @property( diffuse_map ) 67 | @property( !hlms_shadowcaster ) 68 | @piece( SampleDiffuseMap ) diffuseCol = textureMaps[@value( diffuse_map_idx )].Sample( samplerStates[@value(diffuse_map_idx)], float3( inPs.uv@value(uv_diffuse).xy, diffuseIdx ) ); 69 | @property( !hw_gamma_read ) diffuseCol = diffuseCol * diffuseCol;@end @end 70 | @end @property( hlms_shadowcaster ) 71 | @piece( SampleDiffuseMap ) diffuseCol = textureMaps[@value( diffuse_map_idx )].Sample( samplerStates[@value(diffuse_map_idx)], float3( inPs.uv@value(uv_diffuse).xy, diffuseIdx ) ).w;@end 72 | @end 73 | @end 74 | 75 | @property( transparent_mode ) 76 | @piece( diffuseExtraParamDef ), float4 diffuseCol@end 77 | @piece( diffuseExtraParam ), diffuseCol.xyzw@end 78 | @end @property( !transparent_mode ) 79 | @piece( diffuseExtraParamDef ), float3 diffuseCol@end 80 | @piece( diffuseExtraParam ), diffuseCol.xyz@end 81 | @end 82 | //diffuseCol always has some colour and is multiplied against material.kD in PixelShader_ps. 83 | @piece( kD )diffuseCol@end 84 | 85 | @property( !hlms_prepass ) 86 | @property( !metallic_workflow ) 87 | @property( specular_map && !fresnel_workflow ) 88 | @piece( SampleSpecularMap ) specularCol = textureMaps[@value( specular_map_idx )].Sample( samplerStates[@value(specular_map_idx)], float3(inPs.uv@value(uv_specular).xy, specularIdx) ).xyz * material.kS.xyz;@end 89 | @piece( specularExtraParamDef ), float3 specularCol@end 90 | @piece( specularExtraParam ), specularCol.xyz@end 91 | @piece( kS )specularCol@end 92 | @end 93 | @property( specular_map && fresnel_workflow ) 94 | @piece( SampleSpecularMap ) F0 = textureMaps[@value( specular_map_idx )].Sample( samplerStates[@value(specular_map_idx)], float3(inPs.uv@value(uv_specular).xy, specularIdx) ).@insertpiece( FresnelSwizzle ) * material.F0.@insertpiece( FresnelSwizzle );@end 95 | @piece( specularExtraParamDef ), @insertpiece( FresnelType ) F0@end 96 | @piece( specularExtraParam ), F0@end 97 | @end 98 | @property( !specular_map || fresnel_workflow ) 99 | @piece( kS )material.kS@end 100 | @end 101 | @end @property( metallic_workflow ) 102 | @piece( SampleSpecularMap ) 103 | @property( specular_map ) 104 | float metalness = textureMaps[@value( specular_map_idx )].Sample( samplerStates[@value(specular_map_idx)], float3(inPs.uv@value(uv_specular).xy, specularIdx) ).x * material.F0.x; 105 | F0 = lerp( float( 0.03f ).xxx, @insertpiece( kD ).xyz * 3.14159f, metalness ); 106 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * metalness; 107 | @end @property( !specular_map ) 108 | F0 = lerp( float( 0.03f ).xxx, @insertpiece( kD ).xyz * 3.14159f, material.F0.x ); 109 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * material.F0.x; 110 | @end 111 | @property( hlms_alphablend )F0 *= material.F0.w;@end 112 | @property( transparent_mode )F0 *= diffuseCol.w;@end 113 | @end /// SampleSpecularMap 114 | 115 | @piece( kS )material.kS.xyz@end 116 | @piece( metallicExtraParamDef ), float3 F0@end 117 | @piece( metallicExtraParam ), F0@end 118 | @end 119 | @end 120 | 121 | @property( roughness_map ) 122 | @piece( SampleRoughnessMap ) ROUGHNESS = material.kS.w * textureMaps[@value( roughness_map_idx )].Sample( samplerStates[@value( roughness_map_idx )], float3(inPs.uv@value(uv_roughness).xy, roughnessIdx) ).x; 123 | ROUGHNESS = max( ROUGHNESS, 0.001f );@end 124 | @piece( roughnessExtraParamDef ), float ROUGHNESS@end 125 | @piece( roughnessExtraParam ), ROUGHNESS@end 126 | @end 127 | 128 | @piece( brdfExtraParamDefs )@insertpiece( diffuseExtraParamDef )@insertpiece( specularExtraParamDef )@insertpiece( roughnessExtraParamDef )@insertpiece( metallicExtraParamDef )@end 129 | @piece( brdfExtraParams )@insertpiece( diffuseExtraParam )@insertpiece( specularExtraParam )@insertpiece( roughnessExtraParam )@insertpiece( metallicExtraParam )@end 130 | 131 | @foreach( detail_maps_normal, n ) 132 | @piece( SampleDetailMapNm@n )getTSDetailNormal( samplerStates[@value(detail_map_nm@n_idx)], textureMaps[@value(detail_map_nm@n_idx)], float3( inPs.uv@value(uv_detail_nm@n).xy@insertpiece( offsetDetailN@n ), detailNormMapIdx@n ) ) * detailWeights.@insertpiece(detail_swizzle@n) @insertpiece( detail@n_nm_weight_mul )@end 133 | @end 134 | 135 | @property( detail_weight_map ) 136 | @piece( SamplerDetailWeightMap )textureMaps[@value(detail_weight_map_idx)].Sample( samplerStates[@value(detail_weight_map_idx)], float3(inPs.uv@value(uv_detail_weight).xy, weightMapIdx) )@end 137 | @end 138 | 139 | @property( envmap_scale ) 140 | @piece( ApplyEnvMapScale )* passBuf.ambientUpperHemi.w@end 141 | @end 142 | 143 | @property( !hlms_render_depth_only && !hlms_shadowcaster && hlms_prepass ) 144 | @undefpiece( DeclOutputType ) 145 | @piece( DeclOutputType ) 146 | struct PS_OUTPUT 147 | { 148 | float4 normals : SV_Target0; 149 | float2 shadowRoughness : SV_Target1; 150 | }; 151 | @end 152 | @end 153 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Pbs/HLSL/VertexShader_vs.hlsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | @insertpiece( Common_Matrix_DeclUnpackMatrix4x4 ) 4 | @insertpiece( Common_Matrix_DeclUnpackMatrix4x3 ) 5 | 6 | struct VS_INPUT 7 | { 8 | float4 vertex : POSITION; 9 | @property( hlms_normal ) float3 normal : NORMAL;@end 10 | @property( hlms_qtangent ) float4 qtangent : NORMAL;@end 11 | 12 | @property( normal_map && !hlms_qtangent ) 13 | float3 tangent : TANGENT; 14 | @property( hlms_binormal )float3 binormal : BINORMAL;@end 15 | @end 16 | 17 | @property( hlms_skeleton ) 18 | uint4 blendIndices : BLENDINDICES; 19 | float4 blendWeights : BLENDWEIGHT;@end 20 | 21 | @foreach( hlms_uv_count, n ) 22 | float@value( hlms_uv_count@n ) uv@n : TEXCOORD@n;@end 23 | uint drawId : DRAWID; 24 | @insertpiece( custom_vs_attributes ) 25 | }; 26 | 27 | struct PS_INPUT 28 | { 29 | @insertpiece( VStoPS_block ) 30 | float4 gl_Position: SV_Position; 31 | @property( hlms_global_clip_distances ) 32 | float gl_ClipDistance0 : SV_ClipDistance0; 33 | @end 34 | }; 35 | 36 | // START UNIFORM DECLARATION 37 | @insertpiece( PassDecl ) 38 | @property( hlms_skeleton || hlms_shadowcaster )@insertpiece( InstanceDecl )@end 39 | Buffer worldMatBuf : register(t0); 40 | @insertpiece( custom_vs_uniformDeclaration ) 41 | // END UNIFORM DECLARATION 42 | 43 | @property( hlms_qtangent ) 44 | @insertpiece( DeclQuat_xAxis ) 45 | @property( normal_map ) 46 | @insertpiece( DeclQuat_yAxis ) 47 | @end @end 48 | 49 | @property( !hlms_skeleton ) 50 | @piece( local_vertex )input.vertex@end 51 | @piece( local_normal )normal@end 52 | @piece( local_tangent )tangent@end 53 | @end 54 | @property( hlms_skeleton ) 55 | @piece( local_vertex )worldPos@end 56 | @piece( local_normal )worldNorm@end 57 | @piece( local_tangent )worldTang@end 58 | @end 59 | 60 | @property( hlms_skeleton )@piece( SkeletonTransform ) 61 | uint _idx = (input.blendIndices[0] << 1u) + input.blendIndices[0]; //blendIndices[0] * 3u; a 32-bit int multiply is 4 cycles on GCN! (and mul24 is not exposed to GLSL...) 62 | uint matStart = worldMaterialIdx[input.drawId].x >> 9u; 63 | float4 worldMat[3]; 64 | worldMat[0] = worldMatBuf.Load( int(matStart + _idx + 0u) ); 65 | worldMat[1] = worldMatBuf.Load( int(matStart + _idx + 1u) ); 66 | worldMat[2] = worldMatBuf.Load( int(matStart + _idx + 2u) ); 67 | float4 worldPos; 68 | worldPos.x = dot( worldMat[0], input.vertex ); 69 | worldPos.y = dot( worldMat[1], input.vertex ); 70 | worldPos.z = dot( worldMat[2], input.vertex ); 71 | worldPos.xyz *= input.blendWeights[0]; 72 | @property( hlms_normal || hlms_qtangent )float3 worldNorm; 73 | worldNorm.x = dot( worldMat[0].xyz, normal ); 74 | worldNorm.y = dot( worldMat[1].xyz, normal ); 75 | worldNorm.z = dot( worldMat[2].xyz, normal ); 76 | worldNorm *= input.blendWeights[0];@end 77 | @property( normal_map )float3 worldTang; 78 | worldTang.x = dot( worldMat[0].xyz, tangent ); 79 | worldTang.y = dot( worldMat[1].xyz, tangent ); 80 | worldTang.z = dot( worldMat[2].xyz, tangent ); 81 | worldTang *= input.blendWeights[0];@end 82 | 83 | @psub( NeedsMoreThan1BonePerVertex, hlms_bones_per_vertex, 1 ) 84 | @property( NeedsMoreThan1BonePerVertex )float4 tmp; 85 | tmp.w = 1.0;@end //!NeedsMoreThan1BonePerVertex 86 | @foreach( hlms_bones_per_vertex, n, 1 ) 87 | _idx = (input.blendIndices[@n] << 1u) + input.blendIndices[@n]; //blendIndices[@n] * 3; a 32-bit int multiply is 4 cycles on GCN! (and mul24 is not exposed to GLSL...) 88 | worldMat[0] = worldMatBuf.Load( int(matStart + _idx + 0u) ); 89 | worldMat[1] = worldMatBuf.Load( int(matStart + _idx + 1u) ); 90 | worldMat[2] = worldMatBuf.Load( int(matStart + _idx + 2u) ); 91 | tmp.x = dot( worldMat[0], input.vertex ); 92 | tmp.y = dot( worldMat[1], input.vertex ); 93 | tmp.z = dot( worldMat[2], input.vertex ); 94 | worldPos.xyz += (tmp * input.blendWeights[@n]).xyz; 95 | @property( hlms_normal || hlms_qtangent ) 96 | tmp.x = dot( worldMat[0].xyz, normal ); 97 | tmp.y = dot( worldMat[1].xyz, normal ); 98 | tmp.z = dot( worldMat[2].xyz, normal ); 99 | worldNorm += tmp.xyz * input.blendWeights[@n];@end 100 | @property( normal_map ) 101 | tmp.x = dot( worldMat[0].xyz, tangent ); 102 | tmp.y = dot( worldMat[1].xyz, tangent ); 103 | tmp.z = dot( worldMat[2].xyz, tangent ); 104 | worldTang += tmp.xyz * input.blendWeights[@n];@end 105 | @end 106 | 107 | worldPos.w = 1.0; 108 | @end @end //SkeletonTransform // !hlms_skeleton 109 | 110 | @property( hlms_skeleton ) 111 | @piece( worldViewMat )passBuf.view@end 112 | @end @property( !hlms_skeleton ) 113 | @piece( worldViewMat )worldView@end 114 | @end 115 | 116 | @piece( CalculatePsPos )mul( @insertpiece(local_vertex), @insertpiece( worldViewMat ) ).xyz@end 117 | 118 | @piece( VertexTransform ) 119 | //Lighting is in view space 120 | @property( hlms_normal || hlms_qtangent )outVs.pos = @insertpiece( CalculatePsPos );@end 121 | @property( hlms_normal || hlms_qtangent )outVs.normal = mul( @insertpiece(local_normal), (float3x3)@insertpiece( worldViewMat ) );@end 122 | @property( normal_map )outVs.tangent = mul( @insertpiece(local_tangent), (float3x3)@insertpiece( worldViewMat ) );@end 123 | @property( !hlms_dual_paraboloid_mapping ) 124 | outVs.gl_Position = mul( worldPos, passBuf.viewProj );@end 125 | @property( hlms_dual_paraboloid_mapping ) 126 | //Dual Paraboloid Mapping 127 | outVs.gl_Position.w = 1.0f; 128 | @property( hlms_normal || hlms_qtangent )outVs.gl_Position.xyz = outVs.pos;@end 129 | @property( !hlms_normal && !hlms_qtangent )outVs.gl_Position.xyz = @insertpiece( CalculatePsPos );@end 130 | float L = length( outVs.gl_Position.xyz ); 131 | outVs.gl_Position.z += 1.0f; 132 | outVs.gl_Position.xy /= outVs.gl_Position.z; 133 | outVs.gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end 134 | @end 135 | 136 | PS_INPUT main( VS_INPUT input ) 137 | { 138 | PS_INPUT outVs; 139 | @insertpiece( custom_vs_preExecution ) 140 | @property( !hlms_skeleton ) 141 | float4x3 worldMat = UNPACK_MAT4x3( worldMatBuf, input.drawId @property( !hlms_shadowcaster )<< 1u@end ); 142 | @property( hlms_normal || hlms_qtangent ) 143 | float4x4 worldView = UNPACK_MAT4( worldMatBuf, (input.drawId << 1u) + 1u ); 144 | @end 145 | 146 | float4 worldPos = float4( mul( input.vertex, worldMat ).xyz, 1.0f ); 147 | @end 148 | 149 | @property( hlms_qtangent ) 150 | //Decode qTangent to TBN with reflection 151 | float3 normal = xAxis( normalize( input.qtangent ) ); 152 | @property( normal_map ) 153 | float3 tangent = yAxis( input.qtangent ); 154 | outVs.biNormalReflection = sign( input.qtangent.w ); //We ensure in C++ qtangent.w is never 0 155 | @end 156 | @end @property( !hlms_qtangent && hlms_normal ) 157 | float3 normal = input.normal; 158 | @property( normal_map )float3 tangent = input.tangent;@end 159 | @end 160 | 161 | @insertpiece( SkeletonTransform ) 162 | @insertpiece( VertexTransform ) 163 | 164 | @insertpiece( DoShadowReceiveVS ) 165 | @insertpiece( DoShadowCasterVS ) 166 | 167 | /// hlms_uv_count will be 0 on shadow caster passes w/out alpha test 168 | @foreach( hlms_uv_count, n ) 169 | outVs.uv@n = input.uv@n;@end 170 | 171 | @property( (!hlms_shadowcaster || alpha_test) && !lower_gpu_overhead ) 172 | outVs.drawId = input.drawId;@end 173 | 174 | @property( hlms_use_prepass_msaa > 1 ) 175 | outVs.zwDepth.xy = outVs.gl_Position.zw; 176 | @end 177 | 178 | @property( hlms_global_clip_distances ) 179 | outVs.gl_ClipDistance0 = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); 180 | @end 181 | 182 | @insertpiece( custom_vs_posExecution ) 183 | 184 | return outVs; 185 | } 186 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/PbsMobile/GLSL/BlendModes_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @piece( NormalNonPremul ) 2 | //Normal Non Premultiplied @value(t) 3 | diffuseCol.xyz = mix( diffuseCol.xyz, detailCol@value(t).xyz, detailCol@value(t).a );@add( t, 1 ) 4 | @end 5 | 6 | @piece( NormalPremul ) 7 | //Normal Premultiplied @value(t) 8 | diffuseCol.xyz = (1.0 - detailCol@value(t).a) * diffuseCol.xyz + detailCol@value(t).xyz;@add( t, 1 ) 9 | @end 10 | 11 | @piece( Add ) 12 | //Add @value(t) 13 | diffuseCol.xyz = mix( diffuseCol.xyz, 14 | min( diffuseCol.xyz + detailCol@value(t).xyz, vec3(1.0) ), 15 | detailCol@value(t).a );@add( t, 1 ) 16 | @end 17 | 18 | @piece( Subtract ) 19 | //Subtract @value(t) 20 | diffuseCol.xyz = mix( diffuseCol.xyz, 21 | max( diffuseCol.xyz - detailCol@value(t).xyz, vec3(0.0) ), 22 | detailCol@value(t).a );@add( t, 1 ) 23 | @end 24 | 25 | @piece( Multiply ) 26 | //Multiply @value(t) 27 | diffuseCol.xyz = mix( diffuseCol.xyz, 28 | diffuseCol.xyz * detailCol@value(t).xyz, 29 | detailCol@value(t).a );@add( t, 1 ) 30 | @end 31 | 32 | @piece( Multiply2x ) 33 | //Multiply2x @value(t) 34 | diffuseCol.xyz = mix( diffuseCol.xyz, 35 | min( diffuseCol.xyz * detailCol@value(t).xyz * 2.0, vec3(1.0) ), 36 | detailCol@value(t).a );@add( t, 1 ) 37 | @end 38 | 39 | @piece( Screen ) 40 | //Screen @value(t) 41 | diffuseCol.xyz = mix( diffuseCol.xyz, 42 | 1.0 - (1.0 - diffuseCol.xyz) * (1.0 - detailCol@value(t).xyz), 43 | detailCol@value(t).a );@add( t, 1 ) 44 | @end 45 | 46 | @piece( Overlay ) 47 | //Overlay @value(t) 48 | diffuseCol.xyz = mix( diffuseCol.xyz, 49 | diffuseCol.xyz * ( diffuseCol.xyz + 2.0 * detailCol@value(t).xyz * (1.0 - diffuseCol.xyz) ), 50 | detailCol@value(t).a );@add( t, 1 ) 51 | @end 52 | 53 | @piece( Lighten ) 54 | //Lighten @value(t) 55 | diffuseCol.xyz = mix( diffuseCol.xyz, 56 | max( diffuseCol.xyz, detailCol@value(t).xyz ), 57 | detailCol@value(t).a );@add( t, 1 ) 58 | @end 59 | 60 | @piece( Darken ) 61 | //Darken @value(t) 62 | diffuseCol.xyz = mix( diffuseCol.xyz, 63 | min( diffuseCol.xyz, detailCol@value(t).xyz ), 64 | detailCol@value(t).a );@add( t, 1 ) 65 | @end 66 | 67 | @piece( GrainExtract ) 68 | //GrainExtract @value(t) 69 | diffuseCol.xyz = mix( diffuseCol.xyz, 70 | (diffuseCol.xyz - detailCol@value(t).xyz) + 0.5f, 71 | detailCol@value(t).a );@add( t, 1 ) 72 | @end 73 | 74 | @piece( GrainMerge ) 75 | //GrainMerge @value(t) 76 | diffuseCol.xyz = mix( diffuseCol.xyz, 77 | (diffuseCol.xyz + detailCol@value(t).xyz) - 0.5f, 78 | detailCol@value(t).a );@add( t, 1 ) 79 | @end 80 | 81 | @piece( Difference ) 82 | //Difference @value(t) 83 | diffuseCol.xyz = mix( diffuseCol.xyz, 84 | abs(diffuseCol.xyz - detailCol@value(t).xyz), 85 | detailCol@value(t).a );@add( t, 1 ) 86 | @end 87 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/PbsMobile/GLSL/VertexShader_vs.glsl: -------------------------------------------------------------------------------- 1 | @property( GL3+ )#version 330@end 2 | @property( !GL3+ )#define in attribute 3 | #define out varying@end 4 | 5 | in vec4 vertex; 6 | 7 | @property( hlms_normal )in vec3 normal;@end 8 | @property( hlms_qtangent )in vec4 normal;@end 9 | 10 | @property( normal_map && !hlms_qtangent ) 11 | in vec3 tangent; 12 | @property( hlms_binormal )in vec3 binormal;@end 13 | @end 14 | @property( hlms_normal ) 15 | out vec3 psPos; 16 | out vec3 psNormal; 17 | @property( normal_map )out vec3 psTangent;@end 18 | @end 19 | 20 | @property( hlms_skeleton ) 21 | in vec4 blendIndices; 22 | in vec4 blendWeights;@end 23 | 24 | @property( hlms_shadowcaster || hlms_pssm_splits )out float psDepth;@end 25 | 26 | @foreach( hlms_uv_count, n ) 27 | in vec@value( hlms_uv_count@n ) uv@n;@end 28 | @foreach( hlms_uv_count, n ) 29 | out vec@value( hlms_uv_count@n ) psUv@n;@end 30 | 31 | @foreach( hlms_num_shadow_maps, n ) 32 | out vec4 psPosL@n;@end 33 | 34 | // START UNIFORM DECLARATION 35 | @property( !hlms_shadowcaster )@property( hlms_num_shadow_maps ) 36 | //Uniforms that change per pass 37 | uniform mat4 texWorldViewProj[@value(hlms_num_shadow_maps)]; 38 | uniform vec2 shadowDepthRange[@value(hlms_num_shadow_maps)];@end @end 39 | @property( hlms_shadowcaster )uniform vec2 depthRange;@end 40 | //Uniforms that change per pass (skeleton anim) or per entity (non-skeleton anim) 41 | //Note: worldView becomes "view" and worldViewProj "viewProj" on skel. anim. 42 | uniform mat4 worldViewProj; 43 | @property( !hlms_shadowcaster )uniform mat4 worldView;@end 44 | //Uniforms that change per entity 45 | @property( hlms_skeleton )uniform vec4 worldMat[180]; //180 = 60 matrices * 3 rows per matrix@end 46 | @property( hlms_shadowcaster )uniform float shadowConstantBias;@end 47 | // END UNIFORM DECLARATION 48 | 49 | @property( !hlms_skeleton ) 50 | @piece( local_vertex )vertex@end 51 | @piece( local_normal )normal@end 52 | @piece( local_tangent )tangent@end 53 | @end 54 | @property( hlms_skeleton ) 55 | @piece( local_vertex )_localPos@end 56 | @piece( local_normal )_localNorm@end 57 | @piece( local_tangent )_localTang@end 58 | @end 59 | 60 | @property( hlms_skeleton )@piece( SkeletonTransform ) 61 | int _idx = int(blendIndices[0] * 3.0); 62 | vec4 _localPos; 63 | _localPos.x = dot( worldMat[_idx + 0], vertex ); 64 | _localPos.y = dot( worldMat[_idx + 1], vertex ); 65 | _localPos.z = dot( worldMat[_idx + 2], vertex ); 66 | _localPos.xyz *= blendWeights[0]; 67 | @property( hlms_normal )vec3 _localNorm; 68 | _localNorm.x = dot( worldMat[_idx + 0].xyz, normal ); 69 | _localNorm.y = dot( worldMat[_idx + 1].xyz, normal ); 70 | _localNorm.z = dot( worldMat[_idx + 2].xyz, normal ); 71 | _localNorm *= blendWeights[0];@end 72 | @property( normal_map )vec3 _localTang; 73 | _localTang.x = dot( worldMat[_idx + 0].xyz, tangent ); 74 | _localTang.y = dot( worldMat[_idx + 1].xyz, tangent ); 75 | _localTang.z = dot( worldMat[_idx + 2].xyz, tangent ); 76 | _localTang *= blendWeights[0];@end 77 | 78 | @psub( NeedsMoreThan1BonePerVertex, hlms_bones_per_vertex, 1 ) 79 | @property( NeedsMoreThan1BonePerVertex )vec3 tmp;@end 80 | @foreach( hlms_bones_per_vertex, n, 1 ) 81 | _idx = int(blendIndices[@n] * 3.0); 82 | tmp.x = dot( worldMat[_idx + 0], vertex ); 83 | tmp.y = dot( worldMat[_idx + 1], vertex ); 84 | tmp.z = dot( worldMat[_idx + 2], vertex ); 85 | _localPos.xyz += tmp.xyz * blendWeights[@n]; 86 | @property( hlms_normal ) 87 | tmp.x = dot( worldMat[_idx + 0].xyz, normal ); 88 | tmp.y = dot( worldMat[_idx + 1].xyz, normal ); 89 | tmp.z = dot( worldMat[_idx + 2].xyz, normal ); 90 | _localNorm += tmp.xyz * blendWeights[@n];@end 91 | @property( normal_map ) 92 | tmp.x = dot( worldMat[_idx + 0].xyz, tangent ); 93 | tmp.y = dot( worldMat[_idx + 1].xyz, tangent ); 94 | tmp.z = dot( worldMat[_idx + 2].xyz, tangent ); 95 | _localTang += tmp.xyz * blendWeights[@n];@end 96 | @end 97 | 98 | _localPos.w = 1.0; 99 | @end @end 100 | 101 | @piece( CalculatePsPos )(worldView * @insertpiece(local_vertex)).xyz@end 102 | 103 | @piece( VertexTransform ) 104 | //Lighting is in view space 105 | @property( hlms_normal )psPos = @insertpiece( CalculatePsPos );@end 106 | @property( hlms_normal )psNormal = mat3(worldView) * @insertpiece(local_normal);@end 107 | @property( normal_map )psTangent = mat3(worldView) * @insertpiece(local_tangent);@end 108 | @property( !hlms_dual_paraboloid_mapping ) 109 | gl_Position = worldViewProj * @insertpiece(local_vertex);@end 110 | @property( hlms_dual_paraboloid_mapping ) 111 | //Dual Paraboloid Mapping 112 | gl_Position.w = 1.0f; 113 | @property( hlms_normal )gl_Position.xyz = psPos;@end 114 | @property( !hlms_normal )gl_Position.xyz = @insertpiece( CalculatePsPos );@end 115 | float L = length( gl_Position.xyz ); 116 | gl_Position.z += 1.0f; 117 | gl_Position.xy /= gl_Position.z; 118 | gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end 119 | @end 120 | @piece( ShadowReceive ) 121 | @foreach( hlms_num_shadow_maps, n ) 122 | psPosL@n = texWorldViewProj[@n] * @insertpiece(local_vertex);@end 123 | @end 124 | 125 | void main() 126 | { 127 | @insertpiece( SkeletonTransform ) 128 | @insertpiece( VertexTransform ) 129 | @foreach( hlms_uv_count, n ) 130 | psUv@n = uv@n;@end 131 | 132 | @property( !hlms_shadowcaster ) 133 | @insertpiece( ShadowReceive ) 134 | @foreach( hlms_num_shadow_maps, n ) 135 | psPosL@n.z = (psPosL@n.z - shadowDepthRange[@n].x) * shadowDepthRange[@n].y;@end 136 | 137 | @property( hlms_pssm_splits ) psDepth = gl_Position.z;@end 138 | @end @property( hlms_shadowcaster ) 139 | //Linear depth 140 | psDepth = (gl_Position.z - depthRange.x + shadowConstantBias) * depthRange.y; 141 | 142 | //We can't make the depth buffer linear without Z out in the fragment shader; 143 | //however we can use a cheap approximation ("pseudo linear depth") 144 | //see http://yosoygames.com.ar/wp/2014/01/linear-depth-buffer-my-ass/ 145 | gl_Position.z = gl_Position.z * (gl_Position.w * depthRange.y); 146 | @end 147 | } 148 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/Any/StructsUnlit_piece_all.any: -------------------------------------------------------------------------------- 1 | 2 | @piece( PassInternalDecl ) 3 | //Vertex shader 4 | float4x4 viewProj[2]; 5 | @property( hlms_global_clip_distances ) 6 | float4 clipPlane0; 7 | @end 8 | @property( hlms_global_clip_distances || exponential_shadow_maps || hlms_shadowcaster_point )float4x4 invViewProj;@end 9 | @property( hlms_shadowcaster ) 10 | @property( exponential_shadow_maps )float4 viewZRow;@end 11 | float4 depthRange; 12 | @property( hlms_shadowcaster_point ) 13 | float4 cameraPosWS; //Camera position in world space 14 | @end 15 | @end 16 | //Pixel Shader 17 | float4 invWindowSize; 18 | @insertpiece( custom_passBuffer ) 19 | @end 20 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/GLSL/BlendModes_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @piece( NormalNonPremul ) 5 | //Normal Non Premultiplied @counter(t) 6 | outColour.xyz = mix( outColour.xyz, topImage@value(t).xyz, topImage@value(t).a ); 7 | outColour.w = mix( outColour.w, 1.0, topImage@value(t).w ); 8 | @end 9 | 10 | @piece( NormalPremul ) 11 | //Normal Premultiplied @counter(t) 12 | outColour.xyz = (1.0 - topImage@value(t).a) * outColour.xyz + topImage@value(t).xyz; 13 | outColour.w = mix( outColour.w, 1.0, topImage@value(t).w ); 14 | @end 15 | 16 | @piece( Add ) 17 | //Add @counter(t) 18 | outColour.xyz = mix( outColour.xyz, 19 | min( outColour.xyz + topImage@value(t).xyz, vec3(1.0) ), 20 | topImage@value(t).a ); 21 | @end 22 | 23 | @piece( Subtract ) 24 | //Subtract @counter(t) 25 | outColour.xyz = mix( outColour.xyz, 26 | max( outColour.xyz - topImage@value(t).xyz, vec3(0.0) ), 27 | topImage@value(t).a ); 28 | @end 29 | 30 | @piece( Multiply ) 31 | //Multiply @counter(t) 32 | outColour.xyz = mix( outColour.xyz, 33 | outColour.xyz * topImage@value(t).xyz, 34 | topImage@value(t).a ); 35 | @end 36 | 37 | @piece( Multiply2x ) 38 | //Multiply2x @counter(t) 39 | outColour.xyz = mix( outColour.xyz, 40 | min( outColour.xyz * topImage@value(t).xyz * 2.0, vec3(1.0) ), 41 | topImage@value(t).a ); 42 | @end 43 | 44 | @piece( Screen ) 45 | //Screen @counter(t) 46 | outColour.xyz = mix( outColour.xyz, 47 | 1.0 - (1.0 - outColour.xyz) * (1.0 - topImage@value(t).xyz), 48 | topImage@value(t).a ); 49 | @end 50 | 51 | @piece( Overlay ) 52 | //Overlay @counter(t) 53 | outColour.xyz = mix( outColour.xyz, 54 | outColour.xyz * ( outColour.xyz + 2.0 * topImage@value(t).xyz * (1.0 - outColour.xyz) ), 55 | topImage@value(t).a ); 56 | @end 57 | 58 | @piece( Lighten ) 59 | //Lighten @counter(t) 60 | outColour.xyz = mix( outColour.xyz, 61 | max( outColour.xyz, topImage@value(t).xyz ), 62 | topImage@value(t).a ); 63 | @end 64 | 65 | @piece( Darken ) 66 | //Darken @counter(t) 67 | outColour.xyz = mix( outColour.xyz, 68 | min( outColour.xyz, topImage@value(t).xyz ), 69 | topImage@value(t).a ); 70 | @end 71 | 72 | @piece( GrainExtract ) 73 | //GrainExtract @counter(t) 74 | outColour.xyz = mix( outColour.xyz, 75 | (outColour.xyz - topImage@value(t).xyz) + 0.5f, 76 | topImage@value(t).a ); 77 | @end 78 | 79 | @piece( GrainMerge ) 80 | //GrainMerge @counter(t) 81 | outColour.xyz = mix( outColour.xyz, 82 | (outColour.xyz + topImage@value(t).xyz) - 0.5f, 83 | topImage@value(t).a ); 84 | @end 85 | 86 | @piece( Difference ) 87 | //Difference @counter(t) 88 | outColour.xyz = mix( outColour.xyz, 89 | abs(outColour.xyz - topImage@value(t).xyz), 90 | topImage@value(t).a ); 91 | @end 92 | 93 | @foreach( 16, n ) 94 | @property( uv_atlas@n ) @piece( atlasOffset@n )* atlasOffsets[@n].z + atlasOffsets[@n].xy @end @end @end 95 | 96 | // Get the indexes to the textureMaps[] array using template code. We had to add 1 97 | // to the actual value otherwise property( diffuse_map ) fails when the index is 0 98 | @foreach( diffuse_map, n ) 99 | @sub( diffuse_map@n_idx, diffuse_map@n, 1 ) @end 100 | 101 | @piece( diffuseIdx0 )material.indices0_3.x & 0x0000FFFFu@end 102 | @piece( diffuseIdx1 )material.indices0_3.x >> 16u@end 103 | @piece( diffuseIdx2 )material.indices0_3.y & 0x0000FFFFu@end 104 | @piece( diffuseIdx3 )material.indices0_3.y >> 16u@end 105 | @piece( diffuseIdx4 )material.indices0_3.z & 0x0000FFFFu@end 106 | @piece( diffuseIdx5 )material.indices0_3.z >> 16u@end 107 | @piece( diffuseIdx6 )material.indices0_3.w & 0x0000FFFFu@end 108 | @piece( diffuseIdx7 )material.indices0_3.w >> 16u@end 109 | 110 | @foreach( diffuse_map, n ) 111 | @property( diffuse_map@n_array ) 112 | @piece( SamplerOrigin@n )textureMapsArray[@value(diffuse_map@n_idx)]@end 113 | @end @property( !diffuse_map@n_array ) 114 | @piece( SamplerOrigin@n )textureMaps[@value(diffuse_map@n_idx)]@end 115 | @end 116 | @property( !diffuse_map@n_reflection ) 117 | @property( diffuse_map@n_array ) 118 | @piece( SamplerUV@n )vec3( inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n ), @insertpiece( diffuseIdx@n ) )@end 119 | @end @property( !diffuse_map@n_array ) 120 | @piece( SamplerUV@n )inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n )@end 121 | @end 122 | @end @property( diffuse_map@n_reflection ) 123 | @property( !hlms_forwardplus_flipY ) 124 | @property( diffuse_map@n_array ) 125 | @piece( SamplerUV@n )vec3( gl_FragCoord.x * passBuf.invWindowSize.x, 1.0 - gl_FragCoord.y * passBuf.invWindowSize.y, @insertpiece( diffuseIdx@n ) )@end 126 | @end @property( !diffuse_map@n_array ) 127 | @piece( SamplerUV@n )vec2( gl_FragCoord.x * passBuf.invWindowSize.x, 1.0 - gl_FragCoord.y * passBuf.invWindowSize.y )@end 128 | @end 129 | @end @property( hlms_forwardplus_flipY ) 130 | @property( diffuse_map@n_array ) 131 | @piece( SamplerUV@n )vec3( gl_FragCoord.xy * passBuf.invWindowSize.xy, @insertpiece( diffuseIdx@n ) )@end 132 | @end @property( !diffuse_map@n_array ) 133 | @piece( SamplerUV@n )vec2( gl_FragCoord.xy * passBuf.invWindowSize.xy )@end 134 | @end 135 | @end 136 | @end 137 | @end 138 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/GLSL/PixelShader_ps.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | layout(std140) uniform; 4 | #define FRAG_COLOR 0 5 | 6 | @property( hlms_vpos ) 7 | in vec4 gl_FragCoord; 8 | @end 9 | 10 | @property( !hlms_shadowcaster ) 11 | layout(location = FRAG_COLOR, index = 0) out vec4 outColour; 12 | @end @property( hlms_shadowcaster ) 13 | layout(location = FRAG_COLOR, index = 0) out float outColour; 14 | @end 15 | 16 | // START UNIFORM DECLARATION 17 | @property( has_planar_reflections ) 18 | @insertpiece( PassDecl ) 19 | @end 20 | @property( !hlms_shadowcaster ) 21 | @insertpiece( MaterialDecl ) 22 | @insertpiece( InstanceDecl ) 23 | @end 24 | @insertpiece( custom_ps_uniformDeclaration ) 25 | // END UNIFORM DECLARATION 26 | in block 27 | { 28 | @insertpiece( VStoPS_block ) 29 | } inPs; 30 | 31 | @property( !hlms_shadowcaster ) 32 | @property( num_array_textures )uniform sampler2DArray textureMapsArray[@value( num_array_textures )];@end 33 | @property( num_textures )uniform sampler2D textureMaps[@value( num_textures )];@end 34 | 35 | @property( diffuse )@piece( MultiplyDiffuseConst )* material.diffuse@end @end 36 | 37 | @property( diffuse_map || alpha_test || diffuse )Material material;@end 38 | 39 | void main() 40 | { 41 | @insertpiece( custom_ps_preExecution ) 42 | @property( diffuse_map || alpha_test || diffuse ) 43 | uint materialId = instance.worldMaterialIdx[inPs.drawId].x; 44 | material = materialArray.m[materialId]; 45 | @end 46 | @insertpiece( custom_ps_posMaterialLoad ) 47 | 48 | @property( !diffuse_map && !diffuse_map0 ) 49 | @property( hlms_colour && !diffuse_map ) outColour = inPs.colour @insertpiece( MultiplyDiffuseConst );@end 50 | @property( !hlms_colour && !diffuse ) outColour = vec4(1, 1, 1, 1);@end 51 | @property( !hlms_colour && diffuse ) outColour = material.diffuse;@end 52 | @end 53 | 54 | @property( diffuse_map )@property( diffuse_map0 ) 55 | //Load base image 56 | outColour = texture( @insertpiece( SamplerOrigin0 ), @insertpiece( SamplerUV0 ) ).@insertpiece(diffuse_map0_tex_swizzle);@end 57 | 58 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 59 | vec4 topImage@n = texture( @insertpiece( SamplerOrigin@n ), @insertpiece( SamplerUV@n ) ).@insertpiece(diffuse_map@n_tex_swizzle);@end @end 60 | 61 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 62 | @insertpiece( blend_mode_idx@n )@end @end 63 | 64 | @property( hlms_colour )outColour *= inPs.colour @insertpiece( MultiplyDiffuseConst );@end 65 | @property( !hlms_colour && diffuse )outColour *= material.diffuse;@end 66 | @end 67 | 68 | @insertpiece( custom_ps_preLights ) 69 | 70 | @property( alpha_test ) 71 | if( material.alpha_test_threshold.x @insertpiece( alpha_test_cmp_func ) outColour.a ) 72 | discard;@end 73 | 74 | @insertpiece( custom_ps_posExecution ) 75 | } 76 | 77 | @end @property( hlms_shadowcaster ) 78 | @property( hlms_render_depth_only ) 79 | @set( hlms_disable_stage, 1 ) 80 | @end 81 | 82 | @insertpiece( DeclShadowCasterMacros ) 83 | 84 | @property( hlms_shadowcaster_point ) 85 | @insertpiece( PassDecl ) 86 | @end 87 | 88 | void main() 89 | { 90 | @insertpiece( custom_ps_preExecution ) 91 | @insertpiece( DoShadowCastPS ) 92 | @insertpiece( custom_ps_posExecution ) 93 | } 94 | @end 95 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/GLSL/Structs_piece_vs_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @piece( PassDecl ) 2 | //Uniforms that change per pass 3 | layout(binding = 0) uniform PassBuffer 4 | { 5 | @insertpiece( PassInternalDecl ) 6 | } passBuf; 7 | @end 8 | 9 | @piece( MaterialDecl ) 10 | struct Material 11 | { 12 | vec4 alpha_test_threshold; 13 | vec4 diffuse; 14 | 15 | uvec4 indices0_3; 16 | uvec4 indices4_7; 17 | }; 18 | 19 | layout(binding = 1) uniform MaterialBuf 20 | { 21 | Material m[@value( materials_per_buffer )]; 22 | } materialArray; 23 | @end 24 | 25 | 26 | @piece( InstanceDecl ) 27 | //Uniforms that change per Item/Entity 28 | layout(binding = 2) uniform InstanceBuffer 29 | { 30 | //.x = 31 | //Contains the material's start index. 32 | // 33 | //.y = 34 | //shadowConstantBias. Send the bias directly to avoid an 35 | //unnecessary indirection during the shadow mapping pass. 36 | //Must be loaded with uintBitsToFloat 37 | // 38 | //.z = 39 | //Contains 0 or 1 to index into passBuf.viewProj[]. Only used 40 | //if hlms_identity_viewproj_dynamic is set. 41 | uvec4 worldMaterialIdx[4096]; 42 | } instance; 43 | @end 44 | 45 | @piece( VStoPS_block ) 46 | @property( !hlms_shadowcaster ) 47 | flat uint drawId; 48 | @property( hlms_colour )vec4 colour;@end 49 | @foreach( out_uv_half_count, n ) 50 | vec@value( out_uv_half_count@n ) uv@n;@end 51 | @end 52 | @property( hlms_shadowcaster ) 53 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 54 | float depth; 55 | @end 56 | @property( hlms_shadowcaster_point ) 57 | vec3 toCameraWS; 58 | @property( !exponential_shadow_maps ) 59 | flat float constBias; 60 | @end 61 | @end 62 | @end 63 | @insertpiece( custom_VStoPS ) 64 | @end 65 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/GLSL/VertexShader_vs.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | out gl_PerVertex 4 | { 5 | vec4 gl_Position; 6 | @property( hlms_global_clip_distances ) 7 | float gl_ClipDistance[1]; 8 | @end 9 | }; 10 | 11 | layout(std140) uniform; 12 | 13 | @insertpiece( Common_Matrix_DeclUnpackMatrix4x4 ) 14 | 15 | in vec4 vertex; 16 | @property( hlms_colour )in vec4 colour;@end 17 | 18 | @foreach( hlms_uv_count, n ) 19 | in vec@value( hlms_uv_count@n ) uv@n;@end 20 | 21 | in uint drawId; 22 | 23 | @insertpiece( custom_vs_attributes ) 24 | 25 | @property( !hlms_shadowcaster || !hlms_shadow_uses_depth_texture || exponential_shadow_maps ) 26 | out block 27 | { 28 | @insertpiece( VStoPS_block ) 29 | } outVs; 30 | @end 31 | 32 | // START UNIFORM DECLARATION 33 | @insertpiece( PassDecl ) 34 | @insertpiece( InstanceDecl ) 35 | layout(binding = 0) uniform samplerBuffer worldMatBuf; 36 | @property( texture_matrix )layout(binding = 1) uniform samplerBuffer animationMatrixBuf;@end 37 | @insertpiece( custom_vs_uniformDeclaration ) 38 | // END UNIFORM DECLARATION 39 | 40 | @property( !hlms_identity_world ) 41 | @piece( worldViewProj )worldViewProj@end 42 | @end @property( hlms_identity_world ) 43 | @property( !hlms_identity_viewproj_dynamic ) 44 | @piece( worldViewProj )passBuf.viewProj[@value(hlms_identity_viewproj)]@end 45 | @end @property( hlms_identity_viewproj_dynamic ) 46 | @piece( worldViewProj )passBuf.viewProj[instance.worldMaterialIdx[drawId].z]@end 47 | @end 48 | @end 49 | 50 | void main() 51 | { 52 | @insertpiece( custom_vs_preExecution ) 53 | @property( !hlms_identity_world ) 54 | mat4 worldViewProj; 55 | worldViewProj = UNPACK_MAT4( worldMatBuf, drawId ); 56 | @end 57 | 58 | @property( !hlms_dual_paraboloid_mapping ) 59 | gl_Position = vertex * @insertpiece( worldViewProj ); 60 | @end 61 | 62 | @property( hlms_dual_paraboloid_mapping ) 63 | //Dual Paraboloid Mapping 64 | gl_Position.w = 1.0f; 65 | gl_Position.xyz = (vertex * @insertpiece( worldViewProj )).xyz; 66 | float L = length( gl_Position.xyz ); 67 | gl_Position.z += 1.0f; 68 | gl_Position.xy /= gl_Position.z; 69 | gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane); 70 | @end 71 | 72 | @property( !hlms_shadowcaster ) 73 | @property( hlms_colour ) outVs.colour = colour;@end 74 | 75 | @property( texture_matrix ) mat4 textureMatrix;@end 76 | 77 | @foreach( out_uv_count, n ) 78 | @property( out_uv@n_texture_matrix ) 79 | textureMatrix = UNPACK_MAT4( animationMatrixBuf, (instance.worldMaterialIdx[drawId].x << 4u) + @value( out_uv@n_tex_unit )u ); 80 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = (vec4( uv@value( out_uv@n_source_uv ).xy, 0, 1 ) * textureMatrix).xy; 81 | @end @property( !out_uv@n_texture_matrix ) 82 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = uv@value( out_uv@n_source_uv ).xy; 83 | @end @end 84 | 85 | outVs.drawId = drawId; 86 | 87 | @end 88 | 89 | @property( hlms_global_clip_distances || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point)) ) 90 | float3 worldPos = (gl_Position * passBuf.invViewProj).xyz; 91 | @end 92 | @insertpiece( DoShadowCasterVS ) 93 | 94 | @property( hlms_global_clip_distances ) 95 | gl_ClipDistance[0] = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); 96 | @end 97 | 98 | @insertpiece( custom_vs_posExecution ) 99 | } 100 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/HLSL/BlendModes_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @piece( NormalNonPremul ) 5 | //Normal Non Premultiplied @counter(t) 6 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, topImage@value(t).xyz, topImage@value(t).a ); 7 | outPs.colour0.w = lerp( outPs.colour0.w, 1.0, topImage@value(t).w ); 8 | @end 9 | 10 | @piece( NormalPremul ) 11 | //Normal Premultiplied @counter(t) 12 | outPs.colour0.xyz = (1.0 - topImage@value(t).a) * outPs.colour0.xyz + topImage@value(t).xyz; 13 | outPs.colour0.w = lerp( outPs.colour0.w, 1.0, topImage@value(t).w ); 14 | @end 15 | 16 | @piece( Add ) 17 | //Add @counter(t) 18 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 19 | min( outPs.colour0.xyz + topImage@value(t).xyz, float3(1.0) ), 20 | topImage@value(t).a ); 21 | @end 22 | 23 | @piece( Subtract ) 24 | //Subtract @counter(t) 25 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 26 | max( outPs.colour0.xyz - topImage@value(t).xyz, float3(0.0) ), 27 | topImage@value(t).a ); 28 | @end 29 | 30 | @piece( Multiply ) 31 | //Multiply @counter(t) 32 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 33 | outPs.colour0.xyz * topImage@value(t).xyz, 34 | topImage@value(t).a ); 35 | @end 36 | 37 | @piece( Multiply2x ) 38 | //Multiply2x @counter(t) 39 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 40 | min( outPs.colour0.xyz * topImage@value(t).xyz * 2.0, float3(1.0) ), 41 | topImage@value(t).a ); 42 | @end 43 | 44 | @piece( Screen ) 45 | //Screen @counter(t) 46 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 47 | 1.0 - (1.0 - outPs.colour0.xyz) * (1.0 - topImage@value(t).xyz), 48 | topImage@value(t).a ); 49 | @end 50 | 51 | @piece( Overlay ) 52 | //Overlay @counter(t) 53 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 54 | outPs.colour0.xyz * ( outPs.colour0.xyz + 2.0 * topImage@value(t).xyz * (1.0 - outPs.colour0.xyz) ), 55 | topImage@value(t).a ); 56 | @end 57 | 58 | @piece( Lighten ) 59 | //Lighten @counter(t) 60 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 61 | max( outPs.colour0.xyz, topImage@value(t).xyz ), 62 | topImage@value(t).a ); 63 | @end 64 | 65 | @piece( Darken ) 66 | //Darken @counter(t) 67 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 68 | min( outPs.colour0.xyz, topImage@value(t).xyz ), 69 | topImage@value(t).a ); 70 | @end 71 | 72 | @piece( GrainExtract ) 73 | //GrainExtract @counter(t) 74 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 75 | (outPs.colour0.xyz - topImage@value(t).xyz) + 0.5f, 76 | topImage@value(t).a ); 77 | @end 78 | 79 | @piece( GrainMerge ) 80 | //GrainMerge @counter(t) 81 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 82 | (outPs.colour0.xyz + topImage@value(t).xyz) - 0.5f, 83 | topImage@value(t).a ); 84 | @end 85 | 86 | @piece( Difference ) 87 | //Difference @counter(t) 88 | outPs.colour0.xyz = lerp( outPs.colour0.xyz, 89 | abs(outPs.colour0.xyz - topImage@value(t).xyz), 90 | topImage@value(t).a ); 91 | @end 92 | 93 | @foreach( 16, n ) 94 | @property( uv_atlas@n ) @piece( atlasOffset@n )* atlasOffsets[@n].z + atlasOffsets[@n].xy @end @end @end 95 | 96 | // Get the indexes to the textureMaps[] array using template code. We had to add 1 97 | // to the actual value otherwise property( diffuse_map ) fails when the index is 0 98 | @foreach( diffuse_map, n ) 99 | @sub( diffuse_map@n_idx, diffuse_map@n, 1 ) @end 100 | 101 | @piece( diffuseIdx0 )material.indices0_3.x & 0x0000FFFFu@end 102 | @piece( diffuseIdx1 )material.indices0_3.x >> 16u@end 103 | @piece( diffuseIdx2 )material.indices0_3.y & 0x0000FFFFu@end 104 | @piece( diffuseIdx3 )material.indices0_3.y >> 16u@end 105 | @piece( diffuseIdx4 )material.indices0_3.z & 0x0000FFFFu@end 106 | @piece( diffuseIdx5 )material.indices0_3.z >> 16u@end 107 | @piece( diffuseIdx6 )material.indices0_3.w & 0x0000FFFFu@end 108 | @piece( diffuseIdx7 )material.indices0_3.w >> 16u@end 109 | 110 | @foreach( diffuse_map, n ) 111 | @property( !diffuse_map@n_reflection ) 112 | @property( diffuse_map@n_array ) 113 | @piece( TextureOrigin@n )textureMapsArray@value(diffuse_map@n_idx)@end 114 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 115 | @piece( SamplerUV@n )float3( inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n ), @insertpiece( diffuseIdx@n ) )@end 116 | @end @property( !diffuse_map@n_array ) 117 | @piece( TextureOrigin@n )textureMaps@value(diffuse_map@n_idx)@end 118 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 119 | @piece( SamplerUV@n )inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n )@end 120 | @end 121 | @end @property( diffuse_map@n_reflection ) 122 | @property( diffuse_map@n_array ) 123 | @piece( TextureOrigin@n )textureMapsArray@value(diffuse_map@n_idx)@end 124 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 125 | @piece( SamplerUV@n )float3( gl_FragCoord.xy * passBuf.invWindowSize.xy, @insertpiece( diffuseIdx@n ) )@end 126 | @end @property( !diffuse_map@n_array ) 127 | @piece( TextureOrigin@n )textureMaps@value(diffuse_map@n_idx)@end 128 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 129 | @piece( SamplerUV@n )gl_FragCoord.xy * passBuf.invWindowSize.xy@end 130 | @end 131 | @end 132 | @end 133 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/HLSL/PixelShader_ps.hlsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | // START UNIFORM DECLARATION 4 | @property( has_planar_reflections ) 5 | @insertpiece( PassDecl ) 6 | @end 7 | @property( !hlms_shadowcaster ) 8 | @insertpiece( MaterialDecl ) 9 | @insertpiece( InstanceDecl ) 10 | @end 11 | @insertpiece( custom_ps_uniformDeclaration ) 12 | // END UNIFORM DECLARATION 13 | struct PS_INPUT 14 | { 15 | @insertpiece( VStoPS_block ) 16 | }; 17 | 18 | @property( !hlms_shadowcaster ) 19 | 20 | @foreach( num_array_textures, n ) 21 | Texture2DArray textureMapsArray@n : register(t@value(array_texture_bind@n));@end 22 | @foreach( num_textures, n ) 23 | Texture2D textureMaps@n : register(t@value(texture_bind@n));@end 24 | 25 | @padd( numSamplerStates, num_array_textures, num_textures ) 26 | @pset( samplerStateBind, 2 ) 27 | 28 | @foreach( numSamplerStates, n ) 29 | SamplerState samplerState@n : register(s@counter(samplerStateBind));@end 30 | 31 | @property( diffuse )@piece( MultiplyDiffuseConst )* material.diffuse@end @end 32 | 33 | @insertpiece( DeclOutputType ) 34 | 35 | @insertpiece( output_type ) main( PS_INPUT inPs 36 | @property( hlms_vpos ), float4 gl_FragCoord : SV_Position@end ) 37 | { 38 | PS_OUTPUT outPs; 39 | @insertpiece( custom_ps_preExecution ) 40 | 41 | @property( diffuse_map || alpha_test || diffuse )Material material;@end 42 | 43 | @property( diffuse_map || alpha_test || diffuse ) 44 | uint materialId = worldMaterialIdx[inPs.drawId].x; 45 | material = materialArray[materialId]; 46 | @end 47 | 48 | @insertpiece( custom_ps_posMaterialLoad ) 49 | 50 | @property( !diffuse_map && !diffuse_map0 ) 51 | @property( hlms_colour && !diffuse_map ) outPs.colour0 = inPs.colour @insertpiece( MultiplyDiffuseConst );@end 52 | @property( !hlms_colour && !diffuse ) outPs.colour0 = float4(1, 1, 1, 1);@end 53 | @property( !hlms_colour && diffuse ) outPs.colour0 = material.diffuse;@end 54 | @end 55 | 56 | @property( diffuse_map )@property( diffuse_map0 ) 57 | //Load base image 58 | outPs.colour0 = @insertpiece( TextureOrigin0 ).Sample( @insertpiece( SamplerOrigin0 ), @insertpiece( SamplerUV0 ) ).@insertpiece(diffuse_map0_tex_swizzle);@end 59 | 60 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 61 | float4 topImage@n = @insertpiece( TextureOrigin@n ).Sample( @insertpiece( SamplerOrigin@n ), @insertpiece( SamplerUV@n ) ).@insertpiece(diffuse_map@n_tex_swizzle);@end @end 62 | 63 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 64 | @insertpiece( blend_mode_idx@n )@end @end 65 | 66 | @property( hlms_colour )outPs.colour0 *= inPs.colour @insertpiece( MultiplyDiffuseConst );@end 67 | @property( !hlms_colour && diffuse )outPs.colour0 *= material.diffuse;@end 68 | @end 69 | 70 | @insertpiece( custom_ps_preLights ) 71 | 72 | @property( alpha_test ) 73 | if( material.alpha_test_threshold.x @insertpiece( alpha_test_cmp_func ) outPs.colour0.a ) 74 | discard;@end 75 | 76 | @insertpiece( custom_ps_posExecution ) 77 | 78 | @property( !hlms_render_depth_only ) 79 | return outPs; 80 | @end 81 | } 82 | @end @property( hlms_shadowcaster ) 83 | @property( hlms_render_depth_only ) 84 | @set( hlms_disable_stage, 1 ) 85 | @end 86 | @insertpiece( DeclShadowCasterMacros ) 87 | 88 | @property( hlms_shadowcaster_point ) 89 | @insertpiece( PassDecl ) 90 | @end 91 | 92 | @insertpiece( DeclOutputType ) 93 | @insertpiece( output_type ) main( PS_INPUT inPs 94 | @property( hlms_vpos ), float4 gl_FragCoord : SV_Position@end ) 95 | { 96 | PS_OUTPUT outPs; 97 | @insertpiece( custom_ps_preExecution ) 98 | @insertpiece( DoShadowCastPS ) 99 | @insertpiece( custom_ps_posExecution ) 100 | return outPs; 101 | } 102 | @end 103 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/HLSL/Structs_piece_vs_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | @piece( PassDecl ) 2 | //Uniforms that change per pass 3 | cbuffer PassBuffer : register(b0) 4 | { 5 | struct PassData 6 | { 7 | @insertpiece( PassInternalDecl ) 8 | } passBuf; 9 | }; 10 | @end 11 | 12 | @piece( MaterialDecl ) 13 | struct Material 14 | { 15 | float4 alpha_test_threshold; 16 | float4 diffuse; 17 | 18 | uint4 indices0_3; 19 | uint4 indices4_7; 20 | }; 21 | 22 | cbuffer materialArray : register(b1) 23 | { 24 | Material materialArray[@value( materials_per_buffer )]; 25 | }; 26 | @end 27 | 28 | 29 | @piece( InstanceDecl ) 30 | //Uniforms that change per Item/Entity 31 | cbuffer instance : register(b2) 32 | { 33 | //.x = 34 | //Contains the material's start index. 35 | // 36 | //.y = 37 | //shadowConstantBias. Send the bias directly to avoid an 38 | //unnecessary indirection during the shadow mapping pass. 39 | //Must be loaded with uintBitsToFloat 40 | // 41 | //.z = 42 | //Contains 0 or 1 to index into passBuf.viewProj[]. Only used 43 | //if hlms_identity_viewproj_dynamic is set. 44 | @property( fast_shader_build_hack ) 45 | uint4 worldMaterialIdx[2]; 46 | @end @property( !fast_shader_build_hack ) 47 | uint4 worldMaterialIdx[4096]; 48 | @end 49 | }; 50 | @end 51 | 52 | //Reset texcoord to 0 for every shader stage (since values are preserved). 53 | @pset( texcoord, 0 ) 54 | 55 | @piece( VStoPS_block ) 56 | @property( !hlms_shadowcaster ) 57 | nointerpolation uint drawId : TEXCOORD@counter(texcoord); 58 | @property( hlms_colour )float4 colour : TEXCOORD@counter(texcoord);@end 59 | @foreach( out_uv_half_count, n ) 60 | float@value( out_uv_half_count@n ) uv@n : TEXCOORD@counter(texcoord);@end 61 | @end 62 | @property( hlms_shadowcaster ) 63 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 64 | float depth : TEXCOORD@counter(texcoord); 65 | @end 66 | @property( hlms_shadowcaster_point ) 67 | float3 toCameraWS : TEXCOORD@counter(texcoord); 68 | @property( !exponential_shadow_maps ) 69 | nointerpolation float constBias : TEXCOORD@counter(texcoord); 70 | @end 71 | @end 72 | @end 73 | @insertpiece( custom_VStoPS ) 74 | @end 75 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/Unlit/HLSL/VertexShader_vs.hlsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | @insertpiece( Common_Matrix_DeclUnpackMatrix4x4 ) 4 | 5 | // START UNIFORM DECLARATION 6 | @insertpiece( PassDecl ) 7 | @insertpiece( InstanceDecl ) 8 | Buffer worldMatBuf : register(t0); 9 | @property( texture_matrix )Buffer animationMatrixBuf : register(t1);@end 10 | @insertpiece( custom_vs_uniformDeclaration ) 11 | // END UNIFORM DECLARATION 12 | 13 | struct VS_INPUT 14 | { 15 | float4 vertex : POSITION; 16 | @property( hlms_colour ) float4 colour : COLOR0;@end 17 | @foreach( hlms_uv_count, n ) 18 | float@value( hlms_uv_count@n ) uv@n : TEXCOORD@n;@end 19 | uint drawId : DRAWID; 20 | @insertpiece( custom_vs_attributes ) 21 | }; 22 | 23 | struct PS_INPUT 24 | { 25 | @insertpiece( VStoPS_block ) 26 | float4 gl_Position : SV_Position; 27 | @property( hlms_global_clip_distances ) 28 | float gl_ClipDistance0 : SV_ClipDistance0; 29 | @end 30 | }; 31 | 32 | @property( !hlms_identity_world ) 33 | @piece( worldViewProj )worldViewProj@end 34 | @end @property( hlms_identity_world ) 35 | @property( !hlms_identity_viewproj_dynamic ) 36 | @piece( worldViewProj )passBuf.viewProj[@value(hlms_identity_viewproj)]@end 37 | @end @property( hlms_identity_viewproj_dynamic ) 38 | @piece( worldViewProj )passBuf.viewProj[worldMaterialIdx[input.drawId].z]@end 39 | @end 40 | @end 41 | 42 | PS_INPUT main( VS_INPUT input ) 43 | { 44 | PS_INPUT outVs; 45 | @insertpiece( custom_vs_preExecution ) 46 | 47 | @property( !hlms_identity_world ) 48 | float4x4 worldViewProj; 49 | worldViewProj = UNPACK_MAT4( worldMatBuf, input.drawId ); 50 | @end 51 | 52 | @property( !hlms_dual_paraboloid_mapping ) 53 | outVs.gl_Position = mul( input.vertex, @insertpiece( worldViewProj ) ); 54 | @end 55 | 56 | @property( hlms_dual_paraboloid_mapping ) 57 | //Dual Paraboloid Mapping 58 | outVs.gl_Position.w = 1.0f; 59 | outVs.gl_Position.xyz = mul( input.vertex, @insertpiece( worldViewProj ) ).xyz; 60 | float L = length( outVs.gl_Position.xyz ); 61 | outVs.gl_Position.z += 1.0f; 62 | outVs.gl_Position.xy /= outVs.gl_Position.z; 63 | outVs.gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane); 64 | @end 65 | 66 | @property( !hlms_shadowcaster ) 67 | @property( hlms_colour ) outVs.colour = input.colour;@end 68 | 69 | @property( texture_matrix ) float4x4 textureMatrix;@end 70 | 71 | @foreach( out_uv_count, n ) 72 | @property( out_uv@n_texture_matrix ) 73 | textureMatrix = UNPACK_MAT4( animationMatrixBuf, (worldMaterialIdx[input.drawId].x << 4u) + @value( out_uv@n_tex_unit ) ); 74 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = mul( float4( input.uv@value( out_uv@n_source_uv ).xy, 0, 1 ), textureMatrix ).xy; 75 | @end @property( !out_uv@n_texture_matrix ) 76 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = input.uv@value( out_uv@n_source_uv ).xy; 77 | @end @end 78 | 79 | outVs.drawId = input.drawId; 80 | 81 | @end 82 | 83 | @property( hlms_global_clip_distances || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point)) ) 84 | float3 worldPos = mul(outVs.gl_Position, passBuf.invViewProj).xyz; 85 | @end 86 | @insertpiece( DoShadowCasterVS ) 87 | 88 | @property( hlms_global_clip_distances ) 89 | outVs.gl_ClipDistance0 = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); 90 | @end 91 | 92 | @insertpiece( custom_vs_posExecution ) 93 | 94 | return outVs; 95 | } 96 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/UnlitMobile/GLSL/BlendModes_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @piece( NormalNonPremul ) 2 | //Normal Non Premultiplied @counter(t) 3 | outColour.xyz = mix( outColour.xyz, topImage@value(t).xyz, topImage@value(t).a ); 4 | @end 5 | 6 | @piece( NormalPremul ) 7 | //Normal Premultiplied @counter(t) 8 | outColour.xyz = (1.0 - topImage@value(t).a) * outColour.xyz + topImage@value(t).xyz; 9 | @end 10 | 11 | @piece( Add ) 12 | //Add @counter(t) 13 | outColour.xyz = mix( outColour.xyz, 14 | min( outColour.xyz + topImage@value(t).xyz, vec3(1.0) ), 15 | topImage@value(t).a ); 16 | @end 17 | 18 | @piece( Subtract ) 19 | //Subtract @counter(t) 20 | outColour.xyz = mix( outColour.xyz, 21 | max( outColour.xyz - topImage@value(t).xyz, vec3(0.0) ), 22 | topImage@value(t).a ); 23 | @end 24 | 25 | @piece( Multiply ) 26 | //Multiply @counter(t) 27 | outColour.xyz = mix( outColour.xyz, 28 | outColour.xyz * topImage@value(t).xyz, 29 | topImage@value(t).a ); 30 | @end 31 | 32 | @piece( Multiply2x ) 33 | //Multiply2x @counter(t) 34 | outColour.xyz = mix( outColour.xyz, 35 | min( outColour.xyz * topImage@value(t).xyz * 2.0, vec3(1.0) ), 36 | topImage@value(t).a ); 37 | @end 38 | 39 | @piece( Screen ) 40 | //Screen @counter(t) 41 | outColour.xyz = mix( outColour.xyz, 42 | 1.0 - (1.0 - outColour.xyz) * (1.0 - topImage@value(t).xyz), 43 | topImage@value(t).a ); 44 | @end 45 | 46 | @piece( Overlay ) 47 | //Overlay @counter(t) 48 | outColour.xyz = mix( outColour.xyz, 49 | outColour.xyz * ( outColour.xyz + 2.0 * topImage@value(t).xyz * (1.0 - outColour.xyz) ), 50 | topImage@value(t).a ); 51 | @end 52 | 53 | @piece( Lighten ) 54 | //Lighten @counter(t) 55 | outColour.xyz = mix( outColour.xyz, 56 | max( outColour.xyz, topImage@value(t).xyz ), 57 | topImage@value(t).a ); 58 | @end 59 | 60 | @piece( Darken ) 61 | //Darken @counter(t) 62 | outColour.xyz = mix( outColour.xyz, 63 | min( outColour.xyz, topImage@value(t).xyz ), 64 | topImage@value(t).a ); 65 | @end 66 | 67 | @piece( GrainExtract ) 68 | //GrainExtract @counter(t) 69 | outColour.xyz = mix( outColour.xyz, 70 | (outColour.xyz - topImage@value(t).xyz) + 0.5f, 71 | topImage@value(t).a ); 72 | @end 73 | 74 | @piece( GrainMerge ) 75 | //GrainMerge @counter(t) 76 | outColour.xyz = mix( outColour.xyz, 77 | (outColour.xyz + topImage@value(t).xyz) - 0.5f, 78 | topImage@value(t).a ); 79 | @end 80 | 81 | @piece( Difference ) 82 | //Difference @counter(t) 83 | outColour.xyz = mix( outColour.xyz, 84 | abs(outColour.xyz - topImage@value(t).xyz), 85 | topImage@value(t).a ); 86 | @end 87 | 88 | @foreach( 16, n ) 89 | @property( uv_atlas@n ) @piece( atlasOffset@n )* atlasOffsets[@n].z + atlasOffsets[@n].xy @end @end @end 90 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/UnlitMobile/GLSL/CrossPlatformSettings_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @piece( SetCrossPlatformSettings ) 2 | @property( GL3+ ) 3 | #version 330 4 | #define FRAG_COLOR 0 5 | layout(location = FRAG_COLOR, index = 0) out vec4 outColour; 6 | @piece( texture2D )texture@end 7 | @piece( textureCube )texture@end 8 | @piece( textureCubeLod )textureLod@end 9 | 10 | @piece( lowp )highp@end 11 | @piece( mediump )highp@end 12 | @end @property( !GL3+ ) 13 | #define in varying 14 | #define outColour gl_FragColor 15 | @property( hlms_high_quality ) 16 | @piece( lowp )highp@end 17 | @piece( mediump )highp@end 18 | precision highp float; 19 | @end @property( !hlms_high_quality ) 20 | @piece( lowp )lowp@end 21 | @piece( mediump )mediump@end 22 | precision mediump float; 23 | @end 24 | 25 | @piece( texture2D )texture2D@end 26 | @piece( textureCube )textureCube@end 27 | @piece( textureCubeLod )textureCube@end 28 | @end 29 | @end 30 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/UnlitMobile/GLSL/CrossPlatformSettings_piece_vs.glsl: -------------------------------------------------------------------------------- 1 | @piece( SetCrossPlatformSettings ) 2 | @property( GL3+ ) 3 | #version 330 4 | @end @property( !GL3+ ) 5 | #define in attribute 6 | #define out varying 7 | @end 8 | @end 9 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/UnlitMobile/GLSL/PixelShader_ps.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | @property( hlms_colour )in @insertpiece( lowp ) vec4 psColour;@end 4 | 5 | @foreach( hlms_uv_count, n ) 6 | in @insertpiece( mediump ) vec@value( hlms_uv_count@n ) psUv@n;@end 7 | 8 | // START UNIFORM DECLARATION 9 | //Uniforms that change per material 10 | @property( diffuse )uniform @insertpiece( mediump ) vec4 diffuseColour;@end 11 | @property( alpha_test )uniform @insertpiece( lowp ) float alpha_test_threshold;@end 12 | @property( uv_atlas )uniform @insertpiece( mediump ) vec3 atlasOffsets[@value( uv_atlas )];@end 13 | // END UNIFORM DECLARATION 14 | 15 | @property( diffuse_map )uniform @insertpiece( lowp ) sampler2D texDiffuseMap[@value( diffuse_map )];@end 16 | 17 | @property( diffuse )@piece( MultiplyDiffuseConst )* diffuseColour@end @end 18 | 19 | void main() 20 | { 21 | @property( !diffuse_map ) 22 | @property( hlms_colour ) outColour = psColour @insertpiece( MultiplyDiffuseConst );@end 23 | @property( !hlms_colour && !diffuse ) outColour = @insertpiece( lowp ) vec4(1, 1, 1, 1);@end 24 | @property( !hlms_colour && diffuse ) outColour = diffuseColour;@end 25 | @end 26 | 27 | @property( diffuse_map ) 28 | //Load base image 29 | outColour = texture( texDiffuseMap[0], psUv@value( diffuse_map_count0 ) @insertpiece( atlasOffset0 )); 30 | 31 | //Group all texture loads together to help the GPU hide the 32 | //latency (bad GL ES2 drivers won't optimize this automatically) 33 | @foreach( diffuse_map, n, 1 ) 34 | @insertpiece( lowp ) vec4 topImage@n = texture( texDiffuseMap[@n], psUv@value( diffuse_map_count@n ) @insertpiece( atlasOffset@n ));@end 35 | 36 | @foreach( diffuse_map, n, 1 ) 37 | @insertpiece( blend_mode_idx@n )@end 38 | 39 | @property( hlms_colour )outColour *= psColour @insertpiece( MultiplyDiffuseConst );@end 40 | @property( !hlms_colour && diffuse )outColour *= diffuseColour;@end 41 | @end 42 | 43 | @property( alpha_test ) 44 | if( alpha_test_threshold @insertpiece( alpha_test_cmp_func ) outColour.a ) 45 | discard;@end 46 | } 47 | -------------------------------------------------------------------------------- /testMedia/HLMS/Hlms/UnlitMobile/GLSL/VertexShader_vs.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | in vec4 vertex; 4 | @property( hlms_colour )in vec4 colour; 5 | out vec4 psColour;@end 6 | 7 | @foreach( hlms_uv_count, n ) 8 | in vec@value( hlms_uv_count@n ) uv@n;@end 9 | @foreach( hlms_uv_count, n ) 10 | out vec@value( hlms_uv_count@n ) psUv@n;@end 11 | 12 | // START UNIFORM DECLARATION 13 | //Uniforms that change per material 14 | @property( hlms_texture_matrix_count )uniform mat4 texture_matrix[@value( hlms_texture_matrix_count )];@end 15 | //Uniforms that change per entity 16 | uniform mat4 worldViewProj; 17 | // END UNIFORM DECLARATION 18 | 19 | void main() 20 | { 21 | @property( !hlms_dual_paraboloid_mapping ) 22 | gl_Position = worldViewProj * vertex; 23 | @end 24 | 25 | @property( hlms_dual_paraboloid_mapping ) 26 | //Dual Paraboloid Mapping 27 | gl_Position.w = 1.0f; 28 | gl_Position.xyz = (worldViewProj * vertex).xyz; 29 | float L = length( gl_Position.xyz ); 30 | gl_Position.z += 1.0f; 31 | gl_Position.xy /= gl_Position.z; 32 | gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane); 33 | @end 34 | 35 | @property( hlms_colour ) psColour = colour;@end 36 | 37 | @foreach( hlms_uv_count, n ) 38 | psUv@n = uv@n @property( hlms_texture_matrix_count@n ) * texture_matrix[@counter(CurrentTexMatrix)]@end ;@end 39 | } 40 | -------------------------------------------------------------------------------- /testMedia/Suzanne.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ybalrid/Qt5Ogre21/68d48f3c155b5e71c86ba869e43e1b28a8801f7e/testMedia/Suzanne.mesh -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/Any/Cubemap_piece_all.any: -------------------------------------------------------------------------------- 1 | 2 | //#include "SyntaxHighlightingMisc.h" 3 | @property( parallax_correct_cubemaps ) 4 | 5 | @piece( DeclCubemapProbeStruct ) 6 | struct CubemapProbe 7 | { 8 | float4 row0_centerX; 9 | float4 row1_centerY; 10 | float4 row2_centerZ; 11 | float4 halfSize; 12 | float4 cubemapPosLS; 13 | }; 14 | @end 15 | 16 | @piece( DeclParallaxLocalCorrect ) 17 | /** Parallax Correct a reflection dir based on an OBB (Oriented Bounding Box) from a cubemap probe. 18 | \param reflDir 19 | Reflection dir, in view space. 20 | \param pos 21 | Position of the object where the reflection is going to reflect, in local space. 22 | Use toProbeLocalSpace to conver to LS. 23 | \param probe 24 | Cubemap's probe 25 | \return 26 | Parallax-Corrected reflection dir, IN LOCAL SPACE (local to probe's). 27 | Unlike the inputs, this vector is LEFT HANDED. 28 | */ 29 | @property( syntax == metal )inline @end float3 localCorrect( float3 reflDir, float3 posLS, 30 | CubemapProbe probe ) 31 | { 32 | float3 probeShapeHalfSize = probe.halfSize.xyz; 33 | float3x3 viewSpaceToProbeLocal = float3x3( probe.row0_centerX.xyz, 34 | probe.row1_centerY.xyz, 35 | probe.row2_centerZ.xyz ); 36 | 37 | @property( syntax == hlsl ) 38 | float3 reflDirLS = mul( viewSpaceToProbeLocal, reflDir ); 39 | @end @property( syntax != hlsl ) 40 | float3 reflDirLS = reflDir * viewSpaceToProbeLocal; 41 | @end 42 | 43 | //Find the ray intersection with box plane 44 | float3 invReflDirLS = float3( 1.0, 1.0, 1.0 ) / reflDirLS; 45 | float3 intersectAtMinPlane = ( -probeShapeHalfSize - posLS ) * invReflDirLS; 46 | float3 intersectAtMaxPlane = ( probeShapeHalfSize - posLS ) * invReflDirLS; 47 | //Get the largest intersection values (we are not intersted in negative values) 48 | float3 largestIntersect = max( intersectAtMaxPlane.xyz, intersectAtMinPlane.xyz ); 49 | //Get the closest of all solutions 50 | float distance = min( min( largestIntersect.x, largestIntersect.y ), largestIntersect.z ); 51 | //Get the intersection position 52 | float3 intersectPositionLS = posLS.xyz + reflDirLS.xyz * distance; 53 | //Get corrected vector 54 | float3 localCorrectedVec = intersectPositionLS.xyz - probe.cubemapPosLS.xyz; 55 | 56 | //Make it left-handed. 57 | localCorrectedVec.z = -localCorrectedVec.z; 58 | return localCorrectedVec; 59 | } 60 | /** Converts a position from view space to probe's local space. 61 | \param pos 62 | Position of the object where the reflection is going to reflect, in view space 63 | \return 64 | Position in local space. 65 | */ 66 | @property( syntax == metal )inline @end float3 toProbeLocalSpace( float3 pos, CubemapProbe probe ) 67 | { 68 | float3 probeShapeCenterVS = float3( probe.row0_centerX.w, 69 | probe.row1_centerY.w, 70 | probe.row2_centerZ.w ); 71 | 72 | float3x3 viewSpaceToProbeLocal = float3x3( probe.row0_centerX.xyz, 73 | probe.row1_centerY.xyz, 74 | probe.row2_centerZ.xyz ); 75 | float3 posLS = pos - probeShapeCenterVS; 76 | 77 | @property( syntax == hlsl ) 78 | posLS = mul( viewSpaceToProbeLocal, posLS ); 79 | @end @property( syntax != hlsl ) 80 | posLS = posLS * viewSpaceToProbeLocal; 81 | @end 82 | 83 | return posLS; 84 | } 85 | 86 | /// Returns true if position (in local space) is inside the probe. False otherwise 87 | @property( syntax == metal )inline @end bool isInsideProbe( float3 posLS, CubemapProbe probe ) 88 | { 89 | return !( abs( posLS.x ) > probe.halfSize.x || 90 | abs( posLS.y ) > probe.halfSize.y || 91 | abs( posLS.z ) > probe.halfSize.z ); 92 | } 93 | 94 | /// Returns value in range (-inf; 1]. 95 | /// 1 means being at the center of the probe. 96 | /// 0 means being at the edge of the probe 97 | /// <0 means position is outside the probe. 98 | @property( syntax == metal )inline @end float getProbeFade( float3 posLS, CubemapProbe probe ) 99 | { 100 | float3 vDiff = ( probe.halfSize.xyz - abs( posLS.xyz ) ) / probe.halfSize.xyz; 101 | return min( min( vDiff.x, vDiff.y ), vDiff.z ); 102 | } 103 | @end 104 | 105 | //float3 main( float3 reflDir : TEXCOORD0, float3 pos : TEXCOORD1 ) : SV_Target0 106 | //{ 107 | // return localCorrect( reflDir, pos, probe ); 108 | //} 109 | @end 110 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/GLSL/RenderDepthOnly_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @property( hlms_render_depth_only && !alpha_test && !hlms_shadows_esm ) 2 | @set( hlms_disable_stage, 1 ) 3 | @end 4 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/HLSL/RenderDepthOnly_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | 2 | @property( !hlms_render_depth_only || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point)) ) 3 | @piece( output_type )PS_OUTPUT@end 4 | @end @property( !(!hlms_render_depth_only || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point))) ) 5 | @piece( output_type )void@end 6 | @end 7 | 8 | @property( hlms_render_depth_only && !alpha_test && !hlms_shadows_esm ) 9 | @set( hlms_disable_stage, 1 ) 10 | @end 11 | 12 | @piece( DeclOutputType ) 13 | struct PS_OUTPUT 14 | { 15 | @property( !hlms_shadowcaster ) 16 | float4 colour0 : SV_Target0; 17 | @end @property( hlms_shadowcaster ) 18 | @property( !hlms_render_depth_only ) 19 | float colour0 : SV_Target0; 20 | @end 21 | @property( hlms_render_depth_only ) 22 | float colour0 : SV_Depth; 23 | @end 24 | @end 25 | }; 26 | @end 27 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/Metal/CrossPlatformSettings_piece_all.metal: -------------------------------------------------------------------------------- 1 | @piece( SetCrossPlatformSettings ) 2 | #include 3 | using namespace metal; 4 | 5 | struct float1 6 | { 7 | float x; 8 | float1() {} 9 | float1( float _x ) : x( _x ) {} 10 | }; 11 | 12 | #define mul( x, y ) ((x) * (y)) 13 | #define lerp mix 14 | #define INLINE inline 15 | 16 | #define outVs_Position outVs.gl_Position 17 | #define OGRE_SampleLevel( tex, sampler, uv, lod ) tex.sample( sampler, float2( uv ), level( lod ) ) 18 | @end 19 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/Metal/Matrix_piece_all.metal: -------------------------------------------------------------------------------- 1 | @piece( Common_Matrix_DeclUnpackMatrix4x4 ) 2 | inline float4x4 UNPACK_MAT4( device const float4 *matrixBuf, uint pixelIdx ) 3 | { 4 | float4 row0 = matrixBuf[(pixelIdx << 2u)]; 5 | float4 row1 = matrixBuf[(pixelIdx << 2u) + 1u]; 6 | float4 row2 = matrixBuf[(pixelIdx << 2u) + 2u]; 7 | float4 row3 = matrixBuf[(pixelIdx << 2u) + 3u]; 8 | return float4x4( row0, row1, row2, row3 ); 9 | } 10 | @end 11 | 12 | @piece( Common_Matrix_DeclUnpackMatrix3x4 ) 13 | inline float3x4 UNPACK_MAT3x4( device const float4 *matrixBuf, uint pixelIdx ) 14 | { 15 | float4 row0 = matrixBuf[(pixelIdx << 2u)]; 16 | float4 row1 = matrixBuf[(pixelIdx << 2u) + 1u]; 17 | float4 row2 = matrixBuf[(pixelIdx << 2u) + 2u]; 18 | return float3x4( row0, row1, row2 ); 19 | } 20 | @end 21 | 22 | @piece( Common_Matrix_Conversions ) 23 | inline float3x3 toMat3x3( float4x4 m ) 24 | { 25 | return float3x3( m[0].xyz, m[1].xyz, m[2].xyz ); 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/Metal/QuaternionCode_piece_all.metal: -------------------------------------------------------------------------------- 1 | @piece( DeclQuat_xAxis ) 2 | inline float3 xAxis( float4 qQuat ) 3 | { 4 | float fTy = 2.0 * qQuat.y; 5 | float fTz = 2.0 * qQuat.z; 6 | float fTwy = fTy * qQuat.w; 7 | float fTwz = fTz * qQuat.w; 8 | float fTxy = fTy * qQuat.x; 9 | float fTxz = fTz * qQuat.x; 10 | float fTyy = fTy * qQuat.y; 11 | float fTzz = fTz * qQuat.z; 12 | 13 | return float3( 1.0-(fTyy+fTzz), fTxy+fTwz, fTxz-fTwy ); 14 | } 15 | @end 16 | 17 | @piece( DeclQuat_yAxis ) 18 | inline float3 yAxis( float4 qQuat ) 19 | { 20 | float fTx = 2.0 * qQuat.x; 21 | float fTy = 2.0 * qQuat.y; 22 | float fTz = 2.0 * qQuat.z; 23 | float fTwx = fTx * qQuat.w; 24 | float fTwz = fTz * qQuat.w; 25 | float fTxx = fTx * qQuat.x; 26 | float fTxy = fTy * qQuat.x; 27 | float fTyz = fTz * qQuat.y; 28 | float fTzz = fTz * qQuat.z; 29 | 30 | return float3( fTxy-fTwz, 1.0-(fTxx+fTzz), fTyz+fTwx ); 31 | } 32 | @end 33 | 34 | @piece( DeclQuat_zAxis ) 35 | inline float3 zAxis( float4 qQuat ) 36 | { 37 | float fTx = 2.0 * qQuat.x; 38 | float fTy = 2.0 * qQuat.y; 39 | float fTz = 2.0 * qQuat.z; 40 | float fTwx = fTx * qQuat.w; 41 | float fTwy = fTy * qQuat.w; 42 | float fTxx = fTx * qQuat.x; 43 | float fTxz = fTz * qQuat.x; 44 | float fTyy = fTy * qQuat.y; 45 | float fTyz = fTz * qQuat.y; 46 | 47 | return float3( fTxz+fTwy, fTyz-fTwx, 1.0-(fTxx+fTyy) ); 48 | } 49 | @end 50 | 51 | @piece( DeclQuat_AllAxis ) 52 | @insertpiece( DeclQuat_xAxis ) 53 | @insertpiece( DeclQuat_yAxis ) 54 | @insertpiece( DeclQuat_zAxis ) 55 | @end 56 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Common/Metal/RenderDepthOnly_piece_ps.metal: -------------------------------------------------------------------------------- 1 | 2 | @property( !hlms_render_depth_only || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point)) ) 3 | @piece( output_type )PS_OUTPUT@end 4 | @end @property( !(!hlms_render_depth_only || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point))) ) 5 | @piece( output_type )void@end 6 | @end 7 | 8 | @property( hlms_render_depth_only && !alpha_test && !hlms_shadows_esm ) 9 | @set( hlms_disable_stage, 1 ) 10 | @end 11 | 12 | @piece( DeclOutputType ) 13 | struct PS_OUTPUT 14 | { 15 | @property( !hlms_shadowcaster ) 16 | float4 colour0 [[ color(0) ]]; 17 | @end @property( hlms_shadowcaster ) 18 | @property( !hlms_render_depth_only ) 19 | float colour0 [[ color(0) ]]; 20 | @end 21 | @property( hlms_render_depth_only ) 22 | float colour0 [[ depth(any) ]]; 23 | @end 24 | @end 25 | }; 26 | @end 27 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/GLSL/IrradianceVolume_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @property( irradiance_volumes ) 2 | @piece( applyIrradianceVolumes ) 3 | vec3 worldNormal = nNormal.xyz * mat3(passBuf.invView); 4 | vec3 worldPos = (vec4( inPs.pos.xyz, 1.0 ) * passBuf.invView).xyz; 5 | 6 | vec3 irradiancePos = worldPos.xyz * passBuf.irradianceSize.xyz - passBuf.irradianceOrigin.xyz; 7 | //Floor irradiancePos.y and put the fractional part so we can lerp. 8 | irradiancePos.y -= 0.5f; //Texel centers are at center. Move it to origin. 9 | float origYPos; 10 | float fIrradianceYWeight = modf( irradiancePos.y, origYPos ); 11 | origYPos *= 6.0; 12 | origYPos += 0.5f; //Make sure we sample at center (so HW doesn't do linear 13 | //filtering on the Y axis. We'll do that manually) 14 | 15 | vec3 isNegative = vec3( lessThan( worldNormal.xyz, vec3( 0, 0, 0 ) ) ); 16 | 17 | vec3 tmpAmbientSample; 18 | 19 | //We need to make 3 samples (actually 6), one for each axis. 20 | /* The code is basically doing: 21 | vec3 cAmbientCube[6]; 22 | int3 isNegative = ( worldNormal < 0.0 ); 23 | float3 linearColor; 24 | linearColor = worldNormalSq.x * cAmbientCube[isNegative.x] + 25 | worldNormalSq.y * cAmbientCube[isNegative.y+2] + 26 | worldNormalSq.z * cAmbientCube[isNegative.z+4]; 27 | 28 | We have 6 colour values per voxel. But GPUs can only store 1 colour value per cell. 29 | So we 6x the height to workaround that limitation. This also means we loose the ability 30 | to do HW bilinear filtering around the Y axis; therefore we do it ourselves manually. 31 | Because of this, instead of doing 3 samples, we end up doing 6 (in order to perform 32 | filtering around the Y axis) 33 | **/ 34 | 35 | float irradianceTexInvHeight = passBuf.irradianceSize.w; 36 | 37 | irradiancePos.y = (origYPos + isNegative.x) * irradianceTexInvHeight; 38 | vec3 xAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 39 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 40 | tmpAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 41 | 42 | xAmbientSample = mix( xAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 43 | 44 | irradiancePos.y = (origYPos + (2.0f + isNegative.y)) * irradianceTexInvHeight; 45 | vec3 yAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 46 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 47 | tmpAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 48 | 49 | yAmbientSample = mix( yAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 50 | 51 | irradiancePos.y = (origYPos + (4.0f + isNegative.z)) * irradianceTexInvHeight; 52 | vec3 zAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 53 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 54 | tmpAmbientSample = texture( irradianceVolume, irradiancePos ).xyz; 55 | 56 | zAmbientSample = mix( zAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 57 | 58 | 59 | vec3 worldNormalSq = worldNormal.xyz * worldNormal.xyz; 60 | vec3 ambientTerm = worldNormalSq.x * xAmbientSample.xyz + 61 | worldNormalSq.y * yAmbientSample.xyz + 62 | worldNormalSq.z * zAmbientSample.xyz; 63 | ambientTerm *= passBuf.irradianceOrigin.w; //irradianceOrigin.w = irradianceMaxPower 64 | 65 | finalColour.xyz += ambientTerm.xyz * @insertpiece( kD ).xyz; 66 | @end 67 | @end 68 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/HLSL/IrradianceVolume_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | @property( irradiance_volumes ) 2 | @piece( applyIrradianceVolumes ) 3 | float3 worldNormal = mul( nNormal.xyz, (float3x3)passBuf.invView ); 4 | float3 worldPos = mul( float4( inPs.pos.xyz, 1.0 ), passBuf.invView ).xyz; 5 | 6 | float3 irradiancePos = worldPos.xyz * passBuf.irradianceSize.xyz - passBuf.irradianceOrigin.xyz; 7 | //Floor irradiancePos.y and put the fractional part so we can lerp. 8 | irradiancePos.y -= 0.5f; //Texel centers are at center. Move it to origin. 9 | float origYPos; 10 | float fIrradianceYWeight = modf( irradiancePos.y, origYPos ); 11 | origYPos *= 6.0; 12 | origYPos += 0.5f; //Make sure we sample at center (so HW doesn't do linear 13 | //filtering on the Y axis. We'll do that manually) 14 | 15 | float3 isNegative = float3( worldNormal.xyz < float3( 0, 0, 0 ) ); 16 | 17 | float3 tmpAmbientSample; 18 | 19 | //We need to make 3 samples (actually 6), one for each axis. 20 | /* The code is basically doing: 21 | float3 cAmbientCube[6]; 22 | int3 isNegative = ( worldNormal < 0.0 ); 23 | float3 linearColor; 24 | linearColor = worldNormalSq.x * cAmbientCube[isNegative.x] + 25 | worldNormalSq.y * cAmbientCube[isNegative.y+2] + 26 | worldNormalSq.z * cAmbientCube[isNegative.z+4]; 27 | 28 | We have 6 colour values per voxel. But GPUs can only store 1 colour value per cell. 29 | So we 6x the height to workaround that limitation. This also means we loose the ability 30 | to do HW bilinear filtering around the Y axis; therefore we do it ourselves manually. 31 | Because of this, instead of doing 3 samples, we end up doing 6 (in order to perform 32 | filtering around the Y axis) 33 | **/ 34 | 35 | float irradianceTexInvHeight = passBuf.irradianceSize.w; 36 | 37 | irradiancePos.y = (origYPos + isNegative.x) * irradianceTexInvHeight; 38 | float3 xAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 39 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 40 | tmpAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 41 | 42 | xAmbientSample = lerp( xAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 43 | 44 | irradiancePos.y = (origYPos + (2.0f + isNegative.y)) * irradianceTexInvHeight; 45 | float3 yAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 46 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 47 | tmpAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 48 | 49 | yAmbientSample = lerp( yAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 50 | 51 | irradiancePos.y = (origYPos + (4.0f + isNegative.z)) * irradianceTexInvHeight; 52 | float3 zAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 53 | irradiancePos.y += 6.0f * irradianceTexInvHeight; 54 | tmpAmbientSample = irradianceVolume.Sample( irradianceVolumeSampler, irradiancePos ).xyz; 55 | 56 | zAmbientSample = lerp( zAmbientSample, tmpAmbientSample, fIrradianceYWeight ); 57 | 58 | 59 | float3 worldNormalSq = worldNormal.xyz * worldNormal.xyz; 60 | float3 ambientTerm = worldNormalSq.x * xAmbientSample.xyz + 61 | worldNormalSq.y * yAmbientSample.xyz + 62 | worldNormalSq.z * zAmbientSample.xyz; 63 | ambientTerm *= passBuf.irradianceOrigin.w; //irradianceOrigin.w = irradianceMaxPower 64 | 65 | finalColour.xyz += ambientTerm.xyz * @insertpiece( kD ).xyz; 66 | @end 67 | @end 68 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/Metal/BlendModes_piece_ps.metal: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @property( !hlms_shadowcaster ) 5 | @piece( NormalNonPremul ) 6 | //Normal Non Premultiplied @value(t) 7 | diffuseCol.xyz = mix( diffuseCol.xyz, detailCol@value(t).xyz, detailCol@value(t).a ); 8 | diffuseCol.w = mix( diffuseCol.w, 1.0, detailCol@value(t).w ); 9 | @end 10 | 11 | @piece( NormalPremul ) 12 | //Normal Premultiplied @value(t) 13 | diffuseCol.xyz = (1.0 - detailCol@value(t).a) * diffuseCol.xyz + detailCol@value(t).xyz; 14 | diffuseCol.w = mix( diffuseCol.w, 1.0, detailCol@value(t).w ); 15 | @end 16 | 17 | @piece( Add ) 18 | //Add @value(t) 19 | diffuseCol.xyz = mix( diffuseCol.xyz, 20 | min( diffuseCol.xyz + detailCol@value(t).xyz, float3(1.0, 1.0, 1.0) ), 21 | detailCol@value(t).a ); 22 | @end 23 | 24 | @piece( Subtract ) 25 | //Subtract @value(t) 26 | diffuseCol.xyz = mix( diffuseCol.xyz, 27 | max( diffuseCol.xyz - detailCol@value(t).xyz, float3(0.0, 0.0, 0.0) ), 28 | detailCol@value(t).a ); 29 | @end 30 | 31 | @piece( Multiply ) 32 | //Multiply @value(t) 33 | diffuseCol.xyz = mix( diffuseCol.xyz, 34 | diffuseCol.xyz * detailCol@value(t).xyz, 35 | detailCol@value(t).a ); 36 | @end 37 | 38 | @piece( Multiply2x ) 39 | //Multiply2x @value(t) 40 | diffuseCol.xyz = mix( diffuseCol.xyz, 41 | min( diffuseCol.xyz * detailCol@value(t).xyz * 2.0, float3(1.0, 1.0, 1.0) ), 42 | detailCol@value(t).a ); 43 | @end 44 | 45 | @piece( Screen ) 46 | //Screen @value(t) 47 | diffuseCol.xyz = mix( diffuseCol.xyz, 48 | 1.0 - (1.0 - diffuseCol.xyz) * (1.0 - detailCol@value(t).xyz), 49 | detailCol@value(t).a ); 50 | @end 51 | 52 | @piece( Overlay ) 53 | //Overlay @value(t) 54 | diffuseCol.xyz = mix( diffuseCol.xyz, 55 | diffuseCol.xyz * ( diffuseCol.xyz + 2.0 * detailCol@value(t).xyz * (1.0 - diffuseCol.xyz) ), 56 | detailCol@value(t).a ); 57 | @end 58 | 59 | @piece( Lighten ) 60 | //Lighten @value(t) 61 | diffuseCol.xyz = mix( diffuseCol.xyz, 62 | max( diffuseCol.xyz, detailCol@value(t).xyz ), 63 | detailCol@value(t).a ); 64 | @end 65 | 66 | @piece( Darken ) 67 | //Darken @value(t) 68 | diffuseCol.xyz = mix( diffuseCol.xyz, 69 | min( diffuseCol.xyz, detailCol@value(t).xyz ), 70 | detailCol@value(t).a ); 71 | @end 72 | 73 | @piece( GrainExtract ) 74 | //GrainExtract @value(t) 75 | diffuseCol.xyz = mix( diffuseCol.xyz, 76 | (diffuseCol.xyz - detailCol@value(t).xyz) + 0.5f, 77 | detailCol@value(t).a ); 78 | @end 79 | 80 | @piece( GrainMerge ) 81 | //GrainMerge @value(t) 82 | diffuseCol.xyz = mix( diffuseCol.xyz, 83 | (diffuseCol.xyz + detailCol@value(t).xyz) - 0.5f, 84 | detailCol@value(t).a ); 85 | @end 86 | 87 | @piece( Difference ) 88 | //Difference @value(t) 89 | diffuseCol.xyz = mix( diffuseCol.xyz, 90 | abs(diffuseCol.xyz - detailCol@value(t).xyz), 91 | detailCol@value(t).a ); 92 | @end 93 | @end @property( hlms_shadowcaster ) 94 | 95 | @piece( NormalNonPremul ) 96 | //Normal Non Premultiplied @value(t) 97 | diffuseCol = mix( diffuseCol, 1.0, detailCol@value(t) ); 98 | @end 99 | 100 | @piece( NormalPremul ) 101 | //Normal Premultiplied @value(t) 102 | diffuseCol = mix( diffuseCol, 1.0, detailCol@value(t) ); 103 | @end 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/Metal/DetailMaps_piece_ps.metal: -------------------------------------------------------------------------------- 1 | // detail_maps_diffuse & detail_maps_normal are either 0 or 4 2 | 3 | @foreach( detail_maps_diffuse, n ) 4 | @property( detail_offsetsD@n ) 5 | @piece( offsetDetailD@n ) * material.detailOffsetScaleD[@value(currOffsetDetailD)].zw + material.detailOffsetScaleD[@counter(currOffsetDetailD)].xy@end 6 | @end 7 | @end 8 | @foreach( detail_maps_normal, n ) 9 | @property( detail_offsetsN@n ) 10 | @piece( offsetDetailN@n ) * material.detailOffsetScaleN[@value(currOffsetDetailN)].zw + material.detailOffsetScaleN[@counter(currOffsetDetailN)].xy@end 11 | @end 12 | @end 13 | 14 | @piece( detail_swizzle0 )x@end; 15 | @piece( detail_swizzle1 )y@end; 16 | @piece( detail_swizzle2 )z@end; 17 | @piece( detail_swizzle3 )w@end; 18 | 19 | /* 20 | Down below we perform: 21 | if( detail_maps_normal ) 22 | second_valid_detail_map_nm = first_valid_detail_map_nm + 1; 23 | else 24 | second_valid_detail_map_nm = 0; 25 | */ 26 | @property( detail_maps_normal ) 27 | @add( second_valid_detail_map_nm, first_valid_detail_map_nm, 1 ) 28 | @end @property( !detail_maps_normal ) 29 | @set( second_valid_detail_map_nm, 0 ) 30 | @end 31 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/Metal/Forward3D_piece_ps.metal: -------------------------------------------------------------------------------- 1 | @property( hlms_forwardplus ) 2 | @property( hlms_forwardplus_fine_light_mask ) 3 | @piece( andObjLightMaskFwdPlusCmp )&& ((inPs.objLightMask & as_type( lightDiffuse.w )) != 0u)@end 4 | @end 5 | @piece( forward3dLighting ) 6 | @property( hlms_forwardplus == forward3d ) 7 | float f3dMinDistance = passBuf.f3dData.x; 8 | float f3dInvMaxDistance = passBuf.f3dData.y; 9 | float f3dNumSlicesSub1 = passBuf.f3dData.z; 10 | uint cellsPerTableOnGrid0= as_type( passBuf.f3dData.w ); 11 | 12 | // See C++'s Forward3D::getSliceAtDepth 13 | /*float fSlice = 1.0 - clamp( (-inPs.pos.z + f3dMinDistance) * f3dInvMaxDistance, 0.0, 1.0 ); 14 | fSlice = (fSlice * fSlice) * (fSlice * fSlice); 15 | fSlice = (fSlice * fSlice); 16 | fSlice = floor( (1.0 - fSlice) * f3dNumSlicesSub1 );*/ 17 | float fSlice = clamp( (-inPs.pos.z + f3dMinDistance) * f3dInvMaxDistance, 0.0, 1.0 ); 18 | fSlice = floor( fSlice * f3dNumSlicesSub1 ); 19 | uint slice = uint( fSlice ); 20 | 21 | //TODO: Profile performance: derive this mathematically or use a lookup table? 22 | uint offset = cellsPerTableOnGrid0 * (((1u << (slice << 1u)) - 1u) / 3u); 23 | 24 | float lightsPerCell = passBuf.f3dGridHWW[0].w; 25 | float windowHeight = passBuf.f3dGridHWW[1].w; //renderTarget->height 26 | 27 | //passBuf.f3dGridHWW[slice].x = grid_width / renderTarget->width; 28 | //passBuf.f3dGridHWW[slice].y = grid_height / renderTarget->height; 29 | //passBuf.f3dGridHWW[slice].z = grid_width * lightsPerCell; 30 | //uint sampleOffset = 0; 31 | uint sampleOffset = offset + 32 | uint(floor( (windowHeight - inPs.gl_FragCoord.y) * passBuf.f3dGridHWW[slice].y ) * passBuf.f3dGridHWW[slice].z) + 33 | uint(floor( inPs.gl_FragCoord.x * passBuf.f3dGridHWW[slice].x ) * lightsPerCell); 34 | @end @property( hlms_forwardplus != forward3d ) 35 | float f3dMinDistance = passBuf.f3dData.x; 36 | float f3dInvExponentK = passBuf.f3dData.y; 37 | float f3dNumSlicesSub1 = passBuf.f3dData.z; 38 | 39 | // See C++'s ForwardClustered::getSliceAtDepth 40 | float fSlice = log2( max( -inPs.pos.z - f3dMinDistance, 1.0 ) ) * f3dInvExponentK; 41 | fSlice = floor( min( fSlice, f3dNumSlicesSub1 ) ); 42 | uint sliceSkip = uint( fSlice * @value( fwd_clustered_width_x_height ) ); 43 | 44 | uint sampleOffset = sliceSkip + 45 | uint(floor( inPs.gl_FragCoord.x * passBuf.fwdScreenToGrid.x )); 46 | float windowHeight = passBuf.f3dData.w; //renderTarget->height 47 | sampleOffset += uint(floor( (windowHeight - inPs.gl_FragCoord.y) * passBuf.fwdScreenToGrid.y ) * 48 | @value( fwd_clustered_width )); 49 | 50 | sampleOffset *= @value( fwd_clustered_lights_per_cell )u; 51 | @end 52 | 53 | ushort numLightsInGrid = f3dGrid[int(sampleOffset)]; 54 | 55 | @property( hlms_forwardplus_debug )uint totalNumLightsInGrid = numLightsInGrid;@end 56 | 57 | for( ushort i=0u; i= spotParams.y ) 137 | { 138 | float3 tmpColour = BRDF( lightDir, viewDir, NdotV, lightDiffuse.xyz, lightSpecular, 139 | material, nNormal @insertpiece( brdfExtraParams ) ); 140 | finalColour += tmpColour * atten; 141 | } 142 | } 143 | } 144 | 145 | @property( hlms_enable_vpls ) 146 | prevLightCount = numLightsInGrid; 147 | numLightsInGrid = f3dGrid[int(sampleOffset + 2u)]; 148 | 149 | @property( hlms_forwardplus_debug )totalNumLightsInGrid += numLightsInGrid;@end 150 | 151 | for( ushort i=prevLightCount; i 1 || 66 | irradiancePos.z < 0 || irradiancePos.z > 1 || 67 | irradiancePos.y <= (6.0f * irradianceTexInvHeight) || irradiancePos.y >= 1 ) 68 | { 69 | //Metal does not support border colour addressing mode. 70 | ambientTerm = float3( 0 ); 71 | } 72 | 73 | finalColour.xyz += ambientTerm.xyz * @insertpiece( kD ).xyz; 74 | @end 75 | @end 76 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/Metal/Structs_piece_vs_piece_ps.metal: -------------------------------------------------------------------------------- 1 | @piece( PassStructDecl ) 2 | struct ShadowReceiverData 3 | { 4 | float4x4 texViewProj; 5 | @property( exponential_shadow_maps ) 6 | float4 texViewZRow; 7 | @end 8 | float2 shadowDepthRange; 9 | float2 padding; 10 | float4 invShadowMapSize; 11 | }; 12 | 13 | struct Light 14 | { 15 | float4 position; //.w contains the objLightMask 16 | float3 diffuse; 17 | float3 specular; 18 | @property( hlms_num_shadow_map_lights ) 19 | float3 attenuation; 20 | float3 spotDirection; 21 | float3 spotParams; 22 | @end 23 | }; 24 | 25 | @insertpiece( DeclCubemapProbeStruct ) 26 | 27 | //Uniforms that change per pass 28 | struct PassData 29 | { 30 | //Vertex shader (common to both receiver and casters) 31 | float4x4 viewProj; 32 | 33 | @property( hlms_global_clip_distances ) 34 | float4 clipPlane0; 35 | @end 36 | 37 | @property( hlms_shadowcaster_point ) 38 | float4 cameraPosWS; //Camera position in world space 39 | @end 40 | 41 | @property( !hlms_shadowcaster ) 42 | //Vertex shader 43 | float4x4 view; 44 | @property( hlms_num_shadow_map_lights )ShadowReceiverData shadowRcv[@value(hlms_num_shadow_map_lights)];@end 45 | 46 | //------------------------------------------------------------------------- 47 | 48 | //Pixel shader 49 | float3x3 invViewMatCubemap; 50 | 51 | @property( hlms_use_prepass ) 52 | float4 windowHeight; 53 | @end 54 | 55 | @property( ambient_hemisphere || ambient_fixed || envmap_scale ) 56 | float4 ambientUpperHemi; 57 | @end 58 | @property( ambient_hemisphere ) 59 | float4 ambientLowerHemi; 60 | float4 ambientHemisphereDir; 61 | @end 62 | @property( irradiance_volumes ) 63 | float4 irradianceOrigin; //.w = maxPower 64 | float4 irradianceSize; //.w = 1.0f / irradianceTexture->getHeight() 65 | float4x4 invView; 66 | @end 67 | @property( hlms_pssm_splits )@foreach( hlms_pssm_splits, n ) 68 | float pssmSplitPoints@n;@end @end 69 | @property( hlms_lights_spot )Light lights[@value(hlms_lights_spot)];@end 70 | @end @property( hlms_shadowcaster ) 71 | //Vertex shader 72 | @property( exponential_shadow_maps )float4 viewZRow;@end 73 | float2 depthRange; 74 | @end 75 | 76 | @property( hlms_forwardplus ) 77 | //Forward3D 78 | //f3dData.x = minDistance; 79 | //f3dData.y = invMaxDistance; 80 | //f3dData.z = f3dNumSlicesSub1; 81 | //f3dData.w = uint cellsPerTableOnGrid0 (floatBitsToUint); 82 | 83 | //Clustered Forward: 84 | //f3dData.x = minDistance; 85 | //f3dData.y = invExponentK; 86 | //f3dData.z = f3dNumSlicesSub1; 87 | //f3dData.w = renderWindow->getHeight(); 88 | float4 f3dData; 89 | @property( hlms_forwardplus == forward3d ) 90 | float4 f3dGridHWW[@value( forward3d_num_slices )]; 91 | @end 92 | @property( hlms_forwardplus != forward3d ) 93 | float4 fwdScreenToGrid; 94 | @end 95 | @end 96 | 97 | @insertpiece( DeclPlanarReflUniforms ) 98 | 99 | @property( parallax_correct_cubemaps ) 100 | CubemapProbe autoProbe; 101 | @end 102 | 103 | @insertpiece( custom_passBuffer ) 104 | };@end 105 | 106 | @piece( PassDecl ) 107 | , constant PassData &passBuf [[buffer(CONST_SLOT_START+0)]] 108 | @end 109 | 110 | @property( fresnel_scalar )@piece( FresnelType )float3@end @piece( FresnelSwizzle )xyz@end @end 111 | @property( !fresnel_scalar )@piece( FresnelType )float@end @piece( FresnelSwizzle )x@end @end 112 | 113 | @piece( MaterialStructDecl ) 114 | //Uniforms that change per Item/Entity, but change very infrequently 115 | struct Material 116 | { 117 | /* kD is already divided by PI to make it energy conserving. 118 | (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) 119 | */ 120 | float4 bgDiffuse; 121 | float4 kD; //kD.w is alpha_test_threshold 122 | float4 kS; //kS.w is roughness 123 | //Fresnel coefficient, may be per colour component (float3) or scalar (float) 124 | //F0.w is transparency 125 | float4 F0; 126 | float4 normalWeights; 127 | float4 cDetailWeights; 128 | float4 detailOffsetScaleD[4]; 129 | float4 detailOffsetScaleN[4]; 130 | 131 | //uint4 indices0_3; 132 | ushort diffuseIdx; 133 | ushort normalIdx; 134 | ushort specularIdx; 135 | ushort roughnessIdx; 136 | ushort weightMapIdx; 137 | ushort detailMapIdx0; 138 | ushort detailMapIdx1; 139 | ushort detailMapIdx2; 140 | 141 | //uint4 indices4_7; 142 | ushort detailMapIdx3; 143 | ushort detailNormMapIdx0; 144 | ushort detailNormMapIdx1; 145 | ushort detailNormMapIdx2; 146 | ushort detailNormMapIdx3; 147 | ushort envMapIdx; 148 | float mNormalMapWeight; 149 | };@end 150 | 151 | @piece( MaterialDecl ) 152 | , constant Material *materialArray [[buffer(CONST_SLOT_START+1)]] 153 | @end 154 | 155 | 156 | @piece( InstanceDecl ) 157 | //Uniforms that change per Item/Entity 158 | //.x = 159 | //The lower 9 bits contain the material's start index. 160 | //The higher 23 bits contain the world matrix start index. 161 | // 162 | //.y = 163 | //shadowConstantBias. Send the bias directly to avoid an 164 | //unnecessary indirection during the shadow mapping pass. 165 | //Must be loaded with uintBitsToFloat 166 | , constant uint4 *worldMaterialIdx [[buffer(CONST_SLOT_START+2)]] 167 | @end 168 | 169 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 170 | @piece( PccManualProbeDecl ) 171 | , constant CubemapProbe &manualProbe [[buffer(CONST_SLOT_START+3)]] 172 | @end 173 | @end 174 | 175 | //Reset texcoord to 0 for every shader stage (since values are preserved). 176 | @pset( texcoord, 0 ) 177 | 178 | @piece( VStoPS_block ) 179 | @property( !hlms_shadowcaster ) 180 | @property( !lower_gpu_overhead ) 181 | ushort materialId [[flat]]; 182 | @end 183 | @property( hlms_fine_light_mask || hlms_forwardplus_fine_light_mask ) 184 | uint objLightMask [[flat]]; 185 | @end 186 | @property( use_planar_reflections ) 187 | ushort planarReflectionIdx [[flat]]; 188 | @end 189 | @property( hlms_normal || hlms_qtangent ) 190 | float3 pos; 191 | float3 normal; 192 | @property( normal_map )float3 tangent; 193 | @property( hlms_qtangent )float biNormalReflection [[flat]];@end 194 | @end 195 | @end 196 | @foreach( hlms_uv_count, n ) 197 | float@value( hlms_uv_count@n ) uv@n;@end 198 | 199 | @foreach( hlms_num_shadow_map_lights, n ) 200 | @property( !hlms_shadowmap@n_is_point_light ) 201 | float4 posL@n;@end @end 202 | 203 | @property( hlms_pssm_splits )float depth;@end 204 | @end 205 | 206 | @property( hlms_shadowcaster ) 207 | @property( alpha_test ) 208 | ushort drawId [[flat]]; 209 | @foreach( hlms_uv_count, n ) 210 | float@value( hlms_uv_count@n ) uv@n;@end 211 | @end 212 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 213 | float depth; 214 | @end 215 | @property( hlms_shadowcaster_point ) 216 | float3 toCameraWS; 217 | @property( !exponential_shadow_maps ) 218 | float constBias [[flat]]; 219 | @end 220 | @end 221 | @end 222 | 223 | @insertpiece( custom_VStoPS ) 224 | @end 225 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Pbs/Metal/Textures_piece_ps.metal: -------------------------------------------------------------------------------- 1 | 2 | //Set the sampler starts. Note that 'padd' get calculated before _any_ 'add' 3 | @set( texUnit, 1 ) 4 | 5 | @property( hlms_forwardplus ) 6 | @add( texUnit, 2 ) 7 | @end 8 | 9 | @property( hlms_use_prepass ) 10 | @set( gBuf_normals, texUnit ) 11 | @add( gBuf_shadowRoughness, texUnit, 1 ) 12 | @add( texUnit, 2 ) 13 | 14 | @property( hlms_use_ssr ) 15 | @set( ssrTexture, texUnit ) 16 | @add( texUnit, 1 ) 17 | @end 18 | @end 19 | 20 | @property( irradiance_volumes ) 21 | @set( irradianceVolumeTexUnit, texUnit ) 22 | @add( texUnit, 1 ) 23 | @end 24 | 25 | @set( textureRegShadowMapStart, texUnit ) 26 | @add( texUnit, hlms_num_shadow_map_textures ) 27 | 28 | @property( parallax_correct_cubemaps ) 29 | @set( globaPccTexUnit, texUnit ) 30 | @add( texUnit, 1 ) 31 | @end 32 | 33 | @property( has_planar_reflections ) 34 | @set( planarReflectionTexUnit, texUnit ) 35 | @add( texUnit, 1 ) 36 | @end 37 | 38 | @set( textureRegStart, texUnit ) 39 | @set( samplerStateStart, texUnit ) 40 | @set( numSamplerStates, num_textures ) 41 | @add( texUnit, num_textures ) 42 | 43 | @set( envMapReg, texUnit ) 44 | 45 | @property( (envprobe_map && envprobe_map != target_envprobe_map) || parallax_correct_cubemaps ) 46 | @set( use_envprobe_map, 1 ) 47 | 48 | @property( !envprobe_map || envprobe_map == target_envprobe_map ) 49 | /// "No cubemap"? Then we're in auto mode or... 50 | /// We're rendering to the cubemap probe we're using as manual. Use the auto mode as fallback. 51 | @piece( pccProbeSource )passBuf.autoProbe@end 52 | @set( use_parallax_correct_cubemaps, 1 ) 53 | /// Auto cubemap textures are set at the beginning. Manual cubemaps are the end. 54 | @set( envMapReg, globaPccTexUnit ) 55 | @end 56 | @property( envprobe_map && envprobe_map != target_envprobe_map && use_parallax_correct_cubemaps ) 57 | @piece( pccProbeSource )manualProbe@end 58 | @end 59 | @end 60 | 61 | @property( diffuse_map ) 62 | @property( !hlms_shadowcaster ) 63 | @piece( SampleDiffuseMap ) diffuseCol = textureMaps@value( diffuse_map_idx ).sample( samplerStates@value(diffuse_map_idx), inPs.uv@value(uv_diffuse).xy, diffuseIdx ); 64 | @property( !hw_gamma_read ) diffuseCol = diffuseCol * diffuseCol;@end @end 65 | @end @property( hlms_shadowcaster ) 66 | @piece( SampleDiffuseMap ) diffuseCol = textureMaps@value( diffuse_map_idx ).sample( samplerStates@value(diffuse_map_idx), inPs.uv@value(uv_diffuse).xy, diffuseIdx ).w;@end 67 | @end 68 | @end 69 | 70 | @property( transparent_mode ) 71 | @piece( diffuseExtraParamDef ), float4 diffuseCol@end 72 | @piece( diffuseExtraParam ), diffuseCol.xyzw@end 73 | @end @property( !transparent_mode ) 74 | @piece( diffuseExtraParamDef ), float3 diffuseCol@end 75 | @piece( diffuseExtraParam ), diffuseCol.xyz@end 76 | @end 77 | //diffuseCol always has some colour and is multiplied against material.kD in PixelShader_ps. 78 | @piece( kD )diffuseCol@end 79 | 80 | @property( !hlms_prepass ) 81 | @property( !metallic_workflow ) 82 | @property( specular_map && !fresnel_workflow ) 83 | @piece( SampleSpecularMap ) specularCol = textureMaps@value( specular_map_idx ).sample( samplerStates@value(specular_map_idx), inPs.uv@value(uv_specular).xy, specularIdx ).xyz * material.kS.xyz;@end 84 | @piece( specularExtraParamDef ), float3 specularCol@end 85 | @piece( specularExtraParam ), specularCol.xyz@end 86 | @piece( kS )specularCol@end 87 | @end 88 | @property( specular_map && fresnel_workflow ) 89 | @piece( SampleSpecularMap ) F0 = textureMaps@value( specular_map_idx ).sample( samplerStates@value(specular_map_idx), inPs.uv@value(uv_specular).xy, specularIdx ).@insertpiece( FresnelSwizzle ) * material.F0.@insertpiece( FresnelSwizzle );@end 90 | @piece( specularExtraParamDef ), @insertpiece( FresnelType ) F0@end 91 | @piece( specularExtraParam ), F0@end 92 | @end 93 | @property( !specular_map || fresnel_workflow ) 94 | @piece( kS )material.kS@end 95 | @end 96 | @end @property( metallic_workflow ) 97 | @piece( SampleSpecularMap ) 98 | @property( specular_map ) 99 | float metalness = textureMaps@value( specular_map_idx ).sample( samplerStates@value(specular_map_idx), inPs.uv@value(uv_specular).xy, specularIdx ).x * material.F0.x; 100 | F0 = mix( 0.03f, @insertpiece( kD ).xyz * 3.14159f, metalness ); 101 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * metalness; 102 | @end @property( !specular_map ) 103 | F0 = mix( 0.03f, @insertpiece( kD ).xyz * 3.14159f, material.F0.x ); 104 | @insertpiece( kD ).xyz = @insertpiece( kD ).xyz - @insertpiece( kD ).xyz * material.F0.x; 105 | @end 106 | @property( hlms_alphablend )F0 *= material.F0.w;@end 107 | @property( transparent_mode )F0 *= diffuseCol.w;@end 108 | @end /// SampleSpecularMap 109 | 110 | @piece( kS )material.kS.xyz@end 111 | @piece( metallicExtraParamDef ), float3 F0@end 112 | @piece( metallicExtraParam ), F0@end 113 | @end 114 | @end 115 | 116 | @property( roughness_map ) 117 | @piece( SampleRoughnessMap ) ROUGHNESS = material.kS.w * textureMaps@value( roughness_map_idx ).sample( samplerStates@value( roughness_map_idx ), inPs.uv@value(uv_roughness).xy, roughnessIdx ).x; 118 | ROUGHNESS = max( ROUGHNESS, 0.001f );@end 119 | @piece( roughnessExtraParamDef ), float ROUGHNESS@end 120 | @piece( roughnessExtraParam ), ROUGHNESS@end 121 | @end 122 | 123 | @piece( brdfExtraParamDefs )@insertpiece( diffuseExtraParamDef )@insertpiece( specularExtraParamDef )@insertpiece( roughnessExtraParamDef )@insertpiece( metallicExtraParamDef )@end 124 | @piece( brdfExtraParams )@insertpiece( diffuseExtraParam )@insertpiece( specularExtraParam )@insertpiece( roughnessExtraParam )@insertpiece( metallicExtraParam )@end 125 | 126 | @foreach( detail_maps_normal, n ) 127 | @piece( SampleDetailMapNm@n )getTSNormal( samplerStates@value(detail_map_nm@n_idx), textureMaps@value(detail_map_nm@n_idx), inPs.uv@value(uv_detail_nm@n).xy@insertpiece( offsetDetailN@n ), detailNormMapIdx@n ) * detailWeights.@insertpiece(detail_swizzle@n) @insertpiece( detail@n_nm_weight_mul )@end 128 | @end 129 | 130 | @property( detail_weight_map ) 131 | @piece( SamplerDetailWeightMap )textureMaps@value(detail_weight_map_idx).sample( samplerStates@value(detail_weight_map_idx), inPs.uv@value(uv_detail_weight).xy, weightMapIdx )@end 132 | @end 133 | 134 | @property( envmap_scale ) 135 | @piece( ApplyEnvMapScale )* passBuf.ambientUpperHemi.w@end 136 | @end 137 | 138 | @property( !hlms_render_depth_only && !hlms_shadowcaster && hlms_prepass ) 139 | @undefpiece( DeclOutputType ) 140 | @piece( DeclOutputType ) 141 | struct PS_OUTPUT 142 | { 143 | float4 normals [[ color(0) ]]; 144 | float2 shadowRoughness [[ color(1) ]]; 145 | }; 146 | @end 147 | @end 148 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/GLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | @property( !hlms_shadowcaster && terra_enabled ) 2 | 3 | @piece( custom_VStoPS ) 4 | float terrainShadow; 5 | @end 6 | 7 | /// Extra per-pass global data we need for applying our 8 | /// shadows to regular objects, passed to all PBS shaders. 9 | @piece( custom_passBuffer ) 10 | vec4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions 11 | //.xz = terrain 1.0 / XZ dimensions. 12 | //.y = 1.0 / terrainHeight; 13 | vec4 invTerraBounds; 14 | @end 15 | 16 | /// Add the shadows' texture to the vertex shader 17 | @piece( custom_vs_uniformDeclaration ) 18 | uniform sampler2D terrainShadows; 19 | @end 20 | 21 | /// Evaluate the shadow based on world XZ position & height in the vertex shader. 22 | /// Doing it at the pixel shader level would be more accurate, but the difference 23 | /// is barely noticeable, and slower 24 | @piece( custom_vs_posExecution ) 25 | vec3 terraShadowData = textureLod( terrainShadows, worldPos.xz * passBuf.invTerraBounds.xz + passBuf.terraOrigin.xz, 0 ).xyz; 26 | float terraHeightWeight = worldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; 27 | terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; 28 | outVs.terrainShadow = mix( terraShadowData.x, 1.0, clamp( terraHeightWeight, 0.0, 1.0 ) ); 29 | @end 30 | 31 | @property( hlms_num_shadow_map_lights ) 32 | @piece( custom_ps_preLights )fShadow *= inPs.terrainShadow;@end 33 | @end @property( !hlms_num_shadow_map_lights ) 34 | @piece( custom_ps_preLights )float fShadow = inPs.terrainShadow;@end 35 | @piece( DarkenWithShadowFirstLight )* fShadow@end 36 | @end 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/GLSL/Structs_piece_vs_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | 2 | @piece( TerraMaterialDecl ) 3 | layout(binding = 1) uniform MaterialBuf 4 | { 5 | /* kD is already divided by PI to make it energy conserving. 6 | (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) 7 | */ 8 | vec4 kD; //kD.w is padding 9 | vec4 roughness; 10 | vec4 metalness; 11 | vec4 detailOffsetScale[4]; 12 | 13 | } material; 14 | @end 15 | 16 | @piece( TerraInstanceDecl ) 17 | struct CellData 18 | { 19 | //.x = numVertsPerLine 20 | //.y = lodLevel 21 | //.z = vao->getPrimitiveCount() / m_verticesPerLine - 2u 22 | //.w = skirtY (float) 23 | uvec4 numVertsPerLine; 24 | ivec4 xzTexPosBounds; //XZXZ 25 | vec4 pos; //.w contains 1.0 / xzTexPosBounds.z 26 | vec4 scale; //.w contains 1.0 / xzTexPosBounds.w 27 | }; 28 | layout(binding = 2) uniform InstanceBuffer 29 | { 30 | CellData cellData[256]; 31 | } instance; 32 | @end 33 | 34 | @piece( Terra_VStoPS_block ) 35 | //flat uint drawId; 36 | vec3 pos; 37 | vec2 uv0; 38 | 39 | @foreach( hlms_num_shadow_map_lights, n ) 40 | @property( !hlms_shadowmap@n_is_point_light ) 41 | vec4 posL@n;@end @end 42 | @property( hlms_pssm_splits )float depth;@end 43 | @insertpiece( custom_VStoPS ) 44 | @end 45 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/GLSL/Textures_piece_ps.glsl: -------------------------------------------------------------------------------- 1 | 2 | @undefpiece( kD ) 3 | @piece( kD )diffuseCol@end 4 | 5 | @undefpiece( kS ) 6 | @piece( kS )vec3( 1, 1, 1 )@end 7 | 8 | @foreach( detail_maps_normal, n ) 9 | @undefpiece( SampleDetailMapNm@n ) 10 | @piece( SampleDetailMapNm@n )getTSDetailNormal( textureMaps[@value(detail_map_nm@n_idx)], vec3( inPs.uv0.xy * material.detailOffsetScale[@n].zw + 11 | material.detailOffsetScale[@n].xy , @value(detail_map_nm@n_idx_slice) ) )@end 12 | @end 13 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/GLSL/VertexShader_vs.glsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | out gl_PerVertex 4 | { 5 | vec4 gl_Position; 6 | }; 7 | 8 | layout(std140) uniform; 9 | 10 | //To render a 2x2 (quads) terrain: 11 | //You'll normally need 6 vertices per line + 2 for degenerates. 12 | //You'll need 8 vertices per line. 13 | //So you'll need a total of 16 vertices. 14 | 15 | //To render a 4x2 (quads) terrain: 16 | //You'll need 10 vertices per line. 17 | //If we include degenerate vertices, you'll need 12 per line 18 | //So you'll need a total of 24 vertices. 19 | //in int gl_VertexID; 20 | 21 | in uint drawId; 22 | 23 | @insertpiece( custom_vs_attributes ) 24 | 25 | out block 26 | { 27 | @insertpiece( Terra_VStoPS_block ) 28 | } outVs; 29 | 30 | // START UNIFORM DECLARATION 31 | @insertpiece( PassDecl ) 32 | @insertpiece( TerraInstanceDecl ) 33 | uniform sampler2D heightMap; 34 | @insertpiece( custom_vs_uniformDeclaration ) 35 | // END UNIFORM DECLARATION 36 | 37 | @piece( VertexTransform ) 38 | //Lighting is in view space 39 | outVs.pos = ( vec4(worldPos.xyz, 1.0f) * passBuf.view ).xyz; 40 | @property( !hlms_dual_paraboloid_mapping ) 41 | gl_Position = vec4(worldPos.xyz, 1.0f) * passBuf.viewProj;@end 42 | @property( hlms_dual_paraboloid_mapping ) 43 | //Dual Paraboloid Mapping 44 | gl_Position.w = 1.0f; 45 | gl_Position.xyz = outVs.pos; 46 | float L = length( gl_Position.xyz ); 47 | gl_Position.z += 1.0f; 48 | gl_Position.xy /= gl_Position.z; 49 | gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end 50 | @end 51 | @piece( ShadowReceive ) 52 | @foreach( hlms_num_shadow_map_lights, n ) 53 | @property( !hlms_shadowmap@n_is_point_light ) 54 | outVs.posL@n = vec4(worldPos.xyz, 1.0f) * passBuf.shadowRcv[@n].texViewProj;@end @end 55 | @end 56 | 57 | void main() 58 | { 59 | @insertpiece( custom_vs_preExecution ) 60 | 61 | CellData cellData = instance.cellData[drawId]; 62 | 63 | //Map pointInLine from range [0; 12) to range [0; 9] so that it reads: 64 | // 0 0 1 2 3 4 5 6 7 8 9 9 65 | uint pointInLine = uint(gl_VertexID) % (cellData.numVertsPerLine.x); //cellData.numVertsPerLine.x = 12 66 | pointInLine = uint(clamp( int(pointInLine) - 1, 0, int(cellData.numVertsPerLine.x - 3u) )); 67 | 68 | uvec2 uVertexPos; 69 | 70 | uVertexPos.x = pointInLine >> 1u; 71 | //Even numbers are the next line, odd numbers are current line. 72 | uVertexPos.y = (pointInLine & 0x01u) == 0u ? 1u : 0u; 73 | uVertexPos.y += uint(gl_VertexID) / cellData.numVertsPerLine.x; 74 | //uVertexPos.y += floor( (float)gl_VertexID / (float)cellData.numVertsPerLine ); Could be faster on GCN. 75 | 76 | @property( use_skirts ) 77 | //Apply skirt. 78 | bool isSkirt =( pointInLine.x <= 1u || 79 | pointInLine.x >= (cellData.numVertsPerLine.x - 4u) || 80 | uVertexPos.y == 0u || 81 | uVertexPos.y == (cellData.numVertsPerLine.z + 2u) ); 82 | 83 | //Now shift X position for the left & right skirts 84 | uVertexPos.x = uint( max( int(uVertexPos.x) - 1, 0 ) ); 85 | uVertexPos.x = min( uVertexPos.x, ((cellData.numVertsPerLine.x - 7u) >> 1u) ); 86 | // uVertexPos.x becomes: 87 | // 0 0 0 1 1 2 2 3 3 4 4 4 88 | // 0 0 0 0 0 1 1 2 2 3 3 3 89 | // 0 0 0 0 0 1 1 2 2 2 2 2 90 | 91 | //Now shift Y position for the front & back skirts 92 | uVertexPos.y = uint( max( int(uVertexPos.y) - 1, 0 ) ); 93 | uVertexPos.y = min( uVertexPos.y, cellData.numVertsPerLine.z ); 94 | @end 95 | 96 | uint lodLevel = cellData.numVertsPerLine.y; 97 | uVertexPos = uVertexPos << lodLevel; 98 | 99 | uVertexPos.xy = uvec2( clamp( ivec2(uVertexPos.xy) + cellData.xzTexPosBounds.xy, 100 | ivec2( 0, 0 ), cellData.xzTexPosBounds.zw ) ); 101 | 102 | vec3 worldPos; 103 | worldPos.y = texelFetch( heightMap, ivec2( uVertexPos.xy ), 0 ).x; 104 | @property( use_skirts ) 105 | worldPos.y = isSkirt ? uintBitsToFloat(cellData.numVertsPerLine.w) : worldPos.y; 106 | @end 107 | worldPos.xz = uVertexPos.xy; 108 | worldPos.xyz = worldPos.xyz * cellData.scale.xyz + cellData.pos.xyz; 109 | 110 | @insertpiece( VertexTransform ) 111 | 112 | outVs.uv0.xy = vec2( uVertexPos.xy ) * vec2( cellData.pos.w, cellData.scale.w ); 113 | 114 | @insertpiece( ShadowReceive ) 115 | @foreach( hlms_num_shadow_map_lights, n ) 116 | @property( !hlms_shadowmap@n_is_point_light ) 117 | outVs.posL@n.z = outVs.posL@n.z * passBuf.shadowRcv[@n].shadowDepthRange.y; 118 | outVs.posL@n.z = (outVs.posL@n.z * 0.5) + 0.5; 119 | @end 120 | @end 121 | 122 | @property( hlms_pssm_splits ) outVs.depth = gl_Position.z;@end 123 | 124 | //outVs.drawId = drawId; 125 | 126 | @insertpiece( custom_vs_posExecution ) 127 | } 128 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/HLSL/PbsTerraShadows/PbsTerraShadows_piece_vs_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | @property( !hlms_shadowcaster && terra_enabled ) 2 | 3 | @piece( custom_VStoPS ) 4 | float terrainShadow : TEXCOORD@counter(texcoord); 5 | @end 6 | 7 | /// Extra per-pass global data we need for applying our 8 | /// shadows to regular objects, passed to all PBS shaders. 9 | @piece( custom_passBuffer ) 10 | float4 terraOrigin; //Normalized. i.e. -terrainOrigin / terrainDimensions 11 | //.xz = terrain 1.0 / XZ dimensions. 12 | //.y = 1.0 / terrainHeight; 13 | float4 invTerraBounds; 14 | @end 15 | 16 | /// Add the shadows' texture to the vertex shader 17 | @piece( custom_vs_uniformDeclaration ) 18 | SamplerState terrainShadowSampler : register(s12); 19 | Texture2D terrainShadows : register(t12); 20 | @end 21 | 22 | /// Evaluate the shadow based on world XZ position & height in the vertex shader. 23 | /// Doing it at the pixel shader level would be more accurate, but the difference 24 | /// is barely noticeable, and slower 25 | @piece( custom_vs_posExecution ) 26 | float3 terraShadowData = terrainShadows.SampleLevel( terrainShadowSampler, worldPos.xz * passBuf.invTerraBounds.xz + passBuf.terraOrigin.xz, 0 ).xyz; 27 | float terraHeightWeight = worldPos.y * passBuf.invTerraBounds.y + passBuf.terraOrigin.y; 28 | terraHeightWeight = (terraHeightWeight - terraShadowData.y) * terraShadowData.z * 1023.0; 29 | outVs.terrainShadow = lerp( terraShadowData.x, 1.0, saturate( terraHeightWeight ) ); 30 | @end 31 | 32 | @property( hlms_num_shadow_map_lights ) 33 | @piece( custom_ps_preLights )fShadow *= inPs.terrainShadow;@end 34 | @end @property( !hlms_num_shadow_map_lights ) 35 | @piece( custom_ps_preLights )float fShadow = inPs.terrainShadow;@end 36 | @piece( DarkenWithShadowFirstLight )* fShadow@end 37 | @end 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/HLSL/Structs_piece_vs_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | @piece( TerraMaterialDecl ) 2 | //Uniforms that change per Item/Entity, but change very infrequently 3 | struct Material 4 | { 5 | /* kD is already divided by PI to make it energy conserving. 6 | (formula is finalDiffuse = NdotL * surfaceDiffuse / PI) 7 | */ 8 | float4 kD; //kD.w is padding 9 | float4 roughness; 10 | float4 metalness; 11 | float4 detailOffsetScale[4]; 12 | }; 13 | 14 | cbuffer MaterialBuf : register(b1) 15 | { 16 | Material material; 17 | }; 18 | @end 19 | 20 | 21 | @piece( TerraInstanceDecl ) 22 | struct CellData 23 | { 24 | //.x = numVertsPerLine 25 | //.y = lodLevel 26 | //.z = vao->getPrimitiveCount() / m_verticesPerLine - 2u 27 | //.w = skirtY (float) 28 | uint4 numVertsPerLine; 29 | int4 xzTexPosBounds; //XZXZ 30 | float4 pos; //.w contains 1.0 / xzTexPosBounds.z 31 | float4 scale; //.w contains 1.0 / xzTexPosBounds.w 32 | }; 33 | //Uniforms that change per Item/Entity 34 | cbuffer InstanceBuffer : register(b2) 35 | { 36 | CellData cellDataArray[256]; 37 | }; 38 | @end 39 | 40 | //Reset texcoord to 0 for every shader stage (since values are preserved). 41 | @pset( texcoord, 0 ) 42 | 43 | @piece( Terra_VStoPS_block ) 44 | float3 pos : TEXCOORD@counter(texcoord); 45 | float2 uv0 : TEXCOORD@counter(texcoord); 46 | @foreach( hlms_num_shadow_map_lights, n ) 47 | @property( !hlms_shadowmap@n_is_point_light ) 48 | float4 posL@n : TEXCOORD@counter(texcoord);@end @end 49 | 50 | @property( hlms_pssm_splits )float depth : TEXCOORD@counter(texcoord);@end 51 | @insertpiece( custom_VStoPS ) 52 | @end 53 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/HLSL/Textures_piece_ps.hlsl: -------------------------------------------------------------------------------- 1 | 2 | @undefpiece( kD ) 3 | @piece( kD )diffuseCol@end 4 | 5 | @undefpiece( kS ) 6 | @piece( kS )float3( 1, 1, 1 )@end 7 | 8 | @add( textureRegStart, 2 ) 9 | @add( envMapReg, 2 ) 10 | @add( textureRegShadowMapStart, 2 ) 11 | @add( samplerStateStart, 2 ) 12 | 13 | @undefpiece( diffuseExtraParam ) 14 | @undefpiece( specularExtraParam ) 15 | @undefpiece( roughnessExtraParam ) 16 | @undefpiece( metallicExtraParam ) 17 | 18 | @undefpiece( diffuseExtraParamDef ) 19 | @undefpiece( specularExtraParamDef ) 20 | @undefpiece( roughnessExtraParamDef ) 21 | @undefpiece( metallicExtraParamDef ) 22 | 23 | @piece( diffuseExtraParamDef ), float3 diffuseCol@end 24 | @piece( diffuseExtraParam ), diffuseCol.xyz@end 25 | @piece( metallicExtraParamDef ), float3 F0@end 26 | @piece( metallicExtraParam ), F0@end 27 | @piece( roughnessExtraParamDef ), float ROUGHNESS@end 28 | @piece( roughnessExtraParam ), ROUGHNESS@end 29 | 30 | @foreach( detail_maps_normal, n ) 31 | @undefpiece( SampleDetailMapNm@n ) 32 | @piece( SampleDetailMapNm@n )getTSDetailNormal( samplerStates[@value(detail_map_nm@n_idx)], textureMaps[@value(detail_map_nm@n_idx)], 33 | float3( inPs.uv0.xy * material.detailOffsetScale[@n].zw + 34 | material.detailOffsetScale[@n].xy, @value(detail_map_nm@n_idx_slice) ) )@end 35 | @end 36 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Terra/HLSL/VertexShader_vs.hlsl: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | //To render a 2x2 (quads) terrain: 4 | //You'll normally need 6 vertices per line + 2 for degenerates. 5 | //You'll need 8 vertices per line. 6 | //So you'll need a total of 16 vertices. 7 | 8 | //To render a 4x2 (quads) terrain: 9 | //You'll need 10 vertices per line. 10 | //If we include degenerate vertices, you'll need 12 per line 11 | //So you'll need a total of 24 vertices. 12 | //in int gl_VertexID; 13 | 14 | struct VS_INPUT 15 | { 16 | uint gl_VertexID : SV_VertexID; 17 | uint drawId : DRAWID; 18 | @insertpiece( custom_vs_attributes ) 19 | }; 20 | 21 | struct PS_INPUT 22 | { 23 | @insertpiece( Terra_VStoPS_block ) 24 | float4 gl_Position: SV_Position; 25 | }; 26 | 27 | // START UNIFORM DECLARATION 28 | @insertpiece( PassDecl ) 29 | @insertpiece( TerraInstanceDecl ) 30 | Texture2D heightMap: register(t0); 31 | @insertpiece( custom_vs_uniformDeclaration ) 32 | // END UNIFORM DECLARATION 33 | 34 | @piece( VertexTransform ) 35 | //Lighting is in view space 36 | outVs.pos = mul( float4( worldPos.xyz, 1.0f ), passBuf.view ).xyz; 37 | @property( !hlms_dual_paraboloid_mapping ) 38 | outVs.gl_Position = mul( float4( worldPos.xyz, 1.0f ), passBuf.viewProj );@end 39 | @property( hlms_dual_paraboloid_mapping ) 40 | //Dual Paraboloid Mapping 41 | outVs.gl_Position.w = 1.0f; 42 | outVs.gl_Position.xyz = outVs.pos; 43 | float L = length( outVs.gl_Position.xyz ); 44 | outVs.gl_Position.z += 1.0f; 45 | outVs.gl_Position.xy /= outVs.gl_Position.z; 46 | outVs.gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane);@end 47 | @end 48 | @piece( ShadowReceive ) 49 | @foreach( hlms_num_shadow_map_lights, n ) 50 | @property( !hlms_shadowmap@n_is_point_light ) 51 | outVs.posL@n = mul( float4(worldPos.xyz, 1.0f), passBuf.shadowRcv[@n].texViewProj );@end @end 52 | @end 53 | 54 | PS_INPUT main( VS_INPUT input ) 55 | { 56 | PS_INPUT outVs; 57 | @insertpiece( custom_vs_preExecution ) 58 | CellData cellData = cellDataArray[input.drawId]; 59 | 60 | //Map pointInLine from range [0; 12) to range [0; 9] so that it reads: 61 | // 0 0 1 2 3 4 5 6 7 8 9 9 62 | uint pointInLine = input.gl_VertexID % (cellData.numVertsPerLine.x); //cellData.numVertsPerLine.x = 12 63 | pointInLine = uint(clamp( int(pointInLine) - 1, 0, int(cellData.numVertsPerLine.x - 3u) )); 64 | 65 | uint2 uVertexPos; 66 | 67 | uVertexPos.x = pointInLine >> 1u; 68 | //Even numbers are the next line, odd numbers are current line. 69 | uVertexPos.y = (pointInLine & 0x01u) == 0u ? 1u : 0u; 70 | uVertexPos.y += input.gl_VertexID / cellData.numVertsPerLine.x; 71 | //uVertexPos.y += floor( (float)input.gl_VertexID / (float)cellData.numVertsPerLine ); Could be faster on GCN. 72 | 73 | @property( use_skirts ) 74 | //Apply skirt. 75 | bool isSkirt =( pointInLine.x <= 1u || 76 | pointInLine.x >= (cellData.numVertsPerLine.x - 4u) || 77 | uVertexPos.y == 0u || 78 | uVertexPos.y == (cellData.numVertsPerLine.z + 2u) ); 79 | 80 | //Now shift X position for the left & right skirts 81 | uVertexPos.x = uint( max( int(uVertexPos.x) - 1, 0 ) ); 82 | uVertexPos.x = min( uVertexPos.x, ((cellData.numVertsPerLine.x - 7u) >> 1u) ); 83 | // uVertexPos.x becomes: 84 | // 0 0 0 1 1 2 2 3 3 4 4 4 85 | // 0 0 0 0 0 1 1 2 2 3 3 3 86 | // 0 0 0 0 0 1 1 2 2 2 2 2 87 | 88 | //Now shift Y position for the front & back skirts 89 | uVertexPos.y = uint( max( int(uVertexPos.y) - 1, 0 ) ); 90 | uVertexPos.y = min( uVertexPos.y, cellData.numVertsPerLine.z ); 91 | @end 92 | 93 | uint lodLevel = cellData.numVertsPerLine.y; 94 | uVertexPos = uVertexPos << lodLevel; 95 | 96 | uVertexPos.xy = uint2( clamp( int2(uVertexPos.xy) + cellData.xzTexPosBounds.xy, 97 | int2( 0, 0 ), cellData.xzTexPosBounds.zw ) ); 98 | 99 | float3 worldPos; 100 | worldPos.y = heightMap.Load( int3( uVertexPos.xy, 0 ) ).x; 101 | @property( use_skirts ) 102 | worldPos.y = isSkirt ? asfloat(cellData.numVertsPerLine.w) : worldPos.y; 103 | @end 104 | worldPos.xz = uVertexPos.xy; 105 | worldPos.xyz = worldPos.xyz * cellData.scale.xyz + cellData.pos.xyz; 106 | 107 | @insertpiece( VertexTransform ) 108 | 109 | outVs.uv0.xy = float2( uVertexPos.xy ) * float2( cellData.pos.w, cellData.scale.w ); 110 | 111 | @insertpiece( ShadowReceive ) 112 | @foreach( hlms_num_shadow_map_lights, n ) 113 | @property( !hlms_shadowmap@n_is_point_light ) 114 | outVs.posL@n.z = outVs.posL@n.z * passBuf.shadowRcv[@n].shadowDepthRange.y;@end @end 115 | 116 | @property( hlms_pssm_splits ) outVs.depth = outVs.gl_Position.z;@end 117 | 118 | //outVs.drawId = input.drawId; 119 | 120 | @insertpiece( custom_vs_posExecution ) 121 | 122 | return outVs; 123 | } 124 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Unlit/Metal/BlendModes_piece_ps.metal: -------------------------------------------------------------------------------- 1 | //Reset t to 0 just in case (values are preserved from previous stages) 2 | @pset( t, 0 ) 3 | 4 | @piece( NormalNonPremul ) 5 | //Normal Non Premultiplied @counter(t) 6 | outPs.colour0.xyz = mix( outPs.colour0.xyz, topImage@value(t).xyz, topImage@value(t).a ); 7 | outPs.colour0.w = mix( outPs.colour0.w, 1.0, topImage@value(t).w ); 8 | @end 9 | 10 | @piece( NormalPremul ) 11 | //Normal Premultiplied @counter(t) 12 | outPs.colour0.xyz = (1.0 - topImage@value(t).a) * outPs.colour0.xyz + topImage@value(t).xyz; 13 | outPs.colour0.w = mix( outPs.colour0.w, 1.0, topImage@value(t).w ); 14 | @end 15 | 16 | @piece( Add ) 17 | //Add @counter(t) 18 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 19 | min( outPs.colour0.xyz + topImage@value(t).xyz, float3(1.0) ), 20 | topImage@value(t).a ); 21 | @end 22 | 23 | @piece( Subtract ) 24 | //Subtract @counter(t) 25 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 26 | max( outPs.colour0.xyz - topImage@value(t).xyz, float3(0.0) ), 27 | topImage@value(t).a ); 28 | @end 29 | 30 | @piece( Multiply ) 31 | //Multiply @counter(t) 32 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 33 | outPs.colour0.xyz * topImage@value(t).xyz, 34 | topImage@value(t).a ); 35 | @end 36 | 37 | @piece( Multiply2x ) 38 | //Multiply2x @counter(t) 39 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 40 | min( outPs.colour0.xyz * topImage@value(t).xyz * 2.0, float3(1.0) ), 41 | topImage@value(t).a ); 42 | @end 43 | 44 | @piece( Screen ) 45 | //Screen @counter(t) 46 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 47 | 1.0 - (1.0 - outPs.colour0.xyz) * (1.0 - topImage@value(t).xyz), 48 | topImage@value(t).a ); 49 | @end 50 | 51 | @piece( Overlay ) 52 | //Overlay @counter(t) 53 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 54 | outPs.colour0.xyz * ( outPs.colour0.xyz + 2.0 * topImage@value(t).xyz * (1.0 - outPs.colour0.xyz) ), 55 | topImage@value(t).a ); 56 | @end 57 | 58 | @piece( Lighten ) 59 | //Lighten @counter(t) 60 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 61 | max( outPs.colour0.xyz, topImage@value(t).xyz ), 62 | topImage@value(t).a ); 63 | @end 64 | 65 | @piece( Darken ) 66 | //Darken @counter(t) 67 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 68 | min( outPs.colour0.xyz, topImage@value(t).xyz ), 69 | topImage@value(t).a ); 70 | @end 71 | 72 | @piece( GrainExtract ) 73 | //GrainExtract @counter(t) 74 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 75 | (outPs.colour0.xyz - topImage@value(t).xyz) + 0.5f, 76 | topImage@value(t).a ); 77 | @end 78 | 79 | @piece( GrainMerge ) 80 | //GrainMerge @counter(t) 81 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 82 | (outPs.colour0.xyz + topImage@value(t).xyz) - 0.5f, 83 | topImage@value(t).a ); 84 | @end 85 | 86 | @piece( Difference ) 87 | //Difference @counter(t) 88 | outPs.colour0.xyz = mix( outPs.colour0.xyz, 89 | abs(outPs.colour0.xyz - topImage@value(t).xyz), 90 | topImage@value(t).a ); 91 | @end 92 | 93 | @foreach( 16, n ) 94 | @property( uv_atlas@n ) @piece( atlasOffset@n )* atlasOffsets[@n].z + atlasOffsets[@n].xy @end @end @end 95 | 96 | // Get the indexes to the textureMaps[] array using template code. We had to add 1 97 | // to the actual value otherwise property( diffuse_map ) fails when the index is 0 98 | @foreach( diffuse_map, n ) 99 | @sub( diffuse_map@n_idx, diffuse_map@n, 1 ) @end 100 | 101 | @foreach( diffuse_map, n ) 102 | @property( !diffuse_map@n_reflection ) 103 | @property( diffuse_map@n_array ) 104 | @piece( TextureOrigin@n )textureMapsArray@value(diffuse_map@n_idx)@end 105 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 106 | @piece( SamplerUV@n )inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n ), material.diffuseIdx@n @end 107 | @end @property( !diffuse_map@n_array ) 108 | @piece( TextureOrigin@n )textureMaps@value(diffuse_map@n_idx)@end 109 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 110 | @piece( SamplerUV@n )inPs.uv@value( uv_diffuse@n ).@insertpiece( uv_diffuse_swizzle@n )@end 111 | @end 112 | @end @property( diffuse_map@n_reflection ) 113 | @property( diffuse_map@n_array ) 114 | @piece( TextureOrigin@n )textureMapsArray@value(diffuse_map@n_idx)@end 115 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 116 | @piece( SamplerUV@n )gl_FragCoord.xy * passBuf.invWindowSize.xy, material.diffuseIdx@n@end 117 | @end @property( !diffuse_map@n_array ) 118 | @piece( TextureOrigin@n )textureMaps@value(diffuse_map@n_idx)@end 119 | @piece( SamplerOrigin@n )samplerState@value(diffuse_map@n_idx)@end 120 | @piece( SamplerUV@n )gl_FragCoord.xy * passBuf.invWindowSize.xy@end 121 | @end 122 | @end 123 | @end 124 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Unlit/Metal/PixelShader_ps.metal: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | // START UNIFORM STRUCT DECLARATION 4 | @property( has_planar_reflections ) 5 | @insertpiece( PassStructDecl ) 6 | @end 7 | @property( !hlms_shadowcaster ) 8 | @insertpiece( MaterialStructDecl ) 9 | @end 10 | @insertpiece( custom_ps_uniformStructDeclaration ) 11 | // END UNIFORM STRUCT DECLARATION 12 | struct PS_INPUT 13 | { 14 | @insertpiece( VStoPS_block ) 15 | }; 16 | 17 | @property( !hlms_shadowcaster ) 18 | 19 | @padd( numSamplerStates, num_array_textures, num_textures ) 20 | @pset( samplerStateBind, 2 ) 21 | 22 | @property( diffuse )@piece( MultiplyDiffuseConst )* material.diffuse@end @end 23 | 24 | @insertpiece( DeclOutputType ) 25 | 26 | fragment @insertpiece( output_type ) main_metal 27 | ( 28 | PS_INPUT inPs [[stage_in]] 29 | // START UNIFORM DECLARATION 30 | @property( has_planar_reflections ) 31 | @insertpiece( PassDecl ) 32 | @end 33 | @property( !hlms_shadowcaster ) 34 | @insertpiece( MaterialDecl ) 35 | @end 36 | @insertpiece( custom_ps_uniformDeclaration ) 37 | // END UNIFORM DECLARATION 38 | @property( hlms_vpos ), float4 gl_FragCoord [[position]]@end 39 | 40 | @foreach( num_array_textures, n ) 41 | , texture2d_array textureMapsArray@n [[texture(@value(array_texture_bind@n))]]@end 42 | @foreach( num_textures, n ) 43 | , texture2d textureMaps@n [[texture(@value(texture_bind@n))]]@end 44 | @foreach( numSamplerStates, n ) 45 | , sampler samplerState@n [[sampler(@counter(samplerStateBind))]]@end 46 | ) 47 | { 48 | PS_OUTPUT outPs; 49 | 50 | @insertpiece( custom_ps_preExecution ) 51 | 52 | @property( diffuse_map || alpha_test || diffuse )Material material;@end 53 | 54 | @property( diffuse_map || alpha_test || diffuse ) 55 | material = materialArray[inPs.materialId]; 56 | @end 57 | 58 | @insertpiece( custom_ps_posMaterialLoad ) 59 | 60 | @property( !diffuse_map && !diffuse_map0 ) 61 | @property( hlms_colour && !diffuse_map ) outPs.colour0 = inPs.colour @insertpiece( MultiplyDiffuseConst );@end 62 | @property( !hlms_colour && !diffuse ) outPs.colour0 = float4(1, 1, 1, 1);@end 63 | @property( !hlms_colour && diffuse ) outPs.colour0 = material.diffuse;@end 64 | @end 65 | 66 | @property( diffuse_map )@property( diffuse_map0 ) 67 | //Load base image 68 | outPs.colour0 = @insertpiece( TextureOrigin0 ).sample( @insertpiece( SamplerOrigin0 ), @insertpiece( SamplerUV0 ) ).@insertpiece(diffuse_map0_tex_swizzle);@end 69 | 70 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 71 | float4 topImage@n = @insertpiece( TextureOrigin@n ).sample( @insertpiece( SamplerOrigin@n ), @insertpiece( SamplerUV@n ) ).@insertpiece(diffuse_map@n_tex_swizzle);@end @end 72 | 73 | @foreach( diffuse_map, n, 1 )@property( diffuse_map@n ) 74 | @insertpiece( blend_mode_idx@n )@end @end 75 | 76 | @property( hlms_colour )outPs.colour0 *= inPs.colour @insertpiece( MultiplyDiffuseConst );@end 77 | @property( !hlms_colour && diffuse )outPs.colour0 *= material.diffuse;@end 78 | @end 79 | 80 | @insertpiece( custom_ps_preLights ) 81 | 82 | @property( alpha_test ) 83 | if( material.alpha_test_threshold.x @insertpiece( alpha_test_cmp_func ) outPs.colour0.a ) 84 | discard;@end 85 | 86 | @insertpiece( custom_ps_posExecution ) 87 | 88 | @property( !hlms_render_depth_only ) 89 | return outPs; 90 | @end 91 | } 92 | @end @property( hlms_shadowcaster ) 93 | @property( hlms_render_depth_only ) 94 | @set( hlms_disable_stage, 1 ) 95 | @end 96 | @insertpiece( DeclShadowCasterMacros ) 97 | @property( hlms_shadowcaster_point ) 98 | @insertpiece( PassStructDecl ) 99 | @end 100 | 101 | @insertpiece( DeclOutputType ) 102 | fragment @insertpiece( output_type ) main_metal 103 | ( 104 | PS_INPUT inPs [[stage_in]] 105 | @property( hlms_vpos ), float4 gl_FragCoord [[position]]@end 106 | @property( hlms_shadowcaster_point ) 107 | @insertpiece( PassDecl ) 108 | @end 109 | ) 110 | { 111 | PS_OUTPUT outPs; 112 | @insertpiece( custom_ps_preExecution ) 113 | @insertpiece( DoShadowCastPS ) 114 | @insertpiece( custom_ps_posExecution ) 115 | 116 | return outPs; 117 | } 118 | @end 119 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Unlit/Metal/Structs_piece_vs_piece_ps.metal: -------------------------------------------------------------------------------- 1 | @piece( PassStructDecl ) 2 | //Uniforms that change per pass 3 | struct PassData 4 | { 5 | @insertpiece( PassInternalDecl ) 6 | };@end 7 | 8 | @piece( PassDecl ) 9 | , constant PassData &passBuf [[buffer(CONST_SLOT_START+0)]] 10 | @end 11 | 12 | @piece( MaterialStructDecl ) 13 | struct Material 14 | { 15 | float4 alpha_test_threshold; 16 | float4 diffuse; 17 | 18 | @foreach( 16, n ) 19 | ushort diffuseIdx@n;@end 20 | };@end 21 | 22 | @piece( MaterialDecl ) 23 | , constant Material *materialArray [[buffer(CONST_SLOT_START+1)]] 24 | @end 25 | 26 | 27 | @piece( InstanceDecl ) 28 | //Uniforms that change per Item/Entity 29 | //.x = 30 | //Contains the material's start index. 31 | // 32 | //.y = 33 | //shadowConstantBias. Send the bias directly to avoid an 34 | //unnecessary indirection during the shadow mapping pass. 35 | //Must be loaded with uintBitsToFloat 36 | // 37 | //.z = 38 | //Contains 0 or 1 to index into passBuf.viewProj[]. Only used 39 | //if hlms_identity_viewproj_dynamic is set. 40 | , constant uint4 *worldMaterialIdx [[buffer(CONST_SLOT_START+2)]] 41 | @end 42 | 43 | //Reset texcoord to 0 for every shader stage (since values are preserved). 44 | @pset( texcoord, 0 ) 45 | 46 | @piece( VStoPS_block ) 47 | @property( !hlms_shadowcaster ) 48 | ushort materialId [[flat]]; 49 | @property( hlms_colour )float4 colour;@end 50 | @foreach( out_uv_half_count, n ) 51 | float@value( out_uv_half_count@n ) uv@n;@end 52 | @end 53 | @property( hlms_shadowcaster ) 54 | @property( (!hlms_shadow_uses_depth_texture || exponential_shadow_maps) && !hlms_shadowcaster_point ) 55 | float depth; 56 | @end 57 | @property( hlms_shadowcaster_point ) 58 | float3 toCameraWS; 59 | @property( !exponential_shadow_maps ) 60 | float constBias [[flat]]; 61 | @end 62 | @end 63 | @end 64 | @insertpiece( custom_VStoPS ) 65 | @end 66 | -------------------------------------------------------------------------------- /testMedia/hlms/Hlms/Unlit/Metal/VertexShader_vs.metal: -------------------------------------------------------------------------------- 1 | @insertpiece( SetCrossPlatformSettings ) 2 | 3 | // START UNIFORM STRUCT DECLARATION 4 | @insertpiece( PassStructDecl ) 5 | @insertpiece( custom_vs_uniformStructDeclaration ) 6 | // END UNIFORM STRUCT DECLARATION 7 | 8 | struct VS_INPUT 9 | { 10 | float4 position [[attribute(VES_POSITION)]]; 11 | @property( hlms_colour ) float4 colour [[attribute(VES_DIFFUSE)]];@end 12 | @foreach( hlms_uv_count, n ) 13 | float@value( hlms_uv_count@n ) uv@n [[attribute(VES_TEXTURE_COORDINATES@n)]];@end 14 | @property( !iOS ) 15 | ushort drawId [[attribute(15)]]; 16 | @end 17 | @insertpiece( custom_vs_attributes ) 18 | }; 19 | 20 | struct PS_INPUT 21 | { 22 | @insertpiece( VStoPS_block ) 23 | float4 gl_Position [[position]]; 24 | @property( hlms_global_clip_distances ) 25 | float gl_ClipDistance0 [[clip_distance]]; 26 | @end 27 | }; 28 | 29 | @property( !hlms_identity_world ) 30 | @piece( worldViewProj )worldViewProj@end 31 | @end @property( hlms_identity_world ) 32 | @property( !hlms_identity_viewproj_dynamic ) 33 | @piece( worldViewProj )passBuf.viewProj[@value(hlms_identity_viewproj)]@end 34 | @end @property( hlms_identity_viewproj_dynamic ) 35 | @piece( worldViewProj )passBuf.viewProj[worldMaterialIdx[drawId].z]@end 36 | @end 37 | @end 38 | 39 | vertex PS_INPUT main_metal 40 | ( 41 | VS_INPUT input [[stage_in]] 42 | @property( iOS ) 43 | , ushort instanceId [[instance_id]] 44 | , constant ushort &baseInstance [[buffer(15)]] 45 | @end 46 | // START UNIFORM DECLARATION 47 | @insertpiece( PassDecl ) 48 | @insertpiece( InstanceDecl ) 49 | , device const float4x4 *worldMatBuf [[buffer(TEX_SLOT_START+0)]] 50 | @property( texture_matrix ), device const float4x4 *animationMatrixBuf [[buffer(TEX_SLOT_START+1)]]@end 51 | @insertpiece( custom_vs_uniformDeclaration ) 52 | // END UNIFORM DECLARATION 53 | ) 54 | { 55 | @property( iOS ) 56 | ushort drawId = baseInstance + instanceId; 57 | @end @property( !iOS ) 58 | ushort drawId = input.drawId; 59 | @end 60 | 61 | PS_INPUT outVs; 62 | @insertpiece( custom_vs_preExecution ) 63 | 64 | @property( !hlms_identity_world ) 65 | float4x4 worldViewProj; 66 | worldViewProj = worldMatBuf[drawId]; 67 | @end 68 | 69 | @property( !hlms_dual_paraboloid_mapping ) 70 | outVs.gl_Position = input.position * @insertpiece( worldViewProj ); 71 | @end 72 | 73 | @property( hlms_dual_paraboloid_mapping ) 74 | //Dual Paraboloid Mapping 75 | outVs.gl_Position.w = 1.0f; 76 | outVs.gl_Position.xyz = ( input.position * @insertpiece( worldViewProj ) ).xyz; 77 | float L = length( outVs.gl_Position.xyz ); 78 | outVs.gl_Position.z += 1.0f; 79 | outVs.gl_Position.xy /= outVs.gl_Position.z; 80 | outVs.gl_Position.z = (L - NearPlane) / (FarPlane - NearPlane); 81 | @end 82 | 83 | @property( !hlms_shadowcaster ) 84 | @property( hlms_colour ) outVs.colour = input.colour;@end 85 | 86 | @property( texture_matrix ) float4x4 textureMatrix;@end 87 | 88 | @foreach( out_uv_count, n ) 89 | @property( out_uv@n_texture_matrix ) 90 | textureMatrix = animationMatrixBuf[(worldMaterialIdx[drawId].x << 4u) + @value( out_uv@n_tex_unit )]; 91 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = (float4( input.uv@value( out_uv@n_source_uv ).xy, 0, 1 ) * textureMatrix).xy; 92 | @end @property( !out_uv@n_texture_matrix ) 93 | outVs.uv@value( out_uv@n_out_uv ).@insertpiece( out_uv@n_swizzle ) = input.uv@value( out_uv@n_source_uv ).xy; 94 | @end @end 95 | 96 | outVs.materialId = (ushort)worldMaterialIdx[drawId].x; 97 | 98 | @end 99 | 100 | @property( hlms_global_clip_distances || (hlms_shadowcaster && (exponential_shadow_maps || hlms_shadowcaster_point)) ) 101 | float3 worldPos = (outVs.gl_Position * passBuf.invViewProj).xyz; 102 | @end 103 | @insertpiece( DoShadowCasterVS ) 104 | 105 | @property( hlms_global_clip_distances ) 106 | outVs.gl_ClipDistance0 = dot( float4( worldPos.xyz, 1.0 ), passBuf.clipPlane0.xyzw ); 107 | @end 108 | 109 | @insertpiece( custom_vs_posExecution ) 110 | 111 | return outVs; 112 | } 113 | -------------------------------------------------------------------------------- /testMedia/knot.mesh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ybalrid/Qt5Ogre21/68d48f3c155b5e71c86ba869e43e1b28a8801f7e/testMedia/knot.mesh --------------------------------------------------------------------------------