diff options
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp')
m--------- | src/Runtime/ogl-runtime | 0 | ||||
-rw-r--r-- | src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp | 1931 |
2 files changed, 0 insertions, 1931 deletions
diff --git a/src/Runtime/ogl-runtime b/src/Runtime/ogl-runtime new file mode 160000 +Subproject 2025912174c4cf99270b7439ec3b021e1d089ae diff --git a/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp b/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp deleted file mode 100644 index 221f3296..00000000 --- a/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp +++ /dev/null @@ -1,1931 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2012 NVIDIA Corporation. -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt 3D Studio. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "Qt3DSRenderDefaultMaterialShaderGenerator.h" -#include "foundation/Qt3DSAtomic.h" -#include "Qt3DSRenderContextCore.h" -#include "Qt3DSRenderShaderCodeGeneratorV2.h" -#include "Qt3DSRenderableImage.h" -#include "Qt3DSRenderImage.h" -#include "render/Qt3DSRenderContext.h" -#include "Qt3DSRenderLight.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderCamera.h" -#include "Qt3DSRenderShadowMap.h" -#include "Qt3DSRenderCustomMaterial.h" -#include "Qt3DSRenderDynamicObjectSystem.h" -#include "render/Qt3DSRenderShaderProgram.h" -#include "Qt3DSRenderLightConstantProperties.h" - -using namespace qt3ds::render; -using qt3ds::render::NVRenderCachedShaderProperty; -using qt3ds::render::NVRenderCachedShaderBuffer; - -namespace { - -const QT3DSF32 MINATTENUATION = 0; -const QT3DSF32 MAXATTENUATION = 1000; - -QT3DSF32 ClampFloat(QT3DSF32 value, QT3DSF32 min, QT3DSF32 max) -{ - return value < min ? min : ((value > max) ? max : value); -} - -QT3DSF32 TranslateConstantAttenuation(QT3DSF32 attenuation) -{ - return attenuation * .01f; -} - -QT3DSF32 TranslateLinearAttenuation(QT3DSF32 attenuation) -{ - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0001f; -} - -QT3DSF32 TranslateQuadraticAttenuation(QT3DSF32 attenuation) -{ - attenuation = ClampFloat(attenuation, MINATTENUATION, MAXATTENUATION); - return attenuation * 0.0000001f; -} - -/** - * Cached texture property lookups, used one per texture so a shader generator for N - * textures will have an array of N of these lookup objects. - */ -struct SShaderTextureProperties -{ - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_Sampler; - NVRenderCachedShaderProperty<QT3DSVec3> m_Offsets; - NVRenderCachedShaderProperty<QT3DSVec4> m_Rotations; - NVRenderCachedShaderProperty<QT3DSVec2> m_Size; - SShaderTextureProperties(const char *sampName, const char *offName, const char *rotName, - const char *sizeName, - NVRenderShaderProgram &inShader) - : m_Sampler(sampName, inShader) - , m_Offsets(offName, inShader) - , m_Rotations(rotName, inShader) - , m_Size(sizeName, inShader) - { - } - SShaderTextureProperties() {} -}; - -/** - * Cached light property lookups, used one per light so a shader generator for N - * lights will have an array of N of these lookup objects. - */ -struct SShaderLightProperties -{ - // Color of the light - QT3DSVec4 m_LightColor; - SLightSourceShader m_LightData; - - SShaderLightProperties() {} -}; - -struct SShadowMapProperties -{ - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_ShadowmapTexture; ///< shadow texture - NVRenderCachedShaderProperty<NVRenderTextureCube *> m_ShadowCubeTexture; ///< shadow cubemap - NVRenderCachedShaderProperty<QT3DSMat44> - m_ShadowmapMatrix; ///< world to ligh space transform matrix - NVRenderCachedShaderProperty<QT3DSVec4> m_ShadowmapSettings; ///< shadow rendering settings - - SShadowMapProperties() {} - SShadowMapProperties(const char *shadowmapTextureName, const char *shadowcubeTextureName, - const char *shadowmapMatrixName, const char *shadowmapSettingsName, - NVRenderShaderProgram &inShader) - : m_ShadowmapTexture(shadowmapTextureName, inShader) - , m_ShadowCubeTexture(shadowcubeTextureName, inShader) - , m_ShadowmapMatrix(shadowmapMatrixName, inShader) - , m_ShadowmapSettings(shadowmapSettingsName, inShader) - { - } -}; - -/** - * The results of generating a shader. Caches all possible variable names into - * typesafe objects. - */ -struct SShaderGeneratorGeneratedShader -{ - NVAllocatorCallback &m_Allocator; - NVRenderShaderProgram &m_Shader; - // Specific properties we know the shader has to have. - NVRenderCachedShaderProperty<QT3DSMat44> m_MVP; - NVRenderCachedShaderProperty<QT3DSMat33> m_NormalMatrix; - NVRenderCachedShaderProperty<QT3DSMat44> m_GlobalTransform; - NVRenderCachedShaderProperty<QT3DSMat44> m_ViewProj; - NVRenderCachedShaderProperty<QT3DSMat44> m_ViewMatrix; - NVRenderCachedShaderProperty<QT3DSVec4> m_MaterialDiffuse; - NVRenderCachedShaderProperty<QT3DSVec4> m_MaterialProperties; - // tint, ior - NVRenderCachedShaderProperty<QT3DSVec4> m_MaterialSpecular; - NVRenderCachedShaderProperty<QT3DSF32> m_BumpAmount; - NVRenderCachedShaderProperty<QT3DSF32> m_DisplaceAmount; - NVRenderCachedShaderProperty<QT3DSF32> m_TranslucentFalloff; - NVRenderCachedShaderProperty<QT3DSF32> m_DiffuseLightWrap; - NVRenderCachedShaderProperty<QT3DSF32> m_FresnelPower; - NVRenderCachedShaderProperty<QT3DSVec3> m_DiffuseColor; - NVRenderCachedShaderProperty<QT3DSVec3> m_CameraPosition; - NVRenderCachedShaderProperty<QT3DSVec3> m_CameraDirection; - QT3DSVec3 m_LightAmbientTotal; - NVRenderCachedShaderProperty<QT3DSVec3> m_MaterialDiffuseLightAmbientTotal; - NVRenderCachedShaderProperty<QT3DSVec2> m_CameraProperties; - - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_DepthTexture; - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_AOTexture; - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_LightProbe; - NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeProps; - NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOpts; - NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeRot; - NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbeOfs; - NVRenderCachedShaderProperty<QT3DSVec2> m_LightProbeSize; - NVRenderCachedShaderProperty<NVRenderTexture2D *> m_LightProbe2; - NVRenderCachedShaderProperty<QT3DSVec4> m_LightProbe2Props; - NVRenderCachedShaderProperty<QT3DSVec2> m_LightProbe2Size; - - NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_AoShadowParams; - NVRenderCachedShaderBuffer<qt3ds::render::NVRenderShaderConstantBuffer *> m_LightsBuffer; - - SLightConstantProperties<SShaderGeneratorGeneratedShader> *m_lightConstantProperties; - - // Cache the image property name lookups - nvvector<SShaderTextureProperties> m_Images; - nvvector<SShaderLightProperties> m_Lights; - // Cache shadow map properties - nvvector<SShadowMapProperties> m_ShadowMaps; - - QT3DSI32 m_RefCount; - - SShaderGeneratorGeneratedShader(NVRenderShaderProgram &inShader, NVRenderContext &inContext) - : m_Allocator(inContext.GetAllocator()) - , m_Shader(inShader) - , m_MVP("model_view_projection", inShader) - , m_NormalMatrix("normal_matrix", inShader) - , m_GlobalTransform("model_matrix", inShader) - , m_ViewProj("view_projection_matrix", inShader) - , m_ViewMatrix("view_matrix", inShader) - , m_MaterialDiffuse("material_diffuse", inShader) - , m_MaterialProperties("material_properties", inShader) - , m_MaterialSpecular("material_specular", inShader) - , m_BumpAmount("bumpAmount", inShader) - , m_DisplaceAmount("displaceAmount", inShader) - , m_TranslucentFalloff("translucentFalloff", inShader) - , m_DiffuseLightWrap("diffuseLightWrap", inShader) - , m_FresnelPower("fresnelPower", inShader) - , m_DiffuseColor("diffuse_color", inShader) - , m_CameraPosition("camera_position", inShader) - , m_CameraDirection("camera_direction", inShader) - , m_MaterialDiffuseLightAmbientTotal("light_ambient_total", inShader) - , m_CameraProperties("camera_properties", inShader) - , m_DepthTexture("depth_sampler", inShader) - , m_AOTexture("ao_sampler", inShader) - , m_LightProbe("light_probe", inShader) - , m_LightProbeProps("light_probe_props", inShader) - , m_LightProbeOpts("light_probe_opts", inShader) - , m_LightProbeRot("light_probe_rotation", inShader) - , m_LightProbeOfs("light_probe_offset", inShader) - , m_LightProbeSize("light_probe_size", inShader) - , m_LightProbe2("light_probe2", inShader) - , m_LightProbe2Props("light_probe2_props", inShader) - , m_LightProbe2Size("light_probe2_size", inShader) - , m_AoShadowParams("cbAoShadow", inShader) - , m_LightsBuffer("cbBufferLights", inShader) - , m_lightConstantProperties(NULL) - , m_Images(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Images") - , m_Lights(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_Lights") - , m_ShadowMaps(inContext.GetAllocator(), "SShaderGeneratorGeneratedShader::m_ShadowMaps") - , m_RefCount(0) - { - m_Shader.addRef(); - } - ~SShaderGeneratorGeneratedShader() - { - if (m_lightConstantProperties) - delete m_lightConstantProperties; - m_Shader.release(); - } - - void addRef() { ++m_RefCount; } - void release() - { - --m_RefCount; - if (m_RefCount <= 0) { - NVAllocatorCallback &alloc(m_Allocator); - NVDelete(alloc, this); - } - } -}; - - -#ifndef EA_PLATFORM_WINDOWS -#define _snprintf snprintf -#endif - -struct SShaderGenerator : public IDefaultMaterialShaderGenerator -{ - typedef Qt3DSString TStrType; - typedef nvhash_map<NVRenderShaderProgram *, NVScopedRefCounted<SShaderGeneratorGeneratedShader>> - TProgramToShaderMap; - typedef qt3ds::foundation::nvhash_map<CRegisteredString, - NVScopedRefCounted<qt3ds::render::NVRenderConstantBuffer>> - TStrConstanBufMap; - - IQt3DSRenderContext &m_RenderContext; - IShaderProgramGenerator &m_ProgramGenerator; - - const SDefaultMaterial *m_CurrentMaterial; - SShaderDefaultMaterialKey *m_CurrentKey; - Qt3DSShadowMap *m_ShadowMapManager; - IDefaultMaterialVertexPipeline *m_CurrentPipeline; - TShaderFeatureSet m_CurrentFeatureSet; - NVDataRef<SLight *> m_Lights; - SRenderableImage *m_FirstImage; - bool m_HasTransparency; - bool m_LightsAsSeparateUniforms; - - TStrType m_ImageStem; - TStrType m_ImageSampler; - TStrType m_ImageOffsets; - TStrType m_ImageRotations; - TStrType m_ImageFragCoords; - TStrType m_ImageTemp; - TStrType m_ImageSamplerSize; - - TStrType m_TexCoordTemp; - - TStrType m_LightStem; - TStrType m_LightColor; - TStrType m_LightSpecularColor; - TStrType m_LightAttenuation; - TStrType m_LightConstantAttenuation; - TStrType m_LightLinearAttenuation; - TStrType m_LightQuadraticAttenuation; - TStrType m_NormalizedDirection; - TStrType m_LightDirection; - TStrType m_LightPos; - TStrType m_LightUp; - TStrType m_LightRt; - TStrType m_RelativeDistance; - TStrType m_RelativeDirection; - - TStrType m_ShadowMapStem; - TStrType m_ShadowCubeStem; - TStrType m_ShadowMatrixStem; - TStrType m_ShadowCoordStem; - TStrType m_ShadowControlStem; - - TStrType m_TempStr; - - eastl::string m_GeneratedShaderString; - - SShaderDefaultMaterialKeyProperties m_DefaultMaterialShaderKeyProperties; - TProgramToShaderMap m_ProgramToShaderMap; - - TStrConstanBufMap m_ConstantBuffers; ///< store all constants buffers - - QT3DSI32 m_RefCount; - - SShaderGenerator(IQt3DSRenderContext &inRc) - : m_RenderContext(inRc) - , m_ProgramGenerator(m_RenderContext.GetShaderProgramGenerator()) - , m_CurrentMaterial(NULL) - , m_CurrentKey(NULL) - , m_ShadowMapManager(NULL) - , m_CurrentPipeline(NULL) - , m_FirstImage(NULL) - , m_LightsAsSeparateUniforms(false) - , m_ProgramToShaderMap(inRc.GetAllocator(), "m_ProgramToShaderMap") - , m_ConstantBuffers(inRc.GetAllocator(), "m_ConstantBuffers") - , m_RefCount(0) - { - } - - void addRef() override { atomicIncrement(&m_RefCount); } - void release() override - { - atomicDecrement(&m_RefCount); - if (m_RefCount <= 0) { - m_ConstantBuffers.clear(); - NVDelete(m_RenderContext.GetAllocator(), this); - } - } - IShaderProgramGenerator &ProgramGenerator() { return m_ProgramGenerator; } - IDefaultMaterialVertexPipeline &VertexGenerator() { return *m_CurrentPipeline; } - IShaderStageGenerator &FragmentGenerator() - { - return *m_ProgramGenerator.GetStage(ShaderGeneratorStages::Fragment); - } - SShaderDefaultMaterialKey &Key() { return *m_CurrentKey; } - const SDefaultMaterial &Material() { return *m_CurrentMaterial; } - TShaderFeatureSet FeatureSet() { return m_CurrentFeatureSet; } - bool HasTransparency() { return m_HasTransparency; } - - void addFunction(IShaderStageGenerator &generator, QString functionName) - { - generator.AddFunction(functionName); - } - - void SetupImageVariableNames(size_t imageIdx) - { - m_ImageStem = "image"; - char buf[16]; - _snprintf(buf, 16, "%d", int(imageIdx)); - m_ImageStem.append(buf); - m_ImageStem.append("_"); - - m_ImageSampler = m_ImageStem; - m_ImageSampler.append("sampler"); - m_ImageOffsets = m_ImageStem; - m_ImageOffsets.append("offsets"); - m_ImageRotations = m_ImageStem; - m_ImageRotations.append("rotations"); - m_ImageFragCoords = m_ImageStem; - m_ImageFragCoords.append("uv_coords"); - m_ImageSamplerSize = m_ImageStem; - m_ImageSamplerSize.append("size"); - } - - void SetupTexCoordVariableName(size_t uvSet) - { - m_TexCoordTemp = "varTexCoord"; - char buf[16]; - _snprintf(buf, 16, "%d", int(uvSet)); - m_TexCoordTemp.append(buf); - } - - SImageVariableNames GetImageVariableNames(QT3DSU32 inIdx) override - { - SetupImageVariableNames(inIdx); - SImageVariableNames retval; - retval.m_ImageSampler = m_ImageSampler.c_str(); - retval.m_ImageFragCoords = m_ImageFragCoords.c_str(); - return retval; - } - - void AddLocalVariable(IShaderStageGenerator &inGenerator, const char8_t *inName, - const char8_t *inType) - { - inGenerator << "\t" << inType << " " << inName << ";" << Endl; - } - - void AddLocalVariable(IShaderStageGenerator &inGenerator, const TStrType &inName, - const char8_t *inType) - { - AddLocalVariable(inGenerator, inName.c_str(), inType); - } - - void GenerateImageUVCoordinates(IShaderStageGenerator &inVertexPipeline, QT3DSU32 idx, QT3DSU32 uvSet, - SRenderableImage &image) override - { - IDefaultMaterialVertexPipeline &vertexShader( - static_cast<IDefaultMaterialVertexPipeline &>(inVertexPipeline)); - IShaderStageGenerator &fragmentShader(FragmentGenerator()); - SetupImageVariableNames(idx); - SetupTexCoordVariableName(uvSet); - fragmentShader.AddUniform(m_ImageSampler, "sampler2D"); - vertexShader.AddUniform(m_ImageOffsets, "vec3"); - fragmentShader.AddUniform(m_ImageOffsets, "vec3"); - vertexShader.AddUniform(m_ImageRotations, "vec4"); - fragmentShader.AddUniform(m_ImageRotations, "vec4"); - - if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { - vertexShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " - << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; - vertexShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " - << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; - vertexShader.AddOutgoing(m_ImageFragCoords, "vec2"); - addFunction(vertexShader, "getTransformedUVCoords"); - vertexShader.GenerateUVCoords(uvSet); - m_ImageTemp = m_ImageFragCoords; - m_ImageTemp.append("temp"); - vertexShader << "\tvec2 " << m_ImageTemp << " = getTransformedUVCoords( vec3( " - << m_TexCoordTemp << ", 1.0), uTransform, vTransform );" << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - vertexShader << "\t" << m_ImageTemp << ".y = 1.0 - " << m_ImageFragCoords << ".y;" - << Endl; - - vertexShader.AssignOutput(m_ImageFragCoords.c_str(), m_ImageTemp.c_str()); - } else { - fragmentShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " - << m_ImageRotations << ".y, " << m_ImageOffsets << ".x );" << Endl; - fragmentShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " - << m_ImageRotations << ".w, " << m_ImageOffsets << ".y );" << Endl; - vertexShader.GenerateEnvMapReflection(); - addFunction(fragmentShader, "getTransformedUVCoords"); - fragmentShader << "\tvec2 " << m_ImageFragCoords - << " = getTransformedUVCoords( environment_map_reflection, uTransform, " - "vTransform );" - << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - fragmentShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords - << ".y;" << Endl; - } - } - - void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, QT3DSU32 uvSet = 0) - { - GenerateImageUVCoordinates(VertexGenerator(), idx, uvSet, image); - } - - void GenerateImageUVCoordinates(QT3DSU32 idx, SRenderableImage &image, - IDefaultMaterialVertexPipeline &inShader) - { - if (image.m_Image.m_MappingMode == ImageMappingModes::Normal) { - SetupImageVariableNames(idx); - inShader.AddUniform(m_ImageSampler, "sampler2D"); - inShader.AddUniform(m_ImageOffsets, "vec3"); - inShader.AddUniform(m_ImageRotations, "vec4"); - - inShader << "\tuTransform = vec3( " << m_ImageRotations << ".x, " << m_ImageRotations - << ".y, " << m_ImageOffsets << ".x );" << Endl; - inShader << "\tvTransform = vec3( " << m_ImageRotations << ".z, " << m_ImageRotations - << ".w, " << m_ImageOffsets << ".y );" << Endl; - inShader << "\tvec2 " << m_ImageFragCoords << ";" << Endl; - addFunction(inShader, "getTransformedUVCoords"); - inShader.GenerateUVCoords(); - inShader - << "\t" << m_ImageFragCoords - << " = getTransformedUVCoords( vec3( varTexCoord0, 1.0), uTransform, vTransform );" - << Endl; - if (image.m_Image.m_TextureData.m_TextureFlags.IsInvertUVCoords()) - inShader << "\t" << m_ImageFragCoords << ".y = 1.0 - " << m_ImageFragCoords << ".y;" - << Endl; - } - } - - void OutputSpecularEquation(DefaultMaterialSpecularModel::Enum inSpecularModel, - IShaderStageGenerator &fragmentShader, const char *inLightDir, - const char *inLightSpecColor) - { - switch (inSpecularModel) { - case DefaultMaterialSpecularModel::KGGX: { - fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * kggxGlossyDefaultMtl( " - << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor - << ".rgb, vec3(material_specular.xyz), roughnessAmount, " - "roughnessAmount ).rgb;" - << Endl; - } break; - case DefaultMaterialSpecularModel::KWard: { - fragmentShader.AddInclude("defaultMaterialPhysGlossyBSDF.glsllib"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * wardGlossyDefaultMtl( " - << "world_normal, tangent, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor - << ".rgb, vec3(material_specular.xyz), roughnessAmount, " - "roughnessAmount ).rgb;" - << Endl; - } break; - default: - addFunction(fragmentShader, "specularBSDF"); - fragmentShader << "\tglobal_specular_light.rgb += lightAttenuation * specularAmount * " - "specularColor * specularBSDF( " - << "world_normal, -" << inLightDir << ".xyz, view_vector, " - << inLightSpecColor << ".rgb, 1.0, 2.56 / (roughnessAmount + " - "0.01), vec3(1.0), scatter_reflect ).rgb;" - << Endl; - break; - } - } - - void OutputDiffuseAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, - TStrType inLightPrefix) - { - m_NormalizedDirection = inLightPrefix + "_areaDir"; - AddLocalVariable(infragmentShader, m_NormalizedDirection, "vec3"); - infragmentShader << "\tlightAttenuation = calculateDiffuseAreaOld( " << m_LightDirection - << ".xyz, " << m_LightPos << ".xyz, " << m_LightUp << ", " << m_LightRt - << ", " << inPos << ", " << m_NormalizedDirection << " );" << Endl; - } - - void OutputSpecularAreaLighting(IShaderStageGenerator &infragmentShader, const char *inPos, - const char *inView, const char *inLightSpecColor) - { - addFunction(infragmentShader, "sampleAreaGlossyDefault"); - infragmentShader.AddUniform("material_specular", "vec4"); - infragmentShader << "global_specular_light.rgb += " << inLightSpecColor - << ".rgb * lightAttenuation * shadowFac * material_specular.rgb * " - "specularAmount * sampleAreaGlossyDefault( tanFrame, " - << inPos << ", " << m_NormalizedDirection << ", " << m_LightPos << ".xyz, " - << m_LightRt << ".w, " << m_LightUp << ".w, " << inView - << ", roughnessAmount, roughnessAmount ).rgb;" << Endl; - } - - void AddTranslucencyIrradiance(IShaderStageGenerator &infragmentShader, SRenderableImage *image, - TStrType inLightPrefix, bool areaLight) - { - if (image == NULL) - return; - - addFunction(infragmentShader, "diffuseReflectionWrapBSDF"); - if (areaLight) { - infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "translucent_thickness_exp * diffuseReflectionWrapBSDF( " - "-world_normal, " - << m_NormalizedDirection << ", " << m_LightColor - << ".rgb, diffuseLightWrap ).rgb;" << Endl; - } else { - infragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "translucent_thickness_exp * diffuseReflectionWrapBSDF( " - "-world_normal, " - << "-" << m_NormalizedDirection << ", " << m_LightColor - << ".rgb, diffuseLightWrap ).rgb;" << Endl; - } - } - - void SetupShadowMapVariableNames(size_t lightIdx) - { - m_ShadowMapStem = "shadowmap"; - m_ShadowCubeStem = "shadowcube"; - char buf[16]; - _snprintf(buf, 16, "%d", int(lightIdx)); - m_ShadowMapStem.append(buf); - m_ShadowCubeStem.append(buf); - m_ShadowMatrixStem = m_ShadowMapStem; - m_ShadowMatrixStem.append("_matrix"); - m_ShadowCoordStem = m_ShadowMapStem; - m_ShadowCoordStem.append("_coord"); - m_ShadowControlStem = m_ShadowMapStem; - m_ShadowControlStem.append("_control"); - } - - void AddShadowMapContribution(IShaderStageGenerator &inLightShader, QT3DSU32 lightIndex, - RenderLightTypes::Enum inType) - { - SetupShadowMapVariableNames(lightIndex); - - inLightShader.AddInclude("shadowMapping.glsllib"); - if (inType == RenderLightTypes::Directional) { - inLightShader.AddUniform(m_ShadowMapStem, "sampler2D"); - } else { - inLightShader.AddUniform(m_ShadowCubeStem, "samplerCube"); - } - inLightShader.AddUniform(m_ShadowControlStem, "vec4"); - inLightShader.AddUniform(m_ShadowMatrixStem, "mat4"); - - /* - if ( inType == RenderLightTypes::Area ) - { - inLightShader << "vec2 " << m_ShadowCoordStem << ";" << Endl; - inLightShader << "\tshadow_map_occl = sampleParaboloid( " << m_ShadowMapStem << ", " - << m_ShadowControlStem << ", " - << - m_ShadowMatrixStem << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z), " - << m_ShadowCoordStem - << " );" << Endl; - } - else */ - if (inType != RenderLightTypes::Directional) { - inLightShader << "\tshadow_map_occl = sampleCubemap( " << m_ShadowCubeStem << ", " - << m_ShadowControlStem << ", " << m_ShadowMatrixStem << ", " << m_LightPos - << ".xyz, varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" - << Endl; - } else - inLightShader << "\tshadow_map_occl = sampleOrthographic( " << m_ShadowMapStem << ", " - << m_ShadowControlStem << ", " << m_ShadowMatrixStem - << ", varWorldPos, vec2(1.0, " << m_ShadowControlStem << ".z) );" << Endl; - } - - void AddDisplacementMappingForDepthPass(IShaderStageGenerator &inShader) override - { - inShader.AddIncoming("attr_uv0", "vec2"); - inShader.AddIncoming("attr_norm", "vec3"); - inShader.AddUniform("displacementSampler", "sampler2D"); - inShader.AddUniform("displaceAmount", "float"); - inShader.AddUniform("displacementMap_rot", "vec4"); - inShader.AddUniform("displacementMap_offset", "vec3"); - inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - - inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " - "displacementMap_offset.x );"); - inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " - "displacementMap_offset.y );"); - addFunction(inShader, "getTransformedUVCoords"); - inShader.Append("\tvec2 uv_coords = attr_uv0;"); - inShader << "\tuv_coords = getTransformedUVCoords( vec3( uv_coords, 1.0), uTransform, " - "vTransform );\n"; - inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - "displacementSampler , displaceAmount, uv_coords , attr_norm, attr_pos );" - << Endl; - inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - } - - void AddDisplacementImageUniforms(IShaderStageGenerator &inGenerator, - QT3DSU32 displacementImageIdx, - SRenderableImage *displacementImage) override - { - if (displacementImage) { - SetupImageVariableNames(displacementImageIdx); - inGenerator.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - inGenerator.AddUniform("model_matrix", "mat4"); - inGenerator.AddUniform("camera_position", "vec3"); - inGenerator.AddUniform("displaceAmount", "float"); - inGenerator.AddUniform(m_ImageSampler, "sampler2D"); - } - } - - bool MaybeAddMaterialFresnel(IShaderStageGenerator &fragmentShader, NVConstDataRef<QT3DSU32> inKey, - bool inFragmentHasSpecularAmount) - { - if (m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey)) { - if (inFragmentHasSpecularAmount == false) - fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; - inFragmentHasSpecularAmount = true; - fragmentShader.AddInclude("defaultMaterialFresnel.glsllib"); - fragmentShader.AddUniform("fresnelPower", "float"); - fragmentShader.AddUniform("material_specular", "vec4"); - fragmentShader << "\tfloat fresnelRatio = defaultMaterialSimpleFresnel( world_normal, " - "view_vector, material_specular.w, fresnelPower );" - << Endl; - fragmentShader << "\tspecularAmount *= fresnelRatio;" << Endl; - } - return inFragmentHasSpecularAmount; - } - void SetupLightVariableNames(size_t lightIdx, SLight &inLight) - { - if (m_LightsAsSeparateUniforms) { - char buf[16]; - _snprintf(buf, 16, "light_%d", int(lightIdx)); - m_LightStem = buf; - m_LightColor = m_LightStem; - m_LightColor.append("_diffuse"); - m_LightDirection = m_LightStem; - m_LightDirection.append("_direction"); - m_LightSpecularColor = m_LightStem; - m_LightSpecularColor.append("_specular"); - if (inLight.m_LightType == RenderLightTypes::Point) { - m_LightPos = m_LightStem; - m_LightPos.append("_position"); - m_LightAttenuation = m_LightStem; - m_LightAttenuation.append("_attenuation"); - } else if (inLight.m_LightType == RenderLightTypes::Area) { - m_LightPos = m_LightStem; - m_LightPos.append("_position"); - m_LightUp = m_LightStem; - m_LightUp.append("_up"); - m_LightRt = m_LightStem; - m_LightRt.append("_right"); - } - } else { - m_LightStem = "lights"; - char buf[16]; - _snprintf(buf, 16, "[%d].", int(lightIdx)); - m_LightStem.append(buf); - - m_LightColor = m_LightStem; - m_LightColor.append("diffuse"); - m_LightDirection = m_LightStem; - m_LightDirection.append("direction"); - m_LightSpecularColor = m_LightStem; - m_LightSpecularColor.append("specular"); - if (inLight.m_LightType == RenderLightTypes::Point) { - m_LightPos = m_LightStem; - m_LightPos.append("position"); - m_LightConstantAttenuation = m_LightStem; - m_LightConstantAttenuation.append("constantAttenuation"); - m_LightLinearAttenuation = m_LightStem; - m_LightLinearAttenuation.append("linearAttenuation"); - m_LightQuadraticAttenuation = m_LightStem; - m_LightQuadraticAttenuation.append("quadraticAttenuation"); - } else if (inLight.m_LightType == RenderLightTypes::Area) { - m_LightPos = m_LightStem; - m_LightPos.append("position"); - m_LightUp = m_LightStem; - m_LightUp.append("up"); - m_LightRt = m_LightStem; - m_LightRt.append("right"); - } - } - } - - void addDisplacementMapping(IDefaultMaterialVertexPipeline &inShader) - { - inShader.AddIncoming("attr_uv0", "vec2"); - inShader.AddIncoming("attr_norm", "vec3"); - inShader.AddUniform("displacementSampler", "sampler2D"); - inShader.AddUniform("displaceAmount", "float"); - inShader.AddUniform("displacementMap_rot", "vec4"); - inShader.AddUniform("displacementMap_offset", "vec3"); - inShader.AddInclude("defaultMaterialFileDisplacementTexture.glsllib"); - - inShader.Append("\tvec3 uTransform = vec3( displacementMap_rot.x, displacementMap_rot.y, " - "displacementMap_offset.x );"); - inShader.Append("\tvec3 vTransform = vec3( displacementMap_rot.z, displacementMap_rot.w, " - "displacementMap_offset.y );"); - addFunction(inShader, "getTransformedUVCoords"); - inShader.GenerateUVCoords(); - inShader << "\tvarTexCoord0 = getTransformedUVCoords( vec3( varTexCoord0, 1.0), " - "uTransform, vTransform );\n"; - inShader << "\tvec3 displacedPos = defaultMaterialFileDisplacementTexture( " - "displacementSampler , displaceAmount, varTexCoord0 , attr_norm, attr_pos );" - << Endl; - inShader.Append("\tgl_Position = model_view_projection * vec4(displacedPos, 1.0);"); - } - - void GenerateTextureSwizzle(NVRenderTextureSwizzleMode::Enum swizzleMode, - eastl::basic_string<char8_t> &texSwizzle, - eastl::basic_string<char8_t> &lookupSwizzle) - { - qt3ds::render::NVRenderContextType deprecatedContextFlags(NVRenderContextValues::GL2 - | NVRenderContextValues::GLES2); - - if (!(m_RenderContext.GetRenderContext().GetRenderContextType() & deprecatedContextFlags)) { - switch (swizzleMode) { - case NVRenderTextureSwizzleMode::L8toR8: - case NVRenderTextureSwizzleMode::L16toR16: - texSwizzle.append(".rgb"); - lookupSwizzle.append(".rrr"); - break; - case NVRenderTextureSwizzleMode::L8A8toRG8: - texSwizzle.append(".rgba"); - lookupSwizzle.append(".rrrg"); - break; - case NVRenderTextureSwizzleMode::A8toR8: - texSwizzle.append(".a"); - lookupSwizzle.append(".r"); - break; - default: - break; - } - } - } - - ///< get the light constant buffer and generate if necessary - NVRenderConstantBuffer *GetLightConstantBuffer(QT3DSU32 inLightCount) - { - NVRenderContext &theContext(m_RenderContext.GetRenderContext()); - - // we assume constant buffer support - QT3DS_ASSERT(theContext.GetConstantBufferSupport()); - - // we only create if if we have lights - if (!inLightCount || !theContext.GetConstantBufferSupport()) - return NULL; - - CRegisteredString theName = theContext.GetStringTable().RegisterStr("cbBufferLights"); - NVRenderConstantBuffer *pCB = theContext.GetConstantBuffer(theName); - - if (!pCB) { - // create - SLightSourceShader s[QT3DS_MAX_NUM_LIGHTS]; - NVDataRef<QT3DSU8> cBuffer((QT3DSU8 *)&s, (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) - + (4 * sizeof(QT3DSI32))); - pCB = theContext.CreateConstantBuffer( - theName, qt3ds::render::NVRenderBufferUsageType::Static, - (sizeof(SLightSourceShader) * QT3DS_MAX_NUM_LIGHTS) + (4 * sizeof(QT3DSI32)), cBuffer); - if (!pCB) { - QT3DS_ASSERT(false); - return NULL; - } - // init first set - memset(&s[0], 0x0, sizeof(SLightSourceShader)); - QT3DSI32 cgLights = 0; - pCB->UpdateRaw(0, NVDataRef<QT3DSU8>((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); - pCB->UpdateRaw(4 * sizeof(QT3DSI32), - NVDataRef<QT3DSU8>((QT3DSU8 *)&s[0], sizeof(SLightSourceShader))); - pCB->Update(); // update to hardware - - m_ConstantBuffers.insert(eastl::make_pair(theName, pCB)); - } - - return pCB; - } - - void SetImageShaderVariables(SShaderGeneratorGeneratedShader &inShader, - SRenderableImage &inImage, QT3DSU32 idx) - { - size_t numImageVariables = inShader.m_Images.size(); - for (size_t namesIdx = numImageVariables; namesIdx <= idx; ++namesIdx) { - SetupImageVariableNames(idx); - inShader.m_Images.push_back( - SShaderTextureProperties(m_ImageSampler.c_str(), m_ImageOffsets.c_str(), - m_ImageRotations.c_str(), m_ImageSamplerSize.c_str(), - inShader.m_Shader)); - } - SShaderTextureProperties &theShaderProps = inShader.m_Images[idx]; - const QT3DSMat44 &textureTransform = inImage.m_Image.m_TextureTransform; - // We separate rotational information from offset information so that just maybe the shader - // will attempt to push less information to the card. - const QT3DSF32 *dataPtr(textureTransform.front()); - // The third member of the offsets contains a flag indicating if the texture was - // premultiplied or not. - // We use this to mix the texture alpha. - QT3DSVec3 offsets(dataPtr[12], dataPtr[13], - inImage.m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f - : 0.0f); - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - // The image horizontal and vertical tiling modes need to be set here, before we set texture - // on the shader. - // because setting the image on the texture forces the textue to bind and immediately apply - // any tex params. - NVRenderTexture2D *imageTexture = inImage.m_Image.m_TextureData.m_Texture; - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapS( - inImage.m_Image.m_HorizontalTilingMode); - inImage.m_Image.m_TextureData.m_Texture->SetTextureWrapT( - inImage.m_Image.m_VerticalTilingMode); - theShaderProps.m_Sampler.Set(imageTexture); - theShaderProps.m_Offsets.Set(offsets); - theShaderProps.m_Rotations.Set(rotations); - theShaderProps.m_Size.Set(QT3DSVec2(imageTexture->GetTextureDetails().m_Width, - imageTexture->GetTextureDetails().m_Height)); - } - - void GenerateShadowMapOcclusion(QT3DSU32 lightIdx, bool inShadowEnabled, - RenderLightTypes::Enum inType) - { - if (inShadowEnabled) { - VertexGenerator().GenerateWorldPosition(); - AddShadowMapContribution(FragmentGenerator(), lightIdx, inType); - /* - VertexGenerator().AddUniform( m_ShadowMatrixStem, "mat4" ); - VertexGenerator().AddOutgoing( m_ShadowCoordStem, "vec4" ); - VertexGenerator() << "\tvec4 local_" << m_ShadowCoordStem << " = " << m_ShadowMatrixStem - << " * vec4(local_model_world_position, 1.0);" << Endl; - m_TempStr.assign( "local_" ); - m_TempStr.append( m_ShadowCoordStem ); - VertexGenerator().AssignOutput( m_ShadowCoordStem.c_str(), m_TempStr.c_str() ); - */ - } else { - FragmentGenerator() << "\tshadow_map_occl = 1.0;" << Endl; - } - } - - void GenerateVertexShader() - { - // vertex displacement - QT3DSU32 imageIdx = 0; - SRenderableImage *displacementImage = NULL; - QT3DSU32 displacementImageIdx = 0; - - for (SRenderableImage *img = m_FirstImage; img != NULL; - img = img->m_NextImage, ++imageIdx) { - if (img->m_MapType == ImageMapTypes::Displacement) { - displacementImage = img; - displacementImageIdx = imageIdx; - break; - } - } - - // the pipeline opens/closes up the shaders stages - VertexGenerator().BeginVertexGeneration(displacementImageIdx, displacementImage); - } - - void GenerateFragmentShader(SShaderDefaultMaterialKey &inKey) - { - bool specularEnabled = Material().IsSpecularEnabled(); - bool vertexColorsEnabled = Material().IsVertexColorsEnabled(); - - bool hasLighting = Material().HasLighting(); - bool hasImage = m_FirstImage != NULL; - - bool hasIblProbe = m_DefaultMaterialShaderKeyProperties.m_HasIbl.GetValue(inKey); - bool hasSpecMap = false; - bool hasEnvMap = false; - bool hasEmissiveMap = false; - bool hasLightmaps = false; - // Pull the bump out as - SRenderableImage *bumpImage = NULL; - QT3DSU32 imageIdx = 0; - QT3DSU32 bumpImageIdx = 0; - SRenderableImage *specularAmountImage = NULL; - QT3DSU32 specularAmountImageIdx = 0; - SRenderableImage *roughnessImage = NULL; - QT3DSU32 roughnessImageIdx = 0; - // normal mapping - SRenderableImage *normalImage = NULL; - QT3DSU32 normalImageIdx = 0; - // translucency map - SRenderableImage *translucencyImage = NULL; - QT3DSU32 translucencyImageIdx = 0; - // lightmaps - SRenderableImage *lightmapIndirectImage = NULL; - QT3DSU32 lightmapIndirectImageIdx = 0; - SRenderableImage *lightmapRadiosityImage = NULL; - QT3DSU32 lightmapRadiosityImageIdx = 0; - SRenderableImage *lightmapShadowImage = NULL; - QT3DSU32 lightmapShadowImageIdx = 0; - const bool supportStandardDerivatives - = m_RenderContext.GetRenderContext().IsStandardDerivativesSupported(); - - for (SRenderableImage *img = m_FirstImage; img != NULL; - img = img->m_NextImage, ++imageIdx) { - hasSpecMap = img->m_MapType == ImageMapTypes::Specular; - if (img->m_MapType == ImageMapTypes::Bump) { - bumpImage = img; - bumpImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::SpecularAmountMap) { - specularAmountImage = img; - specularAmountImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Roughness) { - roughnessImage = img; - roughnessImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Normal) { - normalImage = img; - normalImageIdx = imageIdx; - } else if (img->m_Image.m_MappingMode == ImageMappingModes::Environment) { - hasEnvMap = true; - } else if (img->m_MapType == ImageMapTypes::Translucency) { - translucencyImage = img; - translucencyImageIdx = imageIdx; - } else if (img->m_MapType == ImageMapTypes::Emissive) { - hasEmissiveMap = true; - } else if (img->m_MapType == ImageMapTypes::LightmapIndirect) { - lightmapIndirectImage = img; - lightmapIndirectImageIdx = imageIdx; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapRadiosity) { - lightmapRadiosityImage = img; - lightmapRadiosityImageIdx = imageIdx; - hasLightmaps = true; - } else if (img->m_MapType == ImageMapTypes::LightmapShadow) { - lightmapShadowImage = img; - lightmapShadowImageIdx = imageIdx; - hasLightmaps = true; - } - } - - bool enableFresnel = m_DefaultMaterialShaderKeyProperties.m_FresnelEnabled.GetValue(inKey); - bool enableSSAO = false; - bool enableSSDO = false; - bool enableShadowMaps = false; - bool enableBumpNormal = normalImage || bumpImage; - - for (QT3DSU32 idx = 0; idx < FeatureSet().size(); ++idx) { - eastl::string name(FeatureSet()[idx].m_Name.c_str()); - if (name == "QT3DS_ENABLE_SSAO") - enableSSAO = FeatureSet()[idx].m_Enabled; - else if (name == "QT3DS_ENABLE_SSDO") - enableSSDO = FeatureSet()[idx].m_Enabled; - else if (name == "QT3DS_ENABLE_SSM") - enableShadowMaps = FeatureSet()[idx].m_Enabled; - } - - bool includeSSAOSSDOVars = enableSSAO || enableSSDO || enableShadowMaps; - - VertexGenerator().BeginFragmentGeneration(); - IShaderStageGenerator &fragmentShader(FragmentGenerator()); - IDefaultMaterialVertexPipeline &vertexShader(VertexGenerator()); - - // The fragment or vertex shaders may not use the material_properties or diffuse - // uniforms in all cases but it is simpler to just add them and let the linker strip them. - fragmentShader.AddUniform("material_diffuse", "vec4"); - fragmentShader.AddUniform("diffuse_color", "vec3"); - fragmentShader.AddUniform("material_properties", "vec4"); - - // All these are needed for SSAO - if (includeSSAOSSDOVars) { - fragmentShader.AddInclude("SSAOCustomMaterial.glsllib"); - // fragmentShader.AddUniform( "ao_sampler", "sampler2D" ); - } - - if (hasIblProbe && hasLighting) { - fragmentShader.AddInclude("sampleProbe.glsllib"); - } - - if (hasLighting) { - if (!m_LightsAsSeparateUniforms) - addFunction(fragmentShader, "sampleLightVars"); - addFunction(fragmentShader, "diffuseReflectionBSDF"); - } - - if (hasLighting && hasLightmaps) { - fragmentShader.AddInclude("evalLightmaps.glsllib"); - } - - // view_vector, varWorldPos, world_normal are all used if there is a specular map - // in addition to if there is specular lighting. So they are lifted up here, always - // generated. - // we rely on the linker to strip out what isn't necessary instead of explicitly stripping - // it for code simplicity. - if (hasImage) { - fragmentShader.Append("\tvec3 uTransform;"); - fragmentShader.Append("\tvec3 vTransform;"); - } - - if (includeSSAOSSDOVars || hasSpecMap || hasLighting || hasEnvMap || enableFresnel - || hasIblProbe || enableBumpNormal) { - vertexShader.GenerateViewVector(); - vertexShader.GenerateWorldNormal(); - vertexShader.GenerateWorldPosition(); - } - if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) - vertexShader.GenerateVarTangentAndBinormal(); - - if (vertexColorsEnabled) - vertexShader.GenerateVertexColor(); - else - fragmentShader.Append("\tvec3 vertColor = vec3(1.0);"); - - // You do bump or normal mapping but not both - if (bumpImage != NULL) { - GenerateImageUVCoordinates(bumpImageIdx, *bumpImage); - fragmentShader.AddUniform("bumpAmount", "float"); - - fragmentShader.AddUniform(m_ImageSamplerSize, "vec2"); - fragmentShader.AddInclude("defaultMaterialBumpNoLod.glsllib"); - fragmentShader << "\tworld_normal = defaultMaterialBumpNoLod( " << m_ImageSampler - << ", bumpAmount, " << m_ImageFragCoords - << ", tangent, binormal, world_normal, " - << m_ImageSamplerSize << ");" << Endl; - // Do gram schmidt - fragmentShader << "\tbinormal = normalize(cross(world_normal, tangent) );\n"; - fragmentShader << "\ttangent = normalize(cross(binormal, world_normal) );\n"; - - } else if (normalImage != NULL) { - GenerateImageUVCoordinates(normalImageIdx, *normalImage); - - fragmentShader.AddInclude("defaultMaterialFileNormalTexture.glsllib"); - fragmentShader.AddUniform("bumpAmount", "float"); - - fragmentShader << "\tworld_normal = defaultMaterialFileNormalTexture( " - << m_ImageSampler << ", bumpAmount, " << m_ImageFragCoords - << ", tangent, binormal );" << Endl; - } - - if (includeSSAOSSDOVars || specularEnabled || hasIblProbe || enableBumpNormal) - fragmentShader << "\tmat3 tanFrame = mat3(tangent, binormal, world_normal);" << Endl; - - bool fragmentHasSpecularAmount = false; - - if (hasEmissiveMap) { - fragmentShader.Append("\tvec3 global_emission = material_diffuse.rgb;"); - } - - if (hasLighting) { - fragmentShader.AddUniform("light_ambient_total", "vec3"); - - fragmentShader.Append( - "\tvec4 global_diffuse_light = vec4(light_ambient_total.xyz, 1.0);"); - fragmentShader.Append("\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);"); - fragmentShader.Append("\tfloat shadow_map_occl = 1.0;"); - - if (specularEnabled) { - vertexShader.GenerateViewVector(); - fragmentShader.AddUniform("material_properties", "vec4"); - } - - if (lightmapIndirectImage != NULL) { - GenerateImageUVCoordinates(lightmapIndirectImageIdx, *lightmapIndirectImage, 1); - fragmentShader << "\tvec4 indirect_light = texture2D( " << m_ImageSampler << ", " - << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tglobal_diffuse_light += indirect_light;" << Endl; - if (specularEnabled) { - fragmentShader - << "\tglobal_specular_light += indirect_light.rgb * material_properties.x;" - << Endl; - } - } - - if (lightmapRadiosityImage != NULL) { - GenerateImageUVCoordinates(lightmapRadiosityImageIdx, *lightmapRadiosityImage, 1); - fragmentShader << "\tvec4 direct_light = texture2D( " << m_ImageSampler << ", " - << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tglobal_diffuse_light += direct_light;" << Endl; - if (specularEnabled) { - fragmentShader - << "\tglobal_specular_light += direct_light.rgb * material_properties.x;" - << Endl; - } - } - - if (translucencyImage != NULL) { - fragmentShader.AddUniform("translucentFalloff", "float"); - fragmentShader.AddUniform("diffuseLightWrap", "float"); - - GenerateImageUVCoordinates(translucencyImageIdx, *translucencyImage); - - fragmentShader << "\tvec4 translucent_depth_range = texture2D( " << m_ImageSampler - << ", " << m_ImageFragCoords << ");" << Endl; - fragmentShader << "\tfloat translucent_thickness = translucent_depth_range.r * " - "translucent_depth_range.r;" - << Endl; - fragmentShader << "\tfloat translucent_thickness_exp = exp( translucent_thickness " - "* translucentFalloff);" - << Endl; - } - - fragmentShader.Append("\tfloat lightAttenuation = 1.0;"); - - AddLocalVariable(fragmentShader, "aoFactor", "float"); - - if (hasLighting && enableSSAO) - fragmentShader.Append("\taoFactor = customMaterialAO();"); - else - fragmentShader.Append("\taoFactor = 1.0;"); - - AddLocalVariable(fragmentShader, "shadowFac", "float"); - - if (specularEnabled) { - fragmentShader << "\tfloat specularAmount = material_properties.x;" << Endl; - fragmentHasSpecularAmount = true; - } - // Fragment lighting means we can perhaps attenuate the specular amount by a texture - // lookup. - - fragmentShader << "\tvec3 specularColor = vec3(1.0);" << Endl; - if (specularAmountImage) { - if (!specularEnabled) - fragmentShader << "\tfloat specularAmount = 1.0;" << Endl; - GenerateImageUVCoordinates(specularAmountImageIdx, *specularAmountImage); - fragmentShader << "\tspecularColor = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << " ).xyz;" << Endl; - fragmentHasSpecularAmount = true; - } - - fragmentShader << "\tfloat roughnessAmount = material_properties.y;" << Endl; - if (roughnessImage) { - GenerateImageUVCoordinates(roughnessImageIdx, *roughnessImage); - fragmentShader << "\tfloat sampledRoughness = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << " ).x;" << Endl; - //The roughness sampled from roughness textures is Disney roughness - //which has to be squared to get the proper value - fragmentShader << "\troughnessAmount = roughnessAmount * " - << "sampledRoughness * sampledRoughness;" << Endl; - } - - fragmentHasSpecularAmount = - MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); - - // Iterate through all lights - for (QT3DSU32 lightIdx = 0; lightIdx < m_Lights.size(); ++lightIdx) { - SLight *lightNode = m_Lights[lightIdx]; - SetupLightVariableNames(lightIdx, *lightNode); - bool isDirectional = lightNode->m_LightType == RenderLightTypes::Directional; - bool isArea = lightNode->m_LightType == RenderLightTypes::Area; - bool isShadow = enableShadowMaps && lightNode->m_CastShadow; - - fragmentShader.Append(""); - char buf[10]; - sprintf(buf, "%d", lightIdx); - - m_TempStr.assign("light"); - m_TempStr.append(buf); - - fragmentShader << "\t//Light " << buf << Endl; - fragmentShader << "\tlightAttenuation = 1.0;" << Endl; - if (isDirectional) { - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightDirection, "vec4"); - fragmentShader.AddUniform(m_LightColor, "vec4"); - } - - if (enableSSDO) { - fragmentShader << "\tshadowFac = customMaterialShadow( " << m_LightDirection - << ".xyz, varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = 1.0;" << Endl; - } - - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - if (specularEnabled && enableShadowMaps && isShadow) - fragmentShader << "\tlightAttenuation *= shadow_map_occl;" << Endl; - - fragmentShader << "\tglobal_diffuse_light.rgb += shadowFac * shadow_map_occl * " - "diffuseReflectionBSDF( world_normal, " - << "-" << m_LightDirection << ".xyz, view_vector, " - << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; - - if (specularEnabled) { - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, - m_LightDirection.c_str(), - m_LightSpecularColor.c_str()); - } - } else if (isArea) { - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightColor, "vec4"); - fragmentShader.AddUniform(m_LightPos, "vec4"); - fragmentShader.AddUniform(m_LightDirection, "vec4"); - fragmentShader.AddUniform(m_LightUp, "vec4"); - fragmentShader.AddUniform(m_LightRt, "vec4"); - } else { - addFunction(fragmentShader, "areaLightVars"); - } - addFunction(fragmentShader, "calculateDiffuseAreaOld"); - vertexShader.GenerateWorldPosition(); - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - // Debug measure to make sure paraboloid sampling was projecting to the right - // location - // fragmentShader << "\tglobal_diffuse_light.rg += " << m_ShadowCoordStem << ";" - // << Endl; - m_NormalizedDirection = m_TempStr; - m_NormalizedDirection.append("_Frame"); - - AddLocalVariable(fragmentShader, m_NormalizedDirection, "mat3"); - fragmentShader << m_NormalizedDirection << " = mat3( " << m_LightRt << ".xyz, " - << m_LightUp << ".xyz, -" << m_LightDirection << ".xyz );" - << Endl; - - if (enableSSDO) { - fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " - << m_LightDirection << ".xyz, varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; - } - - if (specularEnabled) { - vertexShader.GenerateViewVector(); - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularAreaLighting(fragmentShader, "varWorldPos", "view_vector", - m_LightSpecularColor.c_str()); - } - - OutputDiffuseAreaLighting(fragmentShader, "varWorldPos", m_TempStr); - fragmentShader << "\tlightAttenuation *= shadowFac;" << Endl; - - AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, true); - - fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "diffuseReflectionBSDF( world_normal, " - << m_NormalizedDirection << ", view_vector, " << m_LightColor - << ".rgb, 0.0 ).rgb;" << Endl; - } else { - - vertexShader.GenerateWorldPosition(); - GenerateShadowMapOcclusion(lightIdx, enableShadowMaps && isShadow, - lightNode->m_LightType); - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightColor, "vec4"); - fragmentShader.AddUniform(m_LightPos, "vec4"); - } - - m_RelativeDirection = m_TempStr; - m_RelativeDirection.append("_relativeDirection"); - - m_NormalizedDirection = m_RelativeDirection; - m_NormalizedDirection.append("_normalized"); - - m_RelativeDistance = m_TempStr; - m_RelativeDistance.append("_distance"); - - fragmentShader << "\tvec3 " << m_RelativeDirection << " = varWorldPos - " - << m_LightPos << ".xyz;" << Endl; - fragmentShader << "\tfloat " << m_RelativeDistance << " = length( " - << m_RelativeDirection << " );" << Endl; - fragmentShader << "\tvec3 " << m_NormalizedDirection << " = " - << m_RelativeDirection << " / " << m_RelativeDistance << ";" - << Endl; - - if (enableSSDO) { - fragmentShader << "\tshadowFac = shadow_map_occl * customMaterialShadow( " - << m_NormalizedDirection << ", varWorldPos );" << Endl; - } else { - fragmentShader << "\tshadowFac = shadow_map_occl;" << Endl; - } - - addFunction(fragmentShader, "calculatePointLightAttenuation"); - - if (m_LightsAsSeparateUniforms) { - fragmentShader.AddUniform(m_LightAttenuation, "vec3"); - fragmentShader - << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" - << "vec3( " << m_LightAttenuation << ".x, " << m_LightAttenuation - << ".y, " << m_LightAttenuation << ".z), " << m_RelativeDistance - << ");" << Endl; - } else { - fragmentShader - << "\tlightAttenuation = shadowFac * calculatePointLightAttenuation(" - << "vec3( " << m_LightConstantAttenuation << ", " - << m_LightLinearAttenuation << ", " << m_LightQuadraticAttenuation - << "), " << m_RelativeDistance << ");" - << Endl; - } - - - - AddTranslucencyIrradiance(fragmentShader, translucencyImage, m_TempStr, false); - - fragmentShader << "\tglobal_diffuse_light.rgb += lightAttenuation * " - "diffuseReflectionBSDF( world_normal, " - << "-" << m_NormalizedDirection << ", view_vector, " - << m_LightColor << ".rgb, 0.0 ).rgb;" << Endl; - - if (specularEnabled) { - if (m_LightsAsSeparateUniforms) - fragmentShader.AddUniform(m_LightSpecularColor, "vec4"); - OutputSpecularEquation(Material().m_SpecularModel, fragmentShader, - m_NormalizedDirection.c_str(), - m_LightSpecularColor.c_str()); - } - } - } - - // This may be confusing but the light colors are already modulated by the base - // material color. - // Thus material color is the base material color * material emissive. - // Except material_color.a *is* the actual opacity factor. - // Furthermore object_opacity is something that may come from the vertex pipeline or - // somewhere else. - // We leave it up to the vertex pipeline to figure it out. - fragmentShader << "\tglobal_diffuse_light = vec4(global_diffuse_light.xyz * aoFactor, " - "object_opacity);" - << Endl << "\tglobal_specular_light = vec3(global_specular_light.xyz);" - << Endl; - } else // no lighting. - { - fragmentShader << "\tvec4 global_diffuse_light = vec4(0.0, 0.0, 0.0, object_opacity);" - << Endl << "\tvec3 global_specular_light = vec3(0.0, 0.0, 0.0);" << Endl; - - // We still have specular maps and such that could potentially use the fresnel variable. - fragmentHasSpecularAmount = - MaybeAddMaterialFresnel(fragmentShader, inKey, fragmentHasSpecularAmount); - } - - if (!hasEmissiveMap) - fragmentShader - << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * material_diffuse.rgb;" - << Endl; - - // since we already modulate our material diffuse color - // into the light color we will miss it entirely if no IBL - // or light is used - if (hasLightmaps && !(m_Lights.size() || hasIblProbe)) - fragmentShader << "\tglobal_diffuse_light.rgb *= diffuse_color.rgb;" << Endl; - - if (hasLighting && hasIblProbe) { - vertexShader.GenerateWorldNormal(); - - fragmentShader << "\tglobal_diffuse_light.rgb += diffuse_color.rgb * aoFactor * " - "sampleDiffuse( tanFrame ).xyz;" - << Endl; - - if (specularEnabled) { - - fragmentShader.AddUniform("material_specular", "vec4"); - - fragmentShader << "\tglobal_specular_light.xyz += specularAmount * specularColor * " - "vec3(material_specular.xyz) * sampleGlossy( tanFrame, " - "view_vector, roughnessAmount ).xyz;" - << Endl; - } - } - - if (hasImage) { - fragmentShader.Append("\tvec4 texture_color;"); - QT3DSU32 idx = 0; - for (SRenderableImage *image = m_FirstImage; image; image = image->m_NextImage, ++idx) { - // Various maps are handled on a different locations - if (image->m_MapType == ImageMapTypes::Bump - || image->m_MapType == ImageMapTypes::Normal - || image->m_MapType == ImageMapTypes::Displacement - || image->m_MapType == ImageMapTypes::SpecularAmountMap - || image->m_MapType == ImageMapTypes::Roughness - || image->m_MapType == ImageMapTypes::Translucency - || image->m_MapType == ImageMapTypes::LightmapIndirect - || image->m_MapType == ImageMapTypes::LightmapRadiosity) { - continue; - } - - eastl::basic_string<char8_t> texSwizzle, lookupSwizzle, texLodStr; - - GenerateImageUVCoordinates(idx, *image, 0); - - GenerateTextureSwizzle( - image->m_Image.m_TextureData.m_Texture->GetTextureSwizzleMode(), texSwizzle, - lookupSwizzle); - - if (texLodStr.empty()) { - fragmentShader << "\ttexture_color" << texSwizzle.c_str() << " = texture2D( " - << m_ImageSampler << ", " << m_ImageFragCoords << ")" - << lookupSwizzle.c_str() << ";" << Endl; - } else { - fragmentShader << "\ttexture_color" << texSwizzle.c_str() << "= textureLod( " - << m_ImageSampler << ", " << m_ImageFragCoords << ", " - << texLodStr.c_str() << " )" << lookupSwizzle.c_str() << ";" - << Endl; - } - - if (image->m_Image.m_TextureData.m_TextureFlags.IsPreMultiplied() == true) - fragmentShader << "\ttexture_color.rgb = texture_color.a > 0.0 ? " - "texture_color.rgb / texture_color.a : vec3( 0, 0, 0 );" - << Endl; - - // These mapping types honestly don't make a whole ton of sense to me. - switch (image->m_MapType) { - case ImageMapTypes::Diffuse: // assume images are premultiplied. - case ImageMapTypes::LightmapShadow: - // We use image offsets.z to switch between incoming premultiplied textures or - // not premultiplied textures. - // If Z is 1, then we assume the incoming texture is already premultiplied, else - // we just read the rgb value. - fragmentShader.Append("\tglobal_diffuse_light *= texture_color;"); - break; - case ImageMapTypes::Specular: - - fragmentShader.AddUniform("material_specular", "vec4"); - if (fragmentHasSpecularAmount) { - fragmentShader.Append("\tglobal_specular_light.xyz += specularAmount * " - "specularColor * texture_color.xyz * " - "material_specular.xyz;"); - } else { - fragmentShader.Append("\tglobal_specular_light.xyz += texture_color.xyz * " - "material_specular.xyz;"); - } - fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); - break; - case ImageMapTypes::Opacity: - fragmentShader.Append("\tglobal_diffuse_light.a *= texture_color.a;"); - break; - case ImageMapTypes::Emissive: - fragmentShader.Append( - "\tglobal_emission *= texture_color.xyz * texture_color.a;"); - break; - default: - QT3DS_ASSERT(false); // fallthrough intentional - } - } - } - - if (hasEmissiveMap) { - fragmentShader.Append("\tglobal_diffuse_light.rgb += global_emission.rgb;"); - } - - // Ensure the rgb colors are in range. - fragmentShader.Append("\tfragOutput = vec4( clamp( vertColor * global_diffuse_light.xyz + " - "global_specular_light.xyz, 0.0, 65519.0 ), global_diffuse_light.a " - ");"); - - if (VertexGenerator().HasActiveWireframe()) { - fragmentShader.Append("vec3 edgeDistance = varEdgeDistance * gl_FragCoord.w;"); - fragmentShader.Append( - "\tfloat d = min(min(edgeDistance.x, edgeDistance.y), edgeDistance.z);"); - fragmentShader.Append("\tfloat mixVal = smoothstep(0.0, 1.0, d);"); // line width 1.0 - - fragmentShader.Append( - "\tfragOutput = mix( vec4(0.0, 1.0, 0.0, 1.0), fragOutput, mixVal);"); - } - } - - NVRenderShaderProgram *GenerateMaterialShader(const char8_t *inShaderPrefix) - { - // build a string that allows us to print out the shader we are generating to the log. - // This is time consuming but I feel like it doesn't happen all that often and is very - // useful to users - // looking at the log file. - - m_GeneratedShaderString.clear(); - m_GeneratedShaderString.assign(nonNull(inShaderPrefix)); - - SShaderDefaultMaterialKey theKey(Key()); - theKey.ToString(m_GeneratedShaderString, m_DefaultMaterialShaderKeyProperties); - - m_LightsAsSeparateUniforms = !m_RenderContext.GetRenderContext().GetConstantBufferSupport(); - - GenerateVertexShader(); - GenerateFragmentShader(theKey); - - VertexGenerator().EndVertexGeneration(false); - VertexGenerator().EndFragmentGeneration(false); - - return ProgramGenerator().CompileGeneratedShader(m_GeneratedShaderString.c_str(), - SShaderCacheProgramFlags(), FeatureSet()); - } - - virtual NVRenderShaderProgram * - GenerateShader(const SGraphObject &inMaterial, SShaderDefaultMaterialKey inShaderDescription, - IShaderStageGenerator &inVertexPipeline, TShaderFeatureSet inFeatureSet, - NVDataRef<SLight *> inLights, SRenderableImage *inFirstImage, - bool inHasTransparency, const char8_t *inVertexPipelineName, const char8_t *) override - { - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); - m_CurrentMaterial = static_cast<const SDefaultMaterial *>(&inMaterial); - m_CurrentKey = &inShaderDescription; - m_CurrentPipeline = static_cast<IDefaultMaterialVertexPipeline *>(&inVertexPipeline); - m_CurrentFeatureSet = inFeatureSet; - m_Lights = inLights; - m_FirstImage = inFirstImage; - m_HasTransparency = inHasTransparency; - - return GenerateMaterialShader(inVertexPipelineName); - } - - SShaderGeneratorGeneratedShader &GetShaderForProgram(NVRenderShaderProgram &inProgram) - { - eastl::pair<TProgramToShaderMap::iterator, bool> inserter = - m_ProgramToShaderMap.insert(eastl::make_pair( - &inProgram, NVScopedRefCounted<SShaderGeneratorGeneratedShader>(NULL))); - if (inserter.second) { - NVAllocatorCallback &alloc(m_RenderContext.GetRenderContext().GetAllocator()); - inserter.first->second = QT3DS_NEW(alloc, SShaderGeneratorGeneratedShader)( - inProgram, m_RenderContext.GetRenderContext()); - } - return *inserter.first->second; - } - - void SetGlobalProperties(NVRenderShaderProgram &inProgram, const SLayer & /*inLayer*/ - , - SCamera &inCamera, QT3DSVec3 inCameraDirection, - NVDataRef<SLight *> inLights, NVDataRef<QT3DSVec3> inLightDirections, - Qt3DSShadowMap *inShadowMapManager) - { - SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); - m_RenderContext.GetRenderContext().SetActiveShader(&inProgram); - - m_ShadowMapManager = inShadowMapManager; - - SCamera &theCamera(inCamera); - shader.m_CameraPosition.Set(theCamera.GetGlobalPos()); - shader.m_CameraDirection.Set(inCameraDirection); - - QT3DSMat44 viewProj; - if (shader.m_ViewProj.IsValid()) { - theCamera.CalculateViewProjectionMatrix(viewProj); - shader.m_ViewProj.Set(viewProj); - } - - if (shader.m_ViewMatrix.IsValid()) { - viewProj = theCamera.m_GlobalTransform.getInverse(); - shader.m_ViewMatrix.Set(viewProj); - } - - // update the constant buffer - shader.m_AoShadowParams.Set(); - // We can't cache light properties because they can change per object. - QT3DSVec4 theLightAmbientTotal = QT3DSVec4(0, 0, 0, 1); - size_t numShaderLights = shader.m_Lights.size(); - size_t numShadowLights = shader.m_ShadowMaps.size(); - for (QT3DSU32 lightIdx = 0, shadowMapIdx = 0, lightEnd = inLights.size(); - lightIdx < lightEnd && lightIdx < QT3DS_MAX_NUM_LIGHTS; ++lightIdx) { - SLight *theLight(inLights[lightIdx]); - if (lightIdx >= numShaderLights) { - shader.m_Lights.push_back(SShaderLightProperties()); - ++numShaderLights; - } - if (shadowMapIdx >= numShadowLights && numShadowLights < QT3DS_MAX_NUM_SHADOWS) { - if (theLight->m_Scope == NULL && theLight->m_CastShadow) { - // PKC TODO : Fix multiple shadow issues. - // Need to know when the list of lights changes order, and clear shadow maps - // when that happens. - SetupShadowMapVariableNames(lightIdx); - shader.m_ShadowMaps.push_back(SShadowMapProperties( - m_ShadowMapStem.c_str(), m_ShadowCubeStem.c_str(), - m_ShadowMatrixStem.c_str(), m_ShadowControlStem.c_str(), inProgram)); - } - } - QT3DS_ASSERT(lightIdx < numShaderLights); - SShaderLightProperties &theLightProperties(shader.m_Lights[lightIdx]); - float brightness = TranslateConstantAttenuation(theLight->m_Brightness); - - // setup light data - theLightProperties.m_LightColor = - QT3DSVec4(theLight->m_DiffuseColor.getXYZ() * brightness, 1.0); - theLightProperties.m_LightData.m_specular = - QT3DSVec4(theLight->m_SpecularColor.getXYZ() * brightness, 1.0); - theLightProperties.m_LightData.m_direction = QT3DSVec4(inLightDirections[lightIdx], 1.0); - - // TODO : This does potentially mean that we can create more shadow map entries than - // we can actually use at once. - if ((theLight->m_Scope == NULL) && (theLight->m_CastShadow && inShadowMapManager)) { - SShadowMapProperties &theShadowMapProperties(shader.m_ShadowMaps[shadowMapIdx++]); - SShadowMapEntry *pEntry = inShadowMapManager->GetShadowMapEntry(lightIdx); - if (pEntry) { - // add fixed scale bias matrix - QT3DSMat44 bias(QT3DSVec4(0.5, 0.0, 0.0, 0.0), QT3DSVec4(0.0, 0.5, 0.0, 0.0), - QT3DSVec4(0.0, 0.0, 0.5, 0.0), QT3DSVec4(0.5, 0.5, 0.5, 1.0)); - - if (theLight->m_LightType != RenderLightTypes::Directional) { - theShadowMapProperties.m_ShadowCubeTexture.Set(pEntry->m_DepthCube); - theShadowMapProperties.m_ShadowmapMatrix.Set(pEntry->m_LightView); - } else { - theShadowMapProperties.m_ShadowmapTexture.Set(pEntry->m_DepthMap); - theShadowMapProperties.m_ShadowmapMatrix.Set(bias * pEntry->m_LightVP); - } - - theShadowMapProperties.m_ShadowmapSettings.Set( - QT3DSVec4(theLight->m_ShadowBias, theLight->m_ShadowFactor, - theLight->m_ShadowMapFar, 0.0f)); - } else { - // if we have a light casting shadow we should find an entry - QT3DS_ASSERT(false); - } - } - - if (theLight->m_LightType == RenderLightTypes::Point) { - theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); - theLightProperties.m_LightData.m_constantAttenuation = 1.0; - theLightProperties.m_LightData.m_linearAttenuation = - TranslateLinearAttenuation(theLight->m_LinearFade); - theLightProperties.m_LightData.m_quadraticAttenuation = - TranslateQuadraticAttenuation(theLight->m_ExponentialFade); - } else if (theLight->m_LightType == RenderLightTypes::Area) { - theLightProperties.m_LightData.m_position = QT3DSVec4(theLight->GetGlobalPos(), 1.0); - - QT3DSVec3 upDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(0, 1, 0)); - QT3DSVec3 rtDir = theLight->m_GlobalTransform.getUpper3x3().transform(QT3DSVec3(1, 0, 0)); - - theLightProperties.m_LightData.m_up = QT3DSVec4(upDir, theLight->m_AreaHeight); - theLightProperties.m_LightData.m_right = QT3DSVec4(rtDir, theLight->m_AreaWidth); - } - theLightAmbientTotal += theLight->m_AmbientColor; - } - shader.m_LightAmbientTotal = theLightAmbientTotal.getXYZ(); - } - - // Also sets the blend function on the render context. - void SetMaterialProperties(NVRenderShaderProgram &inProgram, const SDefaultMaterial &inMaterial, - const QT3DSVec2 &inCameraVec, const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - NVRenderTexture2D *inDepthTexture, NVRenderTexture2D *inSSaoTexture, - SImage *inLightProbe, SImage *inLightProbe2, QT3DSF32 inProbeHorizon, - QT3DSF32 inProbeBright, QT3DSF32 inProbe2Window, QT3DSF32 inProbe2Pos, - QT3DSF32 inProbe2Fade, QT3DSF32 inProbeFOV) - { - - NVRenderContext &context(m_RenderContext.GetRenderContext()); - SShaderGeneratorGeneratedShader &shader(GetShaderForProgram(inProgram)); - shader.m_MVP.Set(inModelViewProjection); - shader.m_NormalMatrix.Set(inNormalMatrix); - shader.m_GlobalTransform.Set(inGlobalTransform); - shader.m_DepthTexture.Set(inDepthTexture); - - shader.m_AOTexture.Set(inSSaoTexture); - - qt3ds::render::SImage *theLightProbe = inLightProbe; - qt3ds::render::SImage *theLightProbe2 = inLightProbe2; - - // If the material has its own IBL Override, we should use that image instead. - if ((inMaterial.m_IblProbe) && (inMaterial.m_IblProbe->m_TextureData.m_Texture)) { - theLightProbe = inMaterial.m_IblProbe; - } - - if (theLightProbe) { - if (theLightProbe->m_TextureData.m_Texture) { - NVRenderTextureCoordOp::Enum theHorzLightProbeTilingMode = - theLightProbe->m_HorizontalTilingMode; - NVRenderTextureCoordOp::Enum theVertLightProbeTilingMode = - theLightProbe->m_VerticalTilingMode; - theLightProbe->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - const QT3DSMat44 &textureTransform = theLightProbe->m_TextureTransform; - // We separate rotational information from offset information so that just maybe the - // shader - // will attempt to push less information to the card. - const QT3DSF32 *dataPtr(textureTransform.front()); - // The third member of the offsets contains a flag indicating if the texture was - // premultiplied or not. - // We use this to mix the texture alpha. - QT3DSVec4 offsets(dataPtr[12], dataPtr[13], - theLightProbe->m_TextureData.m_TextureFlags.IsPreMultiplied() ? 1.0f - : 0.0f, - (float)theLightProbe->m_TextureData.m_Texture->GetNumMipmaps()); - - // Grab just the upper 2x2 rotation matrix from the larger matrix. - QT3DSVec4 rotations(dataPtr[0], dataPtr[4], dataPtr[1], dataPtr[5]); - - shader.m_LightProbeRot.Set(rotations); - shader.m_LightProbeOfs.Set(offsets); - - if ((!inMaterial.m_IblProbe) && (inProbeFOV < 180.f)) { - shader.m_LightProbeOpts.Set( - QT3DSVec4(0.01745329251994329547f * inProbeFOV, 0.0f, 0.0f, 0.0f)); - } - - // Also make sure to add the secondary texture, but it should only be added if the - // primary - // (i.e. background) texture is also there. - if (theLightProbe2 && theLightProbe2->m_TextureData.m_Texture) { - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapS( - theHorzLightProbeTilingMode); - theLightProbe2->m_TextureData.m_Texture->SetTextureWrapT( - theVertLightProbeTilingMode); - shader.m_LightProbe2.Set(theLightProbe2->m_TextureData.m_Texture); - shader.m_LightProbe2Props.Set( - QT3DSVec4(inProbe2Window, inProbe2Pos, inProbe2Fade, 1.0f)); - - const QT3DSMat44 &xform2 = theLightProbe2->m_TextureTransform; - const QT3DSF32 *dataPtr(xform2.front()); - shader.m_LightProbeProps.Set( - QT3DSVec4(dataPtr[12], dataPtr[13], inProbeHorizon, inProbeBright * 0.01f)); - } else { - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - shader.m_LightProbeProps.Set( - QT3DSVec4(0.0f, 0.0f, inProbeHorizon, inProbeBright * 0.01f)); - } - NVRenderTexture2D *textureImage = theLightProbe->m_TextureData.m_Texture; - shader.m_LightProbe.Set(textureImage); - shader.m_LightProbeSize.Set(QT3DSVec2(textureImage->GetTextureDetails().m_Width, - textureImage->GetTextureDetails().m_Height)); - } else { - shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - } else { - shader.m_LightProbeProps.Set(QT3DSVec4(0.0f, 0.0f, -1.0f, 0.0f)); - shader.m_LightProbe2Props.Set(QT3DSVec4(0.0f, 0.0f, 0.0f, 0.0f)); - } - - QT3DSF32 emissivePower = 1.0; - - QT3DSU32 hasLighting = inMaterial.m_Lighting != DefaultMaterialLighting::NoLighting; - if (hasLighting) - emissivePower = inMaterial.m_EmissivePower / 100.0f; - - QT3DSVec4 material_diffuse = QT3DSVec4(inMaterial.m_EmissiveColor[0] * emissivePower, - inMaterial.m_EmissiveColor[1] * emissivePower, - inMaterial.m_EmissiveColor[2] * emissivePower, inOpacity); - shader.m_MaterialDiffuse.Set(material_diffuse); - shader.m_DiffuseColor.Set(inMaterial.m_DiffuseColor.getXYZ()); - QT3DSVec4 material_specular = - QT3DSVec4(inMaterial.m_SpecularTint[0], inMaterial.m_SpecularTint[1], - inMaterial.m_SpecularTint[2], inMaterial.m_IOR); - shader.m_MaterialSpecular.Set(material_specular); - shader.m_CameraProperties.Set(inCameraVec); - shader.m_FresnelPower.Set(inMaterial.m_FresnelPower); - - if (context.GetConstantBufferSupport()) { - NVRenderConstantBuffer *pLightCb = GetLightConstantBuffer(shader.m_Lights.size()); - // if we have lights we need a light buffer - QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightCb); - - for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); idx < end && pLightCb; ++idx) { - shader.m_Lights[idx].m_LightData.m_diffuse = - QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, - shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, - shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); - - // this is our final change update memory - pLightCb->UpdateRaw(idx * sizeof(SLightSourceShader) + (4 * sizeof(QT3DSI32)), - NVDataRef<QT3DSU8>((QT3DSU8 *)&shader.m_Lights[idx].m_LightData, - sizeof(SLightSourceShader))); - } - // update light buffer to hardware - if (pLightCb) { - QT3DSI32 cgLights = shader.m_Lights.size(); - pLightCb->UpdateRaw(0, NVDataRef<QT3DSU8>((QT3DSU8 *)&cgLights, sizeof(QT3DSI32))); - shader.m_LightsBuffer.Set(); - } - } else { - SLightConstantProperties<SShaderGeneratorGeneratedShader> *pLightConstants - = GetLightConstantProperties(shader); - - // if we have lights we need a light buffer - QT3DS_ASSERT(shader.m_Lights.size() == 0 || pLightConstants); - - for (QT3DSU32 idx = 0, end = shader.m_Lights.size(); - idx < end && pLightConstants; ++idx) { - shader.m_Lights[idx].m_LightData.m_diffuse = - QT3DSVec4(shader.m_Lights[idx].m_LightColor.x * inMaterial.m_DiffuseColor.x, - shader.m_Lights[idx].m_LightColor.y * inMaterial.m_DiffuseColor.y, - shader.m_Lights[idx].m_LightColor.z * inMaterial.m_DiffuseColor.z, 1.0); - } - // update light buffer to hardware - if (pLightConstants) - pLightConstants->updateLights(shader); - } - - shader.m_MaterialDiffuseLightAmbientTotal.Set( - QT3DSVec3(shader.m_LightAmbientTotal.x * inMaterial.m_DiffuseColor[0], - shader.m_LightAmbientTotal.y * inMaterial.m_DiffuseColor[1], - shader.m_LightAmbientTotal.z * inMaterial.m_DiffuseColor[2])); - - shader.m_MaterialProperties.Set(QT3DSVec4( - inMaterial.m_SpecularAmount, inMaterial.m_SpecularRoughness, emissivePower, 0.0f)); - shader.m_BumpAmount.Set(inMaterial.m_BumpAmount); - shader.m_DisplaceAmount.Set(inMaterial.m_DisplaceAmount); - shader.m_TranslucentFalloff.Set(inMaterial.m_TranslucentFalloff); - shader.m_DiffuseLightWrap.Set(inMaterial.m_DiffuseLightWrap); - QT3DSU32 imageIdx = 0; - for (SRenderableImage *theImage = inFirstImage; theImage; - theImage = theImage->m_NextImage, ++imageIdx) - SetImageShaderVariables(shader, *theImage, imageIdx); - - qt3ds::render::NVRenderBlendFunctionArgument blendFunc; - qt3ds::render::NVRenderBlendEquationArgument blendEqua(NVRenderBlendEquation::Add, - NVRenderBlendEquation::Add); - // The blend function goes: - // src op - // dst op - // src alpha op - // dst alpha op - // All of our shaders produce non-premultiplied values. - switch (inMaterial.m_BlendMode) { - case DefaultMaterialBlendMode::Screen: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::One, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - break; - case DefaultMaterialBlendMode::Multiply: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::DstColor, NVRenderDstBlendFunc::Zero, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::One); - break; - case DefaultMaterialBlendMode::Overlay: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::Overlay, NVRenderBlendEquation::Overlay); - break; - case DefaultMaterialBlendMode::ColorBurn: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorBurn, NVRenderBlendEquation::ColorBurn); - break; - case DefaultMaterialBlendMode::ColorDodge: - // SW fallback is not using blend equation - // note blend func is not used here anymore - if (context.IsAdvancedBlendHwSupported() || context.IsAdvancedBlendHwSupportedKHR()) - blendEqua = qt3ds::render::NVRenderBlendEquationArgument( - NVRenderBlendEquation::ColorDodge, NVRenderBlendEquation::ColorDodge); - break; - default: - blendFunc = qt3ds::render::NVRenderBlendFunctionArgument( - NVRenderSrcBlendFunc::SrcAlpha, NVRenderDstBlendFunc::OneMinusSrcAlpha, - NVRenderSrcBlendFunc::One, NVRenderDstBlendFunc::OneMinusSrcAlpha); - break; - } - context.SetBlendFunction(blendFunc); - context.SetBlendEquation(blendEqua); - } - void SetMaterialProperties(NVRenderShaderProgram &inProgram, - const SGraphObject &inMaterial, const QT3DSVec2 &inCameraVec, - const QT3DSMat44 &inModelViewProjection, - const QT3DSMat33 &inNormalMatrix, - const QT3DSMat44 &inGlobalTransform, - SRenderableImage *inFirstImage, QT3DSF32 inOpacity, - SLayerGlobalRenderProperties inRenderProperties) override - { - const SDefaultMaterial &theMaterial(static_cast<const SDefaultMaterial &>(inMaterial)); - QT3DS_ASSERT(inMaterial.m_Type == GraphObjectTypes::DefaultMaterial); - - SetGlobalProperties(inProgram, inRenderProperties.m_Layer, inRenderProperties.m_Camera, - inRenderProperties.m_CameraDirection, inRenderProperties.m_Lights, - inRenderProperties.m_LightDirections, - inRenderProperties.m_ShadowMapManager); - SetMaterialProperties(inProgram, theMaterial, inCameraVec, inModelViewProjection, - inNormalMatrix, inGlobalTransform, inFirstImage, inOpacity, - inRenderProperties.m_DepthTexture, inRenderProperties.m_SSaoTexture, - inRenderProperties.m_LightProbe, inRenderProperties.m_LightProbe2, - inRenderProperties.m_ProbeHorizon, inRenderProperties.m_ProbeBright, - inRenderProperties.m_Probe2Window, inRenderProperties.m_Probe2Pos, - inRenderProperties.m_Probe2Fade, inRenderProperties.m_ProbeFOV); - } - - SLightConstantProperties<SShaderGeneratorGeneratedShader> *GetLightConstantProperties(SShaderGeneratorGeneratedShader &shader) - { - if (!shader.m_lightConstantProperties - || int(shader.m_Lights.size()) - > shader.m_lightConstantProperties->m_constants.size()) { - if (shader.m_lightConstantProperties) - delete shader.m_lightConstantProperties; - shader.m_lightConstantProperties - = new SLightConstantProperties<SShaderGeneratorGeneratedShader>( - shader, m_LightsAsSeparateUniforms); - } - return shader.m_lightConstantProperties; - } -}; -} - -IDefaultMaterialShaderGenerator & -IDefaultMaterialShaderGenerator::CreateDefaultMaterialShaderGenerator(IQt3DSRenderContext &inRc) -{ - return *QT3DS_NEW(inRc.GetAllocator(), SShaderGenerator)(inRc); -} |