Merge branch 'master' into glesFix

This commit is contained in:
HifiExperiments 2025-06-09 20:33:41 -07:00 committed by GitHub
commit 002bfa1a3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 1280 additions and 634 deletions

View file

@ -15,7 +15,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies
This documentation assumes that you are running our current target distribution, which is currently Ubuntu 22.04. The target distribution is usually the latest Ubuntu LTS still receiving standard support, though we may upgrade a little sooner if we require certain newer packages. Ubuntu version numbers are date codes and standard support is 5 years, meaning that Ubuntu 22.04 leaves standard support after around 2027-04.
### Install build tools:
## Install build tools:
- First update the package cache and your system:
```bash
@ -38,7 +38,7 @@ sudo apt install ./conan-*.deb
```
Verify Conan was installed by running `conan --version`.
### Install build dependencies:
## Install build dependencies:
Most dependencies will be automatically installed by Conan. This section only lists dependencies which might not be handled by Conan.
- OpenGL:
@ -73,7 +73,7 @@ sudo apt-get install -y qtbase5-dev \
```
### Extra dependencies to compile Interface on a server
## Extra dependencies to compile Interface on a server
- Install the following:
@ -96,7 +96,7 @@ sudo apt install python python3 python3-distro
sudo apt install nodejs
```
### Get code and checkout the branch you need
## Get code and checkout the branch you need
Clone this repository:
```bash
@ -114,7 +114,7 @@ git fetch --tags
git tag
```
### Architecture support
## Architecture support
If the build is intended to be packaged for distribution, the `OVERTE_CPU_ARCHITECTURE`
CMake variable needs to be set to an architecture specific value.
@ -127,7 +127,7 @@ For packaging, it is recommended to set it to a different value, for example `-m
Setting `OVERTE_CPU_ARCHITECTURE` to an empty string will use the default compiler settings and yield maximum compatibility.
### Prepare conan
## Prepare conan
The next step is setting up conan
@ -147,7 +147,7 @@ echo "tools.system.package_manager:mode = install" >> ~/.conan2/global.conf
echo "tools.system.package_manager:sudo = True" >> ~/.conan2/global.conf
```
### Compiling
## Compiling
Install the dependencies with conan
```bash
@ -155,12 +155,18 @@ cd overte
conan install . -s build_type=Release -b missing -pr:b=default -of build
```
On systems with GCC 15 additional parameter is needed:
```bash
cd overte
conan install . -s build_type=Release -b missing -pr:b=default -of build -c tools.build:cxxflags="['-include', 'cstdint']"
```
Prepare makefiles:
```bash
cmake --preset conan-release
```
#### Server
### Server
To compile the Domain server:
```bash
@ -169,7 +175,7 @@ make domain-server assignment-client
*Note: For a server, it is not necessary to compile the Interface.*
#### Interface
### Interface
To compile the Interface client:
```bash
@ -181,23 +187,23 @@ The commands above will compile with a single thread. If you have enough memory,
make -j4 interface
```
### Running the software
## Running the software
#### Domain server
### Domain server
Running Domain server:
```bash
./domain-server/domain-server
```
#### Assignment clients
### Assignment clients
Running assignment client:
```bash
./assignment-client/assignment-client -n 6
```
#### Interface
### Interface
Running Interface:
```bash

View file

@ -74,6 +74,8 @@ To create this variable:
* Set "Variable name" to `CONAN_HOME`
* Set "Variable value" to any directory that you have control over.
*Make sure that you copy the contents of your old `.conan2` folder over, or that you add the remote from step 2 again.*
## Step 7. Running CMake to Generate Build Files
These instructions only apply to Visual Studio 2019.

View file

@ -3,7 +3,7 @@ if (WIN32)
# Building with webrtc-audio-processing on Windows fails on cppstd 14.
set(CMAKE_CXX_STANDARD 17)
else ()
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
endif ()
set(CMAKE_CXX_STANDARD_REQUIRED ON)

View file

