summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMäättä Antti <antti.maatta@qt.io>2018-05-31 14:56:38 +0300
committerTomi Korpipää <tomi.korpipaa@qt.io>2018-06-01 04:08:54 +0000
commit8fc0026450fbd9c4591561874578001483cabacb (patch)
treeb27c5e2b53b5d4a6b4df26e57cb6a43fdf8dc5ce
parenta465515bcd856d355f92255d4c0034e0d2aeda24 (diff)
Fix lighting with custom material and shadows
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 <miikka.heikkinen@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderBaseTypes.h4
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderConstant.h48
-rw-r--r--src/Runtime/Source/Qt3DSRender/Include/render/Qt3DSRenderShaderProgram.h54
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/Qt3DSRenderShaderProgram.cpp78
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGL4.cpp9
-rw-r--r--src/Runtime/Source/Qt3DSRender/Source/backends/gl/Qt3DSRenderBackendGLBase.cpp9
-rw-r--r--src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderData.cpp3
-rw-r--r--src/Runtime/Source/Qt3DSRuntimeRender/RendererImpl/Qt3DSRendererImplLayerRenderPreparationData.cpp56
-rw-r--r--src/Runtime/Source/Qt3DSRuntimeRender/Source/Qt3DSRenderCustomMaterialShaderGenerator.cpp76
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<NVRenderTexture2DHandle> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QVector<QT3DSU32> 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<NVRenderTexture2DArrayPtr> : public NVRenderShaderConstantBase
@@ -168,6 +192,30 @@ namespace render {
void Release() override { NVDelete(GetFoundation().getAllocator(), this); }
};
+ ///< A specialized class for cubemap textures
+ template <>
+ class NVRenderShaderConstant<NVRenderTextureCubeHandle> : public NVRenderShaderConstantBase
+ {
+ public:
+ NVFoundationBase &m_Foundation; ///< allocator
+ QVector<QT3DSU32> 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<NVRenderImage2DPtr> : 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<QT3DSMat44> 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 <typename TDataType, int size>
+ 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<TDataType*>::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 <typename TDataType>
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
@@ -343,6 +343,35 @@ namespace render {
};
template <>
+ struct ShaderConstantApplier<NVRenderTexture2DHandle>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend,
+ QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTexture2DHandle inValue, QVector<QT3DSU32> &oldValue)
+ {
+ if (inValue) {
+ bool update = false;
+ for (int i = 0; i < count; i++) {
+ NVRenderTexture2D *texObj = reinterpret_cast<NVRenderTexture2D *>(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<NVRenderTexture2DArrayPtr>
{
void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
@@ -384,6 +413,35 @@ namespace render {
};
template <>
+ struct ShaderConstantApplier<NVRenderTextureCubeHandle>
+ {
+ void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend,
+ QT3DSI32 location, QT3DSI32 count, NVRenderShaderDataTypes::Enum type,
+ NVRenderTextureCubeHandle inValue, QVector<QT3DSU32> &oldValue)
+ {
+ if (inValue) {
+ bool update = false;
+ for (int i = 0; i < count; i++) {
+ NVRenderTextureCube *texObj = reinterpret_cast<NVRenderTextureCube *>(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<NVRenderImage2DPtr>
{
void ApplyConstant(NVRenderShaderProgram *program, NVRenderBackend *backend, QT3DSI32 location,
@@ -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(),
@@ -842,6 +906,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);
}
void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
@@ -853,6 +923,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);
}
void NVRenderShaderProgram::SetConstantValue(NVRenderShaderConstantBase *inConstant,
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<SShaderGeneratorGeneratedShader> *m_lightsProperties;
SLightConstantProperties<SShaderGeneratorGeneratedShader> *m_areaLightsProperties;
+ typedef NVRenderCachedShaderPropertyArray<NVRenderTexture2D *,
+ QT3DS_MAX_NUM_SHADOWS> ShadowMapPropertyArray;
+ typedef NVRenderCachedShaderPropertyArray<NVRenderTextureCube *,
+ QT3DS_MAX_NUM_SHADOWS> 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<TCustomMaterialLightEntry> m_LightEntries;
- nvvector<TShadowMapEntry> m_ShadowMapEntries;
- nvvector<TShadowCubeEntry> 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>((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>((QT3DSU8 *)&cgLights, sizeof(QT3DSI32) * 4));
pCB->UpdateRaw(4 * sizeof(QT3DSI32),
- NVDataRef<QT3DSU8>((QT3DSU8 *)&s[0], sizeof(SLightSourceShader)));
+ NVDataRef<QT3DSU8>((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<NVRenderTextureCube *> 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<NVRenderTexture2D *> 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<SShaderLightProperties *> lprop;
QVector<SShaderLightProperties *> 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);
}