From 336181a14794fef8cad57736aae7767d29e1c77f Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Mon, 16 Sep 2024 22:37:54 -0700 Subject: [PATCH] support PBR materials on polyvox, and add triplanar projection to material entities --- .../src/RenderableEntityItem.cpp | 17 +- .../src/RenderableMaterialEntityItem.cpp | 8 +- .../src/RenderablePolyVoxEntityItem.cpp | 107 +++++++- .../src/RenderablePolyVoxEntityItem.h | 6 +- .../entities/src/EntityItemProperties.cpp.in | 1 + .../entities/src/EntityItemPropertiesDocs.cpp | 10 +- .../entities/src/MaterialEntityItem.cpp.in | 2 +- libraries/graphics/src/graphics/Material.slh | 4 +- .../src/graphics/MaterialTextures.slh | 244 ++++++++++++++++++ .../graphics/src/graphics/ShaderConstants.h | 4 +- .../render-utils/src/MeshPartPayload.cpp | 4 + .../render-utils/src/RenderPipelines.cpp | 191 +++++++++++++- libraries/render-utils/src/model.slf | 77 ++++-- libraries/render-utils/src/model.slv | 7 + .../render-utils/src/render-utils/model.slp | 2 +- libraries/render/src/render/ShapePipeline.h | 8 + libraries/shared/src/MaterialMappingMode.cpp | 3 +- libraries/shared/src/MaterialMappingMode.h | 1 + scripts/system/create/edit.js | 4 + .../html/js/entityProperties.js | 2 +- 20 files changed, 654 insertions(+), 48 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 7ca3a5c341..a30884c870 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -626,7 +626,7 @@ void EntityRenderer::removeMaterial(graphics::MaterialPointer material, const st graphics::MaterialPointer EntityRenderer::getTopMaterial() { std::lock_guard lock(_materialsLock); auto materials = _materials.find("0"); - if (materials != _materials.end()) { + if (materials != _materials.end() && materials->second.size() > 0) { return materials->second.top().material; } return nullptr; @@ -637,7 +637,7 @@ EntityRenderer::Pipeline EntityRenderer::getPipelineType(const graphics::MultiMa return Pipeline::MIRROR; } - if (materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) { + if (materials.size() > 0 && materials.top().material && materials.top().material->isProcedural() && materials.top().material->isReady()) { return Pipeline::PROCEDURAL; } @@ -670,7 +670,7 @@ bool EntityRenderer::needsRenderUpdateFromMaterials() const { return true; } - if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { auto procedural = std::static_pointer_cast(materials->second.top().material); if (procedural->isFading()) { return true; @@ -696,7 +696,7 @@ void EntityRenderer::updateMaterials(bool baseMaterialChanged) { } bool requestUpdate = false; - if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { auto procedural = std::static_pointer_cast(materials->second.top().material); if (procedural->isFading()) { procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f); @@ -725,7 +725,7 @@ bool EntityRenderer::materialsTransparent() const { } } - if (materials->second.top().material) { + if (materials->second.size() > 0 && materials->second.top().material) { if (materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { auto procedural = std::static_pointer_cast(materials->second.top().material); if (procedural->isFading()) { @@ -752,7 +752,7 @@ Item::Bound EntityRenderer::getMaterialBound(RenderArgs* args) { } } - if (materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { + if (materials->second.size() > 0 && materials->second.top().material && materials->second.top().material->isProcedural() && materials->second.top().material->isReady()) { auto procedural = std::static_pointer_cast(materials->second.top().material); if (procedural->hasVertexShader() && procedural->hasBoundOperator()) { return procedural->getBound(args); @@ -825,6 +825,11 @@ void EntityRenderer::updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& build } else { builder.withMToon(); } + + if (materials->second.size() > 0 && materials->second.top().material && + (MaterialMappingMode)materials->second.top().material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) { + builder.withTriplanar(); + } } else if (pipelineType == Pipeline::PROCEDURAL) { builder.withOwnPipeline(); } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 21e6cfece9..1d2b771d4e 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -57,7 +57,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo _materialMappingPos = mappingPos; _materialMappingScale = mappingScale; _materialMappingRot = mappingRot; - transformChanged |= _materialMappingMode == MaterialMappingMode::UV; + transformChanged |= (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR); } } { @@ -264,6 +264,10 @@ ShapeKey MaterialEntityRenderer::getShapeKey() { builder.withTangents(); } + if (drawMaterial && (MaterialMappingMode)drawMaterial->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) { + builder.withTriplanar(); + } + if (drawMaterial && drawMaterial->isMToon()) { builder.withMToon(); } else { @@ -409,7 +413,7 @@ void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID, const QStr void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material) { Transform textureTransform; - if (_materialMappingMode == MaterialMappingMode::UV) { + if (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR) { textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index ef0d8d4449..d1cd4dc473 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -29,12 +29,14 @@ #include #include #include +#include #include "entities-renderer/ShaderConstants.h" #include #include "EntityTreeRenderer.h" +#include "RenderPipelines.h" #include @@ -1707,9 +1709,11 @@ using namespace render; using namespace render::entities; static uint8_t CUSTOM_PIPELINE_NUMBER; +static const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA }; // forward, shadow, fade, wireframe static std::map, ShapePipelinePointer> _pipelines; static gpu::Stream::FormatPointer _vertexFormat; +static gpu::Stream::FormatPointer _vertexColorFormat; ShapePipelinePointer shapePipelineFactory(const ShapePlumber& plumber, const ShapeKey& key, RenderArgs* args) { if (_pipelines.empty()) { @@ -1765,18 +1769,48 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : _vertexFormat = std::make_shared(); _vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); _vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12); + + _vertexColorFormat = std::make_shared(); + _vertexColorFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); + _vertexColorFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12); + _vertexColorFormat->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); }); _params = std::make_shared(sizeof(glm::vec4), nullptr); } ShapeKey PolyVoxEntityRenderer::getShapeKey() { - auto builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER); - if (_primitiveMode == PrimitiveMode::LINES) { - builder.withWireframe(); + bool hasMaterials = false; + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + auto materialsItr = _materials.find("0"); + hasMaterials = (materialsItr != _materials.end()); + if (hasMaterials) { + materials = materialsItr->second; + } + } + ShapeKey::Builder builder; + if (!hasMaterials) { + builder = ShapeKey::Builder().withCustom(CUSTOM_PIPELINE_NUMBER); + if (_primitiveMode == PrimitiveMode::LINES) { + builder.withWireframe(); + } + } else { + updateShapeKeyBuilderFromMaterials(builder); + Pipeline pipelineType = getPipelineType(materials); + if (pipelineType == Pipeline::MATERIAL) { + builder.withTriplanar(); + } + // FIXME: We don't currently generate tangents for PolyVox, so they don't support normal maps + builder.withoutTangents(); } return builder.build(); } +bool PolyVoxEntityRenderer::needsRenderUpdate() const { + return needsRenderUpdateFromMaterials() || Parent::needsRenderUpdate(); +} + bool PolyVoxEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { if (entity->voxelToLocalMatrix() != _lastVoxelToLocalMatrix) { @@ -1834,6 +1868,17 @@ void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoi texture = DependencyManager::get()->getTexture(textureURL); } } + + updateMaterials(); +} + +bool PolyVoxEntityRenderer::isTransparent() const { + // TODO: We don't currently support transparent PolyVox (unless they are using the material path) + return /*Parent::isTransparent() || */materialsTransparent(); +} + +Item::Bound PolyVoxEntityRenderer::getBound(RenderArgs* args) { + return Parent::getMaterialBound(args); } void PolyVoxEntityRenderer::doRender(RenderArgs* args) { @@ -1853,20 +1898,60 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { _prevRenderTransform = transform; } - batch.setInputFormat(_vertexFormat); batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0, sizeof(PolyVox::PositionMaterialNormal)); batch.setIndexBuffer(gpu::UINT32, _mesh->getIndexBuffer()._buffer, 0); - for (size_t i = 0; i < _xyzTextures.size(); ++i) { - const auto& texture = _xyzTextures[i]; - if (texture) { - batch.setResourceTexture((uint32_t)i, texture->getGPUTexture()); - } else { - batch.setResourceTexture((uint32_t)i, DependencyManager::get()->getWhiteTexture()); + bool hasMaterials = false; + graphics::MultiMaterial materials; + { + std::lock_guard lock(_materialsLock); + auto materialsItr = _materials.find("0"); + hasMaterials = (materialsItr != _materials.end()); + if (hasMaterials) { + materials = materialsItr->second; } } + if (!hasMaterials) { + for (size_t i = 0; i < _xyzTextures.size(); ++i) { + const auto& texture = _xyzTextures[i]; + if (texture) { + batch.setResourceTexture((uint32_t)i, texture->getGPUTexture()); + } else { + batch.setResourceTexture((uint32_t)i, DependencyManager::get()->getWhiteTexture()); + } + } + batch.setInputFormat(_vertexFormat); + batch.setUniformBuffer(0, _params); + } else { + glm::vec4 outColor = materials.getColor(); + + if (outColor.a == 0.0f) { + return; + } + + Pipeline pipelineType = getPipelineType(materials); + if (pipelineType == Pipeline::PROCEDURAL) { + auto procedural = std::static_pointer_cast(materials.top().material); + outColor = procedural->getColor(outColor); + outColor.a *= procedural->isFading() ? Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) : 1.0f; + withReadLock([&] { + procedural->prepare(batch, transform.getTranslation(), transform.getScale(), transform.getRotation(), _created, + ProceduralProgramKey(outColor.a < 1.0f)); + }); + } else if (pipelineType == Pipeline::MATERIAL) { + if (RenderPipelines::bindMaterials(materials, batch, args->_renderMode, args->_enableTexturing)) { + args->_details._materialSwitches++; + } + } + + const uint32_t compactColor = GeometryCache::toCompactColor(glm::vec4(outColor)); + _colorBuffer->setData(sizeof(compactColor), (const gpu::Byte*)&compactColor); + gpu::BufferView colorView(_colorBuffer, COLOR_ELEMENT); + batch.setInputBuffer(gpu::Stream::COLOR, colorView); + batch.setInputFormat(_vertexColorFormat); + batch.setUniformBuffer(graphics::slot::buffer::TriplanarScale, _params); + } - batch.setUniformBuffer(0, _params); batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_mesh->getNumIndices(), 0); } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 2c6f29f4b9..72958f73cb 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -204,11 +204,13 @@ public: protected: virtual ShapeKey getShapeKey() override; + virtual bool isTransparent() const override; + virtual Item::Bound getBound(RenderArgs* args) override; + virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; - virtual bool isTransparent() const override { return false; } private: #ifdef POLYVOX_ENTITY_USE_FADE_EFFECT @@ -224,6 +226,8 @@ private: glm::quat _orientation; PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle { PolyVoxEntityItem::SURFACE_MARCHING_CUBES }; std::array _xyzTextureUrls; + + gpu::BufferPointer _colorBuffer { std::make_shared() }; }; } } diff --git a/libraries/entities/src/EntityItemProperties.cpp.in b/libraries/entities/src/EntityItemProperties.cpp.in index 3bc67c71f3..fabdb03429 100644 --- a/libraries/entities/src/EntityItemProperties.cpp.in +++ b/libraries/entities/src/EntityItemProperties.cpp.in @@ -157,6 +157,7 @@ const QHash stringToMaterialMappingModeLookup = [] QHash toReturn; addMaterialMappingMode(toReturn, UV); addMaterialMappingMode(toReturn, PROJECTED); + addMaterialMappingMode(toReturn, TRIPLANAR); return toReturn; }(); QString EntityItemProperties::getMaterialMappingModeAsString() const { return MaterialMappingModeHelpers::getNameForMaterialMappingMode(_materialMappingMode); } diff --git a/libraries/entities/src/EntityItemPropertiesDocs.cpp b/libraries/entities/src/EntityItemPropertiesDocs.cpp index 8195161b77..5f6de26d5d 100644 --- a/libraries/entities/src/EntityItemPropertiesDocs.cpp +++ b/libraries/entities/src/EntityItemPropertiesDocs.cpp @@ -308,10 +308,12 @@ * For example, "[0,1,mat::string,mat::string2]" will replace mesh parts 0 and 1, and any mesh parts with * material "string" or "string2". Do not put spaces around the commas. Invalid values are parsed * to 0.

- * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv" or - * "projected". In "uv" mode, the material is evaluated within the UV space of the mesh it is - * applied to. In "projected" mode, the 3D transform (position, rotation, and dimensions) of the Material - * entity is used to evaluate the texture coordinates for the material. + * @property {string} materialMappingMode="uv" - How the material is mapped to the entity. Either "uv", + * "projected", or "triplanar". In "uv" mode, the material is evaluated within the + * UV space of the mesh it is applied to. In "projected" mode, the 3D transform (position, rotation, and + * dimensions) of the Material entity is used to evaluate the texture coordinates for the material. "triplanar" + * mode is like "uv" mode but the UV coordinates are evaluated based on a triplanar mapping instead of the + * coordinates from the model. * @property {Vec2} materialMappingPos=0,0 - Offset position in UV-space of the top left of the material, range * { x: 0, y: 0 }{ x: 1, y: 1 }. * @property {Vec2} materialMappingScale=1,1 - How much to scale the material within the parent's UV-space. diff --git a/libraries/entities/src/MaterialEntityItem.cpp.in b/libraries/entities/src/MaterialEntityItem.cpp.in index 045c155084..ea5e25cef3 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp.in +++ b/libraries/entities/src/MaterialEntityItem.cpp.in @@ -91,7 +91,7 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) { _desiredDimensions = value; if (_hasVertexShader || _materialMappingMode == MaterialMappingMode::PROJECTED) { EntityItem::setUnscaledDimensions(value); - } else if (_materialMappingMode == MaterialMappingMode::UV) { + } else if (_materialMappingMode == MaterialMappingMode::UV || _materialMappingMode == MaterialMappingMode::TRIPLANAR) { EntityItem::setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS); } } diff --git a/libraries/graphics/src/graphics/Material.slh b/libraries/graphics/src/graphics/Material.slh index 4d4dcde34c..952281c0e5 100644 --- a/libraries/graphics/src/graphics/Material.slh +++ b/libraries/graphics/src/graphics/Material.slh @@ -31,7 +31,7 @@ struct TexMapArray { { <$outTexcoord0$> = mix(<$texMapArray$>._texcoordTransforms0 * vec4(<$inTexcoord0$>.st, 0.0, 1.0), <$texMapArray$>._texcoordTransforms0 * <$worldPosition$> + vec4(0.5), - <$texMapArray$>._materialParams.x).st; + float(<$texMapArray$>._materialParams.x == 1.0)).st; } <@endfunc@> @@ -39,7 +39,7 @@ struct TexMapArray { { <$outTexcoord1$> = mix(<$texMapArray$>._texcoordTransforms1 * vec4(<$inTexcoord1$>.st, 0.0, 1.0), <$texMapArray$>._texcoordTransforms1 * <$worldPosition$> + vec4(0.5), - <$texMapArray$>._materialParams.x).st; + float(<$texMapArray$>._materialParams.x == 1.0)).st; } <@endfunc@> diff --git a/libraries/graphics/src/graphics/MaterialTextures.slh b/libraries/graphics/src/graphics/MaterialTextures.slh index 425b8deed8..fe011d7e70 100644 --- a/libraries/graphics/src/graphics/MaterialTextures.slh +++ b/libraries/graphics/src/graphics/MaterialTextures.slh @@ -234,6 +234,128 @@ float fetchScatteringMap(vec2 uv) { <@endif@> <@endfunc@> +<@func fetchMaterialTexturesCoord0Triplanar(matKey, positionMS, triplanarScale, albedo, roughness, normal, metallic, emissive, scattering)@> + vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz; + vec3 normalMS = normalize(cross(dFdy(<$positionMS$>.xyz), dFdx(<$positionMS$>.xyz))); + + TexMapArray texMapArray = getTexMapArray(); + vec2 uvXY = vec2(-inPosition.x, -inPosition.y); + <$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$> + vec2 uvXZ = vec2(-inPosition.x, inPosition.z); + <$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$> + vec2 uvYZ = vec2(inPosition.z, -inPosition.y); + <$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$> + +<@if albedo@> + vec4 <$albedo$>Triplanar = vec4(0.0); +<@endif@> +<@if roughness@> + float <$roughness$>Triplanar = 0.0; +<@endif@> +<@if normal@> + vec3 <$normal$>Triplanar = vec3(0.0); +<@endif@> +<@if metallic@> + float <$metallic$>Triplanar = 0.0; +<@endif@> +<@if emissive@> + vec3 <$emissive$>Triplanar = vec3(0.0); +<@endif@> +<@if scattering@> + float <$scattering$>Triplanar = 0.0; +<@endif@> + + { + <$fetchMaterialTexturesCoord0($matKey$, uvXY, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$> + float magnitude = abs(normalMS.z); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if roughness@> + <$roughness$>Triplanar += magnitude * <$roughness$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if metallic@> + <$metallic$>Triplanar += magnitude * <$metallic$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if scattering@> + <$scattering$>Triplanar += magnitude * <$scattering$>; + <@endif@> + } + + { + <$fetchMaterialTexturesCoord0($matKey$, uvXZ, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$> + float magnitude = abs(normalMS.y); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if roughness@> + <$roughness$>Triplanar += magnitude * <$roughness$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if metallic@> + <$metallic$>Triplanar += magnitude * <$metallic$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if scattering@> + <$scattering$>Triplanar += magnitude * <$scattering$>; + <@endif@> + } + + { + <$fetchMaterialTexturesCoord0($matKey$, uvYZ, $albedo$, $roughness$, $normal$, $metallic$, $emissive$, $scattering$)$> + float magnitude = abs(normalMS.x); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if roughness@> + <$roughness$>Triplanar += magnitude * <$roughness$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if metallic@> + <$metallic$>Triplanar += magnitude * <$metallic$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if scattering@> + <$scattering$>Triplanar += magnitude * <$scattering$>; + <@endif@> + } + +<@if albedo@> + vec4 <$albedo$> = <$albedo$>Triplanar; +<@endif@> +<@if roughness@> + float <$roughness$> = <$roughness$>Triplanar; +<@endif@> +<@if normal@> + // FIXME: this isn't strictly correct, as our tangents no longer match the space of our UVs + vec3 <$normal$> = normalize(<$normal$>Triplanar); +<@endif@> +<@if metallic@> + float <$metallic$> = <$metallic$>Triplanar; +<@endif@> +<@if emissive@> + vec3 <$emissive$> = <$emissive$>Triplanar; +<@endif@> +<@if scattering@> + float <$scattering$> = <$scattering$>Triplanar; +<@endif@> + +<@endfunc@> + <@func fetchMaterialTexturesCoord1(matKey, texcoord1, occlusion, lightmap)@> <@if occlusion@> float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoord1$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0)); @@ -455,6 +577,128 @@ float fetchUVAnimationMaskMap(vec2 uv) { <@endif@> <@endfunc@> +<@func fetchMToonMaterialTexturesCoord0Triplanar(matKey, positionMS, triplanarScale, albedo, normal, shade, emissive, shadingShift, rim, uvScrollSpeed, time)@> + vec3 inPosition = (<$positionMS$> - vec3(0.5)) / <$triplanarScale$>.xyz; + vec3 normalMS = normalize(cross(dFdy(<$positionMS$>.xyz), dFdx(<$positionMS$>.xyz))); + + TexMapArray texMapArray = getTexMapArray(); + vec2 uvXY = vec2(-inPosition.x, -inPosition.y); + <$evalTexMapArrayTexcoord0(texMapArray, uvXY, _positionWS, uvXY)$> + vec2 uvXZ = vec2(-inPosition.x, inPosition.z); + <$evalTexMapArrayTexcoord0(texMapArray, uvXZ, _positionWS, uvXZ)$> + vec2 uvYZ = vec2(inPosition.z, -inPosition.y); + <$evalTexMapArrayTexcoord0(texMapArray, uvYZ, _positionWS, uvYZ)$> + +<@if albedo@> + vec4 <$albedo$>Triplanar = vec4(0.0); +<@endif@> +<@if normal@> + vec3 <$normal$>Triplanar = vec3(0.0); +<@endif@> +<@if shade@> + vec3 <$shade$>Triplanar = vec3(0.0); +<@endif@> +<@if emissive@> + vec3 <$emissive$>Triplanar = vec3(0.0); +<@endif@> +<@if shadingShift@> + float <$shadingShift$>Triplanar = 0.0; +<@endif@> +<@if rim@> + vec3 <$rim$>Triplanar = vec3(0.0); +<@endif@> + + { + <$fetchMToonMaterialTexturesCoord0($matKey$, uvXY, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$> + float magnitude = abs(normalMS.z); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if shade@> + <$shade$>Triplanar += magnitude * <$shade$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if shadingShift@> + <$shadingShift$>Triplanar += magnitude * <$shadingShift$>; + <@endif@> + <@if rim@> + <$rim$>Triplanar += magnitude * <$rim$>; + <@endif@> + } + + { + <$fetchMToonMaterialTexturesCoord0($matKey$, uvXZ, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$> + float magnitude = abs(normalMS.y); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if shade@> + <$shade$>Triplanar += magnitude * <$shade$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if shadingShift@> + <$shadingShift$>Triplanar += magnitude * <$shadingShift$>; + <@endif@> + <@if rim@> + <$rim$>Triplanar += magnitude * <$rim$>; + <@endif@> + } + + { + <$fetchMToonMaterialTexturesCoord0($matKey$, uvYZ, $albedo$, $normal$, $shade$, $emissive$, $shadingShift$, $rim$, $uvScrollSpeed$, $time$)$> + float magnitude = abs(normalMS.x); + <@if albedo@> + <$albedo$>Triplanar += magnitude * <$albedo$>; + <@endif@> + <@if normal@> + <$normal$>Triplanar += magnitude * <$normal$>; + <@endif@> + <@if shade@> + <$shade$>Triplanar += magnitude * <$shade$>; + <@endif@> + <@if emissive@> + <$emissive$>Triplanar += magnitude * <$emissive$>; + <@endif@> + <@if shadingShift@> + <$shadingShift$>Triplanar += magnitude * <$shadingShift$>; + <@endif@> + <@if rim@> + <$rim$>Triplanar += magnitude * <$rim$>; + <@endif@> + } + +<@if albedo@> + vec4 <$albedo$> = <$albedo$>Triplanar; +<@endif@> +<@if normal@> + // FIXME: this isn't strictly correct, as our tangents no longer match the space of our UVs + vec3 <$normal$> = normalize(<$normal$>Triplanar); +<@endif@> +<@if shade@> + vec3 <$shade$> = <$shade$>Triplanar; +<@endif@> +<@if emissive@> + vec3 <$emissive$> = <$emissive$>Triplanar; +<@endif@> +<@if shadingShift@> + float <$shadingShift$> = <$shadingShift$>Triplanar; +<@endif@> +<@if rim@> + vec3 <$rim$> = <$rim$>Triplanar; +<@endif@> + +<@endfunc@> + <@func evalMaterialShade(fetchedShade, materialShade, matKey, shade)@> { <$shade$> = mix(vec3(1.0), <$materialShade$>, float((<$matKey$> & SHADE_VAL_BIT) != 0)); diff --git a/libraries/graphics/src/graphics/ShaderConstants.h b/libraries/graphics/src/graphics/ShaderConstants.h index 75eb4d00cc..ed76ee287a 100644 --- a/libraries/graphics/src/graphics/ShaderConstants.h +++ b/libraries/graphics/src/graphics/ShaderConstants.h @@ -20,6 +20,7 @@ #define GRAPHICS_BUFFER_KEY_LIGHT 4 #define GRAPHICS_BUFFER_LIGHT 5 #define GRAPHICS_BUFFER_AMBIENT_LIGHT 6 +#define GRAPHICS_BUFFER_TRIPLANAR_SCALE 7 #define GRAPHICS_TEXTURE_MATERIAL_ALBEDO 0 #define GRAPHICS_TEXTURE_MATERIAL_NORMAL 1 @@ -55,7 +56,8 @@ enum Buffer { KeyLight = GRAPHICS_BUFFER_KEY_LIGHT, AmbientLight = GRAPHICS_BUFFER_AMBIENT_LIGHT, SkyboxParams = GRAPHICS_BUFFER_SKYBOX_PARAMS, - HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS + HazeParams = GRAPHICS_BUFFER_HAZE_PARAMS, + TriplanarScale = GRAPHICS_BUFFER_TRIPLANAR_SCALE }; } // namespace buffer diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 1f8cb17841..76db3ca5d7 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -292,6 +292,10 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr } if (material) { builder.withCullFaceMode(material->getCullFaceMode()); + + if ((MaterialMappingMode)material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) { + builder.withTriplanar(); + } } } diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index f491d127c9..b7249b0b9b 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -56,7 +56,7 @@ void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* a void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args); static bool forceLightBatchSetter{ false }; -// TOOD: build this list algorithmically so we don't have to maintain it +// TODO: build this list algorithmically so we don't have to maintain it std::vector> ALL_PIPELINES = { // Simple { Key::Builder(), simple, model_shadow }, @@ -89,6 +89,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon(), model_normalmap_mtoon, model_shadow_mtoon }, { Key::Builder().withMaterial().withTranslucent().withMToon(), model_translucent_mtoon, model_shadow_mtoon }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon(), model_normalmap_translucent_mtoon, model_shadow_mtoon }, + // Unskinned Triplanar + { Key::Builder().withMaterial().withTriplanar(), model_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withTriplanar(), model_normalmap_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar(), model_translucent_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar(), model_normalmap_translucent_triplanar, model_shadow_triplanar }, + // Unskinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar(), model_unlit_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar(), model_normalmap_unlit_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar(), model_translucent_unlit_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar(), model_normalmap_translucent_unlit_triplanar, model_shadow_triplanar }, + // Unskinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar(), model_lightmap_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar(), model_normalmap_lightmap_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar(), model_translucent_lightmap_triplanar, model_shadow_triplanar }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar(), model_normalmap_translucent_lightmap_triplanar, model_shadow_triplanar }, + // Unskinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar(), model_mtoon_triplanar, model_shadow_mtoon_triplanar }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar(), model_normalmap_mtoon_triplanar, model_shadow_mtoon_triplanar }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar(), model_translucent_mtoon_triplanar, model_shadow_mtoon_triplanar }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar(), model_normalmap_translucent_mtoon_triplanar, model_shadow_mtoon_triplanar }, // Unskinned Fade { Key::Builder().withMaterial().withFade(), model_fade, model_shadow_fade }, { Key::Builder().withMaterial().withTangents().withFade(), model_normalmap_fade, model_shadow_fade }, @@ -109,6 +129,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon().withFade(), model_normalmap_mtoon_fade, model_shadow_mtoon_fade }, { Key::Builder().withMaterial().withTranslucent().withMToon().withFade(), model_translucent_mtoon_fade, model_shadow_mtoon_fade }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade(), model_normalmap_translucent_mtoon_fade, model_shadow_mtoon_fade }, + // Unskinned Fade Triplanar + { Key::Builder().withMaterial().withTriplanar().withFade(), model_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withFade(), model_normalmap_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade(), model_translucent_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade(), model_normalmap_translucent_triplanar_fade, model_shadow_triplanar_fade }, + // Unskinned Unlit Fade Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade(), model_unlit_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade(), model_normalmap_unlit_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade(), model_translucent_unlit_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade(), model_normalmap_translucent_unlit_triplanar_fade, model_shadow_triplanar_fade }, + // Unskinned Lightmapped Fade Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade(), model_lightmap_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade(), model_normalmap_lightmap_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade(), model_translucent_lightmap_triplanar_fade, model_shadow_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade(), model_normalmap_translucent_lightmap_triplanar_fade, model_shadow_triplanar_fade }, + // Unskinned MToon Fade Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withFade(), model_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade(), model_normalmap_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade(), model_translucent_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade(), model_normalmap_translucent_mtoon_triplanar_fade, model_shadow_mtoon_triplanar_fade }, // Matrix palette skinned { Key::Builder().withMaterial().withDeformed(), model_deformed, model_shadow_deformed }, @@ -130,6 +170,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon().withDeformed(), model_normalmap_mtoon_deformed, model_shadow_mtoon_deformed }, { Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed(), model_translucent_mtoon_deformed, model_shadow_mtoon_deformed }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed(), model_normalmap_translucent_mtoon_deformed, model_shadow_mtoon_deformed }, + // Matrix palette skinned Triplanar + { Key::Builder().withMaterial().withTriplanar().withDeformed(), model_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed(), model_normalmap_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed(), model_translucent_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed(), model_normalmap_translucent_triplanar_deformed, model_shadow_triplanar_deformed }, + // Matrix palette skinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed(), model_unlit_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed(), model_normalmap_unlit_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_translucent_unlit_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_normalmap_translucent_unlit_triplanar_deformed, model_shadow_triplanar_deformed }, + // Matrix palette skinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed(), model_lightmap_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed(), model_normalmap_lightmap_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_translucent_lightmap_triplanar_deformed, model_shadow_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_normalmap_translucent_lightmap_triplanar_deformed, model_shadow_triplanar_deformed }, + // Matrix palette skinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed(), model_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed(), model_normalmap_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed(), model_translucent_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed(), model_normalmap_translucent_mtoon_triplanar_deformed, model_shadow_mtoon_triplanar_deformed }, // Matrix palette skinned Fade { Key::Builder().withMaterial().withFade().withDeformed(), model_fade_deformed, model_shadow_fade_deformed }, { Key::Builder().withMaterial().withTangents().withFade().withDeformed(), model_normalmap_fade_deformed, model_shadow_fade_deformed }, @@ -150,6 +210,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon().withFade().withDeformed(), model_normalmap_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed }, { Key::Builder().withMaterial().withTranslucent().withMToon().withFade().withDeformed(), model_translucent_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade().withDeformed(), model_normalmap_translucent_mtoon_fade_deformed, model_shadow_mtoon_fade_deformed }, + // Matrix palette skinned Fade Triplanar + { Key::Builder().withMaterial().withTriplanar().withFade().withDeformed(), model_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withFade().withDeformed(), model_normalmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade().withDeformed(), model_translucent_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + // Matrix palette skinned Unlit Fade Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade().withDeformed(), model_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade().withDeformed(), model_normalmap_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed(), model_translucent_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_unlit_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + // Matrix palette skinned Lightmapped Fade Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade().withDeformed(), model_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade().withDeformed(), model_normalmap_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed(), model_translucent_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_lightmap_triplanar_fade_deformed, model_shadow_triplanar_fade_deformed }, + // Matrix palette skinned MToon Fade Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withFade().withDeformed(), model_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade().withDeformed(), model_normalmap_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade().withDeformed(), model_translucent_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade().withDeformed(), model_normalmap_translucent_mtoon_triplanar_fade_deformed, model_shadow_mtoon_triplanar_fade_deformed }, // Dual quaternion skinned { Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), model_deformeddq, model_shadow_deformeddq }, @@ -171,6 +251,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_deformeddq, model_shadow_mtoon_deformeddq }, { Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_deformeddq, model_shadow_mtoon_deformeddq }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_deformeddq, model_shadow_mtoon_deformeddq }, + // Dual quaternion skinned Triplanar + { Key::Builder().withMaterial().withTriplanar().withDeformed().withDualQuatSkinned(), model_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + // Dual quaternion skinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + // Dual quaternion skinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_deformeddq, model_shadow_triplanar_deformeddq }, + // Dual quaternion skinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_deformeddq, model_shadow_mtoon_triplanar_deformeddq }, // Dual quaternion skinned Fade { Key::Builder().withMaterial().withFade().withDeformed().withDualQuatSkinned(), model_fade_deformeddq, model_shadow_fade_deformeddq }, { Key::Builder().withMaterial().withTangents().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_fade_deformeddq, model_shadow_fade_deformeddq }, @@ -191,6 +291,26 @@ std::vector> ALL_PIPELINES = { { Key::Builder().withMaterial().withTangents().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq }, { Key::Builder().withMaterial().withTranslucent().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_fade_deformeddq, model_shadow_mtoon_fade_deformeddq }, + // Dual quaternion skinned Fade Triplanar + { Key::Builder().withMaterial().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + // Dual quaternion skinned Unlit Fade Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + // Dual quaternion skinned Lightmapped Fade Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_fade_deformeddq, model_shadow_triplanar_fade_deformeddq }, + // Dual quaternion skinned MToon Fade Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withFade().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_fade_deformeddq, model_shadow_mtoon_triplanar_fade_deformeddq }, }; void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter) { @@ -245,6 +365,26 @@ void initForwardPipelines(ShapePlumber& plumber) { { Key::Builder().withMaterial().withTangents().withMToon(), model_normalmap_mtoon_forward }, { Key::Builder().withMaterial().withTranslucent().withMToon(), model_translucent_mtoon_forward }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon(), model_normalmap_translucent_mtoon_forward }, + // Unskinned Triplanar + { Key::Builder().withMaterial().withTriplanar(), model_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withTriplanar(), model_normalmap_triplanar_forward }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar(), model_translucent_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar(), model_normalmap_translucent_triplanar_forward }, + // Unskinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar(), model_unlit_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar(), model_normalmap_unlit_triplanar_forward }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar(), model_translucent_unlit_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar(), model_normalmap_translucent_unlit_triplanar_forward }, + // Unskinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar(), model_lightmap_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar(), model_normalmap_lightmap_triplanar_forward }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar(), model_translucent_lightmap_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar(), model_normalmap_translucent_lightmap_triplanar_forward }, + // Unskinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar(), model_mtoon_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar(), model_normalmap_mtoon_triplanar_forward }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar(), model_translucent_mtoon_triplanar_forward }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar(), model_normalmap_translucent_mtoon_triplanar_forward }, // Matrix palette skinned { Key::Builder().withMaterial().withDeformed(), model_forward_deformed }, @@ -266,6 +406,26 @@ void initForwardPipelines(ShapePlumber& plumber) { { Key::Builder().withMaterial().withTangents().withMToon().withDeformed(), model_normalmap_mtoon_forward_deformed }, { Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed(), model_translucent_mtoon_forward_deformed }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed(), model_normalmap_translucent_mtoon_forward_deformed }, + // Matrix palette skinned Triplanar + { Key::Builder().withMaterial().withTriplanar().withDeformed(), model_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed(), model_normalmap_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed(), model_translucent_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed(), model_normalmap_translucent_triplanar_forward_deformed }, + // Matrix palette skinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed(), model_unlit_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed(), model_normalmap_unlit_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_translucent_unlit_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed(), model_normalmap_translucent_unlit_triplanar_forward_deformed }, + // Matrix palette skinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed(), model_lightmap_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed(), model_normalmap_lightmap_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_translucent_lightmap_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed(), model_normalmap_translucent_lightmap_triplanar_forward_deformed }, + // Matrix palette skinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed(), model_mtoon_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed(), model_normalmap_mtoon_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed(), model_translucent_mtoon_triplanar_forward_deformed }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed(), model_normalmap_translucent_mtoon_triplanar_forward_deformed }, // Dual quaternion skinned { Key::Builder().withMaterial().withDeformed().withDualQuatSkinned(), model_forward_deformeddq }, @@ -287,6 +447,26 @@ void initForwardPipelines(ShapePlumber& plumber) { { Key::Builder().withMaterial().withTangents().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_forward_deformeddq }, { Key::Builder().withMaterial().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_forward_deformeddq }, { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_forward_deformeddq }, + // Dual quaternion skinned Triplanar + { Key::Builder().withMaterial().withTriplanar().withDeformed().withDualQuatSkinned(), model_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_triplanar_forward_deformeddq }, + // Dual quaternion skinned Unlit Triplanar + { Key::Builder().withMaterial().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_unlit_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_unlit_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_unlit_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withUnlit().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_unlit_triplanar_forward_deformeddq }, + // Dual quaternion skinned Lightmapped Triplanar + { Key::Builder().withMaterial().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_lightmap_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_lightmap_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_lightmap_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withLightMap().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_lightmap_triplanar_forward_deformeddq }, + // Dual quaternion skinned MToon Triplanar + { Key::Builder().withMaterial().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_mtoon_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_mtoon_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_translucent_mtoon_triplanar_forward_deformeddq }, + { Key::Builder().withMaterial().withTangents().withTranslucent().withMToon().withTriplanar().withDeformed().withDualQuatSkinned(), model_normalmap_translucent_mtoon_triplanar_forward_deformeddq }, }; for (auto& pipeline : pipelines) { @@ -1295,6 +1475,7 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: static gpu::BufferView defaultMaterialSchema; static gpu::TextureTablePointer defaultMToonMaterialTextures = std::make_shared(); static gpu::BufferView defaultMToonMaterialSchema; + static gpu::BufferView defaultTriplanarScale; static std::once_flag once; std::call_once(once, [textureCache] { @@ -1320,8 +1501,16 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu: defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialMatcap, textureCache->getBlackTexture()); defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialRim, textureCache->getWhiteTexture()); defaultMToonMaterialTextures->setTexture(gr::Texture::MaterialUVAnimationMask, textureCache->getWhiteTexture()); + + vec4 triplanarScale = vec4(1.0f); + defaultTriplanarScale = gpu::BufferView(std::make_shared(sizeof(triplanarScale), (const gpu::Byte*) &triplanarScale, sizeof(triplanarScale))); }); + if (multiMaterial.size() > 0 && + (MaterialMappingMode)multiMaterial.top().material->getMaterialParams().x == MaterialMappingMode::TRIPLANAR) { + batch.setUniformBuffer(gr::Buffer::TriplanarScale, defaultTriplanarScale); + } + // For shadows, we only need opacity mask information auto key = multiMaterial.getMaterialKey(); if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE || (key.isOpacityMaskMap() || key.isTranslucentMap())) { diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index a2f15df8a4..2fec410130 100644 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -45,6 +45,16 @@ <@endif@> <@endif@> +<@if HIFI_USE_TRIPLANAR@> + struct TriplanarParams { + vec4 scale; + }; + + LAYOUT(binding=GRAPHICS_BUFFER_TRIPLANAR_SCALE) uniform triplanarParamsBuffer { + TriplanarParams triplanarParams; + }; +<@endif@> + <@if not HIFI_USE_SHADOW@> <@if HIFI_USE_MTOON@> <@include DefaultMaterials.slh@> @@ -111,6 +121,9 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) in vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TANGENT_WS) in vec3 _tangentWS; <@endif@> <@endif@> +<@if HIFI_USE_TRIPLANAR@> + layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec3 _positionMS; +<@endif@> void main(void) { <@if HIFI_USE_FADE@> @@ -129,10 +142,19 @@ void main(void) { Material mat = getMaterial(); BITFIELD matKey = getMaterialKey(mat); <@if HIFI_USE_SHADOW or HIFI_USE_UNLIT@> - <@if not HIFI_USE_MTOON@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> + <@if not HIFI_USE_TRIPLANAR@> + <@if not HIFI_USE_MTOON@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> + <@else@> + <$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> + <@endif@> <@else@> - <$fetchMToonMaterialTexturesCoord0(matKey, _texCoord0, albedoTex)$> + const vec3 triplanarScale = triplanarParams.scale.xyz; + <@if not HIFI_USE_MTOON@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex)$> + <@else@> + <$fetchMToonMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex)$> + <@endif@> <@endif@> float cutoff = getMaterialOpacityCutoff(mat); @@ -264,24 +286,47 @@ void main(void) { <@endif@> <@else@> - <@if not HIFI_USE_LIGHTMAP@> - <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$> - <@elif HIFI_USE_NORMALMAP@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$> - <@elif HIFI_USE_TRANSLUCENT@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$> + <@if not HIFI_USE_TRIPLANAR@> + <@if not HIFI_USE_LIGHTMAP@> + <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$> + <@elif HIFI_USE_NORMALMAP@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$> + <@elif HIFI_USE_TRANSLUCENT@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$> + <@else@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$> + <@endif@> + <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$> <@else@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$> + <@if HIFI_USE_NORMALMAP@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex)$> + <@else@> + <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$> + <@endif@> + <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$> <@endif@> - <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$> <@else@> - <@if HIFI_USE_NORMALMAP@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, normalTex, metallicTex)$> + const vec3 triplanarScale = triplanarParams.scale.xyz; + <@if not HIFI_USE_LIGHTMAP@> + <@if HIFI_USE_NORMALMAP and HIFI_USE_TRANSLUCENT@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, _SCRIBE_NULL)$> + <@elif HIFI_USE_NORMALMAP@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex, emissiveTex, scatteringTex)$> + <@elif HIFI_USE_TRANSLUCENT@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, _SCRIBE_NULL)$> + <@else@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex, emissiveTex, scatteringTex)$> + <@endif@> + <$fetchMaterialTexturesCoord1(matKey, _texCoord1, occlusionTex)$> <@else@> - <$fetchMaterialTexturesCoord0(matKey, _texCoord0, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$> + <@if HIFI_USE_NORMALMAP@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, normalTex, metallicTex)$> + <@else@> + <$fetchMaterialTexturesCoord0Triplanar(matKey, _positionMS, triplanarScale, albedoTex, roughnessTex, _SCRIBE_NULL, metallicTex)$> + <@endif@> + <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$> <@endif@> - <$fetchMaterialTexturesCoord1(matKey, _texCoord1, _SCRIBE_NULL, lightmap)$> <@endif@> float cutoff = getMaterialOpacityCutoff(mat); diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index dc4bcde7fe..ba7abd4534 100644 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -56,12 +56,19 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; layout(location=RENDER_UTILS_ATTR_TANGENT_WS) out vec3 _tangentWS; <@endif@> <@endif@> +<@if HIFI_USE_TRIPLANAR@> + layout(location=RENDER_UTILS_ATTR_POSITION_MS) out vec3 _positionMS; +<@endif@> void main(void) { vec4 positionMS = inPosition; vec3 normalMS = inNormal.xyz; vec3 tangentMS = inTangent.xyz; +<@if HIFI_USE_TRIPLANAR@> + _positionMS = inPosition.xyz; +<@endif@> + <@if HIFI_USE_DEFORMED or HIFI_USE_DEFORMEDDQ@> evalMeshDeformer(inPosition, positionMS, <@if not HIFI_USE_SHADOW@> diff --git a/libraries/render-utils/src/render-utils/model.slp b/libraries/render-utils/src/render-utils/model.slp index f2b1a0d588..641ae0e446 100644 --- a/libraries/render-utils/src/render-utils/model.slp +++ b/libraries/render-utils/src/render-utils/model.slp @@ -1 +1 @@ -DEFINES (normalmap translucent:f unlit:f/lightmap:f)/(shadow mirror:f) mtoon fade:f/forward:f deformed:v/deformeddq:v +DEFINES (normalmap translucent:f unlit:f/lightmap:f)/(shadow mirror:f) mtoon triplanar fade:f/forward:f deformed:v/deformeddq:v diff --git a/libraries/render/src/render/ShapePipeline.h b/libraries/render/src/render/ShapePipeline.h index 87a1d3c834..df1187f99a 100644 --- a/libraries/render/src/render/ShapePipeline.h +++ b/libraries/render/src/render/ShapePipeline.h @@ -40,6 +40,7 @@ public: CULL_FACE_NONE, // if neither of these are set, we're CULL_FACE_BACK CULL_FACE_FRONT, MTOON, + TRIPLANAR, OWN_PIPELINE, INVALID, @@ -81,6 +82,7 @@ public: Builder& withTranslucent() { _flags.set(TRANSLUCENT); return (*this); } Builder& withLightMap() { _flags.set(LIGHTMAP); return (*this); } Builder& withTangents() { _flags.set(TANGENTS); return (*this); } + Builder& withoutTangents() { _flags.reset(TANGENTS); return (*this); } Builder& withUnlit() { _flags.set(UNLIT); return (*this); } Builder& withDeformed() { _flags.set(DEFORMED); return (*this); } Builder& withDualQuatSkinned() { _flags.set(DUAL_QUAT_SKINNED); return (*this); } @@ -88,6 +90,7 @@ public: Builder& withWireframe() { _flags.set(WIREFRAME); return (*this); } Builder& withFade() { _flags.set(FADE); return (*this); } Builder& withMToon() { _flags.set(MTOON); return (*this); } + Builder& withTriplanar() { _flags.set(TRIPLANAR); return (*this); } Builder& withoutCullFace() { return withCullFaceMode(graphics::MaterialKey::CullFaceMode::CULL_NONE); } Builder& withCullFaceMode(graphics::MaterialKey::CullFaceMode cullFaceMode) { @@ -191,6 +194,9 @@ public: Builder& withMToon() { _flags.set(MTOON); _mask.set(MTOON); return (*this); } Builder& withoutMToon() { _flags.reset(MTOON); _mask.set(MTOON); return (*this); } + Builder& withTriplanar() { _flags.set(TRIPLANAR); _mask.set(TRIPLANAR); return (*this); } + Builder& withoutTriplanar() { _flags.reset(TRIPLANAR); _mask.set(TRIPLANAR); 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); } @@ -221,6 +227,7 @@ public: bool isCullFaceFront() const { return !_flags[CULL_FACE_NONE] && _flags[CULL_FACE_FRONT]; } bool isFaded() const { return _flags[FADE]; } bool isMToon() const { return _flags[MTOON]; } + bool isTriplanar() const { return _flags[TRIPLANAR]; } bool hasOwnPipeline() const { return _flags[OWN_PIPELINE]; } bool isValid() const { return !_flags[INVALID]; } @@ -261,6 +268,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) { << "isCullFace:" << key.isCullFace() << "isFaded:" << key.isFaded() << "isMToon:" << key.isMToon() + << "isTriplanar:" << key.isTriplanar() << "]"; } } else { diff --git a/libraries/shared/src/MaterialMappingMode.cpp b/libraries/shared/src/MaterialMappingMode.cpp index 09a7cfd6d9..da2f8429db 100644 --- a/libraries/shared/src/MaterialMappingMode.cpp +++ b/libraries/shared/src/MaterialMappingMode.cpp @@ -10,7 +10,8 @@ const char* materialMappingModeNames[] = { "uv", - "projected" + "projected", + "triplanar" }; static const size_t MATERIAL_MODE_NAMES = (sizeof(materialMappingModeNames) / sizeof(materialMappingModeNames[0])); diff --git a/libraries/shared/src/MaterialMappingMode.h b/libraries/shared/src/MaterialMappingMode.h index d48739562a..391e90d224 100644 --- a/libraries/shared/src/MaterialMappingMode.h +++ b/libraries/shared/src/MaterialMappingMode.h @@ -14,6 +14,7 @@ enum MaterialMappingMode : uint8_t { UV = 0, PROJECTED, + TRIPLANAR, // put new mapping-modes before this line. UNSET_MATERIAL_MAPPING_MODE }; diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index 24df1c9e0f..b7bbacaad5 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -745,6 +745,7 @@ var MATERIAL_MODE_UV = 0; var MATERIAL_MODE_PROJECTED = 1; + var MATERIAL_MODE_TRIPLANAR = 2; function handleNewModelDialogResult(result) { if (result) { @@ -886,6 +887,9 @@ // case MATERIAL_MODE_PROJECTED: // materialMappingMode = "projected"; // break; + // case MATERIAL_MODE_TRIPLANAR: + // materialMappingMode = "triplanar"; + // break; // default: // shapeType = "uv"; //} diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index 408a3771cc..f50088b089 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -1106,7 +1106,7 @@ const GROUPS = [ label: "Material Mapping Mode", type: "dropdown", options: { - uv: "UV space", projected: "3D projected" + uv: "UV space", projected: "3D projected", triplanar: "Triplanar mapping" }, propertyID: "materialMappingMode", },