@ -49,7 +49,9 @@ macro(AUTOSCRIBE_PLATFORM_SHADER)
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}")
# TODO: our qrc file is getting too big to compile. We need to either split it across multiple files
# or look into qt_add_big_resources. But for now, we can skip including the glsl files
#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})
@ -128,19 +130,18 @@ macro(AUTOSCRIBE_SHADER)
file(WRITE "${SHADER_SCRIBED}.name" "${SHADER_NAME}.${SHADER_TYPE}")
AUTOSCRIBE_APPEND_QRC("${SHADER_COUNT}/name" "${SHADER_NAME_FILE}")
if (USE_GLES)
if(USE_GLES)
set(SPIRV_CROSS_ARGS --version 310es)
AUTOSCRIBE_PLATFORM_SHADER("310es")
AUTOSCRIBE_PLATFORM_SHADER("310es/stereo")
else()
elseif(APPLE)
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()
else()
set(SPIRV_CROSS_ARGS --version 450)
AUTOSCRIBE_PLATFORM_SHADER("450")
AUTOSCRIBE_PLATFORM_SHADER("450/stereo")
endif()
string(CONCAT SHADER_LIST "${SHADER_LIST}" "${SHADER_NAME} = ${SHADER_COUNT},\n")
@ -284,7 +285,7 @@ macro(AUTOSCRIBE_SHADER_LIB)
if (CMAKE_MATCH_1)
set(AUTOSCRIBE_PROGRAM_FRAGMENT ${CMAKE_MATCH_1})
endif()
string(REGEX MATCH ".*DEFINES +([a-zA-Z\(\)/: ]+)" MDEF ${PROGRAM_CONFIG})
string(REGEX MATCH ".*DEFINES +([a-zA-Z0-9\(\)/: ]+)" MDEF ${PROGRAM_CONFIG})
if (CMAKE_MATCH_1)
set(AUTOSCRIBE_PROGRAM_DEFINES ${CMAKE_MATCH_1})
string(TOLOWER AUTOSCRIBE_PROGRAM_DEFINES "${AUTOSCRIBE_PROGRAM_DEFINES}")
@ -479,7 +480,7 @@ macro(GENERATE_RENDER_PIPELINES)
set(SRC_FOLDER "${CMAKE_SOURCE_DIR}/libraries/render-utils/src")
file(GLOB_RECURSE MODEL_SLP_FILE ${SRC_FOLDER}/*model.slp)
file(READ ${MODEL_SLP_FILE} MODEL_CONFIG)
string(REGEX MATCH ".*DEFINES +([a-zA-Z\(\)/: ]+)" MDEF ${MODEL_CONFIG})
string(REGEX MATCH ".*DEFINES +([a-zA-Z0-9\(\)/: ]+)" MDEF ${MODEL_CONFIG})
set(MODEL_DEFINES ${CMAKE_MATCH_1})
string(REGEX REPLACE " +" ";" MODEL_DEFINES "${MODEL_DEFINES}")
string(REGEX REPLACE "\:v+" "" MODEL_DEFINES "${MODEL_DEFINES}")
@ -487,8 +488,9 @@ macro(GENERATE_RENDER_PIPELINES)
GENERATE_DEFINES_LIST("${MODEL_DEFINES}")
# These map from define to builder keys
set(DEFINE_STRINGS "normalmap" "translucent" "unlit" "lightmap" "mtoon" "triplanar" "deformed" "deformeddq" "fade")
set(BUILDER_STRINGS "withTangents" "withTranslucent" "withUnlit" "withLightMap" "withMToon" "withTriplanar" "withDeformed" "withDeformed().withDualQuatSkinned" "withFade")
set(DEFINE_STRINGS "normalmap" "translucent" "unlit" "lightmap" "mtoon" "triplanar" "deformed" "deformeddq" "fade" "layers2" "layers3" "splatmap")
set(BUILDER_STRINGS "withTangents" "withTranslucent" "withUnlit" "withLightMap" "withMToon" "withTriplanar" "withDeformed" "withDeformed().withDualQuatSkinned"
"withFade" "withLayers(2)" "withLayers(3)" "withSplatMap")
# We skip some pre-built defines, as they are handled differently
set(IGNORE_DEFINES "shadow" "mirror" "forward")
# Some defines are not used for shadows
@ -496,7 +498,7 @@ macro(GENERATE_RENDER_PIPELINES)
# Some defines are not used for forward rendering
set(IGNORE_FORWARD_DEFINES "fade")
# These defines are "model" specific. For everything else, we also generate a "simple" version.
set(NON_SIMPLE_DEFINES "normalmap" "lightmap" "mtoon" "triplanar" "deformed" "deformeddq")
set(NON_SIMPLE_DEFINES "normalmap" "lightmap" "mtoon" "triplanar" "deformed" "deformeddq" "layers2" "layers3" "splatmap")
# Our base model and simple pipelines
set(ALL_PIPELINES_MAP "")
@ -529,7 +531,11 @@ macro(GENERATE_RENDER_PIPELINES)
list(FIND DEFINE_STRINGS "${PIPELINE_DEFINE}" INDEX)
if (NOT ${INDEX} EQUAL -1)
list(GET BUILDER_STRINGS ${INDEX} BUILDER_ELEMENT)
string(CONCAT BUILDER_STRING "${BUILDER_STRING}" ".${BUILDER_ELEMENT}()")
if (${BUILDER_ELEMENT} MATCHES ".*\\)$")
string(CONCAT BUILDER_STRING "${BUILDER_STRING}" ".${BUILDER_ELEMENT}")
else()
string(CONCAT BUILDER_STRING "${BUILDER_STRING}" ".${BUILDER_ELEMENT}()")
endif()
string(CONCAT DEFERRED_STRING "${DEFERRED_STRING}" "${PIPELINE_DEFINE}_")
if (NOT "${PIPELINE_DEFINE}" IN_LIST IGNORE_SHADOWS_DEFINES)
string(CONCAT SHADOW_STRING "${SHADOW_STRING}" "${PIPELINE_DEFINE}_")

View file

@ -55,7 +55,7 @@ class Overte(ConanFile):
self.requires("gifcreator/2016.11@overte/stable")
self.requires("glad/0.1.36")
self.requires("gli/cci.20210515")
self.requires("glslang/1.3.236.0")
self.requires("glslang/1.3.268.0")
self.requires("liblo/0.30@overte/stable")
self.requires("libnode/18.20.8@overte/stable")
self.requires("nlohmann_json/3.11.2")
@ -69,8 +69,8 @@ class Overte(ConanFile):
self.requires("quazip/1.4")
self.requires("scribe/2019.02@overte/stable")
self.requires("sdl/2.30.3")
self.requires("spirv-cross/1.3.231.1")
self.requires("spirv-tools/1.3.236.0")
self.requires("spirv-cross/1.3.268.0")
self.requires("spirv-tools/1.3.268.0")
self.requires("steamworks/158a@overte/prebuild")
self.requires("v-hacd/4.1.0")
self.requires("vulkan-memory-allocator/3.0.1")

View file

@ -816,6 +816,9 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
auto pipelineType = getPipelineType(materials->second);
if (pipelineType == Pipeline::MATERIAL) {
builder.withMaterial();
builder.withLayers(materials->second.getLayers());
if (drawMaterialKey.isNormalMap()) {
builder.withTangents();
}
@ -830,6 +833,8 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build
if (materials->second.size() > 0 && materials->second.top().material &&
(MaterialMappingMode)materials->second.top().material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
builder.withTriplanar();
} else if (materials->second.isSplatMap()) {
builder.withSplatMap();
}
} else if (pipelineType == Pipeline::PROCEDURAL) {
builder.withOwnPipeline();

View file

@ -17,7 +17,6 @@
#define GPU_BUFFER_TRANSFORM_CAMERA 15
#define GPU_BUFFER_TEXTURE_TABLE0 16
#define GPU_BUFFER_TEXTURE_TABLE1 17
#define GPU_BUFFER_CAMERA_CORRECTION 18
#define GPU_TEXTURE_TRANSFORM_OBJECT 31
@ -45,9 +44,8 @@
#define GPU_ATTR_STEREO_SIDE 14
#define GPU_ATTR_DRAW_CALL_INFO 15
// OSX seems to have an issue using 14 as an attribute location for passing from the vertex to the fragment shader
#define GPU_ATTR_V2F_STEREO_SIDE 8
#define GPU_ATTR_V2F_DRAW_CALL_INFO 13
#define GPU_ATTR_V2F_STEREO_SIDE 14
#define GPU_ATTR_V2F_DRAW_CALL_INFO 15
#define GPU_UNIFORM_EXTRA0 110
#define GPU_UNIFORM_EXTRA1 111
@ -69,7 +67,6 @@ enum Buffer {
CameraTransform = GPU_BUFFER_TRANSFORM_CAMERA,
TextureTable0 = GPU_BUFFER_TEXTURE_TABLE0,
TextureTable1 = GPU_BUFFER_TEXTURE_TABLE1,
CameraCorrection = GPU_BUFFER_CAMERA_CORRECTION,
};
} // namespace buffer

View file

@ -77,6 +77,8 @@ namespace scriptable {
QString scatteringMap { "" };
std::array<glm::mat4, graphics::Material::NUM_TEXCOORD_TRANSFORMS> texCoordTransforms;
QString cullFaceMode { "" };
uint8_t layers { 1 };
QString splatMap { "" };
bool defaultFallthrough { false };
std::unordered_map<uint, bool> propertyFallthroughs; // not actually exposed to script

View file

@ -454,6 +454,14 @@ namespace scriptable {
obj.setProperty("cullFaceMode", material.cullFaceMode);
}
if (material.layers > 1) {
obj.setProperty("layers", material.layers);
}
if (!material.splatMap.isEmpty()) {
obj.setProperty("splatMap", material.splatMap);
}
if (material.model.toStdString() == graphics::Material::HIFI_PBR) {
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::GLOSSY_VAL_BIT)) {
obj.setProperty("roughness", FALLTHROUGH);

View file

@ -38,6 +38,9 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const
bumpMap = material.bumpMap;
cullFaceMode = material.cullFaceMode;
layers = material.layers;
splatMap = material.splatMap;
if (model.toStdString() == graphics::Material::HIFI_PBR) {
roughness = material.roughness;
metallic = material.metallic;
@ -123,6 +126,12 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
cullFaceMode = QString(graphics::MaterialKey::getCullFaceModeName(material->getCullFaceMode()).c_str());
layers = material->getLayers();
map = material->getTextureMap(graphics::Material::MapChannel::SPLAT_MAP);
if (map && map->getTextureSource()) {
splatMap = map->getTextureSource()->getUrl().toString();
}
if (model.toStdString() == graphics::Material::HIFI_PBR) {
roughness = material->getRoughness();
metallic = material->getMetallic();

View file

@ -74,6 +74,7 @@ Material::Material(const Material& material) :
_name(material._name),
_key(material._key),
_model(material._model),
_layers(material._layers),
_emissive(material._emissive),
_opacity(material._opacity),
_albedo(material._albedo),
@ -99,6 +100,7 @@ Material& Material::operator=(const Material& material) {
_name = material._name;
_model = material._model;
_key = material._key;
_layers = material._layers;
_emissive = material._emissive;
_opacity = material._opacity;
_albedo = material._albedo;
@ -309,6 +311,9 @@ const glm::vec3 Material::DEFAULT_OUTLINE = glm::vec3(0.0f);
MultiMaterial::MultiMaterial() {
Schema schema;
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
for (int i = 0; i < _textureTables.size(); i++) {
_textureTables[i] = std::make_shared<gpu::TextureTable>();
}
}
void MultiMaterial::calculateMaterialInfo() const {
@ -317,14 +322,16 @@ void MultiMaterial::calculateMaterialInfo() const {
_textureSize = 0;
_textureCount = 0;
auto textures = _textureTable->getTextures();
for (auto const &texture : textures) {
if (texture && texture->isDefined()) {
auto size = texture->getSize();
_textureSize += size;
_textureCount++;
} else {
allTextures = false;
for (uint8_t i = 0; i < _layers; i++) {
auto textures = _textureTables[i]->getTextures();
for (auto const& texture : textures) {
if (texture && texture->isDefined()) {
auto size = texture->getSize();
_textureSize += size;
_textureCount++;
} else {
allTextures = false;
}
}
}
_hasCalculatedTextureInfo = allTextures;
@ -360,17 +367,21 @@ bool MultiMaterial::anyReferenceMaterialsOrTexturesChanged() const {
return false;
}
void MultiMaterial::setisMToon(bool isMToon) {
if (isMToon != _isMToon) {
void MultiMaterial::setisMToonAndLayers(bool isMToon, uint8_t layers) {
if (isMToon != _isMToon || layers != _layers) {
_isMToon = isMToon;
_layers = layers;
if (isMToon) {
MToonSchema toonSchema;
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(MToonSchema), (const gpu::Byte*) &toonSchema, sizeof(MToonSchema)));
std::array<MToonSchema, 3> toonSchemas;
size_t size = _layers * sizeof(MToonSchema);
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(size, (const gpu::Byte*)toonSchemas.data(), size));
} else {
Schema schema;
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Schema), (const gpu::Byte*) &schema, sizeof(Schema)));
std::array<Schema, 3> schemas;
size_t size = _layers * sizeof(Schema);
_schemaBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(size, (const gpu::Byte*)schemas.data(), size));
}
}
_isMToon = isMToon;
}
void MultiMaterial::setMToonTime() {
@ -384,7 +395,9 @@ void MultiMaterial::setMToonTime() {
});
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
_schemaBuffer.edit<graphics::MultiMaterial::MToonSchema>()._time = (float)((usecTimestampNow() - mtoonStartTime) / USECS_PER_MSEC) / MSECS_PER_SECOND;
float mtoonTime = (float)((usecTimestampNow() - mtoonStartTime) / USECS_PER_MSEC) / MSECS_PER_SECOND;
// MToon time is only stored in the first material
_schemaBuffer.edit<graphics::MultiMaterial::MToonSchema>()._time = mtoonTime;
}
void MultiMaterial::applySamplers() const {

View file

@ -65,6 +65,8 @@ public:
EXTRA_4_BIT,
EXTRA_5_BIT,
SPLAT_MAP_BIT, // Splat maps work differently than the other maps, so we put it at the end to not interfere with the extra bits
NUM_FLAGS,
};
typedef std::bitset<NUM_FLAGS> Flags;
@ -78,6 +80,7 @@ public:
OCCLUSION_MAP,
LIGHT_MAP,
SCATTERING_MAP,
SPLAT_MAP,
NUM_MAP_CHANNELS,
};
@ -425,6 +428,9 @@ public:
virtual glm::vec2 getLightmapParams() const { return _lightmapParams; }
virtual glm::vec2 getMaterialParams() const { return _materialParams; }
virtual uint8_t getLayers() const { return _layers; }
void setLayers(uint8_t layers) { _layers = std::min(3, std::max(1, (int)layers)); }
virtual bool getDefaultFallthrough() const { return _defaultFallthrough; }
void setDefaultFallthrough(bool defaultFallthrough) { _defaultFallthrough = defaultFallthrough; }
@ -487,6 +493,7 @@ protected:
std::string _name { "" };
mutable MaterialKey _key { 0 };
std::string _model { HIFI_PBR };
uint8_t _layers { 1 };
private:
// Material properties
@ -580,6 +587,7 @@ public:
glm::vec2 _lightmapParams { 0.0, 1.0 };
glm::vec3 spare { 0.0f };
uint32_t _texCoordSets { 0 };
Schema() {
@ -630,6 +638,8 @@ public:
uint32_t _texCoordSets { 0 };
float spare { 0.0f };
MToonSchema() {
for (auto& transform : _texcoordTransforms) {
transform = glm::mat4();
@ -643,14 +653,9 @@ public:
}
};
void setMaterialKey(const graphics::MaterialKey& materialKey) { _materialKey = materialKey; }
graphics::MaterialKey getMaterialKey() const { return _materialKey; }
gpu::BufferView& getSchemaBuffer() { return _schemaBuffer; }
graphics::MaterialKey getMaterialKey() const {
if (_isMToon) {
return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::MToonSchema>()._key);
} else {
return graphics::MaterialKey(_schemaBuffer.get<graphics::MultiMaterial::Schema>()._key);
}
}
glm::vec4 getColor() const {
glm::vec3 albedo;
float opacity;
@ -665,11 +670,13 @@ public:
}
return glm::vec4(ColorUtils::tosRGBVec3(albedo), opacity);
}
const gpu::TextureTablePointer& getTextureTable() const { return _textureTable; }
const std::array<gpu::TextureTablePointer, 3>& getTextureTables() const { return _textureTables; }
void setCullFaceMode(graphics::MaterialKey::CullFaceMode cullFaceMode) { _cullFaceMode = cullFaceMode; }
graphics::MaterialKey::CullFaceMode getCullFaceMode() const { return _cullFaceMode; }
uint8_t getLayers() const { return _layers; }
void setNeedsUpdate(bool needsUpdate) { _needsUpdate = needsUpdate; }
void setTexturesLoading(bool value) { _texturesLoading = value; }
void setInitialized() { _initialized = true; }
@ -684,7 +691,7 @@ public:
void addReferenceTexture(const std::function<gpu::TexturePointer()>& textureOperator);
void addReferenceMaterial(const std::function<graphics::MaterialPointer()>& materialOperator);
void setisMToon(bool isMToon);
void setisMToonAndLayers(bool isMToon, uint8_t layers);
bool isMToon() const { return _isMToon; }
void setMToonTime();
bool hasOutline() const { return _outlineWidthMode != 0 && _outlineWidth > 0.0f; }
@ -696,17 +703,24 @@ public:
void setOutlineWidth(float width) { _outlineWidth = width; }
void setOutline(const glm::vec3& outline) { _outline = outline; }
void setSplatMap(const gpu::TexturePointer& splatMap) { _splatMap = splatMap; }
const gpu::TexturePointer& getSplatMap() const { return _splatMap; }
bool isSplatMap() const { return (bool)_splatMap; }
void addSamplerFunc(std::function<void(void)> samplerFunc) { _samplerFuncs.push_back(samplerFunc); }
void resetSamplers() { _samplerFuncs.clear(); }
void applySamplers() const;
private:
graphics::MaterialKey _materialKey;
gpu::BufferView _schemaBuffer;
std::array<gpu::TextureTablePointer, 3> _textureTables;
graphics::MaterialKey::CullFaceMode _cullFaceMode { graphics::Material::DEFAULT_CULL_FACE_MODE };
gpu::TextureTablePointer _textureTable { std::make_shared<gpu::TextureTable>() };
gpu::TexturePointer _splatMap { nullptr };
bool _needsUpdate { false };
bool _texturesLoading { false };
bool _initialized { false };
uint8_t _layers { 1 };
mutable size_t _textureSize { 0 };
mutable int _textureCount { 0 };

View file

@ -22,8 +22,13 @@ struct TexMapArray {
vec2 _materialParams;
<@if not HIFI_USE_MTOON@>
vec2 _lightmapParams;
<@endif@>
vec3 spare;
uint _texCoordSets;
<@else@>
uint _texCoordSets;
float spare;
<@endif@>
};
<@func declareMaterialTexMapArrayBuffer()@>
@ -68,21 +73,33 @@ struct Material {
};
<@endif@>
LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform materialBuffer {
struct MaterialBuffer {
Material _mat;
TexMapArray _texMapArray;
};
Material getMaterial() {
return _mat;
<@if HIFI_USE_LAYERS3@>
#define NUM_LAYERS 3
<@elif HIFI_USE_LAYERS2@>
#define NUM_LAYERS 2
<@else@>
#define NUM_LAYERS 1
<@endif@>
LAYOUT_STD140(binding=GRAPHICS_BUFFER_MATERIAL) uniform MaterialBinding {
MaterialBuffer materialBuffers[NUM_LAYERS];
};
Material getMaterial(int layer) {
return materialBuffers[layer]._mat;
}
TexMapArray getTexMapArray() {
return _texMapArray;
TexMapArray getTexMapArray(int layer) {
return materialBuffers[layer]._texMapArray;
}
vec2 evalTexCoordSet(mat2 uvs, int channel) {
vec2 evalTexCoordSet(int layer, mat2 uvs, int channel) {
// We support up to 4 texCoord sets (0 - 3, 2 bits per channel), but currently we only use 0 and 1 (see setTexCoordSet in Material.h)
const uint MAX_TEX_COORD_SET = 3u;
return uvs[(_texMapArray._texCoordSets >> (2 * channel)) & MAX_TEX_COORD_SET];
return uvs[(materialBuffers[layer]._texMapArray._texCoordSets >> (2 * channel)) & MAX_TEX_COORD_SET];
}
<@if not HIFI_USE_MTOON@>

View file

@ -91,6 +91,27 @@
}
<@endfunc@>
#define SAMPLE_MAP(name, slot, uv, comps) name = texture(slot, uv, TAA_TEXTURE_LOD_BIAS).comps;
<@if HIFI_USE_LAYERS2@>
#define SAMPLE_MAP_LAYER(name, layer, uv, comps) \
if (layer == 1) { \
SAMPLE_MAP(name, name##Map2, uv, comps) \
} else { \
SAMPLE_MAP(name, name##Map, uv, comps) \
}
<@elif HIFI_USE_LAYERS3@>
#define SAMPLE_MAP_LAYER(name, layer, uv, comps) \
if (layer == 2) { \
SAMPLE_MAP(name, name##Map3, uv, comps) \
} else if (layer == 1) { \
SAMPLE_MAP(name, name##Map2, uv, comps) \
} else { \
SAMPLE_MAP(name, name##Map, uv, comps) \
}
<@else@>
#define SAMPLE_MAP_LAYER(name, layer, uv, comps) SAMPLE_MAP(name, name##Map, uv, comps)
<@endif@>
<@if not HIFI_USE_MTOON@>
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
@ -99,76 +120,94 @@
#ifdef GPU_TEXTURE_TABLE_BINDLESS
TextureTable(0, matTex);
<@if HIFI_USE_LAYERS2@>
TextureTable(1, matTex2);
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex, matTex2);
<@elif HIFI_USE_LAYERS3@>
TextureTable(1, matTex2);
TextureTable(2, matTex3);
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex, matTex2, matTex3);
<@else@>
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex);
<@endif@>
<!
ALBEDO = 0,
NORMAL, 1
METALLIC, 2
EMISSIVE_LIGHTMAP, 3
ROUGHNESS, 4
OCCLUSION, 5
SCATTERING, 6
NORMAL = 1,
METALLIC = 2,
EMISSIVE_LIGHTMAP = 3,
ROUGHNESS = 4, // only supported for 1 or 2 layers
OCCLUSION = 5, // only supported for 1 or 2 layers
SCATTERING = 6, // only supported for 1 layer
!>
<@if withAlbedo@>
#define albedoMap 0
vec4 fetchAlbedoMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
vec4 fetchAlbedoMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
// Should take into account TAA_TEXTURE_LOD_BIAS?
return tableTexValue(matTex, albedoMap, uv);
return tableTexValue(_matTexs[layer], albedoMap, uv);
}
<@endif@>
<@if withNormal@>
#define normalMap 1
vec3 fetchNormalMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
vec3 fetchNormalMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
// Should take into account TAA_TEXTURE_LOD_BIAS?
return tableTexValue(matTex, normalMap, uv).xyz;
return tableTexValue(_matTexs[layer], normalMap, uv).xyz;
}
<@endif@>
<@if withMetallic@>
#define metallicMap 2
float fetchMetallicMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_METALLIC);
float fetchMetallicMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_METALLIC);
// Should take into account TAA_TEXTURE_LOD_BIAS?
return tableTexValue(matTex, metallicMap, uv).r;
return tableTexValue(_matTexs[layer], metallicMap, uv).r;
}
<@endif@>
<@if withEmissive@>
#define emissiveMap 3
vec3 fetchEmissiveMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
vec3 fetchEmissiveMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
// Should take into account TAA_TEXTURE_LOD_BIAS?
return tableTexValue(matTex, emissiveMap, uv).rgb;
return tableTexValue(_matTexs[layer], emissiveMap, uv).rgb;
}
<@endif@>
<@if withRoughness@>
#define roughnessMap 4
float fetchRoughnessMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS);
float fetchRoughnessMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS);
// Should take into account TAA_TEXTURE_LOD_BIAS?
return tableTexValue(matTex, roughnessMap, uv).r;
return tableTexValue(_matTexs[layer], roughnessMap, uv).r;
}
<@endif@>
<@if withOcclusion@>
#define occlusionMap 5
float fetchOcclusionMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_OCCLUSION);
return tableTexValue(matTex, occlusionMap, uv).r;
float fetchOcclusionMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_OCCLUSION);
return tableTexValue(_matTexs[layer], occlusionMap, uv).r;
}
<@endif@>
<@if withScattering@>
#define scatteringMap 6
float fetchScatteringMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SCATTERING);
float scattering = texture(tableTex(matTex, scatteringMap), uv).r; // boolean scattering for now
float fetchScatteringMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SCATTERING);
float scattering = texture(tableTex(_matTexs[layer], scatteringMap), uv).r; // boolean scattering for now
return max(((scattering - 0.1) / 0.9), 0.0);
return tableTexValue(matTex, scatteringMap, uv).r; // boolean scattering for now
return tableTexValue(_matTexs[layer], scatteringMap, uv).r; // boolean scattering for now
}
<@endif@>
@ -176,18 +215,34 @@ float fetchScatteringMap(mat2 uvs) {
<@if withAlbedo@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
vec4 fetchAlbedoMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_2) uniform sampler2D albedoMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_3) uniform sampler2D albedoMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO3_3) uniform sampler2D albedoMap3;
<@endif@>
vec4 fetchAlbedoMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
vec4 albedo;
SAMPLE_MAP_LAYER(albedo, layer, uv, rgba)
return albedo;
}
<@endif@>
<@if withNormal@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
vec3 fetchNormalMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL2_2) uniform sampler2D normalMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL2_3) uniform sampler2D normalMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL3_3) uniform sampler2D normalMap3;
<@endif@>
vec3 fetchNormalMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
// 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));
vec2 normal;
SAMPLE_MAP_LAYER(normal, layer, uv, rg)
vec2 t = 2.0 * (normal - vec2(0.5, 0.5));
vec2 t2 = t*t;
return vec3(t.x, sqrt(max(0.0, 1.0 - t2.x - t2.y)), t.y);
}
@ -195,45 +250,78 @@ vec3 fetchNormalMap(mat2 uvs) {
<@if withMetallic@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC) uniform sampler2D metallicMap;
float fetchMetallicMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_METALLIC);
return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC2_2) uniform sampler2D metallicMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC2_3) uniform sampler2D metallicMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_METALLIC3_3) uniform sampler2D metallicMap3;
<@endif@>
float fetchMetallicMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_METALLIC);
float metallic;
SAMPLE_MAP_LAYER(metallic, layer, uv, r)
return metallic;
}
<@endif@>
<@if withEmissive@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
vec3 fetchEmissiveMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_2) uniform sampler2D emissiveMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_3) uniform sampler2D emissiveMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP3_3) uniform sampler2D emissiveMap3;
<@endif@>
vec3 fetchEmissiveMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
vec3 emissive;
SAMPLE_MAP_LAYER(emissive, layer, uv, rgb)
return emissive;
}
<@endif@>
<! only supported for 1 or 2 layers !>
<@if not HIFI_USE_LAYERS3@>
<@if withRoughness@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS) uniform sampler2D roughnessMap;
float fetchRoughnessMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS);
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS2_2) uniform sampler2D roughnessMap2;
<@endif@>
float fetchRoughnessMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS);
float roughness;
SAMPLE_MAP_LAYER(roughness, layer, uv, r)
return roughness;
}
<@endif@>
<@if withOcclusion@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION) uniform sampler2D occlusionMap;
float fetchOcclusionMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_OCCLUSION);
return texture(occlusionMap, uv).r;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_OCCLUSION2_2) uniform sampler2D occlusionMap2;
<@endif@>
float fetchOcclusionMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_OCCLUSION);
float occlusion;
SAMPLE_MAP_LAYER(occlusion, layer, uv, r)
return occlusion;
}
<@endif@>
<@endif@>
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
<! only supported for 1 layer !>
<@else@>
<@if withScattering@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SCATTERING) uniform sampler2D scatteringMap;
float fetchScatteringMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SCATTERING);
float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now
float fetchScatteringMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SCATTERING);
float scattering; // boolean scattering for now
SAMPLE_MAP_LAYER(scattering, layer, uv, r)
return max(((scattering - 0.1) / 0.9), 0.0);
return texture(scatteringMap, uv).r; // boolean scattering for now
}
<@endif@>
<@endif@>
#endif
@ -244,47 +332,66 @@ float fetchScatteringMap(mat2 uvs) {
<$declareMaterialTexMapArrayBuffer()$>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
vec3 fetchLightMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
vec2 lightmapParams = getTexMapArray()._lightmapParams;
vec3 fetchLightMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
vec2 lightmapParams = getTexMapArray(layer)._lightmapParams;
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);
}
<@endfunc@>
<@func fetchMaterialTextures(matKey, texcoords, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
vec2 albedoTexCoords = evalTexCoordSet(<$texcoords$>, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
if (getTexMapArray()._materialParams.y != 1.0 && clamp(albedoTexCoords, vec2(0.0), vec2(1.0)) != albedoTexCoords) {
<@func fetchMaterialTextures(layer, matKey, texcoords, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
vec2 albedoTexCoords = evalTexCoordSet(<$layer$>, <$texcoords$>, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
if (getTexMapArray(<$layer$>)._materialParams.y != 1.0 && clamp(albedoTexCoords, vec2(0.0), vec2(1.0)) != albedoTexCoords) {
discard;
}
<@if albedo@>
vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(<$texcoords$>), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0));
<@endif@>
<@if roughness@>
float <$roughness$> = mix(1.0, fetchRoughnessMap(<$texcoords$>), float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0));
vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(<$layer$>, <$texcoords$>), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0));
<@endif@>
<@if normal@>
vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(<$texcoords$>), float((<$matKey$> & NORMAL_MAP_BIT) != 0));
vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(<$layer$>, <$texcoords$>), float((<$matKey$> & NORMAL_MAP_BIT) != 0));
<@endif@>
<@if metallic@>
float <$metallic$> = float((<$matKey$> & METALLIC_MAP_BIT) != 0) * fetchMetallicMap(<$texcoords$>);
float <$metallic$> = float((<$matKey$> & METALLIC_MAP_BIT) != 0) * fetchMetallicMap(<$layer$>, <$texcoords$>);
<@endif@>
<@if emissive@>
vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(<$texcoords$>);
<@endif@>
<@if scattering@>
float <$scattering$> = float((<$matKey$> & SCATTERING_MAP_BIT) != 0) * fetchScatteringMap(<$texcoords$>);
<@endif@>
<@if occlusion@>
float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoords$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0));
vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(<$layer$>, <$texcoords$>);
<@endif@>
<@if lightmap@>
vec3 <$lightmap$> = fetchLightMap(<$texcoords$>);
vec3 <$lightmap$> = fetchLightMap(<$layer$>, <$texcoords$>);
<@endif@>
<@if not HIFI_USE_LAYERS3@>
<@if roughness@>
float <$roughness$> = mix(1.0, fetchRoughnessMap(<$layer$>, <$texcoords$>), float((<$matKey$> & ROUGHNESS_MAP_BIT) != 0));
<@endif@>
<@if occlusion@>
float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$layer$>, <$texcoords$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0));
<@endif@>
<@else@>
// only supported for 1 or 2 layers
<@if roughness@>
float <$roughness$> = 1.0;
<@endif@>
<@if occlusion@>
float <$occlusion$> = 1.0;
<@endif@>
<@endif@>
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
<@if scattering@>
// only supported for 1 layer
float <$scattering$> = 0.0;
<@endif@>
<@else@>
<@if scattering@>
float <$scattering$> = float((<$matKey$> & SCATTERING_MAP_BIT) != 0) * fetchScatteringMap(<$layer$>, <$texcoords$>);
<@endif@>
<@endif@>
<@endfunc@>
<@if HIFI_USE_TRIPLANAR@>
<@func fetchMaterialTexturesTriplanar(matKey, positionMS, normalMS, texCoord1, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
<@func fetchMaterialTexturesTriplanar(matKeys, positionMS, normalMS, texCoords, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering, occlusion, lightmap)@>
vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
vec3 normalMS = normalize(<$normalMS$>);
@ -297,13 +404,29 @@ vec3 fetchLightMap(mat2 uvs) {
vec3 axisSign = sign(normalMS.xyz);
<@endif@>
TexMapArray texMapArray = getTexMapArray();
<@if HIFI_USE_LAYERS3@>
const int LAYER_X = 0;
const int LAYER_Y = 1;
const int LAYER_Z = 2;
<@elif HIFI_USE_LAYERS2@>
const int LAYER_X = 1;
const int LAYER_Y = 0;
const int LAYER_Z = 1;
<@else@>
const int LAYER_X = 0;
const int LAYER_Y = 0;
const int LAYER_Z = 0;
<@endif@>
TexMapArray texMapArrayZ = getTexMapArray(LAYER_Z);
vec2 uvXY = vec2(-inPosition.x, -inPosition.y);
<$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$>
<$evalTexMapArrayTexcoord0(texMapArrayZ, uvXY, _positionWS, uvXY)$>
TexMapArray texMapArrayY = getTexMapArray(LAYER_Y);
vec2 uvXZ = vec2(-inPosition.x, inPosition.z);
<$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$>
<$evalTexMapArrayTexcoord0(texMapArrayY, uvXZ, _positionWS, uvXZ)$>
TexMapArray texMapArrayX = getTexMapArray(LAYER_X);
vec2 uvYZ = vec2(inPosition.z, -inPosition.y);
<$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$>
<$evalTexMapArrayTexcoord0(texMapArrayX, uvYZ, _positionWS, uvYZ)$>
<@if albedo@>
vec4 <$albedo$>Triplanar = vec4(0.0);
@ -331,8 +454,9 @@ vec3 fetchLightMap(mat2 uvs) {
<@endif@>
{
mat2 triplanarUVs = mat2(uvXY, <$texCoord1$>);
<$fetchMaterialTextures($matKey$, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
BITFIELD matKey = <$matKeys$>[LAYER_Z];
mat2 triplanarUVs = mat2(uvXY, <$texCoords$>[LAYER_Z].zw);
<$fetchMaterialTextures(LAYER_Z, matKey, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
float magnitude = blend.z;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -363,8 +487,9 @@ vec3 fetchLightMap(mat2 uvs) {
}
{
mat2 triplanarUVs = mat2(uvXZ, <$texCoord1$>);
<$fetchMaterialTextures($matKey$, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
BITFIELD matKey = <$matKeys$>[LAYER_Y];
mat2 triplanarUVs = mat2(uvXZ, <$texCoords$>[LAYER_Y].zw);
<$fetchMaterialTextures(LAYER_Y, matKey, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
float magnitude = blend.y;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -395,8 +520,9 @@ vec3 fetchLightMap(mat2 uvs) {
}
{
mat2 triplanarUVs = mat2(uvYZ, <$texCoord1$>);
<$fetchMaterialTextures($matKey$, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
BITFIELD matKey = <$matKeys$>[LAYER_X];
mat2 triplanarUVs = mat2(uvYZ, <$texCoords$>[LAYER_X].zw);
<$fetchMaterialTextures(LAYER_X, matKey, triplanarUVs, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$, $occlusion$, $lightmap$)$>
float magnitude = blend.x;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -490,78 +616,97 @@ vec3 fetchLightMap(mat2 uvs) {
#ifdef GPU_TEXTURE_TABLE_BINDLESS
TextureTable(0, matTex);
<@if HIFI_USE_LAYERS2@>
TextureTable(1, matTex2);
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex, matTex2);
<@elif HIFI_USE_LAYERS3@>
TextureTable(1, matTex2);
TextureTable(2, matTex3);
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex, matTex2, matTex3);
<@else@>
#define DEFINE_MAT_TEXS const GPUTextureTable _matTexs[NUM_LAYERS] = GPUTextureTable[NUM_LAYERS](matTex);
<@endif@>
<!
ALBEDO = 0,
NORMAL, 1
SHADE, 2
EMISSIVE, 3
SHADING_SHIFT, 4
MATCAP, 5
RIM, 6
UV_ANIMATION_MASK, 7
NORMAL = 1,
SHADE = 2,
EMISSIVE = 3,
SHADING_SHIFT = 4, // only for 1 or 2 layers
MATCAP = 5, // only for 1 or 2 layers
RIM = 6, // only for 1 layer
UV_ANIMATION_MASK = 7, // only for 1 layer
!>
<@if withAlbedo@>
#define albedoMap 0
vec4 fetchAlbedoMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
return tableTexValue(matTex, albedoMap, uv);
vec4 fetchAlbedoMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
return tableTexValue(_matTexs[layer], albedoMap, uv);
}
<@endif@>
<@if withNormal@>
#define normalMap 1
vec3 fetchNormalMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
return tableTexValue(matTex, normalMap, uv).xyz;
vec3 fetchNormalMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
return tableTexValue(_matTexs[layer], normalMap, uv).xyz;
}
<@endif@>
<@if withShade@>
#define shadeMap 2
vec3 fetchShadeMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SHADE);
return tableTexValue(matTex, shadeMap, uv).rgb;
vec3 fetchShadeMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SHADE);
return tableTexValue(_matTexs[layer], shadeMap, uv).rgb;
}
<@endif@>
<@if withEmissive@>
#define emissiveMap 3
vec3 fetchEmissiveMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
return tableTexValue(matTex, emissiveMap, uv).rgb;
vec3 fetchEmissiveMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
return tableTexValue(_matTexs[layer], emissiveMap, uv).rgb;
}
<@endif@>
<@if withShadingShift@>
#define shadingShiftMap 4
float fetchShadingShiftMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT);
return tableTexValue(matTex, shadingShiftMap, uv).r;
float fetchShadingShiftMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT);
return tableTexValue(_matTexs[layer], shadingShiftMap, uv).r;
}
<@endif@>
<@if withMatcap@>
#define matcapMap 5
vec3 fetchMatcapMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_MATCAP);
return tableTexValue(matTex, matcapMap, uv).rgb;
vec3 fetchMatcapMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_MATCAP);
return tableTexValue(_matTexs[layer], matcapMap, uv).rgb;
}
<@endif@>
<@if withRim@>
#define rimMap 6
vec3 fetchRimMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_RIM);
return tableTexValue(matTex, rimMap, uv).rgb;
vec3 fetchRimMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_RIM);
return tableTexValue(_matTexs[layer], rimMap, uv).rgb;
}
<@endif@>
<@if withUVAnimationMask@>
#define uvAnimationMaskMap 7
float fetchUVAnimationMaskMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK);
return tableTexValue(matTex, uvAnimationMaskMap, uv).r;
float fetchUVAnimationMaskMap(int layer, mat2 uvs) {
DEFINE_MAT_TEXS
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK);
return tableTexValue(_matTexs[layer], uvAnimationMaskMap, uv).r;
}
<@endif@>
@ -569,18 +714,34 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
<@if withAlbedo@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO) uniform sampler2D albedoMap;
vec4 fetchAlbedoMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_2) uniform sampler2D albedoMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_3) uniform sampler2D albedoMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_ALBEDO3_3) uniform sampler2D albedoMap3;
<@endif@>
vec4 fetchAlbedoMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
vec4 albedo;
SAMPLE_MAP_LAYER(albedo, layer, uv, rgba)
return albedo;
}
<@endif@>
<@if withNormal@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL) uniform sampler2D normalMap;
vec3 fetchNormalMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL2_2) uniform sampler2D normalMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL2_3) uniform sampler2D normalMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_NORMAL3_3) uniform sampler2D normalMap3;
<@endif@>
vec3 fetchNormalMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_NORMAL);
// 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));
vec2 normal;
SAMPLE_MAP_LAYER(normal, layer, uv, rg)
vec2 t = 2.0 * (normal - vec2(0.5, 0.5));
vec2 t2 = t*t;
return vec3(t.x, sqrt(max(0.0, 1.0 - t2.x - t2.y)), t.y);
}
@ -588,98 +749,158 @@ vec3 fetchNormalMap(mat2 uvs) {
<@if withShade@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADE) uniform sampler2D shadeMap;
vec3 fetchShadeMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SHADE);
return texture(shadeMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADE2_2) uniform sampler2D shadeMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADE2_3) uniform sampler2D shadeMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADE3_3) uniform sampler2D shadeMap3;
<@endif@>
vec3 fetchShadeMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SHADE);
vec3 shade;
SAMPLE_MAP_LAYER(shade, layer, uv, rgb)
return shade;
}
<@endif@>
<@if withEmissive@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
vec3 fetchEmissiveMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_2) uniform sampler2D emissiveMap2;
<@elif HIFI_USE_LAYERS3@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_3) uniform sampler2D emissiveMap2;
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP3_3) uniform sampler2D emissiveMap3;
<@endif@>
vec3 fetchEmissiveMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP);
vec3 emissive;
SAMPLE_MAP_LAYER(emissive, layer, uv, rgb)
return emissive;
}
<@endif@>
<! only supported for 1 or 2 layers !>
<@if not HIFI_USE_LAYERS3@>
<@if withShadingShift@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT) uniform sampler2D shadingShiftMap;
float fetchShadingShiftMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT);
return texture(shadingShiftMap, uv, TAA_TEXTURE_LOD_BIAS).r;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT2_2) uniform sampler2D shadingShiftMap2;
<@endif@>
float fetchShadingShiftMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT);
float shadingShift;
SAMPLE_MAP_LAYER(shadingShift, layer, uv, r)
return shadingShift;
}
<@endif@>
<@if withMatcap@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_MATCAP) uniform sampler2D matcapMap;
vec3 fetchMatcapMap(vec2 uv) {
return texture(matcapMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
<@if HIFI_USE_LAYERS2@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_MATCAP2_2) uniform sampler2D matcapMap2;
<@endif@>
vec3 fetchMatcapMap(int layer, vec2 uv) {
vec3 matcap;
SAMPLE_MAP_LAYER(matcap, layer, uv, rgb)
return matcap;
}
<@endif@>
<@endif@>
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
<! only supported for 1 layer !>
<@else@>
<@if withRim@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_RIM) uniform sampler2D rimMap;
vec3 fetchRimMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_RIM);
return texture(rimMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
vec3 fetchRimMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_RIM);
vec3 rim;
SAMPLE_MAP_LAYER(rim, layer, uv, rgb)
return rim;
}
<@endif@>
<@if withUVAnimationMask@>
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK) uniform sampler2D uvAnimationMaskMap;
float fetchUVAnimationMaskMap(mat2 uvs) {
vec2 uv = evalTexCoordSet(uvs, GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK);
return texture(uvAnimationMaskMap, uv, TAA_TEXTURE_LOD_BIAS).r;
float fetchUVAnimationMaskMap(int layer, mat2 uvs) {
vec2 uv = evalTexCoordSet(layer, uvs, GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK);
float uvAnimationMask;
SAMPLE_MAP_LAYER(uvAnimationMask, layer, uv, r)
return uvAnimationMask;
}
<@endif@>
<@endif@>
#endif
<@endfunc@>
<@func fetchMToonMaterialTextures(matKey, texcoords, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
vec2 albedoTexCoords = evalTexCoordSet(<$texcoords$>, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
if (getTexMapArray()._materialParams.y != 1.0 && clamp(albedoTexCoords, vec2(0.0), vec2(1.0)) != albedoTexCoords) {
<@func fetchMToonMaterialTextures(layer, matKey, texcoords, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
vec2 albedoTexCoords = evalTexCoordSet(<$layer$>, <$texcoords$>, GRAPHICS_TEXTURE_MATERIAL_ALBEDO);
if (getTexMapArray(<$layer$>)._materialParams.y != 1.0 && clamp(albedoTexCoords, vec2(0.0), vec2(1.0)) != albedoTexCoords) {
discard;
}
vec2 texCoord = <$texcoords$>[0];
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
<! only supported for 1 layer !>
<@else@>
<@if uvScrollSpeed and time@>
if ((<$matKey$> & UV_ANIMATION_SCROLL_VAL_BIT) != 0) {
<$uvScrollSpeed$> *= mix(1.0, fetchUVAnimationMaskMap(<$texcoords$>), float((<$matKey$> & UV_ANIMATION_MASK_MAP_BIT) != 0));
<$uvScrollSpeed$> *= mix(1.0, fetchUVAnimationMaskMap(<$layer$>, <$texcoords$>), float((<$matKey$> & UV_ANIMATION_MASK_MAP_BIT) != 0));
<$uvScrollSpeed$> *= time;
float cosTime = cos(<$uvScrollSpeed$>.z);
float sinTime = sin(<$uvScrollSpeed$>.z);
texCoord = (mat3(cosTime, sinTime, 0, -sinTime, cosTime, 0, 0, 0, 1) * vec3(texCoord - vec2(0.5), 1.0)).xy + vec2(0.5) + <$uvScrollSpeed$>.xy;
}
<@endif@>
<@endif@>
mat2 texCoordsMToon = mat2(texCoord, <$texcoords$>[1]);
<@if albedo@>
vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(texCoordsMToon), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0));
vec4 <$albedo$> = mix(vec4(1.0), fetchAlbedoMap(<$layer$>, texCoordsMToon), float((<$matKey$> & (ALBEDO_MAP_BIT | OPACITY_MASK_MAP_BIT | OPACITY_TRANSLUCENT_MAP_BIT)) != 0));
<@endif@>
<@if normal@>
vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(texCoordsMToon), float((<$matKey$> & NORMAL_MAP_BIT) != 0));
vec3 <$normal$> = mix(vec3(0.0, 1.0, 0.0), fetchNormalMap(<$layer$>, texCoordsMToon), float((<$matKey$> & NORMAL_MAP_BIT) != 0));
<@endif@>
<@if shade@>
vec3 <$shade$> = float((<$matKey$> & SHADE_MAP_BIT) != 0) * fetchShadeMap(texCoordsMToon);
vec3 <$shade$> = float((<$matKey$> & SHADE_MAP_BIT) != 0) * fetchShadeMap(<$layer$>, texCoordsMToon);
<@endif@>
<@if emissive@>
vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(texCoordsMToon);
vec3 <$emissive$> = float((<$matKey$> & EMISSIVE_MAP_BIT) != 0) * fetchEmissiveMap(<$layer$>, texCoordsMToon);
<@endif@>
<@if not HIFI_USE_LAYERS3@>
<@if shadingShift@>
float <$shadingShift$> = float((<$matKey$> & SHADING_SHIFT_MAP_BIT) != 0) * fetchShadingShiftMap(texCoordsMToon);
float <$shadingShift$> = float((<$matKey$> & SHADING_SHIFT_MAP_BIT) != 0) * fetchShadingShiftMap(<$layer$>, texCoordsMToon);
<@endif@>
<@else@>
// only supported for 1 or 2 layers
<@if shadingShift@>
float <$shadingShift$> = 0.0;
<@endif@>
<@endif@>
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
<@if rim@>
vec3 <$rim$> = mix(vec3(1.0), fetchRimMap(texCoordsMToon), float((<$matKey$> & RIM_MAP_BIT) != 0));
// only supported for 1 layer
vec3 <$rim$> = vec3(1.0);
<@endif@>
<@else@>
<@if rim@>
vec3 <$rim$> = mix(vec3(1.0), fetchRimMap(<$layer$>, texCoordsMToon), float((<$matKey$> & RIM_MAP_BIT) != 0));
<@endif@>
<@endif@>
<@endfunc@>
<@if HIFI_USE_TRIPLANAR@>
<@func fetchMToonMaterialTexturesTriplanar(matKey, positionMS, normalMS, texCoord1, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
<@func fetchMToonMaterialTexturesTriplanar(matKeys, positionMS, normalMS, texCoords, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@>
vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz;
vec3 normalMS = normalize(<$normalMS$>);
@ -692,13 +913,29 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
vec3 axisSign = sign(normalMS.xyz);
<@endif@>
TexMapArray texMapArray = getTexMapArray();
<@if HIFI_USE_LAYERS3@>
const int LAYER_X = 0;
const int LAYER_Y = 1;
const int LAYER_Z = 2;
<@elif HIFI_USE_LAYERS2@>
const int LAYER_X = 1;
const int LAYER_Y = 0;
const int LAYER_Z = 1;
<@else@>
const int LAYER_X = 0;
const int LAYER_Y = 0;
const int LAYER_Z = 0;
<@endif@>
TexMapArray texMapArrayZ = getTexMapArray(LAYER_Z);
vec2 uvXY = vec2(-inPosition.x, -inPosition.y);
<$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$>
<$evalTexMapArrayTexcoord0(texMapArrayZ, uvXY, _positionWS, uvXY)$>
TexMapArray texMapArrayY = getTexMapArray(LAYER_Y);
vec2 uvXZ = vec2(-inPosition.x, inPosition.z);
<$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$>
<$evalTexMapArrayTexcoord0(texMapArrayY, uvXZ, _positionWS, uvXZ)$>
TexMapArray texMapArrayX = getTexMapArray(LAYER_X);
vec2 uvYZ = vec2(inPosition.z, -inPosition.y);
<$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$>
<$evalTexMapArrayTexcoord0(texMapArrayX, uvYZ, _positionWS, uvYZ)$>
<@if albedo@>
vec4 <$albedo$>Triplanar = vec4(0.0);
@ -720,8 +957,9 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
<@endif@>
{
mat2 triplanarUVs = mat2(uvXY, <$texCoord1$>);
<$fetchMToonMaterialTextures($matKey$, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
BITFIELD matKey = <$matKeys$>[LAYER_Z];
mat2 triplanarUVs = mat2(uvXY, <$texCoords$>[LAYER_Z].zw);
<$fetchMToonMaterialTextures(LAYER_Z, matKey, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
float magnitude = blend.z;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -746,8 +984,9 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
}
{
mat2 triplanarUVs = mat2(uvXZ, <$texCoord1$>);
<$fetchMToonMaterialTextures($matKey$, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
BITFIELD matKey = <$matKeys$>[LAYER_Y];
mat2 triplanarUVs = mat2(uvXZ, <$texCoords$>[LAYER_Y].zw);
<$fetchMToonMaterialTextures(LAYER_Y, matKey, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
float magnitude = blend.y;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -772,8 +1011,9 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
}
{
mat2 triplanarUVs = mat2(uvYZ, <$texCoord1$>);
<$fetchMToonMaterialTextures($matKey$, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
BITFIELD matKey = <$matKeys$>[LAYER_X];
mat2 triplanarUVs = mat2(uvYZ, <$texCoords$>[LAYER_X].zw);
<$fetchMToonMaterialTextures(LAYER_X, matKey, triplanarUVs, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$>
float magnitude = blend.x;
<@if albedo@>
<$albedo$>Triplanar += magnitude * <$albedo$>;
@ -838,13 +1078,16 @@ float fetchUVAnimationMaskMap(mat2 uvs) {
}
<@endfunc@>
<@func evalMaterialMatcap(texcoord, materialMatcap, matKey, matcap)@>
<@func evalMaterialMatcap(layer, texcoord, materialMatcap, matKey, matcap)@>
{
if ((<$matKey$> & (MATCAP_VAL_BIT | MATCAP_MAP_BIT)) == 0) {
<$matcap$> = vec3(0.0);
} else {
<$matcap$> = mix(vec3(1.0), <$materialMatcap$>, float((<$matKey$> & MATCAP_VAL_BIT) != 0));
<$matcap$> *= mix(vec3(1.0), fetchMatcapMap(<$texcoord$>), float((<$matKey$> & MATCAP_MAP_BIT) != 0));
<! only supported for 1 or 2 layers !>
<@if not HIFI_USE_LAYERS3@>
<$matcap$> *= mix(vec3(1.0), fetchMatcapMap(<$layer$>, <$texcoord$>), float((<$matKey$> & MATCAP_MAP_BIT) != 0));
<@endif@>
}
}
<@endfunc@>

View file

@ -15,14 +15,20 @@
#ifndef GRAPHICS_SHADER_CONSTANTS_H
#define GRAPHICS_SHADER_CONSTANTS_H
#define GRAPHICS_BUFFER_SKINNING 0
#define GRAPHICS_BUFFER_MATERIAL 1
#define GRAPHICS_BUFFER_KEY_LIGHT 4
#define GRAPHICS_BUFFER_LIGHT 5
#define GRAPHICS_BUFFER_AMBIENT_LIGHT 6
#define GRAPHICS_BUFFER_HAZE_PARAMS 7
#define GRAPHICS_BUFFER_TRIPLANAR_SCALE 8
#define GRAPHICS_BUFFER_MATERIAL 0
#define GRAPHICS_BUFFER_SKINNING 1
#define GRAPHICS_BUFFER_TRIPLANAR_SCALE 2
#define GRAPHICS_BUFFER_KEY_LIGHT 3
#define GRAPHICS_BUFFER_LIGHT 4
#define GRAPHICS_BUFFER_AMBIENT_LIGHT 5
#define GRAPHICS_BUFFER_HAZE_PARAMS 6
// Textures 0 - 11 are used by material layers (although usually fewer for 1 layer)
// 12 is the fade texture
// 13 is the skybox
// 14 is the ambient fresnel LUT
// 15 is the splat map
#define GRAPHICS_TEXTURE_MATERIAL_ALBEDO 0
#define GRAPHICS_TEXTURE_MATERIAL_NORMAL 1
#define GRAPHICS_TEXTURE_MATERIAL_METALLIC 2
@ -30,8 +36,28 @@
#define GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS 4
#define GRAPHICS_TEXTURE_MATERIAL_OCCLUSION 5
#define GRAPHICS_TEXTURE_MATERIAL_SCATTERING 6
// 2 layers
#define GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_2 6
#define GRAPHICS_TEXTURE_MATERIAL_NORMAL2_2 7
#define GRAPHICS_TEXTURE_MATERIAL_METALLIC2_2 8
#define GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_2 9
#define GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS2_2 10
#define GRAPHICS_TEXTURE_MATERIAL_OCCLUSION2_2 11
// 3 layers
#define GRAPHICS_TEXTURE_MATERIAL_ALBEDO2_3 4
#define GRAPHICS_TEXTURE_MATERIAL_NORMAL2_3 5
#define GRAPHICS_TEXTURE_MATERIAL_METALLIC2_3 6
#define GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP2_3 7
#define GRAPHICS_TEXTURE_MATERIAL_ALBEDO3_3 8
#define GRAPHICS_TEXTURE_MATERIAL_NORMAL3_3 9
#define GRAPHICS_TEXTURE_MATERIAL_METALLIC3_3 10
#define GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP3_3 11
#define GRAPHICS_TEXTURE_MATERIAL_MIRROR 1 // Mirrors use albedo textures, but nothing else
// MToon
// Keep aligned with procedural/ProceduralMaterialCache.h
#define GRAPHICS_TEXTURE_MATERIAL_SHADE GRAPHICS_TEXTURE_MATERIAL_METALLIC
#define GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS
@ -39,9 +65,22 @@
#define GRAPHICS_TEXTURE_MATERIAL_RIM GRAPHICS_TEXTURE_MATERIAL_SCATTERING
#define GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK 7
// 2 layers
#define GRAPHICS_TEXTURE_MATERIAL_SHADE2_2 GRAPHICS_TEXTURE_MATERIAL_METALLIC2_2
#define GRAPHICS_TEXTURE_MATERIAL_SHADING_SHIFT2_2 GRAPHICS_TEXTURE_MATERIAL_ROUGHNESS2_2
#define GRAPHICS_TEXTURE_MATERIAL_MATCAP2_2 GRAPHICS_TEXTURE_MATERIAL_OCCLUSION2_2
// 3 layers
#define GRAPHICS_TEXTURE_MATERIAL_SHADE2_3 GRAPHICS_TEXTURE_MATERIAL_METALLIC2_3
#define GRAPHICS_TEXTURE_MATERIAL_SHADE3_3 GRAPHICS_TEXTURE_MATERIAL_METALLIC3_3
// The OpenGL spec says hardware must support at least 16 textures at once, so we use the last
// guaranteed slot for the splat map.
#define GRAPHICS_TEXTURE_MATERIAL_SPLAT 15
// Make sure these match the ones in render-utils/ShaderConstants.h
#define GRAPHICS_TEXTURE_SKYBOX 11
#define GRAPHICS_BUFFER_SKYBOX_PARAMS 5
#define GRAPHICS_TEXTURE_SKYBOX 13
#define GRAPHICS_BUFFER_SKYBOX_PARAMS 7
// <!
@ -49,14 +88,14 @@ namespace graphics { namespace slot {
namespace buffer {
enum Buffer {
Skinning = GRAPHICS_BUFFER_SKINNING,
Material = GRAPHICS_BUFFER_MATERIAL,
Light = GRAPHICS_BUFFER_LIGHT,
Skinning = GRAPHICS_BUFFER_SKINNING,
TriplanarScale = GRAPHICS_BUFFER_TRIPLANAR_SCALE,
KeyLight = GRAPHICS_BUFFER_KEY_LIGHT,
Light = GRAPHICS_BUFFER_LIGHT,
AmbientLight = GRAPHICS_BUFFER_AMBIENT_LIGHT,
SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS,
HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS,
TriplanarScale = GRAPHICS_BUFFER_TRIPLANAR_SCALE
SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS,
};
} // namespace buffer
@ -77,6 +116,8 @@ enum Texture {
MaterialMatcap = GRAPHICS_TEXTURE_MATERIAL_MATCAP,
MaterialRim = GRAPHICS_TEXTURE_MATERIAL_RIM,
MaterialUVAnimationMask = GRAPHICS_TEXTURE_MATERIAL_UV_ANIMATION_MASK,
MaterialSplat = GRAPHICS_TEXTURE_MATERIAL_SPLAT,
};
} // namespace texture

View file

@ -19,7 +19,7 @@
namespace udt {
static const int UDP_IPV4_HEADER_SIZE = 28;
static const int MAX_PACKET_SIZE_WITH_UDP_HEADER = 1492;
static const int MAX_PACKET_SIZE_WITH_UDP_HEADER = 1452;
static const int MAX_PACKET_SIZE = MAX_PACKET_SIZE_WITH_UDP_HEADER - UDP_IPV4_HEADER_SIZE;
static const int MAX_PACKETS_IN_FLIGHT = 25600;
static const int CONNECTION_RECEIVE_BUFFER_SIZE_PACKETS = 8192;

View file

@ -318,6 +318,14 @@ static void setMaterialMap(const QJsonValue& value, const std::shared_ptr<Networ
* @property {boolean} defaultFallthrough=false - <code>true</code> if all properties fall through to the material below
* unless they are set, <code>false</code> if properties respect their individual fall-through settings.
* Supported models: all.
* @property {number} layers=1 - The number of material layers to use, between <code>1</code> and <code>3</code>. If <code>splatMap</code> is
* specified, the layers will be mixed based on that. If the top material is triplanar and <code>layers</code> is <code>3</code>, the top
* 3 materials will be applied to the X, Y, and Z planes respectively, and if <code>layers</code> is <code>2</code>, the top material will be
* used for the Y plane and the second material will be used for X and Z. Otherwise, the layers will be blended based on alpha. You cannot mix
* material of different <code>models</code>. Supported models: <code>"hifi_pbr"</code>, <code>"vrm_mtoon"</code>.
* @property {string|Entities.Texture} splatMap - The URL of the splat texture image, or an entity ID. An entity ID may be that of an Image
* or Web entity. The RGB channels define how material layers are mixed, if <code>layers > 1</code>. Supported models: <code>"hifi_pbr"</code>,
* <code>"vrm_mtoon"</code>.
* @property {ProceduralData} procedural - The definition of a procedural shader material. Supported models: <code>"hifi_shader_simple"</code>.
* @property {ColorFloat|RGBS|string} shade - The shade color. A {@link ColorFloat} value is treated as sRGB and must have
* component values in the range <code>0.0</code> &ndash; <code>1.0</code>. A {@link RGBS} value can be either RGB or sRGB.
@ -490,6 +498,16 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
auto value = materialJSON.value(key);
setMaterialMap(value, material, graphics::MaterialKey::FlagBit::NORMAL_MAP_BIT, graphics::Material::MapChannel::NORMAL_MAP,
baseUrl, [&](const QUrl& url) { material->setNormalMap(url, true); });
} else if (key == "layers") {
auto value = materialJSON.value(key);
if (value.isDouble()) {
material->setLayers(value.toInt());
}
} else if (key == "splatMap") {
auto value = materialJSON.value(key);
setMaterialMap(value, material, graphics::MaterialKey::FlagBit::SPLAT_MAP_BIT,
graphics::Material::MapChannel::SPLAT_MAP, baseUrl,
[&](const QUrl& url) { material->setSplatMap(url); });
} else if (key == "texCoordTransform0") {
auto value = materialJSON.value(key);
if (value.isString()) {
@ -935,6 +953,13 @@ void NetworkMaterial::setLightMap(const QUrl& url) {
}
}
void NetworkMaterial::setSplatMap(const QUrl& url) {
auto map = fetchTextureMap(url, image::TextureUsage::ALBEDO_TEXTURE, MapChannel::SPLAT_MAP);
if (map) {
setTextureMap(MapChannel::SPLAT_MAP, map);
}
}
NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl) :
graphics::Material(*material._material)
{

View file

@ -35,6 +35,7 @@ public:
void setEmissiveMap(const QUrl& url);
void setScatteringMap(const QUrl& url);
void setLightMap(const QUrl& url);
void setSplatMap(const QUrl& url);
virtual bool isMissingTexture();
virtual bool checkResetOpacityMap();

View file

@ -124,6 +124,13 @@ bool ReferenceMaterial::getDefaultFallthrough() const {
});
}
uint8_t ReferenceMaterial::getLayers() const {
return resultWithLock<bool>([&] {
auto material = getMaterial();
return material ? material->getLayers() : 1;
});
}
// NetworkMaterial
bool ReferenceMaterial::isMissingTexture() {
return resultWithLock<bool>([&] {

View file

@ -34,6 +34,7 @@ public:
graphics::Material::TextureMaps getTextureMaps() const override;
glm::vec2 getLightmapParams() const override;
bool getDefaultFallthrough() const override;
uint8_t getLayers() const override;
// NetworkMaterial
bool isMissingTexture() override;

View file

@ -322,7 +322,7 @@ vec3 evalGlobalLightingAlphaBlendedMToon(
const float epsilon = 0.00001;
vec3 rimDiffuse;
<$evalMaterialMatcap(matcapUV, matcap, matKey, rimDiffuse)$>;
<$evalMaterialMatcap(0, matcapUV, matcap, matKey, rimDiffuse)$>;
float rimColor = clamp(1.0 - dot(surfaceWS.normal, surfaceWS.eyeDir) + parametricRimLift, 0.0, 1.0);
rimColor = pow(rimColor, max(parametricRimFresnelPower, epsilon));
rimDiffuse += rimColor * parametricRim;

View file

@ -277,6 +277,8 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
builder.withMaterial();
builder.withLayers(_drawMaterials.getLayers());
if (hasTangents) {
builder.withTangents();
}
@ -295,6 +297,8 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
if ((MaterialMappingMode)material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) {
builder.withTriplanar();
} else if (_drawMaterials.isSplatMap()) {
builder.withSplatMap();
}
}
}

View file

@ -36,13 +36,20 @@ bool RenderPipelines::bindMaterial(graphics::MaterialPointer& material, Batch& b
}
void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial) {
auto& drawMaterialTextures = multiMaterial.getTextureTable();
auto& drawMaterialTextures = multiMaterial.getTextureTables();
multiMaterial.setTexturesLoading(false);
multiMaterial.resetReferenceTexturesAndMaterials();
multiMaterial.setisMToon(!multiMaterial.empty() && multiMaterial.top().material && multiMaterial.top().material->isMToon());
if (!multiMaterial.empty() && multiMaterial.top().material) {
multiMaterial.setisMToonAndLayers(multiMaterial.top().material->isMToon(),
std::max(1, std::min((int)multiMaterial.size(), (int)multiMaterial.top().material->getLayers())));
} else {
multiMaterial.setisMToonAndLayers(false, 1);
}
multiMaterial.resetOutline();
multiMaterial.resetSamplers();
multiMaterial.setSplatMap(nullptr);
// The total list of things we need to look for
static std::set<uint> allFlags;
static std::once_flag once;
@ -59,13 +66,19 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
});
graphics::MultiMaterial materials = multiMaterial;
graphics::MultiMaterial::Schema schema;
graphics::MultiMaterial::MToonSchema toonSchema;
graphics::MaterialKey schemaKey;
std::array<graphics::MultiMaterial::Schema, 3> schemas;
std::array<graphics::MultiMaterial::MToonSchema, 3> toonSchemas;
std::array<graphics::MaterialKey, 3> schemaKeys;
std::set<uint> flagsToCheck = allFlags;
std::set<uint> flagsToSetDefault;
std::array<std::set<uint>, 3> flagsToCheck;
flagsToCheck.fill(allFlags);
// We only look for splat maps on the first material
for (int i = 1; i < 3; i++) {
flagsToCheck[i].erase(graphics::MaterialKey::SPLAT_MAP_BIT);
}
std::array<std::set<uint>, 3> flagsToSetDefault;
uint8_t layerIndex = 0;
while (!materials.empty()) {
auto material = materials.top().material;
if (!material) {
@ -81,8 +94,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
const auto materialKey = material->getKey();
const auto textureMaps = material->getTextureMaps();
auto it = flagsToCheck.begin();
while (it != flagsToCheck.end()) {
auto it = flagsToCheck[layerIndex].begin();
while (it != flagsToCheck[layerIndex].end()) {
auto flag = *it;
bool fallthrough = defaultFallthrough || material->getPropertyFallthrough(flag);
@ -92,56 +105,56 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
switch (flag) {
case graphics::MaterialKey::EMISSIVE_VAL_BIT:
if (materialKey.isEmissive()) {
schema._emissive = material->getEmissive(false);
schemaKey.setEmissive(true);
schemas[layerIndex]._emissive = material->getEmissive(false);
schemaKeys[layerIndex].setEmissive(true);
wasSet = true;
}
break;
case graphics::MaterialKey::UNLIT_VAL_BIT:
if (materialKey.isUnlit()) {
schemaKey.setUnlit(true);
schemaKeys[layerIndex].setUnlit(true);
wasSet = true;
}
break;
case graphics::MaterialKey::ALBEDO_VAL_BIT:
if (materialKey.isAlbedo()) {
schema._albedo = material->getAlbedo(false);
schemaKey.setAlbedo(true);
schemas[layerIndex]._albedo = material->getAlbedo(false);
schemaKeys[layerIndex].setAlbedo(true);
wasSet = true;
}
break;
case graphics::MaterialKey::METALLIC_VAL_BIT:
if (materialKey.isMetallic()) {
schema._metallic = material->getMetallic();
schemaKey.setMetallic(true);
schemas[layerIndex]._metallic = material->getMetallic();
schemaKeys[layerIndex].setMetallic(true);
wasSet = true;
}
break;
case graphics::MaterialKey::GLOSSY_VAL_BIT:
if (materialKey.isRough() || materialKey.isGlossy()) {
schema._roughness = material->getRoughness();
schemaKey.setGlossy(materialKey.isGlossy());
schemas[layerIndex]._roughness = material->getRoughness();
schemaKeys[layerIndex].setGlossy(materialKey.isGlossy());
wasSet = true;
}
break;
case graphics::MaterialKey::OPACITY_VAL_BIT:
if (materialKey.isTranslucentFactor()) {
schema._opacity = material->getOpacity();
schemaKey.setTranslucentFactor(true);
schemas[layerIndex]._opacity = material->getOpacity();
schemaKeys[layerIndex].setTranslucentFactor(true);
wasSet = true;
}
break;
case graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT:
if (materialKey.isOpacityCutoff()) {
schema._opacityCutoff = material->getOpacityCutoff();
schemaKey.setOpacityCutoff(true);
schemas[layerIndex]._opacityCutoff = material->getOpacityCutoff();
schemaKeys[layerIndex].setOpacityCutoff(true);
wasSet = true;
}
break;
case graphics::MaterialKey::SCATTERING_VAL_BIT:
if (materialKey.isScattering()) {
schema._scattering = material->getScattering();
schemaKey.setScattering(true);
schemas[layerIndex]._scattering = material->getScattering();
schemaKeys[layerIndex].setScattering(true);
wasSet = true;
}
break;
@ -151,7 +164,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
material->resetOpacityMap();
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::ALBEDO_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -164,10 +177,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setAlbedoMap(true);
schemaKey.setOpacityMaskMap(material->getKey().isOpacityMaskMap());
schemaKey.setTranslucentMap(material->getKey().isTranslucentMap());
schema.setTexCoordSet(gr::Texture::MaterialAlbedo, material->getTexCoordSet(graphics::MaterialKey::ALBEDO_MAP));
schemaKeys[layerIndex].setAlbedoMap(true);
schemaKeys[layerIndex].setOpacityMaskMap(material->getKey().isOpacityMaskMap());
schemaKeys[layerIndex].setTranslucentMap(material->getKey().isTranslucentMap());
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialAlbedo, material->getTexCoordSet(graphics::MaterialKey::ALBEDO_MAP));
}
break;
case graphics::MaterialKey::METALLIC_MAP_BIT:
@ -175,7 +188,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::METALLIC_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialMetallic, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialMetallic, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::METALLIC_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -188,8 +201,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setMetallicMap(true);
schema.setTexCoordSet(gr::Texture::MaterialMetallic, material->getTexCoordSet(graphics::MaterialKey::METALLIC_MAP));
schemaKeys[layerIndex].setMetallicMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialMetallic, material->getTexCoordSet(graphics::MaterialKey::METALLIC_MAP));
}
break;
case graphics::MaterialKey::ROUGHNESS_MAP_BIT:
@ -197,7 +210,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::ROUGHNESS_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialRoughness, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialRoughness, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::ROUGHNESS_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -210,8 +223,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setRoughnessMap(true);
schema.setTexCoordSet(gr::Texture::MaterialRoughness, material->getTexCoordSet(graphics::MaterialKey::ROUGHNESS_MAP));
schemaKeys[layerIndex].setRoughnessMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialRoughness, material->getTexCoordSet(graphics::MaterialKey::ROUGHNESS_MAP));
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
@ -219,7 +232,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::NORMAL_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -232,8 +245,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setNormalMap(true);
schema.setTexCoordSet(gr::Texture::MaterialNormal, material->getTexCoordSet(graphics::MaterialKey::NORMAL_MAP));
schemaKeys[layerIndex].setNormalMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialNormal, material->getTexCoordSet(graphics::MaterialKey::NORMAL_MAP));
}
break;
case graphics::MaterialKey::OCCLUSION_MAP_BIT:
@ -241,7 +254,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::OCCLUSION_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialOcclusion, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::OCCLUSION_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -254,8 +267,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setOcclusionMap(true);
schema.setTexCoordSet(gr::Texture::MaterialOcclusion, material->getTexCoordSet(graphics::MaterialKey::OCCLUSION_MAP));
schemaKeys[layerIndex].setOcclusionMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialOcclusion, material->getTexCoordSet(graphics::MaterialKey::OCCLUSION_MAP));
}
break;
case graphics::MaterialKey::SCATTERING_MAP_BIT:
@ -263,7 +276,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::SCATTERING_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialScattering, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialScattering, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::SCATTERING_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -276,8 +289,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setScatteringMap(true);
schema.setTexCoordSet(gr::Texture::MaterialScattering, material->getTexCoordSet(graphics::MaterialKey::SCATTERING_MAP));
schemaKeys[layerIndex].setScatteringMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialScattering, material->getTexCoordSet(graphics::MaterialKey::SCATTERING_MAP));
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
@ -286,7 +299,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::EMISSIVE_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -299,8 +312,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setEmissiveMap(true);
schema.setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::EMISSIVE_MAP));
schemaKeys[layerIndex].setEmissiveMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::EMISSIVE_MAP));
} else if (materialKey.isLightMap()) {
// We'll set this later when we check the lightmap
wasSet = true;
@ -311,7 +324,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::LIGHT_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::LIGHT_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -324,31 +337,51 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setLightMap(true);
schema.setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::LIGHT_MAP));
schemaKeys[layerIndex].setLightMap(true);
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::LIGHT_MAP));
}
break;
case graphics::MaterialKey::SPLAT_MAP_BIT: {
auto itr = textureMaps.find(graphics::MaterialKey::SPLAT_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
multiMaterial.setSplatMap(itr->second->getTextureView()._texture);
multiMaterial.addSamplerFunc([=]() { material->applySampler(graphics::MaterialKey::SPLAT_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
}
wasSet = true;
} else {
multiMaterial.setTexturesLoading(true);
forceDefault = true;
}
schemas[layerIndex].setTexCoordSet(gr::Texture::MaterialSplat, material->getTexCoordSet(graphics::MaterialKey::SPLAT_MAP));
} else {
forceDefault = true;
}
break;
}
case graphics::Material::TEXCOORDTRANSFORM0:
if (!fallthrough) {
schema._texcoordTransforms[0] = material->getTexCoordTransform(0);
schemas[layerIndex]._texcoordTransforms[0] = material->getTexCoordTransform(0);
wasSet = true;
}
break;
case graphics::Material::TEXCOORDTRANSFORM1:
if (!fallthrough) {
schema._texcoordTransforms[1] = material->getTexCoordTransform(1);
schemas[layerIndex]._texcoordTransforms[1] = material->getTexCoordTransform(1);
wasSet = true;
}
break;
case graphics::Material::LIGHTMAP_PARAMS:
if (!fallthrough) {
schema._lightmapParams = material->getLightmapParams();
schemas[layerIndex]._lightmapParams = material->getLightmapParams();
wasSet = true;
}
break;
case graphics::Material::MATERIAL_PARAMS:
if (!fallthrough) {
schema._materialParams = material->getMaterialParams();
schemas[layerIndex]._materialParams = material->getMaterialParams();
wasSet = true;
}
break;
@ -365,29 +398,29 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
switch (flag) {
case graphics::MaterialKey::EMISSIVE_VAL_BIT:
if (materialKey.isEmissive()) {
toonSchema._emissive = material->getEmissive(false);
schemaKey.setEmissive(true);
toonSchemas[layerIndex]._emissive = material->getEmissive(false);
schemaKeys[layerIndex].setEmissive(true);
wasSet = true;
}
break;
case graphics::MaterialKey::ALBEDO_VAL_BIT:
if (materialKey.isAlbedo()) {
toonSchema._albedo = material->getAlbedo(false);
schemaKey.setAlbedo(true);
toonSchemas[layerIndex]._albedo = material->getAlbedo(false);
schemaKeys[layerIndex].setAlbedo(true);
wasSet = true;
}
break;
case graphics::MaterialKey::OPACITY_VAL_BIT:
if (materialKey.isTranslucentFactor()) {
toonSchema._opacity = material->getOpacity();
schemaKey.setTranslucentFactor(true);
toonSchemas[layerIndex]._opacity = material->getOpacity();
schemaKeys[layerIndex].setTranslucentFactor(true);
wasSet = true;
}
break;
case graphics::MaterialKey::OPACITY_CUTOFF_VAL_BIT:
if (materialKey.isOpacityCutoff()) {
toonSchema._opacityCutoff = material->getOpacityCutoff();
schemaKey.setOpacityCutoff(true);
toonSchemas[layerIndex]._opacityCutoff = material->getOpacityCutoff();
schemaKeys[layerIndex].setOpacityCutoff(true);
wasSet = true;
}
break;
@ -397,7 +430,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
material->resetOpacityMap();
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialAlbedo, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::ALBEDO_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -410,10 +443,10 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setAlbedoMap(true);
schemaKey.setOpacityMaskMap(material->getKey().isOpacityMaskMap());
schemaKey.setTranslucentMap(material->getKey().isTranslucentMap());
toonSchema.setTexCoordSet(gr::Texture::MaterialAlbedo, material->getTexCoordSet(graphics::MaterialKey::ALBEDO_MAP));
schemaKeys[layerIndex].setAlbedoMap(true);
schemaKeys[layerIndex].setOpacityMaskMap(material->getKey().isOpacityMaskMap());
schemaKeys[layerIndex].setTranslucentMap(material->getKey().isTranslucentMap());
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialAlbedo, material->getTexCoordSet(graphics::MaterialKey::ALBEDO_MAP));
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
@ -421,7 +454,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::NORMAL_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialNormal, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::NORMAL_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -434,8 +467,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setNormalMap(true);
toonSchema.setTexCoordSet(gr::Texture::MaterialNormal, material->getTexCoordSet(graphics::MaterialKey::NORMAL_MAP));
schemaKeys[layerIndex].setNormalMap(true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialNormal, material->getTexCoordSet(graphics::MaterialKey::NORMAL_MAP));
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
@ -444,7 +477,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler(graphics::MaterialKey::EMISSIVE_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -457,28 +490,48 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey.setEmissiveMap(true);
toonSchema.setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::EMISSIVE_MAP));
schemaKeys[layerIndex].setEmissiveMap(true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialEmissiveLightmap, material->getTexCoordSet(graphics::MaterialKey::EMISSIVE_MAP));
} else if (materialKey.isLightMap()) {
// We'll set this later when we check the lightmap
wasSet = true;
}
break;
case graphics::MaterialKey::SPLAT_MAP_BIT: {
auto itr = textureMaps.find(graphics::MaterialKey::SPLAT_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
multiMaterial.setSplatMap(itr->second->getTextureView()._texture);
multiMaterial.addSamplerFunc([=]() { material->applySampler(graphics::MaterialKey::SPLAT_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
}
wasSet = true;
} else {
multiMaterial.setTexturesLoading(true);
forceDefault = true;
}
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialSplat, material->getTexCoordSet(graphics::MaterialKey::SPLAT_MAP));
} else {
forceDefault = true;
}
break;
}
case graphics::Material::TEXCOORDTRANSFORM0:
if (!fallthrough) {
toonSchema._texcoordTransforms[0] = material->getTexCoordTransform(0);
toonSchemas[layerIndex]._texcoordTransforms[0] = material->getTexCoordTransform(0);
wasSet = true;
}
break;
case graphics::Material::TEXCOORDTRANSFORM1:
if (!fallthrough) {
toonSchema._texcoordTransforms[1] = material->getTexCoordTransform(1);
toonSchemas[layerIndex]._texcoordTransforms[1] = material->getTexCoordTransform(1);
wasSet = true;
}
break;
case graphics::Material::MATERIAL_PARAMS:
if (!fallthrough) {
toonSchema._materialParams = material->getMaterialParams();
toonSchemas[layerIndex]._materialParams = material->getMaterialParams();
wasSet = true;
}
break;
@ -490,31 +543,31 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
break;
case NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT]) {
toonSchema._shade = material->getShade();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT, true);
toonSchemas[layerIndex]._shade = material->getShade();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADE_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT]) {
toonSchema._shadingShift = material->getShadingShift();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT, true);
toonSchemas[layerIndex]._shadingShift = material->getShadingShift();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT]) {
toonSchema._shadingToony = material->getShadingToony();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT, true);
toonSchemas[layerIndex]._shadingToony = material->getShadingToony();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_TOONY_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT]) {
toonSchema._uvAnimationScrollSpeed.x = material->getUVAnimationScrollXSpeed();
toonSchema._uvAnimationScrollSpeed.y = material->getUVAnimationScrollYSpeed();
toonSchema._uvAnimationScrollRotationSpeed = material->getUVAnimationRotationSpeed();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT, true);
toonSchemas[layerIndex]._uvAnimationScrollSpeed.x = material->getUVAnimationScrollXSpeed();
toonSchemas[layerIndex]._uvAnimationScrollSpeed.y = material->getUVAnimationScrollYSpeed();
toonSchemas[layerIndex]._uvAnimationScrollRotationSpeed = material->getUVAnimationRotationSpeed();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_SCROLL_VAL_BIT, true);
wasSet = true;
}
break;
@ -523,7 +576,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find((graphics::Material::MapChannel) NetworkMToonMaterial::SHADE_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialShade, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialShade, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler((graphics::Material::MapChannel) NetworkMToonMaterial::SHADE_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -536,8 +589,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT, true);
toonSchema.setTexCoordSet(gr::Texture::MaterialShade, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::SHADE_MAP));
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT, true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialShade, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::SHADE_MAP));
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT:
@ -545,7 +598,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find((graphics::Material::MapChannel) NetworkMToonMaterial::SHADING_SHIFT_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialShadingShift, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialShadingShift, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler((graphics::Material::MapChannel) NetworkMToonMaterial::SHADING_SHIFT_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -558,8 +611,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT, true);
toonSchema.setTexCoordSet(gr::Texture::MaterialShadingShift, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::SHADING_SHIFT_MAP));
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT, true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialShadingShift, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::SHADING_SHIFT_MAP));
}
break;
case NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT:
@ -567,7 +620,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find((graphics::Material::MapChannel) NetworkMToonMaterial::MATCAP_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialMatcap, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialMatcap, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler((graphics::Material::MapChannel) NetworkMToonMaterial::MATCAP_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -580,8 +633,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT, true);
toonSchema.setTexCoordSet(gr::Texture::MaterialMatcap, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::MATCAP_MAP));
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT, true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialMatcap, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::MATCAP_MAP));
}
break;
case NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT:
@ -589,7 +642,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find((graphics::Material::MapChannel) NetworkMToonMaterial::RIM_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialRim, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialRim, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler((graphics::Material::MapChannel) NetworkMToonMaterial::RIM_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -602,8 +655,8 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT, true);
toonSchema.setTexCoordSet(gr::Texture::MaterialRim, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::RIM_MAP));
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT, true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialRim, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::RIM_MAP));
}
break;
case NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT:
@ -611,7 +664,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
auto itr = textureMaps.find((graphics::Material::MapChannel) NetworkMToonMaterial::UV_ANIMATION_MASK_MAP);
if (itr != textureMaps.end()) {
if (itr->second->isDefined()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialUVAnimationMask, itr->second->getTextureView());
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialUVAnimationMask, itr->second->getTextureView());
multiMaterial.addSamplerFunc([=] () { material->applySampler((graphics::Material::MapChannel) NetworkMToonMaterial::UV_ANIMATION_MASK_MAP); });
if (itr->second->getTextureView().isReference()) {
multiMaterial.addReferenceTexture(itr->second->getTextureView().getTextureOperator());
@ -624,42 +677,42 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
} else {
forceDefault = true;
}
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT, true);
toonSchema.setTexCoordSet(gr::Texture::MaterialUVAnimationMask, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::UV_ANIMATION_MASK_MAP));
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT, true);
toonSchemas[layerIndex].setTexCoordSet(gr::Texture::MaterialUVAnimationMask, material->getTexCoordSet((graphics::Material::MapChannel) NetworkMToonMaterial::UV_ANIMATION_MASK_MAP));
}
break;
case NetworkMToonMaterial::MToonFlagBit::MATCAP_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::MATCAP_VAL_BIT]) {
toonSchema._matcap = material->getMatcap(false);
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::MATCAP_VAL_BIT, true);
toonSchemas[layerIndex]._matcap = material->getMatcap(false);
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::MATCAP_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_VAL_BIT]) {
toonSchema._parametricRim = material->getParametricRim(false);
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_VAL_BIT, true);
toonSchemas[layerIndex]._parametricRim = material->getParametricRim(false);
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT]) {
toonSchema._parametricRimFresnelPower = material->getParametricRimFresnelPower();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT, true);
toonSchemas[layerIndex]._parametricRimFresnelPower = material->getParametricRimFresnelPower();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_POWER_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT]) {
toonSchema._parametricRimLift = material->getParametricRimLift();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT, true);
toonSchemas[layerIndex]._parametricRimLift = material->getParametricRimLift();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::PARAMETRIC_RIM_LIFT_VAL_BIT, true);
wasSet = true;
}
break;
case NetworkMToonMaterial::MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT:
if (materialKey._flags[NetworkMToonMaterial::MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT]) {
toonSchema._rimLightingMix = material->getRimLightingMix();
schemaKey._flags.set(NetworkMToonMaterial::MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT, true);
toonSchemas[layerIndex]._rimLightingMix = material->getRimLightingMix();
schemaKeys[layerIndex]._flags.set(NetworkMToonMaterial::MToonFlagBit::RIM_LIGHTING_MIX_VAL_BIT, true);
wasSet = true;
}
break;
@ -687,136 +740,152 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
}
if (wasSet) {
flagsToCheck.erase(it++);
flagsToCheck[layerIndex].erase(it++);
} else if (forceDefault || !fallthrough) {
flagsToSetDefault.insert(flag);
flagsToCheck.erase(it++);
flagsToSetDefault[layerIndex].insert(flag);
flagsToCheck[layerIndex].erase(it++);
} else {
++it;
}
}
if (flagsToCheck.empty()) {
uint8_t numLayers = multiMaterial.getLayers();
if (numLayers > 1) {
// For layered materials, we stop when we reach the desired number of layers
if (layerIndex == numLayers - 1) {
break;
}
layerIndex++;
} else if (flagsToCheck[layerIndex].empty()) {
// For non-layered materials, we can stop once we've checked all the flags
break;
}
}
for (auto flagBit : flagsToCheck) {
flagsToSetDefault.insert(flagBit);
}
for (uint8_t layerIndex = 0; layerIndex < multiMaterial.getLayers(); layerIndex++) {
for (auto flagBit : flagsToCheck[layerIndex]) {
flagsToSetDefault[layerIndex].insert(flagBit);
}
auto textureCache = DependencyManager::get<TextureCache>();
// Handle defaults
for (auto flag : flagsToSetDefault) {
if (!multiMaterial.isMToon()) {
switch (flag) {
case graphics::Material::CULL_FACE_MODE:
multiMaterial.setCullFaceMode(graphics::Material::DEFAULT_CULL_FACE_MODE);
break;
case graphics::MaterialKey::ALBEDO_MAP_BIT:
if (schemaKey.isAlbedoMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::METALLIC_MAP_BIT:
if (schemaKey.isMetallicMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialMetallic, textureCache->getBlackTexture());
}
break;
case graphics::MaterialKey::ROUGHNESS_MAP_BIT:
if (schemaKey.isRoughnessMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialRoughness, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
if (schemaKey.isNormalMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, textureCache->getBlueTexture());
}
break;
case graphics::MaterialKey::OCCLUSION_MAP_BIT:
if (schemaKey.isOcclusionMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialOcclusion, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::SCATTERING_MAP_BIT:
if (schemaKey.isScatteringMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialScattering, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
if (schemaKey.isEmissiveMap() && !schemaKey.isLightMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
}
break;
case graphics::MaterialKey::LIGHT_MAP_BIT:
if (schemaKey.isLightMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
}
break;
default:
// everything else is initialized to the correct default values in Schema()
break;
}
} else {
switch (flag) {
case graphics::Material::CULL_FACE_MODE:
multiMaterial.setCullFaceMode(graphics::Material::DEFAULT_CULL_FACE_MODE);
break;
case graphics::MaterialKey::ALBEDO_MAP_BIT:
if (schemaKey.isAlbedoMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
if (schemaKey.isNormalMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialNormal, textureCache->getBlueTexture());
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
if (schemaKey.isEmissiveMap() && !schemaKey.isLightMap()) {
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT:
if (schemaKey._flags[NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT]) {
drawMaterialTextures->setTexture(gr::Texture::MaterialShade, textureCache->getWhiteTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT:
if (schemaKey._flags[NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT]) {
drawMaterialTextures->setTexture(gr::Texture::MaterialShadingShift, textureCache->getBlackTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT:
if (schemaKey._flags[NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT]) {
drawMaterialTextures->setTexture(gr::Texture::MaterialMatcap, textureCache->getBlackTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT:
if (schemaKey._flags[NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT]) {
drawMaterialTextures->setTexture(gr::Texture::MaterialRim, textureCache->getWhiteTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT:
if (schemaKey._flags[NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT]) {
drawMaterialTextures->setTexture(gr::Texture::MaterialUVAnimationMask, textureCache->getWhiteTexture());
}
break;
default:
// everything else is initialized to the correct default values in ToonSchema()
break;
auto textureCache = DependencyManager::get<TextureCache>();
// Handle defaults
for (auto flag : flagsToSetDefault[layerIndex]) {
if (!multiMaterial.isMToon()) {
switch (flag) {
case graphics::Material::CULL_FACE_MODE:
multiMaterial.setCullFaceMode(graphics::Material::DEFAULT_CULL_FACE_MODE);
break;
case graphics::MaterialKey::ALBEDO_MAP_BIT:
if (schemaKeys[layerIndex].isAlbedoMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::METALLIC_MAP_BIT:
if (schemaKeys[layerIndex].isMetallicMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialMetallic, textureCache->getBlackTexture());
}
break;
case graphics::MaterialKey::ROUGHNESS_MAP_BIT:
if (schemaKeys[layerIndex].isRoughnessMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialRoughness, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
if (schemaKeys[layerIndex].isNormalMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialNormal, textureCache->getBlueTexture());
}
break;
case graphics::MaterialKey::OCCLUSION_MAP_BIT:
if (schemaKeys[layerIndex].isOcclusionMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialOcclusion, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::SCATTERING_MAP_BIT:
if (schemaKeys[layerIndex].isScatteringMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialScattering, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
if (schemaKeys[layerIndex].isEmissiveMap() && !schemaKeys[layerIndex].isLightMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
}
break;
case graphics::MaterialKey::LIGHT_MAP_BIT:
if (schemaKeys[layerIndex].isLightMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
}
break;
default:
// everything else is initialized to the correct default values in Schema()
break;
}
} else {
switch (flag) {
case graphics::Material::CULL_FACE_MODE:
multiMaterial.setCullFaceMode(graphics::Material::DEFAULT_CULL_FACE_MODE);
break;
case graphics::MaterialKey::ALBEDO_MAP_BIT:
if (schemaKeys[layerIndex].isAlbedoMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialAlbedo, textureCache->getWhiteTexture());
}
break;
case graphics::MaterialKey::NORMAL_MAP_BIT:
if (schemaKeys[layerIndex].isNormalMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialNormal, textureCache->getBlueTexture());
}
break;
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
if (schemaKeys[layerIndex].isEmissiveMap() && !schemaKeys[layerIndex].isLightMap()) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT:
if (schemaKeys[layerIndex]._flags[NetworkMToonMaterial::MToonFlagBit::SHADE_MAP_BIT]) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialShade, textureCache->getWhiteTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT:
if (schemaKeys[layerIndex]._flags[NetworkMToonMaterial::MToonFlagBit::SHADING_SHIFT_MAP_BIT]) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialShadingShift, textureCache->getBlackTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT:
if (schemaKeys[layerIndex]._flags[NetworkMToonMaterial::MToonFlagBit::MATCAP_MAP_BIT]) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialMatcap, textureCache->getBlackTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT:
if (schemaKeys[layerIndex]._flags[NetworkMToonMaterial::MToonFlagBit::RIM_MAP_BIT]) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialRim, textureCache->getWhiteTexture());
}
break;
case NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT:
if (schemaKeys[layerIndex]._flags[NetworkMToonMaterial::MToonFlagBit::UV_ANIMATION_MASK_MAP_BIT]) {
drawMaterialTextures[layerIndex]->setTexture(gr::Texture::MaterialUVAnimationMask, textureCache->getWhiteTexture());
}
break;
default:
// everything else is initialized to the correct default values in ToonSchema()
break;
}
}
}
}
auto& schemaBuffer = multiMaterial.getSchemaBuffer();
if (multiMaterial.isMToon()) {
toonSchema._key = (uint32_t)schemaKey._flags.to_ulong();
schemaBuffer.edit<graphics::MultiMaterial::MToonSchema>() = toonSchema;
} else {
schema._key = (uint32_t)schemaKey._flags.to_ulong();
schemaBuffer.edit<graphics::MultiMaterial::Schema>() = schema;
uint32_t materialKey = 0;
for (uint8_t i = 0; i < multiMaterial.getLayers(); i++) {
uint32_t schemaKey = (uint32_t)schemaKeys[i]._flags.to_ulong();
materialKey |= schemaKey;
if (multiMaterial.isMToon()) {
toonSchemas[i]._key = schemaKey;
schemaBuffer._buffer->setSubData(i, toonSchemas[i]);
} else {
schemas[i]._key = schemaKey;
schemaBuffer._buffer->setSubData(i, schemas[i]);
}
}
multiMaterial.setMaterialKey(graphics::MaterialKey(materialKey));
multiMaterial.setNeedsUpdate(false);
multiMaterial.setInitialized();
}
@ -880,7 +949,17 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, Batc
auto& schemaBuffer = multiMaterial.getSchemaBuffer();
batch.setUniformBuffer(gr::Buffer::Material, schemaBuffer);
if (enableTextures) {
batch.setResourceTextureTable(multiMaterial.getTextureTable());
uint8_t numLayers = multiMaterial.getLayers();
auto& textureTables = multiMaterial.getTextureTables();
// We are limited to 16 textures at once. The last 3 slots are reserved for the splat map, skybox, and ambientFresnelLUT (the latter two for transparents only)
// So for 2 layers, we are limited to 6 textures each, and for 3 layers we are limited to 4 each
uint8_t offset = numLayers < 3 ? 6 : 4;
for (uint8_t i = 0; i < numLayers; i++) {
batch.setResourceTextureTable(textureTables[i], i * offset);
}
if (multiMaterial.isSplatMap()) {
batch.setResourceTexture(gr::Texture::MaterialSplat, multiMaterial.getSplatMap());
}
} else {
if (!multiMaterial.isMToon()) {
if (renderMode != Args::RenderMode::SHADOW_RENDER_MODE) {

View file

@ -51,43 +51,66 @@ void lightBatchSetter(const ShapePipeline& pipeline, Batch& batch, RenderArgs* a
static bool forceLightBatchSetter { false };
// builder, deferred pipeline, shadow pipeline, forward pipeline (or 0 if unsupported)
std::vector<std::tuple<Key::Builder, uint32_t, uint32_t, uint32_t>> ALL_PIPELINES = {
typedef std::tuple<Key::Builder, uint32_t, uint32_t, uint32_t> PipelineInfo;
std::vector<PipelineInfo> ALL_PIPELINES = {
@ALL_PIPELINES_MAP@
};
static bool delayLoadingPipeline(const ShapeKey& shapeKey) {
return shapeKey.hasLightMap() || shapeKey.isTriplanar() || shapeKey.numLayers() > 1;
}
void initDeferredPipelines(ShapePlumber& plumber, const ShapePipeline::BatchSetter& batchSetter, const ShapePipeline::ItemSetter& itemSetter) {
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, std::make_shared<State>(), _3, _4);
static std::unordered_map<ShapePlumber*, std::function<void(ShapeKey, int, ShapePipeline::BatchSetter, ShapePipeline::ItemSetter)>> addPipelineMap;
ShapePlumber* plumberKey = &plumber;
addPipelineMap[plumberKey] = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, std::make_shared<State>(), _3, _4);
static auto addPipeline = [=](const ShapeKey& key, int programId, ShapePlumber* plumberKey) {
if (key.isFaded()) {
addPipelineMap[plumberKey](key, programId, batchSetter, itemSetter);
} else {
addPipelineMap[plumberKey](key, programId, nullptr, nullptr);
}
};
for (auto& pipeline : ALL_PIPELINES) {
if (std::get<0>(pipeline).build().isFaded()) {
addPipeline(std::get<0>(pipeline), std::get<1>(pipeline), batchSetter, itemSetter);
render::ShapeKey shapeKey = std::get<0>(pipeline).build();
int programId = std::get<1>(pipeline);
if (delayLoadingPipeline(shapeKey)) {
plumber.addPipelineOperator(shapeKey, [=]() { addPipeline(shapeKey, programId, plumberKey); });
} else {
addPipeline(std::get<0>(pipeline), std::get<1>(pipeline), nullptr, nullptr);
addPipeline(shapeKey, programId, plumberKey);
}
}
}
void initForwardPipelines(ShapePlumber& plumber) {
auto addPipelineBind = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, std::make_shared<State>(), _3, _4);
static std::unordered_map<ShapePlumber*, std::function<void(ShapeKey, int, ShapePipeline::BatchSetter, ShapePipeline::ItemSetter)>> addPipelineMap;
ShapePlumber* plumberKey = &plumber;
addPipelineMap[plumberKey] = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, std::make_shared<State>(), _3, _4);
static auto addPipeline = [=](const ShapeKey& key, int programId, ShapePlumber* plumberKey) {
// Forward pipelines need the lightBatchSetter for opaques and transparents
forceLightBatchSetter = true;
// Disable fade on the forward pipeline, all shaders get added twice, once with the fade key and once without
auto addPipeline = [&](const ShapeKey& key, int programId) {
addPipelineBind(key, programId, nullptr, nullptr);
addPipelineBind(Key::Builder(key).withFade(), programId, nullptr, nullptr);
// Disable fade on the forward pipeline, all shaders get added twice, once with the fade key and once without
addPipelineMap[plumberKey](key, programId, nullptr, nullptr);
addPipelineMap[plumberKey](Key::Builder(key).withFade(), programId, nullptr, nullptr);
forceLightBatchSetter = false;
};
// Forward pipelines need the lightBatchSetter for opaques and transparents
forceLightBatchSetter = true;
for (auto& pipeline : ALL_PIPELINES) {
if (std::get<3>(pipeline) != 0) {
addPipeline(std::get<0>(pipeline), std::get<3>(pipeline));
int programId = std::get<3>(pipeline);
if (programId != 0) {
render::ShapeKey shapeKey = std::get<0>(pipeline).build();
if (delayLoadingPipeline(shapeKey)) {
plumber.addPipelineOperator(shapeKey, [=]() { addPipeline(shapeKey, programId, plumberKey); });
} else {
addPipeline(shapeKey, programId, plumberKey);
}
}
}
forceLightBatchSetter = false;
}
void addPlumberPipeline(ShapePlumber& plumber,
@ -184,13 +207,24 @@ void lightBatchSetter(const ShapePipeline& pipeline, Batch& batch, RenderArgs* a
}
void initZPassPipelines(ShapePlumber& plumber, StatePointer state, const ShapePipeline::BatchSetter& batchSetter, const ShapePipeline::ItemSetter& itemSetter) {
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, state, _3, _4);
static std::unordered_map<ShapePlumber*, std::function<void(ShapeKey, int, ShapePipeline::BatchSetter, ShapePipeline::ItemSetter)>> addPipelineMap;
ShapePlumber* plumberKey = &plumber;
addPipelineMap[plumberKey] = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, std::make_shared<State>(), _3, _4);
static auto addPipeline = [=](const ShapeKey& key, int programId, ShapePlumber* plumberKey) {
if (key.isFaded()) {
addPipelineMap[plumberKey](key, programId, batchSetter, itemSetter);
} else {
addPipelineMap[plumberKey](key, programId, nullptr, nullptr);
}
};
for (auto& pipeline : ALL_PIPELINES) {
if (std::get<0>(pipeline).build().isFaded()) {
addPipeline(std::get<0>(pipeline), std::get<2>(pipeline), batchSetter, itemSetter);
render::ShapeKey shapeKey = std::get<0>(pipeline).build();
int programId = std::get<2>(pipeline);
if (delayLoadingPipeline(shapeKey)) {
plumber.addPipelineOperator(shapeKey, [=]() { addPipeline(shapeKey, programId, plumberKey); });
} else {
addPipeline(std::get<0>(pipeline), std::get<2>(pipeline), nullptr, nullptr);
addPipeline(shapeKey, programId, plumberKey);
}
}
}
@ -237,6 +271,9 @@ void sortAndRenderZPassShapes(const ShapePlumberPointer& shapePlumber, const Ren
variantKey.withDepthBias();
}
//variantKey.withLayers(items.first.numLayers());
//splatmap?
if (items.first.hasOwnPipeline()) {
sortedOwnPipelineShapeKeys[variantKey.build()].push_back(items.first);
} else if (items.first.isCustom()) {

View file

@ -112,8 +112,17 @@
<@endif@>
layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _positionWS;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01;
#define _texCoords mat2(_texCoord01.xy, _texCoord01.zw)
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01[NUM_LAYERS];
#define _texCoords mat2[NUM_LAYERS]( \
mat2(_texCoord01[0].xy, _texCoord01[0].zw) \
<@if HIFI_USE_LAYERS2 or HIFI_USE_LAYERS3@>
, mat2(_texCoord01[1].xy, _texCoord01[1].zw) \
<@endif@>
<@if HIFI_USE_LAYERS3@>
, mat2(_texCoord01[2].xy, _texCoord01[2].zw) \
<@endif@>
)
<@if not HIFI_USE_SHADOW@>
layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES;
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS;
@ -146,41 +155,46 @@ void main(void) {
<@endif@>
<@endif@>
Material mat = getMaterial();
BITFIELD matKey = getMaterialKey(mat);
Material mats[NUM_LAYERS];
BITFIELD matKeys[NUM_LAYERS];
for (int layer = 0; layer < NUM_LAYERS; layer++) {
Material mat = getMaterial(layer);
mats[layer] = mat;
matKeys[layer] = getMaterialKey(mat);
}
<@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@>
<@if not HIFI_USE_TRIPLANAR@>
<@if not HIFI_USE_MTOON@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex)$>
<@else@>
<$fetchMToonMaterialTextures(matKey, _texCoords, albedoTex)$>
<$fetchMToonMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex)$>
<@endif@>
<@else@>
vec3 triplanarScale = triplanarParams.scale.xyz;
<@if not HIFI_USE_MTOON@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex)$>
<@else@>
<$fetchMToonMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex)$>
<$fetchMToonMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex)$>
<@endif@>
<@endif@>
float cutoff = getMaterialOpacityCutoff(mat);
float cutoff = getMaterialOpacityCutoff(mats[0]);
<@if HIFI_USE_TRANSLUCENT@>
float opacity = getMaterialOpacity(mat);
float opacity = getMaterialOpacity(mats[0]);
<@if not HIFI_USE_MTOON@>
opacity *= _color.a;
<@endif@>
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardInvisible(opacity)$>;
<@else@>
float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardTransparent(opacity)$>;
<@endif@>
<@if not HIFI_USE_SHADOW@>
vec3 albedo = getMaterialAlbedo(mat);
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
vec3 albedo = getMaterialAlbedo(mats[0]);
<$evalMaterialAlbedo(albedoTex, albedo, matKeys[0], albedo)$>;
<@if not HIFI_USE_MTOON@>
albedo *= _color.rgb;
<@endif@>
@ -215,30 +229,30 @@ void main(void) {
albedo * isUnlitEnabled());
<@endif@>
<@elif HIFI_USE_MTOON@>
vec3 uvScrollSpeed = getMaterialUVScrollSpeed(mat);
float time = getMaterialTime(mat);
vec3 uvScrollSpeed = getMaterialUVScrollSpeed(mats[0]);
float time = getMaterialTime(mats[0]); // time is only stored in the first material
<@if HIFI_USE_NORMALMAP@>
<$fetchMToonMaterialTextures(matKey, _texCoords, albedoTex, normalTex, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
<$fetchMToonMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, normalTex, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
<@else@>
<$fetchMToonMaterialTextures(matKey, _texCoords, albedoTex, _SCRIBE_NULL, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
<$fetchMToonMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, _SCRIBE_NULL, shadeTex, emissiveTex, shadingShiftTex, rimTex, uvScrollSpeed, time)$>
<@endif@>
float cutoff = getMaterialOpacityCutoff(mat);
float cutoff = getMaterialOpacityCutoff(mats[0]);
<@if HIFI_USE_TRANSLUCENT@>
float opacity = getMaterialOpacity(mat);
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
float opacity = getMaterialOpacity(mats[0]);
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardInvisible(opacity)$>;
<@else@>
float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardTransparent(opacity)$>;
<@endif@>
vec3 albedo = getMaterialAlbedo(mat);
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
vec3 albedo = getMaterialAlbedo(mats[0]);
<$evalMaterialAlbedo(albedoTex, albedo, matKeys[0], albedo)$>;
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 emissive = getMaterialEmissive(mats[0]);
<$evalMaterialEmissive(emissiveTex, emissive, matKeys[0], emissive)$>;
<@if HIFI_USE_NORMALMAP@>
vec3 fragNormalWS;
@ -252,11 +266,11 @@ void main(void) {
<@endif@>
fragNormalWS = evalFrontOrBackFaceNormal(normalize(fragNormalWS));
vec3 shade = getMaterialShade(mat);
<$evalMaterialShade(shadeTex, shade, matKey, shade)$>;
vec3 shade = getMaterialShade(mats[0]);
<$evalMaterialShade(shadeTex, shade, matKeys[0], shade)$>;
float shadingShift = getMaterialShadingShift(mat);
<$evalMaterialShadingShift(shadingShiftTex, shadingShift, matKey, shadingShift)$>;
float shadingShift = getMaterialShadingShift(mats[0]);
<$evalMaterialShadingShift(shadingShiftTex, shadingShift, matKeys[0], shadingShift)$>;
TransformCamera cam = getTransformCamera();
float metallic = DEFAULT_METALLIC;
@ -265,8 +279,8 @@ void main(void) {
vec4 color = vec4(evalGlobalLightingAlphaBlendedMToon(
cam._viewInverse, 1.0, _positionES.xyz, fragNormalWS,
albedo, fresnel, metallic, emissive, DEFAULT_ROUGHNESS, opacity,
shade, shadingShift, getMaterialShadingToony(mat), getMaterialMatcap(mat), getMaterialParametricRim(mat),
getMaterialParametricRimFresnelPower(mat), getMaterialParametricRimLift(mat), rimTex, getMaterialRimLightingMix(mat), matKey), opacity);
shade, shadingShift, getMaterialShadingToony(mats[0]), getMaterialMatcap(mats[0]), getMaterialParametricRim(mats[0]),
getMaterialParametricRimFresnelPower(mats[0]), getMaterialParametricRimLift(mats[0]), rimTex, getMaterialRimLightingMix(mats[0]), matKeys[0]), opacity);
<@if HIFI_USE_FORWARD@>
_fragColor0 = isUnlitEnabled() * vec4(color.rgb
@ -300,73 +314,73 @@ void main(void) {
<@if not HIFI_USE_TRIPLANAR@>
<@if not HIFI_USE_LIGHTMAP@>
<@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@elif HIFI_USE_NORMALMAP@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@elif HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@else@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@endif@>
<@else@>
<@if HIFI_USE_NORMALMAP@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@else@>
<$fetchMaterialTextures(matKey, _texCoords, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTextures(0, matKeys[0], _texCoords[0], albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@endif@>
<@endif@>
<@else@>
vec3 triplanarScale = triplanarParams.scale.xyz;
<@if not HIFI_USE_LIGHTMAP@>
<@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@elif HIFI_USE_NORMALMAP@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@elif HIFI_USE_TRANSLUCENT@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL, occlusionTex)$>
<@else@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex, occlusionTex)$>
<@endif@>
<@else@>
<@if HIFI_USE_NORMALMAP@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@else@>
<$fetchMaterialTexturesTriplanar(matKey, _positionMS, _normalMS, _texCoord01.zw, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<$fetchMaterialTexturesTriplanar(matKeys, _positionMS, _normalMS, _texCoord01, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, _SCRIBE_NULL, _SCRIBE_NULL, _SCRIBE_NULL, lightmap)$>
<@endif@>
<@endif@>
<@endif@>
float cutoff = getMaterialOpacityCutoff(mat);
float cutoff = getMaterialOpacityCutoff(mats[0]);
<@if HIFI_USE_TRANSLUCENT@>
float opacity = getMaterialOpacity(mat) * _color.a;
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
float opacity = getMaterialOpacity(mats[0]) * _color.a;
<$evalMaterialOpacity(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardInvisible(opacity)$>;
<@else@>
float opacity = 1.0;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKey, opacity)$>;
<$evalMaterialOpacityMask(albedoTex.a, cutoff, opacity, matKeys[0], opacity)$>;
<$discardTransparent(opacity)$>;
<@endif@>
vec3 albedo = getMaterialAlbedo(mat);
<$evalMaterialAlbedo(albedoTex, albedo, matKey, albedo)$>;
vec3 albedo = getMaterialAlbedo(mats[0]);
<$evalMaterialAlbedo(albedoTex, albedo, matKeys[0], albedo)$>;
albedo *= _color.rgb;
float roughness = getMaterialRoughness(mat);
<$evalMaterialRoughness(roughnessTex, roughness, matKey, roughness)$>;
float roughness = getMaterialRoughness(mats[0]);
<$evalMaterialRoughness(roughnessTex, roughness, matKeys[0], roughness)$>;
float metallic = getMaterialMetallic(mat);
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
float metallic = getMaterialMetallic(mats[0]);
<$evalMaterialMetallic(metallicTex, metallic, matKeys[0], metallic)$>;
<@if not HIFI_USE_LIGHTMAP@>
vec3 emissive = getMaterialEmissive(mat);
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
vec3 emissive = getMaterialEmissive(mats[0]);
<$evalMaterialEmissive(emissiveTex, emissive, matKeys[0], emissive)$>;
float occlusion = DEFAULT_OCCLUSION;
<$evalMaterialOcclusion(occlusionTex, matKey, occlusion)$>;
<$evalMaterialOcclusion(occlusionTex, matKeys[0], occlusion)$>;
<@if not HIFI_USE_TRANSLUCENT@>
float scattering = getMaterialScattering(mat);
<$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>;
float scattering = getMaterialScattering(mats[0]);
<$evalMaterialScattering(scatteringTex, scattering, matKeys[0], scattering)$>;
<@endif@>
<@endif@>
@ -456,7 +470,7 @@ void main(void) {
packDeferredFragmentLightmap(
_prevPositionCS,
fragNormalWS,
evalOpaqueFinalAlpha(getMaterialOpacity(mat), opacity),
evalOpaqueFinalAlpha(getMaterialOpacity(mats[0]), opacity),
albedo,
roughness,
metallic,

View file

@ -36,7 +36,7 @@
<@endif@>
layout(location=RENDER_UTILS_ATTR_POSITION_WS) out vec4 _positionWS;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01[NUM_LAYERS];
<@if not HIFI_USE_SHADOW@>
layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES;
layout(location=RENDER_UTILS_ATTR_NORMAL_WS) out vec3 _normalWS;
@ -84,6 +84,10 @@ void main(void) {
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();
<@if not HIFI_USE_SHADOW@>
<@if not HIFI_USE_MTOON@>
_color = color_sRGBAToLinear(inColor);
<@endif@>
<$transformModelToWorldEyeClipPosAndPrevClipPos(cam, obj, positionMS, _positionWS, _positionES, gl_Position, _prevPositionCS)$>
<$transformModelToWorldDir(obj, normalMS, _normalWS)$>
<@else@>
@ -97,24 +101,21 @@ void main(void) {
<@endif@>
<@endif@>
<@if HIFI_USE_SHADOW@>
Material mat = getMaterial();
BITFIELD matKey = getMaterialKey(mat);
// If we have an opacity mask than we need the first tex coord
if ((matKey & OPACITY_MASK_MAP_BIT) != 0) {
TexMapArray texMapArray = getTexMapArray();
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$>
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$>
} else {
_texCoord01 = vec4(0.0);
}
<@else@>
<@if not HIFI_USE_MTOON@>
_color = color_sRGBAToLinear(inColor);
<@endif@>
TexMapArray texMapArray = getTexMapArray();
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01.xy)$>
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01.zw)$>
<@endif@>
for (int layer = 0; layer < NUM_LAYERS; layer++) {
_texCoord01[layer] = vec4(0.0);
<@if HIFI_USE_SHADOW@>
Material mat = getMaterial(layer);
BITFIELD matKey = getMaterialKey(mat);
// If we have an opacity mask than we need the first tex coord
if ((matKey & OPACITY_MASK_MAP_BIT) != 0) {
TexMapArray texMapArray = getTexMapArray(layer);
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01[layer].xy)$>
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01[layer].zw)$>
}
<@else@>
TexMapArray texMapArray = getTexMapArray(layer);
<$evalTexMapArrayTexcoord0(texMapArray, inTexCoord0, _positionWS, _texCoord01[layer].xy)$>
<$evalTexMapArrayTexcoord1(texMapArray, inTexCoord1, _positionWS, _texCoord01[layer].zw)$>
<@endif@>
}
}

View file

@ -19,40 +19,43 @@
#define RENDER_UTILS_ENABLE_AMBIENT_FRESNEL_LUT 1
// Binding slots
#define RENDER_UTILS_ATTR_TEXCOORD01 0
#define RENDER_UTILS_ATTR_COLOR 1
#define RENDER_UTILS_ATTR_TEXCOORD01 0 // one per layer, so takes slots 0 - 2
#define RENDER_UTILS_ATTR_COLOR 3
// World space
#define RENDER_UTILS_ATTR_POSITION_WS 2
#define RENDER_UTILS_ATTR_NORMAL_WS 3
#define RENDER_UTILS_ATTR_TANGENT_WS 4
#define RENDER_UTILS_ATTR_POSITION_WS 4
#define RENDER_UTILS_ATTR_NORMAL_WS 5
#define RENDER_UTILS_ATTR_TANGENT_WS 6
// Model space
#define RENDER_UTILS_ATTR_POSITION_MS 5
#define RENDER_UTILS_ATTR_NORMAL_MS 6
#define RENDER_UTILS_ATTR_POSITION_MS 7
#define RENDER_UTILS_ATTR_NORMAL_MS 8
// Eye space
#define RENDER_UTILS_ATTR_POSITION_ES 7
// don't conflict with GPU_ATTR_V2F_STEREO_SIDE in the GPU shader constants
#define RENDER_UTILS_ATTR_DO_NOT_USE 8
#define RENDER_UTILS_ATTR_POSITION_ES 9
// Clip space
#define RENDER_UTILS_ATTR_PREV_POSITION_CS 9
#define RENDER_UTILS_ATTR_PREV_POSITION_CS 10
// Fade
#define RENDER_UTILS_ATTR_FADE1 10
#define RENDER_UTILS_ATTR_FADE2 11
#define RENDER_UTILS_ATTR_FADE3 12
#define RENDER_UTILS_ATTR_FADE1 11
#define RENDER_UTILS_ATTR_FADE2 12
#define RENDER_UTILS_ATTR_FADE3 13
// don't conflict with GPU_ATTR_V2F_STEREO_SIDE in the GPU shader constants
#define RENDER_UTILS_ATTR_DO_NOT_USE 14
// don't conflict with GPU_ATTR_V2F_DRAW_CALL_INFO in the GPU shader constants
#define RENDER_UTILS_ATTR_DO_NOT_USE2 13
#define RENDER_UTILS_ATTR_DO_NOT_USE2 15
// 0 - 7 are in graphics/ShaderConstants.h
#define RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM 7 // can overlap with GRAPHICS_BUFFER_SKYBOX_PARAMS
#define RENDER_UTILS_BUFFER_LIGHT_MODEL 8
#define RENDER_UTILS_BUFFER_LIGHT_INDEX 9 // only used in deferred pass
#define RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM 0
#define RENDER_UTILS_BUFFER_LIGHT_MODEL 3
#define RENDER_UTILS_BUFFER_AMBIENT_LIGHT 6
#define RENDER_UTILS_BUFFER_LIGHT_INDEX 7
// Fading
#define RENDER_UTILS_BUFFER_FADE_PARAMS 9 // this can overlap RENDER_UTILS_BUFFER_LIGHT_INDEX because they aren't used at the same time
#define RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS 10
#define RENDER_UTILS_TEXTURE_FADE_MASK 12
// Deferred lighting resolution
#define RENDER_UTILS_TEXTURE_DEFERRRED_COLOR 0
@ -64,25 +67,19 @@
#define RENDER_UTILS_TEXTURE_DEFERRED_CURVATURE 6
#define RENDER_UTILS_TEXTURE_DEFERRED_DIFFUSED_CURVATURE 7
#define RENDER_UTILS_TEXTURE_DEFERRED_LIGHTING 10
#define RENDER_UTILS_TEXTURE_SKYBOX 11
#define RENDER_UTILS_TEXTURE_SKYBOX 13
#define RENDER_UTILS_TEXTURE_AMBIENT_FRESNEL 14
#define RENDER_UTILS_BUFFER_SHADOW_PARAMS 2
#define RENDER_UTILS_BUFFER_SHADOW_PARAMS 0
#define RENDER_UTILS_TEXTURE_SHADOW 12
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID 10
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID 11
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT 12
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID 11
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_GRID 12
#define RENDER_UTILS_BUFFER_LIGHT_CLUSTER_CONTENT 13
// Haze
#define RENDER_UTILS_TEXTURE_HAZE_COLOR 0
#define RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH 1
// Fading
#define RENDER_UTILS_BUFFER_FADE_PARAMS 8
#define RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS 9
#define RENDER_UTILS_TEXTURE_FADE_MASK 10
// Highlighting
#define RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS 2
#define RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH 0
@ -135,8 +132,8 @@
#define RENDER_UTILS_UNIFORM_TEXT_COLOR 0
#define RENDER_UTILS_UNIFORM_TEXT_OUTLINE 1
// Debugging
#define RENDER_UTILS_BUFFER_DEBUG_SKYBOX 5
// Debugging
#define RENDER_UTILS_BUFFER_DEBUG_SKYBOX 7
#define RENDER_UTILS_DEBUG_TEXTURE0 11
#define RENDER_UTILS_BUFFER_DEBUG_DEFERRED_PARAMS 1
@ -149,7 +146,6 @@ namespace buffer {
enum Buffer {
DeferredFrameTransform = RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM,
LightModel = RENDER_UTILS_BUFFER_LIGHT_MODEL,
AmbientLight = RENDER_UTILS_BUFFER_AMBIENT_LIGHT,
FadeParameters = RENDER_UTILS_BUFFER_FADE_PARAMS,
FadeObjectParameters = RENDER_UTILS_BUFFER_FADE_OBJECT_PARAMS,
LightClusterFrustumGrid = RENDER_UTILS_BUFFER_LIGHT_CLUSTER_FRUSTUM_GRID,
@ -189,7 +185,6 @@ enum Texture {
SsscProfile = RENDER_UTILS_TEXTURE_SSSC_PROFILE,
FadeMask = RENDER_UTILS_TEXTURE_FADE_MASK,
Skybox = RENDER_UTILS_TEXTURE_SKYBOX,
HazeColor = RENDER_UTILS_TEXTURE_HAZE_COLOR,
HazeLinearDepth = RENDER_UTILS_TEXTURE_HAZE_LINEAR_DEPTH,
Shadow = RENDER_UTILS_TEXTURE_SHADOW,
TaaHistory = RENDER_UTILS_TEXTURE_TAA_HISTORY,

View file

@ -142,6 +142,17 @@ const ShapePipelinePointer ShapePlumber::pickPipeline(RenderArgs* args, const Ke
} else {
qCDebug(renderlogging) << "ShapePlumber::Couldn't find a custom pipeline factory for " << key.getCustom() << " key is: " << key;
}
} else {
auto pipelineOperatorItr = _pipelineOperatorMap.find(key);
if (pipelineOperatorItr != _pipelineOperatorMap.end()) {
// We have a deferred pipeline operator - lets call it to populate the pipelines
pipelineOperatorItr->second();
// We're done with this operator for good.
_pipelineOperatorMap.erase(pipelineOperatorItr);
return pickPipeline(args, key);
}
}
_missingKeys.insert(key);

View file

@ -41,6 +41,9 @@ public:
CULL_FACE_FRONT,
MTOON,
TRIPLANAR,
LAYERS2, // if neither of these are set, we just have 1 layer
LAYERS3,
SPLATMAP,
OWN_PIPELINE,
INVALID,
@ -113,6 +116,26 @@ public:
return (*this);
}
Builder& withLayers(uint8_t numLayers) {
switch (numLayers) {
case 3:
_flags.set(LAYERS3);
_flags.reset(LAYERS2);
break;
case 2:
_flags.reset(LAYERS3);
_flags.set(LAYERS2);
break;
default:
_flags.reset(LAYERS3);
_flags.reset(LAYERS2);
break;
}
return (*this);
}
Builder& withSplatMap() { _flags.set(SPLATMAP); return (*this); }
Builder& withOwnPipeline() { _flags.set(OWN_PIPELINE); return (*this); }
Builder& invalidate() { _flags.set(INVALID); return (*this); }
@ -132,7 +155,7 @@ public:
Filter(Flags flags, Flags mask) : _flags{flags}, _mask{mask} {}
Filter(const ShapeKey& key) : _flags{ key._flags } { _mask.set(); }
// Build a standard filter (will always exclude OWN_PIPELINE, INVALID)
// Build a standard filter (will always exclude OWN_PIPELINE and INVALID)
class Builder {
public:
Builder();
@ -197,6 +220,29 @@ public:
Builder& withTriplanar() { _flags.set(TRIPLANAR); _mask.set(TRIPLANAR); return (*this); }
Builder& withoutTriplanar() { _flags.reset(TRIPLANAR); _mask.set(TRIPLANAR); return (*this); }
Builder& withLayers(uint8_t numLayers) {
switch (numLayers) {
case 3:
_flags.set(LAYERS3);
_flags.reset(LAYERS2);
break;
case 2:
_flags.reset(LAYERS3);
_flags.set(LAYERS2);
break;
default:
_flags.reset(LAYERS3);
_flags.reset(LAYERS2);
break;
}
_mask.set(LAYERS3);
_mask.set(LAYERS2);
return (*this);
}
Builder& withSplatMap() { _flags.set(SPLATMAP); _mask.set(SPLATMAP); return (*this); }
Builder& withoutSplatMap() { _flags.reset(SPLATMAP); _mask.set(SPLATMAP); return (*this); }
Builder& withCustom(uint8_t custom) { _flags &= (~CUSTOM_MASK); _flags |= (custom << CUSTOM_0); _mask |= (CUSTOM_MASK); return (*this); }
Builder& withoutCustom() { _flags &= (~CUSTOM_MASK); _mask |= (CUSTOM_MASK); return (*this); }
@ -228,6 +274,8 @@ public:
bool isFaded() const { return _flags[FADE]; }
bool isMToon() const { return _flags[MTOON]; }
bool isTriplanar() const { return _flags[TRIPLANAR]; }
uint8_t numLayers() const { return 1 + (uint8_t)_flags[LAYERS2] + 2 * (uint8_t)_flags[LAYERS3]; }
bool isSplatMap() const { return _flags[SPLATMAP]; }
bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; }
bool isValid() const { return !_flags[INVALID]; }
@ -269,6 +317,8 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
<< "isFaded:" << key.isFaded()
<< "isMToon:" << key.isMToon()
<< "isTriplanar:" << key.isTriplanar()
<< "numLayers:" << key.numLayers()
<< "isSplatMap:" << key.isSplatMap()
<< "]";
}
} else {
@ -350,6 +400,8 @@ public:
using Pipeline = ShapePipeline;
using PipelinePointer = ShapePipelinePointer;
using PipelineMap = std::unordered_map<ShapeKey, PipelinePointer, ShapeKey::Hash, ShapeKey::KeyEqual>;
using PipelineOperator = std::function<void(void)>;
using PipelineOperatorMap = std::unordered_map<ShapeKey, PipelineOperator, ShapeKey::Hash, ShapeKey::KeyEqual>;
using Slot = int32_t;
using Locations = Pipeline::Locations;
using LocationsPointer = Pipeline::LocationsPointer;
@ -361,11 +413,14 @@ public:
void addPipeline(const Filter& filter, const gpu::ShaderPointer& program, const gpu::StatePointer& state,
BatchSetter batchSetter = nullptr, ItemSetter itemSetter = nullptr);
void addPipelineOperator(const Key& key, const PipelineOperator& pipelineOperator) { _pipelineOperatorMap[key] = pipelineOperator; }
const PipelinePointer pickPipeline(RenderArgs* args, const Key& key) const;
protected:
void addPipelineHelper(const Filter& filter, Key key, int bit, const PipelinePointer& pipeline) const;
mutable PipelineMap _pipelineMap;
mutable PipelineOperatorMap _pipelineOperatorMap;
private:
mutable std::unordered_set<Key, Key::Hash, Key::KeyEqual> _missingKeys;

View file

@ -53,7 +53,7 @@ const std::vector<Dialect>& allDialects() {
const Dialect DEFAULT_DIALECT = Dialect::glsl450;
const std::vector<Dialect> & allDialects() {
static const std::vector<Dialect> ALL_DIALECTS{ { Dialect::glsl450, Dialect::glsl410 } };
static const std::vector<Dialect> ALL_DIALECTS{ { Dialect::glsl450 } };
return ALL_DIALECTS;
}
#endif
@ -70,11 +70,10 @@ const std::string& dialectPath(Dialect dialect) {
switch (dialect) {
#if defined(USE_GLES)
case Dialect::glsl310es: return e310esPath;
#else
#if !defined(Q_OS_MAC)
case Dialect::glsl450: return e450Path;
#endif
#elif defined(Q_OS_MAC)
case Dialect::glsl410: return e410Path;
#else
case Dialect::glsl450: return e450Path;
#endif
default: break;
}
@ -106,7 +105,7 @@ DialectVariantSource loadDialectVariantSource(const std::string& basePath) {
DialectVariantSource result;
result.scribe = loadResource(basePath + "scribe");
result.spirv = loadSpirvResource(basePath + "spirv");
result.glsl = loadResource(basePath + "glsl");
//result.glsl = loadResource(basePath + "glsl");
String reflectionJson = loadResource(basePath + "json");
result.reflection.parse(reflectionJson);
return result;
@ -227,10 +226,10 @@ String Source::getSource(Dialect dialect, Variant variant) const {
// which breaks android rendering
return variantSource.scribe;
#else
if (variantSource.glsl.empty()) {
//if (variantSource.glsl.empty()) {
return variantSource.scribe;
}
return variantSource.glsl;
//}
//return variantSource.glsl;
#endif
}

View file

@ -121,7 +121,7 @@ struct DialectVariantSource {
// Optimized SPIRV version of the shader
Binary spirv;
// Regenerated GLSL from the optimized SPIRV
String glsl;
//String glsl;
// Shader reflection from the optimized SPIRV
Reflection reflection;

View file

@ -387,6 +387,7 @@ function makeNameTag(uuid) {
.add("dimensions", scaledDimensions)
.add("parentID", parentID)
.add("localPosition", localPosition)
.add("grab", { grabbable: false })
.create(CLEAR_ENTITY_EDIT_PROPS);
Script.setTimeout(function () {

View file

@ -202,19 +202,13 @@ function Grabber() {
this.liftKey = false; // SHIFT
this.rotateKey = false; // CONTROL
this.mouseRayOverlays = Picks.createPick(PickType.Ray, {
joint: "Mouse",
filter: Picks.PICK_OVERLAYS | Picks.PICK_INCLUDE_NONCOLLIDABLE,
enabled: true
});
var tabletItems = getMainTabletIDs();
if (tabletItems.length > 0) {
Picks.setIncludeItems(this.mouseRayOverlays, tabletItems);
}
var renderStates = [{name: "grabbed", end: beacon}];
this.mouseRayEntities = Pointers.createRayPointer({
joint: "Mouse",
filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE,
filter: Picks.PICK_DOMAIN_ENTITIES |
Picks.PICK_AVATAR_ENTITIES |
Picks.PICK_LOCAL_ENTITIES |
Picks.PICK_INCLUDE_NONCOLLIDABLE,
faceAvatar: true,
scaleWithParent: true,
enabled: true,
@ -224,10 +218,8 @@ function Grabber() {
Grabber.prototype.setPicksAndPointersEnabled = function(enabled) {
if (enabled) {
Picks.enablePick(this.mouseRayOverlays);
Pointers.enablePointer(this.mouseRayEntities);
} else {
Picks.disablePick(this.mouseRayOverlays);
Pointers.disablePointer(this.mouseRayEntities);
}
}
@ -283,11 +275,6 @@ Grabber.prototype.pressEvent = function(event) {
return;
}
var overlayResult = Picks.getPrevPickResult(this.mouseRayOverlays);
if (overlayResult.type != Picks.INTERSECTED_NONE) {
return;
}
var pickResults = Pointers.getPrevPickResult(this.mouseRayEntities);
if (pickResults.type == Picks.INTERSECTED_NONE) {
Pointers.setRenderState(this.mouseRayEntities, "");
@ -494,7 +481,6 @@ Grabber.prototype.keyPressEvent = function(event) {
Grabber.prototype.cleanup = function() {
Pointers.removePointer(this.mouseRayEntities);
Picks.removePick(this.mouseRayOverlays);
if (this.grabID) {
MyAvatar.releaseGrab(this.grabID);
this.grabID = null;

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=192
compiler.runtime=dynamic
compiler.runtime_type=Debug

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=192
compiler.runtime=dynamic
compiler.runtime_type=Debug

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=192
compiler.runtime=dynamic
compiler.runtime_type=Release

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=192
compiler.runtime=dynamic
compiler.runtime_type=Release

View file

@ -4,6 +4,7 @@ os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.cppstd=17
compiler.version=16
build_type=RelWithDebInfo
# Build fails on Windows with C++17

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=194
compiler.runtime=dynamic
compiler.runtime_type=Debug

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=194
compiler.runtime=dynamic
compiler.runtime_type=Debug

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=194
compiler.runtime=dynamic
compiler.runtime_type=Release

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=194
compiler.runtime=dynamic
compiler.runtime_type=Release

View file

@ -2,6 +2,7 @@
os=Windows
arch=x86_64
compiler=msvc
compiler.cppstd=17
compiler.version=194
compiler.runtime=dynamic
compiler.runtime_type=RelWithDebInfo

View file

@ -93,6 +93,63 @@
</v-app>
<div id="main">
<!--
Ripped out of our own website using PageRip and then manually adjusted and simplified.
https://chromewebstore.google.com/detail/pagerip-html-+-css-extrac/bkahkocegdkgicmmfpkoeipjmjaeohfn
-->
<style>
.style-0 {
max-width: 96%;
margin: 20px auto;
background: #27343B none repeat scroll 0% 0% / auto padding-box border-box;
clear: both;
padding: 12px;
line-height: 24px;
margin-bottom: 20px;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
.style-1 {
padding: 6px 12px;
background: rgb(140, 141, 192) none repeat scroll 0% 0% / auto padding-box border-box;
font-size: 16px;
line-height: 16px;
margin: -12px -12px 12px;
font-weight: 700;
display: block;
color: rgb(255, 255, 255);
font-style: normal;
font-variant: normal;
font-size-adjust: none;
font-kerning: auto;
font-optical-sizing: auto;
font-feature-settings: normal;
font-variation-settings: normal;
font-stretch: 100%;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
.style-2 {
padding: 5px;
font-size: 15.2px;
margin-bottom: 0px;
line-height: 24px;
margin: 0px;
box-sizing: border-box;
}
.style-3 {
overflow-wrap: anywhere;
cursor: pointer;
box-sizing: border-box;
}
</style>
<div class="style-0">
<p class="style-1">Note</p>
<p class="style-2">Help us hire a team member! <a class="style-3" href="https://overte.org/donate.html">Donate ♥</a> or <a class="style-3" href="https://overte.org/index.html#help-us-hire-a-team-member">Learn more</a>.</p>
</div>
<h1 class="page-title"><?js= title ?></h1>
<?js= content ?>