summaryrefslogtreecommitdiffstats
path: root/src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp')
m---------src/Runtime/ogl-runtime0
-rw-r--r--src/Runtime/ogl-runtime/src/runtimerender/Qt3DSRenderDefaultMaterialShaderGenerator.cpp1931
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);
-}