diff options
Diffstat (limited to 'src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp')
-rw-r--r-- | src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp | 271 |
1 files changed, 119 insertions, 152 deletions
diff --git a/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp b/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp index b40e10e..4e109dd 100644 --- a/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp +++ b/src/runtimerender/Qt3DSRenderCustomMaterialSystem.cpp @@ -687,11 +687,12 @@ struct SCustomMaterialShader { NVScopedRefCounted<NVRenderShaderProgram> m_Shader; NVRenderCachedShaderProperty<QT3DSMat44> m_ModelMatrix; - NVRenderCachedShaderProperty<QT3DSMat44> m_ViewProjMatrix; + NVRenderCachedShaderProperty<QT3DSMat44> m_ModelViewProjMatrix; NVRenderCachedShaderProperty<QT3DSMat44> m_ViewMatrix; NVRenderCachedShaderProperty<QT3DSMat33> m_NormalMatrix; NVRenderCachedShaderProperty<QT3DSVec3> m_CameraPos; NVRenderCachedShaderProperty<QT3DSMat44> m_ProjMatrix; + NVRenderCachedShaderProperty<QT3DSMat44> m_ViewProjMatrix; NVRenderCachedShaderProperty<QT3DSMat44> m_ViewportMatrix; NVRenderCachedShaderProperty<QT3DSVec2> m_CamProperties; NVRenderCachedShaderProperty<NVRenderTexture2D *> m_DepthTexture; @@ -712,11 +713,12 @@ struct SCustomMaterialShader SCustomMaterialShader(NVRenderShaderProgram &inShader, SDynamicShaderProgramFlags inFlags) : m_Shader(inShader) , m_ModelMatrix("model_matrix", inShader) - , m_ViewProjMatrix("model_view_projection", inShader) + , m_ModelViewProjMatrix("model_view_projection", inShader) , m_ViewMatrix("view_matrix", inShader) , m_NormalMatrix("normal_matrix", inShader) , m_CameraPos("camera_position", inShader) - , m_ProjMatrix("view_projection_matrix", inShader) + , m_ProjMatrix("projection_matrix", inShader) + , m_ViewProjMatrix("view_projection_matrix", inShader) , m_ViewportMatrix("viewport_matrix", inShader) , m_CamProperties("camera_properties", inShader) , m_DepthTexture("depth_sampler", inShader) @@ -873,8 +875,6 @@ struct SMaterialSystem : public ICustomMaterialSystem TShaderMap m_ShaderMap; nvvector<TCustomMaterialTextureEntry> m_TextureEntries; nvvector<SCustomMaterialBuffer> m_AllocatedBuffers; - nvvector<TAllocatedImageEntry> m_AllocatedImages; - nvvector<SCustomMaterial::TImageMapHash *> m_materialImageMaps; bool m_UseFastBlits; eastl::string m_ShaderNameBuilder; QT3DSU64 m_LastFrameTime; @@ -889,8 +889,6 @@ struct SMaterialSystem : public ICustomMaterialSystem , m_ShaderMap(ct.GetAllocator(), "SMaterialSystem::m_ShaderMap") , m_TextureEntries(ct.GetAllocator(), "SMaterialSystem::m_TextureEntries") , m_AllocatedBuffers(ct.GetAllocator(), "SMaterialSystem::m_AllocatedBuffers") - , m_AllocatedImages(ct.GetAllocator(), "SMaterialSystem::m_AllocatedImages") - , m_materialImageMaps(ct.GetAllocator(), "SMaterialSystem::m_materialImageMaps") , m_UseFastBlits(true) , m_LastFrameTime(0) , m_MillisecondsSinceLastFrame(0) @@ -911,22 +909,10 @@ struct SMaterialSystem : public ICustomMaterialSystem void clearImageAndBufferCaches() { while (m_AllocatedBuffers.size()) - ReleaseBuffer(0); - - for (QT3DSU32 idx = 0; idx < m_AllocatedImages.size(); ++idx) { - SImage *pImage = m_AllocatedImages[idx].second; - QT3DS_FREE(m_CoreContext.GetAllocator(), pImage); - } - for (QT3DSU32 idx = 0; idx < m_materialImageMaps.size(); ++idx) { - auto *matmap = m_materialImageMaps[idx]; - matmap->~nvhash_map(); - QT3DS_FREE(m_CoreContext.GetAllocator(), matmap); - } - m_materialImageMaps.clear(); - m_AllocatedImages.clear(); + ReleaseBuffer(0, true); } - void ReleaseBuffer(QT3DSU32 inIdx) + void ReleaseBuffer(QT3DSU32 inIdx, bool forceRelease) { // Don't call this on MaterialSystem destroy. // This causes issues for scene liftime buffers @@ -936,8 +922,8 @@ struct SMaterialSystem : public ICustomMaterialSystem theEntry.m_FrameBuffer->Attach(NVRenderFrameBufferAttachments::Color0, NVRenderTextureOrRenderBuffer()); - theManager.Release(*theEntry.m_FrameBuffer); - theManager.Release(*theEntry.m_Texture); + theManager.Release(*theEntry.m_FrameBuffer, forceRelease); + theManager.Release(*theEntry.m_Texture, forceRelease); m_AllocatedBuffers.replace_with_last(inIdx); } @@ -954,7 +940,7 @@ struct SMaterialSystem : public ICustomMaterialSystem if (IsMaterialRegistered(inName)) return false; m_CoreContext.GetDynamicObjectSystemCore().Register( - inName, inProperties, sizeof(SCustomMaterial), GraphObjectTypes::CustomMaterial); + inName, inProperties, GraphObjectTypes::CustomMaterial); IDynamicObjectClass *theClass = m_CoreContext.GetDynamicObjectSystemCore().GetDynamicObjectClass(inName); if (theClass == NULL) { @@ -1012,14 +998,6 @@ struct SMaterialSystem : public ICustomMaterialSystem return m_AllocatedBuffers.size(); } - virtual QT3DSU32 FindAllocatedImage(CRegisteredString inName) - { - for (QT3DSU32 idx = 0, end = m_AllocatedImages.size(); idx < end; ++idx) - if (m_AllocatedImages[idx].first == inName) - return idx; - return QT3DSU32(-1); - } - virtual bool TextureNeedsMips(const SPropertyDefinition *inPropDec, qt3ds::render::NVRenderTexture2D *inTexture) { @@ -1101,7 +1079,7 @@ struct SMaterialSystem : public ICustomMaterialSystem SCustomMaterial *CreateCustomMaterial(CRegisteredString inName, NVAllocatorCallback &inSceneGraphAllocator) override { - SCustomMaterial *theMaterial = static_cast<SCustomMaterial *>( + SCustomMaterial *theMaterial = QT3DS_NEW(inSceneGraphAllocator, SCustomMaterial)( m_CoreContext.GetDynamicObjectSystemCore().CreateInstance(inName, inSceneGraphAllocator)); SMaterialClass *theClass = GetMaterialClass(inName); @@ -1264,6 +1242,9 @@ struct SMaterialSystem : public ICustomMaterialSystem if (theProgram) { theInsertResult.first->second = QT3DS_NEW(m_Allocator, SCustomMaterialShader)(*theProgram, theFlags); + } else { + // If a changed shader fails to compile, clean away the old result from cache + theInsertResult.first->second = NULL; } } else if (theInsertResult.first->second) theProgram = theInsertResult.first->second->m_Shader; @@ -1292,6 +1273,7 @@ struct SMaterialSystem : public ICustomMaterialSystem NVRenderShaderProgram &inShader, const SPropertyDefinition &inDefinition) { + IStringTable &strTable = m_CoreContext.GetStringTable(); qt3ds::render::NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inPropertyName); using namespace qt3ds::render; @@ -1301,24 +1283,42 @@ struct SMaterialSystem : public ICustomMaterialSystem StaticAssert<sizeof(CRegisteredString) == sizeof(NVRenderTexture2DPtr)>::valid_expression(); CRegisteredString *theStrPtr = reinterpret_cast<CRegisteredString *>(inDataPtr); - if (theStrPtr->IsValid() && inMaterial.m_imageMaps) { - SImage *image = (*inMaterial.m_imageMaps)[inPropertyName]; - if (image) { - if (image->m_ImagePath != *theStrPtr) { - image->m_ImagePath = *theStrPtr; - image->m_Flags.SetDirty(true); - } else { - if (image->m_OffscreenRendererId.IsValid()) { - SetSubpresentation(inShader, inPropertyName, - image->m_TextureData.m_Texture, - &inDefinition); - } else { - SetTexture(inShader, inPropertyName, - image->m_TextureData.m_Texture, &inDefinition, - TextureNeedsMips(&inDefinition, - image->m_TextureData.m_Texture)); - } + + SImage *image = inMaterial.getImage(*theStrPtr); + if (image) { + CRegisteredString strU = strTable.RegisterStr( + QString::fromLatin1(inPropertyName.c_str()) + "TransformU"); + CRegisteredString strV = strTable.RegisterStr( + QString::fromLatin1(inPropertyName.c_str()) + "TransformV"); + qt3ds::render::NVRenderShaderConstantBase *transformU = + inShader.GetShaderConstant(strU); + qt3ds::render::NVRenderShaderConstantBase *transformV = + inShader.GetShaderConstant(strV); + image->CalculateTextureTransform(); + QT3DSMat44 textureTransform = image->m_TextureTransform; + if (image->m_TextureData.m_TextureFlags.IsInvertUVCoords()) { + QT3DSMat44 invertCoordsMat(QT3DSMat44::createIdentity()); + invertCoordsMat.scale(QT3DSVec4(1.0f, -1.0f, 1.0f, 1.0f)); + invertCoordsMat.setPosition(QT3DSVec3(0.0f, 1.0f, 0.0f)); + textureTransform = textureTransform * invertCoordsMat; + } + const QT3DSF32 *dataPtr(textureTransform.front()); + inShader.SetPropertyValue(transformU, + QT3DSVec3(dataPtr[0], dataPtr[4], dataPtr[12])); + inShader.SetPropertyValue(transformV, + QT3DSVec3(dataPtr[1], dataPtr[5], dataPtr[13])); + if (image->m_TextureData.m_Texture) { + auto *texture = image->m_TextureData.m_Texture; + texture->SetTextureWrapS(image->m_HorizontalTilingMode); + texture->SetTextureWrapT(image->m_VerticalTilingMode); + texture->SetMinFilter(image->m_MinFilter); + texture->SetMagFilter(image->m_MagFilter); + if (inDefinition.m_MinFilterOp != NVRenderTextureMinifyingOp::Nearest + && inDefinition.m_MinFilterOp != NVRenderTextureMinifyingOp::Linear + && !texture->GetNumMipmaps()) { + texture->GenerateMipmaps(); } + inShader.SetPropertyValue(theConstant, texture); } } } else { @@ -1348,15 +1348,16 @@ struct SMaterialSystem : public ICustomMaterialSystem NVRenderShaderProgram &inShader, const SApplyInstanceValue &inCommand) { // sanity check + SDynamicObject &dynObj = *inMaterial.m_dynamicObject; if (inCommand.m_PropertyName.IsValid()) { bool canGetData = inCommand.m_ValueOffset + getSizeofShaderDataType(inCommand.m_ValueType) - <= inMaterial.m_DataSectionByteSize; + <= dynObj.m_DataSectionByteSize; if (canGetData == false) { QT3DS_ASSERT(false); return; } - QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + inCommand.m_ValueOffset; + QT3DSU8 *dataPtr = dynObj.GetDataSectionOffset(inCommand.m_ValueOffset); const SPropertyDefinition *theDefinition = inClass.m_Class->FindPropertyByName(inCommand.m_PropertyName); if (theDefinition) @@ -1372,13 +1373,20 @@ struct SMaterialSystem : public ICustomMaterialSystem // This is fine, the property wasn't found and we continue, no problem. if (!theConstant) continue; - QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset; + QT3DSU8 *dataPtr = dynObj.GetDataSectionOffset(theDefinition.m_Offset); DoApplyInstanceValue(inMaterial, dataPtr, theDefinition.m_Name, theDefinition.m_DataType, inShader, theDefinition); } } } + void ApplyDepth(const SApplyDepth &inCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + theContext.SetDepthFunction(inCommand.m_depthFunc); + theContext.SetDepthWriteEnabled(inCommand.m_depthMask); + } + void ApplyBlending(const SApplyBlending &inCommand) { NVRenderContext &theContext(m_Context->GetRenderContext()); @@ -1397,6 +1405,31 @@ struct SMaterialSystem : public ICustomMaterialSystem theContext.SetBlendEquation(blendEqu); } + void ApplyRenderState(const SApplyRenderState &inCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + + switch (inCommand.m_RenderState) { + case NVRenderState::CullFace: + theContext.SetCullingEnabled(inCommand.m_Enabled); + break; + case NVRenderState::StencilTest: + theContext.SetStencilTestEnabled(inCommand.m_Enabled); + break; + default: + break; + } + } + + void ApplyCulling(const SApplyCulling &inCommand) + { + NVRenderContext &theContext(m_Context->GetRenderContext()); + + NVScopedRefCounted<qt3ds::render::NVRenderRasterizerState> state = + theContext.CreateRasterizerState(0.0, 0.0, inCommand.m_CullMode); + theContext.SetRasterizerState(state); + } + // we currently only bind a source texture const NVRenderTexture2D *ApplyBufferValue(const SCustomMaterial &inMaterial, NVRenderShaderProgram &inShader, @@ -1480,7 +1513,7 @@ struct SMaterialSystem : public ICustomMaterialSystem && theDetails.m_Format == theFormat) { theTexture = theEntry.m_Texture; } else { - ReleaseBuffer(bufferIdx); + ReleaseBuffer(bufferIdx, false); } } @@ -1735,7 +1768,6 @@ struct SMaterialSystem : public ICustomMaterialSystem theContext.SetInputAssembler(&inAssembler); - theContext.SetCullingEnabled(true); QT3DSU32 count = inCount; QT3DSU32 offset = inOffset; @@ -1756,8 +1788,10 @@ struct SMaterialSystem : public ICustomMaterialSystem // for refrative materials we come from the transparent render path // but we do not want to do blending bool wasBlendingEnabled = theContext.IsBlendingEnabled(); + bool wasStencilEnabled = theContext.IsStencilTestEnabled(); if (inMaterial.m_hasRefraction) theContext.SetBlendingEnabled(false); + theContext.SetCullingEnabled(true); NVRenderContextScopedProperty<NVRenderFrameBuffer *> __framebuffer( theContext, &NVRenderContext::GetRenderTarget, &NVRenderContext::SetRenderTarget); @@ -1810,9 +1844,18 @@ struct SMaterialSystem : public ICustomMaterialSystem // reset theRenderTargetNeedsClear = false; break; + case CommandTypes::ApplyCulling: + ApplyCulling(static_cast<const SApplyCulling &>(theCommand)); + break; + case CommandTypes::ApplyRenderState: + ApplyRenderState(static_cast<const SApplyRenderState &>(theCommand)); + break; case CommandTypes::ApplyBlending: ApplyBlending(static_cast<const SApplyBlending &>(theCommand)); break; + case CommandTypes::ApplyDepth: + ApplyDepth(static_cast<const SApplyDepth &>(theCommand)); + break; case CommandTypes::ApplyBufferValue: if (theCurrentShader) ApplyBufferValue(inMaterial, *theCurrentShader->m_Shader, @@ -1831,11 +1874,18 @@ struct SMaterialSystem : public ICustomMaterialSystem if (inMaterial.m_hasRefraction) theContext.SetBlendingEnabled(wasBlendingEnabled); + theContext.SetStencilTestEnabled(wasStencilEnabled); + NVScopedRefCounted<qt3ds::render::NVRenderRasterizerState> state = + theContext.CreateRasterizerState(0.0, 0.0, qt3ds::render::NVRenderFaces::Back); + theContext.SetRasterizerState(state); + theContext.SetCullingEnabled(true); + theContext.SetDepthFunction(NVRenderBoolOp::LessThanOrEqual); + theContext.SetDepthWriteEnabled(true); // Release any per-frame buffers for (QT3DSU32 idx = 0; idx < m_AllocatedBuffers.size(); ++idx) { if (m_AllocatedBuffers[idx].m_Flags.IsSceneLifetime() == false) { - ReleaseBuffer(idx); + ReleaseBuffer(idx, false); --idx; } } @@ -1874,17 +1924,18 @@ struct SMaterialSystem : public ICustomMaterialSystem applier); } - void renderSubpresentations(SCustomMaterial &inMaterial) override + bool renderSubpresentations(SCustomMaterial &inMaterial) override { SMaterialClass *theClass = GetMaterialClass(inMaterial.m_ClassName); if (!theClass) - return; + return false; + bool wasDirty = false; NVConstDataRef<SPropertyDefinition> theDefs = theClass->m_Class->GetProperties(); for (QT3DSU32 idx = 0, end = theDefs.size(); idx < end; ++idx) { const SPropertyDefinition &theDefinition(theDefs[idx]); if (theDefinition.m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - QT3DSU8 *dataPtr = inMaterial.GetDataSectionBegin() + theDefinition.m_Offset; + QT3DSU8 *dataPtr = inMaterial.m_dynamicObject->GetDataSectionOffset(theDefinition.m_Offset); StaticAssert<sizeof(CRegisteredString) == sizeof(NVRenderTexture2DPtr)>::valid_expression(); CRegisteredString *theStrPtr = reinterpret_cast<CRegisteredString *>(dataPtr); @@ -1892,11 +1943,16 @@ struct SMaterialSystem : public ICustomMaterialSystem m_Context->GetOffscreenRenderManager()); if (theStrPtr->IsValid()) { - if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr)) - theOffscreenRenderer.GetRenderedItem(*theStrPtr); + if (theOffscreenRenderer.HasOffscreenRenderer(*theStrPtr)) { + SOffscreenRenderResult result + = theOffscreenRenderer.GetRenderedItem(*theStrPtr); + if (result.m_HasChangedSinceLastFrame) + wasDirty = true; + } } } } + return wasDirty; } void clearCaches() override @@ -1929,91 +1985,6 @@ struct SMaterialSystem : public ICustomMaterialSystem return theClass->m_Class->RequiresCompilation(); } - SCustomMaterial::TImageMapHash *newImageMap(NVAllocatorCallback &allocator) - { - const char *name = "SCustomMaterial::TImageMapHash"; - SCustomMaterial::TImageMapHash *ret - = new (QT3DS_ALLOC(allocator, sizeof(SCustomMaterial::TImageMapHash), name)) - SCustomMaterial::TImageMapHash(allocator, name); - m_materialImageMaps.push_back(ret); - return ret; - } - - virtual void PrepareTextureForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) - { - NVConstDataRef<SPropertyDefinition> thePropDefs = inClass.m_Class->GetProperties(); - for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { - if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::NVRenderTexture2DPtr) { - SImage *pImage = nullptr; - CRegisteredString theStrPtr = *reinterpret_cast<CRegisteredString *>( - inMaterial.GetDataSectionBegin() + thePropDefs[idx].m_Offset); - - if (theStrPtr.IsValid()) { - QT3DSU32 index = FindAllocatedImage(theStrPtr); - if (index == QT3DSU32(-1)) { - pImage = QT3DS_NEW(m_CoreContext.GetAllocator(), SImage)(); - m_AllocatedImages.push_back(eastl::make_pair(theStrPtr, pImage)); - } else { - pImage = m_AllocatedImages[index].second; - } - - switch (thePropDefs[idx].m_TexUsageType) { - case NVRenderTextureTypeValue::Displace: - if (inMaterial.m_DisplacementMap != pImage) { - inMaterial.m_DisplacementMap = pImage; - inMaterial.m_DisplacementMap->m_ImagePath = - thePropDefs[idx].m_ImagePath; - inMaterial.m_DisplacementMap->m_ImageShaderName = - thePropDefs[idx].m_Name; // this is our name in the shader - inMaterial.m_DisplacementMap->m_VerticalTilingMode = - thePropDefs[idx].m_CoordOp; - inMaterial.m_DisplacementMap->m_HorizontalTilingMode = - thePropDefs[idx].m_CoordOp; - } - break; - case NVRenderTextureTypeValue::Emissive2: - if (inMaterial.m_EmissiveMap2 != pImage) { - inMaterial.m_EmissiveMap2 = pImage; - inMaterial.m_EmissiveMap2->m_ImagePath = thePropDefs[idx].m_ImagePath; - inMaterial.m_EmissiveMap2->m_ImageShaderName = - thePropDefs[idx].m_Name; // this is our name in the shader - inMaterial.m_EmissiveMap2->m_VerticalTilingMode = - thePropDefs[idx].m_CoordOp; - inMaterial.m_EmissiveMap2->m_HorizontalTilingMode = - thePropDefs[idx].m_CoordOp; - } - break; - default: - if (!inMaterial.m_imageMaps) - inMaterial.m_imageMaps = newImageMap(m_CoreContext.GetAllocator()); - if ((*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] != pImage) { - (*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] = pImage; - pImage->m_ImagePath = thePropDefs[idx].m_ImagePath; - pImage->m_ImageShaderName = thePropDefs[idx].m_Name; - pImage->m_VerticalTilingMode = thePropDefs[idx].m_CoordOp; - pImage->m_HorizontalTilingMode = thePropDefs[idx].m_CoordOp; - } - break; - } - } else { - switch (thePropDefs[idx].m_TexUsageType) { - case NVRenderTextureTypeValue::Displace: - inMaterial.m_DisplacementMap = nullptr; - break; - case NVRenderTextureTypeValue::Emissive2: - inMaterial.m_EmissiveMap2 = nullptr; - break; - default: - if (!inMaterial.m_imageMaps) - inMaterial.m_imageMaps = newImageMap(m_CoreContext.GetAllocator()); - (*inMaterial.m_imageMaps)[thePropDefs[idx].m_Name] = nullptr; - break; - } - } - } - } - } - virtual void PrepareDisplacementForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) { if (inMaterial.m_DisplacementMap == NULL) @@ -2024,13 +1995,11 @@ struct SMaterialSystem : public ICustomMaterialSystem for (QT3DSU32 idx = 0, end = thePropDefs.size(); idx < end; ++idx) { if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSF32 && AreEqual(thePropDefs[idx].m_Name.c_str(), "displaceAmount")) { - QT3DSF32 theValue = *reinterpret_cast<const QT3DSF32 *>(inMaterial.GetDataSectionBegin() - + thePropDefs[idx].m_Offset); + QT3DSF32 theValue = *reinterpret_cast<const QT3DSF32 *>(inMaterial.m_dynamicObject->GetDataSectionOffset(thePropDefs[idx].m_Offset)); inMaterial.m_DisplaceAmount = theValue; } else if (thePropDefs[idx].m_DataType == NVRenderShaderDataTypes::QT3DSVec3 && AreEqual(thePropDefs[idx].m_Name.c_str(), "displace_tiling")) { - QT3DSVec3 theValue = *reinterpret_cast<const QT3DSVec3 *>(inMaterial.GetDataSectionBegin() - + thePropDefs[idx].m_Offset); + QT3DSVec3 theValue = *reinterpret_cast<const QT3DSVec3 *>(inMaterial.m_dynamicObject->GetDataSectionOffset(thePropDefs[idx].m_Offset)); if (theValue.x != inMaterial.m_DisplacementMap->m_Scale.x || theValue.y != inMaterial.m_DisplacementMap->m_Scale.y) { inMaterial.m_DisplacementMap->m_Scale = QT3DSVec2(theValue.x, theValue.y); @@ -2042,8 +2011,6 @@ struct SMaterialSystem : public ICustomMaterialSystem void PrepareMaterialForRender(SMaterialClass &inClass, SCustomMaterial &inMaterial) { - PrepareTextureForRender(inClass, inMaterial); - if (inClass.m_HasDisplacement) PrepareDisplacementForRender(inClass, inMaterial); } |