From 8fc0026450fbd9c4591561874578001483cabacb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A4=C3=A4tt=C3=A4=20Antti?= Date: Thu, 31 May 2018 14:56:38 +0300 Subject: Fix lighting with custom material and shadows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two problems with the shadows. 1. The shader cache key for default materials is not properly initialized, which causes invalid shader being used for the material. 2. Custom material shadow cubes and maps uniforms are not set correctly. Only first element in those sampler arrays were set, so when custom material lighting had more then 1 light and shadows, only one light affected the rendered result. Fixed the default material key and implemented proper setters for sampler uniforms. Task-number: QT3DS-1824 Change-Id: I0b97a4642410f37011392adf1020bc1d2bd21bb3 Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää --- .../Include/render/Qt3DSRenderBaseTypes.h | 4 ++ .../Include/render/Qt3DSRenderShaderConstant.h | 48 +++++++++++++ .../Include/render/Qt3DSRenderShaderProgram.h | 54 +++++++++++++++ .../Source/Qt3DSRenderShaderProgram.cpp | 78 +++++++++++++++++++++- .../Source/backends/gl/Qt3DSRenderBackendGL4.cpp | 9 ++- .../backends/gl/Qt3DSRenderBackendGLBase.cpp | 9 ++- .../Qt3DSRendererImplLayerRenderData.cpp | 3 + ...Qt3DSRendererImplLayerRenderPreparationData.cpp | 56 ++++++++-------- .../Qt3DSRenderCustomMaterialShaderGenerator.cpp | 76 +++++++++++---------- 9 files changed, 266 insertions(+), 71 deletions(-) diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h index eb19be66..945d5084 100644 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h +++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h @@ -1667,8 +1667,10 @@ typedef NVRenderFrameBuffer *NVRenderFrameBufferPtr; typedef NVRenderVertexBuffer *NVRenderVertexBufferPtr; typedef NVRenderIndexBuffer *NVRenderIndexBufferPtr; typedef NVRenderTexture2D *NVRenderTexture2DPtr; +typedef NVRenderTexture2DPtr *NVRenderTexture2DHandle; typedef NVRenderTexture2DArray *NVRenderTexture2DArrayPtr; typedef NVRenderTextureCube *NVRenderTextureCubePtr; +typedef NVRenderTextureCubePtr *NVRenderTextureCubeHandle; typedef NVRenderImage2D *NVRenderImage2DPtr; typedef NVRenderDataBuffer *NVRenderDataBufferPtr; typedef const char *NVRenderConstCharPtr; @@ -1895,8 +1897,10 @@ DECLARE_GENERIC_VECTOR_TYPE(QT3DSI32, 4); HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat33) \ HANDLE_QT3DS_SHADER_DATA_TYPE(QT3DSMat44) \ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DPtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DHandle) \ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTexture2DArrayPtr) \ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubePtr) \ + HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderTextureCubeHandle) \ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderImage2DPtr) \ HANDLE_QT3DS_SHADER_DATA_TYPE(NVRenderDataBufferPtr) diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h index 867f9621..7fb57ffe 100644 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h +++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h @@ -122,6 +122,30 @@ namespace render { void Release() override { NVDelete(GetFoundation().getAllocator(), this); } }; + ///< A specialized class for textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + ///< A specialized class for texture arrays template <> class NVRenderShaderConstant : public NVRenderShaderConstantBase @@ -168,6 +192,30 @@ namespace render { void Release() override { NVDelete(GetFoundation().getAllocator(), this); } }; + ///< A specialized class for cubemap textures + template <> + class NVRenderShaderConstant : public NVRenderShaderConstantBase + { + public: + NVFoundationBase &m_Foundation; ///< allocator + QVector m_Value; ///< constant value + + public: + NVRenderShaderConstant(NVRenderBackend *backend, CRegisteredString name, QT3DSI32 location, + QT3DSI32 elementCount, NVRenderShaderDataTypes::Enum type, + QT3DSI32 binding, NVFoundationBase &allocator) + : NVRenderShaderConstantBase(backend, name, location, elementCount, type, binding) + , m_Foundation(allocator) + { + m_Value.resize(elementCount); + m_Value.fill(QT3DS_MAX_U32); + } + + NVFoundationBase &GetFoundation() { return m_Foundation; } + + void Release() override { NVDelete(GetFoundation().getAllocator(), this); } + }; + ///< A specialized class for texture image buffer template <> class NVRenderShaderConstant : public NVRenderShaderConstantBase diff --git a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h index f3ab2b4e..054db64b 100644 --- a/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h +++ b/src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h @@ -281,10 +281,14 @@ namespace render { const NVConstDataRef inValue, const QT3DSI32 inCount); void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D **inValue, + const QT3DSI32 inCount); void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2DArray *inValue, const QT3DSI32 inCount); void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue, const QT3DSI32 inCount); + void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube **inValue, + const QT3DSI32 inCount); void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderImage2D *inValue, const QT3DSI32 inCount); void SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderDataBuffer *inValue, @@ -445,6 +449,56 @@ namespace render { bool IsValid() const { return m_Constant != 0; } }; + template + struct NVRenderCachedShaderPropertyArray + { + NVRenderShaderProgram *m_Shader; ///< pointer to shader program + NVRenderShaderConstantBase *m_Constant; ///< poiner to shader constant object + TDataType m_array[size]; + + NVRenderCachedShaderPropertyArray(const QString &inConstantName, + NVRenderShaderProgram &inShader) + : NVRenderCachedShaderPropertyArray(qPrintable(inConstantName), inShader) + { + + } + + NVRenderCachedShaderPropertyArray(const char *inConstantName, + NVRenderShaderProgram &inShader) + : m_Shader(&inShader) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + NVRenderShaderConstantBase *theConstant = inShader.GetShaderConstant(inConstantName); + if (theConstant) { + if (theConstant->m_ElementCount > 1 && theConstant->m_ElementCount <= size && + theConstant->GetShaderConstantType() + == NVDataTypeToShaderDataTypeMap::GetType()) { + m_Constant = theConstant; + } else { + // Property types do not match, this probably indicates that the shader changed + // while the code creating this object did not change. + QT3DS_ASSERT(false); + } + } + } + + NVRenderCachedShaderPropertyArray() + : m_Shader(nullptr) + , m_Constant(nullptr) + { + memset(m_array, 0, sizeof(m_array)); + } + + void Set(int count) + { + if (m_Constant) + m_Shader->SetPropertyValue(m_Constant, (TDataType*)m_array, qMin(size, count)); + } + + bool IsValid() const { return m_Constant != 0; } + }; + // Helper class to cache the lookup of shader properties and apply them quickly in a typesafe // way. template diff --git a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp index a11207f4..3e5da0d6 100644 --- a/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp +++ b/src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp @@ -342,6 +342,35 @@ namespace render { } }; + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTexture2DHandle inValue, QVector &oldValue) + { + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTexture2D *texObj = reinterpret_cast(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTexture2DPtr, + count, oldValue.data()); + } + } + }; + template <> struct ShaderConstantApplier { @@ -383,6 +412,35 @@ namespace render { } }; + template <> + struct ShaderConstantApplier + { + void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, + QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type, + NVRenderTextureCubeHandle inValue, QVector &oldValue) + { + if (inValue) { + bool update = false; + for (int i = 0; i < count; i++) { + NVRenderTextureCube *texObj = reinterpret_cast(inValue[i]); + QT3DSU32 texUnit = QT3DS_MAX_U32; + if (texObj) { + texObj->Bind(); + texUnit = texObj->GetTextureUnit(); + } + if (texUnit != oldValue[i]) { + update = true; + oldValue[i] = texUnit; + } + } + if (update) + backend->SetConstantValue(program->GetShaderProgramHandle(), location, + NVRenderShaderDataTypes::NVRenderTextureCubePtr, + count, oldValue.data()); + } + } + }; + template <> struct ShaderConstantApplier { @@ -509,9 +567,15 @@ namespace render { location = m_Backend->GetConstantInfoByID(m_ProgramHandle, idx, 512, &elementCount, &type, &binding, nameBuf); + // sampler arrays have different type + if (type == NVRenderShaderDataTypes::NVRenderTexture2DPtr && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTexture2DHandle; + } else if (type == NVRenderShaderDataTypes::NVRenderTextureCubePtr + && elementCount > 1) { + type = NVRenderShaderDataTypes::NVRenderTextureCubeHandle; + } if (location != -1) { CRegisteredString theName(m_Context.GetStringTable().RegisterStr(nameBuf)); - m_Constants.insert(eastl::make_pair( theName, ShaderConstantFactory(m_Backend, theName, m_Context.GetFoundation(), @@ -841,6 +905,12 @@ namespace render { } void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTexture2D *inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTexture2D **inValue, + const QT3DSI32 inCount) { SetConstantValueOfType(this, inConstant, inValue, inCount); } @@ -852,6 +922,12 @@ namespace render { } void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, NVRenderTextureCube *inValue, const QT3DSI32 inCount) + { + SetConstantValueOfType(this, inConstant, inValue, 1); + } + void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant, + NVRenderTextureCube **inValue, + const QT3DSI32 inCount) { SetConstantValueOfType(this, inConstant, inValue, inCount); } diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp index 47a26e7f..08ff9bb0 100644 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp +++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp @@ -513,8 +513,13 @@ namespace render { case GL_SAMPLER_2D_ARRAY: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE: { - GLint sampler = *(GLint *)value; - GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); + if (count <= 1) { + GLint sampler = *(GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1i(programID, id, sampler)); + } else { + GLint *sampler = (GLint *)value; + GL_CALL_EXTRA_FUNCTION(glProgramUniform1iv(programID, id, count, sampler)); + } } break; default: qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); diff --git a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp index 7a780e24..0fb26b35 100644 --- a/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp +++ b/src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp @@ -1962,8 +1962,13 @@ namespace render { case GL_SAMPLER_2D_ARRAY: case GL_SAMPLER_2D_SHADOW: case GL_SAMPLER_CUBE: { - GLint sampler = *(GLint *)value; - GL_CALL_FUNCTION(glUniform1i(id, sampler)); + if (count > 1) { + GLint *sampler = (GLint *)value; + GL_CALL_FUNCTION(glUniform1iv(id, count, sampler)); + } else { + GLint sampler = *(GLint *)value; + GL_CALL_FUNCTION(glUniform1i(id, sampler)); + } } break; default: qCCritical(INTERNAL_ERROR, "Unknown shader type format %d", type); diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp index 52423df3..51bff7f4 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp @@ -693,6 +693,9 @@ namespace render { | qt3ds::render::NVRenderClearValues::Color); for (QT3DSU32 i = 0; i < m_Lights.size(); i++) { + // don't render shadows when not casting + if (m_Lights[i]->m_CastShadow == false) + continue; SShadowMapEntry *pEntry = m_ShadowMapManager->GetShadowMapEntry(i); if (pEntry && pEntry->m_DepthMap && pEntry->m_DepthCopy && pEntry->m_DepthRender) { SCamera theCamera; diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp index 3275d889..aa1606d6 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp @@ -319,13 +319,14 @@ namespace render { SLayerRenderPreparationData::GenerateLightingKey(DefaultMaterialLighting::Enum inLightingType) { SShaderDefaultMaterialKey theGeneratedKey(GetShaderFeatureSetHash()); - if (inLightingType != DefaultMaterialLighting::NoLighting) { - m_Renderer.DefaultMaterialShaderKeyProperties().m_HasLighting.SetValue(theGeneratedKey, - true); - - if (m_Layer.m_LightProbe && m_Layer.m_LightProbe->m_TextureData.m_Texture) - m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, - true); + const bool lighting = inLightingType != DefaultMaterialLighting::NoLighting; + m_Renderer.DefaultMaterialShaderKeyProperties().m_HasLighting.SetValue(theGeneratedKey, + lighting); + if (lighting) { + const bool lightProbe = m_Layer.m_LightProbe + && m_Layer.m_LightProbe->m_TextureData.m_Texture; + m_Renderer.DefaultMaterialShaderKeyProperties().m_HasIbl.SetValue(theGeneratedKey, + lightProbe); QT3DSU32 numLights = (QT3DSU32)m_Lights.size(); if (numLights > SShaderDefaultMaterialKeyProperties::LightCount @@ -338,19 +339,20 @@ namespace render { m_Renderer.DefaultMaterialShaderKeyProperties().m_LightCount.SetValue(theGeneratedKey, numLights); - for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); lightIdx < lightEnd; ++lightIdx) { + for (QT3DSU32 lightIdx = 0, lightEnd = m_Lights.size(); + lightIdx < lightEnd; ++lightIdx) { SLight *theLight(m_Lights[lightIdx]); - if (theLight->m_LightType != RenderLightTypes::Directional) - m_Renderer.DefaultMaterialShaderKeyProperties().m_LightFlags[lightIdx].SetValue( - theGeneratedKey, true); - if (theLight->m_LightType == RenderLightTypes::Area) - m_Renderer.DefaultMaterialShaderKeyProperties() - .m_LightAreaFlags[lightIdx] - .SetValue(theGeneratedKey, true); - if ((theLight->m_LightType != RenderLightTypes::Point) && (theLight->m_CastShadow)) - m_Renderer.DefaultMaterialShaderKeyProperties() - .m_LightShadowFlags[lightIdx] - .SetValue(theGeneratedKey, true); + const bool isDirectional = theLight->m_LightType == RenderLightTypes::Directional; + const bool isArea = theLight->m_LightType == RenderLightTypes::Area; + const bool castShadowsArea = (theLight->m_LightType != RenderLightTypes::Area) + && (theLight->m_CastShadow); + + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightFlags[lightIdx] + .SetValue(theGeneratedKey, !isDirectional); + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightAreaFlags[lightIdx] + .SetValue(theGeneratedKey, isArea); + m_Renderer.DefaultMaterialShaderKeyProperties().m_LightShadowFlags[lightIdx] + .SetValue(theGeneratedKey, castShadowsArea); } } return theGeneratedKey; @@ -682,22 +684,18 @@ namespace render { } bool specularEnabled = theMaterial->IsSpecularEnabled(); + m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularEnabled.SetValue( + theGeneratedKey, specularEnabled); if (specularEnabled) { - m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularEnabled.SetValue( - theGeneratedKey, true); m_Renderer.DefaultMaterialShaderKeyProperties().m_SpecularModel.SetSpecularModel( theGeneratedKey, theMaterial->m_SpecularModel); } - if (theMaterial->IsFresnelEnabled()) { - m_Renderer.DefaultMaterialShaderKeyProperties().m_FresnelEnabled.SetValue( - theGeneratedKey, true); - } + m_Renderer.DefaultMaterialShaderKeyProperties().m_FresnelEnabled.SetValue( + theGeneratedKey, theMaterial->IsFresnelEnabled()); - if (theMaterial->IsVertexColorsEnabled()) { - m_Renderer.DefaultMaterialShaderKeyProperties().m_VertexColorsEnabled.SetValue( - theGeneratedKey, true); - } + m_Renderer.DefaultMaterialShaderKeyProperties().m_VertexColorsEnabled.SetValue( + theGeneratedKey, theMaterial->IsVertexColorsEnabled()); // Run through the material's images and prepare them for render. // this may in fact set pickable on the renderable flags if one of the images diff --git a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp index 43df5172..37244978 100644 --- a/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp +++ b/src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp @@ -181,6 +181,14 @@ struct SShaderGeneratorGeneratedShader SLightConstantProperties *m_lightsProperties; SLightConstantProperties *m_areaLightsProperties; + typedef NVRenderCachedShaderPropertyArray ShadowMapPropertyArray; + typedef NVRenderCachedShaderPropertyArray ShadowCubePropertyArray; + + ShadowMapPropertyArray m_shadowMaps; + ShadowCubePropertyArray m_shadowCubes; + // Cache the image property name lookups TCustomMaterialImagMap m_Images; // Images external to custom material usage volatile QT3DSI32 m_RefCount; @@ -215,6 +223,8 @@ struct SShaderGeneratorGeneratedShader , m_AreaLightsBuffer("cbBufferAreaLights", inShader) , m_lightsProperties(nullptr) , m_areaLightsProperties(nullptr) + , m_shadowMaps("shadowMaps[0]", inShader) + , m_shadowCubes("shadowCubes[0]", inShader) , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") , m_RefCount(0) { @@ -297,8 +307,6 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator TProgramToShaderMap m_ProgramToShaderMap; nvvector m_LightEntries; - nvvector m_ShadowMapEntries; - nvvector m_ShadowCubeEntries; TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers @@ -314,8 +322,6 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator , m_HasTransparency(false) , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") , m_LightEntries(inRc.GetAllocator(), "m_LightEntries") - , m_ShadowMapEntries(inRc.GetAllocator(), "m_ShadowMapEntries") - , m_ShadowCubeEntries(inRc.GetAllocator(), "m_ShadowCubeEntries") , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") , m_RefCount(0) { @@ -467,11 +473,12 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator return NULL; } // init first set - memset(&s[0], 0x0, sizeof(SLightSourceShader)); - QT3DSI32 cgLights = 0; - pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); + memset(&s[0], 0x0, sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS); + QT3DSI32 cgLights[4] = {0, 0, 0, 0}; + pCB->UpdateRaw(0, NVDataRef((QT3DSU8 *)&cgLights, sizeof(QT3DSI32) * 4)); pCB->UpdateRaw(4 * sizeof(QT3DSI32), - NVDataRef((QT3DSU8 *)&s[0], sizeof(SLightSourceShader))); + NVDataRef((QT3DSU8 *)&s[0], + sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS)); pCB->Update(); // update to hardware m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); @@ -553,33 +560,18 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator } void SetShadowMaps(NVRenderShaderProgram &inProgram, SShadowMapEntry *inShadow, - QT3DSI32 &numShadowMaps, QT3DSI32 &numShadowCubes) + QT3DSI32 &numShadowMaps, QT3DSI32 &numShadowCubes, bool shadowMap, + SShaderGeneratorGeneratedShader::ShadowMapPropertyArray &shadowMaps, + SShaderGeneratorGeneratedShader::ShadowCubePropertyArray &shadowCubes) { if (inShadow) { - eastl::string shadowName; - if (inShadow->m_DepthCube && (numShadowCubes < QT3DS_MAX_NUM_SHADOWS)) { - shadowName = "shadowCubes"; - char buf[16]; - _snprintf(buf, 16, "[%d]", numShadowCubes); - shadowName.append(buf); - - NVRenderCachedShaderProperty theNewEntry(shadowName.c_str(), - inProgram); - theNewEntry.Set(inShadow->m_DepthCube); - m_ShadowCubeEntries.push_back(eastl::make_pair(numShadowCubes, theNewEntry)); - + if (shadowMap == false && inShadow->m_DepthCube + && (numShadowCubes < QT3DS_MAX_NUM_SHADOWS)) { + shadowCubes.m_array[numShadowCubes] = inShadow->m_DepthCube.mPtr; ++numShadowCubes; - } else if (inShadow->m_DepthMap && (numShadowMaps < QT3DS_MAX_NUM_SHADOWS)) { - shadowName = "shadowMaps"; - char buf[16]; - _snprintf(buf, 16, "[%d]", numShadowMaps); - shadowName.append(buf); - - NVRenderCachedShaderProperty theNewEntry(shadowName.c_str(), - inProgram); - theNewEntry.Set(inShadow->m_DepthMap); - m_ShadowMapEntries.push_back(eastl::make_pair(numShadowMaps, theNewEntry)); - + } else if (shadowMap && inShadow->m_DepthMap + && (numShadowMaps < QT3DS_MAX_NUM_SHADOWS)) { + shadowMaps.m_array[numShadowMaps] = inShadow->m_DepthMap.mPtr; ++numShadowMaps; } } @@ -624,14 +616,16 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator // Split the count between CG lights and area lights for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size() && pLightCb; ++lightIdx) { SShadowMapEntry *theShadow = NULL; - if (inShadowMaps) + if (inShadowMaps && inLights[lightIdx]->m_CastShadow) theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType != RenderLightTypes::Directional) ? numShadowCubes : numShadowMaps; - SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes); + SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, + inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, + theShader.m_shadowMaps, theShader.m_shadowCubes); if (inLights[lightIdx]->m_LightType == RenderLightTypes::Area) { SShaderLightProperties *theAreaLightEntry = @@ -677,17 +671,19 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator } else { QVector lprop; QVector alprop; - for (int lightIdx = 0; lightIdx < inLights.size(); ++lightIdx) { + for (QT3DSU32 lightIdx = 0; lightIdx < inLights.size(); ++lightIdx) { SShadowMapEntry *theShadow = NULL; - if (inShadowMaps) + if (inShadowMaps && inLights[lightIdx]->m_CastShadow) theShadow = inShadowMaps->GetShadowMapEntry(lightIdx); QT3DSI32 shdwIdx = (inLights[lightIdx]->m_LightType != RenderLightTypes::Directional) ? numShadowCubes : numShadowMaps; - SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes); + SetShadowMaps(inProgram, theShadow, numShadowMaps, numShadowCubes, + inLights[lightIdx]->m_LightType == RenderLightTypes::Directional, + theShader.m_shadowMaps, theShader.m_shadowCubes); SShaderLightProperties *p = SetLight(inProgram, lightIdx, areaLights, inLights[lightIdx], theShadow, @@ -708,6 +704,12 @@ struct SShaderGenerator : public ICustomMaterialShaderGenerator theShader.m_LightCount.Set(lprop.size()); theShader.m_AreaLightCount.Set(alprop.size()); } + for (int i = numShadowMaps; i < QT3DS_MAX_NUM_SHADOWS; ++i) + theShader.m_shadowMaps.m_array[i] = NULL; + for (int i = numShadowCubes; i < QT3DS_MAX_NUM_SHADOWS; ++i) + theShader.m_shadowCubes.m_array[i] = NULL; + theShader.m_shadowMaps.Set(numShadowMaps); + theShader.m_shadowCubes.Set(numShadowCubes); theShader.m_ShadowMapCount.Set(numShadowMaps); theShader.m_ShadowCubeCount.Set(numShadowCubes); } -- cgit v1.2.3