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ää --- .../Qt3DSRenderCustomMaterialShaderGenerator.cpp | 76 +++++++++++----------- 1 file changed, 39 insertions(+), 37 deletions(-) (limited to 'src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp') 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