mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 17:52:26 +02:00
Merge pull request #13951 from jherico/feature/spirv
Bug 15087: Updating our shader tool chain to enable SPIRV optimization
This commit is contained in:
commit
5416de9a02
181 changed files with 2418 additions and 1742 deletions
1
BUILD.md
1
BUILD.md
|
@ -9,6 +9,7 @@
|
|||
|
||||
- [cmake](https://cmake.org/download/): 3.9
|
||||
- [Qt](https://www.qt.io/download-open-source): 5.10.1
|
||||
- [Python](https://www.python.org/downloads/): 3.6 or higher
|
||||
- [OpenSSL](https://www.openssl.org/): Use the latest available 1.0 version (**NOT** 1.1) of OpenSSL to avoid security vulnerabilities.
|
||||
- [VHACD](https://github.com/virneo/v-hacd)(clone this repository)(Optional)
|
||||
|
||||
|
|
|
@ -40,6 +40,11 @@ Install build tools:
|
|||
sudo apt-get install cmake
|
||||
```
|
||||
|
||||
Install Python 3:
|
||||
```bash
|
||||
sudo apt-get install python3.6
|
||||
```
|
||||
|
||||
|
||||
### Get code and checkout the tag you need
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ Please read the [general build guide](BUILD.md) for information on dependencies
|
|||
|
||||
brew install cmake openssl qt
|
||||
|
||||
### Python 3
|
||||
|
||||
Download an install Python 3.6.6 or higher from [here](https://www.python.org/downloads/). Execute the `Update Shell Profile.command` script that is provided with the installer.
|
||||
|
||||
### OpenSSL
|
||||
|
||||
Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations.
|
||||
|
@ -28,7 +32,9 @@ Note that this uses the version from the homebrew formula at the time of this wr
|
|||
|
||||
If Xcode is your editor of choice, you can ask CMake to generate Xcode project files instead of Unix Makefiles.
|
||||
|
||||
cmake .. -GXcode
|
||||
cmake .. -G Xcode
|
||||
|
||||
If `cmake` complains about Python 3 being missing, you may need to update your CMake binary with command `brew upgrade cmake`, or by downloading and running the latest CMake installer, depending on how you originally instaled CMake
|
||||
|
||||
After running cmake, you will have the make files or Xcode project file necessary to build all of the components. Open the hifi.xcodeproj file, choose ALL_BUILD from the Product > Scheme menu (or target drop down), and click Run.
|
||||
|
||||
|
|
10
BUILD_WIN.md
10
BUILD_WIN.md
|
@ -5,11 +5,17 @@ Note: We are now using Visual Studio 2017 and Qt 5.10.1. If you are upgrading fr
|
|||
|
||||
Note: The prerequisites will require about 10 GB of space on your drive. You will also need a system with at least 8GB of main memory.
|
||||
|
||||
### Step 1. Visual Studio 2017
|
||||
### Step 1. Visual Studio 2017 & Python
|
||||
|
||||
If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/).
|
||||
|
||||
When selecting components, check "Desktop development with C++." Also on the right on the Summary toolbar, check "Windows 8.1 SDK and UCRT SDK" and "VC++ 2015.3 v140 toolset (x86,x64)".
|
||||
When selecting components, check "Desktop development with C++". Also on the right on the Summary toolbar, check "Windows 8.1 SDK and UCRT SDK" and "VC++ 2015.3 v140 toolset (x86,x64)". If you do not already have a python development environment installed, also check "Python Development" in this screen.
|
||||
|
||||
If you already have Visual Studio installed and need to add python, open the "Add or remove programs" control panel and find the "Microsoft Visual Studio Installer". Select it and click "Modify". In the installer, select "Modify" again, then check "Python Development" and allow the installer to apply the changes.
|
||||
|
||||
### Step 1a. Alternate Python
|
||||
|
||||
If you do not wish to use the Python installation bundled with Visual Studio, you can download the installer from [here](https://www.python.org/downloads/). Ensure you get version 3.6.6 or higher.
|
||||
|
||||
### Step 2. Installing CMake
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ android {
|
|||
'-DANDROID_STL=c++_shared',
|
||||
'-DQT_CMAKE_PREFIX_PATH=' + HIFI_ANDROID_PRECOMPILED + '/qt/lib/cmake',
|
||||
'-DNATIVE_SCRIBE=' + HIFI_ANDROID_PRECOMPILED + '/scribe' + EXEC_SUFFIX,
|
||||
'-DNATIVE_SHREFLECT=' + HIFI_ANDROID_PRECOMPILED + '/shreflect' + EXEC_SUFFIX,
|
||||
'-DHIFI_ANDROID_PRECOMPILED=' + HIFI_ANDROID_PRECOMPILED,
|
||||
'-DRELEASE_NUMBER=' + RELEASE_NUMBER,
|
||||
'-DRELEASE_TYPE=' + RELEASE_TYPE,
|
||||
|
|
|
@ -161,31 +161,19 @@ def packages = [
|
|||
]
|
||||
]
|
||||
|
||||
|
||||
def scribeLocalFile='scribe' + EXEC_SUFFIX
|
||||
def scribeFile='scribe_linux_x86_64'
|
||||
def scribeChecksum='ca4b904f52f4f993c29175ba96798fa6'
|
||||
def scribeVersion='u_iTrJDaE95i2abTPXOpPZckGBIim53G'
|
||||
|
||||
def shreflectLocalFile='shreflect' + EXEC_SUFFIX
|
||||
def shreflectFile='shreflect_linux_x86_64'
|
||||
def shreflectChecksum='d6094a8580066c0b6f4e80b5adfb1d98'
|
||||
def shreflectVersion='jnrpudh6fptIg6T2.Z6fgKP2ultAdKmE'
|
||||
def scribeChecksum='4635c28192724281d2367ce9e94380ab'
|
||||
def scribeVersion='mPAY_N846oZH1tPY1bwChB_hzqkiYyoC'
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_MAC)) {
|
||||
scribeFile = 'scribe_osx_x86_64'
|
||||
scribeChecksum='72db9d32d4e1e50add755570ac5eb749'
|
||||
scribeVersion='DAW0DmnjCRib4MD8x93bgc2Z2MpPojZC'
|
||||
shreflectFile='shreflect_osx_x86_64'
|
||||
shreflectChecksum='d613ef0703c21371fee93fd2e54b964f'
|
||||
shreflectVersion='.rYNzjSFq6WtWDnE5KIKRIAGyJtr__ad'
|
||||
scribeChecksum='1ead61c285d265eba9a5ef91ae3b7c26'
|
||||
scribeVersion='4TAXWdo9fviw60N2wUA8HNyQ9TabjZa3'
|
||||
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
scribeFile = 'scribe_win32_x86_64.exe'
|
||||
scribeChecksum='678e43d290c90fda670c6fefe038a06d'
|
||||
scribeVersion='PuullrA_bPlO9kXZRt8rLe536X1UI.m7'
|
||||
shreflectFile='shreflect_win32_x86_64.exe'
|
||||
shreflectChecksum='6f4a77b8cceb3f1bbc655132c3665060'
|
||||
shreflectVersion='iIyCyza1nelkbI7ihybF59bBlwrfAC3D'
|
||||
scribeChecksum='9c29a62595daf4844f95f6744d568c15'
|
||||
scribeVersion='DUoxjufeX8ZAIVRBKRczWTuZwT13enTv'
|
||||
}
|
||||
|
||||
def options = [
|
||||
|
@ -461,27 +449,11 @@ task fixScribePermissions(type: Exec, dependsOn: verifyScribe) {
|
|||
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + scribeLocalFile
|
||||
}
|
||||
|
||||
task downloadShreflect(type: Download) {
|
||||
src baseUrl + shreflectFile + '?versionId=' + shreflectVersion
|
||||
dest new File(baseFolder, shreflectLocalFile)
|
||||
onlyIfNewer true
|
||||
}
|
||||
|
||||
task verifyShreflect(type: Verify, dependsOn: downloadShreflect) {
|
||||
src new File(baseFolder, shreflectLocalFile);
|
||||
checksum shreflectChecksum
|
||||
}
|
||||
|
||||
task fixShreflectPermissions(type: Exec, dependsOn: verifyShreflect) {
|
||||
commandLine 'chmod', 'a+x', HIFI_ANDROID_PRECOMPILED + '/' + shreflectLocalFile
|
||||
}
|
||||
|
||||
task setupScribe(dependsOn: [verifyScribe, verifyShreflect]) { }
|
||||
task setupScribe(dependsOn: [verifyScribe]) { }
|
||||
|
||||
// On Windows, we don't need to set the executable bit, but on OSX and Unix we do
|
||||
if (!Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
setupScribe.dependsOn fixScribePermissions
|
||||
setupScribe.dependsOn fixShreflectPermissions
|
||||
}
|
||||
|
||||
task extractGvrBinaries(dependsOn: extractDependencies) {
|
||||
|
|
42
cmake/externals/glslang/CMakeLists.txt
vendored
Normal file
42
cmake/externals/glslang/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
set(EXTERNAL_NAME glslang)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/glslang/archive/7.8.2853.zip
|
||||
URL_MD5 4f93e3818528176c622c137fba05cbf8
|
||||
CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG>
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
# includes
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
list(APPEND INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include)
|
||||
#list(APPEND INCLUDE_DIRS ${INSTALL_DIR}/include)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIR ${INCLUDE_DIRS} CACHE PATH "List of glslang include directories")
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${${EXTERNAL_NAME_UPPER}_INCLUDE_DIR} CACHE PATH "List of glslang include directories")
|
||||
|
||||
|
||||
set(LIB_DIR ${SUFFIXED_INSTALL_DIR}/lib)
|
||||
list(APPEND LIB_NAMES glslang HLSL OGLCompiler OSDependent SPIRV SPVRemapper)
|
||||
include(SelectLibraryConfigurations)
|
||||
|
||||
foreach(BASE_LIB ${LIB_NAMES})
|
||||
string(TOUPPER ${BASE_LIB} BASE_LIB_UPPER)
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE "${LIB_DIR}/${BASE_LIB}.lib")
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "${LIB_DIR}/${BASE_LIB}d.lib")
|
||||
endforeach()
|
||||
|
||||
select_library_configurations(${EXTERNAL_NAME_UPPER})
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY ${${EXTERNAL_NAME_UPPER}_LIBRARY} CACHE FILEPATH "Location of glslang libraries")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Location of glslang libraries")
|
34
cmake/externals/spirv_binaries/CMakeLists.txt
vendored
Normal file
34
cmake/externals/spirv_binaries/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
set(EXTERNAL_NAME spirv_binaries)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-win32-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 3a83ef490bce248b1a4d6726a3e5893e)
|
||||
set(BIN_DIR "Bin")
|
||||
elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-macos-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 a57d37275b2c5db023ba8e84a63461ff)
|
||||
set(BIN_DIR "macOS/bin")
|
||||
else ()
|
||||
set(DOWNLOAD_URL https://public.highfidelity.com/dependencies/vulkan/vulkansdk-linux-x86_64-1.1.82.1.tar.gz)
|
||||
set(DOWNLOAD_MD5 5a7c9eeda8cee6b36724da7f7cbe5ec6)
|
||||
set(BIN_DIR "x86_64/bin")
|
||||
endif ()
|
||||
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL ${DOWNLOAD_URL}
|
||||
URL_MD5 ${DOWNLOAD_MD5}
|
||||
BUILD_COMMAND ""
|
||||
CONFIGURE_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD ON
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR)
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_DIR "${SOURCE_DIR}/${BIN_DIR}" CACHE FILEPATH "SPIRV binary tools location")
|
||||
|
35
cmake/externals/spirv_cross/CMakeLists.txt
vendored
Normal file
35
cmake/externals/spirv_cross/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
set(EXTERNAL_NAME spirv_cross)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Cross/archive/2018-08-07.zip
|
||||
URL_MD5 11198e4dc6a815ffbdb7a0a56d2d9261
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include CACHE PATH "List of Draco include directories")
|
||||
|
||||
if (UNIX)
|
||||
set(LIB_PREFIX "lib")
|
||||
set(LIB_EXT "a")
|
||||
elseif (WIN32)
|
||||
set(LIB_EXT "lib")
|
||||
endif ()
|
||||
|
||||
foreach(lib glsl msl cpp hlsl reflect util core)
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/spirv-cross-${lib}.${LIB_EXT})
|
||||
endforeach()
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Path to SPIRV-Cross libraries")
|
18
cmake/externals/spirv_headers/CMakeLists.txt
vendored
Normal file
18
cmake/externals/spirv_headers/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
set(EXTERNAL_NAME spirv_headers)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Headers/archive/2c512180ca03b5d4f56283efc85745775b45fdc4.zip
|
||||
URL_MD5 83e652221b5f21d5fdb61c45f5b4d9f9
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(${EXTERNAL_NAME_UPPER}_ROOT ${INSTALL_DIR} CACHE PATH "List of include directories")
|
33
cmake/externals/spirv_tools/CMakeLists.txt
vendored
Normal file
33
cmake/externals/spirv_tools/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
set(EXTERNAL_NAME spirv_tools)
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL https://github.com/KhronosGroup/SPIRV-Tools/archive/v2018.4.zip
|
||||
URL_MD5 7a7c69cf6ff0318910b4bfbdf30bcfc9
|
||||
CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DSPIRV-Headers_SOURCE_DIR=${SPIRV_HEADERS_ROOT} -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>-$<CONFIG> ${EXTRA_CMAKE_FLAGS}
|
||||
LOG_DOWNLOAD 1
|
||||
LOG_CONFIGURE 1
|
||||
LOG_BUILD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
set(SUFFIXED_INSTALL_DIR "${INSTALL_DIR}-$<CONFIG>")
|
||||
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SUFFIXED_INSTALL_DIR}/include CACHE PATH "List of SPIRV-Tools include directories")
|
||||
|
||||
if (UNIX)
|
||||
set(LIB_PREFIX "lib")
|
||||
set(LIB_EXT "a")
|
||||
elseif (WIN32)
|
||||
set(LIB_EXT "lib")
|
||||
endif ()
|
||||
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools-opt.${LIB_EXT})
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools-link.${LIB_EXT})
|
||||
list(APPEND ${EXTERNAL_NAME_UPPER}_LIBRARIES ${SUFFIXED_INSTALL_DIR}/lib/SPIRV-Tools.${LIB_EXT})
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${${EXTERNAL_NAME_UPPER}_LIBRARIES} CACHE FILEPATH "Path to SPIRV-Tool libraries")
|
|
@ -10,6 +10,10 @@ if (POLICY CMP0042)
|
|||
cmake_policy(SET CMP0042 NEW)
|
||||
endif ()
|
||||
|
||||
if (POLICY CMP0074)
|
||||
cmake_policy(SET CMP0074 OLD)
|
||||
endif ()
|
||||
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
|
||||
# Hide automoc folders (for IDEs)
|
||||
|
|
|
@ -8,34 +8,132 @@
|
|||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
|
||||
# FIXME use the built tools
|
||||
|
||||
macro(AUTOSCRIBE_APPEND_QRC)
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${ARGV0}\">${ARGV1}</file>\n")
|
||||
endmacro()
|
||||
|
||||
set(VULKAN_DIR $ENV{VULKAN_SDK})
|
||||
set(GLSLANG_EXEC "${VULKAN_DIR}/Bin/glslangValidator.exe")
|
||||
set(SPIRV_CROSS_EXEC "${VULKAN_DIR}/Bin/spirv-cross.exe")
|
||||
set(SPIRV_OPT_EXEC "${VULKAN_DIR}/Bin/spirv-opt.exe")
|
||||
set(GLSLC_EXEC "${VULKAN_DIR}/Bin/glslc.exe")
|
||||
set(SCRIBE_EXEC "D:/scribe.exe")
|
||||
|
||||
macro(AUTOSCRIBE_PLATFORM_SHADER)
|
||||
set(AUTOSCRIBE_PLATFORM_PATH "${ARGV0}")
|
||||
string(REGEX MATCH "([0-9]+(es)?)(/stereo)?" PLATFORM_PATH_REGEX ${AUTOSCRIBE_PLATFORM_PATH})
|
||||
set(AUTOSCRIBE_DIALECT "${CMAKE_MATCH_1}")
|
||||
if (CMAKE_MATCH_3)
|
||||
set(AUTOSCRIBE_VARIANT "stereo")
|
||||
else()
|
||||
set(AUTOSCRIBE_VARIANT "mono")
|
||||
endif()
|
||||
string(REGEX REPLACE "/" "\\\\" SOURCE_GROUP_PATH ${AUTOSCRIBE_PLATFORM_PATH})
|
||||
set(SOURCE_GROUP_PATH "${SHADER_LIB}\\${SOURCE_GROUP_PATH}")
|
||||
set(AUTOSCRIBE_DIALECT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_DIALECT}/header.glsl")
|
||||
set(AUTOSCRIBE_VARIANT_HEADER "${AUTOSCRIBE_HEADER_DIR}/${AUTOSCRIBE_VARIANT}.glsl")
|
||||
|
||||
set(AUTOSCRIBE_OUTPUT_FILE "${SHADERS_DIR}/${SHADER_LIB}/${AUTOSCRIBE_PLATFORM_PATH}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/scribe" "${AUTOSCRIBE_OUTPUT_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_OUTPUT_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SCRIBED_SHADERS ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_FILE "${AUTOSCRIBE_OUTPUT_FILE}.spv")
|
||||
# don't add unoptimized spirv to the QRC
|
||||
#AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv_unopt" "${AUTOSCRIBE_SPIRV_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_OPT_FILE "${AUTOSCRIBE_OUTPUT_FILE}.opt.spv")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/spirv" "${AUTOSCRIBE_SPIRV_OPT_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_OPT_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_OPT_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_OPT_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_GLSL_FILE "${AUTOSCRIBE_OUTPUT_FILE}.glsl")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/glsl" "${AUTOSCRIBE_SPIRV_GLSL_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_GLSL_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_GLSL_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND SPIRV_SHADERS ${AUTOSCRIBE_SPIRV_GLSL_FILE})
|
||||
|
||||
set(AUTOSCRIBE_SPIRV_JSON_FILE "${AUTOSCRIBE_OUTPUT_FILE}.json")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/${AUTOSCRIBE_PLATFORM_PATH}/json" "${AUTOSCRIBE_SPIRV_JSON_FILE}")
|
||||
source_group(${SOURCE_GROUP_PATH} FILES ${AUTOSCRIBE_SPIRV_JSON_FILE})
|
||||
set_property(SOURCE ${AUTOSCRIBE_SPIRV_JSON_FILE} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND REFLECTED_SHADERS ${AUTOSCRIBE_SPIRV_JSON_FILE})
|
||||
|
||||
unset(SHADER_GEN_LINE)
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_DIALECT})
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_VARIANT})
|
||||
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${SHADER_FILE})
|
||||
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
|
||||
file(RELATIVE_PATH TEMP_PATH ${CMAKE_SOURCE_DIR} ${AUTOSCRIBE_OUTPUT_FILE})
|
||||
list(APPEND SHADER_GEN_LINE ${TEMP_PATH})
|
||||
list(APPEND SHADER_GEN_LINE ${AUTOSCRIBE_SHADER_SEEN_LIBS})
|
||||
string(CONCAT AUTOSCRIBE_SHADERGEN_COMMANDS "${AUTOSCRIBE_SHADERGEN_COMMANDS}" "${SHADER_GEN_LINE}\n")
|
||||
|
||||
# # FIXME need better mechanism for determining the include files
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_OUTPUT_FILE}
|
||||
# COMMAND ${SCRIBE_COMMAND} ${SHADER_FILE} ${SCRIBE_ARGS} -o ${AUTOSCRIBE_OUTPUT_FILE} -h ${AUTOSCRIBE_DIALECT_HEADER} -h ${AUTOSCRIBE_VARIANT_HEADER}
|
||||
# DEPENDS ${SCRIBE_COMMAND} ${SHADER_FILE} ${AUTOSCRIBE_DIALECT_HEADER} ${AUTOSCRIBE_VARIANT_HEADER})
|
||||
|
||||
# # Generate the spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_FILE}
|
||||
# COMMAND ${GLSLANG_EXEC} -V110 -o ${AUTOSCRIBE_SPIRV_FILE} ${AUTOSCRIBE_OUTPUT_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_OUTPUT_FILE} ${GLSLANG_EXEC})
|
||||
|
||||
# # Generate the optimized spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_OPT_FILE}
|
||||
# COMMAND ${SPIRV_OPT_EXEC} -O ${AUTOSCRIBE_SPIRV_FILE} -o ${AUTOSCRIBE_SPIRV_OPT_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_FILE} ${SPIRV_OPT_EXEC})
|
||||
|
||||
# # Generate the optimized GLSL file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_GLSL_FILE}
|
||||
# COMMAND ${SPIRV_CROSS_EXEC} ${SPIRV_CROSS_ARGS} ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_GLSL_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
|
||||
|
||||
# # Generate the optimized spirv file
|
||||
# add_custom_command(
|
||||
# OUTPUT ${AUTOSCRIBE_SPIRV_JSON_FILE}
|
||||
# COMMAND ${SPIRV_CROSS_EXEC} --reflect json ${AUTOSCRIBE_SPIRV_OPT_FILE} --output ${AUTOSCRIBE_SPIRV_JSON_FILE}
|
||||
# DEPENDS ${AUTOSCRIBE_SPIRV_OPT_FILE} ${SPIRV_CROSS_EXEC})
|
||||
endmacro()
|
||||
|
||||
macro(AUTOSCRIBE_SHADER)
|
||||
#
|
||||
# Set the include paths
|
||||
#
|
||||
# FIXME base the include paths off of output from the scribe tool,
|
||||
# instead of treating every previously seen shader as a possible header
|
||||
unset(SHADER_INCLUDE_FILES)
|
||||
# Grab include files
|
||||
foreach(includeFile ${ARGN})
|
||||
list(APPEND SHADER_INCLUDE_FILES ${includeFile})
|
||||
endforeach()
|
||||
|
||||
foreach(SHADER_INCLUDE ${SHADER_INCLUDE_FILES})
|
||||
get_filename_component(INCLUDE_DIR ${SHADER_INCLUDE} PATH)
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${INCLUDE_DIR})
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
#Extract the unique include shader paths
|
||||
set(INCLUDES ${HIFI_LIBRARIES_SHADER_INCLUDE_FILES})
|
||||
foreach(EXTRA_SHADER_INCLUDE ${INCLUDES})
|
||||
list(APPEND SHADER_INCLUDES_PATHS ${EXTRA_SHADER_INCLUDE})
|
||||
endforeach()
|
||||
|
||||
list(REMOVE_DUPLICATES SHADER_INCLUDES_PATHS)
|
||||
#message(ready for includes ${SHADER_INCLUDES_PATHS})
|
||||
|
||||
# make the scribe include arguments
|
||||
set(SCRIBE_INCLUDES)
|
||||
unset(SCRIBE_INCLUDES)
|
||||
foreach(INCLUDE_PATH ${SHADER_INCLUDES_PATHS})
|
||||
set(SCRIBE_INCLUDES ${SCRIBE_INCLUDES} -I ${INCLUDE_PATH}/)
|
||||
endforeach()
|
||||
|
||||
#
|
||||
# Figure out the various output names
|
||||
#
|
||||
# Define the final name of the generated shader file
|
||||
get_filename_component(SHADER_NAME ${SHADER_FILE} NAME_WE)
|
||||
get_filename_component(SHADER_EXT ${SHADER_FILE} EXT)
|
||||
|
@ -46,38 +144,36 @@ macro(AUTOSCRIBE_SHADER)
|
|||
elseif(${SHADER_EXT} STREQUAL .slg)
|
||||
set(SHADER_TYPE geom)
|
||||
endif()
|
||||
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
|
||||
set(SHADER_TARGET "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
file(TO_CMAKE_PATH "${SHADER_TARGET}" COMPILED_SHADER)
|
||||
set(REFLECTED_SHADER "${COMPILED_SHADER}.json")
|
||||
|
||||
set(SCRIBE_ARGS -T ${SHADER_TYPE} -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE})
|
||||
set(SCRIBE_ARGS -D GLPROFILE ${GLPROFILE} -T ${SHADER_TYPE} ${SCRIBE_INCLUDES} )
|
||||
|
||||
# Generate the frag/vert file
|
||||
add_custom_command(
|
||||
OUTPUT ${SHADER_TARGET}
|
||||
COMMAND ${SCRIBE_COMMAND} ${SCRIBE_ARGS}
|
||||
DEPENDS ${SHADER_FILE} ${SCRIBE_COMMAND} ${SHADER_INCLUDE_FILES})
|
||||
# SHADER_SCRIBED -> the output of scribe
|
||||
set(SHADER_SCRIBED "${SHADERS_DIR}/${SHADER_LIB}/${SHADER_NAME}.${SHADER_TYPE}")
|
||||
|
||||
# Generate the json reflection
|
||||
# FIXME move to spirv-cross for this task after we have spirv compatible shaders
|
||||
add_custom_command(
|
||||
OUTPUT ${REFLECTED_SHADER}
|
||||
COMMAND ${SHREFLECT_COMMAND} ${COMPILED_SHADER}
|
||||
DEPENDS ${SHREFLECT_DEPENDENCY} ${COMPILED_SHADER})
|
||||
# SHADER_NAME_FILE -> a file containing the shader name and extension (useful for debugging and for
|
||||
# determining the type of shader from the filename)
|
||||
set(SHADER_NAME_FILE "${SHADER_SCRIBED}.name")
|
||||
file(TO_CMAKE_PATH "${SHADER_SCRIBED}" SHADER_SCRIBED)
|
||||
file(WRITE "${SHADER_SCRIBED}.name" "${SHADER_NAME}.${SHADER_TYPE}")
|
||||
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/name" "${SHADER_NAME_FILE}")
|
||||
|
||||
#output the generated file name
|
||||
source_group("Compiled/${SHADER_LIB}" FILES ${COMPILED_SHADER})
|
||||
set_property(SOURCE ${COMPILED_SHADER} PROPERTY SKIP_AUTOMOC ON)
|
||||
list(APPEND COMPILED_SHADERS ${COMPILED_SHADER})
|
||||
if (USE_GLES)
|
||||
set(SPIRV_CROSS_ARGS --version 310es)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("310es")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("310es/stereo")
|
||||
else()
|
||||
set(SPIRV_CROSS_ARGS --version 410 --no-420pack-extension)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("410")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("410/stereo")
|
||||
if (NOT APPLE)
|
||||
set(SPIRV_CROSS_ARGS --version 450)
|
||||
AUTOSCRIBE_PLATFORM_SHADER("450")
|
||||
AUTOSCRIBE_PLATFORM_SHADER("450/stereo")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
source_group("Reflected/${SHADER_LIB}" FILES ${REFLECTED_SHADER})
|
||||
list(APPEND REFLECTED_SHADERS ${REFLECTED_SHADER})
|
||||
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}\">${COMPILED_SHADER}</file>\n")
|
||||
string(CONCAT SHADER_QRC "${SHADER_QRC}" "<file alias=\"${SHADER_COUNT}_reflection\">${REFLECTED_SHADER}</file>\n")
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "${SHADER_NAME} = ${SHADER_COUNT},\n")
|
||||
|
||||
string(CONCAT SHADER_SHADERS_ARRAY "${SHADER_SHADERS_ARRAY}" "${SHADER_COUNT},\n")
|
||||
MATH(EXPR SHADER_COUNT "${SHADER_COUNT}+1")
|
||||
endmacro()
|
||||
|
||||
|
@ -86,6 +182,8 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
|||
message(FATAL_ERROR "AUTOSCRIBE_SHADER_LIB can only be used by the shaders library")
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${SHADERS_DIR}/${SHADER_LIB}")
|
||||
|
||||
list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES "${CMAKE_SOURCE_DIR}/libraries/${SHADER_LIB}/src")
|
||||
string(REGEX REPLACE "[-]" "_" SHADER_NAMESPACE ${SHADER_LIB})
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "namespace ${SHADER_NAMESPACE} {\n")
|
||||
|
@ -165,66 +263,103 @@ macro(AUTOSCRIBE_SHADER_LIB)
|
|||
|
||||
# Finish the shader enums
|
||||
string(CONCAT SHADER_ENUMS "${SHADER_ENUMS}" "} // namespace ${SHADER_NAMESPACE}\n")
|
||||
#file(RELATIVE_PATH RELATIVE_LIBRARY_DIR_PATH ${CMAKE_CURRENT_SOURCE_DIR} "${HIFI_LIBRARY_DIR}")
|
||||
#foreach(HIFI_LIBRARY ${ARGN})
|
||||
#list(APPEND HIFI_LIBRARIES_SHADER_INCLUDE_FILES ${HIFI_LIBRARY_DIR}/${HIFI_LIBRARY}/src)
|
||||
#endforeach()
|
||||
#endif()
|
||||
endmacro()
|
||||
|
||||
macro(AUTOSCRIBE_SHADER_LIBS)
|
||||
set(SCRIBE_COMMAND scribe)
|
||||
set(SHREFLECT_COMMAND shreflect)
|
||||
set(SHREFLECT_DEPENDENCY shreflect)
|
||||
|
||||
# Target dependant Custom rule on the SHADER_FILE
|
||||
if (ANDROID)
|
||||
set(GLPROFILE LINUX_GL)
|
||||
set(SCRIBE_COMMAND ${NATIVE_SCRIBE})
|
||||
set(SHREFLECT_COMMAND ${NATIVE_SHREFLECT})
|
||||
unset(SHREFLECT_DEPENDENCY)
|
||||
else()
|
||||
if (APPLE)
|
||||
set(GLPROFILE MAC_GL)
|
||||
elseif(UNIX)
|
||||
set(GLPROFILE LINUX_GL)
|
||||
else()
|
||||
set(GLPROFILE PC_GL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Shader processing start")
|
||||
set(AUTOSCRIBE_HEADER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/headers)
|
||||
# Start the shader IDs
|
||||
set(SHADER_COUNT 1)
|
||||
set(SHADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/shaders")
|
||||
set(SHADER_ENUMS "")
|
||||
file(MAKE_DIRECTORY ${SHADERS_DIR})
|
||||
set(SHADER_ENUMS "")
|
||||
set(SHADER_COUNT 1)
|
||||
|
||||
#
|
||||
# Scribe generation & program defintiion
|
||||
#
|
||||
foreach(SHADER_LIB ${ARGN})
|
||||
list(APPEND AUTOSCRIBE_SHADER_SEEN_LIBS ${SHADER_LIB})
|
||||
AUTOSCRIBE_SHADER_LIB(${SHADER_LIB})
|
||||
endforeach()
|
||||
|
||||
# Generate the library files
|
||||
configure_file(
|
||||
ShaderEnums.cpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
|
||||
configure_file(
|
||||
ShaderEnums.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h)
|
||||
configure_file(
|
||||
shaders.qrc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h)
|
||||
|
||||
set(AUTOSCRIBE_SHADER_LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.h;${CMAKE_CURRENT_BINARY_DIR}/shaders/ShaderEnums.cpp")
|
||||
set(QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
configure_file(shaders.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
list(APPEND QT_RESOURCES_FILE ${CMAKE_CURRENT_BINARY_DIR}/shaders.qrc)
|
||||
|
||||
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
|
||||
list(APPEND AUTOSCRIBE_SHADER_HEADERS ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
|
||||
source_group("Shader Headers" FILES ${AUTOSCRIBE_HEADER_DIR}/mono.glsl ${AUTOSCRIBE_HEADER_DIR}/stereo.glsl)
|
||||
source_group("Shader Headers\\450" FILES ${AUTOSCRIBE_HEADER_DIR}/450/header.glsl)
|
||||
source_group("Shader Headers\\410" FILES ${AUTOSCRIBE_HEADER_DIR}/410/header.glsl)
|
||||
source_group("Shader Headers\\310es" FILES ${AUTOSCRIBE_HEADER_DIR}/310es/header.glsl)
|
||||
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${AUTOSCRIBE_SHADER_HEADERS})
|
||||
list(APPEND AUTOSCRIBE_SHADER_LIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.h ${CMAKE_CURRENT_BINARY_DIR}/ShaderEnums.cpp)
|
||||
|
||||
# Write the shadergen command list
|
||||
set(AUTOSCRIBE_SHADERGEN_COMMANDS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shadergen.txt)
|
||||
file(WRITE ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE} "${AUTOSCRIBE_SHADERGEN_COMMANDS}")
|
||||
|
||||
# grab the SPIRV binaries we require
|
||||
# note we don't use the normal ADD_DEPENDENCY_EXTERNAL_PROJECTS macro because only a custom command
|
||||
# depends on these, not any of our build artifacts, so there's no valid target for the add_dependencies
|
||||
# call in ADD_DEPENDENCY_EXTERNAL_PROJECTS to use
|
||||
add_subdirectory(${EXTERNAL_PROJECT_DIR}/spirv_binaries ${EXTERNALS_BINARY_DIR}/spirv_binaries)
|
||||
|
||||
target_python()
|
||||
|
||||
# A custom python script which will generate
|
||||
if (ANDROID)
|
||||
add_custom_command(
|
||||
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
||||
COMMENT "Generating/updating shaders"
|
||||
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
|
||||
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
|
||||
--spirv-binaries ${SPIRV_BINARIES_DIR}
|
||||
--scribe ${NATIVE_SCRIBE}
|
||||
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||
--source-dir ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS}
|
||||
COMMENT "Generating/updating shaders"
|
||||
COMMAND ${HIFI_PYTHON_EXEC} ${CMAKE_SOURCE_DIR}/tools/shadergen.py
|
||||
--commands ${AUTOSCRIBE_SHADERGEN_COMMANDS_FILE}
|
||||
--spirv-binaries ${SPIRV_BINARIES_DIR}
|
||||
--scribe $<TARGET_FILE:scribe>
|
||||
--build-dir ${CMAKE_CURRENT_BINARY_DIR}
|
||||
--source-dir ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS ${AUTOSCRIBE_SHADER_HEADERS} scribe spirv_binaries ${CMAKE_SOURCE_DIR}/tools/shadergen.py ${ALL_SCRIBE_SHADERS})
|
||||
endif()
|
||||
|
||||
add_custom_target(shadergen DEPENDS ${SCRIBED_SHADERS} ${SPIRV_SHADERS} ${REFLECTED_SHADERS})
|
||||
set_target_properties(shadergen PROPERTIES FOLDER "Shaders")
|
||||
|
||||
# Custom targets required to force generation of the shaders via scribe
|
||||
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS})
|
||||
add_custom_target(compiled_shaders SOURCES ${COMPILED_SHADERS})
|
||||
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
|
||||
add_custom_target(scribe_shaders SOURCES ${ALL_SCRIBE_SHADERS} ${AUTOSCRIBE_SHADER_HEADERS})
|
||||
set_target_properties(scribe_shaders PROPERTIES FOLDER "Shaders")
|
||||
set_target_properties(compiled_shaders PROPERTIES FOLDER "Shaders")
|
||||
|
||||
add_custom_target(scribed_shaders SOURCES ${SCRIBED_SHADERS})
|
||||
set_target_properties(scribed_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(scribed_shaders shadergen)
|
||||
|
||||
add_custom_target(spirv_shaders SOURCES ${SPIRV_SHADERS})
|
||||
set_target_properties(spirv_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(spirv_shaders shadergen)
|
||||
|
||||
add_custom_target(reflected_shaders SOURCES ${REFLECTED_SHADERS})
|
||||
set_target_properties(reflected_shaders PROPERTIES FOLDER "Shaders")
|
||||
add_dependencies(reflected_shaders shadergen)
|
||||
|
||||
message(STATUS "Shader processing end")
|
||||
endmacro()
|
||||
|
||||
|
||||
|
|
22
cmake/macros/TargetPython.cmake
Normal file
22
cmake/macros/TargetPython.cmake
Normal file
|
@ -0,0 +1,22 @@
|
|||
macro(TARGET_PYTHON)
|
||||
if (NOT HIFI_PYTHON_EXEC)
|
||||
# Find the python interpreter
|
||||
if (CAME_VERSION VERSION_LESS 3.12)
|
||||
# this logic is deprecated in CMake after 3.12
|
||||
# FIXME eventually we should make 3.12 the min cmake verion and just use the Python3 find_package path
|
||||
set(Python_ADDITIONAL_VERSIONS 3)
|
||||
find_package(PythonInterp)
|
||||
set(HIFI_PYTHON_VERSION ${PYTHON_VERSION_STRING})
|
||||
set(HIFI_PYTHON_EXEC ${PYTHON_EXECUTABLE})
|
||||
else()
|
||||
# the new hotness
|
||||
find_package(Python3)
|
||||
set(HIFI_PYTHON_VERSION ${Python3_VERSION})
|
||||
set(HIFI_PYTHON_EXEC ${Python3_EXECUTABLE})
|
||||
endif()
|
||||
|
||||
if ((NOT HIFI_PYTHON_EXEC) OR (HIFI_PYTHON_VERSION VERSION_LESS 3.5))
|
||||
message(FATAL_ERROR "Unable to locate Python interpreter 3.5 or higher")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
15
cmake/macros/TargetSPIRV.cmake
Normal file
15
cmake/macros/TargetSPIRV.cmake
Normal file
|
@ -0,0 +1,15 @@
|
|||
macro(TARGET_SPIRV)
|
||||
add_dependency_external_projects(spirv_cross)
|
||||
target_link_libraries(${TARGET_NAME} ${SPIRV_CROSS_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SPIRV_CROSS_INCLUDE_DIRS})
|
||||
|
||||
# spirv-tools requires spirv-headers
|
||||
add_dependency_external_projects(spirv_headers)
|
||||
add_dependency_external_projects(spirv_tools)
|
||||
target_link_libraries(${TARGET_NAME} ${SPIRV_TOOLS_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${SPIRV_TOOLS_INCLUDE_DIRS})
|
||||
|
||||
add_dependency_external_projects(glslang)
|
||||
target_link_libraries(${TARGET_NAME} ${GLSLANG_LIBRARIES})
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${GLSLANG_INCLUDE_DIRS})
|
||||
endmacro()
|
10
cmake/macros/TargetSpirvBinaries.cmake
Normal file
10
cmake/macros/TargetSpirvBinaries.cmake
Normal file
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Created by Bradley Austin Davis on 2016/02/16
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_SPIRV_BINARIES)
|
||||
add_dependency_external_projects(spirv_binaries)
|
||||
endmacro()
|
||||
|
19
cmake/macros/TargetVulkan.cmake
Normal file
19
cmake/macros/TargetVulkan.cmake
Normal file
|
@ -0,0 +1,19 @@
|
|||
#
|
||||
# Created by Bradley Austin Davis on 2016/02/16
|
||||
#
|
||||
# Distributed under the Apache License, Version 2.0.
|
||||
# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
#
|
||||
macro(TARGET_VULKAN)
|
||||
find_package(Vulkan)
|
||||
|
||||
if (Vulkan_FOUND)
|
||||
add_definitions(-DHAVE_VULKAN)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${Vulkan_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${Vulkan_LIBRARIES})
|
||||
|
||||
add_dependency_external_projects(glslang)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${GLSLANG_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${GLSLANG_LIBRARIES})
|
||||
endif()
|
||||
endmacro()
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME avatars-renderer)
|
||||
setup_hifi_library(Network Script)
|
||||
link_hifi_libraries(shared gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
|
||||
link_hifi_libraries(shared shaders gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
|
||||
include_hifi_library_headers(avatars)
|
||||
include_hifi_library_headers(networking)
|
||||
include_hifi_library_headers(fbx)
|
||||
|
|
|
@ -2,11 +2,11 @@ struct TextureData {
|
|||
ivec2 textureSize;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform textureDataBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform textureDataBuffer {
|
||||
TextureData textureData;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
|
|
|
@ -363,56 +363,35 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
}
|
||||
|
||||
if (!_presentPipeline) {
|
||||
gpu::StatePointer blendState = gpu::StatePointer(new gpu::State());
|
||||
blendState->setDepthTest(gpu::State::DepthTest(false));
|
||||
blendState->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State());
|
||||
scissorState->setDepthTest(gpu::State::DepthTest(false));
|
||||
scissorState->setScissorEnable(true);
|
||||
|
||||
{
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::drawTexture);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setScissorEnable(true);
|
||||
_simplePipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
|
||||
_simplePipeline = gpu::Pipeline::create(program, scissorState);
|
||||
_hudPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
|
||||
{
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setScissorEnable(true);
|
||||
_presentPipeline = gpu::Pipeline::create(program, state);
|
||||
_presentPipeline = gpu::Pipeline::create(program, scissorState);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_hudPipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
|
||||
_mirrorHUDPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawUnitQuadTexcoord);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTextureMirroredX);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_mirrorHUDPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
{
|
||||
auto vs = gpu::Shader::createVertex(shader::gpu::vertex::DrawTransformUnitQuad);
|
||||
auto ps = gpu::Shader::createPixel(shader::gpu::fragment::DrawTexture);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
state->setDepthTest(gpu::State::DepthTest(false));
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_cursorPipeline = gpu::Pipeline::create(program, state);
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture);
|
||||
_cursorPipeline = gpu::Pipeline::create(program, blendState);
|
||||
}
|
||||
}
|
||||
updateCompositeFramebuffer();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// OpenGLDisplayPlugin_present.frag
|
||||
|
||||
layout(binding = 0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location = 0) in vec2 varTexCoord0;
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
|
||||
layout(location = 0) out vec4 outFragColor;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
float sRGBFloatToLinear(float value) {
|
||||
const float SRGB_ELBOW = 0.04045;
|
||||
|
|
|
@ -30,12 +30,14 @@ using namespace render::entities;
|
|||
// is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down.
|
||||
static const float SPHERE_ENTITY_SCALE = 0.5f;
|
||||
|
||||
static_assert(shader::render_utils::program::simple != 0, "Validate simple program exists");
|
||||
static_assert(shader::render_utils::program::simple_transparent != 0, "Validate simple transparent program exists");
|
||||
|
||||
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
|
||||
_procedural._vertexSource = gpu::Shader::getVertexShaderSource(shader::render_utils::vertex::simple);
|
||||
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
|
||||
_procedural._opaquefragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple);
|
||||
_procedural._transparentfragmentSource = gpu::Shader::getFragmentShaderSource(shader::render_utils::fragment::simple_transparent);
|
||||
_procedural._opaqueFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple);
|
||||
_procedural._transparentFragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::simple_transparent);
|
||||
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
|
||||
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=0) in vec3 interpolatedNormal;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<$declareFadeFragment()$>
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=0) uniform sampler2D originalTexture;
|
||||
LAYOUT(binding=0) uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=0) in vec3 interpolatedNormal;
|
||||
|
@ -30,7 +30,7 @@ struct PolyLineUniforms {
|
|||
vec3 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyLineBuffer {
|
||||
LAYOUT(binding=0) uniform polyLineBuffer {
|
||||
PolyLineUniforms polyline;
|
||||
};
|
||||
|
||||
|
|
|
@ -20,15 +20,15 @@ layout(location=RENDER_UTILS_ATTR_NORMAL_MS) in vec3 _normal;
|
|||
layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _position;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
|
||||
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
|
||||
struct PolyvoxParams {
|
||||
vec4 voxelVolumeSize;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyvoxParamsBuffer {
|
||||
LAYOUT(binding=0) uniform polyvoxParamsBuffer {
|
||||
PolyvoxParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec4 _position;
|
|||
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition;
|
||||
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _worldFadePosition;
|
||||
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap;
|
||||
LAYOUT(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap;
|
||||
|
||||
struct PolyvoxParams {
|
||||
vec4 voxelVolumeSize;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform polyvoxParamsBuffer {
|
||||
LAYOUT(binding=0) uniform polyvoxParamsBuffer {
|
||||
PolyvoxParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec4 varColor;
|
||||
layout(location=1) in vec2 varTexcoord;
|
||||
|
|
|
@ -43,7 +43,7 @@ struct ParticleUniforms {
|
|||
vec2 spare;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform particleBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform particleBuffer {
|
||||
ParticleUniforms particle;
|
||||
};
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@ include_hifi_library_headers(fbx)
|
|||
include_hifi_library_headers(gpu)
|
||||
include_hifi_library_headers(image)
|
||||
include_hifi_library_headers(ktx)
|
||||
link_hifi_libraries(shared networking octree avatars graphics model-networking)
|
||||
link_hifi_libraries(shared shaders networking octree avatars graphics model-networking)
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME gpu-gl-common)
|
||||
setup_hifi_library(Concurrent)
|
||||
link_hifi_libraries(shared gl gpu)
|
||||
link_hifi_libraries(shared gl gpu shaders)
|
||||
GroupSources("src")
|
||||
target_opengl()
|
||||
|
||||
|
|
|
@ -643,18 +643,21 @@ protected:
|
|||
}
|
||||
} _pipeline;
|
||||
|
||||
// Backend dependant compilation of the shader
|
||||
// Backend dependent compilation of the shader
|
||||
virtual void postLinkProgram(ShaderObject& programObject, const Shader& program) const;
|
||||
virtual GLShader* compileBackendProgram(const Shader& program, const Shader::CompilationHandler& handler);
|
||||
virtual GLShader* compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler);
|
||||
virtual std::string getBackendShaderHeader() const = 0;
|
||||
// For a program, this will return a string containing all the source files (without any
|
||||
// backend headers or defines). For a vertex, fragment or geometry shader, this will
|
||||
// return the fully customized shader with all the version and backend specific
|
||||
|
||||
// For a program, this will return a string containing all the source files (without any
|
||||
// backend headers or defines). For a vertex, fragment or geometry shader, this will
|
||||
// return the fully customized shader with all the version and backend specific
|
||||
// preprocessor directives
|
||||
// The program string returned can be used as a key for a cache of shader binaries
|
||||
// The shader strings can be reliably sent to the low level `compileShader` functions
|
||||
virtual std::string getShaderSource(const Shader& shader, int version) final;
|
||||
virtual std::string getShaderSource(const Shader& shader, shader::Variant version) final;
|
||||
shader::Variant getShaderVariant() const { return isStereo() ? shader::Variant::Stereo : shader::Variant::Mono; }
|
||||
virtual shader::Dialect getShaderDialect() const = 0;
|
||||
|
||||
class ElementResource {
|
||||
public:
|
||||
gpu::Element _element;
|
||||
|
|
|
@ -54,7 +54,7 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) {
|
|||
// check the program cache
|
||||
// pick the program version
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
GLuint glprogram = pipelineObject->_program->getProgram((GLShader::Version)isStereo());
|
||||
GLuint glprogram = pipelineObject->_program->getProgram(getShaderVariant());
|
||||
#else
|
||||
GLuint glprogram = pipelineObject->_program->getProgram();
|
||||
#endif
|
||||
|
|
|
@ -25,120 +25,53 @@ static const std::array<GLenum, NUM_SHADER_DOMAINS> SHADER_DOMAINS{ {
|
|||
GL_GEOMETRY_SHADER,
|
||||
} };
|
||||
|
||||
// Domain specific defines
|
||||
// Must match the order of type specified in gpu::Shader::Type
|
||||
static const std::array<std::string, NUM_SHADER_DOMAINS> DOMAIN_DEFINES{ {
|
||||
"#define GPU_VERTEX_SHADER",
|
||||
"#define GPU_PIXEL_SHADER",
|
||||
"#define GPU_GEOMETRY_SHADER",
|
||||
} };
|
||||
|
||||
// Stereo specific defines
|
||||
static const std::string stereoVersion{
|
||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA_INSTANCED
|
||||
#define GPU_TRANSFORM_STEREO_SPLIT_SCREEN
|
||||
)SHADER"
|
||||
#endif
|
||||
#ifdef GPU_STEREO_DRAWCALL_DOUBLED
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA
|
||||
#define GPU_TRANSFORM_STEREO_CAMERA_ATTRIBUTED
|
||||
)SHADER"
|
||||
#else
|
||||
R"SHADER(
|
||||
#define GPU_TRANSFORM_IS_STEREO
|
||||
)SHADER"
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
// TextureTable specific defines
|
||||
static const std::string textureTableVersion {
|
||||
"#extension GL_ARB_bindless_texture : require\n#define GPU_TEXTURE_TABLE_BINDLESS\n"
|
||||
};
|
||||
|
||||
// Versions specific of the shader
|
||||
static const std::array<std::string, GLShader::NumVersions> VERSION_DEFINES { {
|
||||
"",
|
||||
stereoVersion
|
||||
} };
|
||||
|
||||
static std::string getShaderTypeString(Shader::Type type) {
|
||||
switch (type) {
|
||||
case Shader::Type::VERTEX:
|
||||
return "vertex";
|
||||
case Shader::Type::PIXEL:
|
||||
return "pixel";
|
||||
case Shader::Type::GEOMETRY:
|
||||
return "geometry";
|
||||
case Shader::Type::PROGRAM:
|
||||
return "program";
|
||||
default:
|
||||
qFatal("Unexpected shader type %d", type);
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
std::string GLBackend::getShaderSource(const Shader& shader, int version) {
|
||||
std::string GLBackend::getShaderSource(const Shader& shader, shader::Variant variant) {
|
||||
if (shader.isProgram()) {
|
||||
std::string result;
|
||||
result.append("// VERSION " + std::to_string(version));
|
||||
for (const auto& subShader : shader.getShaders()) {
|
||||
result.append("//-------- ");
|
||||
result.append(getShaderTypeString(subShader->getType()));
|
||||
result.append("\n");
|
||||
result.append(subShader->getSource().getCode());
|
||||
if (subShader) {
|
||||
result += subShader->getSource().getSource(getShaderDialect(), variant);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string shaderDefines = getBackendShaderHeader() + "\n"
|
||||
+ (supportsBindless() ? textureTableVersion : "\n")
|
||||
+ DOMAIN_DEFINES[shader.getType()] + "\n"
|
||||
+ VERSION_DEFINES[version];
|
||||
|
||||
return shaderDefines + "\n" + shader.getSource().getCode();
|
||||
}
|
||||
return shader.getSource().getSource(getShaderDialect(), variant);
|
||||
}
|
||||
|
||||
GLShader* GLBackend::compileBackendShader(const Shader& shader, const Shader::CompilationHandler& handler) {
|
||||
// Any GLSLprogram ? normally yes...
|
||||
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
||||
GLShader::ShaderObjects shaderObjects;
|
||||
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
|
||||
const auto& variants = shader::allVariants();
|
||||
Shader::CompilationLogs compilationLogs(variants.size());
|
||||
shader.incrementCompilationAttempt();
|
||||
|
||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||
auto& shaderObject = shaderObjects[version];
|
||||
auto shaderSource = getShaderSource(shader, version);
|
||||
for (const auto& variant : variants) {
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
auto shaderSource = getShaderSource(shader, variant);
|
||||
auto& shaderObject = shaderObjects[index];
|
||||
if (handler) {
|
||||
bool retest = true;
|
||||
std::string currentSrc = shaderSource;
|
||||
// When a Handler is specified, we can try multiple times to build the shader and let the handler change the source if the compilation fails.
|
||||
// The retest bool is set to false as soon as the compilation succeed to wexit the while loop.
|
||||
// The retest bool is set to false as soon as the compilation succeed to exit the while loop.
|
||||
// The handler tells us if we should retry or not while returning a modified version of the source.
|
||||
while (retest) {
|
||||
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[version].message);
|
||||
compilationLogs[version].compiled = result;
|
||||
bool result = ::gl::compileShader(shaderDomain, currentSrc, shaderObject.glshader, compilationLogs[index].message);
|
||||
compilationLogs[index].compiled = result;
|
||||
if (!result) {
|
||||
std::string newSrc;
|
||||
retest = handler(shader, currentSrc, compilationLogs[version], newSrc);
|
||||
retest = handler(shader, currentSrc, compilationLogs[index], newSrc);
|
||||
currentSrc = newSrc;
|
||||
} else {
|
||||
retest = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
compilationLogs[version].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[version].message);
|
||||
compilationLogs[index].compiled = ::gl::compileShader(shaderDomain, shaderSource, shaderObject.glshader, compilationLogs[index].message);
|
||||
}
|
||||
|
||||
if (!compilationLogs[version].compiled) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[version].message.c_str();
|
||||
if (!compilationLogs[index].compiled) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Shader didn't compile:\n" << compilationLogs[index].message.c_str();
|
||||
shader.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -162,11 +95,13 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
|
||||
GLShader::ShaderObjects programObjects;
|
||||
program.incrementCompilationAttempt();
|
||||
Shader::CompilationLogs compilationLogs(GLShader::NumVersions);
|
||||
const auto& variants = shader::allVariants();
|
||||
Shader::CompilationLogs compilationLogs(variants.size());
|
||||
|
||||
for (int version = 0; version < GLShader::NumVersions; version++) {
|
||||
auto& programObject = programObjects[version];
|
||||
auto programSource = getShaderSource(program, version);
|
||||
for (const auto& variant : variants) {
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
auto& programObject = programObjects[index];
|
||||
auto programSource = getShaderSource(program, variant);
|
||||
auto hash = ::gl::getShaderHash(programSource);
|
||||
|
||||
CachedShader cachedBinary;
|
||||
|
@ -199,11 +134,11 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
for (auto subShader : program.getShaders()) {
|
||||
auto object = GLShader::sync((*this), *subShader, handler);
|
||||
if (object) {
|
||||
shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
|
||||
shaderGLObjects.push_back(object->_shaderObjects[index].glshader);
|
||||
} else {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - One of the shaders of the program is not compiled?";
|
||||
compilationLogs[version].compiled = false;
|
||||
compilationLogs[version].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
|
||||
compilationLogs[index].compiled = false;
|
||||
compilationLogs[index].message = std::string("Failed to compile, one of the shaders of the program is not compiled ?");
|
||||
program.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -211,9 +146,9 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
|
||||
glprogram = ::gl::buildProgram(shaderGLObjects);
|
||||
|
||||
if (!::gl::linkProgram(glprogram, compilationLogs[version].message)) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
|
||||
compilationLogs[version].compiled = false;
|
||||
if (!::gl::linkProgram(glprogram, compilationLogs[index].message)) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
|
||||
compilationLogs[index].compiled = false;
|
||||
glDeleteProgram(glprogram);
|
||||
glprogram = 0;
|
||||
return nullptr;
|
||||
|
@ -228,12 +163,12 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
}
|
||||
|
||||
if (glprogram == 0) {
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[version].message.c_str();
|
||||
qCWarning(gpugllogging) << "GLBackend::compileBackendProgram - Program didn't link:\n" << compilationLogs[index].message.c_str();
|
||||
program.setCompilationLogs(compilationLogs);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
compilationLogs[version].compiled = true;
|
||||
compilationLogs[index].compiled = true;
|
||||
programObject.glprogram = glprogram;
|
||||
postLinkProgram(programObject, program);
|
||||
}
|
||||
|
@ -249,7 +184,10 @@ GLShader* GLBackend::compileBackendProgram(const Shader& program, const Shader::
|
|||
static const GLint INVALID_UNIFORM_INDEX = -1;
|
||||
|
||||
GLint GLBackend::getRealUniformLocation(GLint location) const {
|
||||
auto& shader = _pipeline._programShader->_shaderObjects[(GLShader::Version)isStereo()];
|
||||
auto variant = isStereo() ? shader::Variant::Stereo : shader::Variant::Mono;
|
||||
auto index = static_cast<uint32_t>(variant);
|
||||
|
||||
auto& shader = _pipeline._programShader->_shaderObjects[index];
|
||||
auto itr = shader.uniformRemap.find(location);
|
||||
if (itr == shader.uniformRemap.end()) {
|
||||
// This shouldn't happen, because we use reflection to determine all the possible
|
||||
|
@ -264,20 +202,23 @@ GLint GLBackend::getRealUniformLocation(GLint location) const {
|
|||
|
||||
void GLBackend::postLinkProgram(ShaderObject& shaderObject, const Shader& program) const {
|
||||
const auto& glprogram = shaderObject.glprogram;
|
||||
const auto& expectedUniforms = program.getUniforms();
|
||||
const auto expectedLocationsByName = expectedUniforms.getLocationsByName();
|
||||
const auto uniforms = ::gl::Uniform::load(glprogram, expectedUniforms.getNames());
|
||||
auto& uniformRemap = shaderObject.uniformRemap;
|
||||
const auto& expectedUniforms = program.getReflection().uniforms;
|
||||
|
||||
// Pre-initialize all the uniforms with an invalid location
|
||||
for (const auto& entry : expectedLocationsByName) {
|
||||
auto& uniformRemap = shaderObject.uniformRemap;
|
||||
// initialize all the uniforms with an invalid location
|
||||
for (const auto& entry : expectedUniforms) {
|
||||
uniformRemap[entry.second] = INVALID_UNIFORM_INDEX;
|
||||
}
|
||||
|
||||
// Now load up all the actual found uniform location
|
||||
|
||||
// Get the actual uniform locations from the shader
|
||||
const auto names = Shader::Reflection::getNames(expectedUniforms);
|
||||
const auto uniforms = ::gl::Uniform::load(glprogram, names);
|
||||
|
||||
// Now populate the remapping with the found locations
|
||||
for (const auto& uniform : uniforms) {
|
||||
const auto& name = uniform.name;
|
||||
const auto& expectedLocation = expectedLocationsByName.at(name);
|
||||
const auto& expectedLocation = expectedUniforms.at(name);
|
||||
const auto& location = uniform.binding;
|
||||
uniformRemap[expectedLocation] = location;
|
||||
}
|
||||
|
@ -462,3 +403,4 @@ void GLBackend::initShaderBinaryCache() {
|
|||
void GLBackend::killShaderBinaryCache() {
|
||||
::gl::saveShaderCache(_shaderBinaryCache._binaries);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ GLPipeline* GLPipeline::sync(GLBackend& backend, const Pipeline& pipeline) {
|
|||
// Special case for view correction matrices, any pipeline that declares the correction buffer
|
||||
// uniform will automatically have it provided without any client code necessary.
|
||||
// Required for stable lighting in the HMD.
|
||||
object->_cameraCorrection = shader->getUniformBuffers().isValid(gpu::slot::buffer::CameraCorrection);
|
||||
object->_cameraCorrection = shader->getReflection().validUniformBuffer(gpu::slot::buffer::CameraCorrection);
|
||||
object->_program = programObject;
|
||||
object->_state = stateObject;
|
||||
|
||||
|
|
|
@ -14,43 +14,45 @@
|
|||
namespace gpu { namespace gl {
|
||||
|
||||
struct ShaderObject {
|
||||
GLuint glshader { 0 };
|
||||
GLuint glprogram { 0 };
|
||||
enum class BindingType
|
||||
{
|
||||
INPUT,
|
||||
OUTPUT,
|
||||
TEXTURE,
|
||||
SAMPLER,
|
||||
UNIFORM_BUFFER,
|
||||
RESOURCE_BUFFER,
|
||||
UNIFORM,
|
||||
};
|
||||
|
||||
using LocationMap = std::unordered_map <GLuint, GLuint>;
|
||||
LocationMap uniformRemap;
|
||||
using LocationMap = std::unordered_map<std::string, int32_t>;
|
||||
using ReflectionMap = std::map<BindingType, LocationMap>;
|
||||
using UniformMap = std::unordered_map<GLuint, GLuint>;
|
||||
|
||||
GLuint glshader{ 0 };
|
||||
GLuint glprogram{ 0 };
|
||||
|
||||
UniformMap uniformRemap;
|
||||
};
|
||||
|
||||
class GLShader : public GPUObject {
|
||||
public:
|
||||
static GLShader* sync(GLBackend& backend, const Shader& shader, const Shader::CompilationHandler& handler = nullptr);
|
||||
|
||||
enum Version {
|
||||
Mono = 0,
|
||||
Stereo,
|
||||
|
||||
NumVersions
|
||||
};
|
||||
|
||||
using ShaderObject = gpu::gl::ShaderObject;
|
||||
using ShaderObjects = std::array< ShaderObject, NumVersions >;
|
||||
|
||||
using UniformMapping = std::map<GLint, GLint>;
|
||||
using UniformMappingVersions = std::vector<UniformMapping>;
|
||||
using ShaderObjects = std::array<ShaderObject, shader::NUM_VARIANTS>;
|
||||
|
||||
GLShader(const std::weak_ptr<GLBackend>& backend);
|
||||
~GLShader();
|
||||
|
||||
ShaderObjects _shaderObjects;
|
||||
|
||||
GLuint getProgram(Version version = Mono) const {
|
||||
return _shaderObjects[version].glprogram;
|
||||
GLuint getProgram(shader::Variant version = shader::Variant::Mono) const {
|
||||
return _shaderObjects[static_cast<uint32_t>(version)].glprogram;
|
||||
}
|
||||
|
||||
const std::weak_ptr<GLBackend> _backend;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
}} // namespace gpu::gl
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
set(TARGET_NAME gpu-gl)
|
||||
setup_hifi_library(Concurrent)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common shaders)
|
||||
if (UNIX)
|
||||
target_link_libraries(${TARGET_NAME} pthread)
|
||||
endif(UNIX)
|
||||
|
|
|
@ -170,8 +170,7 @@ protected:
|
|||
// Output stage
|
||||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
std::string getBackendShaderHeader() const override;
|
||||
|
||||
shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl410; }
|
||||
void postLinkProgram(ShaderObject& programObject, const Shader& program) const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,22 +12,13 @@ using namespace gpu;
|
|||
using namespace gpu::gl;
|
||||
using namespace gpu::gl41;
|
||||
|
||||
// GLSL version
|
||||
std::string GL41Backend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 410 core
|
||||
#define GPU_GL410
|
||||
#define BITFIELD int
|
||||
)SHADER");
|
||||
return header;
|
||||
}
|
||||
|
||||
void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& program) const {
|
||||
Parent::postLinkProgram(programObject, program);
|
||||
const auto& glprogram = programObject.glprogram;
|
||||
const auto& reflection = program.getReflection();
|
||||
// For the UBOs, use glUniformBlockBinding to fixup the locations based on the reflection
|
||||
{
|
||||
const auto expectedUbos = program.getUniformBuffers().getLocationsByName();
|
||||
const auto& expectedUbos = reflection.uniformBuffers;
|
||||
auto ubos = ::gl::UniformBlock::load(glprogram);
|
||||
for (const auto& ubo : ubos) {
|
||||
const auto& name = ubo.name;
|
||||
|
@ -41,7 +32,7 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
|
|||
|
||||
// For the Textures, use glUniform1i to fixup the active texture slots based on the reflection
|
||||
{
|
||||
const auto expectedTextures = program.getTextures().getLocationsByName();
|
||||
const auto& expectedTextures = reflection.textures;
|
||||
for (const auto& expectedTexture : expectedTextures) {
|
||||
auto location = glGetUniformLocation(glprogram, expectedTexture.first.c_str());
|
||||
if (location < 0) {
|
||||
|
@ -53,8 +44,9 @@ void GL41Backend::postLinkProgram(ShaderObject& programObject, const Shader& pro
|
|||
|
||||
// For the resource buffers, do the same as for the textures, since in GL 4.1 that's how they're implemented
|
||||
{
|
||||
const auto expectedResourceBuffers = program.getResourceBuffers().getLocationsByName();
|
||||
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, program.getResourceBuffers().getNames());
|
||||
const auto& expectedResourceBuffers = reflection.resourceBuffers;
|
||||
const auto names = Shader::Reflection::getNames(expectedResourceBuffers);
|
||||
const auto resourceBufferUniforms = ::gl::Uniform::loadByName(glprogram, names);
|
||||
for (const auto& resourceBuffer : resourceBufferUniforms) {
|
||||
const auto& targetBinding = expectedResourceBuffers.at(resourceBuffer.name);
|
||||
glProgramUniform1i(glprogram, resourceBuffer.binding, targetBinding + GL41Backend::RESOURCE_BUFFER_SLOT0_TEX_UNIT);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define GPU_BINDLESS_TEXTURES 0
|
||||
|
||||
namespace gpu { namespace gl45 {
|
||||
|
||||
|
||||
using namespace gpu::gl;
|
||||
using TextureWeakPointer = std::weak_ptr<Texture>;
|
||||
|
||||
|
@ -56,6 +56,7 @@ public:
|
|||
using Parent = GLTexture;
|
||||
friend class GL45Backend;
|
||||
static GLuint allocate(const Texture& texture);
|
||||
|
||||
protected:
|
||||
GL45Texture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
void generateMips() const override;
|
||||
|
@ -88,6 +89,7 @@ public:
|
|||
virtual const Bindless& getBindless() const;
|
||||
void releaseBindless() const;
|
||||
void recreateBindless() const;
|
||||
|
||||
private:
|
||||
mutable Bindless _bindless;
|
||||
#endif
|
||||
|
@ -98,10 +100,11 @@ public:
|
|||
mutable Sampler _cachedSampler{ getInvalidSampler() };
|
||||
};
|
||||
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
#if GPU_BINDLESS_TEXTURES
|
||||
class GL45TextureTable : public GLObject<TextureTable> {
|
||||
static GLuint allocate();
|
||||
using Parent = GLObject<TextureTable>;
|
||||
|
||||
public:
|
||||
using BindlessArray = std::array<GL45Texture::Bindless, TextureTable::COUNT>;
|
||||
|
||||
|
@ -116,7 +119,6 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Textures that have fixed allocation sizes and cannot be managed at runtime
|
||||
//
|
||||
|
@ -134,12 +136,13 @@ public:
|
|||
|
||||
void allocateStorage() const;
|
||||
void syncSampler() const override;
|
||||
const Size _size { 0 };
|
||||
const Size _size{ 0 };
|
||||
};
|
||||
|
||||
class GL45AttachmentTexture : public GL45FixedAllocationTexture {
|
||||
using Parent = GL45FixedAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45AttachmentTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
~GL45AttachmentTexture();
|
||||
|
@ -148,6 +151,7 @@ public:
|
|||
class GL45StrictResourceTexture : public GL45FixedAllocationTexture {
|
||||
using Parent = GL45FixedAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45StrictResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
~GL45StrictResourceTexture();
|
||||
|
@ -179,6 +183,7 @@ public:
|
|||
class GL45ResourceTexture : public GL45VariableAllocationTexture {
|
||||
using Parent = GL45VariableAllocationTexture;
|
||||
friend class GL45Backend;
|
||||
|
||||
protected:
|
||||
GL45ResourceTexture(const std::weak_ptr<GLBackend>& backend, const Texture& texture);
|
||||
|
||||
|
@ -186,7 +191,6 @@ public:
|
|||
size_t promote() override;
|
||||
size_t demote() override;
|
||||
void populateTransferQueue(TransferQueue& pendingTransfers) override;
|
||||
|
||||
|
||||
void allocateStorage(uint16 mip);
|
||||
Size copyMipsFromTexture();
|
||||
|
@ -226,7 +230,6 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void draw(GLenum mode, uint32 numVertices, uint32 startVertex) override;
|
||||
|
@ -244,7 +247,6 @@ protected:
|
|||
GLuint getQueryID(const QueryPointer& query) override;
|
||||
GLQuery* syncGPUObject(const Query& query) override;
|
||||
|
||||
|
||||
// Draw Stage
|
||||
void do_draw(const Batch& batch, size_t paramOffset) override;
|
||||
void do_drawIndexed(const Batch& batch, size_t paramOffset) override;
|
||||
|
@ -270,7 +272,7 @@ protected:
|
|||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
// Shader Stage
|
||||
std::string getBackendShaderHeader() const override;
|
||||
shader::Dialect getShaderDialect() const override;
|
||||
|
||||
// Texture Management Stage
|
||||
void initTextureManagementStage() override;
|
||||
|
@ -282,9 +284,8 @@ protected:
|
|||
#endif
|
||||
};
|
||||
|
||||
} }
|
||||
}} // namespace gpu::gl45
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(gpugl45logging)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,22 +7,16 @@
|
|||
//
|
||||
#include "GL45Backend.h"
|
||||
#include <gpu/gl/GLShader.h>
|
||||
//#include <gl/GLShaders.h>
|
||||
|
||||
using namespace gpu;
|
||||
using namespace gpu::gl;
|
||||
using namespace gpu::gl45;
|
||||
|
||||
// GLSL version
|
||||
std::string GL45Backend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 450 core
|
||||
#define GPU_GL450
|
||||
#define BITFIELD int
|
||||
)SHADER"
|
||||
#ifdef GPU_SSBO_TRANSFORM_OBJECT
|
||||
R"SHADER(#define GPU_SSBO_TRANSFORM_OBJECT)SHADER"
|
||||
shader::Dialect GL45Backend::getShaderDialect() const {
|
||||
#if defined(Q_OS_MAC)
|
||||
// We build, but don't actually use GL 4.5 on OSX
|
||||
throw std::runtime_error("GL 4.5 unavailable on OSX");
|
||||
#else
|
||||
return shader::Dialect::glsl450;
|
||||
#endif
|
||||
);
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
set(TARGET_NAME gpu-gles)
|
||||
setup_hifi_library(Gui Concurrent)
|
||||
link_hifi_libraries(shared gl gpu gpu-gl-common)
|
||||
link_hifi_libraries(shared shaders gl gpu gpu-gl-common)
|
||||
GroupSources("src")
|
||||
target_opengl()
|
||||
|
|
|
@ -27,11 +27,7 @@ class GLESBackend : public GLBackend {
|
|||
friend class Context;
|
||||
|
||||
public:
|
||||
static const GLint TRANSFORM_OBJECT_SLOT { 31 };
|
||||
static const GLint RESOURCE_TRANSFER_TEX_UNIT { 32 };
|
||||
static const GLint RESOURCE_TRANSFER_EXTRA_TEX_UNIT { 33 };
|
||||
static const GLint RESOURCE_BUFFER_TEXBUF_TEX_UNIT { 34 };
|
||||
static const GLint RESOURCE_BUFFER_SLOT0_TEX_UNIT { 35 };
|
||||
explicit GLESBackend(bool syncCache) : Parent(syncCache) {}
|
||||
GLESBackend() : Parent() {}
|
||||
virtual ~GLESBackend() {
|
||||
|
@ -166,7 +162,7 @@ protected:
|
|||
// Output stage
|
||||
void do_blit(const Batch& batch, size_t paramOffset) override;
|
||||
|
||||
std::string getBackendShaderHeader() const override;
|
||||
shader::Dialect getShaderDialect() const override { return shader::Dialect::glsl310es; }
|
||||
};
|
||||
|
||||
} }
|
||||
|
|
|
@ -12,15 +12,3 @@ using namespace gpu;
|
|||
using namespace gpu::gl;
|
||||
using namespace gpu::gles;
|
||||
|
||||
// GLSL version
|
||||
std::string GLESBackend::getBackendShaderHeader() const {
|
||||
static const std::string header(
|
||||
R"SHADER(#version 310 es
|
||||
#extension GL_EXT_texture_buffer : enable
|
||||
precision highp float;
|
||||
precision highp samplerBuffer;
|
||||
precision highp sampler2DShadow;
|
||||
#define BITFIELD highp int
|
||||
)SHADER");
|
||||
return header;
|
||||
}
|
||||
|
|
|
@ -60,12 +60,11 @@ void GLESBackend::transferTransformState(const Batch& batch) const {
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + GLESBackend::TRANSFORM_OBJECT_SLOT);
|
||||
glActiveTexture(GL_TEXTURE0 + slot::texture::ObjectTransforms);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, _transform._objectBufferTexture);
|
||||
if (!batch._objects.empty()) {
|
||||
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _transform._objectBuffer);
|
||||
}
|
||||
|
||||
CHECK_GL_ERROR();
|
||||
|
||||
// Make sure the current Camera offset is unknown before render Draw
|
||||
|
|
|
@ -17,7 +17,7 @@ struct DrawColorParams {
|
|||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform drawColorParamsBuffer {
|
||||
LAYOUT(binding=0) uniform drawColorParamsBuffer {
|
||||
DrawColorParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
struct DrawColorParams {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform drawColorParams {
|
||||
LAYOUT(binding=0) uniform drawColorParams {
|
||||
DrawColorParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ struct TexCoordRectParams {
|
|||
vec4 texcoordRect;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform texcoordRectBuffer {
|
||||
LAYOUT(binding=0) uniform texcoordRectBuffer {
|
||||
TexCoordRectParams params;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
VERTEX DrawUnitQuadTexcoord
|
||||
FRAGMENT DrawTexture
|
|
@ -14,7 +14,7 @@
|
|||
//
|
||||
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
1
libraries/gpu/src/gpu/DrawTextureMirroredX.slp
Normal file
1
libraries/gpu/src/gpu/DrawTextureMirroredX.slp
Normal file
|
@ -0,0 +1 @@
|
|||
VERTEX DrawUnitQuadTexcoord
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<@include gpu/ShaderConstants.h@>
|
||||
|
||||
layout(binding=0) uniform sampler2D colorMap;
|
||||
LAYOUT(binding=0) uniform sampler2D colorMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
|
||||
|
|
2
libraries/gpu/src/gpu/DrawTransformedTexture.slp
Normal file
2
libraries/gpu/src/gpu/DrawTransformedTexture.slp
Normal file
|
@ -0,0 +1,2 @@
|
|||
VERTEX DrawTransformUnitQuad
|
||||
FRAGMENT DrawTexture
|
|
@ -10,44 +10,49 @@
|
|||
//
|
||||
|
||||
#include "Shader.h"
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
#include <set>
|
||||
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
#include <shaders/Shaders.h>
|
||||
|
||||
#include "Context.h"
|
||||
|
||||
using namespace gpu;
|
||||
|
||||
std::atomic<uint32_t> Shader::_nextShaderID( 1 );
|
||||
Shader::DomainShaderMaps Shader::_domainShaderMaps;
|
||||
Shader::ProgramMap Shader::_programMap;
|
||||
|
||||
|
||||
Shader::Shader(Type type, const Source& source) :
|
||||
_source(source),
|
||||
_type(type),
|
||||
_ID(_nextShaderID++)
|
||||
Shader::Shader(Type type, const Source& source, bool dynamic) :
|
||||
_type(type)
|
||||
{
|
||||
auto& thisSource = const_cast<Source&>(_source);
|
||||
thisSource = source;
|
||||
if (!dynamic) {
|
||||
thisSource.id = source.id;
|
||||
}
|
||||
}
|
||||
|
||||
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel):
|
||||
_type(type),
|
||||
_ID(_nextShaderID++)
|
||||
Shader::Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel) :
|
||||
_type(type)
|
||||
{
|
||||
|
||||
auto& shaders = const_cast<Shaders&>(_shaders);
|
||||
if (geometry) {
|
||||
_shaders.resize(3);
|
||||
_shaders[VERTEX] = vertex;
|
||||
_shaders[GEOMETRY] = geometry;
|
||||
_shaders[PIXEL] = pixel;
|
||||
shaders.resize(3);
|
||||
shaders[VERTEX] = vertex;
|
||||
shaders[GEOMETRY] = geometry;
|
||||
shaders[PIXEL] = pixel;
|
||||
} else {
|
||||
_shaders.resize(2);
|
||||
_shaders[VERTEX] = vertex;
|
||||
_shaders[PIXEL] = pixel;
|
||||
shaders.resize(2);
|
||||
shaders[VERTEX] = vertex;
|
||||
shaders[PIXEL] = pixel;
|
||||
}
|
||||
|
||||
auto& reflection = const_cast<Reflection&>(getReflection());
|
||||
for (const auto& subShader : _shaders) {
|
||||
reflection.merge(subShader->getReflection());
|
||||
}
|
||||
if (_shaders[VERTEX]) {
|
||||
reflection.inputs = _shaders[VERTEX]->getReflection().inputs;
|
||||
}
|
||||
if (_shaders[PIXEL]) {
|
||||
reflection.outputs = _shaders[PIXEL]->getReflection().outputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,46 +60,27 @@ Shader::~Shader()
|
|||
{
|
||||
}
|
||||
|
||||
void populateSlotSet(Shader::SlotSet& slotSet, const Shader::LocationMap& map) {
|
||||
for (const auto& entry : map) {
|
||||
const auto& name = entry.first;
|
||||
const auto& location = entry.second;
|
||||
slotSet.insert({ name, location, Element() });
|
||||
}
|
||||
static std::unordered_map<uint32_t, std::weak_ptr<Shader>> _shaderCache;
|
||||
|
||||
Shader::ID Shader::getID() const {
|
||||
if (isProgram()) {
|
||||
return (_shaders[VERTEX]->getID() << 16) | (_shaders[PIXEL]->getID());
|
||||
}
|
||||
|
||||
return _source.id;
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createOrReuseDomainShader(Type type, const Source& source) {
|
||||
auto found = _domainShaderMaps[type].find(source);
|
||||
if (found != _domainShaderMaps[type].end()) {
|
||||
Shader::Pointer Shader::createOrReuseDomainShader(Type type, uint32_t sourceId) {
|
||||
// Don't attempt to cache non-static shaders
|
||||
auto found = _shaderCache.find(sourceId);
|
||||
if (found != _shaderCache.end()) {
|
||||
auto sharedShader = (*found).second.lock();
|
||||
if (sharedShader) {
|
||||
return sharedShader;
|
||||
}
|
||||
}
|
||||
auto shader = Pointer(new Shader(type, source));
|
||||
const auto& reflection = source.getReflection();
|
||||
if (0 != reflection.count(BindingType::INPUT)) {
|
||||
populateSlotSet(shader->_inputs, reflection.find(BindingType::INPUT)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::OUTPUT)) {
|
||||
populateSlotSet(shader->_outputs, reflection.find(BindingType::OUTPUT)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
|
||||
populateSlotSet(shader->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
|
||||
populateSlotSet(shader->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::TEXTURE)) {
|
||||
populateSlotSet(shader->_textures, reflection.find(BindingType::TEXTURE)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::SAMPLER)) {
|
||||
populateSlotSet(shader->_samplers, reflection.find(BindingType::SAMPLER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM)) {
|
||||
populateSlotSet(shader->_uniforms, reflection.find(BindingType::UNIFORM)->second);
|
||||
}
|
||||
_domainShaderMaps[type].emplace(source, std::weak_ptr<Shader>(shader));
|
||||
auto shader = Pointer(new Shader(type, getShaderSource(sourceId), false));
|
||||
_shaderCache.insert({ sourceId, shader });
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
@ -137,28 +123,6 @@ ShaderPointer Shader::createOrReuseProgramShader(Type type, const Pointer& verte
|
|||
|
||||
// Program is a new one, let's create it
|
||||
auto program = Pointer(new Shader(type, vertexShader, geometryShader, pixelShader));
|
||||
|
||||
// Combine the slots from the sub-shaders
|
||||
for (const auto& shader : program->_shaders) {
|
||||
const auto& reflection = shader->_source.getReflection();
|
||||
if (0 != reflection.count(BindingType::UNIFORM_BUFFER)) {
|
||||
populateSlotSet(program->_uniformBuffers, reflection.find(BindingType::UNIFORM_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::RESOURCE_BUFFER)) {
|
||||
populateSlotSet(program->_resourceBuffers, reflection.find(BindingType::RESOURCE_BUFFER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::TEXTURE)) {
|
||||
populateSlotSet(program->_textures, reflection.find(BindingType::TEXTURE)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::SAMPLER)) {
|
||||
populateSlotSet(program->_samplers, reflection.find(BindingType::SAMPLER)->second);
|
||||
}
|
||||
if (0 != reflection.count(BindingType::UNIFORM)) {
|
||||
populateSlotSet(program->_uniforms, reflection.find(BindingType::UNIFORM)->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_programMap.emplace(key, std::weak_ptr<Shader>(program));
|
||||
return program;
|
||||
}
|
||||
|
@ -175,24 +139,21 @@ void Shader::incrementCompilationAttempt() const {
|
|||
}
|
||||
|
||||
Shader::Pointer Shader::createVertex(const Source& source) {
|
||||
return createOrReuseDomainShader(VERTEX, source);
|
||||
return Pointer(new Shader(VERTEX, source, true));
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createPixel(const Source& source) {
|
||||
return createOrReuseDomainShader(FRAGMENT, source);
|
||||
return Pointer(new Shader(FRAGMENT, source, true));
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createVertex(uint32_t id) {
|
||||
return createVertex(getShaderSource(id));
|
||||
return createOrReuseDomainShader(VERTEX, id);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createPixel(uint32_t id) {
|
||||
return createPixel(getShaderSource(id));
|
||||
return createOrReuseDomainShader(FRAGMENT, id);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
||||
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, pixelShader);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(uint32_t programId) {
|
||||
auto vertexShader = createVertex(shader::getVertexId(programId));
|
||||
|
@ -200,98 +161,15 @@ Shader::Pointer Shader::createProgram(uint32_t programId) {
|
|||
return createOrReuseProgramShader(PROGRAM, vertexShader, nullptr, fragmentShader);
|
||||
}
|
||||
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
|
||||
return Pointer(new Shader(PROGRAM, vertexShader, nullptr, pixelShader));
|
||||
}
|
||||
|
||||
// Dynamic program, bypass caching
|
||||
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& geometryShader, const Pointer& pixelShader) {
|
||||
return createOrReuseProgramShader(PROGRAM, vertexShader, geometryShader, pixelShader);
|
||||
return Pointer(new Shader(PROGRAM, vertexShader, geometryShader, pixelShader));
|
||||
}
|
||||
|
||||
static const std::string IGNORED_BINDING = "transformObjectBuffer";
|
||||
|
||||
void updateBindingsFromJsonObject(Shader::LocationMap& inOutSet, const QJsonObject& json) {
|
||||
for (const auto& key : json.keys()) {
|
||||
auto keyStr = key.toStdString();
|
||||
if (IGNORED_BINDING == keyStr) {
|
||||
continue;
|
||||
}
|
||||
inOutSet[keyStr] = json[key].toInt();
|
||||
}
|
||||
}
|
||||
|
||||
void updateTextureAndResourceBuffersFromJsonObjects(Shader::LocationMap& inOutTextures, Shader::LocationMap& inOutResourceBuffers,
|
||||
const QJsonObject& json, const QJsonObject& types) {
|
||||
static const std::string RESOURCE_BUFFER_TEXTURE_TYPE = "samplerBuffer";
|
||||
for (const auto& key : json.keys()) {
|
||||
auto keyStr = key.toStdString();
|
||||
if (keyStr == IGNORED_BINDING) {
|
||||
continue;
|
||||
}
|
||||
auto location = json[key].toInt();
|
||||
auto type = types[key].toString().toStdString();
|
||||
if (type == RESOURCE_BUFFER_TEXTURE_TYPE) {
|
||||
inOutResourceBuffers[keyStr] = location;
|
||||
} else {
|
||||
inOutTextures[key.toStdString()] = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Shader::ReflectionMap getShaderReflection(const std::string& reflectionJson) {
|
||||
if (reflectionJson.empty() && reflectionJson != std::string("null")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
#define REFLECT_KEY_INPUTS "inputs"
|
||||
#define REFLECT_KEY_OUTPUTS "outputs"
|
||||
#define REFLECT_KEY_UBOS "uniformBuffers"
|
||||
#define REFLECT_KEY_SSBOS "storageBuffers"
|
||||
#define REFLECT_KEY_UNIFORMS "uniforms"
|
||||
#define REFLECT_KEY_TEXTURES "textures"
|
||||
#define REFLECT_KEY_TEXTURE_TYPES "textureTypes"
|
||||
|
||||
auto doc = QJsonDocument::fromJson(reflectionJson.c_str());
|
||||
if (doc.isNull()) {
|
||||
qWarning() << "Invalid shader reflection JSON" << reflectionJson.c_str();
|
||||
return {};
|
||||
}
|
||||
|
||||
Shader::ReflectionMap result;
|
||||
auto json = doc.object();
|
||||
if (json.contains(REFLECT_KEY_INPUTS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::INPUT], json[REFLECT_KEY_INPUTS].toObject());
|
||||
}
|
||||
if (json.contains(REFLECT_KEY_OUTPUTS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::OUTPUT], json[REFLECT_KEY_OUTPUTS].toObject());
|
||||
}
|
||||
// FIXME eliminate the last of the uniforms
|
||||
if (json.contains(REFLECT_KEY_UNIFORMS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM], json[REFLECT_KEY_UNIFORMS].toObject());
|
||||
}
|
||||
if (json.contains(REFLECT_KEY_UBOS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::UNIFORM_BUFFER], json[REFLECT_KEY_UBOS].toObject());
|
||||
}
|
||||
|
||||
// SSBOs need to come BEFORE the textures. In GL 4.5 the reflection slots aren't really used, but in 4.1 the slots
|
||||
// are used to explicitly setup bindings after shader linkage, so we want the resource buffer slots to contain the
|
||||
// texture locations, not the SSBO locations
|
||||
if (json.contains(REFLECT_KEY_SSBOS)) {
|
||||
updateBindingsFromJsonObject(result[Shader::BindingType::RESOURCE_BUFFER], json[REFLECT_KEY_SSBOS].toObject());
|
||||
}
|
||||
|
||||
// samplerBuffer textures map to gpu ResourceBuffer, while all other textures map to regular gpu Texture
|
||||
if (json.contains(REFLECT_KEY_TEXTURES)) {
|
||||
updateTextureAndResourceBuffersFromJsonObjects(
|
||||
result[Shader::BindingType::TEXTURE],
|
||||
result[Shader::BindingType::RESOURCE_BUFFER],
|
||||
json[REFLECT_KEY_TEXTURES].toObject(),
|
||||
json[REFLECT_KEY_TEXTURE_TYPES].toObject());
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shader::Source Shader::getShaderSource(uint32_t id) {
|
||||
auto source = shader::loadShaderSource(id);
|
||||
auto reflectionJson = shader::loadShaderReflection(id);
|
||||
auto reflection = getShaderReflection(reflectionJson);
|
||||
return { source, reflection };
|
||||
const Shader::Source& Shader::getShaderSource(uint32_t id) {
|
||||
return shader::Source::get(id);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <shaders/Shaders.h>
|
||||
#include <QUrl>
|
||||
|
||||
namespace gpu {
|
||||
|
@ -42,58 +43,10 @@ public:
|
|||
typedef std::shared_ptr<Shader> Pointer;
|
||||
typedef std::vector<Pointer> Shaders;
|
||||
|
||||
// Needs to match values in shaders/Shaders.h
|
||||
enum class BindingType
|
||||
{
|
||||
INVALID = -1,
|
||||
INPUT = 0,
|
||||
OUTPUT,
|
||||
TEXTURE,
|
||||
SAMPLER,
|
||||
UNIFORM_BUFFER,
|
||||
RESOURCE_BUFFER,
|
||||
UNIFORM,
|
||||
};
|
||||
|
||||
using LocationMap = std::unordered_map<std::string, int32_t>;
|
||||
using ReflectionMap = std::map<BindingType, LocationMap>;
|
||||
|
||||
class Source {
|
||||
public:
|
||||
enum Language
|
||||
{
|
||||
INVALID = -1,
|
||||
GLSL = 0,
|
||||
SPIRV = 1,
|
||||
MSL = 2,
|
||||
HLSL = 3,
|
||||
};
|
||||
|
||||
Source() {}
|
||||
Source(const std::string& code, const ReflectionMap& reflection, Language lang = GLSL) :
|
||||
_code(code), _reflection(reflection), _lang(lang) {}
|
||||
Source(const Source& source) : _code(source._code), _reflection(source._reflection), _lang(source._lang) {}
|
||||
virtual ~Source() {}
|
||||
|
||||
virtual const std::string& getCode() const { return _code; }
|
||||
virtual const ReflectionMap& getReflection() const { return _reflection; }
|
||||
|
||||
class Less {
|
||||
public:
|
||||
bool operator()(const Source& x, const Source& y) const {
|
||||
if (x._lang == y._lang) {
|
||||
return x._code < y._code;
|
||||
} else {
|
||||
return (x._lang < y._lang);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
std::string _code;
|
||||
ReflectionMap _reflection;
|
||||
Language _lang;
|
||||
};
|
||||
using Source = shader::Source;
|
||||
using Reflection = shader::Reflection;
|
||||
using Dialect = shader::Dialect;
|
||||
using Variant = shader::Variant;
|
||||
|
||||
struct CompilationLog {
|
||||
std::string message;
|
||||
|
@ -112,85 +65,13 @@ public:
|
|||
bool operator()(const T& x, const T& y) const { return x._name < y._name; }
|
||||
};
|
||||
|
||||
class Slot {
|
||||
public:
|
||||
std::string _name;
|
||||
int32 _location{ INVALID_LOCATION };
|
||||
Element _element;
|
||||
uint16 _resourceType{ Resource::BUFFER };
|
||||
uint32 _size{ 0 };
|
||||
|
||||
Slot(const Slot& s) :
|
||||
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
|
||||
Slot(Slot&& s) :
|
||||
_name(s._name), _location(s._location), _element(s._element), _resourceType(s._resourceType), _size(s._size) {}
|
||||
Slot(const std::string& name,
|
||||
int32 location,
|
||||
const Element& element,
|
||||
uint16 resourceType = Resource::BUFFER,
|
||||
uint32 size = 0) :
|
||||
_name(name),
|
||||
_location(location), _element(element), _resourceType(resourceType), _size(size) {}
|
||||
Slot(const std::string& name) : _name(name) {}
|
||||
|
||||
Slot& operator=(const Slot& s) {
|
||||
_name = s._name;
|
||||
_location = s._location;
|
||||
_element = s._element;
|
||||
_resourceType = s._resourceType;
|
||||
_size = s._size;
|
||||
return (*this);
|
||||
}
|
||||
};
|
||||
|
||||
class SlotSet : protected std::set<Slot, Less<Slot>> {
|
||||
using Parent = std::set<Slot, Less<Slot>>;
|
||||
|
||||
public:
|
||||
void insert(const Parent::value_type& value) {
|
||||
Parent::insert(value);
|
||||
if (value._location != INVALID_LOCATION) {
|
||||
_validSlots.insert(value._location);
|
||||
}
|
||||
}
|
||||
|
||||
using Parent::begin;
|
||||
using Parent::empty;
|
||||
using Parent::end;
|
||||
using Parent::size;
|
||||
|
||||
using LocationMap = std::unordered_map<std::string, int32>;
|
||||
using NameVector = std::vector<std::string>;
|
||||
|
||||
NameVector getNames() const {
|
||||
NameVector result;
|
||||
for (const auto& entry : *this) {
|
||||
result.push_back(entry._name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LocationMap getLocationsByName() const {
|
||||
LocationMap result;
|
||||
for (const auto& entry : *this) {
|
||||
result.insert({ entry._name, entry._location });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isValid(int32 slot) const { return 0 != _validSlots.count(slot); }
|
||||
|
||||
protected:
|
||||
std::unordered_set<int> _validSlots;
|
||||
};
|
||||
|
||||
static Source getShaderSource(uint32_t id);
|
||||
static Source getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static Source getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
|
||||
static const Source& getShaderSource(uint32_t id);
|
||||
static const Source& getVertexShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static const Source& getFragmentShaderSource(uint32_t id) { return getShaderSource(id); }
|
||||
static Pointer createVertex(const Source& source);
|
||||
static Pointer createPixel(const Source& source);
|
||||
static Pointer createGeometry(const Source& source);
|
||||
|
||||
static Pointer createVertex(uint32_t shaderId);
|
||||
static Pointer createPixel(uint32_t shaderId);
|
||||
static Pointer createGeometry(uint32_t shaderId);
|
||||
|
@ -201,8 +82,7 @@ public:
|
|||
|
||||
~Shader();
|
||||
|
||||
ID getID() const { return _ID; }
|
||||
|
||||
ID getID() const;
|
||||
Type getType() const { return _type; }
|
||||
bool isProgram() const { return getType() > NUM_DOMAINS; }
|
||||
bool isDomain() const { return getType() < NUM_DOMAINS; }
|
||||
|
@ -211,17 +91,12 @@ public:
|
|||
|
||||
const Shaders& getShaders() const { return _shaders; }
|
||||
|
||||
// Access the exposed uniform, input and output slot
|
||||
const SlotSet& getUniforms() const { return _uniforms; }
|
||||
const SlotSet& getUniformBuffers() const { return _uniformBuffers; }
|
||||
const SlotSet& getResourceBuffers() const { return _resourceBuffers; }
|
||||
const SlotSet& getTextures() const { return _textures; }
|
||||
const SlotSet& getSamplers() const { return _samplers; }
|
||||
const Reflection& getReflection() const { return _source.reflection; }
|
||||
|
||||
// Compilation Handler can be passed while compiling a shader (in the makeProgram call) to be able to give the hand to
|
||||
// the caller thread if the comilation fails and to prvide a different version of the source for it
|
||||
// the caller thread if the compilation fails and to provide a different version of the source for it
|
||||
// @param0 the Shader object that just failed to compile
|
||||
// @param1 the original source code as submited to the compiler
|
||||
// @param1 the original source code as submitted to the compiler
|
||||
// @param2 the compilation log containing the error message
|
||||
// @param3 a new string ready to be filled with the new version of the source that could be proposed from the handler functor
|
||||
// @return boolean true if the backend should keep trying to compile the shader with the new source returned or false to stop and fail that shader compilation
|
||||
|
@ -240,32 +115,21 @@ public:
|
|||
const GPUObjectPointer gpuObject{};
|
||||
|
||||
protected:
|
||||
Shader(Type type, const Source& source);
|
||||
Shader(Type type, const Source& source, bool dynamic);
|
||||
Shader(Type type, const Pointer& vertex, const Pointer& geometry, const Pointer& pixel);
|
||||
|
||||
Shader(const Shader& shader); // deep copy of the sysmem shader
|
||||
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture
|
||||
|
||||
// Source contains the actual source code or nothing if the shader is a program
|
||||
Source _source;
|
||||
const Source _source;
|
||||
|
||||
// if shader is composed of sub shaders, here they are
|
||||
Shaders _shaders;
|
||||
|
||||
// List of exposed uniform, input and output slots
|
||||
SlotSet _uniforms;
|
||||
SlotSet _uniformBuffers;
|
||||
SlotSet _resourceBuffers;
|
||||
SlotSet _textures;
|
||||
SlotSet _samplers;
|
||||
SlotSet _inputs;
|
||||
SlotSet _outputs;
|
||||
const Shaders _shaders;
|
||||
|
||||
|
||||
// The type of the shader, the master key
|
||||
Type _type;
|
||||
|
||||
// The unique identifier of a shader in the GPU lib
|
||||
uint32_t _ID{ 0 };
|
||||
const Type _type;
|
||||
|
||||
// Number of attempts to compile the shader
|
||||
mutable uint32_t _numCompilationAttempts{ 0 };
|
||||
|
@ -277,13 +141,9 @@ protected:
|
|||
|
||||
// Global maps of the shaders
|
||||
// Unique shader ID
|
||||
static std::atomic<ID> _nextShaderID;
|
||||
//static std::atomic<ID> _nextShaderID;
|
||||
|
||||
using ShaderMap = std::map<Source, std::weak_ptr<Shader>, Source::Less>;
|
||||
using DomainShaderMaps = std::array<ShaderMap, NUM_DOMAINS>;
|
||||
static DomainShaderMaps _domainShaderMaps;
|
||||
|
||||
static ShaderPointer createOrReuseDomainShader(Type type, const Source& source);
|
||||
static ShaderPointer createOrReuseDomainShader(Type type, uint32_t sourceId);
|
||||
|
||||
using ProgramMapKey = glm::uvec3; // The IDs of the shaders in a program make its key
|
||||
class ProgramKeyLess {
|
||||
|
|
|
@ -98,21 +98,6 @@ enum Attribute {
|
|||
};
|
||||
} // namespace attr
|
||||
|
||||
namespace uniform {
|
||||
enum Uniform {
|
||||
Extra0 = GPU_UNIFORM_EXTRA0,
|
||||
Extra1 = GPU_UNIFORM_EXTRA1,
|
||||
Extra2 = GPU_UNIFORM_EXTRA2,
|
||||
Extra3 = GPU_UNIFORM_EXTRA3,
|
||||
Extra4 = GPU_UNIFORM_EXTRA4,
|
||||
Extra5 = GPU_UNIFORM_EXTRA5,
|
||||
Extra6 = GPU_UNIFORM_EXTRA6,
|
||||
Extra7 = GPU_UNIFORM_EXTRA7,
|
||||
Extra8 = GPU_UNIFORM_EXTRA8,
|
||||
Extra9 = GPU_UNIFORM_EXTRA9,
|
||||
};
|
||||
} // namespace uniform
|
||||
|
||||
} } // namespace gpu::slot
|
||||
|
||||
// !>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define TransformCamera _TransformCamera
|
||||
|
||||
layout(std140, binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffer {
|
||||
LAYOUT_STD140(binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffer {
|
||||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
#ifdef GPU_TRANSFORM_STEREO_CAMERA
|
||||
TransformCamera _camera[2];
|
||||
|
@ -26,7 +26,7 @@ layout(std140, binding=GPU_BUFFER_TRANSFORM_CAMERA) uniform transformCameraBuffe
|
|||
#else
|
||||
TransformCamera _camera;
|
||||
#endif
|
||||
};
|
||||
} _cameraBlock;
|
||||
|
||||
#ifdef GPU_VERTEX_SHADER
|
||||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
|
@ -76,12 +76,12 @@ TransformCamera getTransformCamera() {
|
|||
_stereoSide = gl_InstanceID % 2;
|
||||
#endif
|
||||
#endif
|
||||
return _camera[_stereoSide];
|
||||
return _cameraBlock._camera[_stereoSide];
|
||||
#else
|
||||
return _camera;
|
||||
return _cameraBlock._camera;
|
||||
#endif
|
||||
#else
|
||||
return _camera;
|
||||
return _cameraBlock._camera;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ bool cam_isStereo() {
|
|||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
return getTransformCamera()._stereoInfo.x > 0.0;
|
||||
#else
|
||||
return _camera._stereoInfo.x > 0.0;
|
||||
return _cameraBlock._camera._stereoInfo.x > 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -102,10 +102,10 @@ float cam_getStereoSide() {
|
|||
#ifdef GPU_TRANSFORM_STEREO_CAMERA
|
||||
return getTransformCamera()._stereoInfo.y;
|
||||
#else
|
||||
return _camera._stereoInfo.y;
|
||||
return _cameraBlock._camera._stereoInfo.y;
|
||||
#endif
|
||||
#else
|
||||
return _camera._stereoInfo.y;
|
||||
return _cameraBlock._camera._stereoInfo.y;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ struct TransformObject {
|
|||
layout(location=GPU_ATTR_DRAW_CALL_INFO) in ivec2 _drawCallInfo;
|
||||
|
||||
#if defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
layout(std140, binding=GPU_STORAGE_TRANSFORM_OBJECT) buffer transformObjectBuffer {
|
||||
LAYOUT_STD140(binding=GPU_STORAGE_TRANSFORM_OBJECT) buffer transformObjectBuffer {
|
||||
TransformObject _object[];
|
||||
};
|
||||
TransformObject getTransformObject() {
|
||||
|
@ -128,7 +128,7 @@ TransformObject getTransformObject() {
|
|||
return transformObject;
|
||||
}
|
||||
#else
|
||||
layout(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer;
|
||||
LAYOUT(binding=GPU_TEXTURE_TRANSFORM_OBJECT) uniform samplerBuffer transformObjectBuffer;
|
||||
|
||||
TransformObject getTransformObject() {
|
||||
int offset = 8 * _drawCallInfo.x;
|
||||
|
@ -167,7 +167,9 @@ TransformObject getTransformObject() {
|
|||
vec4 eyeClipEdge[2]= vec4[2](vec4(-1,0,0,1), vec4(1,0,0,1));
|
||||
vec2 eyeOffsetScale = vec2(-0.5, +0.5);
|
||||
uint eyeIndex = uint(_stereoSide);
|
||||
#ifndef GPU_GLES
|
||||
gl_ClipDistance[0] = dot(<$clipPos$>, eyeClipEdge[eyeIndex]);
|
||||
#endif
|
||||
float newClipPosX = <$clipPos$>.x * 0.5 + eyeOffsetScale[eyeIndex] * <$clipPos$>.w;
|
||||
<$clipPos$>.x = newClipPosX;
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,7 @@ float getLightAmbientMapNumMips(LightAmbient l) { return l._ambient.y; }
|
|||
|
||||
|
||||
<@if N@>
|
||||
layout(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_LIGHT) uniform lightBuffer {
|
||||
Light lightArray[<$N$>];
|
||||
};
|
||||
Light getLight(int index) {
|
||||
|
@ -59,7 +59,7 @@ Light getLight(int index) {
|
|||
}
|
||||
|
||||
<@else@>
|
||||
layout(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_KEY_LIGHT) uniform keyLightBuffer {
|
||||
Light light;
|
||||
};
|
||||
Light getKeyLight() {
|
||||
|
@ -79,7 +79,7 @@ Light getKeyLight() {
|
|||
|
||||
<@if N@>
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LightAmbient lightAmbientArray[<$N$>];
|
||||
};
|
||||
|
||||
|
@ -88,7 +88,7 @@ LightAmbient getLightAmbient(int index) {
|
|||
}
|
||||
|
||||
<@else@>
|
||||
layout(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_AMBIENT_LIGHT) uniform lightAmbientBuffer {
|
||||
LightAmbient lightAmbient;
|
||||
};
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ struct Material {
|
|||
vec4 _scatteringSpare2Key;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
|
||||
Material _mat;
|
||||
TexMapArray _texMapArray;
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<@if not MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
<@def MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
@ -91,21 +92,21 @@ float fetchScatteringMap(vec2 uv) {
|
|||
#else
|
||||
|
||||
<@if withAlbedo@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withNormal@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
// unpack normal, swizzle to get into hifi tangent space with Y axis pointing out
|
||||
vec2 t = 2.0 * (texture(normalMap, uv, TAA_TEXTURE_LOD_BIAS).rg - vec2(0.5, 0.5));
|
||||
|
@ -115,28 +116,28 @@ vec3 fetchNormalMap(vec2 uv) {
|
|||
<@endif@>
|
||||
|
||||
<@if withMetallic@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
|
||||
float fetchMetallicMap(vec2 uv) {
|
||||
return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withOcclusion@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
|
||||
float fetchOcclusionMap(vec2 uv) {
|
||||
return texture(occlusionMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withScattering@>
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_SCATTERING) uniform sampler2D scatteringMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SCATTERING) uniform sampler2D scatteringMap;
|
||||
float fetchScatteringMap(vec2 uv) {
|
||||
float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now
|
||||
return max(((scattering - 0.1) / 0.9), 0.0);
|
||||
|
@ -185,7 +186,7 @@ float fetchScatteringMap(vec2 uv) {
|
|||
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||
vec3 fetchLightmapMap(vec2 uv) {
|
||||
vec2 lightmapParams = getTexMapArray()._lightmapParams.xy;
|
||||
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
//
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
|
||||
struct Skybox {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
Skybox skybox;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
set(TARGET_NAME model-networking)
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared networking graphics fbx ktx image gl)
|
||||
link_hifi_libraries(shared shaders networking graphics fbx ktx image gl)
|
||||
include_hifi_library_headers(gpu)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
Q_LOGGING_CATEGORY(proceduralLog, "hifi.gpu.procedural")
|
||||
|
||||
// Userdata parsing constants
|
||||
// User-data parsing constants
|
||||
static const QString PROCEDURAL_USER_DATA_KEY = "ProceduralEntity";
|
||||
static const QString URL_KEY = "shaderUrl";
|
||||
static const QString VERSION_KEY = "version";
|
||||
|
@ -39,10 +39,7 @@ static const std::string PROCEDURAL_BLOCK = "//PROCEDURAL_BLOCK";
|
|||
static const std::string PROCEDURAL_VERSION = "//PROCEDURAL_VERSION";
|
||||
|
||||
bool operator==(const ProceduralData& a, const ProceduralData& b) {
|
||||
return (
|
||||
(a.version == b.version) &&
|
||||
(a.shaderUrl == b.shaderUrl) &&
|
||||
(a.uniforms == b.uniforms) &&
|
||||
return ((a.version == b.version) && (a.shaderUrl == b.shaderUrl) && (a.uniforms == b.uniforms) &&
|
||||
(a.channels == b.channels));
|
||||
}
|
||||
|
||||
|
@ -108,7 +105,9 @@ Procedural::Procedural() {
|
|||
_transparentState->setCullMode(gpu::State::CULL_NONE);
|
||||
_transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
_transparentState->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
_standardInputsBuffer = std::make_shared<gpu::Buffer>(sizeof(StandardInputs), nullptr);
|
||||
}
|
||||
|
||||
void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
||||
|
@ -119,7 +118,7 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
|||
_dirty = true;
|
||||
_enabled = false;
|
||||
|
||||
if (proceduralData.version != _data.version ) {
|
||||
if (proceduralData.version != _data.version) {
|
||||
_data.version = proceduralData.version;
|
||||
_shaderDirty = true;
|
||||
}
|
||||
|
@ -144,7 +143,6 @@ void Procedural::setProceduralData(const ProceduralData& proceduralData) {
|
|||
_channels[channel] = textureCache->getTexture(QUrl());
|
||||
}
|
||||
}
|
||||
_channelsDirty = true;
|
||||
}
|
||||
|
||||
if (proceduralData.shaderUrl != _data.shaderUrl) {
|
||||
|
@ -212,28 +210,11 @@ bool Procedural::isReady() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
std::string Procedural::replaceProceduralBlock(const std::string& fragmentSource) {
|
||||
std::string result = fragmentSource;
|
||||
auto replaceIndex = result.find(PROCEDURAL_VERSION);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
if (_data.version == 1) {
|
||||
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
|
||||
} else if (_data.version == 2) {
|
||||
result.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
|
||||
}
|
||||
}
|
||||
replaceIndex = result.find(PROCEDURAL_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
result.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Procedural::prepare(gpu::Batch& batch,
|
||||
const glm::vec3& position,
|
||||
const glm::vec3& size,
|
||||
const glm::quat& orientation,
|
||||
const glm::vec4& color) {
|
||||
const glm::vec3& position,
|
||||
const glm::vec3& size,
|
||||
const glm::quat& orientation,
|
||||
const glm::vec4& color) {
|
||||
_entityDimensions = size;
|
||||
_entityPosition = position;
|
||||
_entityOrientation = glm::mat3_cast(orientation);
|
||||
|
@ -256,19 +237,21 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
}
|
||||
|
||||
// Build the fragment shader
|
||||
std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource.getCode());
|
||||
auto opaqueReflection = _opaquefragmentSource.getReflection();
|
||||
auto& opaqueUniforms = opaqueReflection[gpu::Shader::BindingType::UNIFORM];
|
||||
std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource.getCode());
|
||||
auto transparentReflection = _transparentfragmentSource.getReflection();
|
||||
auto& transparentUniforms = transparentReflection[gpu::Shader::BindingType::UNIFORM];
|
||||
_opaqueFragmentSource.replacements.clear();
|
||||
if (_data.version == 1) {
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V1 1";
|
||||
} else if (_data.version == 2) {
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_VERSION] = "#define PROCEDURAL_V2 1";
|
||||
}
|
||||
_opaqueFragmentSource.replacements[PROCEDURAL_BLOCK] = _shaderSource.toStdString();
|
||||
_transparentFragmentSource.replacements = _opaqueFragmentSource.replacements;
|
||||
|
||||
// Set any userdata specified uniforms
|
||||
int customSlot = procedural::slot::uniform::Custom;
|
||||
for (const auto& key : _data.uniforms.keys()) {
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
opaqueUniforms[uniformName] = customSlot;
|
||||
transparentUniforms[uniformName] = customSlot;
|
||||
_opaqueFragmentSource.reflection.uniforms[uniformName] = customSlot;
|
||||
_transparentFragmentSource.reflection.uniforms[uniformName] = customSlot;
|
||||
++customSlot;
|
||||
}
|
||||
|
||||
|
@ -276,18 +259,18 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
// qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str();
|
||||
|
||||
// TODO: THis is a simple fix, we need a cleaner way to provide the "hosting" program for procedural custom shaders to be defined together with the required bindings.
|
||||
_opaqueFragmentShader = gpu::Shader::createPixel({ opaqueShaderSource, opaqueReflection });
|
||||
_opaqueFragmentShader = gpu::Shader::createPixel(_opaqueFragmentSource);
|
||||
_opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader);
|
||||
if (!transparentShaderSource.empty() && transparentShaderSource != opaqueShaderSource) {
|
||||
_transparentFragmentShader = gpu::Shader::createPixel({ transparentShaderSource, transparentReflection });
|
||||
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
|
||||
if (_transparentFragmentSource.valid()) {
|
||||
_transparentFragmentShader = gpu::Shader::createPixel(_transparentFragmentSource);
|
||||
_transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader);
|
||||
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
|
||||
} else {
|
||||
_transparentFragmentShader = _opaqueFragmentShader;
|
||||
_transparentShader = _opaqueShader;
|
||||
_transparentPipeline = _opaquePipeline;
|
||||
}
|
||||
|
||||
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
|
||||
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
|
||||
_start = usecTimestampNow();
|
||||
_frameCount = 0;
|
||||
}
|
||||
|
@ -299,12 +282,8 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
setupUniforms(transparent);
|
||||
}
|
||||
|
||||
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
|
||||
setupChannels(_shaderDirty || _uniformsDirty, transparent);
|
||||
}
|
||||
|
||||
_prevTransparent = transparent;
|
||||
_shaderDirty = _uniformsDirty = _channelsDirty = false;
|
||||
_shaderDirty = _uniformsDirty = false;
|
||||
|
||||
for (auto lambda : _uniforms) {
|
||||
lambda(batch);
|
||||
|
@ -329,18 +308,13 @@ void Procedural::prepare(gpu::Batch& batch,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Procedural::setupUniforms(bool transparent) {
|
||||
_uniforms.clear();
|
||||
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
|
||||
const auto& uniformSlots = pipeline->getUniforms();
|
||||
auto customUniformCount = _data.uniforms.keys().size();
|
||||
|
||||
// Set any userdata specified uniforms
|
||||
for (int i = 0; i < customUniformCount; ++i) {
|
||||
int slot = procedural::slot::uniform::Custom + i;
|
||||
if (!uniformSlots.isValid(slot)) {
|
||||
continue;
|
||||
}
|
||||
QString key = _data.uniforms.keys().at(i);
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
QJsonValue value = _data.uniforms[key];
|
||||
|
@ -350,113 +324,80 @@ void Procedural::setupUniforms(bool transparent) {
|
|||
} else if (value.isArray()) {
|
||||
auto valueArray = value.toArray();
|
||||
switch (valueArray.size()) {
|
||||
case 0:
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
float v = valueArray[0].toDouble();
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform1f(slot, v); });
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
float v = valueArray[0].toDouble();
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform1f(slot, v); });
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
glm::vec2 v{ valueArray[0].toDouble(), valueArray[1].toDouble() };
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform2f(slot, v.x, v.y); });
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
glm::vec2 v{ valueArray[0].toDouble(), valueArray[1].toDouble() };
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform2f(slot, v.x, v.y); });
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
glm::vec3 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform3f(slot, v.x, v.y, v.z); });
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
glm::vec3 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform3f(slot, v.x, v.y, v.z); });
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
case 4: {
|
||||
glm::vec4 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
valueArray[3].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform4f(slot, v.x, v.y, v.z, v.w); });
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case 4: {
|
||||
glm::vec4 v{
|
||||
valueArray[0].toDouble(),
|
||||
valueArray[1].toDouble(),
|
||||
valueArray[2].toDouble(),
|
||||
valueArray[3].toDouble(),
|
||||
};
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform4f(slot, v.x, v.y, v.z, v.w); });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Time)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
batch._glUniform(procedural::slot::uniform::Time, time);
|
||||
});
|
||||
}
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
_standardInputs.position = vec4(_entityPosition, 1.0f);
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
_standardInputs.time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Date)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Date
|
||||
{
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
QDate date = now.date();
|
||||
QTime time = now.time();
|
||||
vec4 v;
|
||||
v.x = date.year();
|
||||
_standardInputs.date.x = date.year();
|
||||
// Shadertoy month is 0 based
|
||||
v.y = date.month() - 1;
|
||||
_standardInputs.date.y = date.month() - 1;
|
||||
// But not the day... go figure
|
||||
v.z = date.day();
|
||||
_standardInputs.date.z = date.day();
|
||||
float fractSeconds = (time.msec() / 1000.0f);
|
||||
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
batch._glUniform(procedural::slot::uniform::Date, v);
|
||||
});
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::FrameCount)) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::FrameCount, ++_frameCount); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Scale)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back([=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Scale, _entityDimensions); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Orientation)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back(
|
||||
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityOrientation); });
|
||||
}
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::Position)) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back(
|
||||
[=](gpu::Batch& batch) { batch._glUniform(procedural::slot::uniform::Orientation, _entityPosition); });
|
||||
}
|
||||
}
|
||||
|
||||
void Procedural::setupChannels(bool shouldCreate, bool transparent) {
|
||||
auto& pipeline = transparent ? _transparentShader : _opaqueShader;
|
||||
const auto& uniformSlots = pipeline->getUniforms();
|
||||
|
||||
if (uniformSlots.isValid(procedural::slot::uniform::ChannelResolution)) {
|
||||
if (!shouldCreate) {
|
||||
// Instead of modifying the last element, just remove and recreate it.
|
||||
_uniforms.pop_back();
|
||||
_standardInputs.date.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
}
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
vec3 channelSizes[MAX_PROCEDURAL_TEXTURE_CHANNELS];
|
||||
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
|
||||
if (_channels[i]) {
|
||||
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0);
|
||||
}
|
||||
|
||||
_standardInputs.scale = vec4(_entityDimensions, 1.0f);
|
||||
_standardInputs.frameCount = ++_frameCount;
|
||||
_standardInputs.orientation = mat4(_entityOrientation);
|
||||
|
||||
for (size_t i = 0; i < MAX_PROCEDURAL_TEXTURE_CHANNELS; ++i) {
|
||||
if (_channels[i]) {
|
||||
_standardInputs.resolution[i] = vec4(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0f, 1.0f);
|
||||
} else {
|
||||
_standardInputs.resolution[i] = vec4(1.0f);
|
||||
}
|
||||
batch._glUniform3fv(procedural::slot::uniform::ChannelResolution, MAX_PROCEDURAL_TEXTURE_CHANNELS,
|
||||
&channelSizes[0].x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_standardInputsBuffer->setSubData(0, _standardInputs);
|
||||
batch.setUniformBuffer(0, _standardInputsBuffer, 0, sizeof(StandardInputs));
|
||||
});
|
||||
}
|
||||
|
||||
glm::vec4 Procedural::getColor(const glm::vec4& entityColor) {
|
||||
|
|
|
@ -65,14 +65,37 @@ public:
|
|||
void setDoesFade(bool doesFade) { _doesFade = doesFade; }
|
||||
|
||||
gpu::Shader::Source _vertexSource;
|
||||
gpu::Shader::Source _opaquefragmentSource;
|
||||
gpu::Shader::Source _transparentfragmentSource;
|
||||
gpu::Shader::Source _opaqueFragmentSource;
|
||||
gpu::Shader::Source _transparentFragmentSource;
|
||||
|
||||
gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() };
|
||||
gpu::StatePointer _transparentState { std::make_shared<gpu::State>() };
|
||||
|
||||
|
||||
protected:
|
||||
// DO NOT TOUCH
|
||||
// We have to pack these in a particular way to match the ProceduralCommon.slh
|
||||
// layout.
|
||||
struct StandardInputs {
|
||||
vec4 date;
|
||||
vec4 position;
|
||||
vec4 scale;
|
||||
float time;
|
||||
int frameCount;
|
||||
vec2 _spare1;
|
||||
vec4 resolution[4];
|
||||
mat4 orientation;
|
||||
};
|
||||
|
||||
static_assert(0 == offsetof(StandardInputs, date), "ProceduralOffsets");
|
||||
static_assert(16 == offsetof(StandardInputs, position), "ProceduralOffsets");
|
||||
static_assert(32 == offsetof(StandardInputs, scale), "ProceduralOffsets");
|
||||
static_assert(48 == offsetof(StandardInputs, time), "ProceduralOffsets");
|
||||
static_assert(52 == offsetof(StandardInputs, frameCount), "ProceduralOffsets");
|
||||
static_assert(56 == offsetof(StandardInputs, _spare1), "ProceduralOffsets");
|
||||
static_assert(64 == offsetof(StandardInputs, resolution), "ProceduralOffsets");
|
||||
static_assert(128 == offsetof(StandardInputs, orientation), "ProceduralOffsets");
|
||||
|
||||
// Procedural metadata
|
||||
ProceduralData _data;
|
||||
|
||||
|
@ -88,13 +111,14 @@ protected:
|
|||
bool _dirty { false };
|
||||
bool _shaderDirty { true };
|
||||
bool _uniformsDirty { true };
|
||||
bool _channelsDirty { true };
|
||||
|
||||
// Rendering objects
|
||||
UniformLambdas _uniforms;
|
||||
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
|
||||
gpu::PipelinePointer _opaquePipeline;
|
||||
gpu::PipelinePointer _transparentPipeline;
|
||||
StandardInputs _standardInputs;
|
||||
gpu::BufferPointer _standardInputsBuffer;
|
||||
gpu::ShaderPointer _vertexShader;
|
||||
gpu::ShaderPointer _opaqueFragmentShader;
|
||||
gpu::ShaderPointer _transparentFragmentShader;
|
||||
|
@ -109,9 +133,6 @@ protected:
|
|||
private:
|
||||
// This should only be called from the render thread, as it shares data with Procedural::prepare
|
||||
void setupUniforms(bool transparent);
|
||||
void setupChannels(bool shouldCreate, bool transparent);
|
||||
|
||||
std::string replaceProceduralBlock(const std::string& fragmentSource);
|
||||
|
||||
mutable quint64 _fadeStartTime { 0 };
|
||||
mutable bool _hasStartedFade { false };
|
||||
|
|
|
@ -14,18 +14,48 @@
|
|||
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
#define PROCEDURAL 1
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
|
||||
LAYOUT(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
|
||||
|
||||
//PROCEDURAL_VERSION
|
||||
// DO NOT TOUCH
|
||||
// This block does not follow our normal rules of always using a struct and
|
||||
// always using 16 byte aligned types like vec4 and mat4
|
||||
//
|
||||
// This is because this block must be EXACTLY how it is in order to maintain
|
||||
// comptability with existing procedural shaders that previously relied on these
|
||||
// inputs as uniforms, not members of a UBO
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
LAYOUT_STD140(binding=0) uniform standardInputsBuffer {
|
||||
// Offset 0
|
||||
vec4 date;
|
||||
// Offset 16, acts as vec4 for alignment purposes
|
||||
vec3 worldPosition;
|
||||
// Offset 32, acts as vec4 for alignment purposes
|
||||
vec3 worldScale;
|
||||
// Offset 48
|
||||
float globalTime;
|
||||
// Offset 52
|
||||
int frameCount;
|
||||
// Offset 56
|
||||
vec2 _spare1;
|
||||
// Offset 64, acts as vec4[4] for alignment purposes
|
||||
vec3 channelResolution[4];
|
||||
// Offset 128, acts as vec4[3] for alignment purposes
|
||||
// Also, each individual component is aligned as a vec4
|
||||
mat3 worldOrientation;
|
||||
// Offset 176
|
||||
vec4 _spare2;
|
||||
} standardInputs;
|
||||
|
||||
// shader playback time (in seconds)
|
||||
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime;
|
||||
// the dimensions of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale;
|
||||
|
||||
#else
|
||||
#define iDate standardInputs.date
|
||||
#define iWorldPosition standardInputs.worldPosition
|
||||
#define iWorldScale standardInputs.worldScale
|
||||
#define iGlobalTime standardInputs.globalTime
|
||||
#define iFrameCount standardInputs.frameCount
|
||||
#define iChannelResolution standardInputs.channelResolution
|
||||
#define iWorldOrientation standardInputs.worldOrientation
|
||||
|
||||
// Unimplemented uniforms
|
||||
// Resolution doesn't make sense in the VR context
|
||||
|
@ -37,20 +67,9 @@ const float iSampleRate = 1.0;
|
|||
// No support for video input
|
||||
const vec4 iChannelTime = vec4(0.0);
|
||||
|
||||
#define PROCEDURAL 1
|
||||
|
||||
layout(location=PROCEDURAL_UNIFORM_TIME) uniform float iGlobalTime; // shader playback time (in seconds)
|
||||
layout(location=PROCEDURAL_UNIFORM_DATE) uniform vec4 iDate;
|
||||
layout(location=PROCEDURAL_UNIFORM_FRAME_COUNT) uniform int iFrameCount;
|
||||
layout(location=PROCEDURAL_UNIFORM_POSITION) uniform vec3 iWorldPosition; // the position of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_SCALE) uniform vec3 iWorldScale; // the dimensions of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_ORIENTATION) uniform mat3 iWorldOrientation; // the orientation of the object being rendered
|
||||
layout(location=PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION) uniform vec3 iChannelResolution[4];
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL0) uniform sampler2D iChannel0;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL1) uniform sampler2D iChannel1;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL2) uniform sampler2D iChannel2;
|
||||
layout(binding=PROCEDURAL_TEXTURE_CHANNEL3) uniform sampler2D iChannel3;
|
||||
|
||||
#endif
|
||||
//PROCEDURAL_VERSION
|
||||
|
||||
// hack comment for extra whitespace
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
|
||||
_procedural._vertexSource = gpu::Shader::createVertex(shader::graphics::vertex::skybox)->getSource();
|
||||
_procedural._opaquefragmentSource = gpu::Shader::createPixel(shader::procedural::fragment::proceduralSkybox)->getSource();
|
||||
_procedural._opaqueFragmentSource = shader::Source::get(shader::procedural::fragment::proceduralSkybox);
|
||||
// Adjust the pipeline state for background using the stencil test
|
||||
_procedural.setDoesFade(false);
|
||||
// Must match PrepareStencil::STENCIL_BACKGROUND
|
||||
|
|
|
@ -14,14 +14,6 @@
|
|||
#ifndef PROCEDURAL_SHADER_CONSTANTS_H
|
||||
#define PROCEDURAL_SHADER_CONSTANTS_H
|
||||
|
||||
#define PROCEDURAL_UNIFORM_TIME 200
|
||||
#define PROCEDURAL_UNIFORM_DATE 201
|
||||
#define PROCEDURAL_UNIFORM_FRAME_COUNT 202
|
||||
#define PROCEDURAL_UNIFORM_POSITION 203
|
||||
#define PROCEDURAL_UNIFORM_SCALE 204
|
||||
#define PROCEDURAL_UNIFORM_ORIENTATION 205
|
||||
// Additional space because orientation will take up 3-4 locations, being a matrix
|
||||
#define PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION 209
|
||||
#define PROCEDURAL_UNIFORM_CUSTOM 220
|
||||
|
||||
#define PROCEDURAL_TEXTURE_CHANNEL0 0
|
||||
|
@ -33,15 +25,9 @@
|
|||
|
||||
namespace procedural { namespace slot {
|
||||
|
||||
|
||||
namespace uniform {
|
||||
enum Uniform {
|
||||
Time = PROCEDURAL_UNIFORM_TIME,
|
||||
Date = PROCEDURAL_UNIFORM_DATE,
|
||||
FrameCount = PROCEDURAL_UNIFORM_FRAME_COUNT,
|
||||
Position = PROCEDURAL_UNIFORM_POSITION,
|
||||
Scale = PROCEDURAL_UNIFORM_SCALE,
|
||||
Orientation = PROCEDURAL_UNIFORM_ORIENTATION,
|
||||
ChannelResolution = PROCEDURAL_UNIFORM_CHANNEL_RESOLUTION,
|
||||
Custom = PROCEDURAL_UNIFORM_CUSTOM,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
//
|
||||
<@include graphics/ShaderConstants.h@>
|
||||
|
||||
layout(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
LAYOUT(binding=GRAPHICS_TEXTURE_SKYBOX) uniform samplerCube cubeMap;
|
||||
|
||||
struct Skybox {
|
||||
vec4 color;
|
||||
};
|
||||
|
||||
layout(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
LAYOUT(binding=GRAPHICS_BUFFER_SKYBOX_PARAMS) uniform skyboxBuffer {
|
||||
Skybox skybox;
|
||||
};
|
||||
|
||||
|
@ -28,9 +28,13 @@ layout(location=0) out vec4 _fragColor;
|
|||
<@include procedural/ProceduralCommon.slh@>
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
//PROCEDURAL_BLOCK_BEGIN
|
||||
vec3 getSkyboxColor() {
|
||||
return vec3(abs(sin(iGlobalTime / 5.0)), 1.0, 0.0);
|
||||
}
|
||||
//PROCEDURAL_BLOCK_END
|
||||
|
||||
#line 2033
|
||||
#line 2038
|
||||
void main(void) {
|
||||
vec3 color = getSkyboxColor();
|
||||
// Protect from NaNs and negative values
|
||||
|
|
1
libraries/procedural/src/procedural/proceduralSkybox.slp
Normal file
1
libraries/procedural/src/procedural/proceduralSkybox.slp
Normal file
|
@ -0,0 +1 @@
|
|||
VERTEX graphics::vertex::skybox
|
|
@ -10,13 +10,13 @@
|
|||
|
||||
<@func declareBlendshape(USE_NORMAL, USE_TANGENT)@>
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer blendshapeOffsetsBuffer;
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
return floatBitsToUint(texelFetch(blendshapeOffsetsBuffer, i));
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer blendshapeOffsetsBuffer {
|
||||
LAYOUT_STD140(binding=0) buffer blendshapeOffsetsBuffer {
|
||||
uvec4 _packedBlendshapeOffsets[];
|
||||
};
|
||||
uvec4 getPackedBlendshapeOffset(int i) {
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
<@include BloomApply.shared.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(binding=0) uniform sampler2D blurMap0;
|
||||
layout(binding=1) uniform sampler2D blurMap1;
|
||||
layout(binding=2) uniform sampler2D blurMap2;
|
||||
LAYOUT(binding=0) uniform sampler2D blurMap0;
|
||||
LAYOUT(binding=1) uniform sampler2D blurMap1;
|
||||
LAYOUT(binding=2) uniform sampler2D blurMap2;
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
<@include BloomThreshold.shared.slh@>
|
||||
<@include render-utils/ShaderConstants.h@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap;
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_BLOOM_COLOR) uniform sampler2D colorMap;
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_BLOOM_PARAMS) uniform parametersBuffer {
|
||||
Parameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -243,7 +243,7 @@ static const std::string DEFAULT_CUSTOM_SHADER{
|
|||
" }"
|
||||
};
|
||||
|
||||
static std::string getFileContent(std::string fileName, std::string defaultContent = std::string()) {
|
||||
static std::string getFileContent(const std::string& fileName, const std::string& defaultContent = std::string()) {
|
||||
QFile customFile(QString::fromStdString(fileName));
|
||||
if (customFile.open(QIODevice::ReadOnly)) {
|
||||
return customFile.readAll().toStdString();
|
||||
|
@ -270,7 +270,7 @@ DebugDeferredBuffer::~DebugDeferredBuffer() {
|
|||
}
|
||||
}
|
||||
|
||||
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string customFile) {
|
||||
std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, const std::string& customFile) {
|
||||
switch (mode) {
|
||||
case AlbedoMode:
|
||||
return DEFAULT_ALBEDO_SHADER;
|
||||
|
@ -334,7 +334,7 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
|
|||
return std::string();
|
||||
}
|
||||
|
||||
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile) const {
|
||||
bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, const std::string& customFile) const {
|
||||
if (mode != CustomMode) {
|
||||
return !_pipelines[mode];
|
||||
}
|
||||
|
@ -351,19 +351,17 @@ bool DebugDeferredBuffer::pipelineNeedsUpdate(Mode mode, std::string customFile)
|
|||
return true;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, std::string customFile) {
|
||||
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Mode mode, const std::string& customFile) {
|
||||
if (pipelineNeedsUpdate(mode, customFile)) {
|
||||
static const auto FRAGMENT_SHADER_SOURCE =
|
||||
gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
|
||||
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
|
||||
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
|
||||
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO, "Could not find source placeholder");
|
||||
static_assert(shader::render_utils::program::debug_deferred_buffer != 0, "Validate debug deferred program");
|
||||
|
||||
auto bakedFragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
|
||||
bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), getShaderSourceCode(mode, customFile));
|
||||
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
|
||||
shader::Source resolvedFragmentSource;
|
||||
resolvedFragmentSource = shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
|
||||
resolvedFragmentSource.replacements[REPLACEMENT_MARKER] = getShaderSourceCode(mode, customFile);
|
||||
|
||||
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
const auto ps = gpu::Shader::createPixel({ bakedFragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
|
||||
const auto ps = gpu::Shader::createPixel(resolvedFragmentSource);
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());
|
||||
|
||||
|
|
|
@ -112,9 +112,9 @@ private:
|
|||
using StandardPipelines = std::array<gpu::PipelinePointer, NumModes>;
|
||||
using CustomPipelines = std::unordered_map<std::string, CustomPipeline>;
|
||||
|
||||
bool pipelineNeedsUpdate(Mode mode, std::string customFile = std::string()) const;
|
||||
const gpu::PipelinePointer& getPipeline(Mode mode, std::string customFile = std::string());
|
||||
std::string getShaderSourceCode(Mode mode, std::string customFile = std::string());
|
||||
bool pipelineNeedsUpdate(Mode mode, const std::string& customFile = std::string()) const;
|
||||
const gpu::PipelinePointer& getPipeline(Mode mode, const std::string& customFile = std::string());
|
||||
std::string getShaderSourceCode(Mode mode, const std::string& customFile = std::string());
|
||||
|
||||
ParametersBuffer _parameters;
|
||||
StandardPipelines _pipelines;
|
||||
|
|
|
@ -17,23 +17,23 @@
|
|||
// See DeferredShader_MapSlot in DeferredLightingEffect.cpp for constants
|
||||
|
||||
// the albedo texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_COLOR) uniform sampler2D albedoMap;
|
||||
|
||||
// the normal texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL) uniform sampler2D normalMap;
|
||||
|
||||
// the specular texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_SPECULAR) uniform sampler2D specularMap;
|
||||
|
||||
// the depth texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_DEPTH) uniform sampler2D depthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRRED_LINEAR_Z_EYE) uniform sampler2D linearZeyeMap;
|
||||
|
||||
// the obscurance texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_OBSCURANCE) uniform sampler2D obscuranceMap;
|
||||
|
||||
// the lighting texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING) uniform sampler2D lightingMap;
|
||||
|
||||
|
||||
struct DeferredFragment {
|
||||
|
@ -170,14 +170,14 @@ DeferredFragment unpackDeferredFragment(DeferredFrameTransform deferredTransform
|
|||
<@func declareDeferredCurvature()@>
|
||||
|
||||
// the curvature texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE) uniform sampler2D curvatureMap;
|
||||
|
||||
vec4 fetchCurvature(vec2 texcoord) {
|
||||
return texture(curvatureMap, texcoord);
|
||||
}
|
||||
|
||||
// the curvature texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE) uniform sampler2D diffusedCurvatureMap;
|
||||
|
||||
vec4 fetchDiffusedCurvature(vec2 texcoord) {
|
||||
return texture(diffusedCurvatureMap, texcoord);
|
||||
|
|
|
@ -44,7 +44,7 @@ using namespace render;
|
|||
struct LightLocations {
|
||||
bool shadowTransform{ false };
|
||||
void initialize(const gpu::ShaderPointer& program) {
|
||||
shadowTransform = program->getUniformBuffers().isValid(ru::Buffer::ShadowParams);
|
||||
shadowTransform = program->getReflection().validUniformBuffer(ru::Buffer::ShadowParams);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ struct CameraCorrection {
|
|||
mat4 _prevViewInverse;
|
||||
};
|
||||
|
||||
layout(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
|
||||
LAYOUT(binding=GPU_BUFFER_CAMERA_CORRECTION) uniform cameraCorrectionBuffer {
|
||||
CameraCorrection cameraCorrection;
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ struct DeferredFrameTransform {
|
|||
mat4 _invProjectionUnJittered[2];
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer {
|
||||
DeferredFrameTransform frameTransform;
|
||||
};
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
<@include FadeObjectParams.shared.slh@>
|
||||
|
||||
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_PARAMS) uniform fadeParametersBuffer {
|
||||
FadeParameters fadeParameters[CATEGORY_COUNT];
|
||||
};
|
||||
|
||||
// See ShapePipeline::Slot::MAP in ShapePipeline.h
|
||||
layout(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_FADE_MASK) uniform sampler2D fadeMaskMap;
|
||||
|
||||
vec3 getNoiseInverseSize(int category) {
|
||||
return fadeParameters[category]._noiseInvSizeAndLevel.xyz;
|
||||
|
@ -117,7 +117,7 @@ void applyFade(FadeObjectParams params, vec3 position, out vec3 emissive) {
|
|||
|
||||
<@func declareFadeFragmentUniform()@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS) uniform fadeObjectParametersBuffer {
|
||||
FadeObjectParams fadeObjectParams;
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<@include Haze.slh@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH) uniform sampler2D linearDepthMap;
|
||||
|
||||
vec4 unpackPositionFromZeye(vec2 texcoord) {
|
||||
float Zeye = -texture(linearDepthMap, texcoord).x;
|
||||
|
|
|
@ -39,7 +39,7 @@ struct HazeParams {
|
|||
};
|
||||
|
||||
// See ShapePipeline::Slot::BUFFER in ShapePipeline.h
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HAZE_PARAMS) uniform hazeBuffer {
|
||||
HazeParams hazeParams;
|
||||
};
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
<@include Highlight_shared.slh@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuffer {
|
||||
HighlightParameters params;
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap;
|
||||
|
||||
layout(location=0) in vec2 varTexCoord0;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
|
|
@ -402,36 +402,31 @@ void DebugHighlight::run(const render::RenderContextPointer& renderContext, cons
|
|||
}
|
||||
|
||||
void DebugHighlight::initializePipelines() {
|
||||
static const auto FRAGMENT_SHADER_SOURCE = gpu::Shader::createPixel(shader::render_utils::fragment::debug_deferred_buffer)->getSource();
|
||||
static const std::string SOURCE_PLACEHOLDER{ "//SOURCE_PLACEHOLDER" };
|
||||
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER_SOURCE.getCode().find(SOURCE_PLACEHOLDER);
|
||||
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
|
||||
"Could not find source placeholder");
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setDepthTest(gpu::State::DepthTest(false, false));
|
||||
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
|
||||
state->setColorWriteMask(true, true, true, true);
|
||||
|
||||
const auto vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
|
||||
static const std::string REPLACEMENT_MARKER{ "//SOURCE_PLACEHOLDER" };
|
||||
// Depth shader
|
||||
{
|
||||
static const std::string DEPTH_SHADER{ R"SHADER(
|
||||
static const std::string DEPTH_SHADER{ R"SHADER(
|
||||
vec4 getFragmentColor() {
|
||||
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
|
||||
Zdb = 1.0-(1.0-Zdb)*100;
|
||||
return vec4(Zdb, Zdb, Zdb, 1.0);
|
||||
}
|
||||
)SHADER" };
|
||||
static const auto& vs = gpu::Shader::createVertex(shader::render_utils::vertex::debug_deferred_buffer);
|
||||
|
||||
auto fragmentShader = FRAGMENT_SHADER_SOURCE.getCode();
|
||||
fragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(), DEPTH_SHADER);
|
||||
|
||||
const auto ps = gpu::Shader::createPixel({ fragmentShader, FRAGMENT_SHADER_SOURCE.getReflection() });
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
_depthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
gpu::Shader::Source fragmentSource;
|
||||
fragmentSource = gpu::Shader::Source::get(shader::render_utils::fragment::debug_deferred_buffer);
|
||||
fragmentSource.replacements[REPLACEMENT_MARKER] = DEPTH_SHADER;
|
||||
|
||||
const auto ps = gpu::Shader::createPixel(fragmentSource);
|
||||
const auto program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
auto state = std::make_shared<gpu::State>();
|
||||
state->setDepthTest(gpu::State::DepthTest(false, false));
|
||||
state->setStencilTest(true, 0, gpu::State::StencilTest(OUTLINE_STENCIL_MASK, 0xFF, gpu::EQUAL));
|
||||
state->setColorWriteMask(true, true, true, true);
|
||||
|
||||
_depthPipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& DebugHighlight::getDepthPipeline() {
|
||||
|
|
|
@ -22,8 +22,8 @@ struct ItemBound {
|
|||
vec4 boundDim_s;
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer ssbo0Buffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer ssbo0Buffer;
|
||||
ItemBound getItemBound(int i) {
|
||||
int offset = 2 * i;
|
||||
ItemBound bound;
|
||||
|
@ -32,7 +32,7 @@ ItemBound getItemBound(int i) {
|
|||
return bound;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer ssbo0Buffer {
|
||||
LAYOUT_STD140(binding=0) buffer ssbo0Buffer {
|
||||
ItemBound bounds[];
|
||||
};
|
||||
ItemBound getItemBound(int i) {
|
||||
|
@ -45,7 +45,7 @@ struct HighlightParameters {
|
|||
vec2 outlineWidth;
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform parametersBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform parametersBuffer {
|
||||
HighlightParameters _parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<@include render-utils/ShaderConstants.h@>
|
||||
<@func declareSkyboxMap()@>
|
||||
// declareSkyboxMap
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SKYBOX) uniform samplerCube skyboxMap;
|
||||
|
||||
vec4 evalSkyboxLight(vec3 direction, float lod) {
|
||||
// textureQueryLevels is not available until #430, so we require explicit lod
|
||||
|
|
|
@ -24,7 +24,7 @@ struct FrustumGrid {
|
|||
mat4 eyeToWorldMat;
|
||||
};
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID) uniform frustumGridBuffer {
|
||||
FrustumGrid frustumGrid;
|
||||
};
|
||||
|
||||
|
@ -60,11 +60,11 @@ float projection_getFar(mat4 projection) {
|
|||
#define GRID_FETCH_BUFFER(i) i!>
|
||||
<@endif@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID) uniform clusterGridBuffer {
|
||||
GRID_INDEX_TYPE _clusterGridTable[GRID_NUM_ELEMENTS];
|
||||
};
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT) uniform clusterContentBuffer {
|
||||
GRID_INDEX_TYPE _clusterGridContent[GRID_NUM_ELEMENTS];
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ struct LightingModel {
|
|||
};
|
||||
|
||||
// See DeferredShader_BufferSlot in DeferredLightingEffect.cpp
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_MODEL) uniform lightingModelBuffer{
|
||||
LightingModel lightingModel;
|
||||
};
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
}
|
||||
|
||||
void initForwardPipelines(ShapePlumber& plumber) {
|
||||
using namespace shader::render_utils::program;
|
||||
using namespace shader::render_utils;
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4);
|
||||
|
@ -244,33 +244,33 @@ void initForwardPipelines(ShapePlumber& plumber) {
|
|||
forceLightBatchSetter = true;
|
||||
|
||||
// Simple Opaques
|
||||
addPipeline(Key::Builder(), simple);
|
||||
addPipeline(Key::Builder().withUnlit(), simpleUnlit);
|
||||
addPipeline(Key::Builder(), program::forward_simple_textured);
|
||||
addPipeline(Key::Builder().withUnlit(), program::forward_simple_textured_unlit);
|
||||
|
||||
// Simple Translucents
|
||||
addPipeline(Key::Builder().withTranslucent(), simpleTranslucent);
|
||||
addPipeline(Key::Builder().withTranslucent().withUnlit(), simpleTranslucentUnlit);
|
||||
addPipeline(Key::Builder().withTranslucent(), program::forward_simple_textured_transparent);
|
||||
addPipeline(Key::Builder().withTranslucent().withUnlit(), program::simple_transparent_textured_unlit);
|
||||
|
||||
// Opaques
|
||||
addPipeline(Key::Builder().withMaterial(), forward_model);
|
||||
addPipeline(Key::Builder().withMaterial().withUnlit(), forward_model_unlit);
|
||||
addPipeline(Key::Builder().withMaterial().withTangents(), forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial(), program::forward_model);
|
||||
addPipeline(Key::Builder().withMaterial().withUnlit(), program::forward_model_unlit);
|
||||
addPipeline(Key::Builder().withMaterial().withTangents(), program::forward_model_translucent);
|
||||
|
||||
// Deformed Opaques
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed(), forward_deformed_model);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), forward_deformed_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), forward_deformed_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), forward_deformed_model_normal_map_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed(), program::forward_deformed_model);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents(), program::forward_deformed_model_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), program::forward_deformed_model_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTangents().withDualQuatSkinned(), program::forward_deformed_model_normal_map_dq);
|
||||
|
||||
// Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent(), forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), forward_model_normal_map_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent(), program::forward_model_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withTranslucent().withTangents(), program::forward_model_normal_map_translucent);
|
||||
|
||||
// Deformed Translucents
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), forward_deformed_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), forward_deformed_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), forward_deformed_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), forward_deformed_translucent_normal_map_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent(), program::forward_deformed_translucent);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents(), program::forward_deformed_translucent_normal_map);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withDualQuatSkinned(), program::forward_deformed_translucent_dq);
|
||||
addPipeline(Key::Builder().withMaterial().withDeformed().withTranslucent().withTangents().withDualQuatSkinned(), program::forward_deformed_translucent_normal_map_dq);
|
||||
|
||||
forceLightBatchSetter = false;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<@func declareBeckmannSpecular()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_SPECULAR_BECKMANN) uniform sampler2D scatteringSpecularBeckmann;
|
||||
|
||||
float fetchSpecularBeckmann(float ndoth, float roughness) {
|
||||
return pow(2.0 * texture(scatteringSpecularBeckmann, vec2(ndoth, roughness)).r, 10.0);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define SHADOW_SCREEN_SPACE_DITHER 1
|
||||
|
||||
// the shadow texture
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
|
||||
// Sample the shadowMap with PCF (built-in)
|
||||
float fetchShadow(int cascadeIndex, vec3 shadowTexcoord) {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<@include Shadows_shared.slh@>
|
||||
|
||||
layout(std140, binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
|
||||
LAYOUT_STD140(binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer {
|
||||
ShadowParameters shadow;
|
||||
};
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
const int MAX_CLUSTERS = 128;
|
||||
const int INDICES_PER_VERTEX = 4;
|
||||
|
||||
layout(std140, binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
|
||||
LAYOUT_STD140(binding=GRAPHICS_BUFFER_SKINNING) uniform skinClusterBuffer {
|
||||
mat4 clusterMatrices[MAX_CLUSTERS];
|
||||
};
|
||||
|
||||
|
|
|
@ -421,6 +421,10 @@ void DebugSubsurfaceScattering::configure(const Config& config) {
|
|||
_showSpecularTable = config.showSpecularTable;
|
||||
_showCursorPixel = config.showCursorPixel;
|
||||
_debugCursorTexcoord = config.debugCursorTexcoord;
|
||||
if (!_debugParams) {
|
||||
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
|
||||
}
|
||||
_debugParams->setSubData(0, _debugCursorTexcoord);
|
||||
}
|
||||
|
||||
|
||||
|
@ -479,6 +483,10 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
|
|||
assert(lightStage);
|
||||
// const auto light = DependencyManager::get<DeferredLightingEffect>()->getLightStage()->getLight(0);
|
||||
const auto light = lightStage->getLight(0);
|
||||
if (!_debugParams) {
|
||||
_debugParams = std::make_shared<gpu::Buffer>(sizeof(glm::vec4), nullptr);
|
||||
_debugParams->setSubData(0, _debugCursorTexcoord);
|
||||
}
|
||||
|
||||
gpu::doInBatch("DebugSubsurfaceScattering::run", args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
@ -521,9 +529,7 @@ void DebugSubsurfaceScattering::run(const render::RenderContextPointer& renderCo
|
|||
batch.setResourceTexture(ru::Texture::DeferredNormal, deferredFramebuffer->getDeferredNormalTexture());
|
||||
batch.setResourceTexture(ru::Texture::DeferredColor, deferredFramebuffer->getDeferredColorTexture());
|
||||
batch.setResourceTexture(ru::Texture::DeferredDepth, linearDepthTexture);
|
||||
|
||||
|
||||
batch._glUniform2f(gpu::slot::uniform::Extra0, _debugCursorTexcoord.x, _debugCursorTexcoord.y);
|
||||
batch.setUniformBuffer(1, _debugParams);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,6 +179,7 @@ private:
|
|||
|
||||
gpu::PipelinePointer _showLUTPipeline;
|
||||
gpu::PipelinePointer getShowLUTPipeline();
|
||||
gpu::BufferPointer _debugParams;
|
||||
bool _showProfile{ false };
|
||||
bool _showLUT{ false };
|
||||
bool _showSpecularTable{ false };
|
||||
|
|
|
@ -56,7 +56,7 @@ vec3 generateProfile(vec2 uv) {
|
|||
|
||||
<@func declareSubsurfaceScatteringProfileMap()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_PROFILE) uniform sampler2D scatteringProfile;
|
||||
|
||||
vec3 scatter(float r) {
|
||||
return texture(scatteringProfile, vec2(r * 0.5, 0.5)).rgb;
|
||||
|
@ -104,7 +104,7 @@ vec3 integrate(float cosTheta, float skinRadius) {
|
|||
|
||||
<@func declareSubsurfaceScatteringResource()@>
|
||||
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SSSC_LUT) uniform sampler2D scatteringLUT;
|
||||
|
||||
vec3 fetchBRDF(float LdotN, float curvature) {
|
||||
return texture(scatteringLUT, vec2( clamp(LdotN * 0.5 + 0.5, 0.0, 1.0), clamp(2.0 * curvature, 0.0, 1.0))).xyz;
|
||||
|
@ -124,7 +124,7 @@ struct ScatteringParameters {
|
|||
vec4 debugFlags;
|
||||
};
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_SSSC_PARAMS) uniform subsurfaceScatteringParametersBuffer {
|
||||
ScatteringParameters parameters;
|
||||
};
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@ struct WorkloadProxy {
|
|||
vec4 region;
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=0) uniform samplerBuffer workloadProxiesBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=0) uniform samplerBuffer workloadProxiesBuffer;
|
||||
WorkloadProxy getWorkloadProxy(int i) {
|
||||
int offset = 2 * i;
|
||||
WorkloadProxy proxy;
|
||||
|
@ -35,7 +35,7 @@ WorkloadProxy getWorkloadProxy(int i) {
|
|||
return proxy;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=0) buffer workloadProxiesBuffer {
|
||||
LAYOUT_STD140(binding=0) buffer workloadProxiesBuffer {
|
||||
WorkloadProxy _proxies[];
|
||||
};
|
||||
WorkloadProxy getWorkloadProxy(int i) {
|
||||
|
@ -57,17 +57,23 @@ struct WorkloadView {
|
|||
vec4 regions[3];
|
||||
};
|
||||
|
||||
#if defined(GPU_GL410)
|
||||
layout(binding=1) uniform samplerBuffer workloadViewsBuffer;
|
||||
#if !defined(GPU_SSBO_TRANSFORM_OBJECT)
|
||||
LAYOUT(binding=1) uniform samplerBuffer workloadViewsBuffer;
|
||||
WorkloadView getWorkloadView(int i) {
|
||||
int offset = 2 * i;
|
||||
int offset = 8 * i;
|
||||
WorkloadView view;
|
||||
view.origin = texelFetch(workloadViewsBuffer, offset);
|
||||
view.radiuses = texelFetch(workloadViewsBuffer, offset + 1);
|
||||
view.direction_far = texelFetch(workloadViewsBuffer, offset + 0);
|
||||
view.fov = texelFetch(workloadViewsBuffer, offset + 1);
|
||||
view.origin = texelFetch(workloadViewsBuffer, offset + 2);
|
||||
view.backFront[0] = texelFetch(workloadViewsBuffer, offset + 3);
|
||||
view.backFront[1] = texelFetch(workloadViewsBuffer, offset + 4);
|
||||
view.regions[0] = texelFetch(workloadViewsBuffer, offset + 5);
|
||||
view.regions[1] = texelFetch(workloadViewsBuffer, offset + 6);
|
||||
view.regions[2] = texelFetch(workloadViewsBuffer, offset + 7);
|
||||
return view;
|
||||
}
|
||||
#else
|
||||
layout(std140, binding=1) buffer workloadViewsBuffer {
|
||||
LAYOUT_STD140(binding=1) buffer workloadViewsBuffer {
|
||||
WorkloadView _views[];
|
||||
};
|
||||
WorkloadView getWorkloadView(int i) {
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<@include gpu/Color.slh@>
|
||||
<$declareColorWheel()$>
|
||||
|
||||
layout(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
|
||||
layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
LAYOUT(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0;
|
||||
LAYOUT(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps;
|
||||
|
||||
<@include ShadowCore.slh@>
|
||||
|
||||
|
@ -36,7 +36,13 @@ float curvatureAO(float k) {
|
|||
layout(location=0) in vec2 uv;
|
||||
layout(location=0) out vec4 outFragColor;
|
||||
|
||||
//SOURCE_PLACEHOLDER
|
||||
//SOURCE_PLACEHOLDER_BEGIN
|
||||
vec4 getFragmentColor() {
|
||||
DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);
|
||||
return vec4(pow(frag.albedo, vec3(1.0 / 2.2)), 1.0);
|
||||
}
|
||||
//SOURCE_PLACEHOLDER_END
|
||||
|
||||
|
||||
void main(void) {
|
||||
outFragColor = getFragmentColor();
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<$declareLightBuffer(256)$>
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
int lightIndex[256];
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<$declareLightBuffer(256)$>
|
||||
|
||||
layout(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
LAYOUT(binding=RENDER_UTILS_BUFFER_LIGHT_INDEX) uniform lightIndexBuffer {
|
||||
int lightIndex[256];
|
||||
};
|
||||
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord0;
|
||||
|
|
|
@ -32,7 +32,7 @@ struct DrawMesh {
|
|||
vec4 verts[NUM_SEGMENT_PER_VIEW_REGION];
|
||||
};
|
||||
|
||||
layout(std140, binding=0) uniform DrawMeshBuffer {
|
||||
LAYOUT_STD140(binding=0) uniform DrawMeshBuffer {
|
||||
DrawMesh _drawMeshBuffer;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
// the interpolated normal
|
||||
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
|
||||
|
@ -35,12 +37,6 @@ layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
|
|||
|
||||
layout(location=0) out vec4 _fragColor0;
|
||||
|
||||
<@include procedural/ProceduralCommon.slh@>
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 normal = normalize(_normalWS.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
|
@ -48,45 +44,18 @@ void main(void) {
|
|||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
||||
#ifdef PROCEDURAL
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
diffuse = getProceduralColor().rgb;
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//diffuse = pow(diffuse, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _positionES.xyz;
|
||||
|
||||
if (emissiveAmount > 0.0) {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
specular,
|
||||
DEFAULT_METALLIC,
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
} else {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
length(specular),
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
}
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
length(specular),
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue