diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index 4e7ce55a5..062505f1c 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -45,6 +45,8 @@ S32 GFXTextureManager::smTextureReductionLevel = 0; String GFXTextureManager::smMissingTexturePath(Con::getVariable("$Core::MissingTexturePath")); String GFXTextureManager::smUnavailableTexturePath(Con::getVariable("$Core::UnAvailableTexturePath")); String GFXTextureManager::smWarningTexturePath(Con::getVariable("$Core::WarningTexturePath")); +String GFXTextureManager::smDefaultIrradianceCubemapPath(Con::getVariable("$Core::DefaultIrradianceCubemap")); +String GFXTextureManager::smDefaultPrefilterCubemapPath(Con::getVariable("$Core::DefaultPrefilterCubemap")); GFXTextureManager::EventSignal GFXTextureManager::smEventSignal; @@ -70,6 +72,14 @@ void GFXTextureManager::init() Con::addVariable( "$pref::Video::warningTexturePath", TypeRealString, &smWarningTexturePath, "The file path of the texture used to warn the developer.\n" "@ingroup GFX\n" ); + + Con::addVariable("$Core::DefaultIrradianceCubemap", TypeRealString, &smDefaultIrradianceCubemapPath, + "The file path of the texture used as the default irradiance cubemap for PBR.\n" + "@ingroup GFX\n"); + + Con::addVariable("$Core::DefaultPrefilterCubemap", TypeRealString, &smDefaultPrefilterCubemapPath, + "The file path of the texture used as the default specular cubemap for PBR.\n" + "@ingroup GFX\n"); } GFXTextureManager::GFXTextureManager() diff --git a/Engine/source/gfx/gfxTextureManager.h b/Engine/source/gfx/gfxTextureManager.h index d33582c5e..1254299f5 100644 --- a/Engine/source/gfx/gfxTextureManager.h +++ b/Engine/source/gfx/gfxTextureManager.h @@ -74,6 +74,9 @@ public: /// Provide the path to the texture used to warn the developer static const String& getWarningTexturePath() { return smWarningTexturePath; } + static const String& getDefaultIrradianceCubemapPath() { return smDefaultIrradianceCubemapPath; } + static const String& getDefaultPrefilterCubemapPath() { return smDefaultPrefilterCubemapPath; } + /// Update width and height based on available resources. /// /// We provide a simple interface for managing texture memory usage. Specifically, @@ -210,6 +213,9 @@ protected: /// File path to the warning texture static String smWarningTexturePath; + static String smDefaultIrradianceCubemapPath; + static String smDefaultPrefilterCubemapPath; + GFXTextureObject *mListHead; GFXTextureObject *mListTail; diff --git a/Engine/source/renderInstance/renderProbeMgr.cpp b/Engine/source/renderInstance/renderProbeMgr.cpp index 824577aa1..bced3a345 100644 --- a/Engine/source/renderInstance/renderProbeMgr.cpp +++ b/Engine/source/renderInstance/renderProbeMgr.cpp @@ -199,7 +199,8 @@ RenderProbeMgr::RenderProbeMgr() : RenderBinManager(RenderPassManager::RIT_Probes, 1.0f, 1.0f), mLastShader(nullptr), mLastConstants(nullptr), - mProbesDirty(false) + mProbesDirty(false), + hasSkylight(false) { mEffectiveProbeCount = 0; mMipCount = 0; @@ -250,13 +251,17 @@ bool RenderProbeMgr::onAdd() //create our own default default skylight mDefaultSkyLight = new ProbeRenderInst; mDefaultSkyLight->mProbeShapeType = ProbeRenderInst::Skylight; - if (!mDefaultSkyLight->mIrradianceCubemap.set("core/art/pbr/default_irradiance.dds")) + mDefaultSkyLight->mIsEnabled = false; + + String defaultIrradMapPath = GFXTextureManager::getDefaultIrradianceCubemapPath(); + if (!mDefaultSkyLight->mIrradianceCubemap.set(defaultIrradMapPath)) { Con::errorf("RenderProbeMgr::onAdd: Failed to load default irradiance cubemap"); return false; } - if (!mDefaultSkyLight->mPrefilterCubemap.set("core/art/pbr/default_prefilter.dds")) + String defaultPrefilterPath = GFXTextureManager::getDefaultPrefilterCubemapPath(); + if (!mDefaultSkyLight->mPrefilterCubemap.set(defaultPrefilterPath)) { Con::errorf("RenderProbeMgr::onAdd: Failed to load default prefilter cubemap"); return false; @@ -825,15 +830,15 @@ void RenderProbeMgr::render( SceneRenderState *state ) mProbeArrayEffect->setShaderConst("$probeContribColors", contribColors); } - - mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData); - mProbeArrayEffect->setShaderConst("$inRefPosArray", probeRefPositionsData); - mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData); - mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData); - mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData); - mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData); } + mProbeArrayEffect->setShaderConst("$inProbePosArray", probePositionsData); + mProbeArrayEffect->setShaderConst("$inRefPosArray", probeRefPositionsData); + mProbeArrayEffect->setShaderConst("$worldToObjArray", probeWorldToObjData); + mProbeArrayEffect->setShaderConst("$bbMinArray", probeBBMinData); + mProbeArrayEffect->setShaderConst("$bbMaxArray", probeBBMaxData); + mProbeArrayEffect->setShaderConst("$probeConfigData", probeConfigData); + // Make sure the effect is gonna render. getProbeArrayEffect()->setSkip(false); diff --git a/Engine/source/ts/assimp/assimpAppMaterial.cpp b/Engine/source/ts/assimp/assimpAppMaterial.cpp index 713ca9b87..8418445de 100644 --- a/Engine/source/ts/assimp/assimpAppMaterial.cpp +++ b/Engine/source/ts/assimp/assimpAppMaterial.cpp @@ -210,10 +210,10 @@ void AssimpAppMaterial::initMaterial(const Torque::Path& path, Material* mat) co mat->mSpecularMapFilename[0] = cleanTextureName(torquePath, cleanFile); } - LinearColorF specularColor(1.0f, 1.0f, 1.0f, 1.0f); + /*LinearColorF specularColor(1.0f, 1.0f, 1.0f, 1.0f); if (AI_SUCCESS == mAIMat->Get(AI_MATKEY_COLOR_SPECULAR, read_color)) specularColor.set(read_color.r, read_color.g, read_color.b, opacity); - mat->mSpecular[0] = specularColor; + mat->mMetalness[0] = specularColor; // Specular Power F32 specularPower = 1.0f; @@ -223,7 +223,7 @@ void AssimpAppMaterial::initMaterial(const Torque::Path& path, Material* mat) co // Specular F32 specularStrength = 0.0f; if (AI_SUCCESS == mAIMat->Get(AI_MATKEY_SHININESS, specularStrength)) - mat->mSpecularStrength[0] = specularStrength; + mat->mSpecularStrength[0] = specularStrength;*/ #endif // Double-Sided @@ -343,4 +343,4 @@ void AssimpAppMaterial::enumerateMaterialProperties(aiMaterial* mtl) } } } -#endif \ No newline at end of file +#endif diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs index dd70e31ea..e3229b93e 100644 --- a/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs +++ b/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs @@ -44,6 +44,9 @@ function clientCmdMissionStartPhase1(%seq, %missionName) echo ("*** New Mission: " @ %missionName); echo ("*** Phase 1: Download Datablocks & Targets"); + $Client::MissionFile = %missionName; + $pref::ReflectionProbes::CurrentLevelPath = filePath($Client::MissionFile) @ "/" @ fileBase($Client::MissionFile) @ "/probes/"; + //Prep the postFX stuff // Load the post effect presets for this mission. %path = filePath( %missionName ) @ "/" @ fileBase( %missionName ) @ $PostFXManager::fileExtension; diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 12 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 12 (ansi).uft index 67a177016..ebcc8a82f 100644 Binary files a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 12 (ansi).uft and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 12 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft index f4f19745f..8ac49b72a 100644 Binary files a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 16 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 16 (ansi).uft index fb096776f..f1f94acb3 100644 Binary files a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 16 (ansi).uft and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 16 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 18 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 18 (ansi).uft index 1f8fdedd3..8d0881956 100644 Binary files a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 18 (ansi).uft and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 18 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft index 5bac0316e..6babff51e 100644 Binary files a/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft and b/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft differ diff --git a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs index a73598d9b..3a52199b4 100644 --- a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs +++ b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs @@ -30,9 +30,16 @@ new GFXStateBlockData( AL_VectorLightState ) blendDest = GFXBlendOne; blendOp = GFXBlendOpAdd; + colorWriteDefined = true; + colorWriteRed = true; + colorWriteBlue = true; + colorWriteGreen = true; + colorWriteAlpha = false; //disable alpha write + zDefined = true; zEnable = false; - zWriteEnable = false; + zWriteEnable = true; + zFunc = GFXCmpGreater; samplersDefined = true; samplerStates[0] = SamplerClampPoint; // G-buffer @@ -49,12 +56,8 @@ new GFXStateBlockData( AL_VectorLightState ) cullMode = GFXCullNone; stencilDefined = true; - stencilEnable = true; - stencilFailOp = GFXStencilOpKeep; - stencilZFailOp = GFXStencilOpKeep; - stencilPassOp = GFXStencilOpKeep; - stencilFunc = GFXCmpLess; - stencilRef = 0; + stencilEnable = false; + }; // Vector Light Material @@ -87,11 +90,11 @@ new CustomMaterial( AL_VectorLightMaterial ) sampler["shadowMap"] = "$dynamiclight"; sampler["dynamicShadowMap"] = "$dynamicShadowMap"; sampler["ssaoMask"] = "#ssaoMask"; - sampler["lightBuffer"] = "#lightinfo"; + sampler["lightBuffer"] = "#specularLighting"; sampler["colorBuffer"] = "#color"; sampler["matInfoBuffer"] = "#matinfo"; - target = "lightinfo"; + target = "AL_FormatToken"; pixVersion = 3.0; }; @@ -107,10 +110,16 @@ new GFXStateBlockData( AL_ConvexLightState ) blendDest = GFXBlendOne; blendOp = GFXBlendOpAdd; + colorWriteDefined = true; + colorWriteRed = true; + colorWriteBlue = true; + colorWriteGreen = true; + colorWriteAlpha = false; //disable alpha write + zDefined = true; zEnable = true; zWriteEnable = false; - zFunc = GFXCmpGreaterEqual; + zFunc = GFXCmpGreater; samplersDefined = true; samplerStates[0] = SamplerClampPoint; // G-buffer @@ -126,12 +135,8 @@ new GFXStateBlockData( AL_ConvexLightState ) cullMode = GFXCullCW; stencilDefined = true; - stencilEnable = true; - stencilFailOp = GFXStencilOpKeep; - stencilZFailOp = GFXStencilOpKeep; - stencilPassOp = GFXStencilOpKeep; - stencilFunc = GFXCmpLess; - stencilRef = 0; + stencilEnable = false; + }; // Point Light Material @@ -164,11 +169,11 @@ new CustomMaterial( AL_PointLightMaterial ) sampler["shadowMap"] = "$dynamiclight"; sampler["dynamicShadowMap"] = "$dynamicShadowMap"; sampler["cookieMap"] = "$dynamiclightmask"; - sampler["lightBuffer"] = "#lightinfo"; + sampler["lightBuffer"] = "#specularLighting"; sampler["colorBuffer"] = "#color"; sampler["matInfoBuffer"] = "#matinfo"; - target = "lightinfo"; + target = "AL_FormatToken"; pixVersion = 3.0; }; @@ -203,11 +208,11 @@ new CustomMaterial( AL_SpotLightMaterial ) sampler["shadowMap"] = "$dynamiclight"; sampler["dynamicShadowMap"] = "$dynamicShadowMap"; sampler["cookieMap"] = "$dynamiclightmask"; - sampler["lightBuffer"] = "#lightinfo"; + sampler["lightBuffer"] = "#specularLighting"; sampler["colorBuffer"] = "#color"; sampler["matInfoBuffer"] = "#matinfo"; - target = "lightinfo"; + target = "AL_FormatToken"; pixVersion = 3.0; }; @@ -270,7 +275,84 @@ new CustomMaterial( AL_ParticlePointLightMaterial ) stateBlock = AL_ConvexLightState; sampler["deferredBuffer"] = "#deferred"; - target = "lightinfo"; + target = "diffuseLighting"; pixVersion = 3.0; }; + +//Probe Processing +new ShaderData( IrradianceShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/cubemapV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/irradianceP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/cubemapV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/irradianceP.glsl"; + + samplerNames[0] = "$environmentMap"; + + pixVersion = 3.0; +}; + +new ShaderData( PrefiterCubemapShader ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/cubemapV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/prefilterP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/cubemapV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/prefilterP.glsl"; + + samplerNames[0] = "$environmentMap"; + + pixVersion = 3.0; +}; + +// +singleton ShaderData( PFX_ReflectionProbeArray ) +{ + DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/reflectionProbeArrayP.hlsl"; + + OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/reflectionProbeArrayP.glsl"; + + samplerNames[0] = "$deferredBuffer"; + samplerNames[1] = "$colorBuffer"; + samplerNames[2] = "$matInfoBuffer"; + samplerNames[3] = "$BRDFTexture"; + samplerNames[4] = "$specularCubemapAR"; + samplerNames[5] = "$irradianceCubemapAR"; + samplerNames[6] = "$skylightSpecularMap"; + samplerNames[7] = "$skylightIrradMap"; + + pixVersion = 2.0; +}; + +singleton GFXStateBlockData( PFX_ReflectionProbeArrayStateBlock ) +{ + alphaDefined = true; + alphaTestEnable = true; + alphaTestRef = 1; + alphaTestFunc = GFXCmpGreaterEqual; + + // Do a one to one blend. + blendDefined = true; + blendEnable = true; + blendSrc = GFXBlendOne; + blendDest = GFXBlendOne; + + zDefined = true; + zEnable = false; + zWriteEnable = false; + + + samplersDefined = true; + samplerStates[0] = SamplerClampPoint; + samplerStates[1] = SamplerClampPoint; + samplerStates[2] = SamplerClampPoint; + samplerStates[3] = SamplerClampPoint; + samplerStates[4] = SamplerClampLinear; + samplerStates[5] = SamplerClampLinear; + samplerStates[6] = SamplerClampLinear; + samplerStates[7] = SamplerClampLinear; +}; \ No newline at end of file diff --git a/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs index 99be20c5c..46dc45509 100644 --- a/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs +++ b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs @@ -64,7 +64,7 @@ singleton CustomMaterial( BL_ProjectedShadowMaterial ) function onActivateBasicLM() { // If HDR is enabled... enable the special format token. - if ( $platform !$= "macos" && HDRPostFx.isEnabled ) + if ( HDRPostFx.isEnabled ) AL_FormatToken.enable(); // Create render pass for projected shadow. diff --git a/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs b/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs index 5dbacd2e3..eb6afe74c 100644 --- a/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs +++ b/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs @@ -1,14 +1,3 @@ -singleton ShaderData( ClearGBufferShader ) -{ - DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/deferredClearGBufferV.hlsl"; - DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/deferredClearGBufferP.hlsl"; - - OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl"; - OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/deferredClearGBufferP.glsl"; - - pixVersion = 2.0; -}; - singleton ShaderData( DeferredColorShader ) { DXVertexShaderFile = $Core::CommonShaderPath @ "/postFx/postFxV.hlsl"; @@ -20,15 +9,15 @@ singleton ShaderData( DeferredColorShader ) pixVersion = 2.0; }; -// Primary Deferred Shader -new GFXStateBlockData( AL_DeferredShadingState : PFX_DefaultStateBlock ) -{ - cullMode = GFXCullNone; +new GFXStateBlockData( AL_DeferredCaptureState : PFX_DefaultStateBlock ) +{ + blendEnable = false; - blendDefined = true; - blendEnable = true; - blendSrc = GFXBlendSrcAlpha; - blendDest = GFXBlendInvSrcAlpha; + separateAlphaBlendDefined = true; + separateAlphaBlendEnable = true; + separateAlphaBlendSrc = GFXBlendSrcAlpha; + separateAlphaBlendDest = GFXBlendDestAlpha; + separateAlphaBlendOp = GFXBlendOpMin; samplersDefined = true; samplerStates[0] = SamplerWrapLinear; @@ -38,33 +27,33 @@ new GFXStateBlockData( AL_DeferredShadingState : PFX_DefaultStateBlock ) samplerStates[4] = SamplerWrapLinear; }; -new ShaderData( AL_DeferredShader ) +new ShaderData( AL_ProbeShader ) { DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl"; - DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/deferredShadingP.hlsl"; + DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/probeShadingP.hlsl"; OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl"; - OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/deferredShadingP.glsl"; + OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/probeShadingP.glsl"; samplerNames[0] = "colorBufferTex"; - samplerNames[1] = "lightDeferredTex"; + samplerNames[1] = "diffuseLightingBuffer"; samplerNames[2] = "matInfoTex"; - samplerNames[3] = "deferredTex"; - + samplerNames[3] = "specularLightingBuffer"; + samplerNames[4] = "deferredTex"; pixVersion = 2.0; }; -singleton PostEffect( AL_DeferredShading ) +singleton PostEffect( AL_PreCapture ) { - renderTime = "PFXAfterBin"; - renderBin = "SkyBin"; - shader = AL_DeferredShader; - stateBlock = AL_DeferredShadingState; + renderTime = "PFXBeforeBin"; + renderBin = "EditorBin"; + shader = AL_ProbeShader; + stateBlock = AL_DeferredCaptureState; texture[0] = "#color"; - texture[1] = "#lightinfo"; + texture[1] = "#diffuseLighting"; texture[2] = "#matinfo"; - texture[3] = "#deferred"; - + texture[3] = "#specularLighting"; + texture[4] = "#deferred"; target = "$backBuffer"; renderPriority = 10000; allowReflectPass = true; diff --git a/Templates/BaseGame/game/core/postFX/scripts/hdr.cs b/Templates/BaseGame/game/core/postFX/scripts/hdr.cs index 3b2de8b7b..b5ee40f03 100644 --- a/Templates/BaseGame/game/core/postFX/scripts/hdr.cs +++ b/Templates/BaseGame/game/core/postFX/scripts/hdr.cs @@ -170,7 +170,6 @@ singleton ShaderData( HDR_CombineShader ) samplerNames[1] = "$luminanceTex"; samplerNames[2] = "$bloomTex"; samplerNames[3] = "$colorCorrectionTex"; - samplerNames[4] = "deferredTex"; pixVersion = 3.0; }; @@ -295,7 +294,7 @@ function HDRPostFX::onEnabled( %this ) // Change the format of the offscreen surface // to an HDR compatible format. - AL_FormatToken.format = %format; + %this.previousFormat = AL_FormatToken.format; setReflectFormat( %format ); // Reset the light manager which will ensure the new @@ -312,7 +311,7 @@ function HDRPostFX::onDisabled( %this ) GammaPostFX.enable(); // Restore the non-HDR offscreen surface format. - %format = getBestHDRFormat(); + %format = %this.previousFormat; AL_FormatToken.format = %format; setReflectFormat( %format ); diff --git a/Templates/BaseGame/game/core/postFX/scripts/pbr.cs b/Templates/BaseGame/game/core/postFX/scripts/pbr.cs new file mode 100644 index 000000000..89f65eb5d --- /dev/null +++ b/Templates/BaseGame/game/core/postFX/scripts/pbr.cs @@ -0,0 +1,19 @@ +singleton PostEffect( reflectionProbeArrayPostFX ) +{ + // Do not allow the selection effect to work in reflection + // passes by default so we don't do the extra drawing. + //allowReflectPass = false; + + renderTime = "PFXAfterBin"; + renderBin = "ProbeBin"; + renderPriority = 9999; + isEnabled = true; + + shader = PFX_ReflectionProbeArray; + stateBlock = PFX_ReflectionProbeArrayStateBlock; + + texture[0] = "#deferred"; + texture[1] = "#color"; + texture[2] = "#matinfo"; + texture[3] = "core/rendering/images/brdfTexture.dds"; +}; diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.cs b/Templates/BaseGame/game/core/rendering/Core_Rendering.cs index d09e0cbe3..8fc913948 100644 --- a/Templates/BaseGame/game/core/rendering/Core_Rendering.cs +++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.cs @@ -5,6 +5,8 @@ function Core_Rendering::onCreate(%this) $Core::UnAvailableTexturePath = "core/rendering/images/unavailable"; $Core::WarningTexturePath = "core/rendering/images/warnMat"; $Core::CommonShaderPath = "core/rendering/shaders"; + $Core::DefaultIrradianceCubemap = "core/rendering/images/default_irradiance.dds"; + $Core::DefaultPrefilterCubemap = "core/rendering/images/default_prefilter.dds"; exec("./scripts/renderManager.cs"); exec("./scripts/gfxData/clouds.cs"); diff --git a/Templates/BaseGame/game/core/rendering/images/brdfTexture.dds b/Templates/BaseGame/game/core/rendering/images/brdfTexture.dds new file mode 100644 index 000000000..33c50918c Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/brdfTexture.dds differ diff --git a/Templates/BaseGame/game/core/rendering/images/default_irradiance.dds b/Templates/BaseGame/game/core/rendering/images/default_irradiance.dds new file mode 100644 index 000000000..4cd4bdc6e Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/default_irradiance.dds differ diff --git a/Templates/BaseGame/game/core/rendering/images/default_prefilter.dds b/Templates/BaseGame/game/core/rendering/images/default_prefilter.dds new file mode 100644 index 000000000..0d9e41939 Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/default_prefilter.dds differ diff --git a/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs b/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs index 4a80a45b1..d0d08f26b 100644 --- a/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs +++ b/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs @@ -48,9 +48,7 @@ function initRenderManager() }; DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 0.001; stateToken = AL_FormatToken; } ); - // We really need to fix the sky to render after all the - // meshes... but that causes issues in reflections. - DiffuseRenderPassManager.addManager( new RenderObjectMgr(SkyBin) { bintype = "Sky"; renderOrder = 0.1; processAddOrder = 0.1; } ); + DiffuseRenderPassManager.addManager( new RenderProbeMgr(ProbeBin) { bintype = "Probes"; renderOrder = 0.019; processAddOrder = 0.019; } ); //DiffuseRenderPassManager.addManager( new RenderVistaMgr() { bintype = "Vista"; renderOrder = 0.15; processAddOrder = 0.15; } ); @@ -65,6 +63,10 @@ function initRenderManager() DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalRoadBin) { bintype = "DecalRoad"; renderOrder = 0.8; processAddOrder = 0.8; } ); DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalBin) { bintype = "Decal"; renderOrder = 0.81; processAddOrder = 0.81; } ); DiffuseRenderPassManager.addManager( new RenderOcclusionMgr(OccluderBin){ bintype = "Occluder"; renderOrder = 0.9; processAddOrder = 0.9; } ); + + // Render the sky last + DiffuseRenderPassManager.addManager( new RenderObjectMgr(SkyBin) { bintype = "Sky"; renderOrder = 0.95; processAddOrder = 0.95; } ); + // We now render translucent objects that should handle // their own fogging and lighting. diff --git a/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl index a176fdbcd..79976343c 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl @@ -46,7 +46,7 @@ ConnectData main( CloudVert IN ) ConnectData OUT; OUT.hpos = mul(modelview, float4(IN.pos,1.0)); - + OUT.hpos.z = OUT.hpos.w; float2 uv = IN.uv0; uv += texOffset; uv *= texScale; diff --git a/Templates/BaseGame/game/core/rendering/shaders/brdf.hlsl b/Templates/BaseGame/game/core/rendering/shaders/brdf.hlsl new file mode 100644 index 000000000..2fb7d221a --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/brdf.hlsl @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2018 GarageGames, LLC +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef BRDF_HLSL +#define BRDF_HLSL + +#include "./torque.hlsl" + +// BRDF from Frostbite presentation: +// Moving Frostbite to Physically Based Rendering +// S“ebastien Lagarde - Electronic Arts Frostbite +// Charles de Rousiers - Electronic Arts Frostbite +// SIGGRAPH 2014 + +float3 F_Schlick(in float3 f0, in float f90, in float u) +{ + return f0 + (f90 - f0) * pow(1.f - u, 5.f); +} + +float3 F_Fresnel(float3 SpecularColor, float VoH) +{ + float3 SpecularColorSqrt = sqrt(min(SpecularColor, float3(0.99, 0.99, 0.99))); + float3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt); + float3 g = sqrt(n*n + VoH*VoH - 1); + return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1))); +} + +float3 FresnelSchlickRoughness(float cosTheta, float3 F0, float roughness) +{ + float3 ret = float3(0.0, 0.0, 0.0); + float powTheta = pow(1.0 - cosTheta, 5.0); + float invRough = float(1.0 - roughness); + + ret.x = F0.x + (max(invRough, F0.x) - F0.x) * powTheta; + ret.y = F0.y + (max(invRough, F0.y) - F0.y) * powTheta; + ret.z = F0.z + (max(invRough, F0.z) - F0.z) * powTheta; + + return ret; +} + +float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness) +{ + float energyBias = lerp(0, 0.5, linearRoughness); + float energyFactor = lerp(1.0, 1.0 / 1.51, linearRoughness); + float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness; + float3 f0 = float3(1.0f, 1.0f, 1.0f); + float lightScatter = F_Schlick(f0, fd90, NdotL).r; + float viewScatter = F_Schlick(f0, fd90, NdotV).r; + + return lightScatter * viewScatter * energyFactor; +} + +float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaG2) +{ + // Original formulation of G_SmithGGX Correlated + // lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f; + // lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f; + // G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l); + // V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV); + + + // This is the optimized version + //float alphaG2 = alphaG * alphaG; + + // Caution: the "NdotL *" and "NdotV *" are explicitely inversed , this is not a mistake. + float Lambda_GGXV = NdotL * sqrt((-NdotV * alphaG2 + NdotV) * NdotV + alphaG2); + float Lambda_GGXL = NdotV * sqrt((-NdotL * alphaG2 + NdotL) * NdotL + alphaG2); + + return 0.5f / (Lambda_GGXV + Lambda_GGXL); +} + +float D_GGX(float NdotH, float m2) +{ + // Divide by PI is apply later + //float m2 = m * m; + float f = (NdotH * m2 - NdotH) * NdotH + 1; + return m2 / (f * f); +} + +#endif diff --git a/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl index d60dd251d..49b325b42 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl @@ -63,6 +63,7 @@ ConnectData main( CloudVert IN ) ConnectData OUT; OUT.hpos = mul(modelview, float4(IN.pos,1.0)); + OUT.hpos.z = OUT.hpos.w; // Offset the uv so we don't have a seam directly over our head. float2 uv = IN.uv0 + float2( 0.5, 0.5 ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl index cccbafa8c..5cd9d219e 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl @@ -41,6 +41,7 @@ out vec2 texCoord; void main() { gl_Position = tMul(modelview, IN_pos); + gl_Position.z = gl_Position.w; vec2 uv = IN_uv0; uv += texOffset; diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/brdf.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/brdf.glsl new file mode 100644 index 000000000..2b9709dab --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/brdf.glsl @@ -0,0 +1,98 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2018 GarageGames, LLC +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#ifndef BRDF_HLSL +#define BRDF_HLSL + +#include "./torque.glsl" + +// BRDF from Frostbite presentation: +// Moving Frostbite to Physically Based Rendering +// S“ebastien Lagarde - Electronic Arts Frostbite +// Charles de Rousiers - Electronic Arts Frostbite +// SIGGRAPH 2014 + +vec3 F_Schlick(in vec3 f0, in float f90, in float u) +{ + return f0 + (f90 - f0) * pow(1.f - u, 5.f); +} + +vec3 F_Fresnel(vec3 SpecularColor, float VoH) +{ + vec3 SpecularColorSqrt = sqrt(min(SpecularColor, vec3(0.99, 0.99, 0.99))); + vec3 n = (1 + SpecularColorSqrt) / (1 - SpecularColorSqrt); + vec3 g = sqrt(n*n + VoH*VoH - 1); + return 0.5 * sqr((g - VoH) / (g + VoH)) * (1 + sqr(((g + VoH)*VoH - 1) / ((g - VoH)*VoH + 1))); +} + +vec3 FresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) +{ + vec3 ret = vec3(0.0, 0.0, 0.0); + float powTheta = pow(1.0 - cosTheta, 5.0); + float invRough = float(1.0 - roughness); + + ret.x = F0.x + (max(invRough, F0.x) - F0.x) * powTheta; + ret.y = F0.y + (max(invRough, F0.y) - F0.y) * powTheta; + ret.z = F0.z + (max(invRough, F0.z) - F0.z) * powTheta; + + return ret; +} + +float Fr_DisneyDiffuse(float NdotV, float NdotL, float LdotH, float linearRoughness) +{ + float energyBias = lerp(0, 0.5, linearRoughness); + float energyFactor = lerp(1.0, 1.0 / 1.51, linearRoughness); + float fd90 = energyBias + 2.0 * LdotH*LdotH * linearRoughness; + vec3 f0 = vec3(1.0f, 1.0f, 1.0f); + float lightScatter = F_Schlick(f0, fd90, NdotL).r; + float viewScatter = F_Schlick(f0, fd90, NdotV).r; + + return lightScatter * viewScatter * energyFactor; +} + +float V_SmithGGXCorrelated(float NdotL, float NdotV, float alphaG2) +{ + // Original formulation of G_SmithGGX Correlated + // lambda_v = (-1 + sqrt(alphaG2 * (1 - NdotL2) / NdotL2 + 1)) * 0.5f; + // lambda_l = (-1 + sqrt(alphaG2 * (1 - NdotV2) / NdotV2 + 1)) * 0.5f; + // G_SmithGGXCorrelated = 1 / (1 + lambda_v + lambda_l); + // V_SmithGGXCorrelated = G_SmithGGXCorrelated / (4.0f * NdotL * NdotV); + + + // This is the optimized version + //float alphaG2 = alphaG * alphaG; + + // Caution: the "NdotL *" and "NdotV *" are explicitely inversed , this is not a mistake. + float Lambda_GGXV = NdotL * sqrt((-NdotV * alphaG2 + NdotV) * NdotV + alphaG2); + float Lambda_GGXL = NdotV * sqrt((-NdotL * alphaG2 + NdotL) * NdotL + alphaG2); + + return 0.5f / (Lambda_GGXV + Lambda_GGXL); +} + +float D_GGX(float NdotH, float m2) +{ + // Divide by PI is apply later + //float m2 = m * m; + float f = (NdotH * m2 - NdotH) * NdotH + 1; + return m2 / (f * f); +} + +#endif diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl index 395c6f286..a1085f755 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl @@ -62,6 +62,7 @@ void main() vec2 IN_uv0 = vTexCoord0.st; gl_Position = modelview * IN_pos; + gl_Position.z = gl_Position.w; // Offset the uv so we don't have a seam directly over our head. vec2 uv = IN_uv0 + vec2( 0.5, 0.5 ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveP.glsl new file mode 100644 index 000000000..ab1ab367f --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveP.glsl @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2016 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" +#include "torque.glsl" + +uniform samplerCube cubemapTex; + +in float3 face_pos_x; +in float3 face_neg_x; +in float3 face_pos_y; +in float3 face_neg_y; +in float3 face_pos_z; +in float3 face_neg_z; + +out float4 target0; +out float4 target1; +out float4 target2; +out float4 target3; +out float4 target4; +out float4 target5; +//----------------------------------------------------------------------------- +// Main +//----------------------------------------------------------------------------- +void main() +{ + target0 = texture(cubemapTex, face_pos_x); + target1 = texture(cubemapTex, face_neg_x); + target2 = texture(cubemapTex, face_pos_y); + target3 = texture(cubemapTex, face_neg_y); + target4 = texture(cubemapTex, face_pos_z); + target5 = texture(cubemapTex, face_neg_z); +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveV.glsl new file mode 100644 index 000000000..f51bf696a --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/cubemapSaveV.glsl @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2016 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "hlslCompat.glsl" +#include "torque.glsl" + +uniform float4x4 matrix0; +uniform float4x4 matrix1; +uniform float4x4 matrix2; +uniform float4x4 matrix3; +uniform float4x4 matrix4; +uniform float4x4 matrix5; + +out float3 face_pos_x; +out float3 face_neg_x; +out float3 face_pos_y; +out float3 face_neg_y; +out float3 face_pos_z; +out float3 face_neg_z; + +void main() +{ + float4 vertex = float4(float2((gl_VertexID << 1) & 2, gl_VertexID & 2) * float2(2, -2) + float2(-1, 1), 0, 1); + gl_Position = vertex; + correctSSP(gl_Position); + face_pos_x = tMul(matrix0, vertex).xyz; + face_neg_x = tMul(matrix1, vertex).xyz; + face_pos_y = tMul(matrix2, vertex).xyz; + face_neg_y = tMul(matrix3, vertex).xyz; + face_pos_z = tMul(matrix4, vertex).xyz; + face_neg_z = tMul(matrix5, vertex).xyz; +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl index 804ab1e3b..a00d4ad60 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC -// +// Portions Copyright Zefiros // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the @@ -21,9 +21,9 @@ //----------------------------------------------------------------------------- #include "./torque.glsl" - +#include "./brdf.glsl" #ifndef TORQUE_SHADERGEN - +#line 26 // These are the uniforms used by most lighting shaders. uniform vec4 inLightPos[3]; @@ -38,11 +38,31 @@ uniform vec4 inLightColor[4]; uniform vec4 ambient; #define ambientCameraFactor 0.3 -uniform float specularPower; -uniform vec4 specularColor; +uniform float smoothness; +uniform float metalness; +uniform vec4 albedo; #endif // !TORQUE_SHADERGEN +#define MAX_PROBES 50 +#define MAX_FORWARD_PROBES 4 + +vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, vec4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +vec3 getDistanceVectorToPlane( float negFarPlaneDotEye, vec3 direction, vec4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} void compute4Lights( vec3 wsView, vec3 wsPosition, @@ -57,193 +77,366 @@ void compute4Lights( vec3 wsView, vec4 inLightSpotDir[3], vec4 inLightSpotAngle, vec4 inLightSpotFalloff, - float specularPower, - vec4 specularColor, + float smoothness, + float metalness, + vec4 albedo, #endif // TORQUE_SHADERGEN out vec4 outDiffuse, out vec4 outSpecular ) { - // NOTE: The light positions and spotlight directions - // are stored in SoA order, so inLightPos[0] is the - // x coord for all 4 lights... inLightPos[1] is y... etc. - // - // This is the key to fully utilizing the vector units and - // saving a huge amount of instructions. - // - // For example this change saved more than 10 instructions - // over a simple for loop for each light. - - int i; - - vec4 lightVectors[3]; - for ( i = 0; i < 3; i++ ) - lightVectors[i] = wsPosition[i] - inLightPos[i]; - - vec4 squareDists = vec4(0); - for ( i = 0; i < 3; i++ ) - squareDists += lightVectors[i] * lightVectors[i]; - - // Accumulate the dot product between the light - // vector and the normal. - // - // The normal is negated because it faces away from - // the surface and the light faces towards the - // surface... this keeps us from needing to flip - // the light vector direction which complicates - // the spot light calculations. - // - // We normalize the result a little later. - // - vec4 nDotL = vec4(0); - for ( i = 0; i < 3; i++ ) - nDotL += lightVectors[i] * -wsNormal[i]; - - vec4 rDotL = vec4(0); - #ifndef TORQUE_BL_NOSPECULAR - - // We're using the Phong specular reflection model - // here where traditionally Torque has used Blinn-Phong - // which has proven to be more accurate to real materials. - // - // We do so because its cheaper as do not need to - // calculate the half angle for all 4 lights. - // - // Advanced Lighting still uses Blinn-Phong, but the - // specular reconstruction it does looks fairly similar - // to this. - // - vec3 R = reflect( wsView, -wsNormal ); - - for ( i = 0; i < 3; i++ ) - rDotL += lightVectors[i] * R[i]; - - #endif - - // Normalize the dots. - // - // Notice we're using the half type here to get a - // much faster sqrt via the rsq_pp instruction at - // the loss of some precision. - // - // Unless we have some extremely large point lights - // i don't believe the precision loss will matter. - // - half4 correction = half4(inversesqrt( squareDists )); - nDotL = saturate( nDotL * correction ); - rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); - - // First calculate a simple point light linear - // attenuation factor. - // - // If this is a directional light the inverse - // radius should be greater than the distance - // causing the attenuation to have no affect. - // - vec4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); - - #ifndef TORQUE_BL_NOSPOTLIGHT - - // The spotlight attenuation factor. This is really - // fast for what it does... 6 instructions for 4 spots. - - vec4 spotAtten = vec4(0); - for ( i = 0; i < 3; i++ ) - spotAtten += lightVectors[i] * inLightSpotDir[i]; - - vec4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; - atten *= saturate( cosAngle * inLightSpotFalloff ); - - #endif - - // Finally apply the shadow masking on the attenuation. - atten *= shadowMask; - - // Get the final light intensity. - vec4 intensity = nDotL * atten; - - // Combine the light colors for output. - outDiffuse = vec4(0); - for ( i = 0; i < 4; i++ ) - outDiffuse += intensity[i] * inLightColor[i]; - - // Output the specular power. - vec4 specularIntensity = pow( rDotL, vec4(specularPower) ) * atten; - - // Apply the per-light specular attenuation. - vec4 specular = vec4(0,0,0,1); - for ( i = 0; i < 4; i++ ) - specular += vec4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); - - // Add the final specular intensity values together - // using a single dot product operation then get the - // final specular lighting color. - outSpecular = specularColor * specular; + outDiffuse = vec4(0,0,0,0); + outSpecular = vec4(0,0,0,0); } - -// This value is used in AL as a constant power to raise specular values -// to, before storing them into the light info buffer. The per-material -// specular value is then computer by using the integer identity of -// exponentiation: -// -// (a^m)^n = a^(m*n) -// -// or -// -// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) -// -#define AL_ConstantSpecularPower 12.0f - -/// The specular calculation used in Advanced Lighting. -/// -/// @param toLight Normalized vector representing direction from the pixel -/// being lit, to the light source, in world space. -/// -/// @param normal Normalized surface normal. -/// -/// @param toEye The normalized vector representing direction from the pixel -/// being lit to the camera. -/// -float AL_CalcSpecular( vec3 toLight, vec3 normal, vec3 toEye ) +struct Surface { - // (R.V)^c - float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + vec3 P; // world space position + vec3 N; // world space normal + vec3 V; // world space view vector + vec4 baseColor; // base color [0 -> 1] (rgba) + float metalness; // metalness [0:dielectric -> 1:metal] + float roughness; // roughness: [0:smooth -> 1:rough] (linear) + float roughness_brdf; // roughness remapped from linear to BRDF + float depth; // depth: [0:near -> 1:far] (linear) + float ao; // ambient occlusion [0 -> 1] + float matFlag; // material flag - use getFlag to retreive - // Return the specular factor. - return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); + float NdotV; // cos(angle between normal and view vector) + vec3 f0; // fresnel value (rgb) + vec3 albedo; // diffuse light absorbtion value (rgb) + vec3 R; // reflection vector + vec3 F; // fresnel term computed from f0, N and V + void Update(); +}; + +void Surface::Update() +{ + NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact + + albedo = baseColor.rgb * (1.0 - metalness); + f0 = lerp(vec3(0.04), baseColor.rgb, metalness); + R = -reflect(V, N); + float f90 = saturate(50.0 * dot(f0, vec3(0.33,0.33,0.33))); + F = F_Schlick(f0, f90, NdotV); +} + +Surface createSurface(vec4 normDepth, sampler2D colorBuffer, sampler2D matInfoBuffer, in vec2 uv, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4 invView) +{ + Surface surface;// = Surface(); + + vec4 gbuffer1 = texture(colorBuffer, uv); + vec4 gbuffer2 = texture(matInfoBuffer, uv); + surface.depth = normDepth.a; + surface.P = wsEyePos + wsEyeRay * surface.depth; + surface.N = tMul(invView, vec4(normDepth.xyz,0)).xyz; //TODO move t3d to use WS normals + surface.V = normalize(wsEyePos - surface.P); + surface.baseColor = gbuffer1; + const float minRoughness=1e-4; + surface.roughness = clamp(1.0 - gbuffer2.b, minRoughness, 1.0); //t3d uses smoothness, so we convert to roughness. + surface.roughness_brdf = surface.roughness * surface.roughness; + surface.metalness = gbuffer2.a; + surface.ao = gbuffer2.g; + surface.matFlag = gbuffer2.r; + surface.Update(); + return surface; } -/// The output for Deferred Lighting -/// -/// @param toLight Normalized vector representing direction from the pixel -/// being lit, to the light source, in world space. -/// -/// @param normal Normalized surface normal. -/// -/// @param toEye The normalized vector representing direction from the pixel -/// being lit to the camera. -/// -vec4 AL_DeferredOutput( - vec3 lightColor, - vec3 diffuseColor, - vec4 matInfo, - vec4 ambient, - float specular, - float shadowAttenuation) +Surface createForwardSurface(vec4 baseColor, vec4 normal, vec4 pbrProperties, in vec2 uv, in vec3 wsPosition, in vec3 wsEyePos, in vec3 wsEyeRay, in mat4x4 invView) { - vec3 specularColor = vec3(specular); - bool metalness = getFlag(matInfo.r, 3); - if ( metalness ) - { - specularColor = 0.04 * (1 - specular) + diffuseColor * specular; + Surface surface;// = Surface(); + + surface.depth = 0; + surface.P = wsPosition; + surface.N = tMul(invView, vec4(normal.xyz,0)).xyz; //TODO move t3d to use WS normals + surface.V = normalize(wsEyePos - surface.P); + surface.baseColor = baseColor; + const float minRoughness=1e-4; + surface.roughness = clamp(1.0 - pbrProperties.b, minRoughness, 1.0); //t3d uses smoothness, so we convert to roughness. + surface.roughness_brdf = surface.roughness * surface.roughness; + surface.metalness = pbrProperties.a; + surface.ao = pbrProperties.g; + surface.matFlag = pbrProperties.r; + + surface.Update(); + return surface; +} + +struct SurfaceToLight +{ + vec3 L; // surface to light vector + vec3 Lu; // un-normalized surface to light vector + vec3 H; // half-vector between view vector and light vector + float NdotL; // cos(angle between N and L) + float HdotV; // cos(angle between H and V) = HdotL = cos(angle between H and L) + float NdotH; // cos(angle between N and H) + +}; + +SurfaceToLight createSurfaceToLight(in Surface surface, in vec3 L) +{ + SurfaceToLight surfaceToLight;// = SurfaceToLight(); + surfaceToLight.Lu = L; + surfaceToLight.L = normalize(L); + surfaceToLight.H = normalize(surface.V + surfaceToLight.L); + surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N)); + surfaceToLight.HdotV = saturate(dot(surfaceToLight.H, surface.V)); + surfaceToLight.NdotH = saturate(dot(surfaceToLight.H, surface.N)); + return surfaceToLight; +} + +vec3 BRDF_GetSpecular(in Surface surface, in SurfaceToLight surfaceToLight) +{ + float f90 = saturate(50.0 * dot(surface.f0, vec3(0.33,0.33,0.33))); + vec3 F = F_Schlick(surface.f0, f90, surfaceToLight.HdotV); + float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness_brdf); + float D = D_GGX(surfaceToLight.NdotH, surface.roughness_brdf); + vec3 Fr = D * F * Vis / M_PI_F; + return Fr; +} + +vec3 BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight) +{ + //getting some banding with disney method, using lambert instead - todo futher testing + float Fd = 1.0 / M_PI_F; + //energy conservation - remove this if reverting back to disney method + vec3 kD = vec3(1.0) - surface.F; + kD *= 1.0 - surface.metalness; + vec3 diffuse = kD * surface.baseColor.rgb * Fd; + return diffuse; +} + +//attenuations functions from "moving frostbite to pbr paper" +//https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf +float smoothDistanceAtt ( float squaredDistance , float invSqrAttRadius ) +{ + float factor = squaredDistance * invSqrAttRadius ; + float smoothFactor = saturate (1.0f - factor * factor ); + return sqr(smoothFactor); +} + +float getDistanceAtt( vec3 unormalizedLightVector , float invSqrAttRadius ) +{ + float sqrDist = dot ( unormalizedLightVector , unormalizedLightVector ); + float attenuation = 1.0 / (max ( sqrDist , 0.01*0.01) ); + attenuation *= smoothDistanceAtt ( sqrDist , invSqrAttRadius ); + return attenuation; +} + + float getSpotAngleAtt( vec3 normalizedLightVector , vec3 lightDir , vec2 lightSpotParams ) + { + float cd = dot ( lightDir , normalizedLightVector ); + float attenuation = saturate ( ( cd - lightSpotParams.x ) / lightSpotParams.y ); + // smooth the transition + return sqr(attenuation); +} + +vec3 getDirectionalLight(in Surface surface, in SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float shadow) +{ + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity; + vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + vec3 final = max(vec3(0.0f), diffuse + spec * surface.ao); + return final; +} + +vec3 getPunctualLight(in Surface surface, in SurfaceToLight surfaceToLight, vec3 lightColor, float lightIntensity, float radius, float shadow) +{ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + vec3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + vec3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + vec3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + vec3 final = max(vec3(0.0f), diffuse + spec * surface.ao * surface.F); + return final; +} + +float G1V(float dotNV, float k) +{ + return 1.0f/(dotNV*(1.0f-k)+k); +} + +vec3 directSpecular(vec3 N, vec3 V, vec3 L, float roughness, float F0) +{ + float alpha = roughness*roughness; + + //TODO don't need to calculate all this again timmy!!!!!! + vec3 H = normalize(V + L); + float dotNL = clamp(dot(N,L), 0.0, 1.0); + float dotNV = clamp(dot(N,V), 0.0, 1.0); + float dotNH = clamp(dot(N,H), 0.0, 1.0); + float dotHV = clamp(dot(H,V), 0.0, 1.0); + float dotLH = clamp(dot(L,H), 0.0, 1.0); + + float F, D, vis; + + // D + float alphaSqr = alpha*alpha; + float pi = 3.14159f; + float denom = dotNH * dotNH *(alphaSqr-1.0) + 1.0f; + D = alphaSqr/(pi * denom * denom); + + // F + float dotLH5 = pow(1.0f-dotLH,5); + F = F0 + (1.0-F0)*(dotLH5); + + // V + float k = alpha/2.0f; + vis = G1V(dotNL,k)*G1V(dotNV,k); + + float specular = dotNL * D * F * vis; + return vec3(specular,specular,specular); +} + +//Probe IBL stuff +float defineSphereSpaceInfluence(vec3 wsPosition, vec3 wsProbePosition, float radius) +{ + vec3 L = wsProbePosition.xyz - wsPosition; + float contribution = 1.0 - length(L) / radius; + return contribution; +} + +float getDistBoxToPoint(vec3 pt, vec3 extents) +{ + vec3 d = max(max(-extents - pt, 0), pt - extents); + return max(max(d.x, d.y), d.z); +} + +float defineBoxSpaceInfluence(vec3 wsPosition, mat4 worldToObj, float attenuation) +{ + vec3 surfPosLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz; + float atten = 1.0 - attenuation; + float baseVal = 0.25; + float dist = getDistBoxToPoint(surfPosLS, vec3(baseVal, baseVal, baseVal)); + return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist)); +} + +// Box Projected IBL Lighting +// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ +// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +vec3 boxProject(vec3 wsPosition, vec3 wsReflectVec, mat4 worldToObj, vec3 bbMin, vec3 bbMax, vec3 refPosition) +{ + vec3 RayLS = tMul(worldToObj, vec4(wsReflectVec, 0.0)).xyz; + vec3 PositionLS = tMul(worldToObj, vec4(wsPosition, 1.0)).xyz; + + vec3 unit = bbMax.xyz - bbMin.xyz; + vec3 plane1vec = (unit / 2 - PositionLS) / RayLS; + vec3 plane2vec = (-unit / 2 - PositionLS) / RayLS; + vec3 furthestPlane = max(plane1vec, plane2vec); + float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); + vec3 posonbox = wsPosition + wsReflectVec * dist; + + return posonbox - refPosition.xyz; +} + +vec4 computeForwardProbes(Surface surface, + float cubeMips, float numProbes, mat4x4 worldToObjArray[MAX_FORWARD_PROBES], vec4 probeConfigData[MAX_FORWARD_PROBES], + vec4 inProbePosArray[MAX_FORWARD_PROBES], vec4 bbMinArray[MAX_FORWARD_PROBES], vec4 bbMaxArray[MAX_FORWARD_PROBES], vec4 inRefPosArray[MAX_FORWARD_PROBES], + float hasSkylight, sampler2D BRDFTexture, + samplerCube skylightIrradMap, samplerCube skylightSpecularMap, + samplerCubeArray irradianceCubemapAR, samplerCubeArray specularCubemapAR) +{ + int i = 0; + float blendFactor[MAX_FORWARD_PROBES]; + float blendSum = 0; + float blendFacSum = 0; + float invBlendSum = 0; + float probehits = 0; + //Set up our struct data + float contribution[MAX_FORWARD_PROBES]; + for (i = 0; i < numProbes; ++i) + { + contribution[i] = 0; + + if (probeConfigData[i].r == 0) //box + { + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + if (contribution[i] > 0.0) + probehits++; + } + else if (probeConfigData[i].r == 1) //sphere + { + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + if (contribution[i] > 0.0) + probehits++; + } + + contribution[i] = max(contribution[i], 0); + + blendSum += contribution[i]; + invBlendSum += (1.0f - contribution[i]); } - //specular = color * map * spec^gloss - float specularOut = (specularColor * matInfo.b * min(pow(max(specular,1.0f), max((matInfo.a / AL_ConstantSpecularPower),1.0f)),matInfo.a)).r; - - lightColor *= vec3(shadowAttenuation); - lightColor += ambient.rgb; - return vec4(lightColor.rgb, specularOut); -} + if (probehits > 1.0) + { + for (i = 0; i < numProbes; i++) + { + blendFactor[i] = ((contribution[i] / blendSum)) / probehits; + blendFactor[i] *= ((contribution[i]) / invBlendSum); + blendFactor[i] = saturate(blendFactor[i]); + blendFacSum += blendFactor[i]; + } + + // Normalize blendVal + if (blendFacSum == 0.0f) // Possible with custom weight + { + blendFacSum = 1.0f; + } + + float invBlendSumWeighted = 1.0f / blendFacSum; + for (i = 0; i < numProbes; ++i) + { + blendFactor[i] *= invBlendSumWeighted; + contribution[i] *= blendFactor[i]; + } + } + + vec3 irradiance = vec3(0, 0, 0); + vec3 specular = vec3(0, 0, 0); + + // Radiance (Specular) + float lod = surface.roughness*cubeMips; + +//1 + float alpha = 1.0f; + for (i = 0; i < numProbes; ++i) + { + float contrib = contribution[i]; + if (contrib != 0) + { + int cubemapIdx = int(probeConfigData[i].a); + vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz); + + irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; + specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; + alpha -= contrib; + } + } + + if (hasSkylight == 1 && alpha > 0.001) + { + irradiance += textureLod(skylightIrradMap, surface.R, 0).xyz * alpha; + specular += textureLod(skylightSpecularMap, surface.R, lod).xyz * alpha; + } + + vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + + //energy conservation + vec3 kD = vec3(1.0,1.0,1.0) - F; + kD *= 1.0 - surface.metalness; + + //apply brdf + //Do it once to save on texture samples + vec2 brdf = textureLod(BRDFTexture, vec2(surface.roughness, surface.NdotV),0).xy; + specular *= brdf.x * F + brdf.y; + + //final diffuse color + vec3 diffuse = kD * irradiance * surface.baseColor.rgb; + vec4 finalColor = vec4(diffuse + specular * surface.ao, 1.0); + + finalColor = vec4(irradiance.rgb,1); + return finalColor; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl index 6e369bd5e..f542d09a8 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl @@ -22,7 +22,7 @@ #ifndef _TORQUE_GLSL_ #define _TORQUE_GLSL_ - +#line 25 float M_HALFPI_F = 1.57079632679489661923; float M_PI_F = 3.14159265358979323846; @@ -336,4 +336,53 @@ vec3 toGamma(vec3 tex) } #endif // +vec3 PBRFresnel(vec3 albedo, vec3 indirect, float metalness, float fresnel) +{ + vec3 diffuseColor = albedo - (albedo * metalness); + vec3 reflectColor = mix(indirect*albedo, indirect, fresnel); + + return diffuseColor + reflectColor; +} + +vec3 simpleFresnel(vec3 diffuseColor, vec3 reflectColor, float metalness, float angle, float bias, float power) +{ + float fresnelTerm = bias + (1.0 - bias) * pow(abs(1.0 - max(angle, 0)), power); + + fresnelTerm *= metalness; + + return mix(diffuseColor, reflectColor, fresnelTerm); +} + +//get direction for a cube face +vec3 getCubeDir(int face, vec2 uv) +{ + vec2 debiased = uv * 2.0f - 1.0f; + + vec3 dir = vec3(0); + + switch (face) + { + case 0: dir = vec3(1, -debiased.y, -debiased.x); + break; + + case 1: dir = vec3(-1, -debiased.y, debiased.x); + break; + + case 2: dir = vec3(debiased.x, 1, debiased.y); + break; + + case 3: dir = vec3(debiased.x, -1, -debiased.y); + break; + + case 4: dir = vec3(debiased.x, -debiased.y, 1); + break; + + case 5: dir = vec3(-debiased.x, -debiased.y, -1); + break; + }; + + return normalize(dir); +} + +#define sqr(a) ((a)*(a)) #endif // _TORQUE_GLSL_ diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl index a41b8a873..03dd662cd 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC -// +// Portions Copyright Zefiros // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the @@ -21,6 +21,8 @@ //----------------------------------------------------------------------------- #include "./torque.hlsl" +#include "./brdf.hlsl" +#include "./shaderModelAutoGen.hlsl" #ifndef TORQUE_SHADERGEN @@ -37,13 +39,33 @@ uniform float4 inLightColor[4]; #endif uniform float4 ambient; -#define ambientCameraFactor 0.3 -uniform float specularPower; -uniform float4 specularColor; +uniform float smoothness; +uniform float metalness; +uniform float4 albedo; #endif // !TORQUE_SHADERGEN +#define MAX_PROBES 50 +#define MAX_FORWARD_PROBES 4 +inline float3 getDistanceVectorToPlane( float3 origin, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float num = dot( plane, float4( origin, 1.0 ) ); + float t = -num / denum; + + return direction.xyz * t; +} + +inline float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 direction, float4 plane ) +{ + float denum = dot( plane.xyz, direction.xyz ); + float t = negFarPlaneDotEye / denum; + + return direction.xyz * t; +} + +//TODO fix compute 4 lights void compute4Lights( float3 wsView, float3 wsPosition, float3 wsNormal, @@ -57,193 +79,331 @@ void compute4Lights( float3 wsView, float4 inLightSpotDir[3], float4 inLightSpotAngle, float4 inLightSpotFalloff, - float specularPower, - float4 specularColor, + float smoothness, + float metalness, + float4 albedo, #endif // TORQUE_SHADERGEN out float4 outDiffuse, out float4 outSpecular ) { - // NOTE: The light positions and spotlight directions - // are stored in SoA order, so inLightPos[0] is the - // x coord for all 4 lights... inLightPos[1] is y... etc. - // - // This is the key to fully utilizing the vector units and - // saving a huge amount of instructions. - // - // For example this change saved more than 10 instructions - // over a simple for loop for each light. - - int i; - float4 lightVectors[3]; - for ( i = 0; i < 3; i++ ) - lightVectors[i] = wsPosition[i] - inLightPos[i]; - - float4 squareDists = 0; - for ( i = 0; i < 3; i++ ) - squareDists += lightVectors[i] * lightVectors[i]; - - // Accumulate the dot product between the light - // vector and the normal. - // - // The normal is negated because it faces away from - // the surface and the light faces towards the - // surface... this keeps us from needing to flip - // the light vector direction which complicates - // the spot light calculations. - // - // We normalize the result a little later. - // - float4 nDotL = 0; - for ( i = 0; i < 3; i++ ) - nDotL += lightVectors[i] * -wsNormal[i]; - - float4 rDotL = 0; - #ifndef TORQUE_BL_NOSPECULAR - - // We're using the Phong specular reflection model - // here where traditionally Torque has used Blinn-Phong - // which has proven to be more accurate to real materials. - // - // We do so because its cheaper as do not need to - // calculate the half angle for all 4 lights. - // - // Advanced Lighting still uses Blinn-Phong, but the - // specular reconstruction it does looks fairly similar - // to this. - // - float3 R = reflect( wsView, -wsNormal ); - - for ( i = 0; i < 3; i++ ) - rDotL += lightVectors[i] * R[i]; - - #endif - - // Normalize the dots. - // - // Notice we're using the half type here to get a - // much faster sqrt via the rsq_pp instruction at - // the loss of some precision. - // - // Unless we have some extremely large point lights - // i don't believe the precision loss will matter. - // - half4 correction = (half4)rsqrt( squareDists ); - nDotL = saturate( nDotL * correction ); - rDotL = clamp( rDotL * correction, 0.00001, 1.0 ); - - // First calculate a simple point light linear - // attenuation factor. - // - // If this is a directional light the inverse - // radius should be greater than the distance - // causing the attenuation to have no affect. - // - float4 atten = saturate( 1.0 - ( squareDists * inLightInvRadiusSq ) ); - - #ifndef TORQUE_BL_NOSPOTLIGHT - - // The spotlight attenuation factor. This is really - // fast for what it does... 6 instructions for 4 spots. - - float4 spotAtten = 0; - for ( i = 0; i < 3; i++ ) - spotAtten += lightVectors[i] * inLightSpotDir[i]; - - float4 cosAngle = ( spotAtten * correction ) - inLightSpotAngle; - atten *= saturate( cosAngle * inLightSpotFalloff ); - - #endif - - // Finally apply the shadow masking on the attenuation. - atten *= shadowMask; - - // Get the final light intensity. - float4 intensity = nDotL * atten; - - // Combine the light colors for output. - outDiffuse = 0; - for ( i = 0; i < 4; i++ ) - outDiffuse += intensity[i] * inLightColor[i]; - - // Output the specular power. - float4 specularIntensity = pow( rDotL, specularPower.xxxx ) * atten; - - // Apply the per-light specular attenuation. - float4 specular = float4(0,0,0,1); - for ( i = 0; i < 4; i++ ) - specular += float4( inLightColor[i].rgb * inLightColor[i].a * specularIntensity[i], 1 ); - - // Add the final specular intensity values together - // using a single dot product operation then get the - // final specular lighting color. - outSpecular = specularColor * specular; + outDiffuse = float4(0,0,0,0); + outSpecular = float4(0,0,0,0); } - -// This value is used in AL as a constant power to raise specular values -// to, before storing them into the light info buffer. The per-material -// specular value is then computer by using the integer identity of -// exponentiation: -// -// (a^m)^n = a^(m*n) -// -// or -// -// (specular^constSpecular)^(matSpecular/constSpecular) = specular^(matSpecular*constSpecular) -// -#define AL_ConstantSpecularPower 12.0f - -/// The specular calculation used in Advanced Lighting. -/// -/// @param toLight Normalized vector representing direction from the pixel -/// being lit, to the light source, in world space. -/// -/// @param normal Normalized surface normal. -/// -/// @param toEye The normalized vector representing direction from the pixel -/// being lit to the camera. -/// -float AL_CalcSpecular( float3 toLight, float3 normal, float3 toEye ) +struct Surface { - // (R.V)^c - float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye ); + float3 P; // world space position + float3 N; // world space normal + float3 V; // world space view vector + float4 baseColor; // base color [0 -> 1] (rgba) + float metalness; // metalness [0:dielectric -> 1:metal] + float roughness; // roughness: [0:smooth -> 1:rough] (linear) + float roughness_brdf; // roughness remapped from linear to BRDF + float depth; // depth: [0:near -> 1:far] (linear) + float ao; // ambient occlusion [0 -> 1] + float matFlag; // material flag - use getFlag to retreive - // Return the specular factor. - return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower ); + float NdotV; // cos(angle between normal and view vector) + float3 f0; // fresnel value (rgb) + float3 albedo; // diffuse light absorbtion value (rgb) + float3 R; // reflection vector + float3 F; // fresnel term computed from f0, N and V + + inline void Update() + { + NdotV = abs(dot(N, V)) + 1e-5f; // avoid artifact + + albedo = baseColor.rgb * (1.0 - metalness); + f0 = lerp(0.04.xxx, baseColor.rgb, metalness); + + R = -reflect(V, N); + float f90 = saturate(50.0 * dot(f0, 0.33)); + F = F_Schlick(f0, f90, NdotV); + } +}; + +inline Surface createSurface(float4 gbuffer0, TORQUE_SAMPLER2D(gbufferTex1), TORQUE_SAMPLER2D(gbufferTex2), in float2 uv, in float3 wsEyePos, in float3 wsEyeRay, in float4x4 invView) +{ + Surface surface = (Surface)0; + + float4 gbuffer1 = TORQUE_TEX2DLOD(gbufferTex1, float4(uv,0,0)); + float4 gbuffer2 = TORQUE_TEX2DLOD(gbufferTex2, float4(uv,0,0)); + + surface.depth = gbuffer0.a; + surface.P = wsEyePos + wsEyeRay * surface.depth; + surface.N = mul(invView, float4(gbuffer0.xyz,0)).xyz; //TODO move t3d to use WS normals + surface.V = normalize(wsEyePos - surface.P); + surface.baseColor = gbuffer1; + const float minRoughness=1e-4; + surface.roughness = clamp(1.0 - gbuffer2.b, minRoughness, 1.0); //t3d uses smoothness, so we convert to roughness. + surface.roughness_brdf = surface.roughness * surface.roughness; + surface.metalness = gbuffer2.a; + surface.ao = gbuffer2.g; + surface.matFlag = gbuffer2.r; + + surface.Update(); + return surface; } -/// The output for Deferred Lighting -/// -/// @param toLight Normalized vector representing direction from the pixel -/// being lit, to the light source, in world space. -/// -/// @param normal Normalized surface normal. -/// -/// @param toEye The normalized vector representing direction from the pixel -/// being lit to the camera. -/// -float4 AL_DeferredOutput( - float3 lightColor, - float3 diffuseColor, - float4 matInfo, - float4 ambient, - float specular, - float shadowAttenuation) +inline Surface createForwardSurface(float4 baseColor, float3 normal, float4 pbrProperties, in float2 uv, + in float3 wsPosition, in float3 wsEyePos, in float3 wsEyeRay) { - float3 specularColor = float3(specular, specular, specular); - bool metalness = getFlag(matInfo.r, 3); - if ( metalness ) - { - specularColor = 0.04 * (1 - specular) + diffuseColor * specular; + Surface surface = (Surface)0; + + surface.depth = 0; + surface.P = wsPosition; + surface.N = normal; + surface.V = normalize(wsEyePos - surface.P); + surface.baseColor = baseColor; + const float minRoughness=1e-4; + surface.roughness = clamp(1.0 - pbrProperties.b, minRoughness, 1); //t3d uses smoothness, so we convert to roughness. + surface.roughness_brdf = surface.roughness * surface.roughness; + surface.metalness = pbrProperties.a; + surface.ao = pbrProperties.g; + surface.matFlag = pbrProperties.r; + + surface.Update(); + return surface; +} + +struct SurfaceToLight +{ + float3 L; // surface to light vector + float3 Lu; // un-normalized surface to light vector + float3 H; // half-vector between view vector and light vector + float NdotL; // cos(angle between N and L) + float HdotV; // cos(angle between H and V) = HdotL = cos(angle between H and L) + float NdotH; // cos(angle between N and H) +}; + +inline SurfaceToLight createSurfaceToLight(in Surface surface, in float3 L) +{ + SurfaceToLight surfaceToLight = (SurfaceToLight)0; + surfaceToLight.Lu = L; + surfaceToLight.L = normalize(L); + surfaceToLight.H = normalize(surface.V + surfaceToLight.L); + surfaceToLight.NdotL = saturate(dot(surfaceToLight.L, surface.N)); + surfaceToLight.HdotV = saturate(dot(surfaceToLight.H, surface.V)); + surfaceToLight.NdotH = saturate(dot(surfaceToLight.H, surface.N)); + + return surfaceToLight; +} + +float3 BRDF_GetSpecular(in Surface surface, in SurfaceToLight surfaceToLight) +{ + float f90 = saturate(50.0 * dot(surface.f0, 0.33)); + float3 F = F_Schlick(surface.f0, f90, surfaceToLight.HdotV); + float Vis = V_SmithGGXCorrelated(surface.NdotV, surfaceToLight.NdotL, surface.roughness_brdf); + float D = D_GGX(surfaceToLight.NdotH, surface.roughness_brdf); + float3 Fr = D * F * Vis / M_PI_F; + return Fr; +} + +float3 BRDF_GetDiffuse(in Surface surface, in SurfaceToLight surfaceToLight) +{ + //getting some banding with disney method, using lambert instead - todo futher testing + float Fd = 1.0 / M_PI_F; + //energy conservation - remove this if reverting back to disney method + float3 kD = 1.0.xxx - surface.F; + kD *= 1.0 - surface.metalness; + float3 diffuse = kD * surface.baseColor.rgb * Fd; + return diffuse; +} + +//attenuations functions from "moving frostbite to pbr paper" +//https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf +float smoothDistanceAtt ( float squaredDistance , float invSqrAttRadius ) +{ + float factor = squaredDistance * invSqrAttRadius ; + float smoothFactor = saturate (1.0f - factor * factor ); + return sqr(smoothFactor); +} + +float getDistanceAtt( float3 unormalizedLightVector , float invSqrAttRadius ) +{ + float sqrDist = dot ( unormalizedLightVector , unormalizedLightVector ); + float attenuation = 1.0 / (max ( sqrDist , 0.01*0.01) ); + attenuation *= smoothDistanceAtt ( sqrDist , invSqrAttRadius ); + return attenuation; +} + + float getSpotAngleAtt( float3 normalizedLightVector , float3 lightDir , float2 lightSpotParams ) + { + float cd = dot ( lightDir , normalizedLightVector ); + float attenuation = saturate ( ( cd - lightSpotParams.x ) / lightSpotParams.y ); + // smooth the transition + return sqr(attenuation); +} + +inline float3 getDirectionalLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float shadow) +{ + float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity; + float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + float3 final = max(0.0f, diffuse + spec * surface.ao); + return final; +} + +inline float3 getPunctualLight(in Surface surface, in SurfaceToLight surfaceToLight, float3 lightColor, float lightIntensity, float radius, float shadow) +{ + float attenuation = getDistanceAtt(surfaceToLight.Lu, radius); + float3 factor = lightColor * max(surfaceToLight.NdotL, 0) * shadow * lightIntensity * attenuation; + + float3 diffuse = BRDF_GetDiffuse(surface,surfaceToLight) * factor; + float3 spec = BRDF_GetSpecular(surface,surfaceToLight) * factor; + + float3 final = max(0.0f, diffuse + spec * surface.ao * surface.F); + return final; +} + +//Probe IBL stuff +float defineSphereSpaceInfluence(float3 wsPosition, float3 wsProbePosition, float radius) +{ + float3 L = wsProbePosition.xyz - wsPosition; + float contribution = 1.0 - length(L) / radius; + return contribution; +} + +float getDistBoxToPoint(float3 pt, float3 extents) +{ + float3 d = max(max(-extents - pt, 0), pt - extents); + return max(max(d.x, d.y), d.z); +} + +float defineBoxSpaceInfluence(float3 wsPosition, float4x4 worldToObj, float attenuation) +{ + float3 surfPosLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz; + float atten = 1.0 - attenuation; + float baseVal = 0.25; + float dist = getDistBoxToPoint(surfPosLS, float3(baseVal, baseVal, baseVal)); + return saturate(smoothstep(baseVal + 0.0001, atten*baseVal, dist)); +} + +// Box Projected IBL Lighting +// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ +// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +float3 boxProject(float3 wsPosition, float3 wsReflectVec, float4x4 worldToObj, float3 bbMin, float3 bbMax, float3 refPosition) +{ + float3 RayLS = mul(worldToObj, float4(wsReflectVec, 0.0)).xyz; + float3 PositionLS = mul(worldToObj, float4(wsPosition, 1.0)).xyz; + + float3 unit = bbMax.xyz - bbMin.xyz; + float3 plane1vec = (unit / 2 - PositionLS) / RayLS; + float3 plane2vec = (-unit / 2 - PositionLS) / RayLS; + float3 furthestPlane = max(plane1vec, plane2vec); + float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); + float3 posonbox = wsPosition + wsReflectVec * dist; + + return posonbox - refPosition.xyz; +} + +float4 computeForwardProbes(Surface surface, + float cubeMips, float numProbes, float4x4 worldToObjArray[MAX_FORWARD_PROBES], float4 probeConfigData[MAX_FORWARD_PROBES], + float4 inProbePosArray[MAX_FORWARD_PROBES], float4 bbMinArray[MAX_FORWARD_PROBES], float4 bbMaxArray[MAX_FORWARD_PROBES], float4 inRefPosArray[MAX_FORWARD_PROBES], + float hasSkylight, TORQUE_SAMPLER2D(BRDFTexture), + TORQUE_SAMPLERCUBE(skylightIrradMap), TORQUE_SAMPLERCUBE(skylightSpecularMap), + TORQUE_SAMPLERCUBEARRAY(irradianceCubemapAR), TORQUE_SAMPLERCUBEARRAY(specularCubemapAR)) +{ + int i = 0; + float blendFactor[MAX_FORWARD_PROBES]; + float blendSum = 0; + float blendFacSum = 0; + float invBlendSum = 0; + float probehits = 0; + //Set up our struct data + float contribution[MAX_FORWARD_PROBES]; + for (i = 0; i < numProbes; ++i) + { + contribution[i] = 0; + + if (probeConfigData[i].r == 0) //box + { + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + if (contribution[i] > 0.0) + probehits++; + } + else if (probeConfigData[i].r == 1) //sphere + { + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + if (contribution[i] > 0.0) + probehits++; + } + + contribution[i] = max(contribution[i], 0); + + blendSum += contribution[i]; + invBlendSum += (1.0f - contribution[i]); } - - //specular = color * map * spec^gloss - float specularOut = (specularColor * matInfo.b * min(pow(abs(specular), max(( matInfo.a/ AL_ConstantSpecularPower),1.0f)),matInfo.a)).r; - - lightColor *= shadowAttenuation; - lightColor += ambient.rgb; - return float4(lightColor.rgb, specularOut); -} + + if (probehits > 1.0) + { + for (i = 0; i < numProbes; i++) + { + blendFactor[i] = ((contribution[i] / blendSum)) / probehits; + blendFactor[i] *= ((contribution[i]) / invBlendSum); + blendFactor[i] = saturate(blendFactor[i]); + blendFacSum += blendFactor[i]; + } + + // Normalize blendVal + if (blendFacSum == 0.0f) // Possible with custom weight + { + blendFacSum = 1.0f; + } + + float invBlendSumWeighted = 1.0f / blendFacSum; + for (i = 0; i < numProbes; ++i) + { + blendFactor[i] *= invBlendSumWeighted; + contribution[i] *= blendFactor[i]; + } + } + + float3 irradiance = float3(0, 0, 0); + float3 specular = float3(0, 0, 0); + + // Radiance (Specular) + float lod = surface.roughness*cubeMips; + + float alpha = 1; + for (i = 0; i < numProbes; ++i) + { + float contrib = contribution[i]; + if (contrib != 0) + { + int cubemapIdx = probeConfigData[i].a; + float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz); + + irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; + specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; + alpha -= contrib; + } + } + + if (hasSkylight && alpha > 0.001) + { + irradiance += TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz; + specular = TORQUE_TEXCUBELOD(skylightSpecularMap, float4(surface.R, lod)).xyz; + } + + float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + + //energy conservation + float3 kD = 1.0.xxx - F; + kD *= 1.0 - surface.metalness; + + //apply brdf + //Do it once to save on texture samples + float2 brdf = TORQUE_TEX2DLOD(BRDFTexture,float4(surface.roughness, 1.0-surface.NdotV, 0.0, 0.0)).xy; + specular *= brdf.x * F + brdf.y; + + //final diffuse color + float3 diffuse = kD * irradiance * surface.baseColor.rgb; + float4 finalColor = float4(diffuse + specular, 1); +//finalColor.rgb += abs(surface.N); + return finalColor; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl index 064fcffa6..a16e303e4 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl @@ -37,11 +37,12 @@ struct ConvexConnectV float4 vsEyeDir : TEXCOORD2; }; -ConvexConnectV main( VertData IN, - uniform float4x4 modelview, - uniform float4x4 objTrans, - uniform float4x4 worldViewOnly, - uniform float3 eyePosWorld ) +uniform float4x4 modelview; +uniform float4x4 objTrans; +uniform float4x4 worldViewOnly; +uniform float3 eyePosWorld; + +ConvexConnectV main( VertData IN ) { ConvexConnectV OUT; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/cubemapV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/cubemapV.hlsl new file mode 100644 index 000000000..4defd5eb7 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/cubemapV.hlsl @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../shaderModel.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 uv : TEXCOORD; +}; + +ConnectData main( uint vertexID : SV_VertexID ) +{ + ConnectData result; + result.uv = float2((vertexID << 1) & 2, vertexID & 2); + result.hpos = float4(result.uv * float2(2.0f, -2.0f) + float2(-1.0f, 1.0f), 0.0f, 1.0f); + return result; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl index 0167d901a..eabe6f0e0 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl @@ -23,9 +23,9 @@ #include "../../hlslStructs.hlsl" #include "farFrustumQuad.hlsl" +uniform float4 rtParams0; -FarFrustumQuadConnectV main( VertexIn_PNTT IN, - uniform float4 rtParams0 ) +FarFrustumQuadConnectV main( VertexIn_PNTT IN ) { FarFrustumQuadConnectV OUT; diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/brdfLookupP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/brdfLookupP.glsl new file mode 100644 index 000000000..3ddc9af2b --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/brdfLookupP.glsl @@ -0,0 +1,136 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../torque.glsl" +#line 24 +in vec4 hpos; +in vec2 uv0; + +// ---------------------------------------------------------------------------- +// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html +// efficient VanDerCorpus calculation. +float RadicalInverse_VdC(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} +// ---------------------------------------------------------------------------- +vec2 Hammersley(uint i, uint N) +{ + return vec2(float(i)/float(N), RadicalInverse_VdC(i)); +} +// ---------------------------------------------------------------------------- +vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness) +{ + float a = roughness*roughness; + + float phi = 2.0 * M_PI_F * Xi.x; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta*cosTheta); + + // from spherical coordinates to cartesian coordinates - halfway vector + vec3 H; + H.x = cos(phi) * sinTheta; + H.y = sin(phi) * sinTheta; + H.z = cosTheta; + + // from tangent-space H vector to world-space sample vector + vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 tangent = normalize(cross(up, N)); + vec3 bitangent = cross(N, tangent); + + vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z; + return normalize(sampleVec); +} +// ---------------------------------------------------------------------------- +float GeometrySchlickGGX(float NdotV, float roughness) +{ + // note that we use a different k for IBL + float a = roughness; + float k = (a * a) / 2.0; + + float nom = NdotV; + float denom = NdotV * (1.0 - k) + k; + + return nom / denom; +} +// ---------------------------------------------------------------------------- +float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) +{ + float NdotV = max(dot(N, V), 0.0); + float NdotL = max(dot(N, L), 0.0); + float ggx2 = GeometrySchlickGGX(NdotV, roughness); + float ggx1 = GeometrySchlickGGX(NdotL, roughness); + + return ggx1 * ggx2; +} +// ---------------------------------------------------------------------------- +vec2 IntegrateBRDF(float NdotV, float roughness) +{ + vec3 V; + V.x = sqrt(1.0 - NdotV*NdotV); + V.y = 0.0; + V.z = NdotV; + + float A = 0.0; + float B = 0.0; + + vec3 N = vec3(0.0, 0.0, 1.0); + + const uint SAMPLE_COUNT = 1024u; + for(uint i = 0u; i < SAMPLE_COUNT; ++i) + { + // generates a sample vector that's biased towards the + // preferred alignment direction (importance sampling). + vec2 Xi = Hammersley(i, SAMPLE_COUNT); + vec3 H = ImportanceSampleGGX(Xi, N, roughness); + vec3 L = normalize(2.0 * dot(V, H) * H - V); + + float NdotL = max(L.z, 0.0); + float NdotH = max(H.z, 0.0); + float VdotH = max(dot(V, H), 0.0); + + if(NdotL > 0.0) + { + float G = GeometrySmith(N, V, L, roughness); + float G_Vis = (G * VdotH) / (NdotH * NdotV); + float Fc = pow(1.0 - VdotH, 5.0); + + A += (1.0 - Fc) * G_Vis; + B += Fc * G_Vis; + } + } + A /= float(SAMPLE_COUNT); + B /= float(SAMPLE_COUNT); + return vec2(A, B); +} + +out vec4 OUT_col; + +void main() +{ + OUT_col = vec4(IntegrateBRDF(uv0.x, uv0.y).rg,0,1); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/cubemapV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/cubemapV.glsl new file mode 100644 index 000000000..8b511effb --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/cubemapV.glsl @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +out vec2 uv0; + +void main() +{ + float x = float((gl_VertexID & 1) << 2)-1.0; + float y = float((gl_VertexID & 2) << 1)-1.0; + gl_Position = vec4(x, y, 0, 1); + uv0.x = (x+1.0)*0.5; + uv0.y = (y+1.0)*0.5; +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredShadingP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredShadingP.glsl index 0234d5fd1..aefdfedd9 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredShadingP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredShadingP.glsl @@ -26,8 +26,9 @@ #include "../../../gl/torque.glsl" uniform sampler2D colorBufferTex; -uniform sampler2D lightDeferredTex; +uniform sampler2D diffuseLightingBuffer; uniform sampler2D matInfoTex; +uniform sampler2D specularLightingBuffer; uniform sampler2D deferredTex; out vec4 OUT_col; @@ -40,20 +41,26 @@ void main() OUT_col = vec4(0.0); return; } - vec4 lightBuffer = texture( lightDeferredTex, uv0 ); - vec4 colorBuffer = texture( colorBufferTex, uv0 ); - vec4 matInfo = texture( matInfoTex, uv0 ); - float specular = clamp(lightBuffer.a,0.0,1.0); + + vec3 albedo = texture( colorBufferTex, uv0 ).rgb; //albedo + vec4 matInfo = texture( matInfoTex, uv0 ); //flags|smoothness|ao|metallic - // Diffuse Color Altered by Metalness - bool metalness = getFlag(matInfo.r, 3); - if ( metalness ) + bool emissive = getFlag(matInfo.r, 0); + if (emissive) { - colorBuffer *= (1.0 - colorBuffer.a); + OUT_col = float4(albedo, 1.0); + return; } + + vec4 diffuse = texture( diffuseLightingBuffer, uv0 ); //shadowmap*specular + vec4 specular = texture( specularLightingBuffer, uv0 ); //environment mapping*lightmaps - colorBuffer += vec4(specular, specular, specular, 1.0); - colorBuffer *= vec4(lightBuffer.rgb, 1.0); + float metalness = matInfo.a; + + vec3 diffuseColor = albedo - (albedo * metalness); + vec3 specularColor = lerp(float3(0.04,0.04,0.04), albedo, metalness); - OUT_col = hdrEncode( vec4(colorBuffer.rgb, 1.0) ); + vec3 light = (diffuseColor * diffuse.rgb) + (specularColor * specular.rgb); + + OUT_col = hdrEncode(vec4(light, 1.0)); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/irradianceP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/irradianceP.glsl new file mode 100644 index 000000000..2078e6f38 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/irradianceP.glsl @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" + +in vec2 uv0; +uniform int face; + +uniform samplerCube environmentMap; + +out vec4 OUT_col; + +void main() +{ + vec3 N = getCubeDir(face, uv0); + vec3 irradiance = vec3(0.0); + + // tangent space calculation from origin point + vec3 up = vec3(0.0, 0.0, 1.0); + vec3 right = cross(up, N); + up = cross(N, right); + + float sampleDelta = 0.025; + int nrSamples = 0; + for(float phi = 0.0; phi < M_2PI_F; phi += sampleDelta) + { + for(float theta = 0.0; theta < M_HALFPI_F; theta += sampleDelta) + { + // spherical to cartesian (in tangent space) + vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + // tangent space to world + vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; + + irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta); + nrSamples++; + } + } + irradiance = M_PI_F * irradiance * (1.0 / float(nrSamples)); + + OUT_col = vec4(irradiance, 1.0); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/lightingUtils.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/lightingUtils.glsl index 08af9231b..a7860397b 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/lightingUtils.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/lightingUtils.glsl @@ -33,34 +33,6 @@ float attenuate( vec4 lightColor, vec2 attParams, float dist ) #endif } -// Calculate the specular coefficent -// -// pxlToLight - Normalized vector representing direction from the pixel being lit, to the light source, in world space -// normal - Normalized surface normal -// pxlToEye - Normalized vector representing direction from pixel being lit, to the camera, in world space -// specPwr - Specular exponent -// specularScale - A scalar on the specular output used in RGB accumulation. -// -float calcSpecular( vec3 pxlToLight, vec3 normal, vec3 pxlToEye, float specPwr, float specularScale ) -{ -#ifdef PHONG_SPECULAR - // (R.V)^c - float specVal = dot( normalize( -reflect( pxlToLight, normal ) ), pxlToEye ); -#else - // (N.H)^c [Blinn-Phong, TGEA style, default] - float specVal = dot( normal, normalize( pxlToLight + pxlToEye ) ); -#endif - -#ifdef ACCUMULATE_LUV - return pow( max( specVal, 0.00001f ), specPwr ); -#else - // If this is RGB accumulation, than there is no facility for the luminance - // of the light to play in to the specular intensity. In LUV, the luminance - // of the light color gets rolled into N.L * Attenuation - return specularScale * pow( max( specVal, 0.00001f ), specPwr ); -#endif -} - vec3 getDistanceVectorToPlane( vec3 origin, vec3 direction, vec4 plane ) { float denum = dot( plane.xyz, direction.xyz ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl index 80869de25..03353c7fc 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl @@ -24,11 +24,11 @@ #include "shadergen:/autogenConditioners.h" #include "farFrustumQuad.glsl" -#include "lightingUtils.glsl" #include "../../../gl/lighting.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" #include "softShadow.glsl" #include "../../../gl/torque.glsl" +#line 31 in vec4 wsEyeDir; in vec4 ssPos; @@ -38,7 +38,7 @@ in vec4 color; #ifdef USE_COOKIE_TEX /// The texture for cookie rendering. -uniform samplerCube cookieMap ; +uniform samplerCube cookieMap; #endif @@ -85,7 +85,9 @@ uniform samplerCube cookieMap ; // this value was found via experementation // NOTE: this is wrong, it only biases in one direction, not towards the uv // center ( 0.5 0.5 ). - //shadowCoord.xy *= 0.997; + float offsetVal = 0.95; + shadowCoord.xy *= offsetVal; + shadowCoord.xy += vec2(1.0-offsetVal) / 2.0; #ifndef SHADOW_PARABOLOID @@ -122,152 +124,86 @@ uniform vec3 lightPosition; uniform vec4 lightColor; uniform float lightBrightness; uniform float lightRange; -uniform vec2 lightAttenuation; uniform vec4 lightMapParams; uniform vec4 vsFarPlane; -uniform mat3 viewToLightProj; -uniform mat3 dynamicViewToLightProj; uniform vec4 lightParams; + +uniform float lightInvSqrRange; uniform float shadowSoftness; +uniform mat3 worldToLightProj; +uniform mat3 dynamicWorldToLightProj; + +uniform vec3 eyePosWorld; +uniform mat4 cameraToWorld; out vec4 OUT_col; - void main() { // Compute scene UV - vec3 ssPos = ssPos.xyz / ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + vec2 uvScene = getUVFromSSPos(ssPos.xyz/ssPos.w, rtParams0); + + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, uvScene); + + //eye ray WS/VS + vec3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 wsEyeRay = tMul(cameraToWorld, vec4(vsEyeRay, 0)).xyz; + + //create surface + Surface surface = createSurface( normDepth, colorBuffer, matInfoBuffer, + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); - // Emissive. - vec4 matInfo = texture( matInfoBuffer, uvScene ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) + //early out if emissive + if (getFlag(surface.matFlag, 0)) { - OUT_col = vec4(0.0, 0.0, 0.0, 0.0); - return; + OUT_col = vec4(0.0); + return; } - vec4 colorSample = texture( colorBuffer, uvScene ); - vec3 subsurface = vec3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) + vec3 L = lightPosition - surface.P; + float dist = length(L); + vec3 lighting = vec3(0.0); + if(dist < lightRange) { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = vec3(0.772549, 0.337255, 0.262745); - else - subsurface = vec3(0.337255, 0.772549, 0.262745); - } - - // Sample/unpack the normal/z data - vec4 deferredSample = deferredUncondition( deferredBuffer, uvScene ); - vec3 normal = deferredSample.rgb; - float depth = deferredSample.a; - - // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); - vec3 viewSpacePos = eyeRay * depth; - - // Build light vec, get length, clip pixel if needed - vec3 lightVec = lightPosition - viewSpacePos; - float lenLightV = length( lightVec ); - clip( lightRange - lenLightV ); - - // Get the attenuated falloff. - float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - clip( atten - 1e-6 ); - - // Normalize lightVec - lightVec /= lenLightV; - - // If we can do dynamic branching then avoid wasting - // fillrate on pixels that are backfacing to the light. - float nDotL = dot( lightVec, normal ); - //DB_CLIP( nDotL < 0 ); + float distToLight = dist / lightRange; + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); #ifdef NO_SHADOW - float shadowed = 1.0; - #else - // Get a linear depth from the light source. - float distToLight = lenLightV / lightRange; - #ifdef SHADOW_CUBE // TODO: We need to fix shadow cube to handle soft shadows! - float occ = texture( shadowMap, tMul( viewToLightProj, -lightVec ) ).r; + float occ = texture( shadowMap, ttMul( worldToLightProj, -surfaceToLight.L ) ).r; float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); #else - - vec2 shadowCoord = decodeShadowCoord( tMul( viewToLightProj, -lightVec ) ).xy; - - float static_shadowed = softShadow_filter( shadowMap, - ssPos.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - vec2 dynamicShadowCoord = decodeShadowCoord( tMul( dynamicViewToLightProj, -lightVec ) ).xy; - float dynamic_shadowed = softShadow_filter( dynamicShadowMap, - ssPos.xy, - dynamicShadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - + vec2 shadowCoord = decodeShadowCoord( tMul( worldToLightProj, -surfaceToLight.L ) ).xy; + vec2 dynShadowCoord = decodeShadowCoord( tMul( dynamicWorldToLightProj, -surfaceToLight.L ) ).xy; + float static_shadowed = softShadow_filter(shadowMap, ssPos.xy/ssPos.w, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + float dynamic_shadowed = softShadow_filter(dynamicShadowMap, ssPos.xy/ssPos.w, dynShadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); float shadowed = min(static_shadowed, dynamic_shadowed); #endif #endif // !NO_SHADOW - vec3 lightcol = lightColor.rgb; + vec3 lightCol = lightColor.rgb; #ifdef USE_COOKIE_TEX // Lookup the cookie sample. - vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) ); - + vec4 cookie = texture(cookieMap, ttMul(worldToLightProj, -surfaceToLight.L)); // Multiply the light with the cookie tex. - lightcol *= cookie.rgb; - + lightCol *= cookie.rgb; // Use a maximum channel luminance to attenuate // the lighting else we get specular in the dark // regions of the cookie texture. - atten *= max( cookie.r, max( cookie.g, cookie.b ) ); - + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif - // NOTE: Do not clip on fully shadowed pixels as it would - // cause the hardware occlusion query to disable the shadow. - - // Specular term - float specular = AL_CalcSpecular( lightVec, - normal, - normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - - float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; - vec3 lightColorOut = lightMapParams.rgb * lightcol; - vec4 addToResult = vec4(0.0); - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = nDotL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - shadowed = mix( 1.0f, shadowed, atten ); - lightColorOut = vec3(shadowed); - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + //get punctual light contribution + lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); } - OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + OUT_col = vec4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl new file mode 100644 index 000000000..de4c26039 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/prefilterP.glsl @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/torque.glsl" + +in vec4 hpos; +in vec2 uv0; + +uniform samplerCube environmentMap; + +uniform float roughness; +uniform int face; +uniform int mipSize; +uniform int resolution; +float RadicalInverse_VdC(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} + +vec2 Hammersley(uint i, uint N) +{ + return vec2(float(i) / float(N), RadicalInverse_VdC(i)); +} + +float DistributionGGX(vec3 N, vec3 H, float roughness) +{ + float a = roughness * roughness; + float a2 = a * a; + float NdotH = max(dot(N, H), 0.0); + float NdotH2 = NdotH * NdotH; + + float nom = a2; + float denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = M_PI_F * denom * denom; + + return nom / denom; +} + +vec3 ImportanceSampleGGX(vec2 Xi, vec3 N) +{ + float a = roughness * roughness; + + float phi = 2.0 * M_PI_F * Xi.x; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + + // from spherical coordinates to cartesian coordinates + vec3 H; + H.x = cos(phi) * sinTheta; + H.y = sin(phi) * sinTheta; + H.z = cosTheta; + + // from tangent-space vector to world-space sample vector + vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + vec3 tangent = normalize(cross(up, N)); + vec3 bitangent = cross(N, tangent); + + vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z; + return normalize(sampleVec); +} + +vec4 prefilterEnvMap(vec3 R) +{ + int sampleCount = resolution*2; + vec3 N = R; + vec3 V = R; + float totalWeight = 0.0; + vec4 prefilteredColor = vec4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < sampleCount; ++i) + { + vec2 Xi = Hammersley(i, sampleCount); + vec3 H = ImportanceSampleGGX(Xi, N); + vec3 L = normalize(2.0 * dot(V, H) * H - V); + + float NdotL = max(dot(N, L), 0.0); + if (NdotL > 0.0) + { + // sample from the environment's mip level based on roughness/pdf + float D = DistributionGGX(N, H, roughness); + float NdotH = max(dot(N, H), 0.0); + float HdotV = max(dot(H, V), 0.0); + float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; + + float saTexel = 4.0 * M_PI_F / float(6.0 * sampleCount * sampleCount); + float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); + + float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); + + prefilteredColor += texture(environmentMap, L, mipLevel) * NdotL; + + totalWeight += NdotL; + } + } + + return (prefilteredColor / totalWeight); +} + +out vec4 OUT_col; + +void main() +{ + + vec3 N = getCubeDir(face, uv0); + OUT_col = prefilterEnvMap(N); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/probeShadingP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/probeShadingP.glsl new file mode 100644 index 000000000..437340d29 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/probeShadingP.glsl @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../postFx/gl/postFX.glsl" +#include "../../../gl/torque.glsl" + +uniform sampler2D colorBufferTex; +uniform sampler2D diffuseLightingBuffer; +uniform sampler2D matInfoTex; +uniform sampler2D specularLightingBuffer; +uniform sampler2D deferredTex; + +uniform float radius; +uniform vec2 targetSize; +uniform int captureRez; + +out vec4 OUT_col; + +void main() +{ + float depth = deferredUncondition( deferredTex, uv0 ).w; + if (depth>0.9999) + { + discard; + return; + } + vec3 colorBuffer = texture( colorBufferTex, uv0 ).rgb; //albedo + vec4 matInfo = texture(matInfoTex, uv0); //flags|smoothness|ao|metallic + + bool emissive = getFlag(matInfo.r, 0); + if (emissive) + { + OUT_col = vec4(colorBuffer, 1.0); + return; + } + + vec4 diffuseLighting = texture( diffuseLightingBuffer, uv0 ); //shadowmap*specular + colorBuffer *= diffuseLighting.rgb; + vec2 relUV = uv0*targetSize/captureRez; + + //we use a 1k depth range in the capture frustum. + //reduce that a bit to get something resembling depth fidelity out of 8 bits + depth*=2000/radius; + + float rLen = length(vec3(relUV,depth)-vec3(0.5,0.5,0)); + OUT_col = hdrEncode( vec4(colorBuffer,rLen)); +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl new file mode 100644 index 000000000..2298c958c --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeArrayP.glsl @@ -0,0 +1,209 @@ +#include "../../../gl/hlslCompat.glsl" +#include "../../../postFx/gl/postFx.glsl" +#include "../../../gl/torque.glsl" +#include "shadergen:/autogenConditioners.h" +#include "../../../gl/lighting.glsl" + +#line 7 + +uniform sampler2D deferredBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; +uniform sampler2D BRDFTexture; + +uniform vec4 rtParams0; +uniform vec4 vsFarPlane; +uniform mat4 cameraToWorld; +uniform vec3 eyePosWorld; + +//cubemap arrays require all the same size. so shared mips# value +uniform float cubeMips; + +uniform float numProbes; +uniform samplerCubeArray specularCubemapAR; +uniform samplerCubeArray irradianceCubemapAR; + +uniform vec4 inProbePosArray[MAX_PROBES]; +uniform vec4 inRefPosArray[MAX_PROBES]; +uniform mat4 worldToObjArray[MAX_PROBES]; +uniform vec4 bbMinArray[MAX_PROBES]; +uniform vec4 bbMaxArray[MAX_PROBES]; +uniform vec4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten + +#if DEBUGVIZ_CONTRIB +uniform vec4 probeContribColors[MAX_PROBES]; +#endif + +uniform samplerCube skylightSpecularMap; +uniform samplerCube skylightIrradMap; +uniform float hasSkylight; + +out vec4 OUT_col; + +void main() +{ + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, IN_uv0.xy); + + //create surface + Surface surface = createSurface(normDepth, colorBuffer, matInfoBuffer, IN_uv0.xy, eyePosWorld, IN_wsEyeRay, cameraToWorld); + + //early out if emissive + if (getFlag(surface.matFlag, 0)) + { + discard; + } + + float alpha = 1; + + int i = 0; + float blendFactor[MAX_PROBES]; + float blendSum = 0; + float blendFacSum = 0; + float invBlendSum = 0; + float probehits = 0; + //Set up our struct data + float contribution[MAX_PROBES]; + if (alpha > 0) + { + //Process prooooobes + for (i = 0; i < numProbes; ++i) + { + contribution[i] = 0; + + if (probeConfigData[i].r == 0) //box + { + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + if (contribution[i]>0.0) + probehits++; + } + else if (probeConfigData[i].r == 1) //sphere + { + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + if (contribution[i]>0.0) + probehits++; + } + + contribution[i] = max(contribution[i],0); + + blendSum += contribution[i]; + invBlendSum += (1.0f - contribution[i]); + } + // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. + // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). + // respect constraint B. + // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary + // and respect constraint A. + + if (probehits>1.0) + { + for (i = 0; i < numProbes; i++) + { + blendFactor[i] = ((contribution[i] / blendSum)) / probehits; + blendFactor[i] *= ((contribution[i]) / invBlendSum); + blendFactor[i] = saturate(blendFactor[i]); + blendFacSum += blendFactor[i]; + } + + // Normalize blendVal +#if DEBUGVIZ_ATTENUATION == 0 //this can likely be removed when we fix the above normalization behavior + if (blendFacSum == 0.0f) // Possible with custom weight + { + blendFacSum = 1.0f; + } +#endif + + float invBlendSumWeighted = 1.0f / blendFacSum; + for (i = 0; i < numProbes; ++i) + { + blendFactor[i] *= invBlendSumWeighted; + contribution[i] *= blendFactor[i]; + } + } + +#if DEBUGVIZ_ATTENUATION == 1 + float contribAlpha = 1; + for (i = 0; i < numProbes; ++i) + { + contribAlpha -= contribution[i]; + } + + OUT_col = vec4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1); + return; +#endif + +#if DEBUGVIZ_CONTRIB == 1 + vec3 finalContribColor = vec3(0, 0, 0); + float contribAlpha = 1; + for (i = 0; i < numProbes; ++i) + { + finalContribColor += contribution[i] *probeContribColors[i].rgb; + contribAlpha -= contribution[i]; + } + + //Skylight coloration for anything not covered by probes above + finalContribColor += vec3(0.3, 0.3, 0.3) * contribAlpha; + + OUT_col = vec4(finalContribColor, 1); + return; +#endif + } + + vec3 irradiance = vec3(0, 0, 0); + vec3 specular = vec3(0, 0, 0); + + // Radiance (Specular) +#if DEBUGVIZ_SPECCUBEMAP == 0 + float lod = surface.roughness*cubeMips; +#elif DEBUGVIZ_SPECCUBEMAP == 1 + float lod = 0; +#endif + + alpha = 1; + for (i = 0; i < numProbes; ++i) + { + float contrib = contribution[i]; + if (contrib != 0) + { + float cubemapIdx = probeConfigData[i].a; + vec3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz); + + irradiance += textureLod(irradianceCubemapAR, vec4(dir, cubemapIdx), 0).xyz * contrib; + specular += textureLod(specularCubemapAR, vec4(dir, cubemapIdx), lod).xyz * contrib; + //irradiance += vec3(1,1,1) * contrib; + //specular += vec3(1,1,1) * contrib; + alpha -= contrib; + } + } + + if (hasSkylight == 1 && alpha > 0.001) + { + irradiance += textureLod(skylightIrradMap, surface.R, 0).xyz * alpha; + specular += textureLod(skylightSpecularMap, surface.R, lod).xyz * alpha; + } + +#if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0 + OUT_col = vec4(specular, 1); + return; +#elif DEBUGVIZ_DIFFCUBEMAP == 1 + OUT_col = vec4(irradiance, 1); + return; +#endif + + vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + + //energy conservation + vec3 kD = vec3(1,1,1) - F; + kD *= 1.0 - surface.metalness; + + //apply brdf + //Do it once to save on texture samples + vec2 brdf = textureLod(BRDFTexture, vec2(surface.roughness, surface.NdotV),0).xy; + specular *= brdf.x * F + brdf.y; + + //final diffuse color + vec3 diffuse = kD * irradiance * surface.baseColor.rgb; + vec4 finalColor = vec4(diffuse + specular * surface.ao, 1.0); + + OUT_col = finalColor; +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeP.glsl new file mode 100644 index 000000000..fee0b8783 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeP.glsl @@ -0,0 +1,162 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "../../../gl/torque.glsl" +#include "../../../gl/lighting.glsl" +#line 27 + +in vec4 pos; +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; + +uniform sampler2D deferredBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; +uniform samplerCube cubeMap; +uniform samplerCube irradianceCubemap; +uniform sampler2D BRDFTexture; +uniform float cubeMips; + +uniform vec4 rtParams0; + +uniform vec3 probeWSPos; +uniform vec3 probeLSPos; +uniform vec4 vsFarPlane; + +uniform float radius; +uniform vec2 attenuation; + +uniform mat4 worldToObj; +uniform mat4 cameraToWorld; + +uniform vec3 eyePosWorld; +uniform vec3 bbMin; +uniform vec3 bbMax; + +uniform float useSphereMode; + +// Box Projected IBL Lighting +// Based on: http://www.gamedev.net/topic/568829-box-projected-cubemap-environment-mapping/ +// and https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ +vec3 boxProject(vec3 wsPosition, vec3 reflectDir, vec3 boxWSPos, vec3 boxMin, vec3 boxMax) +{ + vec3 nrdir = reflectDir; + vec3 offset = wsPosition; + vec3 plane1vec = (boxMax - offset) / nrdir; + vec3 plane2vec = (boxMin - offset) / nrdir; + + vec3 furthestPlane = max(plane1vec, plane2vec); + float dist = min(min(furthestPlane.x, furthestPlane.y), furthestPlane.z); + vec3 posonbox = offset + nrdir * dist; + + return posonbox - boxWSPos; +} + +vec3 iblBoxSpecular(vec3 normal, vec3 wsPos, float roughness, vec3 surfToEye, + sampler2D brdfTexture, + samplerCube radianceCube, + vec3 boxPos, + vec3 boxMin, + vec3 boxMax) +{ + float ndotv = clamp(dot(normal, surfToEye), 0.0, 1.0); + + // BRDF + vec2 brdf = textureLod(brdfTexture, vec2(roughness, ndotv),0).xy; + + // Radiance (Specular) + float maxmip = pow(cubeMips+1,2); + float lod = roughness*maxmip; + vec3 r = reflect(surfToEye, normal); + vec3 cubeR = normalize(r); + cubeR = boxProject(wsPos, cubeR, boxPos, boxMin, boxMax); + + vec3 radiance = textureLod(radianceCube, cubeR, lod).xyz * (brdf.x + brdf.y); + + return radiance; +} + +float defineBoxSpaceInfluence(vec3 surfPosWS, vec3 probePos, float radius, float atten) +{ + vec3 surfPosLS = tMul( worldToObj, vec4(surfPosWS,1.0)).xyz; + + vec3 boxMinLS = probePos-(vec3(1,1,1)*radius); + vec3 boxMaxLS = probePos+(vec3(1,1,1)*radius); + + float boxOuterRange = length(boxMaxLS - boxMinLS); + float boxInnerRange = boxOuterRange / atten; + + vec3 localDir = vec3(abs(surfPosLS.x), abs(surfPosLS.y), abs(surfPosLS.z)); + localDir = (localDir - boxInnerRange) / (boxOuterRange - boxInnerRange); + + return max(localDir.x, max(localDir.y, localDir.z)) * -1; +} +out vec4 OUT_col; + +void main() +{ + + // Compute scene UV + vec2 uvScene = getUVFromSSPos( ssPos.xyz/ssPos.w, rtParams0 ); + + //eye ray WS/LS + vec3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 wsEyeRay = tMul(cameraToWorld, vec4(vsEyeRay, 0)).xyz; + + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, uvScene); + + //create surface + Surface surface = createSurface( normDepth, colorBuffer, matInfoBuffer, + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); + float blendVal = 1.0; + if(useSphereMode>0) + { + vec3 L = probeWSPos - surface.P; + blendVal = 1.0-length(L)/radius; + clip(blendVal); + } + else + { + float tempAttenVal = 3.5; + blendVal = defineBoxSpaceInfluence(surface.P, probeWSPos, radius, tempAttenVal); + clip(blendVal); + float compression = 0.05; + blendVal=(1.0-compression)+blendVal*compression; + } + //render into the bound space defined above + vec3 surfToEye = normalize(surface.P - eyePosWorld); + vec3 irradiance = textureLod(irradianceCubemap, surface.N,0).xyz; + vec3 specular = iblBoxSpecular(surface.N, surface.P, surface.roughness, surfToEye, BRDFTexture, cubeMap, probeWSPos, bbMin, bbMax); + vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + specular *= F; + //energy conservation + vec3 kD = vec3(1.0) - F; + kD *= 1.0 - surface.metalness; + //final diffuse color + vec3 diffuse = kD * irradiance * surface.baseColor.rgb; + + OUT_col = vec4(diffuse + specular * surface.ao, blendVal); +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeV.glsl new file mode 100644 index 000000000..5d48e6613 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/reflectionProbeV.glsl @@ -0,0 +1,32 @@ +#include "shadergen:/autogenConditioners.h" +#include "../../torque.hlsl" + +// This is the shader input +struct Vert +{ + float4 position : POSITION; + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; +}; + +// This is the shader output data. +struct Conn +{ + float4 position : POSITION; + float2 uv0 : TEXCOORD0; + float3 wsEyeRay : TEXCOORD1; +}; + +// Render Target Paramaters +float4 rtParams0; + +Conn main(Vert IN, + uniform float4x4 modelView : register(C0)) +{ + Conn OUT; + OUT.position = IN.position; + OUT.uv0 = viewportCoordToRenderTarget( IN.uv0, rtParams0 ); + OUT.wsEyeRay = IN.wsEyeRay; + return OUT; +} + diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/skylightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/skylightP.glsl new file mode 100644 index 000000000..7b174641d --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/skylightP.glsl @@ -0,0 +1,82 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- +#include "../../../gl/hlslCompat.glsl" +#include "shadergen:/autogenConditioners.h" +#include "farFrustumQuad.glsl" +#include "../../../gl/lighting.glsl" +#include "../../../gl/torque.glsl" +#line 27 + +in vec4 pos; +in vec4 wsEyeDir; +in vec4 ssPos; +in vec4 vsEyeDir; + +uniform sampler2D deferredBuffer; +uniform sampler2D colorBuffer; +uniform sampler2D matInfoBuffer; +uniform samplerCube cubeMap; +uniform samplerCube irradianceCubemap; +uniform sampler2D BRDFTexture; + +uniform vec4 rtParams0; + +uniform vec4 vsFarPlane; +uniform mat4 cameraToWorld; +uniform vec3 eyePosWorld; + +vec3 iblSpecular(in Surface surface, vec3 F) +{ + const float MAX_REFLECTION_LOD = 4.0; + vec3 prefilteredColor = textureLod(cubeMap, surface.R, surface.roughness * MAX_REFLECTION_LOD).rgb; + vec2 envBRDF = texture(BRDFTexture, vec2(surface.NdotV, surface.roughness)).rg; + return prefilteredColor * (F * envBRDF.x + envBRDF.y); +} + +out vec4 OUT_col; +void main() +{ + // Compute scene UV + vec2 uvScene = getUVFromSSPos( ssPos.xyz/ssPos.w, rtParams0 ); + + //eye ray WS/LS + vec3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 wsEyeRay = tMul(cameraToWorld, vec4(vsEyeRay, 0)).xyz; + + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, uvScene); + + //create surface + Surface surface = createSurface( normDepth, colorBuffer, matInfoBuffer, + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); + + vec3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + vec3 irradiance = textureLod(irradianceCubemap, surface.N,0).rgb; + vec3 specular = iblSpecular(surface, F); + //energy conservation + vec3 kD = vec3(1.0) - F; + kD *= 1.0 - surface.metalness; + //final diffuse color + vec3 diffuse = kD * irradiance * surface.baseColor.rgb; + + OUT_col = vec4(diffuse + specular * surface.ao, 0); +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl index 5fcf1b19c..5e9c19f82 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl @@ -22,7 +22,6 @@ #include "../../../gl/hlslCompat.glsl" #include "farFrustumQuad.glsl" -#include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" #include "shadergen:/autogenConditioners.h" #include "softShadow.glsl" @@ -34,11 +33,6 @@ in vec4 ssPos; in vec4 vsEyeDir; in vec4 color; -#define IN_wsEyeDir wsEyeDir -#define IN_ssPos ssPos -#define IN_vsEyeDir vsEyeDir -#define IN_color color - #ifdef USE_COOKIE_TEX /// The texture for cookie rendering. @@ -49,162 +43,99 @@ uniform sampler2D cookieMap; uniform sampler2D deferredBuffer; uniform sampler2D shadowMap; uniform sampler2D dynamicShadowMap; - -uniform sampler2D lightBuffer; uniform sampler2D colorBuffer; uniform sampler2D matInfoBuffer; uniform vec4 rtParams0; +uniform float lightBrightness; uniform vec3 lightPosition; uniform vec4 lightColor; -uniform float lightBrightness; + uniform float lightRange; -uniform vec2 lightAttenuation; +uniform float lightInvSqrRange; uniform vec3 lightDirection; -uniform vec4 lightSpotParams; +uniform vec2 lightSpotParams; uniform vec4 lightMapParams; uniform vec4 vsFarPlane; -uniform mat4 viewToLightProj; -uniform mat4 dynamicViewToLightProj; - +uniform mat4 worldToLightProj; +uniform mat4 dynamicWorldToLightProj; uniform vec4 lightParams; uniform float shadowSoftness; +uniform vec3 eyePosWorld; + +uniform mat4 cameraToWorld; +uniform mat4 worldToCamera; out vec4 OUT_col; - void main() { // Compute scene UV - vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w; - vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + vec2 uvScene = getUVFromSSPos(ssPos.xyz/ssPos.w, rtParams0); - // Emissive. - vec4 matInfo = texture( matInfoBuffer, uvScene ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, uvScene); + + //eye ray WS/VS + vec3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, vsEyeDir.xyz, vsFarPlane ); + vec3 wsEyeRay = tMul(cameraToWorld, vec4(vsEyeRay, 0)).xyz; + + //create surface + Surface surface = createSurface( normDepth, colorBuffer,matInfoBuffer, + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); + + //early out if emissive + if (getFlag(surface.matFlag, 0)) { - OUT_col = vec4(0.0, 0.0, 0.0, 0.0); + OUT_col = vec4(0.0); return; } - vec4 colorSample = texture( colorBuffer, uvScene ); - vec3 subsurface = vec3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) + vec3 L = lightPosition - surface.P; + float dist = length(L); + vec3 lighting = vec3(0.0); + if(dist < lightRange) { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = vec3(0.772549, 0.337255, 0.262745); - else - subsurface = vec3(0.337255, 0.772549, 0.262745); - } - - // Sample/unpack the normal/z data - vec4 deferredSample = deferredUncondition( deferredBuffer, uvScene ); - vec3 normal = deferredSample.rgb; - float depth = deferredSample.a; - - // Eye ray - Eye -> Pixel - vec3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN_vsEyeDir.xyz, vsFarPlane ); - vec3 viewSpacePos = eyeRay * depth; - - // Build light vec, get length, clip pixel if needed - vec3 lightToPxlVec = viewSpacePos - lightPosition; - float lenLightV = length( lightToPxlVec ); - lightToPxlVec /= lenLightV; - - //lightDirection = vec3( -lightDirection.xy, lightDirection.z ); //vec3( 0, 0, -1 ); - float cosAlpha = dot( lightDirection, lightToPxlVec ); - clip( cosAlpha - lightSpotParams.x ); - clip( lightRange - lenLightV ); - - float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; - clip( atten - 1e-6 ); - atten = saturate( atten ); - - float nDotL = dot( normal, -lightToPxlVec ); - + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); + #ifdef NO_SHADOW + float shadowed = 1.0; + #else // Get the shadow texture coordinate - vec4 pxlPosLightProj = tMul( viewToLightProj, vec4( viewSpacePos, 1 ) ); + vec4 pxlPosLightProj = tMul( worldToLightProj, vec4( surface.P, 1 ) ); vec2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); shadowCoord.y = 1.0f - shadowCoord.y; - // Get the dynamic shadow texture coordinate - vec4 dynpxlPosLightProj = tMul( dynamicViewToLightProj, vec4( viewSpacePos, 1 ) ); - vec2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); - dynshadowCoord.y = 1.0f - dynshadowCoord.y; - #ifdef NO_SHADOW - - float shadowed = 1.0; - - #else + vec4 dynPxlPosLightProj = tMul( dynamicWorldToLightProj, vec4( surface.P, 1 ) ); + vec2 dynShadowCoord = ( ( dynPxlPosLightProj.xy / dynPxlPosLightProj.w ) * 0.5 ) + vec2( 0.5, 0.5 ); + dynShadowCoord.y = 1.0f - dynShadowCoord.y; - // Get a linear depth from the light source. + //distance to light in shadow map space float distToLight = pxlPosLightProj.z / lightRange; - - float static_shadowed = softShadow_filter( shadowMap, - ssPos.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - float dynamic_shadowed = softShadow_filter( dynamicShadowMap, - ssPos.xy, - dynshadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); + float dynDistToLight = dynPxlPosLightProj.z / lightRange; + float static_shadowed = softShadow_filter(shadowMap, ssPos.xy/ssPos.w, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + float dynamic_shadowed = softShadow_filter(dynamicShadowMap, ssPos.xy/ssPos.w, dynShadowCoord, shadowSoftness, dynDistToLight, surfaceToLight.NdotL, lightParams.y); float shadowed = min(static_shadowed, dynamic_shadowed); - #endif // !NO_SHADOW + #endif - vec3 lightcol = lightColor.rgb; + vec3 lightCol = lightColor.rgb; #ifdef USE_COOKIE_TEX // Lookup the cookie sample. - vec4 cookie = texture( cookieMap, shadowCoord ); - + vec4 cookie = texture(cookieMap, tMul(worldToLightProj, -surfaceToLight.L)); // Multiply the light with the cookie tex. - lightcol *= cookie.rgb; - + lightCol *= cookie.rgb; // Use a maximum channel luminance to attenuate // the lighting else we get specular in the dark // regions of the cookie texture. - atten *= max( cookie.r, max( cookie.g, cookie.b ) ); - + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif - // NOTE: Do not clip on fully shadowed pixels as it would - // cause the hardware occlusion query to disable the shadow. - - // Specular term - float specular = AL_CalcSpecular( -lightToPxlVec, - normal, - normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - - float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; - vec3 lightColorOut = lightMapParams.rgb * lightcol; - vec4 addToResult = vec4(0.0); - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = nDotL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - shadowed = mix( 1.0f, shadowed, atten ); - lightColorOut = vec3(shadowed); - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + //get Punctual light contribution + lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); + //get spot angle attenuation + lighting *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); } - OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + OUT_col = vec4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl index 142e58b10..75ba29d04 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl @@ -25,15 +25,15 @@ #include "farFrustumQuad.glsl" #include "../../../gl/torque.glsl" #include "../../../gl/lighting.glsl" -#include "lightingUtils.glsl" #include "../../shadowMap/shadowMapIO_GLSL.h" #include "softShadow.glsl" - +#line 30 in vec4 hpos; in vec2 uv0; in vec3 wsEyeRay; in vec3 vsEyeRay; +uniform sampler2D deferredBuffer; uniform sampler2D shadowMap; uniform sampler2D dynamicShadowMap; @@ -42,68 +42,68 @@ uniform sampler2D ssaoMask ; uniform vec4 rtParams3; #endif -uniform sampler2D deferredBuffer; -uniform sampler2D lightBuffer; uniform sampler2D colorBuffer; uniform sampler2D matInfoBuffer; +uniform float lightBrightness; uniform vec3 lightDirection; uniform vec4 lightColor; -uniform float lightBrightness; uniform vec4 lightAmbient; + +uniform float shadowSoftness; uniform vec3 eyePosWorld; -uniform mat4x4 eyeMat; + uniform vec4 atlasXOffset; uniform vec4 atlasYOffset; -uniform vec2 atlasScale; uniform vec4 zNearFarInvNearFar; uniform vec4 lightMapParams; -uniform vec2 fadeStartLength; +uniform vec4 farPlaneScalePSSM; uniform vec4 overDarkPSSM; -uniform float shadowSoftness; - + +uniform vec2 fadeStartLength; +uniform vec2 atlasScale; + +uniform mat4 eyeMat; +uniform mat4 cameraToWorld; + //static shadowMap -uniform mat4x4 worldToLightProj; +uniform mat4 worldToLightProj; uniform vec4 scaleX; uniform vec4 scaleY; uniform vec4 offsetX; uniform vec4 offsetY; -uniform vec4 farPlaneScalePSSM; //dynamic shadowMap -uniform mat4x4 dynamicWorldToLightProj; +uniform mat4 dynamicWorldToLightProj; uniform vec4 dynamicScaleX; uniform vec4 dynamicScaleY; uniform vec4 dynamicOffsetX; uniform vec4 dynamicOffsetY; uniform vec4 dynamicFarPlaneScalePSSM; -vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap, +vec4 AL_VectorLightShadowCast( sampler2D _sourceShadowMap, vec2 _texCoord, mat4 _worldToLightProj, - vec4 _worldPos, - vec4 _scaleX, vec4 _scaleY, - vec4 _offsetX, vec4 _offsetY, + vec3 _worldPos, + vec4 _scaleX, + vec4 _scaleY, + vec4 _offsetX, + vec4 _offsetY, vec4 _farPlaneScalePSSM, - vec4 _atlasXOffset, vec4 _atlasYOffset, - vec2 _atlasScale, - float _shadowSoftness, - float _dotNL , - vec4 _overDarkPSSM -) + float _dotNL) { // Compute shadow map coordinate - vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos); + vec4 pxlPosLightProj = tMul(_worldToLightProj, vec4(_worldPos,1)); vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; - // Distance to light, in shadowMap space + // Distance to light, in shadowmap space float distToLight = pxlPosLightProj.z / pxlPosLightProj.w; // Figure out which split to sample from. Basically, we compute the shadowMap sample coord // for all of the splits and then check if its valid. - vec4 shadowCoordX = vec4( baseShadowCoord.x ); - vec4 shadowCoordY = vec4( baseShadowCoord.y ); - vec4 farPlaneDists = vec4( distToLight ); + vec4 shadowCoordX = baseShadowCoord.xxxx; + vec4 shadowCoordY = baseShadowCoord.yyyy; + vec4 farPlaneDists = vec4(distToLight); shadowCoordX *= _scaleX; shadowCoordY *= _scaleY; shadowCoordX += _offsetX; @@ -132,10 +132,10 @@ vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap, else finalMask = vec4(0, 0, 0, 1); - vec3 debugColor = vec3(0); + vec3 debugColor = vec3(0,0,0); #ifdef NO_SHADOW - debugColor = vec3(1.0); + debugColor = vec3(1.0,1.0,1.0); #endif #ifdef PSSM_DEBUG_RENDER @@ -164,16 +164,16 @@ vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap, shadowCoord = baseShadowCoord * finalScale; shadowCoord += finalOffset; - // Convert to _texCoord space + // Convert to texcoord space shadowCoord = 0.5 * shadowCoord + vec2(0.5, 0.5); shadowCoord.y = 1.0f - shadowCoord.y; // Move around inside of atlas vec2 aOffset; - aOffset.x = dot(finalMask, _atlasXOffset); - aOffset.y = dot(finalMask, _atlasYOffset); + aOffset.x = dot(finalMask, atlasXOffset); + aOffset.y = dot(finalMask, atlasYOffset); - shadowCoord *= _atlasScale; + shadowCoord *= atlasScale; shadowCoord += aOffset; // Each split has a different far plane, take this into account. @@ -181,147 +181,77 @@ vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap, distToLight *= farPlaneScale; return vec4(debugColor, - softShadow_filter( _sourceshadowMap, - _texCoord, - shadowCoord, - farPlaneScale * _shadowSoftness, - distToLight, - _dotNL, - dot( finalMask, _overDarkPSSM ) ) ); + softShadow_filter( _sourceShadowMap, + _texCoord, + shadowCoord, + farPlaneScale * shadowSoftness, + distToLight, + _dotNL, + dot( finalMask, overDarkPSSM ) ) ); } out vec4 OUT_col; void main() { - // Emissive. - float4 matInfo = texture( matInfoBuffer, uv0 ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) - { - OUT_col = vec4(1.0, 1.0, 1.0, 0.0); - return; - } + //unpack normal and linear depth + vec4 normDepth = deferredUncondition(deferredBuffer, uv0); + + //create surface + Surface surface = createSurface( normDepth, colorBuffer, matInfoBuffer, + uv0, eyePosWorld, wsEyeRay, cameraToWorld); - vec4 colorSample = texture( colorBuffer, uv0 ); - vec3 subsurface = vec3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) + //early out if emissive + if (getFlag(surface.matFlag, 0)) { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = vec3(0.772549, 0.337255, 0.262745); - else - subsurface = vec3(0.337255, 0.772549, 0.262745); + OUT_col = vec4(0); + return; } - // Sample/unpack the normal/z data - vec4 deferredSample = deferredUncondition( deferredBuffer, uv0 ); - vec3 normal = deferredSample.rgb; - float depth = deferredSample.a; + //create surface to light + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, -lightDirection); - // Use eye ray to get ws pos - vec4 worldPos = vec4(eyePosWorld + wsEyeRay * depth, 1.0f); - - // Get the light attenuation. - float dotNL = dot(-lightDirection, normal); - - #ifdef PSSM_DEBUG_RENDER - vec3 debugColor = vec3(0); - #endif + //light color might be changed by PSSM_DEBUG_RENDER + vec3 lightingColor = lightColor.rgb; #ifdef NO_SHADOW - - // Fully unshadowed. - float shadowed = 1.0; - - #ifdef PSSM_DEBUG_RENDER - debugColor = vec3(1.0); - #endif - + float shadow = 1.0; #else - vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap, - uv0.xy, - worldToLightProj, - worldPos, - scaleX, scaleY, - offsetX, offsetY, - farPlaneScalePSSM, - atlasXOffset, atlasYOffset, - atlasScale, - shadowSoftness, - dotNL, - overDarkPSSM); - vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap, - uv0.xy, - dynamicWorldToLightProj, - worldPos, - dynamicScaleX, dynamicScaleY, - dynamicOffsetX, dynamicOffsetY, - dynamicFarPlaneScalePSSM, - atlasXOffset, atlasYOffset, - atlasScale, - shadowSoftness, - dotNL, - overDarkPSSM); + // Fade out the shadow at the end of the range. + vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * surface.depth); + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + + vec4 static_shadowed_colors = AL_VectorLightShadowCast( shadowMap, uv0.xy, worldToLightProj, surface.P, scaleX, scaleY, offsetX, offsetY, + farPlaneScalePSSM, surfaceToLight.NdotL); + + vec4 dynamic_shadowed_colors = AL_VectorLightShadowCast( dynamicShadowMap, uv0.xy, dynamicWorldToLightProj, surface.P, dynamicScaleX, + dynamicScaleY, dynamicOffsetX, dynamicOffsetY, dynamicFarPlaneScalePSSM, surfaceToLight.NdotL); + float static_shadowed = static_shadowed_colors.a; float dynamic_shadowed = dynamic_shadowed_colors.a; #ifdef PSSM_DEBUG_RENDER - debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; + lightingColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; #endif - // Fade out the shadow at the end of the range. - vec4 zDist = vec4(zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); - float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; - - static_shadowed = mix( static_shadowed, 1.0, saturate( fadeOutAmt ) ); - dynamic_shadowed = mix( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) ); + static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) ); + dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) ); - // temp for debugging. uncomment one or the other. - //float shadowed = static_shadowed; - //float shadowed = dynamic_shadowed; - float shadowed = min(static_shadowed, dynamic_shadowed); + float shadow = min(static_shadowed, dynamic_shadowed); #ifdef PSSM_DEBUG_RENDER if ( fadeOutAmt > 1.0 ) - debugColor = vec3(1.0); + lightingColor = 1.0; #endif - #endif // !NO_SHADOW - - // Specular term - float specular = AL_CalcSpecular( -lightDirection, - normal, - normalize(-vsEyeRay) ) * lightBrightness * shadowed; - - float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; - vec3 lightColorOut = lightMapParams.rgb * lightColor.rgb; - vec4 addToResult = (lightAmbient * (1 - ambientCameraFactor)) + ( lightAmbient * ambientCameraFactor * saturate(dot(normalize(-vsEyeRay), normal)) ); - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = dotNL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - lightColorOut = vec3(shadowed); - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); - } - + #endif //NO_SHADOW // Sample the AO texture. #ifdef USE_SSAO_MASK - float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams3 ) ).r; - addToResult *= ao; + surface.ao *= 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams3 ) ).r; #endif - #ifdef PSSM_DEBUG_RENDER - lightColorOut = debugColor; - #endif + //get directional light contribution + vec3 lighting = getDirectionalLight(surface, surfaceToLight, lightingColor.rgb, lightBrightness, shadow); - OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + OUT_col = vec4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/irradianceP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/irradianceP.hlsl new file mode 100644 index 000000000..8edf5c3e6 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/irradianceP.hlsl @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" + +struct ConnectData +{ + float4 hpos : TORQUE_POSITION; + float2 uv : TEXCOORD; +}; + +uniform int face; + +TORQUE_UNIFORM_SAMPLERCUBE(environmentMap, 0); + +float4 main(ConnectData IN) : TORQUE_TARGET0 +{ + float3 N = getCubeDir(face,IN.uv); + float3 irradiance = 0; + + // tangent space calculation from origin point + float3 up = float3(0.0, 0.0, 1.0); + float3 right = cross(up, N); + up = cross(N, right); + + float sampleDelta = 0.025; + int nrSamples = 0; + for(float phi = 0.0; phi < M_2PI_F; phi += sampleDelta) + { + for(float theta = 0.0; theta < M_HALFPI_F; theta += sampleDelta) + { + // spherical to cartesian (in tangent space) + float3 tangentSample = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + // tangent space to world + float3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; + + irradiance += TORQUE_TEXCUBE(environmentMap, sampleVec).rgb * cos(theta) * sin(theta); + nrSamples++; + } + } + irradiance = M_PI_F * irradiance * (1.0 / float(nrSamples)); + + return float4(irradiance, 1.0); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl index 317feb0b3..eeb96d674 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl @@ -23,7 +23,6 @@ #include "../../shaderModelAutoGen.hlsl" #include "farFrustumQuad.hlsl" -#include "lightingUtils.hlsl" #include "../../lighting.hlsl" #include "../shadowMap/shadowMapIO_HLSL.h" #include "softShadow.hlsl" @@ -37,7 +36,6 @@ struct ConvexConnectP float4 vsEyeDir : TEXCOORD2; }; - #ifdef USE_COOKIE_TEX /// The texture for cookie rendering. @@ -88,7 +86,9 @@ TORQUE_UNIFORM_SAMPLERCUBE(cookieMap, 3); // this value was found via experementation // NOTE: this is wrong, it only biases in one direction, not towards the uv // center ( 0.5 0.5 ). - //shadowCoord.xy *= 0.997; + float offsetVal = 0.95; + shadowCoord.xy *= offsetVal; + shadowCoord.xy += (1.0-offsetVal).xx / 2.0; #ifndef SHADOW_PARABOLOID @@ -129,149 +129,83 @@ uniform float4 lightMapParams; uniform float4 vsFarPlane; uniform float4 lightParams; -uniform float lightRange; +uniform float lightRange; +uniform float lightInvSqrRange; uniform float shadowSoftness; -uniform float2 lightAttenuation; +uniform float4x4 worldToCamera; +uniform float3x3 worldToLightProj; +uniform float3x3 dynamicWorldToLightProj; -uniform float3x3 viewToLightProj; -uniform float3x3 dynamicViewToLightProj; +uniform float3 eyePosWorld; +uniform float4x4 cameraToWorld; -float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +float4 main( ConvexConnectP IN ) : SV_TARGET { // Compute scene UV float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; - float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); - - // Emissive. - float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) - { - return float4(0.0, 0.0, 0.0, 0.0); - } - float4 colorSample = TORQUE_TEX2D( colorBuffer, uvScene ); - float3 subsurface = float3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) - { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = float3(0.772549, 0.337255, 0.262745); - else - subsurface = float3(0.337255, 0.772549, 0.262745); - } - - // Sample/unpack the normal/z data - float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uvScene ); - float3 normal = deferredSample.rgb; - float depth = deferredSample.a; - - // Eye ray - Eye -> Pixel - float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); - float3 viewSpacePos = eyeRay * depth; + float2 uvScene = getUVFromSSPos(ssPos, rtParams0); + + //unpack normal and linear depth + float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, uvScene); - // Build light vec, get length, clip pixel if needed - float3 lightVec = lightPosition - viewSpacePos; - float lenLightV = length( lightVec ); - clip( lightRange - lenLightV ); + //eye ray WS/VS + float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz; - // Get the attenuated falloff. - float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - clip( atten - 1e-6 ); + //create surface + Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); - // Normalize lightVec - lightVec /= lenLightV; - - // If we can do dynamic branching then avoid wasting - // fillrate on pixels that are backfacing to the light. - float nDotL = dot( lightVec, normal ); - //DB_CLIP( nDotL < 0 ); + //early out if emissive + if (getFlag(surface.matFlag, 0)) + { + return 0.0.xxxx; + } + + float3 L = lightPosition - surface.P; + float dist = length(L); + float3 lighting = 0.0.xxx; + [branch] + if(dist < lightRange) + { + float distToLight = dist / lightRange; + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); #ifdef NO_SHADOW - float shadowed = 1.0; - #else - // Get a linear depth from the light source. - float distToLight = lenLightV / lightRange; + #ifdef SHADOW_CUBE - #ifdef SHADOW_CUBE - - // TODO: We need to fix shadow cube to handle soft shadows! - float occ = TORQUE_TEXCUBE( shadowMap, mul( viewToLightProj, -lightVec ) ).r; - float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); - - #else - - // Static - float2 shadowCoord = decodeShadowCoord( mul( viewToLightProj, -lightVec ) ).xy; - float static_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(shadowMap), - ssPos.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - // Dynamic - float2 dynamicShadowCoord = decodeShadowCoord( mul( dynamicViewToLightProj, -lightVec ) ).xy; - float dynamic_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), - ssPos.xy, - dynamicShadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - float shadowed = min(static_shadowed, dynamic_shadowed); - - #endif + // TODO: We need to fix shadow cube to handle soft shadows! + float occ = TORQUE_TEXCUBE( shadowMap, mul( worldToLightProj, -surfaceToLight.L ) ).r; + float shadowed = saturate( exp( lightParams.y * ( occ - distToLight ) ) ); + #else + float2 shadowCoord = decodeShadowCoord( mul( worldToLightProj, -surfaceToLight.L ) ).xy; + float2 dynShadowCoord = decodeShadowCoord( mul( dynamicWorldToLightProj, -surfaceToLight.L ) ).xy; + float static_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + float dynamic_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), ssPos.xy, dynShadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + float shadowed = min(static_shadowed, dynamic_shadowed); + #endif + #endif // !NO_SHADOW - float3 lightcol = lightColor.rgb; + float3 lightCol = lightColor.rgb; #ifdef USE_COOKIE_TEX - // Lookup the cookie sample. - float4 cookie = TORQUE_TEXCUBE( cookieMap, mul( viewToLightProj, -lightVec ) ); - + float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(worldToLightProj, -surfaceToLight.L)); // Multiply the light with the cookie tex. - lightcol *= cookie.rgb; - + lightCol *= cookie.rgb; // Use a maximum channel luminance to attenuate // the lighting else we get specular in the dark // regions of the cookie texture. - atten *= max( cookie.r, max( cookie.g, cookie.b ) ); - + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif - // NOTE: Do not clip on fully shadowed pixels as it would - // cause the hardware occlusion query to disable the shadow. - - // Specular term - float specular = AL_CalcSpecular( lightVec, - normal, - normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - - float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; - float3 lightColorOut = lightMapParams.rgb * lightcol; - float4 addToResult = 0.0; - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = nDotL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - shadowed = lerp( 1.0f, shadowed, atten ); - lightColorOut = shadowed; - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + //get punctual light contribution + lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); } - - return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + + return float4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl new file mode 100644 index 000000000..eeeb670c2 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/prefilterP.hlsl @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "../../torque.hlsl" + +struct ConnectData +{ + float4 hpos : SV_Position; + float2 uv : TEXCOORD; +}; + +TORQUE_UNIFORM_SAMPLERCUBE(environmentMap, 0); + +uniform float roughness; +uniform int face; +uniform int mipSize; +uniform int resolution; +float RadicalInverse_VdC(uint bits) +{ + bits = (bits << 16u) | (bits >> 16u); + bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); + bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); + bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); + bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); + return float(bits) * 2.3283064365386963e-10; // / 0x100000000 +} + +float2 Hammersley(uint i, uint N) +{ + return float2(float(i) / float(N), RadicalInverse_VdC(i)); +} + +float DistributionGGX(float3 N, float3 H, float roughness) +{ + float a = roughness * roughness; + float a2 = a * a; + float NdotH = max(dot(N, H), 0.0); + float NdotH2 = NdotH * NdotH; + + float nom = a2; + float denom = (NdotH2 * (a2 - 1.0) + 1.0); + denom = M_PI_F * denom * denom; + + return nom / denom; +} + +float3 ImportanceSampleGGX(float2 Xi, float3 N) +{ + float a = roughness * roughness; + + float phi = 2.0 * M_PI_F * Xi.x; + float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y)); + float sinTheta = sqrt(1.0 - cosTheta * cosTheta); + + // from spherical coordinates to cartesian coordinates + float3 H; + H.x = cos(phi) * sinTheta; + H.y = sin(phi) * sinTheta; + H.z = cosTheta; + + // from tangent-space vector to world-space sample vector + float3 up = abs(N.z) < 0.999 ? float3(0.0, 0.0, 1.0) : float3(1.0, 0.0, 0.0); + float3 tangent = normalize(cross(up, N)); + float3 bitangent = cross(N, tangent); + + float3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z; + return normalize(sampleVec); +} + +float4 prefilterEnvMap(float3 R) +{ + int sampleCount = resolution*2; + float3 N = R; + float3 V = R; + float totalWeight = 0.0; + float4 prefilteredColor = float4(0.0, 0.0, 0.0, 0.0); + + for (int i = 0; i < sampleCount; ++i) + { + float2 Xi = Hammersley(i, sampleCount); + float3 H = ImportanceSampleGGX(Xi, N); + float3 L = normalize(2.0 * dot(V, H) * H - V); + + float NdotL = max(dot(N, L), 0.0); + if (NdotL > 0.0) + { + // sample from the environment's mip level based on roughness/pdf + float D = DistributionGGX(N, H, roughness); + float NdotH = max(dot(N, H), 0.0); + float HdotV = max(dot(H, V), 0.0); + float pdf = D * NdotH / (4.0 * HdotV) + 0.0001; + + float saTexel = 4.0 * M_PI_F / (6.0 * sampleCount * sampleCount); + float saSample = 1.0 / (float(sampleCount) * pdf + 0.0001); + + float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel); + + prefilteredColor += TORQUE_TEXCUBELOD(environmentMap, float4(L, mipLevel)) * NdotL; + + totalWeight += NdotL; + } + } + + return (prefilteredColor / totalWeight); +} + +float4 main(ConnectData IN) : TORQUE_TARGET0 +{ + float3 N = getCubeDir(face, IN.uv); + return prefilterEnvMap(N); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl new file mode 100644 index 000000000..ea2ca7641 --- /dev/null +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/reflectionProbeArrayP.hlsl @@ -0,0 +1,203 @@ +#include "../../postFx/postFx.hlsl" +#include "../../shaderModel.hlsl" +#include "../../shaderModelAutoGen.hlsl" +#include "../../lighting.hlsl" + +TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); +TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 1); +TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 2); +TORQUE_UNIFORM_SAMPLER2D(BRDFTexture, 3); + +uniform float4 rtParams0; +uniform float4 vsFarPlane; +uniform float4x4 cameraToWorld; +uniform float3 eyePosWorld; + +//cubemap arrays require all the same size. so shared mips# value +uniform float cubeMips; + +uniform float numProbes; +TORQUE_UNIFORM_SAMPLERCUBEARRAY(specularCubemapAR, 4); +TORQUE_UNIFORM_SAMPLERCUBEARRAY(irradianceCubemapAR, 5); + +uniform float4 inProbePosArray[MAX_PROBES]; +uniform float4 inRefPosArray[MAX_PROBES]; +uniform float4x4 worldToObjArray[MAX_PROBES]; +uniform float4 bbMinArray[MAX_PROBES]; +uniform float4 bbMaxArray[MAX_PROBES]; +uniform float4 probeConfigData[MAX_PROBES]; //r,g,b/mode,radius,atten + +#if DEBUGVIZ_CONTRIB +uniform float4 probeContribColors[MAX_PROBES]; +#endif + +TORQUE_UNIFORM_SAMPLERCUBE(skylightSpecularMap, 6); +TORQUE_UNIFORM_SAMPLERCUBE(skylightIrradMap, 7); +uniform float hasSkylight; + +float4 main(PFXVertToPix IN) : SV_TARGET +{ + //unpack normal and linear depth + float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, IN.uv0.xy); + + //create surface + Surface surface = createSurface(normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), + IN.uv0.xy, eyePosWorld, IN.wsEyeRay, cameraToWorld); + + //early out if emissive + if (getFlag(surface.matFlag, 0)) + { + discard; + } + + float alpha = 1; + + int i = 0; + float blendFactor[MAX_PROBES]; + float blendSum = 0; + float blendFacSum = 0; + float invBlendSum = 0; + float probehits = 0; + //Set up our struct data + float contribution[MAX_PROBES]; + if (alpha > 0) + { + //Process prooooobes + for (i = 0; i < numProbes; ++i) + { + contribution[i] = 0; + + if (probeConfigData[i].r == 0) //box + { + contribution[i] = defineBoxSpaceInfluence(surface.P, worldToObjArray[i], probeConfigData[i].b); + if (contribution[i]>0.0) + probehits++; + } + else if (probeConfigData[i].r == 1) //sphere + { + contribution[i] = defineSphereSpaceInfluence(surface.P, inProbePosArray[i].xyz, probeConfigData[i].g); + if (contribution[i]>0.0) + probehits++; + } + + contribution[i] = max(contribution[i],0); + + blendSum += contribution[i]; + invBlendSum += (1.0f - contribution[i]); + } + // Weight0 = normalized NDF, inverted to have 1 at center, 0 at boundary. + // And as we invert, we need to divide by Num-1 to stay normalized (else sum is > 1). + // respect constraint B. + // Weight1 = normalized inverted NDF, so we have 1 at center, 0 at boundary + // and respect constraint A. + + if (probehits>1.0) + { + for (i = 0; i < numProbes; i++) + { + blendFactor[i] = ((contribution[i] / blendSum)) / probehits; + blendFactor[i] *= ((contribution[i]) / invBlendSum); + blendFactor[i] = saturate(blendFactor[i]); + blendFacSum += blendFactor[i]; + } + + // Normalize blendVal +#if DEBUGVIZ_ATTENUATION == 0 //this can likely be removed when we fix the above normalization behavior + if (blendFacSum == 0.0f) // Possible with custom weight + { + blendFacSum = 1.0f; + } +#endif + + float invBlendSumWeighted = 1.0f / blendFacSum; + for (i = 0; i < numProbes; ++i) + { + blendFactor[i] *= invBlendSumWeighted; + contribution[i] *= blendFactor[i]; + alpha -= contribution[i]; + } + } + else + alpha -= blendSum; + +#if DEBUGVIZ_ATTENUATION == 1 + float contribAlpha = 1; + for (i = 0; i < numProbes; ++i) + { + contribAlpha -= contribution[i]; + } + + return float4(1 - contribAlpha, 1 - contribAlpha, 1 - contribAlpha, 1); +#endif + +#if DEBUGVIZ_CONTRIB == 1 + float3 finalContribColor = float3(0, 0, 0); + float contribAlpha = 1; + for (i = 0; i < numProbes; ++i) + { + finalContribColor += contribution[i] *probeContribColors[i].rgb; + contribAlpha -= contribution[i]; + } + + //Skylight coloration for anything not covered by probes above + finalContribColor += float3(0.3, 0.3, 0.3) * contribAlpha; + + return float4(finalContribColor, 1); +#endif + } + + float3 irradiance = float3(0, 0, 0); + float3 specular = float3(0, 0, 0); + + // Radiance (Specular) +#if DEBUGVIZ_SPECCUBEMAP == 0 + float lod = surface.roughness*cubeMips; +#elif DEBUGVIZ_SPECCUBEMAP == 1 + float lod = 0; +#endif + + alpha = 1; + for (i = 0; i < numProbes; ++i) + { + float contrib = contribution[i]; + if (contrib != 0) + { + int cubemapIdx = probeConfigData[i].a; + float3 dir = boxProject(surface.P, surface.R, worldToObjArray[i], bbMinArray[i].xyz, bbMaxArray[i].xyz, inRefPosArray[i].xyz); + + irradiance += TORQUE_TEXCUBEARRAYLOD(irradianceCubemapAR, dir, cubemapIdx, 0).xyz * contrib; + specular += TORQUE_TEXCUBEARRAYLOD(specularCubemapAR, dir, cubemapIdx, lod).xyz * contrib; + alpha -= contrib; + } + } + + if (hasSkylight && alpha > 0.001) + { + irradiance += TORQUE_TEXCUBELOD(skylightIrradMap, float4(surface.R, 0)).xyz * alpha; + specular += TORQUE_TEXCUBELOD(skylightSpecularMap, float4(surface.R, lod)).xyz * alpha; + } + +#if DEBUGVIZ_SPECCUBEMAP == 1 && DEBUGVIZ_DIFFCUBEMAP == 0 + return float4(specular, 1); +#elif DEBUGVIZ_DIFFCUBEMAP == 1 + return float4(irradiance, 1); +#endif + + float3 F = FresnelSchlickRoughness(surface.NdotV, surface.f0, surface.roughness); + + //energy conservation + float3 kD = 1.0.xxx - F; + kD *= 1.0 - surface.metalness; + + //apply brdf + //Do it once to save on texture samples + float2 brdf = TORQUE_TEX2DLOD(BRDFTexture, float4(surface.roughness, 1.0-surface.NdotV, 0.0, 0.0)).xy; + specular *= brdf.x * F + brdf.y; + + //final diffuse color + float3 diffuse = kD * irradiance * surface.baseColor.rgb; + float4 finalColor = float4(diffuse + specular * surface.ao, 1.0); + +//finalColor.rgb += abs(surface.N); + return finalColor; +} diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl index 196286dc2..8cdc8630e 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl @@ -24,7 +24,6 @@ #include "../../shaderModelAutoGen.hlsl" #include "farFrustumQuad.hlsl" -#include "lightingUtils.hlsl" #include "../../lighting.hlsl" #include "../shadowMap/shadowMapIO_HLSL.h" #include "softShadow.hlsl" @@ -48,10 +47,8 @@ TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap,2); TORQUE_UNIFORM_SAMPLER2D(cookieMap, 3); #endif - -TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5); -TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6); -TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7); +TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 5); +TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 6); uniform float4 rtParams0; @@ -60,150 +57,90 @@ uniform float3 lightPosition; uniform float4 lightColor; -uniform float lightRange; +uniform float lightRange; +uniform float lightInvSqrRange; uniform float3 lightDirection; -uniform float4 lightSpotParams; +uniform float2 lightSpotParams; uniform float4 lightMapParams; uniform float4 vsFarPlane; -uniform float4x4 viewToLightProj; +uniform float4x4 worldToLightProj; +uniform float4x4 dynamicWorldToLightProj; uniform float4 lightParams; -uniform float4x4 dynamicViewToLightProj; -uniform float2 lightAttenuation; uniform float shadowSoftness; +uniform float3 eyePosWorld; -float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +uniform float4x4 cameraToWorld; +uniform float4x4 worldToCamera; + +float4 main( ConvexConnectP IN ) : SV_TARGET { // Compute scene UV float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; - float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); - - // Emissive. - float4 matInfo = TORQUE_TEX2D( matInfoBuffer, uvScene ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) - { - return float4(0.0, 0.0, 0.0, 0.0); - } + float2 uvScene = getUVFromSSPos(ssPos, rtParams0); - float4 colorSample = TORQUE_TEX2D( colorBuffer, uvScene ); - float3 subsurface = float3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) - { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = float3(0.772549, 0.337255, 0.262745); - else - subsurface = float3(0.337255, 0.772549, 0.262745); - } - - // Sample/unpack the normal/z data - float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uvScene ); - float3 normal = deferredSample.rgb; - float depth = deferredSample.a; - - // Eye ray - Eye -> Pixel - float3 eyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); - float3 viewSpacePos = eyeRay * depth; + //unpack normal and linear depth + float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, uvScene); - // Build light vec, get length, clip pixel if needed - float3 lightToPxlVec = viewSpacePos - lightPosition; - float lenLightV = length( lightToPxlVec ); - lightToPxlVec /= lenLightV; + //eye ray WS/VS + float3 vsEyeRay = getDistanceVectorToPlane( -vsFarPlane.w, IN.vsEyeDir.xyz, vsFarPlane ); + float3 wsEyeRay = mul(cameraToWorld, float4(vsEyeRay, 0)).xyz; - //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 0, 0, -1 ); - float cosAlpha = dot( lightDirection, lightToPxlVec ); - clip( cosAlpha - lightSpotParams.x ); - clip( lightRange - lenLightV ); + //create surface + Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), + uvScene, eyePosWorld, wsEyeRay, cameraToWorld); - float atten = attenuate( lightColor, lightAttenuation, lenLightV ); - atten *= ( cosAlpha - lightSpotParams.x ) / lightSpotParams.y; - clip( atten - 1e-6 ); - atten = saturate( atten ); - - float nDotL = dot( normal, -lightToPxlVec ); + //early out if emissive + if (getFlag(surface.matFlag, 0)) + { + return 0.0.xxxx; + } - // Get the shadow texture coordinate - float4 pxlPosLightProj = mul( viewToLightProj, float4( viewSpacePos, 1 ) ); - float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); - shadowCoord.y = 1.0f - shadowCoord.y; + float3 L = lightPosition - surface.P; + float dist = length(L); + float3 lighting = 0.0.xxx; + [branch] + if(dist < lightRange) + { + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, L); + #ifdef NO_SHADOW + float shadowed = 1.0; + #else + // Get the shadow texture coordinate + float4 pxlPosLightProj = mul( worldToLightProj, float4( surface.P, 1 ) ); + float2 shadowCoord = ( ( pxlPosLightProj.xy / pxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); + shadowCoord.y = 1.0f - shadowCoord.y; - // Get the dynamic shadow texture coordinate - float4 dynpxlPosLightProj = mul( dynamicViewToLightProj, float4( viewSpacePos, 1 ) ); - float2 dynshadowCoord = ( ( dynpxlPosLightProj.xy / dynpxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); - dynshadowCoord.y = 1.0f - dynshadowCoord.y; - - #ifdef NO_SHADOW - - float shadowed = 1.0; - - #else + float4 dynPxlPosLightProj = mul( dynamicWorldToLightProj, float4( surface.P, 1 ) ); + float2 dynShadowCoord = ( ( dynPxlPosLightProj.xy / dynPxlPosLightProj.w ) * 0.5 ) + float2( 0.5, 0.5 ); + dynShadowCoord.y = 1.0f - dynShadowCoord.y; - // Get a linear depth from the light source. - float distToLight = pxlPosLightProj.z / lightRange; + //distance to light in shadow map space + float distToLight = pxlPosLightProj.z / lightRange; + float dynDistToLight = dynPxlPosLightProj.z / lightRange; + float static_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(shadowMap), ssPos.xy, shadowCoord, shadowSoftness, distToLight, surfaceToLight.NdotL, lightParams.y); + float dynamic_shadowed = softShadow_filter(TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), ssPos.xy, dynShadowCoord, shadowSoftness, dynDistToLight, surfaceToLight.NdotL, lightParams.y); + float shadowed = min(static_shadowed, dynamic_shadowed); + #endif - float static_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(shadowMap), - ssPos.xy, - shadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - - float dynamic_shadowed = softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), - ssPos.xy, - dynshadowCoord, - shadowSoftness, - distToLight, - nDotL, - lightParams.y ); - float shadowed = min(static_shadowed, dynamic_shadowed); - #endif // !NO_SHADOW - - float3 lightcol = lightColor.rgb; + float3 lightCol = lightColor.rgb; #ifdef USE_COOKIE_TEX - // Lookup the cookie sample. - float4 cookie = TORQUE_TEX2D( cookieMap, shadowCoord ); - + float4 cookie = TORQUE_TEXCUBE(cookieMap, mul(worldToLightProj, -surfaceToLight.L)); // Multiply the light with the cookie tex. - lightcol *= cookie.rgb; - + lightCol *= cookie.rgb; // Use a maximum channel luminance to attenuate // the lighting else we get specular in the dark // regions of the cookie texture. - atten *= max( cookie.r, max( cookie.g, cookie.b ) ); - + lightCol *= max(cookie.r, max(cookie.g, cookie.b)); #endif - // NOTE: Do not clip on fully shadowed pixels as it would - // cause the hardware occlusion query to disable the shadow. - - // Specular term - float specular = AL_CalcSpecular( -lightToPxlVec, - normal, - normalize( -eyeRay ) ) * lightBrightness * atten * shadowed; - - float Sat_NL_Att = saturate( nDotL * atten * shadowed ) * lightBrightness; - float3 lightColorOut = lightMapParams.rgb * lightcol; - float4 addToResult = 0.0; - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = nDotL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - shadowed = lerp( 1.0f, shadowed, atten ); - lightColorOut = shadowed; - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); + //get Punctual light contribution + lighting = getPunctualLight(surface, surfaceToLight, lightCol, lightBrightness, lightInvSqrRange, shadowed); + //get spot angle attenuation + lighting *= getSpotAngleAtt(-surfaceToLight.L, lightDirection, lightSpotParams ); } - - return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + + return float4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl index c5efde242..1d1f98930 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl @@ -26,7 +26,6 @@ #include "farFrustumQuad.hlsl" #include "../../torque.hlsl" #include "../../lighting.hlsl" -#include "lightingUtils.hlsl" #include "../shadowMap/shadowMapIO_HLSL.h" #include "softShadow.hlsl" @@ -38,8 +37,7 @@ TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap, 2); TORQUE_UNIFORM_SAMPLER2D(ssaoMask, 3); uniform float4 rtParams3; #endif -//register 4? -TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5); + TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6); TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7); @@ -63,6 +61,7 @@ uniform float2 fadeStartLength; uniform float2 atlasScale; uniform float4x4 eyeMat; +uniform float4x4 cameraToWorld; // Static Shadows uniform float4x4 worldToLightProj; @@ -81,21 +80,16 @@ uniform float4 dynamicFarPlaneScalePSSM; float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap), float2 texCoord, float4x4 worldToLightProj, - float4 worldPos, + float3 worldPos, float4 scaleX, float4 scaleY, float4 offsetX, float4 offsetY, float4 farPlaneScalePSSM, - float4 atlasXOffset, - float4 atlasYOffset, - float2 atlasScale, - float shadowSoftness, - float dotNL , - float4 overDarkPSSM) + float dotNL) { // Compute shadow map coordinate - float4 pxlPosLightProj = mul(worldToLightProj, worldPos); + float4 pxlPosLightProj = mul(worldToLightProj, float4(worldPos,1)); float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w; // Distance to light, in shadowmap space @@ -139,7 +133,7 @@ float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap), #ifdef NO_SHADOW debugColor = float3(1.0,1.0,1.0); #endif - + #ifdef PSSM_DEBUG_RENDER if ( finalMask.x > 0 ) debugColor += float3( 1, 0, 0 ); @@ -182,147 +176,71 @@ float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap), float farPlaneScale = dot( farPlaneScalePSSM, finalMask ); distToLight *= farPlaneScale; - return float4(debugColor, - softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap), - texCoord, - shadowCoord, - farPlaneScale * shadowSoftness, - distToLight, - dotNL, - dot( finalMask, overDarkPSSM ) ) ); + return float4(debugColor, softShadow_filter( TORQUE_SAMPLER2D_MAKEARG(sourceShadowMap), texCoord, shadowCoord, farPlaneScale * shadowSoftness, + distToLight, dotNL, dot( finalMask, overDarkPSSM ) ) ); }; -float4 main( FarFrustumQuadConnectP IN ) : TORQUE_TARGET0 + +float4 main(FarFrustumQuadConnectP IN) : SV_TARGET { - // Emissive. - float4 matInfo = TORQUE_TEX2D( matInfoBuffer, IN.uv0 ); - bool emissive = getFlag( matInfo.r, 0 ); - if ( emissive ) - { - return float4(1.0, 1.0, 1.0, 0.0); - } - - float4 colorSample = TORQUE_TEX2D( colorBuffer, IN.uv0 ); - float3 subsurface = float3(0.0,0.0,0.0); - if (getFlag( matInfo.r, 1 )) - { - subsurface = colorSample.rgb; - if (colorSample.r>colorSample.g) - subsurface = float3(0.772549, 0.337255, 0.262745); - else - subsurface = float3(0.337255, 0.772549, 0.262745); + //unpack normal and linear depth + float4 normDepth = TORQUE_DEFERRED_UNCONDITION(deferredBuffer, IN.uv0); + + //create surface + Surface surface = createSurface( normDepth, TORQUE_SAMPLER2D_MAKEARG(colorBuffer),TORQUE_SAMPLER2D_MAKEARG(matInfoBuffer), + IN.uv0, eyePosWorld, IN.wsEyeRay, cameraToWorld); + + //early out if emissive + if (getFlag(surface.matFlag, 0)) + { + return 0.0.xxxx; } - // Sample/unpack the normal/z data - float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, IN.uv0 ); - float3 normal = deferredSample.rgb; - float depth = deferredSample.a; - - // Use eye ray to get ws pos - float4 worldPos = float4(eyePosWorld + IN.wsEyeRay * depth, 1.0f); - // Get the light attenuation. - float dotNL = dot(-lightDirection, normal); + //create surface to light + SurfaceToLight surfaceToLight = createSurfaceToLight(surface, -lightDirection); - #ifdef PSSM_DEBUG_RENDER - float3 debugColor = float3(0,0,0); - #endif + //light color might be changed by PSSM_DEBUG_RENDER + float3 lightingColor = lightColor.rgb; #ifdef NO_SHADOW - - // Fully unshadowed. - float shadowed = 1.0; - - #ifdef PSSM_DEBUG_RENDER - debugColor = float3(1.0,1.0,1.0); - #endif - + float shadow = 1.0; #else - - float4 static_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(shadowMap), - IN.uv0.xy, - worldToLightProj, - worldPos, - scaleX, scaleY, - offsetX, offsetY, - farPlaneScalePSSM, - atlasXOffset, atlasYOffset, - atlasScale, - shadowSoftness, - dotNL, - overDarkPSSM); - float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), - IN.uv0.xy, - dynamicWorldToLightProj, - worldPos, - dynamicScaleX, dynamicScaleY, - dynamicOffsetX, dynamicOffsetY, - dynamicFarPlaneScalePSSM, - atlasXOffset, atlasYOffset, - atlasScale, - shadowSoftness, - dotNL, - overDarkPSSM); - + + // Fade out the shadow at the end of the range. + float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * surface.depth); + float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; + + float4 static_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(shadowMap), IN.uv0.xy, worldToLightProj, surface.P, scaleX, scaleY, offsetX, offsetY, + farPlaneScalePSSM, surfaceToLight.NdotL); + + float4 dynamic_shadowed_colors = AL_VectorLightShadowCast( TORQUE_SAMPLER2D_MAKEARG(dynamicShadowMap), IN.uv0.xy, dynamicWorldToLightProj, surface.P, dynamicScaleX, + dynamicScaleY, dynamicOffsetX, dynamicOffsetY, dynamicFarPlaneScalePSSM, surfaceToLight.NdotL); + float static_shadowed = static_shadowed_colors.a; float dynamic_shadowed = dynamic_shadowed_colors.a; #ifdef PSSM_DEBUG_RENDER - debugColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; + lightingColor = static_shadowed_colors.rgb*0.5+dynamic_shadowed_colors.rgb*0.5; #endif - - // Fade out the shadow at the end of the range. - float4 zDist = (zNearFarInvNearFar.x + zNearFarInvNearFar.y * depth); - float fadeOutAmt = ( zDist.x - fadeStartLength.x ) * fadeStartLength.y; static_shadowed = lerp( static_shadowed, 1.0, saturate( fadeOutAmt ) ); dynamic_shadowed = lerp( dynamic_shadowed, 1.0, saturate( fadeOutAmt ) ); - // temp for debugging. uncomment one or the other. - //float shadowed = static_shadowed; - //float shadowed = dynamic_shadowed; - float shadowed = min(static_shadowed, dynamic_shadowed); + float shadow = min(static_shadowed, dynamic_shadowed); #ifdef PSSM_DEBUG_RENDER if ( fadeOutAmt > 1.0 ) - debugColor = 1.0; + lightingColor = 1.0; #endif - #endif // !NO_SHADOW - - // Specular term - float specular = AL_CalcSpecular( -lightDirection, - normal, - normalize(-IN.vsEyeRay) ) * lightBrightness * shadowed; - - float Sat_NL_Att = saturate( dotNL * shadowed ) * lightBrightness; - float3 lightColorOut = lightMapParams.rgb * lightColor.rgb; - - float4 addToResult = (lightAmbient * (1 - ambientCameraFactor)) + ( lightAmbient * ambientCameraFactor * saturate(dot(normalize(-IN.vsEyeRay), normal)) ); - - // TODO: This needs to be removed when lightmapping is disabled - // as its extra work per-pixel on dynamic lit scenes. - // - // Special lightmapping pass. - if ( lightMapParams.a < 0.0 ) - { - // This disables shadows on the backsides of objects. - shadowed = dotNL < 0.0f ? 1.0f : shadowed; - - Sat_NL_Att = 1.0f; - lightColorOut = shadowed; - specular *= lightBrightness; - addToResult = ( 1.0 - shadowed ) * abs(lightMapParams); - } - - // Sample the AO texture. + #endif //NO_SHADOW + // Sample the AO texture. #ifdef USE_SSAO_MASK - float ao = 1.0 - TORQUE_TEX2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r; - addToResult *= ao; + surface.ao *= 1.0 - TORQUE_TEX2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r; #endif + + //get directional light contribution + float3 lighting = getDirectionalLight(surface, surfaceToLight, lightingColor.rgb, lightBrightness, shadow); - #ifdef PSSM_DEBUG_RENDER - lightColorOut = debugColor; - #endif - - return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att); + return float4(lighting, 0); } diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_GLSL.h b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_GLSL.h index 10d69b834..d975fc054 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_GLSL.h +++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_GLSL.h @@ -24,16 +24,16 @@ #define pkDepthBitShft 65536.0 #define pkDepthChanMax 256.0 -#define bias -0.5/255.0 -#define coeff 0.9999991 -//#define coeff 1.0 +#define gbias -0.5/255.0 +#define gcoeff 0.9999991 +//#define gcoeff 1.0 vec4 encodeShadowMap( float depth ) { #if defined(SM_Fmt_R8G8B8A8) - return frac( vec4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + vec4(bias); + return frac( vec4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + vec4(gbias); - //float4 packedValue = frac((depth / coeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); + //float4 packedValue = frac((depth / gcoeff) * float4(16777216.0, 65536.0, 256.0, 1.0)); //return (packedValue - packedValue.xxyz * float4(0, 1.0 / 256, 1.0 / 256, 1.0 / 256)); #else return vec4(depth); diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl index 9f3500f67..894e68e79 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl @@ -32,8 +32,7 @@ uniform float3 fogData; uniform float4 rtParams0; float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 -{ - //float2 deferredCoord = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy; +{ float depth = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 ).w; //return float4( depth, 0, 0, 0.7 ); diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl index 269bfea67..dc99702c3 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl @@ -23,11 +23,9 @@ #include "../../shaderModel.hlsl" #define FXAA_PC 1 -#if (TORQUE_SM <= 30) -#define FXAA_HLSL_3 1 -#elif TORQUE_SM < 49 +#if TORQUE_SM == 40 #define FXAA_HLSL_4 1 -#elif TORQUE_SM >=50 +#elif TORQUE_SM > 40 #define FXAA_HLSL_5 1 #endif #define FXAA_QUALITY__PRESET 12 @@ -48,9 +46,7 @@ uniform float2 oneOverTargetSize; float4 main( VertToPix IN ) : TORQUE_TARGET0 { -#if (TORQUE_SM >= 10 && TORQUE_SM <=30) - FxaaTex tex = colorTex; -#elif TORQUE_SM >=40 +#if TORQUE_SM >=40 FxaaTex tex; tex.smpl = colorTex; tex.tex = texture_colorTex; diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl index 1e13d068b..ea9df604d 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl @@ -44,7 +44,7 @@ float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f; // Apply brightness - color.rgb += Brightness; - - return color; + //color.rgb += Brightness; + + return color; } \ No newline at end of file diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl index 07f7276c3..43a71a4a0 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl @@ -43,6 +43,30 @@ uniform float g_fOneOverGamma; uniform float Brightness; uniform float Contrast; +// uncharted 2 tonemapper see: http://filmicgames.com/archives/75 +float3 Uncharted2Tonemap(const float3 x) +{ + const float A = 0.15; + const float B = 0.50; + const float C = 0.10; + const float D = 0.20; + const float E = 0.02; + const float F = 0.30; + return ((x*(A*x + C*B) + D*E) / (x*(A*x + B) + D*F)) - E / F; +} + +float3 tonemap(float3 color) +{ + const float W = 11.2; + float ExposureBias = 2.0f; + //float ExposureAdjust = 1.5f; + //c *= ExposureAdjust; + color = Uncharted2Tonemap(ExposureBias*color); + color = color * (1.0f / Uncharted2Tonemap(W)); + + return color; +} + float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 { float4 sample = hdrDecode( TORQUE_TEX2D( sceneTex, IN.uv0 ) ); @@ -71,22 +95,23 @@ float4 main( PFXVertToPix IN ) : TORQUE_TARGET0 // Add the bloom effect. sample += g_fBloomScale * bloom; - - // Map the high range of color values into a range appropriate for - // display, taking into account the user's adaptation level, - // white point, and selected value for for middle gray. - if ( g_fEnableToneMapping > 0.0f ) - { - float Lp = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( sample.rgb ); - //float toneScalar = ( Lp * ( 1.0 + ( Lp / ( g_fWhiteCutoff ) ) ) ) / ( 1.0 + Lp ); - float toneScalar = Lp; - sample.rgb = lerp( sample.rgb, sample.rgb * toneScalar, g_fEnableToneMapping ); - } // Apply the color correction. sample.r = TORQUE_TEX1D( colorCorrectionTex, sample.r ).r; sample.g = TORQUE_TEX1D( colorCorrectionTex, sample.g ).g; sample.b = TORQUE_TEX1D( colorCorrectionTex, sample.b ).b; + // Apply contrast + sample.rgb = ((sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + //sample.rgb += Brightness; + + //tonemapping - TODO fix up eye adaptation + if ( g_fEnableToneMapping > 0.0f ) + { + sample.rgb = tonemap(sample.rgb); + } + return sample; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/finalPassCombineP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/finalPassCombineP.glsl index 4b173d4d3..224e51c5b 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/finalPassCombineP.glsl +++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/finalPassCombineP.glsl @@ -48,6 +48,29 @@ uniform float Contrast; out vec4 OUT_col; +// uncharted 2 tonemapper see: http://filmicgames.com/archives/75 +vec3 Uncharted2Tonemap(vec3 x) +{ + const float A = 0.15; + const float B = 0.50; + const float C = 0.10; + const float D = 0.20; + const float E = 0.02; + const float F = 0.30; + return ((x*(A*x + C*B) + D*E) / (x*(A*x + B) + D*F)) - E / F; +} + +vec3 tonemap(vec3 c) +{ + const float W = 11.2; + float ExposureBias = 2.0f; + float ExposureAdjust = 1.5f; + c *= ExposureAdjust; + vec3 curr = Uncharted2Tonemap(ExposureBias*c); + vec3 whiteScale = 1.0f / Uncharted2Tonemap(vec3(W,W,W)); + return curr*whiteScale; +} + void main() { vec4 _sample = hdrDecode( texture( sceneTex, IN_uv0 ) ); @@ -76,22 +99,23 @@ void main() // Add the bloom effect. _sample += g_fBloomScale * bloom; - - // Map the high range of color values into a range appropriate for - // display, taking into account the user's adaptation level, - // white point, and selected value for for middle gray. - if ( g_fEnableToneMapping > 0.0f ) - { - float Lp = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( _sample.rgb ); - //float toneScalar = ( Lp * ( 1.0 + ( Lp / ( g_fWhiteCutoff ) ) ) ) / ( 1.0 + Lp ); - float toneScalar = Lp; - _sample.rgb = mix( _sample.rgb, _sample.rgb * toneScalar, g_fEnableToneMapping ); - } // Apply the color correction. _sample.r = texture( colorCorrectionTex, _sample.r ).r; _sample.g = texture( colorCorrectionTex, _sample.g ).g; _sample.b = texture( colorCorrectionTex, _sample.b ).b; + // Apply contrast + _sample.rgb = ((_sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + //_sample.rgb += Brightness; + + //tonemapping - TODO fix up eye adaptation + if ( g_fEnableToneMapping > 0.0f ) + { + _sample.rgb = tonemap(_sample.rgb); + } + OUT_col = _sample; } diff --git a/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl index 70ce3a02d..d3fcd946a 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl @@ -24,74 +24,50 @@ #define _TORQUE_SHADERMODEL_ // Portability helpers for different shader models -//Shader model 1.0 - 3.0 -#if (TORQUE_SM >= 10 && TORQUE_SM <=30) - // Semantics - #define TORQUE_POSITION POSITION - #define TORQUE_DEPTH DEPTH - #define TORQUE_TARGET0 COLOR0 - #define TORQUE_TARGET1 COLOR1 - #define TORQUE_TARGET2 COLOR2 - #define TORQUE_TARGET3 COLOR3 - - // Sampler uniforms - #define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform sampler1D tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform sampler2D tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform sampler3D tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform samplerCUBE tex : register(S##regist) - // Sampling functions - #define TORQUE_TEX1D(tex,coords) tex1D(tex,coords) - #define TORQUE_TEX2D(tex,coords) tex2D(tex,coords) - #define TORQUE_TEX2DPROJ(tex,coords) tex2Dproj(tex,coords) //this really is sm 2 or later - #define TORQUE_TEX3D(tex,coords) tex3D(tex,coords) - #define TORQUE_TEXCUBE(tex,coords) texCUBE(tex,coords) - - //Shader model 3.0 only - #if TORQUE_SM == 30 - #define TORQUE_VPOS VPOS // This is a float2 - // The mipmap LOD is specified in coord.w - #define TORQUE_TEX2DLOD(tex,coords) tex2Dlod(tex,coords) - #endif +#define TORQUE_POSITION SV_Position +#define TORQUE_DEPTH SV_Depth +#define TORQUE_VPOS SV_Position //note float4 compared to SM 3 where it is a float2 +#define TORQUE_TARGET0 SV_Target0 +#define TORQUE_TARGET1 SV_Target1 +#define TORQUE_TARGET2 SV_Target2 +#define TORQUE_TARGET3 SV_Target3 +#define TORQUE_TARGET4 SV_Target4 +#define TORQUE_TARGET5 SV_Target5 +// Sampler uniforms +//1D is emulated to a 2D for now +#define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) +#define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) +#define TORQUE_UNIFORM_SAMPLER2DCMP(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerComparisonState tex : register(S##regist) +#define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform Texture3D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) +#define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform TextureCube texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) +#define TORQUE_UNIFORM_SAMPLERCUBEARRAY(tex,regist) uniform TextureCubeArray texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) +// Sampling functions +#define TORQUE_TEX1D(tex,coords) texture_##tex.Sample(tex,coords) +#define TORQUE_TEX2D(tex,coords) texture_##tex.Sample(tex,coords) +#define TORQUE_TEX2DPROJ(tex,coords) texture_##tex.Sample(tex,coords.xy / coords.w) +#define TORQUE_TEX3D(tex,coords) texture_##tex.Sample(tex,coords) +#define TORQUE_TEXCUBE(tex,coords) texture_##tex.Sample(tex,coords) +#define TORQUE_TEXCUBEARRAY(tex,coords) texture_##tex.Sample(tex,coords) +// The mipmap LOD is specified in coord.w +#define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w) +#define TORQUE_TEXCUBELOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xyz,coords.w) +#define TORQUE_TEXCUBEARRAYLOD(tex,coords,id,lod) texture_##tex.SampleLevel(tex,float4(coords.xyz,id),lod) +// Tex2d comparison +#define TORQUE_TEX2DCMP(tex,coords,compare) texture_##tex.SampleCmpLevelZero(tex,coords,compare) - //helper if you want to pass sampler/texture in a function - //2D - #define TORQUE_SAMPLER2D(tex) sampler2D tex - #define TORQUE_SAMPLER2D_MAKEARG(tex) tex - //Cube - #define TORQUE_SAMPLERCUBE(tex) samplerCUBE tex - #define TORQUE_SAMPLERCUBE_MAKEARG(tex) tex -// Shader model 4.0+ -#elif TORQUE_SM >= 40 - #define TORQUE_POSITION SV_Position - #define TORQUE_DEPTH SV_Depth - #define TORQUE_VPOS SV_Position //note float4 compared to SM 3 where it is a float2 - #define TORQUE_TARGET0 SV_Target0 - #define TORQUE_TARGET1 SV_Target1 - #define TORQUE_TARGET2 SV_Target2 - #define TORQUE_TARGET3 SV_Target3 - // Sampler uniforms - //1D is emulated to a 2D for now - #define TORQUE_UNIFORM_SAMPLER1D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLER2D(tex,regist) uniform Texture2D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLER3D(tex,regist) uniform Texture3D texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) - #define TORQUE_UNIFORM_SAMPLERCUBE(tex,regist) uniform TextureCube texture_##tex : register(T##regist); uniform SamplerState tex : register(S##regist) - // Sampling functions - #define TORQUE_TEX1D(tex,coords) texture_##tex.Sample(tex,coords) - #define TORQUE_TEX2D(tex,coords) texture_##tex.Sample(tex,coords) - #define TORQUE_TEX2DPROJ(tex,coords) texture_##tex.Sample(tex,coords.xy / coords.w) - #define TORQUE_TEX3D(tex,coords) texture_##tex.Sample(tex,coords) - #define TORQUE_TEXCUBE(tex,coords) texture_##tex.Sample(tex,coords) - // The mipmap LOD is specified in coord.w - #define TORQUE_TEX2DLOD(tex,coords) texture_##tex.SampleLevel(tex,coords.xy,coords.w) +#define TORQUE_TEX2DGATHER(tex,coords,compare,offset) texture_##tex.GatherCmp(tex,coords,compare,offset) - //helper if you want to pass sampler/texture in a function - //2D - #define TORQUE_SAMPLER2D(tex) Texture2D texture_##tex, SamplerState tex - #define TORQUE_SAMPLER2D_MAKEARG(tex) texture_##tex, tex - //Cube - #define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex - #define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex -#endif +//helper if you want to pass sampler/texture in a function +//2D +#define TORQUE_SAMPLER2D(tex) Texture2D texture_##tex, SamplerState tex +#define TORQUE_SAMPLER2D_MAKEARG(tex) texture_##tex, tex +// Sampler comparison state - use above MAKEARG with this +#define TORQUE_SAMPLER2DCMP(tex) Texture2D texture_##tex, SamplerComparisonState tex +//Cube +#define TORQUE_SAMPLERCUBE(tex) TextureCube texture_##tex, SamplerState tex +#define TORQUE_SAMPLERCUBE_MAKEARG(tex) texture_##tex, tex +#define TORQUE_SAMPLERCUBEARRAY(tex) TextureCubeArray texture_##tex, SamplerState tex +#define TORQUE_SAMPLERCUBEARRAY_MAKEARG(tex) texture_##tex, tex #endif // _TORQUE_SHADERMODEL_ diff --git a/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl b/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl index d70847e46..7c789216f 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl @@ -24,12 +24,10 @@ #define _TORQUE_SHADERMODEL_AUTOGEN_ #include "shadergen:/autogenConditioners.h" +#include "./shaderModel.hlsl" // Portability helpers for autogenConditioners -#if (TORQUE_SM >= 10 && TORQUE_SM <=30) - #define TORQUE_DEFERRED_UNCONDITION(tex, coords) deferredUncondition(tex, coords) -#elif TORQUE_SM >= 40 - #define TORQUE_DEFERRED_UNCONDITION(tex, coords) deferredUncondition(tex, texture_##tex, coords) -#endif + +#define TORQUE_DEFERRED_UNCONDITION(tex, coords) deferredUncondition(tex, texture_##tex, coords) #endif //_TORQUE_SHADERMODEL_AUTOGEN_ diff --git a/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl index 7081c7153..f4555ec78 100644 --- a/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl +++ b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl @@ -167,22 +167,13 @@ float2 parallaxOffsetDxtnm(TORQUE_SAMPLER2D(texMap), float2 texCoord, float3 neg return offset; } - -/// The maximum value for 16bit per component integer HDR encoding. -static const float HDR_RGB16_MAX = 100.0; - /// The maximum value for 10bit per component integer HDR encoding. static const float HDR_RGB10_MAX = 4.0; /// Encodes an HDR color for storage into a target. float3 hdrEncode( float3 sample ) { - #if defined( TORQUE_HDR_RGB16 ) - - return sample / HDR_RGB16_MAX; - - #elif defined( TORQUE_HDR_RGB10 ) - + #if defined( TORQUE_HDR_RGB10 ) return sample / HDR_RGB10_MAX; #else @@ -202,12 +193,7 @@ float4 hdrEncode( float4 sample ) /// Decodes an HDR color from a target. float3 hdrDecode( float3 sample ) { - #if defined( TORQUE_HDR_RGB16 ) - - return sample * HDR_RGB16_MAX; - - #elif defined( TORQUE_HDR_RGB10 ) - + #if defined( TORQUE_HDR_RGB10 ) return sample * HDR_RGB10_MAX; #else @@ -286,37 +272,6 @@ bool getFlag(float flags, int num) return (fmod(process, pow(2, squareNum)) >= squareNum); } -// #define TORQUE_STOCK_GAMMA -#ifdef TORQUE_STOCK_GAMMA -// Sample in linear space. Decodes gamma. -float4 toLinear(float4 tex) -{ - return tex; -} -// Encodes gamma. -float4 toGamma(float4 tex) -{ - return tex; -} -float3 toLinear(float3 tex) -{ - return tex; -} -// Encodes gamma. -float3 toGamma(float3 tex) -{ - return tex; -} -float3 toLinear(float3 tex) -{ - return tex; -} -// Encodes gamma. -float3 toLinear(float3 tex) -{ - return tex; -} -#else // Sample in linear space. Decodes gamma. float4 toLinear(float4 tex) { @@ -337,6 +292,58 @@ float3 toGamma(float3 tex) { return pow(abs(tex.rgb), 1.0/2.2); } -#endif // +// +float3 PBRFresnel(float3 albedo, float3 indirect, float metalness, float fresnel) +{ + float3 diffuseColor = albedo - (albedo * metalness); + float3 reflectColor = lerp(indirect*albedo, indirect, fresnel); + + return diffuseColor + reflectColor; +} + +float3 simpleFresnel(float3 diffuseColor, float3 reflectColor, float metalness, float angle, float bias, float power) +{ + float fresnelTerm = bias + (1.0 - bias) * pow(abs(1.0 - max(angle, 0)), power); + + fresnelTerm *= metalness; + + return lerp(diffuseColor, reflectColor, fresnelTerm); +} + +//hlsl version of the glsl funcion mod - note hlsl fmod is different +#define mod(x,y) (x-y*floor(x/y)) + +//get direction for a cube face +float3 getCubeDir(int face, float2 uv) +{ + float2 debiased = uv * 2.0f - 1.0f; + + float3 dir = 0; + + switch (face) + { + case 0: dir = float3(1, -debiased.y, -debiased.x); + break; + + case 1: dir = float3(-1, -debiased.y, debiased.x); + break; + + case 2: dir = float3(debiased.x, 1, debiased.y); + break; + + case 3: dir = float3(debiased.x, -1, -debiased.y); + break; + + case 4: dir = float3(debiased.x, -debiased.y, 1); + break; + + case 5: dir = float3(-debiased.x, -debiased.y, -1); + break; + }; + + return normalize(dir); +} + +#define sqr(a) ((a)*(a)) #endif // _TORQUE_HLSL_ diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange.png b/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange.png new file mode 100644 index 000000000..43c4953e8 Binary files /dev/null and b/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange.png differ diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange_ALBEDO.asset.taml b/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange_ALBEDO.asset.taml new file mode 100644 index 000000000..207d697bc --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Images/Grid_512_orange_ALBEDO.asset.taml @@ -0,0 +1,9 @@ + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.asset.taml b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.asset.taml new file mode 100644 index 000000000..385eebc44 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.asset.taml @@ -0,0 +1,9 @@ + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.cs b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.cs new file mode 100644 index 000000000..e5f5535c9 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.cs @@ -0,0 +1,5 @@ + +singleton TSShapeConstructor(CubeFbx) +{ + baseShape = "./Cube.fbx"; +}; diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.fbx b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.fbx new file mode 100644 index 000000000..944bc46b3 Binary files /dev/null and b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cube.fbx differ diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.asset.taml b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.asset.taml new file mode 100644 index 000000000..2550fd56b --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.cs b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.cs new file mode 100644 index 000000000..25a1e3298 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.cs @@ -0,0 +1,5 @@ + +singleton TSShapeConstructor(CylinderFbx) +{ + baseShape = "./Cylinder.fbx"; +}; diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.fbx b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.fbx new file mode 100644 index 000000000..dc74730e1 Binary files /dev/null and b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/Cylinder.fbx differ diff --git a/Templates/BaseGame/game/data/StaticShapeTest/Shapes/materials.cs b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/materials.cs new file mode 100644 index 000000000..859c1cc94 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/Shapes/materials.cs @@ -0,0 +1,11 @@ + +singleton Material(Grid_512_Orange) +{ + mapTo = "Grid_512_orange"; + diffuseColor[0] = "0.8 0.8 0.8 1"; + diffuseMap[0] = "E:/Gamedev/T3DMIT/clangtest/Templates/Full/game/core/art/grids/Grid_512_orange.png"; + specular[0] = "0.8 0.8 0.8 1"; + specularPower[0] = "0.25"; + specularStrength[0] = "25"; + translucentBlendOp = "None"; +}; diff --git a/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.cs b/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.cs new file mode 100644 index 000000000..5a8376011 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.cs @@ -0,0 +1,10 @@ +function StaticShapeTest::onCreate(%this) +{ + +} + +function StaticShapeTest::onDestroy(%this) +{ + +} + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.module b/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.module new file mode 100644 index 000000000..44a535b69 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/StaticShapeTest.module @@ -0,0 +1,25 @@ + + + + + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.asset.taml b/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.asset.taml new file mode 100644 index 000000000..63f68bd6c --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.asset.taml @@ -0,0 +1,9 @@ + diff --git a/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.cs b/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.cs new file mode 100644 index 000000000..84e941012 --- /dev/null +++ b/Templates/BaseGame/game/data/StaticShapeTest/materials/Grid_512_orange.cs @@ -0,0 +1,7 @@ +//--- OBJECT WRITE BEGIN --- +singleton Material(Grid_512_orange) { + mapTo = "Grid_512_orange"; + DiffuseMap[0] = "data/StaticShapeTest/Images/Grid_512_orange.png"; + DiffuseMapAsset[0] = "StaticShapeTest:Grid_512_orange_ALBEDO"; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl index 560f6c23d..baae3874a 100644 --- a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl +++ b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_P.hlsl @@ -4,17 +4,6 @@ // Dependencies: #include "core/rendering/shaders/lighting.hlsl" -//------------------------------------------------------------------------------ -// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method -//------------------------------------------------------------------------------ -inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) -{ - lightColor = bufferSample.rgb; - NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); - specular = bufferSample.a; -} - - #include "core/rendering/shaders/torque.hlsl" // Features: @@ -27,7 +16,8 @@ inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 light struct ConnectData { float4 vpos : SV_Position; - float4 screenspacePos : TEXCOORD0; + float3 wsNormal : TEXCOORD0; + float3 wsPosition : TEXCOORD1; }; @@ -42,10 +32,17 @@ struct Fragout //----------------------------------------------------------------------------- Fragout main( ConnectData IN, uniform float4 diffuseMaterialColor : register(C0), - uniform float4 rtParamslightInfoBuffer : register(C2), - uniform SamplerState lightInfoBuffer : register(S0), - uniform Texture2D lightInfoBufferTex : register(T0), - uniform float visibility : register(C1) + uniform float3 eyePosWorld : register(C17), + uniform float4 inLightPos[3] : register(C1), + uniform float4 inLightInvRadiusSq : register(C4), + uniform float4 inLightColor[4] : register(C5), + uniform float4 inLightSpotDir[3] : register(C9), + uniform float4 inLightSpotAngle : register(C12), + uniform float4 inLightSpotFalloff : register(C13), + uniform float smoothness : register(C14), + uniform float metalness : register(C15), + uniform float4 ambient : register(C18), + uniform float visibility : register(C16) ) { Fragout OUT; @@ -56,15 +53,13 @@ Fragout main( ConnectData IN, OUT.col = diffuseMaterialColor; // Deferred RT Lighting - float2 uvScene = IN.screenspacePos.xy / IN.screenspacePos.w; - uvScene = ( uvScene + 1.0 ) / 2.0; - uvScene.y = 1.0 - uvScene.y; - uvScene = ( uvScene * rtParamslightInfoBuffer.zw ) + rtParamslightInfoBuffer.xy; - float3 d_lightcolor; - float d_NL_Att; - float d_specular; - lightinfoUncondition(lightInfoBufferTex.Sample(lightInfoBuffer, uvScene), d_lightcolor, d_NL_Att, d_specular); - OUT.col *= float4(d_lightcolor, 1.0); + IN.wsNormal = normalize( half3( IN.wsNormal ) ); + float3 wsView = normalize( eyePosWorld - IN.wsPosition ); + float4 rtShading; float4 specular; + compute4Lights( wsView, IN.wsPosition, IN.wsNormal, float4( 1, 1, 1, 1 ), + inLightPos, inLightInvRadiusSq, inLightColor, inLightSpotDir, inLightSpotAngle, inLightSpotFalloff, smoothness, metalness, OUT.col, + rtShading, specular ); + OUT.col *= float4( rtShading.rgb + ambient.rgb, 1 ); // Visibility fizzle( IN.vpos.xy, visibility ); diff --git a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl index be8a848ef..144225bb5 100644 --- a/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl +++ b/Templates/BaseGame/game/data/shaderCache/8625023c97ea6cf9_V.hlsl @@ -4,17 +4,6 @@ // Dependencies: #include "core/rendering/shaders/lighting.hlsl" -//------------------------------------------------------------------------------ -// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method -//------------------------------------------------------------------------------ -inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) -{ - lightColor = bufferSample.rgb; - NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); - specular = bufferSample.a; -} - - #include "core/rendering/shaders/torque.hlsl" // Features: @@ -38,7 +27,8 @@ struct VertData struct ConnectData { float4 hpos : SV_Position; - float4 screenspacePos : TEXCOORD0; + float3 wsNormal : TEXCOORD0; + float3 outWsPosition : TEXCOORD1; }; @@ -46,7 +36,8 @@ struct ConnectData // Main //----------------------------------------------------------------------------- ConnectData main( VertData IN, - uniform float4x4 modelview : register(C0) + uniform float4x4 modelview : register(C0), + uniform float4x4 objTrans : register(C4) ) { ConnectData OUT; @@ -57,7 +48,8 @@ ConnectData main( VertData IN, // Diffuse Color // Deferred RT Lighting - OUT.screenspacePos = OUT.hpos; + OUT.wsNormal = mul( objTrans, float4( normalize( IN.normal ), 0.0 ) ).xyz; + OUT.outWsPosition = mul( objTrans, float4( IN.position.xyz, 1 ) ).xyz; // Visibility diff --git a/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h b/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h index 065cea6dc..ce64bfb4b 100644 --- a/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h +++ b/Templates/BaseGame/game/data/shaderCache/autogenConditioners.h @@ -1,25 +1,3 @@ -//------------------------------------------------------------------------------ -// Autogenerated 'Light Buffer Conditioner [RGB]' Condition Method -//------------------------------------------------------------------------------ -inline float4 autogenCondition_bde4cbab(in float3 lightColor, in float NL_att, in float specular, in float4 bufferSample) -{ - float4 rgbLightInfoOut = float4(lightColor, 0) * NL_att + float4(bufferSample.rgb, specular); - - return rgbLightInfoOut; -} - - -//------------------------------------------------------------------------------ -// Autogenerated 'Light Buffer Conditioner [RGB]' Uncondition Method -//------------------------------------------------------------------------------ -inline void autogenUncondition_bde4cbab(in float4 bufferSample, out float3 lightColor, out float NL_att, out float specular) -{ - lightColor = bufferSample.rgb; - NL_att = dot(bufferSample.rgb, float3(0.3576, 0.7152, 0.1192)); - specular = bufferSample.a; -} - - //------------------------------------------------------------------------------ // Autogenerated 'GBuffer Conditioner' Condition Method //------------------------------------------------------------------------------ diff --git a/Templates/BaseGame/game/data/ui/art/BackgroundImage.png b/Templates/BaseGame/game/data/ui/art/BackgroundImage.png new file mode 100644 index 000000000..d35403338 Binary files /dev/null and b/Templates/BaseGame/game/data/ui/art/BackgroundImage.png differ diff --git a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui index 328d946b6..a759cc42e 100644 --- a/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui +++ b/Templates/BaseGame/game/tools/materialEditor/gui/guiMaterialPropertiesWindow.ed.gui @@ -528,12 +528,115 @@ bitmap = "tools/gui/images/delete"; }; }; - new GuiBitmapCtrl(){ - position="6 360"; - extent ="175 2"; + }; + }; + new GuiRolloutCtrl() { // Light Influence Properties Group + class = "BehaviorQuickEditRollout"; + superclass = LBQuickEditRollout; + Profile = "GuiRolloutProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "0 0"; + Extent = "202 0"; + Caption = "Light Influence Maps"; + Expanded = false; + Margin = "4 4 4 0"; + DragSizable = false; + container = true; + parentRollout = %this.rollout; + object = %behavior; + object = %behavior; + + new GuiStackControl() { + StackingType = "Vertical"; + HorizStacking = "Left to Right"; + VertStacking = "Top to Bottom"; + Padding = "0"; + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "1"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "width"; + VertSizing = "bottom"; + Position = "1 3"; + Extent = "185 16"; + MinExtent = "16 16"; + canSave = "1"; + isDecoy = "0"; + Visible = "1"; + tooltipprofile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + + new GuiContainer(){ // spec Map options + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "6 364"; + Extent = "185 20"; HorizSizing = "width"; - bitmap ="tools/gui/images/separator-v"; - }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "isSRGBCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "5 2"; + Extent = "57 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"isSRGb[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Substance Designer Workaround."; + hovertime = "1000"; + text = "isSRGB"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + new GuiCheckBoxCtrl() { + canSaveDynamicFields = "0"; + internalName = "invertSmoothnessCheckbox"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiCheckBoxProfile"; + HorizSizing = "right"; + VertSizing = "bottom"; + position = "70 2"; + Extent = "57 16"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + Command = "MaterialEditorGui.updateActiveMaterial(\"invertSmoothness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + tooltipprofile = "ToolsGuiDefaultProfile"; + ToolTip = "Treat as Roughest = 1.0, not 0.0"; + hovertime = "1000"; + text = "Invert Smoothness"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + useInactiveState = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + position = "6 75"; + extent = "175 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; new GuiContainer(){ // spec Map profile="ToolsGuiDefaultProfile"; isContainer = "1"; @@ -577,7 +680,7 @@ AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "Spec Map"; + text = "Composite Map"; maxLength = "1024"; }; new GuiBitmapButtonCtrl() { @@ -594,7 +697,7 @@ Visible = "1"; Command = "MaterialEditorGui.updateSpecMap(1);"; tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Change the active Tone Map for this layer."; + ToolTip = "Change the packed spec map for this layer. \n Smoothness (R), Ambient Occlusion (G), and Metalness(B))"; hovertime = "1000"; groupNum = "-1"; buttonType = "PushButton"; @@ -654,7 +757,802 @@ bitmap = "tools/gui/images/delete"; }; }; - }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + position = "6 75"; + extent = "175 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer(){ // save composite Map + profile="ToolsGuiDefaultProfile"; + isContainer = "1"; + position = "0 364"; + Extent = "185 20"; + HorizSizing = "width"; + new GuiTextCtrl() { + canSaveDynamicFields = "0"; + Enabled = "1"; + isContainer = "0"; + Profile = "ToolsGuiDefaultProfile"; + HorizSizing = "left"; + VertSizing = "bottom"; + position = "16 2"; + Extent = "100 18"; + MinExtent = "8 2"; + canSave = "1"; + Visible = "1"; + hovertime = "1000"; + Margin = "0 0 0 0"; + Padding = "0 0 0 0"; + AnchorTop = "1"; + AnchorBottom = "0"; + AnchorLeft = "1"; + AnchorRight = "0"; + text = "Save Composite:"; + maxLength = "1024"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/save-icon"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "125 2"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.saveCompositeMap();"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + wrap = "0"; + position = "6 75"; + extent = "175 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 364"; + extent = "185 52"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "roughMapDisplayBitmap"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Smoothness"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 5"; + extent = "35 8"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateroughMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Change the Smoothness map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "143 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "roughMapNameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "134 34"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateroughMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "177 34"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateroughMap(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(roughChanBtn0) { + text = "R"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "100 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setRoughChan(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(roughChanBtn1) { + text = "G"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "121 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setRoughChan(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(roughChanBtn2) { + text = "B"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "142 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setRoughChan(2);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(roughChanBtn3) { + text = "A"; + groupNum = "1"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "163 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setRoughChan(3);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 364"; + extent = "185 52"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "aoMapDisplayBitmap"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "ao"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 5"; + extent = "35 8"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateaoMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Change the AO map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "143 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "aoMapNameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "134 34"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateaoMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "177 34"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updateaoMap(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(aoChanBtn0) { + text = "R"; + groupNum = "2"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "100 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setAOChan(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(aoChanBtn1) { + text = "G"; + groupNum = "2"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "121 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setAOChan(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(aoChanBtn2) { + text = "B"; + groupNum = "2"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "142 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setAOChan(2);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(aoChanBtn3) { + text = "A"; + groupNum = "2"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "163 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setAOChan(3);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 364"; + extent = "185 52"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialeditor/gui/unknownImage"; + wrap = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "metalMapDisplayBitmap"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "metal"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 5"; + extent = "35 8"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updatemetalMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "Change the Metalness Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "143 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "metalMapNameText"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "134 34"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updatemetalMap(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "177 34"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.updatemetalMap(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(metalChanBtn0) { + text = "R"; + groupNum = "3"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "100 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setMetalChan(0);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(metalChanBtn1) { + text = "G"; + groupNum = "3"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "121 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setMetalChan(1);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(metalChanBtn2) { + text = "B"; + groupNum = "3"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "142 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setMetalChan(2);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiRadioCtrl(metalChanBtn3) { + text = "A"; + groupNum = "3"; + buttonType = "RadioButton"; + useMouseEvents = "0"; + position = "163 5"; + extent = "20 10"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiRadioProfile"; + visible = "1"; + active = "1"; + command = "MaterialEditorGui.setMetalChan(3);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + }; }; new GuiRolloutCtrl(advancedTextureMapsRollout) { class = "BehaviorQuickEditRollout"; @@ -1356,7 +2254,7 @@ }; }; }; - new GuiRolloutCtrl() { + new GuiRolloutCtrl(accumulationPropertiesRollout) { class = "BehaviorQuickEditRollout"; superclass = LBQuickEditRollout; Profile = "GuiRolloutProfile"; @@ -1833,7 +2731,7 @@ }; }; - new GuiRolloutCtrl() { + new GuiRolloutCtrl(lightingPropertiesRollout) { class = "BehaviorQuickEditRollout"; superclass = LBQuickEditRollout; Profile = "GuiRolloutProfile"; @@ -1875,56 +2773,21 @@ position = "0 0"; Extent = "185 44"; HorizSizing = "width"; - - new GuiCheckBoxCtrl() { - canSaveDynamicFields = "0"; - internalName = "pixelSpecularCheckbox"; - Enabled = "1"; - isContainer = "0"; - Profile = "ToolsGuiCheckBoxProfile"; + + new GuiTextCtrl() { HorizSizing = "right"; VertSizing = "bottom"; - position = "8 4"; - Extent = "57 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "MaterialEditorGui.updateSpecularCheckbox($ThisControl.getValue());"; - tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Enables the use of Pixel Specular for this layer."; - hovertime = "1000"; - text = "Specular"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; - useInactiveState = "0"; - }; - new GuiSwatchButtonCtrl() { - canSaveDynamicFields = "0"; - internalName = "specularColorSwatch"; - Enabled = "1"; - isContainer = "0"; - Profile = "GuiInspectorSwatchButtonProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "69 4"; - Extent = "16 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "getColorF(materialEd_PreviewMaterial.specular[MaterialEditorGui.currentLayer], \"MaterialEditorGui.updateSpecular\");"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; + position = "9 4"; + Extent = "72 16"; + text = "Smoothness"; + }; new GuiTextCtrl() { HorizSizing = "right"; VertSizing = "bottom"; position = "9 26"; Extent = "72 16"; - text = "Spec strength"; + text = "Metalness"; }; new GuiControl() { @@ -1934,7 +2797,7 @@ new GuiSliderCtrl() { canSaveDynamicFields = "0"; - internalName = "specularPowerSlider"; + internalName = "SmoothnessSlider"; Enabled = "1"; isContainer = "0"; Profile = "ToolsGuiSliderProfile"; @@ -1945,18 +2808,18 @@ MinExtent = "8 2"; canSave = "1"; Visible = "1"; - Command = "MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, true);"; - AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()), true, false);"; + Command = "MaterialEditorGui.updateActiveMaterial(\"Smoothness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"Smoothness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Sets the hardness of the Pixel Specular value."; + ToolTip = "Sets Smoothness."; hovertime = "1000"; - range = "1 128"; + range = "0 1"; ticks = "0"; - value = "1"; + value = "0"; }; new GuiTextEditCtrl() { canSaveDynamicFields = "0"; - internalName = "specularPowerTextEdit"; + internalName = "SmoothnessTextEdit"; Enabled = "1"; isContainer = "0"; Profile = "ToolsGuiTextEditProfile"; @@ -1967,14 +2830,13 @@ MinExtent = "8 2"; canSave = "1"; Visible = "1"; - Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularPower[\" @ MaterialEditorGui.currentLayer @ \"]\", mCeil($ThisControl.getValue()));"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"Smoothness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; hovertime = "1000"; AnchorTop = "1"; AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "32"; - maxLength = "3"; + text = "0"; }; }; @@ -1985,7 +2847,7 @@ new GuiSliderCtrl() { canSaveDynamicFields = "0"; - internalName = "specularStrengthSlider"; + internalName = "MetalnessSlider"; Enabled = "1"; isContainer = "0"; Profile = "ToolsGuiSliderProfile"; @@ -1996,18 +2858,18 @@ MinExtent = "8 2"; canSave = "1"; Visible = "1"; - Command = "MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; - AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; + Command = "MaterialEditorGui.updateActiveMaterial(\"Metalness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, true);"; + AltCommand = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"Metalness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue(), true, false);"; tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Sets the strength of the Pixel Specular value."; + ToolTip = "Sets Metalness."; hovertime = "1000"; - range = "0 5"; + range = "0 1"; ticks = "0"; - value = "1"; + value = "0"; }; new GuiTextEditCtrl() { canSaveDynamicFields = "0"; - internalName = "specularStrengthTextEdit"; + internalName = "MetalnessTextEdit"; Enabled = "1"; isContainer = "0"; Profile = "ToolsGuiTextEditProfile"; @@ -2018,14 +2880,13 @@ MinExtent = "8 2"; canSave = "1"; Visible = "1"; - Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"specularStrength[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; + Command = "$ThisControl.getParent().updateFromChild($ThisControl); MaterialEditorGui.updateActiveMaterial(\"Metalness[\" @ MaterialEditorGui.currentLayer @ \"]\", $ThisControl.getValue());"; hovertime = "1000"; AnchorTop = "1"; AnchorBottom = "0"; AnchorLeft = "1"; AnchorRight = "0"; - text = "1"; - maxLength = "3"; + text = "0"; }; }; }; diff --git a/Templates/BaseGame/game/tools/materialEditor/main.cs b/Templates/BaseGame/game/tools/materialEditor/main.cs index 4751676fe..49ba068a6 100644 --- a/Templates/BaseGame/game/tools/materialEditor/main.cs +++ b/Templates/BaseGame/game/tools/materialEditor/main.cs @@ -121,6 +121,8 @@ function MaterialEditorPlugin::onActivated( %this ) $wasInWireFrameMode = false; } advancedTextureMapsRollout.Expanded = false; + accumulationPropertiesRollout.Expanded = false; + lightingPropertiesRollout.Expanded = false; materialAnimationPropertiesRollout.Expanded = false; materialAdvancedPropertiesRollout.Expanded = false; WorldEditorPlugin.onActivated(); diff --git a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs index 74869ebb4..191e77bf6 100644 --- a/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs +++ b/Templates/BaseGame/game/tools/materialEditor/scripts/materialEditor.ed.cs @@ -137,8 +137,6 @@ function MaterialEditorGui::open(%this) if( MaterialEditorGui.currentMode $= "Mesh" ) MaterialEditorGui.prepareActiveObject( true ); - else if( MaterialEditorGui.currentMode $= "asset" ) - MaterialEditorGui.prepareActiveMaterial( MaterialEditorGui.currentMaterial, true ); else MaterialEditorGui.prepareActiveMaterial( "", true ); @@ -290,9 +288,7 @@ function MaterialEditorGui::setMode( %this ) } else { - if(MaterialEditorGui.currentMode !$= "asset") - MaterialEditorGui.currentMode = "Material"; - + MaterialEditorGui.currentMode = "Material"; MatEdMaterialMode.setVisible(1); EWorldEditor.clearSelection(); } @@ -597,6 +593,27 @@ function MaterialEditorGui::convertTextureFields(%this) %specMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %specMap); MaterialEditorGui.currentMaterial.specularMap[%specI] = %specMap; } + + for(%roughI = 0; %roughI < 4; %roughI++) + { + %roughMap = MaterialEditorGui.currentMaterial.roughMap[%roughI]; + %roughMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %roughMap); + MaterialEditorGui.currentMaterial.roughMap[%specI] = %roughMap; + } + + for(%aoI = 0; %aoI < 4; %aoI++) + { + %aoMap = MaterialEditorGui.currentMaterial.aoMap[%aoI]; + %aoMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %aoMap); + MaterialEditorGui.currentMaterial.aoMap[%specI] = %aoMap; + } + + for(%metalI = 0; %metalI < 4; %metalI++) + { + %metalMap = MaterialEditorGui.currentMaterial.metalMap[%metalI]; + %metalMap = MaterialEditorGui.searchForTexture(MaterialEditorGui.currentMaterial, %metalMap); + MaterialEditorGui.currentMaterial.metalMap[%metalI] = %metalMap; + } } // still needs to be optimized further @@ -879,7 +896,9 @@ function MaterialEditorGui::guiSync( %this, %material ) MaterialEditorPropertiesWindow-->toneMapNameText.setText( (%material).toneMap[%layer] ); MaterialEditorPropertiesWindow-->toneMapDisplayBitmap.setBitmap( (%material).toneMap[%layer] ); } - + MaterialEditorPropertiesWindow-->isSRGBCheckbox.setValue((%material).isSRGB[%layer]); + MaterialEditorPropertiesWindow-->invertSmoothnessCheckbox.setValue((%material).invertSmoothness[%layer]); + if((%material).specularMap[%layer] $= "") { MaterialEditorPropertiesWindow-->specMapNameText.setText( "None" ); @@ -891,6 +910,39 @@ function MaterialEditorGui::guiSync( %this, %material ) MaterialEditorPropertiesWindow-->specMapDisplayBitmap.setBitmap( (%material).specularMap[%layer] ); } + if((%material).roughMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->roughMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->roughMapNameText.setText( (%material).roughMap[%layer] ); + MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.setBitmap( (%material).roughMap[%layer] ); + } + + if((%material).aoMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->aoMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->aoMapNameText.setText( (%material).aoMap[%layer] ); + MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.setBitmap( (%material).aoMap[%layer] ); + } + + if((%material).metalMap[%layer] $= "") + { + MaterialEditorPropertiesWindow-->metalMapNameText.setText( "None" ); + MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.setBitmap( "tools/materialeditor/gui/unknownImage" ); + } + else + { + MaterialEditorPropertiesWindow-->metalMapNameText.setText( (%material).metalMap[%layer] ); + MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.setBitmap( (%material).metalMap[%layer] ); + } + MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]); MaterialEditorPropertiesWindow-->accuScaleTextEdit.setText((%material).accuScale[%layer]); MaterialEditorPropertiesWindow-->accuDirectionTextEdit.setText((%material).accuDirection[%layer]); @@ -908,11 +960,10 @@ function MaterialEditorGui::guiSync( %this, %material ) MaterialEditorPropertiesWindow-->colorTintSwatch.color = (%material).diffuseColor[%layer]; MaterialEditorPropertiesWindow-->specularColorSwatch.color = (%material).specular[%layer]; - MaterialEditorPropertiesWindow-->specularPowerTextEdit.setText((%material).specularPower[%layer]); - MaterialEditorPropertiesWindow-->specularPowerSlider.setValue((%material).specularPower[%layer]); - MaterialEditorPropertiesWindow-->specularStrengthTextEdit.setText((%material).specularStrength[%layer]); - MaterialEditorPropertiesWindow-->specularStrengthSlider.setValue((%material).specularStrength[%layer]); - MaterialEditorPropertiesWindow-->pixelSpecularCheckbox.setValue((%material).pixelSpecular[%layer]); + MaterialEditorPropertiesWindow-->SmoothnessTextEdit.setText((%material).Smoothness[%layer]); + MaterialEditorPropertiesWindow-->SmoothnessSlider.setValue((%material).Smoothness[%layer]); + MaterialEditorPropertiesWindow-->MetalnessTextEdit.setText((%material).Metalness[%layer]); + MaterialEditorPropertiesWindow-->MetalnessSlider.setValue((%material).Metalness[%layer]); MaterialEditorPropertiesWindow-->glowCheckbox.setValue((%material).glow[%layer]); MaterialEditorPropertiesWindow-->emissiveCheckbox.setValue((%material).emissive[%layer]); MaterialEditorPropertiesWindow-->parallaxTextEdit.setText((%material).parallaxScale[%layer]); @@ -980,11 +1031,34 @@ function MaterialEditorGui::guiSync( %this, %material ) MaterialEditorPropertiesWindow-->SequenceSliderSSS.setValue( %numFrames ); // Accumulation - MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]); + MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]); + MaterialEditorPropertiesWindow-->accuCheckbox.setValue((%material).accuEnabled[%layer]); + + %this.getRoughChan((%material).SmoothnessChan[%layer]); + %this.getAOChan((%material).AOChan[%layer]); + %this.getMetalChan((%material).metalChan[%layer]); %this.preventUndo = false; } +//======================================= +function MaterialEditorGui::getRoughChan(%this, %channel) +{ + %guiElement = roughChanBtn @ %channel; + %guiElement.setStateOn(true); +} + +function MaterialEditorGui::getAOChan(%this, %channel) +{ + %guiElement = AOChanBtn @ %channel; + %guiElement.setStateOn(true); +} + +function MaterialEditorGui::getMetalChan(%this, %channel) +{ + %guiElement = metalChanBtn @ %channel; + %guiElement.setStateOn(true); +} //======================================= // Material Update Functionality @@ -1055,7 +1129,7 @@ function MaterialEditorGui::updateActiveMaterialName(%this, %name) // Some objects (ConvexShape, DecalRoad etc) reference Materials by name => need // to find and update all these references so they don't break when we rename the // Material. - MaterialEditorGui.updateMaterialReferences( getScene(0), %action.oldName, %action.newName ); + MaterialEditorGui.updateMaterialReferences( getRootScene(), %action.oldName, %action.newName ); } function MaterialEditorGui::updateMaterialReferences( %this, %obj, %oldName, %newName ) @@ -1196,6 +1270,90 @@ function MaterialEditorGui::updateSpecMap(%this,%action) MaterialEditorGui.guiSync( materialEd_previewMaterial ); } +function MaterialEditorGui::updateRoughMap(%this,%action) +{ + %layer = MaterialEditorGui.currentLayer; + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.setBitmap(%texture); + + %bitmap = MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.setBitmap(%bitmap); + MaterialEditorPropertiesWindow-->roughMapNameText.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial("roughMap[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + MaterialEditorPropertiesWindow-->roughMapNameText.setText("None"); + MaterialEditorPropertiesWindow-->roughMapDisplayBitmap.setBitmap("tools/materialeditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial("roughMap[" @ %layer @ "]",""); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updateaoMap(%this,%action) +{ + %layer = MaterialEditorGui.currentLayer; + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.setBitmap(%texture); + + %bitmap = MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.setBitmap(%bitmap); + MaterialEditorPropertiesWindow-->aoMapNameText.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial("aoMap[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + MaterialEditorPropertiesWindow-->aoMapNameText.setText("None"); + MaterialEditorPropertiesWindow-->aoMapDisplayBitmap.setBitmap("tools/materialeditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial("aoMap[" @ %layer @ "]",""); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::updatemetalMap(%this,%action) +{ + %layer = MaterialEditorGui.currentLayer; + + if( %action ) + { + %texture = MaterialEditorGui.openFile("texture"); + if( %texture !$= "" ) + { + MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.setBitmap(%texture); + + %bitmap = MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.bitmap; + %bitmap = strreplace(%bitmap,"tools/materialEditor/scripts/",""); + MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.setBitmap(%bitmap); + MaterialEditorPropertiesWindow-->metalMapNameText.setText(%bitmap); + MaterialEditorGui.updateActiveMaterial("metalMap[" @ %layer @ "]","\"" @ %bitmap @ "\""); + } + } + else + { + MaterialEditorPropertiesWindow-->metalMapNameText.setText("None"); + MaterialEditorPropertiesWindow-->metalMapDisplayBitmap.setBitmap("tools/materialeditor/gui/unknownImage"); + MaterialEditorGui.updateActiveMaterial("metalMap[" @ %layer @ "]",""); + } + + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + function MaterialEditorGui::updateRotationOffset(%this, %isSlider, %onMouseUp) { %layer = MaterialEditorGui.currentLayer; @@ -1948,7 +2106,7 @@ function MaterialEditorGui::createNewMaterial( %this ) %material = getUniqueName( "newMaterial" ); new Material(%material) { - diffuseMap[0] = "core/images/warnmat"; + diffuseMap[0] = "core/art/warnmat"; mapTo = "unmapped_mat"; parentGroup = RootGroup; }; @@ -1979,7 +2137,7 @@ function MaterialEditorGui::deleteMaterial( %this ) %toMaterial = getUniqueName( "newMaterial" ); new Material(%toMaterial) { - diffuseMap[0] = "core/images/warnmat"; + diffuseMap[0] = "core/art/warnmat"; mapTo = "unmapped_mat"; parentGroup = RootGroup; }; @@ -1997,7 +2155,7 @@ function MaterialEditorGui::deleteMaterial( %this ) %toMaterial = getUniqueName( "newMaterial" ); new Material(%toMaterial) { - diffuseMap[0] = "core/images/warnmat"; + diffuseMap[0] = "core/art/warnmat"; mapTo = "unmapped_mat"; parentGroup = RootGroup; }; @@ -2012,7 +2170,7 @@ function MaterialEditorGui::deleteMaterial( %this ) %newMaterial = getUniqueName( "newMaterial" ); new Material(%newMaterial) { - diffuseMap[0] = "core/images/warnmat"; + diffuseMap[0] = "core/art/warnmat"; mapTo = "unmapped_mat"; parentGroup = RootGroup; }; @@ -2272,3 +2430,58 @@ function MaterialEditorGui::updateAccuCheckbox(%this, %value) MaterialEditorGui.updateActiveMaterial("accuEnabled[" @ MaterialEditorGui.currentLayer @ "]", %value); MaterialEditorGui.guiSync( materialEd_previewMaterial ); } + +// channel in selectors +function MaterialEditorGui::setRoughChan(%this, %value) +{ + MaterialEditorGui.updateActiveMaterial("SmoothnessChan[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::setAOChan(%this, %value) +{ + MaterialEditorGui.updateActiveMaterial("aoChan[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::setMetalChan(%this, %value) +{ + MaterialEditorGui.updateActiveMaterial("metalChan[" @ MaterialEditorGui.currentLayer @ "]", %value); + MaterialEditorGui.guiSync( materialEd_previewMaterial ); +} + +function MaterialEditorGui::saveCompositeMap(%this) +{ + %saveAs = ""; + %dlg = new SaveFileDialog() + { + Filters = "png"; + DefaultPath = EditorSettings.value("art/shapes/textures"); + ChangePath = false; + OverwritePrompt = true; + }; + + %ret = %dlg.Execute(); + if(%ret) + { + // Immediately override/set the levelsDirectory + EditorSettings.setValue( "art/shapes/textures", collapseFilename(filePath( %dlg.FileName )) ); + %saveAs = %dlg.FileName; + } + + %material = %this.currentMaterial; + %layer = %this.currentLayer; + + %roughMap = %material.roughMap[%layer]; + %aoMap = %material.aoMap[%layer]; + %metalMap = %material.metalMap[%layer]; + + %smooth = %material.SmoothnessChan[%layer]; + %ao = %material.AOChan[%layer]; + %metal = %material.metalChan[%layer]; + + %channelKey = %smooth SPC %ao SPC %metal SPC 3; + error("Storing: \"" @ %roughMap @"\" \""@ %aoMap @"\" \""@ %metalMap @"\" \""@ %channelKey @"\" \""@ %saveAs @"\""); + saveCompositeTexture(%roughMap,%aoMap,%metalMap,"",%channelKey, %saveAs); + %dlg.delete(); +} diff --git a/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae b/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae new file mode 100644 index 000000000..b488de77a --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/ReflectProbeSphere.dae @@ -0,0 +1,115 @@ + + + + + Anonymous + Collada Exporter for Blender 2.6+, by Juan Linietsky (juan@codenix.com) + + 2016-09-06T21:59:07Z + 2016-09-06T21:59:07Z + + Z_UP + + + + + + + + + + 0.0 0.0 0.0 1.0 + + + 0.0 0.0 0.0 1.0 + + + 0.3737608488464481 0.3737608488464481 0.3737608488464481 1.0 + + + 0.0 0.0 0.0 1.0 + + + 50 + + + 1.0 1.0 1.0 1.0 + + + 4.0 + + + + + + + 0 + + + + + + + + + + + + + + + + -0.49039262533187866 0.0 0.09754517674446106 -0.49039262533187866 0.09754519164562225 3.774895063202166e-08 -0.5 0.0 3.774895063202166e-08 -0.09754516184329987 0.0 0.49039262533187866 1.2401747184753731e-08 -6.234699867491145e-08 0.5 -0.09567085653543472 0.019030148163437843 0.49039262533187866 1.6292068494294654e-07 0.0 -0.5 -0.09754504263401031 0.0 -0.49039265513420105 -0.09567073732614517 0.019030125811696053 -0.49039265513420105 -0.4809698760509491 0.09567089378833771 -0.09754510223865509 -0.49039265513420105 0.0 -0.09754510223865509 -0.1876651495695114 0.03732895478606224 0.4619397521018982 -0.19134172797203064 0.0 0.4619397521018982 -0.4619397819042206 0.0 -0.19134163856506348 -0.4530637264251709 0.09012001007795334 -0.19134163856506348 -0.27778512239456177 0.0 0.41573479771614075 -0.2724475562572479 0.054193224757909775 0.41573479771614075 -0.4077465832233429 0.08110587298870087 -0.2777850925922394 -0.41573482751846313 0.0 -0.2777850925922394 -0.34675994515419006 0.06897487491369247 0.3535533845424652 -0.3535533845424652 0.0 0.3535533845424652 -0.3535533845424652 0.0 -0.3535533845424652 -0.34675994515419006 0.06897487491369247 -0.3535533845424652 -0.4077465832233429 0.08110587298870087 0.2777850925922394 -0.41573482751846313 0.0 0.2777850925922394 -0.27244752645492554 0.05419321730732918 -0.41573482751846313 -0.2777850925922394 0.0 -0.41573482751846313 -0.4530636966228485 0.09012000262737274 0.19134171307086945 -0.4619397521018982 0.0 0.19134171307086945 -0.18766506016254425 0.03732893615961075 -0.46193981170654297 -0.19134163856506348 0.0 -0.46193981170654297 -0.4809698462486267 0.09567088633775711 0.09754517674446106 -0.17677661776542664 0.07322333753108978 -0.46193981170654297 -0.4530636668205261 0.187665194272995 0.09754517674446106 -0.0901198536157608 0.03732893243432045 -0.49039265513420105 -0.4619397222995758 0.19134177267551422 3.774895063202166e-08 -0.09011997282505035 0.03732898086309433 0.49039262533187866 -0.4530636668205261 0.187665194272995 -0.09754510223865509 -0.1767767071723938 0.07322336733341217 0.4619397521018982 -0.4267766773700714 0.17677675187587738 -0.19134163856506348 -0.2566399574279785 0.10630382597446442 0.41573479771614075 -0.3840888440608978 0.1590948849916458 -0.2777850925922394 -0.32664069533348083 0.13529908657073975 0.3535533845424652 -0.32664069533348083 0.13529908657073975 -0.3535533845424652 -0.3840888440608978 0.1590948849916458 0.2777850925922394 -0.25663992762565613 0.10630381107330322 -0.41573482751846313 -0.426776647567749 0.1767767369747162 0.19134171307086945 -0.3840888440608978 0.2566400468349457 -0.19134163856506348 -0.34567081928253174 0.23096996545791626 -0.2777850925922394 -0.2939688563346863 0.19642382860183716 0.3535533845424652 -0.2939688563346863 0.19642382860183716 -0.3535533845424652 -0.34567081928253174 0.23096996545791626 0.2777850925922394 -0.23096981644630432 0.15432921051979065 -0.41573482751846313 -0.38408881425857544 0.2566400468349457 0.19134171307086945 -0.15909473598003387 0.10630381107330322 -0.46193981170654297 -0.40774649381637573 0.2724476158618927 0.09754517674446106 -0.08110571652650833 0.05419320985674858 -0.49039265513420105 -0.41573473811149597 0.27778521180152893 3.774895063202166e-08 -0.08110581338405609 0.05419328436255455 0.49039262533187866 -0.40774649381637573 0.2724476158618927 -0.09754510223865509 -0.15909481048583984 0.1063038557767868 0.4619397521018982 -0.2309698462486267 0.15432922542095184 0.41573479771614075 -0.06897471845149994 0.06897486746311188 -0.49039265513420105 -0.3467598557472229 0.3467600345611572 0.09754517674446106 -0.35355329513549805 0.35355350375175476 3.774895063202166e-08 -0.0689748004078865 0.06897496432065964 0.49039262533187866 -0.3467598557472229 0.3467600345611572 -0.09754510223865509 -0.1352989822626114 0.13529914617538452 0.4619397521018982 -0.32664069533348083 0.3266408145427704 -0.19134163856506348 -0.19642367959022522 0.19642384350299835 0.41573479771614075 -0.2939688265323639 0.2939690053462982 -0.2777850925922394 -0.24999994039535522 0.25000008940696716 0.3535533845424652 -0.24999994039535522 0.25000008940696716 -0.3535533845424652 -0.2939688265323639 0.2939690053462982 0.2777850925922394 -0.19642364978790283 0.19642382860183716 -0.41573482751846313 -0.32664066553115845 0.3266408145427704 0.19134171307086945 -0.1352989375591278 0.13529908657073975 -0.46193981170654297 -0.19642364978790283 0.2939690053462982 0.3535533845424652 -0.19642364978790283 0.2939690053462982 -0.3535533845424652 -0.23096978664398193 0.3456709682941437 0.2777850925922394 -0.15432903170585632 0.23096996545791626 -0.41573482751846313 -0.25663989782333374 0.3840889632701874 0.19134171307086945 -0.10630366206169128 0.159094899892807 -0.46193981170654297 -0.272447407245636 0.40774664282798767 0.09754517674446106 -0.054193053394556046 0.08110586553812027 -0.49039265513420105 -0.2777850031852722 0.4157349169254303 3.774895063202166e-08 -0.05419311672449112 0.08110596984624863 0.49039262533187866 -0.272447407245636 0.40774664282798767 -0.09754510223865509 -0.10630369931459427 0.15909495949745178 0.4619397521018982 -0.25663992762565613 0.3840889632701874 -0.19134163856506348 -0.1543290615081787 0.23096999526023865 0.41573479771614075 -0.23096978664398193 0.3456709682941437 -0.2777850925922394 -0.1913415789604187 0.46193987131118774 3.774895063202166e-08 -0.0373288132250309 0.09012012183666229 0.49039262533187866 -0.037328775972127914 0.09012000262737274 -0.49039265513420105 -0.1876649558544159 0.4530637562274933 -0.09754510223865509 -0.07322321087121964 0.17677684128284454 0.4619397521018982 -0.17677661776542664 0.4267767667770386 -0.19134163856506348 -0.10630366206169128 0.25664010643959045 0.41573479771614075 -0.1590946912765503 0.38408899307250977 -0.2777850925922394 -0.13529890775680542 0.3266408443450928 0.3535533845424652 -0.13529890775680542 0.3266408443450928 -0.3535533845424652 -0.1590946912765503 0.38408899307250977 0.2777850925922394 -0.1063036322593689 0.25664007663726807 -0.41573482751846313 -0.17677658796310425 0.4267767667770386 0.19134171307086945 -0.07322318851947784 0.17677676677703857 -0.46193981170654297 -0.1876649558544159 0.4530637562274933 0.09754517674446106 -0.08110568672418594 0.40774667263031006 -0.2777850925922394 -0.06897471100091934 0.3467600643634796 -0.3535533845424652 -0.08110568672418594 0.40774667263031006 0.2777850925922394 -0.05419303476810455 0.2724476456642151 -0.41573482751846313 -0.0901198536157608 0.4530637860298157 0.19134171307086945 -0.03732877969741821 0.1876652091741562 -0.46193981170654297 -0.0956706702709198 0.4809699058532715 0.09754517674446106 -0.019029967486858368 0.09567087888717651 -0.49039265513420105 -0.09754499793052673 0.4903927445411682 3.774895063202166e-08 -0.019029982388019562 0.09567100554704666 0.49039262533187866 -0.0956706702709198 0.4809699058532715 -0.09754510223865509 -0.03732878714799881 0.18766528367996216 0.4619397521018982 -0.09011988341808319 0.4530637860298157 -0.19134163856506348 -0.054193057119846344 0.2724476754665375 0.41573479771614075 -0.06897471100091934 0.3467600643634796 0.3535533845424652 1.6331796359736472e-07 0.09754530340433121 0.49039262533187866 1.5400473785120994e-07 0.09754518419504166 -0.49039265513420105 1.8939499568659812e-07 0.5000001192092896 3.774895063202166e-08 1.9684557628352195e-07 0.49039262533187866 -0.09754510223865509 1.595926732989028e-07 0.1913418471813202 0.4619397521018982 1.1488918971735984e-07 0.46193984150886536 -0.19134163856506348 1.558673830004409e-07 0.2777852416038513 0.41573479771614075 1.6704325389582664e-07 0.4157348871231079 -0.2777850925922394 1.595926732989028e-07 0.3535534739494324 0.3535533845424652 1.595926732989028e-07 0.3535534739494324 -0.3535533845424652 1.6704325389582664e-07 0.4157348871231079 0.2777850925922394 1.7076854419428855e-07 0.27778518199920654 -0.41573482751846313 1.3724093150813133e-07 0.46193984150886536 0.19134171307086945 1.5214209270197898e-07 0.19134177267551422 -0.46193981170654297 1.9684557628352195e-07 0.49039262533187866 0.09754517674446106 0.06897501647472382 0.3467600345611572 0.3535533845424652 0.08110601454973221 0.40774664282798767 0.2777850925922394 0.06897501647472382 0.3467600345611572 -0.3535533845424652 0.05419337376952171 0.2724476158618927 -0.41573482751846313 0.09012012928724289 0.4530637860298157 0.19134171307086945 0.03732908144593239 0.187665194272995 -0.46193981170654297 0.09567105025053024 0.4809698462486267 0.09754517674446106 0.01903027668595314 0.09567087888717651 -0.49039265513420105 0.09754537045955658 0.4903927445411682 3.774895063202166e-08 0.019030308350920677 0.09567099809646606 0.49039262533187866 0.09567105025053024 0.4809698462486267 -0.09754510223865509 0.03732910379767418 0.18766526877880096 0.4619397521018982 0.0901201069355011 0.4530637860298157 -0.19134163856506348 0.054193370044231415 0.2724476754665375 0.41573479771614075 0.08110601454973221 0.40774664282798767 -0.2777850925922394 0.18766531348228455 0.4530636668205261 -0.09754510223865509 0.07322350889444351 0.17677681148052216 0.4619397521018982 0.17677682638168335 0.4267767667770386 -0.19134163856506348 0.10630396008491516 0.25664007663726807 0.41573479771614075 0.15909501910209656 0.3840889036655426 -0.2777850925922394 0.1352992057800293 0.3266408145427704 0.3535533845424652 0.1352992057800293 0.3266408145427704 -0.3535533845424652 0.15909501910209656 0.3840889036655426 0.2777850925922394 0.10630396008491516 0.2566400170326233 -0.41573482751846313 0.17677685618400574 0.4267767667770386 0.19134171307086945 0.07322347909212112 0.1767767369747162 -0.46193981170654297 0.18766531348228455 0.4530636668205261 0.09754517674446106 0.03732908144593239 0.09011999517679214 -0.49039265513420105 0.19134193658828735 0.46193984150886536 3.774895063202166e-08 0.03732913359999657 0.0901200994849205 0.49039262533187866 0.19642391800880432 0.29396897554397583 -0.3535533845424652 0.1543293297290802 0.23096990585327148 -0.41573482751846313 0.25664013624191284 0.384088933467865 0.19134171307086945 0.10630394518375397 0.15909485518932343 -0.46193981170654297 0.27244770526885986 0.4077465236186981 0.09754517674446106 0.05419335886836052 0.08110585063695908 -0.49039265513420105 0.2777853310108185 0.4157348573207855 3.774895063202166e-08 0.05419342592358589 0.08110594004392624 0.49039262533187866 0.27244770526885986 0.4077465236186981 -0.09754510223865509 0.10630397498607635 0.1590949296951294 0.4619397521018982 0.25664013624191284 0.384088933467865 -0.19134163856506348 0.1543293446302414 0.23096996545791626 0.41573479771614075 0.2309700846672058 0.3456708788871765 -0.2777850925922394 0.19642391800880432 0.29396897554397583 0.3535533845424652 0.2309700846672058 0.3456708788871765 0.2777850925922394 0.32664090394973755 0.3266408145427704 -0.19134163856506348 0.1964239478111267 0.19642379879951477 0.41573479771614075 0.2939690947532654 0.29396888613700867 -0.2777850925922394 0.2500001788139343 0.2500000298023224 0.3535533845424652 0.2500001788139343 0.2500000298023224 -0.3535533845424652 0.2939690947532654 0.29396888613700867 0.2777850925922394 0.19642391800880432 0.1964237540960312 -0.41573482751846313 0.32664090394973755 0.3266408145427704 0.19134171307086945 0.1352992057800293 0.13529904186725616 -0.46193981170654297 0.346760094165802 0.3467599153518677 0.09754517674446106 0.06897501647472382 0.06897485256195068 -0.49039265513420105 0.3535536229610443 0.3535534143447876 3.774895063202166e-08 0.06897509843111038 0.06897492706775665 0.49039262533187866 0.346760094165802 0.3467599153518677 -0.09754510223865509 0.13529925048351288 0.13529911637306213 0.4619397521018982 0.15909498929977417 0.10630377382040024 -0.46193981170654297 0.38408905267715454 0.2566400468349457 0.19134171307086945 0.40774670243263245 0.27244749665260315 0.09754517674446106 0.08110600709915161 0.05419319495558739 -0.49039265513420105 0.41573503613471985 0.27778512239456177 3.774895063202166e-08 0.08110609650611877 0.054193247109651566 0.49039262533187866 0.40774670243263245 0.27244749665260315 -0.09754510223865509 0.15909504890441895 0.10630382597446442 0.4619397521018982 0.38408905267715454 0.2566400468349457 -0.19134163856506348 0.2309700846672058 0.15432918071746826 0.41573479771614075 0.34567102789878845 0.2309698611497879 -0.2777850925922394 0.2939690947532654 0.1964237540960312 0.3535533845424652 0.2939690947532654 0.1964237540960312 -0.3535533845424652 0.34567102789878845 0.2309698611497879 0.2777850925922394 0.23097005486488342 0.15432913601398468 -0.41573482751846313 0.1767769157886505 0.07322335243225098 0.4619397521018982 0.2566401958465576 0.10630379617214203 0.41573479771614075 0.42677685618400574 0.1767767369747162 -0.19134163856506348 0.38408902287483215 0.15909478068351746 -0.2777850925922394 0.32664090394973755 0.13529901206493378 0.3535533845424652 0.32664090394973755 0.13529901206493378 -0.3535533845424652 0.38408902287483215 0.15909478068351746 0.2777850925922394 0.25664013624191284 0.10630375146865845 -0.41573482751846313 0.42677685618400574 0.1767767369747162 0.19134171307086945 0.17677685618400574 0.0732233077287674 -0.46193981170654297 0.45306381583213806 0.18766507506370544 0.09754517674446106 0.09012014418840408 0.03732892498373985 -0.49039265513420105 0.4619399905204773 0.19134169816970825 3.774895063202166e-08 0.09012024104595184 0.03732895851135254 0.49039262533187866 0.45306381583213806 0.18766507506370544 -0.09754510223865509 0.45306387543678284 0.09012001007795334 0.19134171307086945 0.48096996545791626 0.09567080438137054 0.09754517674446106 0.18766529858112335 0.037328921258449554 -0.46193981170654297 0.09567102044820786 0.019030120223760605 -0.49039265513420105 0.49039286375045776 0.09754512459039688 3.774895063202166e-08 0.09567112475633621 0.0190301351249218 0.49039262533187866 0.48096996545791626 0.09567080438137054 -0.09754510223865509 0.18766535818576813 0.03732895106077194 0.4619397521018982 0.45306387543678284 0.09012001007795334 -0.19134163856506348 0.27244776487350464 0.05419321358203888 0.41573479771614075 0.40774667263031006 0.0811057835817337 -0.2777850925922394 0.3467601239681244 0.06897483021020889 0.3535533845424652 0.3467601239681244 0.06897483021020889 -0.3535533845424652 0.40774667263031006 0.0811057835817337 0.2777850925922394 0.27244770526885986 0.05419318005442619 -0.41573482751846313 0.4619399309158325 3.1784249898691996e-08 -0.19134163856506348 0.4157348573207855 -4.2721556070546285e-08 -0.2777850925922394 0.2777853310108185 1.3157798406382426e-08 0.41573479771614075 0.35355353355407715 -1.2919233682850972e-08 0.3535533845424652 0.35355353355407715 -1.2919233682850972e-08 -0.3535533845424652 0.4157348573207855 -4.2721556070546285e-08 0.2777850925922394 0.2777852416038513 -5.468653085927144e-09 -0.41573482751846313 0.4619399309158325 3.1784249898691996e-08 0.19134171307086945 0.19134186208248138 1.981927510996684e-09 -0.46193981170654297 0.49039268493652344 -4.2721556070546285e-08 0.09754517674446106 0.0975453183054924 1.981927510996684e-09 -0.49039265513420105 0.5000001788139343 -5.017213666747011e-08 3.774895063202166e-08 0.09754542261362076 -3.6060079366961872e-09 0.49039262533187866 0.49039268493652344 -4.2721556070546285e-08 -0.09754510223865509 0.19134192168712616 2.0608379003306254e-08 0.4619397521018982 0.09567101299762726 -0.019030114635825157 -0.49039265513420105 0.490392804145813 -0.09754522144794464 3.774895063202166e-08 0.09567110985517502 -0.019030140712857246 0.49039262533187866 0.4809699058532715 -0.09567087888717651 -0.09754510223865509 0.18766532838344574 -0.03732890635728836 0.4619397521018982 0.45306387543678284 -0.09011995047330856 -0.19134163856506348 0.27244776487350464 -0.05419318377971649 0.41573479771614075 0.4077466130256653 -0.08110586553812027 -0.2777850925922394 0.346760094165802 -0.06897486001253128 0.3535533845424652 0.346760094165802 -0.06897486001253128 -0.3535533845424652 0.4077466130256653 -0.08110586553812027 0.2777850925922394 0.2724476754665375 -0.05419318377971649 -0.41573482751846313 0.45306387543678284 -0.09011995047330856 0.19134171307086945 0.18766526877880096 -0.03732891008257866 -0.46193981170654297 0.4809699058532715 -0.09567087888717651 0.09754517674446106 0.2566401958465576 -0.10630376636981964 0.41573479771614075 0.32664087414741516 -0.13529902696609497 0.3535533845424652 0.32664087414741516 -0.13529902696609497 -0.3535533845424652 0.3840888738632202 -0.15909482538700104 0.2777850925922394 0.25664010643959045 -0.10630375146865845 -0.41573482751846313 0.42677685618400574 -0.17677666246891022 0.19134171307086945 0.17677681148052216 -0.0732232928276062 -0.46193981170654297 0.4530637264251709 -0.18766513466835022 0.09754517674446106 0.09012012183666229 -0.03732891008257866 -0.49039265513420105 0.46193990111351013 -0.19134178757667542 3.774895063202166e-08 0.09012021869421005 -0.03732895478606224 0.49039262533187866 0.4530637264251709 -0.18766513466835022 -0.09754510223865509 0.17677687108516693 -0.0732233002781868 0.4619397521018982 0.42677685618400574 -0.17677666246891022 -0.19134163856506348 0.3840888738632202 -0.15909482538700104 -0.2777850925922394 0.4157349169254303 -0.27778518199920654 3.774895063202166e-08 0.08110606670379639 -0.05419323593378067 0.49039262533187866 0.08110597729682922 -0.054193172603845596 -0.49039265513420105 0.4077465832233429 -0.27244752645492554 -0.09754510223865509 0.15909498929977417 -0.10630375891923904 0.4619397521018982 0.38408902287483215 -0.2566399574279785 -0.19134163856506348 0.2309700846672058 -0.15432915091514587 0.41573479771614075 0.3456708490848541 -0.2309698462486267 -0.2777850925922394 0.2939690351486206 -0.19642373919487 0.3535533845424652 0.2939690351486206 -0.19642373919487 -0.3535533845424652 0.3456708490848541 -0.2309698462486267 0.2777850925922394 0.23096999526023865 -0.1543291211128235 -0.41573482751846313 0.38408902287483215 -0.2566399574279785 0.19134171307086945 0.1590949296951294 -0.10630373656749725 -0.46193981170654297 0.4077465832233429 -0.27244752645492554 0.09754517674446106 0.25000011920928955 -0.25 -0.3535533845424652 0.25000011920928955 -0.25 0.3535533845424652 0.29396888613700867 -0.2939688265323639 0.2777850925922394 0.19642384350299835 -0.1964237093925476 -0.41573482751846313 0.32664087414741516 -0.32664069533348083 0.19134171307086945 0.13529913127422333 -0.13529899716377258 -0.46193981170654297 0.34675994515419006 -0.3467598855495453 0.09754517674446106 0.06897498667240143 -0.0689748227596283 -0.49039265513420105 0.3535534739494324 -0.35355344414711 3.774895063202166e-08 0.0689750611782074 -0.06897490471601486 0.49039262533187866 0.34675994515419006 -0.3467598855495453 -0.09754510223865509 0.1352991759777069 -0.13529902696609497 0.4619397521018982 0.32664087414741516 -0.32664069533348083 -0.19134163856506348 0.19642393290996552 -0.1964237540960312 0.41573479771614075 0.29396888613700867 -0.2939688265323639 -0.2777850925922394 0.05419332906603813 -0.08110581338405609 -0.49039265513420105 0.27244752645492554 -0.40774646401405334 -0.09754510223865509 0.10630390048027039 -0.15909482538700104 0.4619397521018982 0.25664013624191284 -0.3840888440608978 -0.19134163856506348 0.154329314827919 -0.2309698909521103 0.41573479771614075 0.2309698909521103 -0.34567075967788696 -0.2777850925922394 0.19642385840415955 -0.29396888613700867 0.3535533845424652 0.19642385840415955 -0.29396888613700867 -0.3535533845424652 0.2309698909521103 -0.34567075967788696 0.2777850925922394 0.15432924032211304 -0.2309698462486267 -0.41573482751846313 0.25664013624191284 -0.3840888440608978 0.19134171307086945 0.1063038557767868 -0.15909478068351746 -0.46193981170654297 0.27244752645492554 -0.40774646401405334 0.09754517674446106 0.27778518199920654 -0.41573482751846313 3.774895063202166e-08 0.05419338867068291 -0.08110590279102325 0.49039262533187866 0.106303870677948 -0.25663992762565613 -0.41573482751846313 0.17677685618400574 -0.4267766773700714 0.19134171307086945 0.07322340458631516 -0.17677663266658783 -0.46193981170654297 0.18766511976718903 -0.45306357741355896 0.09754517674446106 0.0373290590941906 -0.09011994302272797 -0.49039265513420105 0.19134177267551422 -0.4619397521018982 3.774895063202166e-08 0.03732910379767418 -0.09012004733085632 0.49039262533187866 0.18766511976718903 -0.45306357741355896 -0.09754510223865509 0.07322343438863754 -0.1767766773700714 0.4619397521018982 0.17677685618400574 -0.4267766773700714 -0.19134163856506348 0.10630391538143158 -0.2566399872303009 0.41573479771614075 0.15909484028816223 -0.3840887248516083 -0.2777850925922394 0.13529913127422333 -0.3266407251358032 0.3535533845424652 0.13529913127422333 -0.3266407251358032 -0.3535533845424652 0.15909484028816223 -0.3840887248516083 0.2777850925922394 0.019030287861824036 -0.09567093104124069 0.49039262533187866 0.03732905164361 -0.18766510486602783 0.4619397521018982 0.09012013673782349 -0.4530636966228485 -0.19134163856506348 0.05419333279132843 -0.2724475562572479 0.41573479771614075 0.08110587298870087 -0.40774640440940857 -0.2777850925922394 0.06897494196891785 -0.34675994515419006 0.3535533845424652 0.06897494196891785 -0.34675994515419006 -0.3535533845424652 0.08110587298870087 -0.40774640440940857 0.2777850925922394 0.05419331043958664 -0.27244749665260315 -0.41573482751846313 0.09012013673782349 -0.4530636966228485 0.19134171307086945 0.03732902929186821 -0.18766506016254425 -0.46193981170654297 0.09567087143659592 -0.48096969723701477 0.09754517674446106 0.019030267372727394 -0.09567081928253174 -0.49039265513420105 0.09754522144794464 -0.4903925955295563 3.774895063202166e-08 0.09567087143659592 -0.48096969723701477 -0.09754510223865509 1.595926732989028e-07 -0.4619397222995758 0.19134171307086945 1.297903509112075e-07 -0.2777850329875946 -0.41573482751846313 1.2606506061274558e-07 -0.19134162366390228 -0.46193981170654297 4.783396434504539e-08 -0.49039241671562195 0.09754517674446106 1.5773002814967185e-07 -0.09754512459039688 -0.49039265513420105 7.018570613581687e-08 -0.49999991059303284 3.774895063202166e-08 1.558673830004409e-07 -0.09754522889852524 0.49039262533187866 4.783396434504539e-08 -0.49039241671562195 -0.09754510223865509 1.4096622180659324e-07 -0.19134168326854706 0.4619397521018982 1.595926732989028e-07 -0.4619397222995758 -0.19134163856506348 1.4096622180659324e-07 -0.2777850925922394 0.41573479771614075 7.018570613581687e-08 -0.4157346189022064 -0.2777850925922394 9.253744792658836e-08 -0.3535533547401428 0.3535533845424652 9.253744792658836e-08 -0.3535533547401428 -0.3535533845424652 7.018570613581687e-08 -0.4157346189022064 0.2777850925922394 -0.09011981636285782 -0.4530636668205261 -0.19134163856506348 -0.05419304221868515 -0.27244752645492554 0.41573479771614075 -0.08110573142766953 -0.4077463448047638 -0.2777850925922394 -0.06897474825382233 -0.3467599153518677 0.3535533845424652 -0.06897474825382233 -0.3467599153518677 -0.3535533845424652 -0.08110573142766953 -0.4077463448047638 0.2777850925922394 -0.05419304221868515 -0.27244746685028076 -0.41573482751846313 -0.09011981636285782 -0.4530636668205261 0.19134171307086945 -0.037328772246837616 -0.18766504526138306 -0.46193981170654297 -0.09567076712846756 -0.4809696078300476 0.09754517674446106 -0.019029950723052025 -0.09567081928253174 -0.49039265513420105 -0.0975450798869133 -0.4903925061225891 3.774895063202166e-08 -0.019029973074793816 -0.0956709235906601 0.49039262533187866 -0.09567076712846756 -0.4809696078300476 -0.09754510223865509 -0.03732876852154732 -0.18766510486602783 0.4619397521018982 -0.10630360245704651 -0.25663986802101135 -0.41573482751846313 -0.07322314381599426 -0.17677660286426544 -0.46193981170654297 -0.17677652835845947 -0.426776647567749 0.19134171307086945 -0.18766498565673828 -0.453063428401947 0.09754517674446106 -0.03732874244451523 -0.09011994302272797 -0.49039265513420105 -0.1913416087627411 -0.46193960309028625 3.774895063202166e-08 -0.03732878342270851 -0.09012003988027573 0.49039262533187866 -0.18766498565673828 -0.453063428401947 -0.09754510223865509 -0.07322315126657486 -0.17677666246891022 0.4619397521018982 -0.17677652835845947 -0.426776647567749 -0.19134163856506348 -0.1063036173582077 -0.25663992762565613 0.41573479771614075 -0.1590946763753891 -0.3840886354446411 -0.2777850925922394 -0.1352989226579666 -0.32664066553115845 0.3535533845424652 -0.1352989226579666 -0.32664066553115845 -0.3535533845424652 -0.1590946763753891 -0.3840886354446411 0.2777850925922394 -0.10630360245704651 -0.15909478068351746 0.4619397521018982 -0.15432898700237274 -0.23096981644630432 0.41573479771614075 -0.2566398084163666 -0.38408881425857544 -0.19134163856506348 -0.23096969723701477 -0.345670610666275 -0.2777850925922394 -0.19642361998558044 -0.2939688265323639 0.3535533845424652 -0.19642361998558044 -0.2939688265323639 -0.3535533845424652 -0.23096969723701477 -0.345670610666275 0.2777850925922394 -0.15432895720005035 -0.23096975684165955 -0.41573482751846313 -0.2566398084163666 -0.38408881425857544 0.19134171307086945 -0.10630358010530472 -0.15909472107887268 -0.46193981170654297 -0.2724473476409912 -0.407746285200119 0.09754517674446106 -0.05419300124049187 -0.0811058059334755 -0.49039265513420105 -0.27778497338294983 -0.4157346189022064 3.774895063202166e-08 -0.05419306457042694 -0.08110588788986206 0.49039262533187866 -0.2724473476409912 -0.407746285200119 -0.09754510223865509 -0.3266405463218689 -0.32664069533348083 0.19134171307086945 -0.3467596769332886 -0.3467596769332886 0.09754517674446106 -0.06897465884685516 -0.0689748153090477 -0.49039265513420105 -0.3535532057285309 -0.3535531759262085 3.774895063202166e-08 -0.06897473335266113 -0.06897488236427307 0.49039262533187866 -0.3467596769332886 -0.3467596769332886 -0.09754510223865509 -0.13529884815216064 -0.1352989673614502 0.4619397521018982 -0.3266405463218689 -0.32664069533348083 -0.19134163856506348 -0.19642357528209686 -0.19642366468906403 0.41573479771614075 -0.29396867752075195 -0.29396864771842957 -0.2777850925922394 -0.24999986588954926 -0.24999992549419403 0.3535533845424652 -0.24999986588954926 -0.24999992549419403 -0.3535533845424652 -0.29396867752075195 -0.29396864771842957 0.2777850925922394 -0.19642353057861328 -0.19642361998558044 -0.41573482751846313 -0.13529881834983826 -0.1352989375591278 -0.46193981170654297 -0.3840886652469635 -0.25663992762565613 -0.19134163856506348 -0.34567058086395264 -0.2309696525335312 -0.2777850925922394 -0.29396873712539673 -0.19642364978790283 0.3535533845424652 -0.29396873712539673 -0.19642364978790283 -0.3535533845424652 -0.34567058086395264 -0.2309696525335312 0.2777850925922394 -0.2309696525335312 -0.15432903170585632 -0.41573482751846313 -0.3840886652469635 -0.25663992762565613 0.19134171307086945 -0.15909460186958313 -0.10630368441343307 -0.46193981170654297 -0.40774622559547424 -0.27244728803634644 0.09754517674446106 -0.08110564947128296 -0.0541931614279747 -0.49039265513420105 -0.41573455929756165 -0.27778491377830505 3.774895063202166e-08 -0.08110573142766953 -0.05419321358203888 0.49039262533187866 -0.40774622559547424 -0.27244728803634644 -0.09754510223865509 -0.15909463167190552 -0.10630370676517487 0.4619397521018982 -0.23096969723701477 -0.1543290615081787 0.41573479771614075 -0.09011978656053543 -0.037328895181417465 -0.49039265513420105 -0.4619394540786743 -0.19134151935577393 3.774895063202166e-08 -0.09011988341808319 -0.03732892870903015 0.49039262533187866 -0.45306330919265747 -0.18766489624977112 -0.09754510223865509 -0.17677649855613708 -0.07322325557470322 0.4619397521018982 -0.4267764687538147 -0.17677664756774902 -0.19134163856506348 -0.2566397786140442 -0.10630369186401367 0.41573479771614075 -0.38408854603767395 -0.15909460186958313 -0.2777850925922394 -0.3266405761241913 -0.1352989375591278 0.3535533845424652 -0.3266405761241913 -0.1352989375591278 -0.3535533845424652 -0.38408854603767395 -0.15909460186958313 0.2777850925922394 -0.2566397190093994 -0.10630366206169128 -0.41573482751846313 -0.4267764687538147 -0.17677664756774902 0.19134171307086945 -0.1767764687538147 -0.07322324067354202 -0.46193981170654297 -0.45306330919265747 -0.18766489624977112 0.09754517674446106 -0.34675976634025574 -0.06897476315498352 -0.3535533845424652 -0.34675976634025574 -0.06897476315498352 0.3535533845424652 -0.40774619579315186 -0.08110565692186356 0.2777850925922394 -0.27244725823402405 -0.054193101823329926 -0.41573482751846313 -0.4530634880065918 -0.09011993557214737 0.19134171307086945 -0.18766489624977112 -0.03732886165380478 -0.46193981170654297 -0.4809694290161133 -0.0956706702709198 0.09754517674446106 -0.0956706628203392 -0.019030101597309113 -0.49039265513420105 -0.49039226770401 -0.09754499047994614 3.774895063202166e-08 -0.09567075967788696 -0.019030112773180008 0.49039262533187866 -0.4809694290161133 -0.0956706702709198 -0.09754510223865509 -0.1876649260520935 -0.037328869104385376 0.4619397521018982 -0.4530634880065918 -0.09011993557214737 -0.19134163856506348 -0.2724473178386688 -0.05419312044978142 0.41573479771614075 -0.40774619579315186 -0.08110565692186356 -0.2777850925922394 + + + + + + + + + + -0.9809869527816772 0.0 0.19391460716724396 -0.9807733297348022 0.19507431983947754 0.0 -1.0 0.0 0.0 -0.20096439123153687 0.0 0.9795831441879272 0.0 0.0 1.0 -0.19708853960037231 0.039185766130685806 0.9795831441879272 0.0 0.0 -1.0 -0.20096439123153687 0.0 -0.9795831441879272 -0.19708853960037231 0.039185766130685806 -0.9795831441879272 -0.9621570706367493 0.191381573677063 -0.19391460716724396 -0.9809869527816772 0.0 -0.19391460716724396 -0.3804132342338562 0.07565538585186005 0.921689510345459 -0.3878597319126129 0.0 0.921689510345459 -0.9247413277626038 0.0 -0.3805353045463562 -0.9069795608520508 0.18039490282535553 -0.3805353045463562 -0.5597705245018005 0.0 0.8286385536193848 -0.5489974617958069 0.10919522494077682 0.8286385536193848 -0.8173161745071411 0.16257210075855255 -0.5527512431144714 -0.8333384394645691 0.0 -0.5527512431144714 -0.6964934468269348 0.13852351903915405 0.7040314674377441 -0.7101352214813232 0.0 0.7040314674377441 -0.7101352214813232 0.0 -0.7040314674377441 -0.6964934468269348 0.13852351903915405 -0.7040314674377441 -0.8173161745071411 0.16257210075855255 0.5527512431144714 -0.8333384394645691 0.0 0.5527512431144714 -0.5489974617958069 0.10919522494077682 -0.8286385536193848 -0.5597705245018005 0.0 -0.8286385536193848 -0.9069795608520508 0.18039490282535553 0.3805353045463562 -0.9247413277626038 0.0 0.3805353045463562 -0.3804132342338562 0.07565538585186005 -0.921689510345459 -0.3878597319126129 0.0 -0.921689510345459 -0.9621570706367493 0.191381573677063 0.19391460716724396 -0.3583483397960663 0.14841151237487793 -0.921689510345459 -0.9063386917114258 0.3754081726074219 0.19391460716724396 -0.18564409017562866 0.07690664380788803 -0.9795831441879272 -0.9238563179969788 0.382671594619751 0.0 -0.18564409017562866 0.07690664380788803 0.9795831441879272 -0.9063386917114258 0.3754081726074219 -0.19391460716724396 -0.3583483397960663 0.14841151237487793 0.921689510345459 -0.8543656468391418 0.35389262437820435 -0.3805353045463562 -0.5171361565589905 0.2142094224691391 0.8286385536193848 -0.7698904275894165 0.3188879191875458 -0.5527512431144714 -0.6560564041137695 0.2717368006706238 0.7040314674377441 -0.6560564041137695 0.2717368006706238 -0.7040314674377441 -0.7698904275894165 0.3188879191875458 0.5527512431144714 -0.5171361565589905 0.2142094224691391 -0.8286385536193848 -0.8543656468391418 0.35386210680007935 0.3805353045463562 -0.7689138650894165 0.5137485861778259 -0.3805353045463562 -0.6928922533988953 0.46296578645706177 -0.5527512431144714 -0.5904415845870972 0.39451277256011963 0.7040314674377441 -0.5904415845870972 0.39451277256011963 -0.7040314674377441 -0.6928922533988953 0.46296578645706177 0.5527512431144714 -0.46540728211402893 0.3109835982322693 -0.8286385536193848 -0.7689138650894165 0.5137485861778259 0.3805353045463562 -0.32248908281326294 0.2154911905527115 -0.921689510345459 -0.8156682252883911 0.5449995398521423 0.19391460716724396 -0.1670888364315033 0.1116367056965828 -0.9795831441879272 -0.8314462900161743 0.5555589199066162 0.0 -0.1670888364315033 0.1116367056965828 0.9795831441879272 -0.8156682252883911 0.5449995398521423 -0.19391460716724396 -0.32248908281326294 0.2154911905527115 0.921689510345459 -0.46540728211402893 0.3109835982322693 0.8286385536193848 -0.1420941799879074 0.1420941799879074 -0.9795831441879272 -0.6936551928520203 0.6936551928520203 0.19391460716724396 -0.7070833444595337 0.7070833444595337 0.0 -0.1420941799879074 0.1420941799879074 0.9795831441879272 -0.6936551928520203 0.6936551928520203 -0.19391460716724396 -0.27426984906196594 0.27426984906196594 0.921689510345459 -0.6538895964622498 0.6538895964622498 -0.3805353045463562 -0.395794540643692 0.395794540643692 0.8286385536193848 -0.5892513990402222 0.5892513990402222 -0.5527512431144714 -0.5021210312843323 0.5021210312843323 0.7040314674377441 -0.5021210312843323 0.5021210312843323 -0.7040314674377441 -0.5892513990402222 0.5892513990402222 0.5527512431144714 -0.395794540643692 0.395794540643692 -0.8286385536193848 -0.6538895964622498 0.6538895964622498 0.3805353045463562 -0.27426984906196594 0.27426984906196594 -0.921689510345459 -0.39451277256011963 0.5904415845870972 0.7040314674377441 -0.39451277256011963 0.5904415845870972 -0.7040314674377441 -0.46296578645706177 0.6928922533988953 0.5527512431144714 -0.3109835982322693 0.46540728211402893 -0.8286385536193848 -0.5137485861778259 0.7689138650894165 0.3805353045463562 -0.2154911905527115 0.32248908281326294 -0.921689510345459 -0.5449995398521423 0.8156682252883911 0.19391460716724396 -0.1116367056965828 0.1670888364315033 -0.9795831441879272 -0.5555589199066162 0.8314462900161743 0.0 -0.1116367056965828 0.1670888364315033 0.9795831441879272 -0.5449995398521423 0.8156682252883911 -0.19391460716724396 -0.2154911905527115 0.32248908281326294 0.921689510345459 -0.5137485861778259 0.7689138650894165 -0.3805353045463562 -0.3109835982322693 0.46540728211402893 0.8286385536193848 -0.46296578645706177 0.6928922533988953 -0.5527512431144714 -0.382671594619751 0.9238563179969788 0.0 -0.07690664380788803 0.18564409017562866 0.9795831441879272 -0.07690664380788803 0.18564409017562866 -0.9795831441879272 -0.3754081726074219 0.9063386917114258 -0.19391460716724396 -0.14841151237487793 0.3583483397960663 0.921689510345459 -0.35386210680007935 0.8543656468391418 -0.3805353045463562 -0.2142094224691391 0.5171361565589905 0.8286385536193848 -0.3188879191875458 0.7698904275894165 -0.5527512431144714 -0.2717368006706238 0.6560564041137695 0.7040314674377441 -0.2717368006706238 0.6560564041137695 -0.7040314674377441 -0.3188879191875458 0.7698904275894165 0.5527512431144714 -0.2142094224691391 0.5171361565589905 -0.8286385536193848 -0.35386210680007935 0.8543656468391418 0.3805353045463562 -0.14841151237487793 0.3583483397960663 -0.921689510345459 -0.3754081726074219 0.9063386917114258 0.19391460716724396 -0.16257210075855255 0.8173161745071411 -0.5527512431144714 -0.13852351903915405 0.6964934468269348 -0.7040314674377441 -0.16257210075855255 0.8173161745071411 0.5527512431144714 -0.10919522494077682 0.5489974617958069 -0.8286385536193848 -0.18039490282535553 0.9069795608520508 0.3805353045463562 -0.07565538585186005 0.3804132342338562 -0.921689510345459 -0.191381573677063 0.9621570706367493 0.19391460716724396 -0.039185766130685806 0.19708853960037231 -0.9795831441879272 -0.19507431983947754 0.9807733297348022 0.0 -0.039185766130685806 0.19708853960037231 0.9795831441879272 -0.191381573677063 0.9621570706367493 -0.19391460716724396 -0.07565538585186005 0.3804132342338562 0.921689510345459 -0.18039490282535553 0.9069795608520508 -0.3805353045463562 -0.10919522494077682 0.5489974617958069 0.8286385536193848 -0.13852351903915405 0.6964934468269348 0.7040314674377441 0.0 0.20096439123153687 0.9795831441879272 0.0 0.20096439123153687 -0.9795831441879272 0.0 1.0 0.0 0.0 0.9809869527816772 -0.19391460716724396 0.0 0.3878597319126129 0.921689510345459 0.0 0.9247413277626038 -0.3805353045463562 0.0 0.5597705245018005 0.8286385536193848 0.0 0.8333384394645691 -0.5527512431144714 0.0 0.7101352214813232 0.7040314674377441 0.0 0.7101352214813232 -0.7040314674377441 0.0 0.8333384394645691 0.5527512431144714 0.0 0.5597705245018005 -0.8286385536193848 0.0 0.9247413277626038 0.3805353045463562 0.0 0.3878597319126129 -0.921689510345459 0.0 0.9809869527816772 0.19391460716724396 0.13852351903915405 0.6964934468269348 0.7040314674377441 0.16257210075855255 0.8173161745071411 0.5527512431144714 0.13852351903915405 0.6964934468269348 -0.7040314674377441 0.10919522494077682 0.5489974617958069 -0.8286385536193848 0.18039490282535553 0.9069795608520508 0.3805353045463562 0.07565538585186005 0.3804132342338562 -0.921689510345459 0.191381573677063 0.9621570706367493 0.19391460716724396 0.039185766130685806 0.19708853960037231 -0.9795831441879272 0.19507431983947754 0.9807733297348022 0.0 0.039185766130685806 0.19708853960037231 0.9795831441879272 0.191381573677063 0.9621570706367493 -0.19391460716724396 0.07565538585186005 0.3804132342338562 0.921689510345459 0.18039490282535553 0.9069795608520508 -0.3805353045463562 0.10919522494077682 0.5489974617958069 0.8286385536193848 0.16257210075855255 0.8173161745071411 -0.5527512431144714 0.3754081726074219 0.9063386917114258 -0.19391460716724396 0.14841151237487793 0.3583483397960663 0.921689510345459 0.35386210680007935 0.8543656468391418 -0.3805353045463562 0.2142094224691391 0.5171361565589905 0.8286385536193848 0.3188879191875458 0.7698904275894165 -0.5527512431144714 0.2717368006706238 0.6560564041137695 0.7040314674377441 0.2717368006706238 0.6560564041137695 -0.7040314674377441 0.3188879191875458 0.7698904275894165 0.5527512431144714 0.2142094224691391 0.5171361565589905 -0.8286385536193848 0.35386210680007935 0.8543656468391418 0.3805353045463562 0.14841151237487793 0.3583483397960663 -0.921689510345459 0.3754081726074219 0.9063386917114258 0.19391460716724396 0.07690664380788803 0.18564409017562866 -0.9795831441879272 0.382671594619751 0.9238563179969788 0.0 0.07690664380788803 0.18564409017562866 0.9795831441879272 0.39451277256011963 0.5904415845870972 -0.7040314674377441 0.3109835982322693 0.46540728211402893 -0.8286385536193848 0.5137485861778259 0.7689138650894165 0.3805353045463562 0.2154911905527115 0.32248908281326294 -0.921689510345459 0.5449995398521423 0.8156682252883911 0.19391460716724396 0.1116367056965828 0.1670888364315033 -0.9795831441879272 0.5555589199066162 0.8314462900161743 0.0 0.1116367056965828 0.1670888364315033 0.9795831441879272 0.5449995398521423 0.8156682252883911 -0.19391460716724396 0.2154911905527115 0.32248908281326294 0.921689510345459 0.5137485861778259 0.7689138650894165 -0.3805353045463562 0.3109835982322693 0.46540728211402893 0.8286385536193848 0.46296578645706177 0.6928922533988953 -0.5527512431144714 0.39451277256011963 0.5904415845870972 0.7040314674377441 0.46296578645706177 0.6928922533988953 0.5527512431144714 0.6538895964622498 0.6538895964622498 -0.3805353045463562 0.395794540643692 0.395794540643692 0.8286385536193848 0.5892513990402222 0.5892513990402222 -0.5527512431144714 0.5021210312843323 0.5021210312843323 0.7040314674377441 0.5021210312843323 0.5021210312843323 -0.7040314674377441 0.5892513990402222 0.5892513990402222 0.5527512431144714 0.395794540643692 0.395794540643692 -0.8286385536193848 0.6538895964622498 0.6538895964622498 0.3805353045463562 0.27426984906196594 0.27426984906196594 -0.921689510345459 0.6936551928520203 0.6936551928520203 0.19391460716724396 0.1420941799879074 0.1420941799879074 -0.9795831441879272 0.7070833444595337 0.7070833444595337 0.0 0.1420941799879074 0.1420941799879074 0.9795831441879272 0.6936551928520203 0.6936551928520203 -0.19391460716724396 0.27426984906196594 0.27426984906196594 0.921689510345459 0.32248908281326294 0.2154911905527115 -0.921689510345459 0.7689138650894165 0.5137485861778259 0.3805353045463562 0.8156682252883911 0.5449995398521423 0.19391460716724396 0.1670888364315033 0.1116367056965828 -0.9795831441879272 0.8314462900161743 0.5555589199066162 0.0 0.1670888364315033 0.1116367056965828 0.9795831441879272 0.8156682252883911 0.5449995398521423 -0.19391460716724396 0.32248908281326294 0.2154911905527115 0.921689510345459 0.7689138650894165 0.5137485861778259 -0.3805353045463562 0.46540728211402893 0.3109835982322693 0.8286385536193848 0.6928922533988953 0.46296578645706177 -0.5527512431144714 0.5904415845870972 0.39451277256011963 0.7040314674377441 0.5904415845870972 0.39451277256011963 -0.7040314674377441 0.6928922533988953 0.46296578645706177 0.5527512431144714 0.46540728211402893 0.3109835982322693 -0.8286385536193848 0.3583483397960663 0.14841151237487793 0.921689510345459 0.5171361565589905 0.2142094224691391 0.8286385536193848 0.8543656468391418 0.35386210680007935 -0.3805353045463562 0.7698904275894165 0.3188879191875458 -0.5527512431144714 0.6560564041137695 0.2717368006706238 0.7040314674377441 0.6560564041137695 0.2717368006706238 -0.7040314674377441 0.7698904275894165 0.3188879191875458 0.5527512431144714 0.5171361565589905 0.2142094224691391 -0.8286385536193848 0.8543656468391418 0.35386210680007935 0.3805353045463562 0.3583483397960663 0.14841151237487793 -0.921689510345459 0.9063386917114258 0.3754081726074219 0.19391460716724396 0.18564409017562866 0.07690664380788803 -0.9795831441879272 0.9238563179969788 0.382671594619751 0.0 0.18564409017562866 0.07690664380788803 0.9795831441879272 0.9063386917114258 0.3754081726074219 -0.19391460716724396 0.9069795608520508 0.18039490282535553 0.3805353045463562 0.9621570706367493 0.191381573677063 0.19391460716724396 0.3804132342338562 0.07565538585186005 -0.921689510345459 0.19708853960037231 0.039185766130685806 -0.9795831441879272 0.9807733297348022 0.19507431983947754 0.0 0.19708853960037231 0.039185766130685806 0.9795831441879272 0.9621570706367493 0.191381573677063 -0.19391460716724396 0.3804132342338562 0.07565538585186005 0.921689510345459 0.9069795608520508 0.18039490282535553 -0.3805353045463562 0.5489974617958069 0.10919522494077682 0.8286385536193848 0.8173161745071411 0.16257210075855255 -0.5527512431144714 0.6964934468269348 0.13852351903915405 0.7040314674377441 0.6964934468269348 0.13852351903915405 -0.7040314674377441 0.8173161745071411 0.16257210075855255 0.5527512431144714 0.5489974617958069 0.10919522494077682 -0.8286385536193848 0.9247413277626038 0.0 -0.3805353045463562 0.8333384394645691 0.0 -0.5527512431144714 0.5597705245018005 0.0 0.8286385536193848 0.7101352214813232 0.0 0.7040314674377441 0.7101352214813232 0.0 -0.7040314674377441 0.8333384394645691 0.0 0.5527512431144714 0.5597705245018005 0.0 -0.8286385536193848 0.9247413277626038 0.0 0.3805353045463562 0.3878597319126129 0.0 -0.921689510345459 0.9809869527816772 0.0 0.19391460716724396 0.20096439123153687 0.0 -0.9795831441879272 1.0 0.0 0.0 0.20096439123153687 0.0 0.9795831441879272 0.9809869527816772 0.0 -0.19391460716724396 0.3878597319126129 0.0 0.921689510345459 0.19708853960037231 -0.039185766130685806 -0.9795831441879272 0.9807733297348022 -0.19507431983947754 0.0 0.19708853960037231 -0.039185766130685806 0.9795831441879272 0.9621570706367493 -0.191381573677063 -0.19391460716724396 0.3804132342338562 -0.07565538585186005 0.921689510345459 0.9069795608520508 -0.18039490282535553 -0.3805353045463562 0.5489974617958069 -0.10919522494077682 0.8286385536193848 0.8173161745071411 -0.16257210075855255 -0.5527512431144714 0.6964934468269348 -0.13852351903915405 0.7040314674377441 0.6964934468269348 -0.13852351903915405 -0.7040314674377441 0.8173161745071411 -0.16257210075855255 0.5527512431144714 0.5489974617958069 -0.10919522494077682 -0.8286385536193848 0.9069795608520508 -0.18039490282535553 0.3805353045463562 0.3804132342338562 -0.07565538585186005 -0.921689510345459 0.9621570706367493 -0.191381573677063 0.19391460716724396 0.5171361565589905 -0.2142094224691391 0.8286385536193848 0.6560564041137695 -0.2717368006706238 0.7040314674377441 0.6560564041137695 -0.2717368006706238 -0.7040314674377441 0.7698904275894165 -0.3188879191875458 0.5527512431144714 0.5171361565589905 -0.2142094224691391 -0.8286385536193848 0.8543656468391418 -0.35389262437820435 0.3805353045463562 0.3583483397960663 -0.14841151237487793 -0.921689510345459 0.9063386917114258 -0.3754081726074219 0.19391460716724396 0.18564409017562866 -0.07690664380788803 -0.9795831441879272 0.9238563179969788 -0.382671594619751 0.0 0.18564409017562866 -0.07690664380788803 0.9795831441879272 0.9063386917114258 -0.3754081726074219 -0.19391460716724396 0.3583483397960663 -0.14841151237487793 0.921689510345459 0.8543656468391418 -0.35386210680007935 -0.3805353045463562 0.7698904275894165 -0.3188879191875458 -0.5527512431144714 0.8314462900161743 -0.5555589199066162 0.0 0.1670888364315033 -0.1116367056965828 0.9795831441879272 0.1670888364315033 -0.1116367056965828 -0.9795831441879272 0.8156682252883911 -0.5449995398521423 -0.19391460716724396 0.32248908281326294 -0.2154911905527115 0.921689510345459 0.7689138650894165 -0.5137485861778259 -0.3805353045463562 0.46540728211402893 -0.3109835982322693 0.8286385536193848 0.6928922533988953 -0.46296578645706177 -0.5527512431144714 0.5904415845870972 -0.39451277256011963 0.7040314674377441 0.5904415845870972 -0.39451277256011963 -0.7040314674377441 0.6928922533988953 -0.46296578645706177 0.5527512431144714 0.46540728211402893 -0.3109835982322693 -0.8286385536193848 0.7689138650894165 -0.5137485861778259 0.3805353045463562 0.32248908281326294 -0.2154911905527115 -0.921689510345459 0.8156682252883911 -0.5449995398521423 0.19391460716724396 0.5021210312843323 -0.5021210312843323 -0.7040314674377441 0.5021210312843323 -0.5021210312843323 0.7040314674377441 0.5892513990402222 -0.5892513990402222 0.5527512431144714 0.395794540643692 -0.395794540643692 -0.8286385536193848 0.6538895964622498 -0.6538895964622498 0.3805353045463562 0.27426984906196594 -0.27426984906196594 -0.921689510345459 0.6936551928520203 -0.6936551928520203 0.19391460716724396 0.1420941799879074 -0.1420941799879074 -0.9795831441879272 0.7070833444595337 -0.7070833444595337 0.0 0.1420941799879074 -0.1420941799879074 0.9795831441879272 0.6936551928520203 -0.6936551928520203 -0.19391460716724396 0.27426984906196594 -0.27426984906196594 0.921689510345459 0.6538895964622498 -0.6538895964622498 -0.3805353045463562 0.395794540643692 -0.395794540643692 0.8286385536193848 0.5892513990402222 -0.5892513990402222 -0.5527512431144714 0.1116367056965828 -0.1670888364315033 -0.9795831441879272 0.5449995398521423 -0.8156682252883911 -0.19391460716724396 0.2154911905527115 -0.32248908281326294 0.921689510345459 0.5137485861778259 -0.7689138650894165 -0.3805353045463562 0.3109835982322693 -0.46540728211402893 0.8286385536193848 0.46296578645706177 -0.6928922533988953 -0.5527512431144714 0.39451277256011963 -0.5904415845870972 0.7040314674377441 0.39451277256011963 -0.5904415845870972 -0.7040314674377441 0.46296578645706177 -0.6928922533988953 0.5527512431144714 0.3109835982322693 -0.46540728211402893 -0.8286385536193848 0.5137485861778259 -0.7689138650894165 0.3805353045463562 0.2154911905527115 -0.32248908281326294 -0.921689510345459 0.5449995398521423 -0.8156682252883911 0.19391460716724396 0.5555589199066162 -0.8314462900161743 0.0 0.1116367056965828 -0.1670888364315033 0.9795831441879272 0.2142094224691391 -0.5171361565589905 -0.8286385536193848 0.35386210680007935 -0.8543656468391418 0.3805353045463562 0.14841151237487793 -0.3583483397960663 -0.921689510345459 0.3754081726074219 -0.9063386917114258 0.19391460716724396 0.07690664380788803 -0.18564409017562866 -0.9795831441879272 0.382671594619751 -0.9238563179969788 0.0 0.07687612622976303 -0.18564409017562866 0.9795831441879272 0.3754081726074219 -0.9063386917114258 -0.19391460716724396 0.14841151237487793 -0.3583483397960663 0.921689510345459 0.35386210680007935 -0.8543656468391418 -0.3805353045463562 0.2142094224691391 -0.5171361565589905 0.8286385536193848 0.3188879191875458 -0.7698904275894165 -0.5527512431144714 0.2717368006706238 -0.6560564041137695 0.7040314674377441 0.2717368006706238 -0.6560564041137695 -0.7040314674377441 0.3188879191875458 -0.7698904275894165 0.5527512431144714 0.039185766130685806 -0.19708853960037231 0.9795831441879272 0.07565538585186005 -0.3804132342338562 0.921689510345459 0.18039490282535553 -0.9069795608520508 -0.3805353045463562 0.10919522494077682 -0.5489974617958069 0.8286385536193848 0.16257210075855255 -0.8173161745071411 -0.5527512431144714 0.13852351903915405 -0.6964934468269348 0.7040314674377441 0.13852351903915405 -0.6964934468269348 -0.7040314674377441 0.16257210075855255 -0.8173161745071411 0.5527512431144714 0.10919522494077682 -0.5489974617958069 -0.8286385536193848 0.18039490282535553 -0.9069795608520508 0.3805353045463562 0.07565538585186005 -0.3804132342338562 -0.921689510345459 0.191381573677063 -0.9621570706367493 0.19391460716724396 0.039185766130685806 -0.19708853960037231 -0.9795831441879272 0.19507431983947754 -0.9807733297348022 0.0 0.191381573677063 -0.9621570706367493 -0.19391460716724396 0.0 -0.9247413277626038 0.3805353045463562 0.0 -0.5597705245018005 -0.8286385536193848 0.0 -0.3878597319126129 -0.921689510345459 0.0 -0.9809869527816772 0.19391460716724396 0.0 -0.20096439123153687 -0.9795831441879272 0.0 -1.0 0.0 0.0 -0.20096439123153687 0.9795831441879272 0.0 -0.9809869527816772 -0.19391460716724396 0.0 -0.3878597319126129 0.921689510345459 0.0 -0.9247413277626038 -0.3805353045463562 0.0 -0.5597705245018005 0.8286385536193848 0.0 -0.8333384394645691 -0.5527512431144714 0.0 -0.7101352214813232 0.7040314674377441 0.0 -0.7101352214813232 -0.7040314674377441 0.0 -0.8333384394645691 0.5527512431144714 -0.18039490282535553 -0.9069795608520508 -0.3805353045463562 -0.10919522494077682 -0.5489974617958069 0.8286385536193848 -0.16257210075855255 -0.8173161745071411 -0.5527512431144714 -0.13852351903915405 -0.6964934468269348 0.7040314674377441 -0.13852351903915405 -0.6964934468269348 -0.7040314674377441 -0.16257210075855255 -0.8173161745071411 0.5527512431144714 -0.10919522494077682 -0.5489974617958069 -0.8286385536193848 -0.18039490282535553 -0.9069795608520508 0.3805353045463562 -0.07565538585186005 -0.3804132342338562 -0.921689510345459 -0.191381573677063 -0.9621570706367493 0.19391460716724396 -0.039185766130685806 -0.19708853960037231 -0.9795831441879272 -0.19507431983947754 -0.9807733297348022 0.0 -0.039185766130685806 -0.19708853960037231 0.9795831441879272 -0.191381573677063 -0.9621570706367493 -0.19391460716724396 -0.07565538585186005 -0.3804132342338562 0.921689510345459 -0.2142094224691391 -0.5171361565589905 -0.8286385536193848 -0.14841151237487793 -0.3583483397960663 -0.921689510345459 -0.35389262437820435 -0.8543656468391418 0.3805353045463562 -0.3754081726074219 -0.9063386917114258 0.19391460716724396 -0.07690664380788803 -0.18564409017562866 -0.9795831441879272 -0.382671594619751 -0.9238563179969788 0.0 -0.07687612622976303 -0.18564409017562866 0.9795831441879272 -0.3754081726074219 -0.9063386917114258 -0.19391460716724396 -0.14841151237487793 -0.3583483397960663 0.921689510345459 -0.35386210680007935 -0.8543656468391418 -0.3805353045463562 -0.2142094224691391 -0.5171361565589905 0.8286385536193848 -0.3188879191875458 -0.7698904275894165 -0.5527512431144714 -0.2717368006706238 -0.6560564041137695 0.7040314674377441 -0.2717368006706238 -0.6560564041137695 -0.7040314674377441 -0.3188879191875458 -0.7698904275894165 0.5527512431144714 -0.2154911905527115 -0.32248908281326294 0.921689510345459 -0.3109835982322693 -0.46540728211402893 0.8286385536193848 -0.5137485861778259 -0.7689138650894165 -0.3805353045463562 -0.46296578645706177 -0.6928922533988953 -0.5527512431144714 -0.39451277256011963 -0.5904415845870972 0.7040314674377441 -0.39451277256011963 -0.5904415845870972 -0.7040314674377441 -0.46296578645706177 -0.6928922533988953 0.5527512431144714 -0.3109835982322693 -0.46540728211402893 -0.8286385536193848 -0.5137485861778259 -0.7689138650894165 0.3805353045463562 -0.2154911905527115 -0.32248908281326294 -0.921689510345459 -0.5449995398521423 -0.8156682252883911 0.19391460716724396 -0.1116367056965828 -0.1670888364315033 -0.9795831441879272 -0.5555589199066162 -0.8314462900161743 0.0 -0.1116367056965828 -0.1670888364315033 0.9795831441879272 -0.5449995398521423 -0.8156682252883911 -0.19391460716724396 -0.6538895964622498 -0.6538895964622498 0.3805353045463562 -0.6936551928520203 -0.6936551928520203 0.19391460716724396 -0.1420941799879074 -0.1420941799879074 -0.9795831441879272 -0.7070833444595337 -0.7070833444595337 0.0 -0.1420941799879074 -0.1420941799879074 0.9795831441879272 -0.6936551928520203 -0.6936551928520203 -0.19391460716724396 -0.27426984906196594 -0.27426984906196594 0.921689510345459 -0.6538895964622498 -0.6538895964622498 -0.3805353045463562 -0.395794540643692 -0.395794540643692 0.8286385536193848 -0.5892513990402222 -0.5892513990402222 -0.5527512431144714 -0.5021210312843323 -0.5021210312843323 0.7040314674377441 -0.5021210312843323 -0.5021210312843323 -0.7040314674377441 -0.5892513990402222 -0.5892513990402222 0.5527512431144714 -0.395794540643692 -0.395794540643692 -0.8286385536193848 -0.27426984906196594 -0.27426984906196594 -0.921689510345459 -0.7689138650894165 -0.5137485861778259 -0.3805353045463562 -0.6928922533988953 -0.46296578645706177 -0.5527512431144714 -0.5904415845870972 -0.39451277256011963 0.7040314674377441 -0.5904415845870972 -0.39451277256011963 -0.7040314674377441 -0.6928922533988953 -0.46296578645706177 0.5527512431144714 -0.46540728211402893 -0.3109835982322693 -0.8286385536193848 -0.7689138650894165 -0.5137485861778259 0.3805353045463562 -0.32248908281326294 -0.2154911905527115 -0.921689510345459 -0.8156682252883911 -0.5449995398521423 0.19391460716724396 -0.1670888364315033 -0.1116367056965828 -0.9795831441879272 -0.8314462900161743 -0.5555589199066162 0.0 -0.1670888364315033 -0.1116367056965828 0.9795831441879272 -0.8156682252883911 -0.5449995398521423 -0.19391460716724396 -0.32248908281326294 -0.2154911905527115 0.921689510345459 -0.46540728211402893 -0.3109835982322693 0.8286385536193848 -0.18564409017562866 -0.07690664380788803 -0.9795831441879272 -0.9238563179969788 -0.382671594619751 0.0 -0.18564409017562866 -0.07690664380788803 0.9795831441879272 -0.9063386917114258 -0.3754081726074219 -0.19391460716724396 -0.3583483397960663 -0.14841151237487793 0.921689510345459 -0.8543656468391418 -0.35386210680007935 -0.3805353045463562 -0.5171361565589905 -0.2142094224691391 0.8286385536193848 -0.7698904275894165 -0.3188879191875458 -0.5527512431144714 -0.6560564041137695 -0.2717368006706238 0.7040314674377441 -0.6560564041137695 -0.2717368006706238 -0.7040314674377441 -0.7698904275894165 -0.3188879191875458 0.5527512431144714 -0.5171361565589905 -0.2142094224691391 -0.8286385536193848 -0.8543656468391418 -0.35386210680007935 0.3805353045463562 -0.3583483397960663 -0.14841151237487793 -0.921689510345459 -0.9063386917114258 -0.3754081726074219 0.19391460716724396 -0.6964934468269348 -0.13852351903915405 -0.7040314674377441 -0.6964934468269348 -0.13852351903915405 0.7040314674377441 -0.8173161745071411 -0.16257210075855255 0.5527512431144714 -0.5489974617958069 -0.10919522494077682 -0.8286385536193848 -0.9069795608520508 -0.18039490282535553 0.3805353045463562 -0.3804132342338562 -0.07565538585186005 -0.921689510345459 -0.9621570706367493 -0.191381573677063 0.19391460716724396 -0.19708853960037231 -0.039185766130685806 -0.9795831441879272 -0.9807733297348022 -0.19507431983947754 0.0 -0.19708853960037231 -0.039185766130685806 0.9795831441879272 -0.9621570706367493 -0.191381573677063 -0.19391460716724396 -0.3804132342338562 -0.07565538585186005 0.921689510345459 -0.9069795608520508 -0.18039490282535553 -0.3805353045463562 -0.5489974617958069 -0.10919522494077682 0.8286385536193848 -0.8173161745071411 -0.16257210075855255 -0.5527512431144714 + + + + + + + + + + + + + + +

0 1 2 3 4 5 6 7 8 2 9 10 3 11 12 13 9 14 15 11 16 13 17 18 15 19 20 21 17 22 20 23 24 21 25 26 24 27 28 26 29 30 28 31 0 30 8 7 25 32 29 27 33 31 29 34 8 31 35 1 5 4 36 6 8 34 9 35 37 5 38 11 14 37 39 11 40 16 14 41 17 16 42 19 22 41 43 19 44 23 22 45 25 23 46 27 41 47 48 40 49 42 43 48 50 42 51 44 43 52 45 44 53 46 45 54 32 33 53 55 32 56 34 33 57 35 36 4 58 6 34 56 35 59 37 36 60 38 37 47 39 38 61 40 54 62 56 57 63 64 58 4 65 6 56 62 57 66 59 58 67 60 59 68 47 60 69 61 48 68 70 61 71 49 48 72 50 49 73 51 50 74 52 51 75 53 52 76 54 53 63 55 69 77 71 70 78 72 73 77 79 74 78 80 73 81 75 76 80 82 75 83 63 76 84 62 64 83 85 65 4 86 6 62 84 64 87 66 65 88 67 66 89 68 67 90 69 70 89 91 83 92 85 86 4 93 6 84 94 85 95 87 86 96 88 87 97 89 88 98 90 91 97 99 90 100 77 78 99 101 79 100 102 78 103 80 79 104 81 82 103 105 83 104 106 82 94 84 101 107 108 100 109 102 101 110 103 102 111 104 103 112 105 106 111 113 94 112 114 106 115 92 93 4 116 6 94 114 92 117 95 93 118 96 95 119 97 96 120 98 99 119 107 100 120 121 116 4 122 6 114 123 117 124 125 116 126 118 117 127 119 118 128 120 107 127 129 120 130 121 107 131 108 121 132 109 110 131 133 109 134 111 112 133 135 113 134 136 114 135 123 113 124 115 132 137 138 133 139 140 132 141 134 133 142 135 136 141 143 123 142 144 136 145 124 122 4 146 6 123 144 124 147 125 126 146 148 125 149 127 126 150 128 129 149 151 128 137 130 129 139 131 145 152 147 146 153 148 147 154 149 150 153 155 151 154 156 150 157 137 151 158 139 137 159 138 139 160 140 138 161 141 142 160 162 143 161 163 142 164 144 143 165 145 146 4 166 6 144 164 160 167 168 159 169 161 160 170 162 163 169 171 162 172 164 163 173 165 166 4 174 6 164 172 152 173 175 166 176 153 152 177 154 153 178 155 156 177 179 155 180 157 156 167 158 159 180 181 175 182 177 176 183 178 177 184 179 178 185 180 179 186 167 180 187 181 168 186 188 181 189 169 168 190 170 171 189 191 172 190 192 171 193 173 174 4 194 6 172 192 173 195 175 174 196 176 188 197 190 191 198 199 192 197 200 191 201 193 194 4 202 6 192 200 195 201 203 194 204 196 195 205 182 196 206 183 184 205 207 185 206 208 184 209 186 187 208 210 188 209 211 187 198 189 206 212 213 207 214 215 206 216 208 207 217 209 208 218 210 211 217 219 210 220 198 211 221 197 199 220 222 197 223 200 199 224 201 202 4 225 6 200 223 201 226 203 202 212 204 203 214 205 222 227 228 223 229 230 222 231 224 225 4 232 6 223 230 224 233 226 225 234 212 226 235 214 212 236 213 215 235 237 213 238 216 215 239 217 216 240 218 217 241 219 218 227 220 219 229 221 237 242 243 238 244 245 237 246 239 238 247 240 241 246 248 240 249 227 241 250 229 228 249 251 230 250 252 228 253 231 232 4 254 6 230 252 231 255 233 232 256 234 233 242 235 236 256 244 250 257 252 251 258 253 254 4 259 6 252 257 253 260 255 254 261 256 255 262 242 256 263 244 243 262 264 245 263 265 243 266 246 247 265 267 246 268 248 247 269 249 248 270 250 251 269 271 265 272 273 264 274 266 267 273 275 266 276 268 267 277 269 270 276 278 271 277 279 257 278 280 271 281 258 259 4 282 6 257 280 260 281 283 259 284 261 260 285 262 261 272 263 264 285 286 279 287 281 282 4 288 6 280 289 281 290 283 282 291 284 283 292 285 284 293 272 286 292 294 272 295 273 286 296 274 275 295 297 276 296 298 275 299 277 276 300 278 279 299 301 280 300 289 294 302 296 297 303 304 296 305 298 297 306 299 298 307 300 301 306 308 300 309 289 287 308 310 288 4 311 6 289 309 287 312 290 288 313 291 290 314 292 291 315 293 294 314 316 295 315 303 6 309 317 310 318 312 311 319 313 312 320 314 313 321 315 316 320 322 303 321 323 316 324 302 304 323 325 302 326 305 304 327 306 307 326 328 308 327 329 307 317 309 308 330 310 311 4 331 324 332 326 325 333 327 328 332 334 329 333 335 317 334 336 329 337 330 331 4 338 6 317 336 330 339 318 331 340 319 318 341 320 319 342 321 322 341 343 323 342 344 324 343 345 325 344 346 340 347 348 339 349 341 340 350 342 343 349 351 344 350 352 343 353 345 346 352 354 345 355 332 346 356 333 334 355 357 335 356 358 334 359 336 335 360 337 338 4 347 6 336 359 337 361 339 354 362 356 357 363 364 358 362 365 357 366 359 358 367 360 347 4 368 6 359 366 361 367 369 348 368 370 361 371 349 348 372 350 351 371 373 352 372 374 351 375 353 352 376 354 355 375 363 369 377 371 370 378 372 373 377 379 374 378 380 373 381 375 376 380 382 375 383 363 376 384 362 364 383 385 365 384 386 364 387 366 365 388 367 368 4 389 6 366 387 369 388 390 370 389 391 385 392 393 386 394 395 385 396 387 386 397 388 389 4 398 6 387 396 388 399 390 389 400 391 390 401 377 391 402 378 379 401 403 380 402 404 379 405 381 380 406 382 381 392 383 382 394 384 402 407 408 403 409 410 404 408 411 403 412 405 406 411 413 405 414 392 406 415 394 393 414 416 395 415 417 393 418 396 395 419 397 398 4 420 6 396 418 399 419 421 398 407 400 399 409 401 417 422 423 416 424 418 417 425 419 420 4 426 6 418 424 421 425 427 420 428 407 421 429 409 407 430 408 410 429 431 408 432 411 410 433 412 413 432 434 412 435 414 413 422 415 414 436 416 431 437 438 430 439 432 431 440 433 434 439 441 435 440 442 434 443 422 435 444 436 423 443 445 436 446 424 425 445 447 426 4 448 6 424 446 425 449 427 426 450 428 427 437 429 428 451 430 444 452 446 445 453 447 448 4 454 6 446 452 447 455 449 450 454 456 449 457 437 451 456 458 438 457 459 439 458 460 438 461 440 441 460 462 440 463 442 441 464 443 442 465 444 445 464 466 459 467 461 462 468 469 461 470 463 462 471 464 463 472 465 466 471 473 452 472 474 466 475 453 454 4 476 6 452 474 453 477 455 454 478 456 455 479 457 456 480 458 459 479 481 458 468 460 476 4 3 6 474 7 475 10 477 478 3 12 477 13 479 480 12 15 479 18 481 468 15 20 481 21 467 469 20 24 467 26 470 471 24 28 470 30 472 473 28 0 472 7 474 475 0 2 0 31 1 2 1 9 3 5 11 13 10 9 15 12 11 13 14 17 15 16 19 21 18 17 20 19 23 21 22 25 24 23 27 26 25 29 28 27 31 30 29 8 25 45 32 27 46 33 29 32 34 31 33 35 9 1 35 5 36 38 14 9 37 11 38 40 14 39 41 16 40 42 22 17 41 19 42 44 22 43 45 23 44 46 41 39 47 40 61 49 43 41 48 42 49 51 43 50 52 44 51 53 45 52 54 33 46 53 32 54 56 33 55 57 35 57 59 36 58 60 37 59 47 38 60 61 54 76 62 57 55 63 57 64 66 58 65 67 59 66 68 60 67 69 48 47 68 61 69 71 48 70 72 49 71 73 50 72 74 51 73 75 52 74 76 53 75 63 69 90 77 70 91 78 73 71 77 74 72 78 73 79 81 76 74 80 75 81 83 76 82 84 64 63 83 64 85 87 65 86 88 66 87 89 67 88 90 70 68 89 83 106 92 85 92 95 86 93 96 87 95 97 88 96 98 91 89 97 90 98 100 78 91 99 79 77 100 78 101 103 79 102 104 82 80 103 83 81 104 82 105 94 101 99 107 100 121 109 101 108 110 102 109 111 103 110 112 106 104 111 94 105 112 106 113 115 92 115 117 93 116 118 95 117 119 96 118 120 99 97 119 100 98 120 117 115 124 116 122 126 117 125 127 118 126 128 107 119 127 120 128 130 107 129 131 121 130 132 110 108 131 109 132 134 112 110 133 113 111 134 114 112 135 113 136 124 132 130 137 133 131 139 132 138 141 133 140 142 136 134 141 123 135 142 136 143 145 124 145 147 126 122 146 125 147 149 126 148 150 129 127 149 128 150 137 129 151 139 145 165 152 146 166 153 147 152 154 150 148 153 151 149 154 150 155 157 151 156 158 137 157 159 139 158 160 138 159 161 142 140 160 143 141 161 142 162 164 143 163 165 160 158 167 159 181 169 160 168 170 163 161 169 162 170 172 163 171 173 152 165 173 166 174 176 152 175 177 153 176 178 156 154 177 155 178 180 156 179 167 159 157 180 175 195 182 176 196 183 177 182 184 178 183 185 179 184 186 180 185 187 168 167 186 181 187 189 168 188 190 171 169 189 172 170 190 171 191 193 173 193 195 174 194 196 188 211 197 191 189 198 192 190 197 191 199 201 195 193 201 194 202 204 195 203 205 196 204 206 184 182 205 185 183 206 184 207 209 187 185 208 188 186 209 187 210 198 206 204 212 207 205 214 206 213 216 207 215 217 208 216 218 211 209 217 210 218 220 211 219 221 199 198 220 197 221 223 199 222 224 201 224 226 202 225 212 203 226 214 222 220 227 223 221 229 222 228 231 224 231 233 225 232 234 226 233 235 212 234 236 215 214 235 213 236 238 215 237 239 216 238 240 217 239 241 218 240 227 219 241 229 237 235 242 238 236 244 237 243 246 238 245 247 241 239 246 240 247 249 241 248 250 228 227 249 230 229 250 228 251 253 231 253 255 232 254 256 233 255 242 236 234 256 250 270 257 251 271 258 253 258 260 254 259 261 255 260 262 256 261 263 243 242 262 245 244 263 243 264 266 247 245 265 246 266 268 247 267 269 248 268 270 251 249 269 265 263 272 264 286 274 267 265 273 266 274 276 267 275 277 270 268 276 271 269 277 257 270 278 271 279 281 260 258 281 259 282 284 260 283 285 261 284 272 264 262 285 279 301 287 281 287 290 282 288 291 283 290 292 284 291 293 286 285 292 272 293 295 286 294 296 275 273 295 276 274 296 275 297 299 276 298 300 279 277 299 280 278 300 294 316 302 297 295 303 296 302 305 297 304 306 298 305 307 301 299 306 300 307 309 287 301 308 287 310 312 288 311 313 290 312 314 291 313 315 294 292 314 295 293 315 310 330 318 311 331 319 312 318 320 313 319 321 316 314 320 303 315 321 316 322 324 304 303 323 302 324 326 304 325 327 307 305 326 308 306 327 307 328 317 308 329 330 324 345 332 325 346 333 328 326 332 329 327 333 317 328 334 329 335 337 330 337 339 331 338 340 318 339 341 319 340 342 322 320 341 323 321 342 324 322 343 325 323 344 340 338 347 339 361 349 340 348 350 343 341 349 344 342 350 343 351 353 346 344 352 345 353 355 346 354 356 334 332 355 335 333 356 334 357 359 335 358 360 337 360 361 354 376 362 357 355 363 358 356 362 357 364 366 358 365 367 361 360 367 348 347 368 361 369 371 348 370 372 351 349 371 352 350 372 351 373 375 352 374 376 355 353 375 369 390 377 370 391 378 373 371 377 374 372 378 373 379 381 376 374 380 375 381 383 376 382 384 364 363 383 365 362 384 364 385 387 365 386 388 369 367 388 370 368 389 385 383 392 386 384 394 385 393 396 386 395 397 388 397 399 389 398 400 390 399 401 391 400 402 379 377 401 380 378 402 379 403 405 380 404 406 381 405 392 382 406 394 402 400 407 403 401 409 404 402 408 403 410 412 406 404 411 405 412 414 406 413 415 393 392 414 395 394 415 393 416 418 395 417 419 399 397 419 398 420 407 399 421 409 417 415 422 416 436 424 417 423 425 421 419 425 420 426 428 421 427 429 407 428 430 410 409 429 408 430 432 410 431 433 413 411 432 412 433 435 413 434 422 414 435 436 431 429 437 430 451 439 431 438 440 434 432 439 435 433 440 434 441 443 435 442 444 423 422 443 436 444 446 425 423 445 425 447 449 426 448 450 427 449 437 428 450 451 444 465 452 445 466 453 447 453 455 450 448 454 449 455 457 451 450 456 438 437 457 439 451 458 438 459 461 441 439 460 440 461 463 441 462 464 442 463 465 445 443 464 459 481 467 462 460 468 461 467 470 462 469 471 463 470 472 466 464 471 452 465 472 466 473 475 453 475 477 454 476 478 455 477 479 456 478 480 459 457 479 458 480 468 475 2 10 478 476 3 477 10 13 480 478 12 479 13 18 468 480 15 481 18 21 469 468 20 467 21 26 471 469 24 470 26 30 473 471 28 472 30 7 475 473 0

+
+
+
+
+ + + + + + + + + + 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 1.0 + + + + + + + + + + + + + +
diff --git a/Templates/BaseGame/game/tools/resources/materials.cs b/Templates/BaseGame/game/tools/resources/materials.cs new file mode 100644 index 000000000..d9c7ea97f --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/materials.cs @@ -0,0 +1,8 @@ +singleton Material(ReflectProbePreviewMat) +{ + mapTo = "ReflectProbePreviewMat"; + diffuseColor[0] = "1 1 1 1"; + smoothness[0] = "1"; + metalness[0] = "1"; + translucentBlendOp = "None"; +}; diff --git a/Templates/BaseGame/game/tools/resources/reflectionProbePreviewP.hlsl b/Templates/BaseGame/game/tools/resources/reflectionProbePreviewP.hlsl new file mode 100644 index 000000000..5eb32ffc7 --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/reflectionProbePreviewP.hlsl @@ -0,0 +1,49 @@ +#include "shaders/common/shaderModelAutoGen.hlsl" + +#include "shaders/common/lighting/advanced/farFrustumQuad.hlsl" +#include "shaders/common/lighting/advanced/lightingUtils.hlsl" +#include "shaders/common/lighting.hlsl" +#include "shaders/common/torque.hlsl" + +struct ConvexConnectP +{ + float4 pos : TORQUE_POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0); +TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 1); + +uniform float4 rtParams0; + +uniform float4x4 invViewMat; + +float4 main( ConvexConnectP IN ) : TORQUE_TARGET0 +{ + // Compute scene UV + float3 ssPos = IN.ssPos.xyz / IN.ssPos.w; + float2 uvScene = getUVFromSSPos( ssPos, rtParams0 ); + + //float3 eyeRay = IN.vsEyeDir.xyz; + + // Sample/unpack the normal/z data + float4 deferredSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uvScene ); + float3 normal = deferredSample.rgb; + float depth = deferredSample.a; + if (depth>0.9999) + return float4(0,0,0,0); + + // Need world-space normal. + float3 wsNormal = mul(float4(normal, 1), invViewMat).rgb; + + float3 reflectionVec = reflect(IN.wsEyeDir, float4(normalize(wsNormal),1)).rgb; + + float4 color = TORQUE_TEXCUBE(cubeMap, reflectionVec); + + //simple visibility testing + //float4 color = float4(1,0,0,1); + + return float4(color.rgb, 1); +} diff --git a/Templates/BaseGame/game/tools/resources/reflectionProbePreviewV.hlsl b/Templates/BaseGame/game/tools/resources/reflectionProbePreviewV.hlsl new file mode 100644 index 000000000..5c571d9e8 --- /dev/null +++ b/Templates/BaseGame/game/tools/resources/reflectionProbePreviewV.hlsl @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// Copyright (c) 2012 GarageGames, LLC +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//----------------------------------------------------------------------------- + +#include "shaders/common/hlslStructs.hlsl" +#include "shaders/common/shaderModel.hlsl" + +struct VertData +{ + float3 pos : POSITION; + float tangentW : TEXCOORD3; + float3 normal : NORMAL; + float3 T : TANGENT; + float2 texCoord : TEXCOORD0; +}; + +struct ConvexConnectV +{ + float4 hpos : TORQUE_POSITION; + float4 wsEyeDir : TEXCOORD0; + float4 ssPos : TEXCOORD1; + float4 vsEyeDir : TEXCOORD2; +}; + +uniform float4x4 modelview; +uniform float4x4 objTrans; +uniform float4x4 worldViewOnly; +uniform float3 eyePosWorld; + +ConvexConnectV main( VertData IN ) +{ + ConvexConnectV OUT; + + OUT.hpos = mul( modelview, float4(IN.pos,1.0) ); + OUT.wsEyeDir = mul(objTrans, float4(IN.pos, 1.0)) - float4(eyePosWorld, 0.0); + OUT.vsEyeDir = mul(worldViewOnly, float4(IN.pos, 1.0)); + OUT.ssPos = OUT.hpos; + + return OUT; +} diff --git a/Templates/BaseGame/game/tools/settings.xml b/Templates/BaseGame/game/tools/settings.xml index d01241a25..0b1fca7bd 100644 --- a/Templates/BaseGame/game/tools/settings.xml +++ b/Templates/BaseGame/game/tools/settings.xml @@ -1,84 +1,84 @@ + + AIPlayer + - 1 - 0 WorldEditorInspectorPlugin - 6 screenCenter - 50 40 - - 255 255 0 255 - 0 255 0 255 - 255 0 0 255 - 255 255 0 255 - 255 255 255 255 - 0 0 255 255 - 100 100 100 255 - - - 8 - 20 - 255 - 0 - 1 - + 0 + 6 + 50 + 1 - 1 - 1 - 1 1 + 1 1 - - - 255 255 255 100 - 102 102 102 100 - 0 - 1 - 51 51 51 100 - - - ../../../Documentation/Official Documentation.html - ../../../Documentation/Torque 3D - Script Manual.chm - http://www.garagegames.com/products/torque-3d/documentation/user - http://www.garagegames.com/products/torque-3d/forums + 1 + 1 tools/worldEditor/images/LockedHandle tools/worldEditor/images/SelectHandle tools/worldEditor/images/DefaultHandle + + 255 255 0 255 + 255 255 255 255 + 0 255 0 255 + 255 255 0 255 + 0 0 255 255 + 255 0 0 255 + 100 100 100 255 + + + 102 102 102 100 + 0 + 1 + 51 51 51 100 + 255 255 255 100 + - 0 - 2 - 100 - 0 1 + 2 1 0 + 100 + 0 + 0 + + + 20 + 255 + 0 + 1 + 8 + + + ../../../Documentation/Torque 3D - Script Manual.chm + ../../../Documentation/Official Documentation.html + http://www.garagegames.com/products/torque-3d/documentation/user + http://www.garagegames.com/products/torque-3d/forums - 1 - 0.8 100 - 0.8 15 - 0 0 + 0.8 + 0.8 + 0 + 1 - 0 - 500 - 0 - 10 10 10 255 255 255 20 0 + 500 + 0 + 0 + 10 10 10 - - AIPlayer - data/FPSGameplay/levels diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui index 09a90ef26..5530dcbd0 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/guiTerrainMaterialDlg.ed.gui @@ -1,1390 +1,1743 @@ //--- OBJECT WRITE BEGIN --- -%guiContent = new GuiControl(TerrainMaterialDlg, EditorGuiGroup) { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; +%guiContent = new GuiControl(TerrainMaterialDlg,EditorGuiGroup) { position = "0 0"; - Extent = "800 768"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + activeMat = "17411"; + matIndex = "0"; + onApplyCallback = "EPainter_TerrainMaterialUpdateCallback"; new GuiWindowCtrl() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiWindowProfile"; - HorizSizing = "center"; - VertSizing = "center"; - position = "221 151"; - Extent = "394 432"; - MinExtent = "358 432"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Docking = "None"; - Margin = "4 4 4 4"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; + text = "Terrain Materials Editor"; resizeWidth = "1"; resizeHeight = "1"; canMove = "1"; canClose = "1"; canMinimize = "0"; canMaximize = "0"; - minSize = "50 50"; + canCollapse = "0"; closeCommand = "TerrainMaterialDlg.dialogCancel();"; - EdgeSnap = "0"; - text = "Terrain Materials Editor"; - new GuiContainer(){ //Node Properties - isContainer = "1"; - Profile = "inspectorStyleRolloutDarkProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - Position = "6 25"; - Extent = "189 64"; - - new GuiTextCtrl(){ - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - Position = "5 0"; - Extent = "91 18"; - text = "Terrain Materials"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "top"; - position = "160 2"; - Extent = "15 15"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.newMat();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/gui/images/new"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "top"; - position = "173 2"; - Extent = "15 15"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.deleteMat();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/gui/images/delete"; - }; - }; + edgeSnap = "0"; + docking = "None"; + margin = "4 4 4 4"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "315 168"; + extent = "394 432"; + minExtent = "358 432"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + new GuiContainer() { - canSaveDynamicFields = "0"; - internalName = "matSettingsParent"; - isContainer = "1"; - Profile = "inspectorStyleRolloutProfile"; - HorizSizing = "left"; - VertSizing = "height"; - position = "202 26"; - Extent = "185 363"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 25"; + extent = "189 64"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "inspectorStyleRolloutDarkProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; - new GuiBitmapCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "1 0"; - Extent = "183 2"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "core/art/gui/images/separator-v"; - wrap = "0"; - }; new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "8 22"; - Extent = "44 17"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiDefaultProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Name"; + text = "Terrain Materials"; maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "matNameCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "39 21"; - Extent = "143 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; - altCommand = "TerrainMaterialDlg.setMaterialName( $ThisControl.getText() );"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiInspectorTitleTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "8 0"; - Extent = "117 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Material Properties"; - maxLength = "1024"; - }; - new GuiContainer() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "6 43"; - Extent = "185 75"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - - new GuiCheckBoxCtrl() { - internalName = "sideProjectionCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiCheckBoxProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "55 54"; - Extent = "119 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - text = " Use Side Projection"; - groupNum = "-1"; - buttonType = "ToggleButton"; - useMouseEvents = "0"; - useInactiveState = "0"; - }; - new GuiBitmapCtrl() { - internalName = "baseTexCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "47 47"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "tools/materialEditor/gui/unknownImage"; - wrap = "0"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "48 48"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeBase();"; - tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Change the Active Diffuse Map for this layer"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "EditorTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "56 -3"; - Extent = "39 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Diffuse"; - maxLength = "1024"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "56 16"; - Extent = "116 17"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "None"; - maxLength = "1024"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "116 0"; - Extent = "40 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeBase();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "159 0"; - Extent = "16 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg-->baseTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/gui/images/delete"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "132 35"; - Extent = "39 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - text = "Size"; - maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "baseSizeCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "94 34"; - Extent = "34 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; - }; - }; - new GuiBitmapCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "6 116"; - Extent = "175 2"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "tools/gui/images/separator-v"; - wrap = "0"; - }; - new GuiContainer() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "6 295"; - Extent = "185 50"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - - new GuiBitmapCtrl() { - internalName = "normTexCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "47 47"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "tools/materialEditor/gui/unknownImage"; - wrap = "0"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "EditorTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "56 -3"; - Extent = "39 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Normal"; - maxLength = "1024"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "48 48"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeNormal();"; - tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Change the active Normal Map for this layer."; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "56 15"; - Extent = "116 17"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "None"; - maxLength = "1024"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "116 0"; - Extent = "40 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeNormal();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "159 0"; - Extent = "16 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg-->normTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/gui/images/delete"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "92 34"; - Extent = "77 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Parallax Scale"; - maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "parallaxScaleCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "55 33"; - Extent = "34 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - text = "0.00"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; - }; - }; - - new GuiBitmapCtrl() { - bitmap = "tools/gui/images/separator-v"; - wrap = "0"; - position = "6 288"; - extent = "175 2"; - minExtent = "8 2"; - horizSizing = "width"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiContainer() { margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "6 122"; - extent = "185 72"; + position = "5 0"; + extent = "91 18"; minExtent = "8 2"; - horizSizing = "width"; + horizSizing = "right"; vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; visible = "1"; active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/new"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "160 2"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.newMat();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "173 2"; + extent = "15 15"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.deleteMat();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "202 26"; + extent = "185 363"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "height"; + profile = "inspectorStyleRolloutProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "matSettingsParent"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Name"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "8 22"; + extent = "44 17"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiDefaultProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "sand"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "39 21"; + extent = "143 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + altCommand = "TerrainMaterialDlg.setMaterialName( $ThisControl.getText() );"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "matNameCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Material Properties"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "8 0"; + extent = "117 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiInspectorTitleTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiScrollCtrl() { + willFirstRespond = "1"; + hScrollBar = "dynamic"; + vScrollBar = "dynamic"; + lockHorizScroll = "1"; + lockVertScroll = "0"; + constantThumbHeight = "0"; + childMargin = "0 0"; + mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 45"; + extent = "189 329"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; - new GuiBitmapCtrl() { - bitmap = "tools/materialEditor/gui/unknownImage"; - wrap = "0"; - position = "1 1"; - extent = "47 47"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "macroTexCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiBitmapButtonCtrl() { - bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "1 1"; - extent = "48 48"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - command = "TerrainMaterialDlg.changeMacro();"; - tooltipProfile = "ToolsGuiDefaultProfile"; - tooltip = "Change the active Macro Map for this layer."; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Macro"; - maxLength = "1024"; + new GuiContainer() { margin = "0 0 0 0"; padding = "0 0 0 0"; anchorTop = "1"; anchorBottom = "0"; anchorLeft = "1"; anchorRight = "0"; - position = "56 -3"; - extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "EditorTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "None"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "1"; - anchorBottom = "0"; - anchorLeft = "1"; - anchorRight = "0"; - position = "56 17"; - extent = "116 17"; + position = "1 1"; + extent = "174 73"; minExtent = "8 2"; horizSizing = "width"; vertSizing = "bottom"; - profile = "ToolsGuiTextProfile"; + profile = "ToolsGuiDefaultProfile"; visible = "1"; active = "1"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; - isContainer = "0"; + isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; + + new GuiCheckBoxCtrl() { + text = " Use Side Projection"; + groupNum = "-1"; + buttonType = "ToggleButton"; + useMouseEvents = "0"; + position = "55 54"; + extent = "119 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiCheckBoxProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "sideProjectionCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "art/terrains/Example/sand"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "baseTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeBase();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the Active Diffuse Map for this layer"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Diffuse"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "39 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 16"; + extent = "79 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "110 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeBase();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "153 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->baseTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 35"; + extent = "39 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "200"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 34"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "baseSizeCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 71"; + extent = "148 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; - new GuiButtonCtrl() { - text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "116 0"; - extent = "40 16"; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "4 78"; + extent = "174 76"; minExtent = "8 2"; - horizSizing = "left"; - vertSizing = "bottom"; - profile = "ToolsGuiButtonProfile"; - visible = "1"; - active = "1"; - command = "TerrainMaterialDlg.changeMacro();"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiBitmapButtonCtrl() { - bitmap = "tools/gui/images/delete"; - bitmapMode = "Stretched"; - autoFitExtents = "0"; - useModifiers = "0"; - useStates = "1"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - position = "159 0"; - extent = "16 16"; - minExtent = "8 2"; - horizSizing = "left"; + horizSizing = "width"; vertSizing = "bottom"; profile = "ToolsGuiDefaultProfile"; visible = "1"; active = "1"; - command = "TerrainMaterialDlg-->macroTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; - isContainer = "0"; + isContainer = "1"; canSave = "1"; canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Size"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "132 33"; - extent = "39 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "94 32"; - extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "macroSizeCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Strength"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "39 54"; - extent = "46 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "1 53"; - extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "macroStrengthCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Distance"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "132 54"; - extent = "45 16"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - new GuiTextEditCtrl() { - historySize = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - password = "0"; - passwordMask = "*"; - maxLength = "1024"; - margin = "0 0 0 0"; - padding = "0 0 0 0"; - anchorTop = "0"; - anchorBottom = "0"; - anchorLeft = "0"; - anchorRight = "0"; - position = "94 53"; - extent = "34 18"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiTextEditProfile"; - visible = "1"; - active = "1"; - tooltipProfile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - isContainer = "0"; - internalName = "macroDistanceCtrl"; - canSave = "1"; - canSaveDynamicFields = "0"; - }; - }; - - new GuiBitmapCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "6 200"; - Extent = "175 2"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "tools/gui/images/separator-v"; - wrap = "0"; - }; - new GuiContainer() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "6 206"; - Extent = "185 72"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - new GuiBitmapCtrl() { - internalName = "detailTexCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "47 47"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - bitmap = "tools/materialEditor/gui/unknownImage"; - wrap = "0"; + new GuiBitmapCtrl() { + bitmap = "art/terrains/Example/sand_d"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detailTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeDetail();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the active Detail Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Detail"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "30 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 16"; + extent = "79 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeDetail();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "154 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->detailTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 33"; + extent = "39 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "10"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 32"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detSizeCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "39 54"; + extent = "46 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "1 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detStrengthCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Distance"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 54"; + extent = "45 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "100"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "detDistanceCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "core/art/gui/images/separator-v"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 73"; + extent = "148 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; - new GuiBitmapButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "48 48"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeDetail();"; - tooltipprofile = "ToolsGuiDefaultProfile"; - ToolTip = "Change the active Detail Map for this layer."; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 158"; + extent = "174 54"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialEditor/gui/unknownImage"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "normTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Normal"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "39 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeNormal();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the active Normal Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 15"; + extent = "79 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeNormal();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "154 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->normTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Parallax Scale"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "92 34"; + extent = "77 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "55 33"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "parallaxScaleCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + color = "255 255 255 255"; + wrap = "0"; + position = "-10 53"; + extent = "148 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "EditorTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "56 -3"; - Extent = "30 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 216"; + extent = "174 53"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "Detail"; - maxLength = "1024"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialEditor/gui/unknownImage"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "compositeTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changecomposite();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the active composite Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Composite"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "61 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "79 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changecomposite();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "154 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->compositeTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapCtrl() { + bitmap = "tools/gui/images/separator-v"; + color = "255 255 255 255"; + wrap = "0"; + position = "4 51"; + extent = "148 2"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "width"; - VertSizing = "bottom"; - position = "56 16"; - Extent = "116 17"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; + new GuiContainer() { + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 272"; + extent = "174 71"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - text = "None"; - maxLength = "1024"; - }; - new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "116 0"; - Extent = "40 16"; - MinExtent = "8 2"; + isContainer = "1"; canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.changeDetail();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - text = "Edit"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - }; - new GuiBitmapButtonCtrl() { canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "left"; - VertSizing = "bottom"; - position = "159 0"; - Extent = "16 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg-->detailTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - groupNum = "-1"; - buttonType = "PushButton"; - useMouseEvents = "0"; - bitmap = "tools/gui/images/delete"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "132 33"; - Extent = "39 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - text = "Size"; - maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "detSizeCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "94 32"; - Extent = "34 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "39 54"; - Extent = "46 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - text = "Strength"; - maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "detStrengthCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 53"; - Extent = "34 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; - }; - new GuiTextCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "132 54"; - Extent = "45 16"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - text = "Distance"; - maxLength = "1024"; - }; - new GuiTextEditCtrl() { - internalName = "detDistanceCtrl"; - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiTextEditProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "94 53"; - Extent = "34 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "0"; - AnchorBottom = "0"; - AnchorLeft = "0"; - AnchorRight = "0"; - maxLength = "1024"; - historySize = "0"; - password = "0"; - tabComplete = "0"; - sinkAllKeyEvents = "0"; - passwordMask = "*"; + + new GuiBitmapCtrl() { + bitmap = "tools/materialEditor/gui/unknownImage"; + color = "255 255 255 255"; + wrap = "0"; + position = "1 1"; + extent = "47 47"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroTexCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/materialEditor/gui/cubemapBtnBorder"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "1 1"; + extent = "48 48"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeMacro();"; + tooltipProfile = "ToolsGuiDefaultProfile"; + tooltip = "Change the active Macro Map for this layer."; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Macro"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 -3"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "EditorTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "None"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "56 17"; + extent = "111 17"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl() { + text = "Edit"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "111 0"; + extent = "40 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.changeMacro();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiBitmapButtonCtrl() { + bitmap = "tools/gui/images/delete"; + bitmapMode = "Stretched"; + autoFitExtents = "0"; + useModifiers = "0"; + useStates = "1"; + masked = "0"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "154 0"; + extent = "16 16"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "bottom"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg-->macroTexCtrl.setBitmap(\"tools/materialEditor/gui/unknownImage\");"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Size"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 33"; + extent = "39 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "200"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 32"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroSizeCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Strength"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "39 54"; + extent = "46 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "0.7"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "1 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroStrengthCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Distance"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "132 54"; + extent = "45 16"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl() { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "500"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "0"; + anchorBottom = "0"; + anchorLeft = "0"; + anchorRight = "0"; + position = "94 53"; + extent = "34 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + internalName = "macroDistanceCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; }; }; new GuiControl() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "width"; - VertSizing = "height"; position = "6 42"; - Extent = "189 373"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; + extent = "189 373"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; new GuiScrollCtrl() { - canSaveDynamicFields = "0"; - isContainer = "1"; - Profile = "ToolsGuiScrollProfile"; - HorizSizing = "width"; - VertSizing = "height"; - position = "0 0"; - Extent = "189 374"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; willFirstRespond = "1"; hScrollBar = "dynamic"; vScrollBar = "dynamic"; - lockHorizScroll = "false"; - lockVertScroll = "false"; + lockHorizScroll = "0"; + lockVertScroll = "0"; constantThumbHeight = "0"; childMargin = "0 0"; mouseWheelScrollSpeed = "-1"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 -1"; + extent = "189 374"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "height"; + profile = "ToolsGuiScrollProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; new GuiTreeViewCtrl() { - internalName = "matLibTree"; - canSaveDynamicFields = "0"; - class = "TerrainMaterialTreeCtrl"; - className = "TerrainMaterialTreeCtrl"; - isContainer = "1"; - Profile = "ToolsGuiTreeViewProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "1 1"; - Extent = "125 84"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; tabSize = "16"; textOffset = "2"; fullRowSelect = "0"; itemHeight = "21"; destroyTreeOnSleep = "1"; - MouseDragging = "0"; - MultipleSelections = "0"; - DeleteObjectAllowed = "0"; - DragToItemAllowed = "0"; - ClearAllOnSingleSelection = "1"; + mouseDragging = "0"; + multipleSelections = "0"; + deleteObjectAllowed = "0"; + dragToItemAllowed = "0"; + clearAllOnSingleSelection = "1"; showRoot = "0"; - internalNamesOnly = "1"; - objectNamesOnly = "0"; + useInspectorTooltips = "0"; + tooltipOnWidthOnly = "0"; + showObjectIds = "0"; + showClassNames = "0"; + showObjectNames = "0"; + showInternalNames = "1"; + showClassNameForUnnamedObjects = "0"; + compareToObjectID = "1"; + canRenameObjects = "1"; + renameInternal = "0"; + position = "1 1"; + extent = "109 147"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "ToolsGuiTreeViewProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "matLibTree"; + class = "TerrainMaterialTreeCtrl"; + canSave = "1"; + canSaveDynamicFields = "0"; }; }; }; new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "top"; - position = "202 394"; - Extent = "98 22"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.dialogApply();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; text = "Apply&Select"; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; + position = "202 394"; + extent = "98 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.dialogApply();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; }; new GuiButtonCtrl() { - canSaveDynamicFields = "0"; - isContainer = "0"; - Profile = "ToolsGuiButtonProfile"; - HorizSizing = "left"; - VertSizing = "top"; - position = "307 394"; - Extent = "80 22"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "TerrainMaterialDlg.dialogCancel();"; - tooltipprofile = "ToolsGuiToolTipProfile"; - hovertime = "1000"; text = "Cancel"; groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; + position = "307 394"; + extent = "80 22"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "top"; + profile = "ToolsGuiButtonProfile"; + visible = "1"; + active = "1"; + command = "TerrainMaterialDlg.dialogCancel();"; + tooltipProfile = "ToolsGuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; }; - - new GuiBitmapCtrl() { // inactive overlay - internalName = "inactiveOverlay"; - Profile = "ToolsGuiDefaultProfile"; - HorizSizing = "left"; - VertSizing = "height"; - position = "199 23"; - Extent = "190 267"; - isContainer = true; - Visible = false; + new GuiBitmapCtrl() { bitmap = "tools/gui/images/inactive-overlay"; - - new GuiTextCtrl(){ - internalName = "inactiveOverlayDlg"; - Profile = "ToolsGuiTextCenterProfile"; - HorizSizing = "width"; - VertSizing = "center"; - position = "0 104"; - Extent = "190 64"; + color = "255 255 255 255"; + wrap = "0"; + position = "199 23"; + extent = "190 267"; + minExtent = "8 2"; + horizSizing = "left"; + vertSizing = "height"; + profile = "ToolsGuiDefaultProfile"; + visible = "0"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "inactiveOverlay"; + hidden = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { text = "Inactive"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "0 104"; + extent = "190 64"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "center"; + profile = "ToolsGuiTextCenterProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "inactiveOverlayDlg"; + canSave = "1"; + canSaveDynamicFields = "0"; }; }; }; diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui index fce36e940..ef7ff4dca 100644 --- a/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui +++ b/Templates/BaseGame/game/tools/worldEditor/gui/objectBuilderGui.ed.gui @@ -877,6 +877,24 @@ function ObjectBuilderGui::buildParticleSimulation(%this) %this.process(); } +function ObjectBuilderGui::buildReflectionProbe(%this) +{ + %this.objectClassName = "ReflectionProbe"; + %this.process(); + + %defaultPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + %this.addField("reflectionPath", "TypeFilepath", "reflectionPath", %defaultPath); +} + +function ObjectBuilderGui::buildSkylight(%this) +{ + %this.objectClassName = "Skylight"; + %this.process(); + + %defaultPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + %this.addField("reflectionPath", "TypeFilepath", "reflectionPath", %defaultPath); +} + //------------------------------------------------------------------------------ // Mission //------------------------------------------------------------------------------ diff --git a/Templates/BaseGame/game/tools/worldEditor/gui/probeBakeDlg.gui b/Templates/BaseGame/game/tools/worldEditor/gui/probeBakeDlg.gui new file mode 100644 index 000000000..6f4c10d77 --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/gui/probeBakeDlg.gui @@ -0,0 +1,192 @@ +//--- OBJECT WRITE BEGIN --- +%guiContent = new GuiControl(ProbeBakeDlg) { + position = "0 0"; + extent = "1024 768"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "1"; + + new GuiWindowCtrl() { + text = "Update Environment Probes"; + resizeWidth = "0"; + resizeHeight = "0"; + canMove = "1"; + canClose = "1"; + canMinimize = "0"; + canMaximize = "0"; + canCollapse = "0"; + closeCommand = "Canvas.popDialog(ProbeBakeDlg);"; + edgeSnap = "0"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "392 314"; + extent = "270 164"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiWindowProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiTextCtrl() { + text = "Probe Resolution"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 32"; + extent = "91 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiPopUpMenuCtrl(ProbeBakeDlg_ProbeResList) { + maxPopupHeight = "200"; + sbUsesNAColor = "0"; + reverseTextList = "0"; + bitmapBounds = "16 16"; + text = "64"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "103 29"; + extent = "157 19"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiPopUpMenuProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Number of bake iterations"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "11 56"; + extent = "129 13"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextEditCtrl(ProbeBakeDlg_NumIterTxt) { + historySize = "0"; + tabComplete = "0"; + sinkAllKeyEvents = "0"; + password = "0"; + passwordMask = "*"; + text = "1"; + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "150 53"; + extent = "108 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextEditProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiButtonCtrl(ProbeBakeDlg_RunBake) { + text = "Update Probes"; + groupNum = "-1"; + buttonType = "PushButton"; + useMouseEvents = "0"; + position = "68 120"; + extent = "140 30"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiButtonProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiProgressCtrl(ProbeBakeDlg_Progress) { + maxLength = "1024"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "8 80"; + extent = "251 25"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiProgressProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/tools/worldEditor/main.cs b/Templates/BaseGame/game/tools/worldEditor/main.cs index 5d337cdf1..8596f2421 100644 --- a/Templates/BaseGame/game/tools/worldEditor/main.cs +++ b/Templates/BaseGame/game/tools/worldEditor/main.cs @@ -44,6 +44,7 @@ function initializeWorldEditor() exec("./gui/SelectObjectsWindow.ed.gui"); exec("./gui/ProceduralTerrainPainterGui.gui" ); exec("./gui/shadowViz.gui" ); + exec("./gui/probeBakeDlg.gui" ); // Load Scripts. exec("./scripts/menus.ed.cs"); @@ -66,6 +67,7 @@ function initializeWorldEditor() exec("./scripts/cameraCommands.ed.cs"); exec("./scripts/lightViz.cs"); exec("./scripts/shadowViz.cs"); + exec("./scripts/probeBake.ed.cs"); // Load Custom Editors loadDirectory(expandFilename("./scripts/editors")); @@ -120,16 +122,24 @@ function initializeWorldEditor() EVisibility.addOption( "Debug Render: Light Frustums", "$Light::renderLightFrustums", "" ); EVisibility.addOption( "Debug Render: Bounding Boxes", "$Scene::renderBoundingBoxes", "" ); EVisibility.addOption( "Debug Render: Physics World", "$PhysicsWorld::render", "togglePhysicsDebugViz" ); + EVisibility.addOption( "Debug Render: Reflection Probes", "$Light::renderReflectionProbes", "" ); + EVisibility.addOption( "Debug Render: Probe Previews", "$Light::renderPreviewProbes", "" ); EVisibility.addOption( "AL: Disable Shadows", "$Shadows::disable", "" ); - EVisibility.addOption( "AL: Light Color Viz", "$AL_LightColorVisualizeVar", "toggleLightColorViz" ); - EVisibility.addOption( "AL: Light Specular Viz", "$AL_LightSpecularVisualizeVar", "toggleLightSpecularViz" ); + EVisibility.addOption( "AL: Diffuse Lighting Viz", "$AL_LightColorVisualizeVar", "toggleLightColorViz" ); + EVisibility.addOption( "AL: Specular Lighting Viz", "$AL_LightSpecularVisualizeVar", "toggleLightSpecularViz" ); EVisibility.addOption( "AL: Normals Viz", "$AL_NormalsVisualizeVar", "toggleNormalsViz" ); EVisibility.addOption( "AL: Depth Viz", "$AL_DepthVisualizeVar", "toggleDepthViz" ); EVisibility.addOption( "AL: Color Buffer", "$AL_ColorBufferShaderVar", "toggleColorBufferViz" ); - EVisibility.addOption( "AL: Spec Map", "$AL_SpecMapShaderVar", "toggleSpecMapViz"); + EVisibility.addOption( "AL: Spec Map(Rough)", "$AL_RoughMapShaderVar", "toggleRoughMapViz"); + EVisibility.addOption( "AL: Spec Map(Metal)", "$AL_MetalMapShaderVar", "toggleMetalMapViz"); EVisibility.addOption( "AL: Backbuffer", "$AL_BackbufferVisualizeVar", "toggleBackbufferViz" ); EVisibility.addOption( "AL: Glow Buffer", "$AL_GlowVisualizeVar", "toggleGlowViz" ); EVisibility.addOption( "AL: PSSM Cascade Viz", "$AL::PSSMDebugRender", "" ); + EVisibility.addOption( "Probes: Attenuation", "$Probes::showAttenuation", "" ); + EVisibility.addOption( "Probes: Specular Cubemaps", "$Probes::showSpecularCubemaps", "" ); + EVisibility.addOption( "Probes: Diffuse Cubemaps", "$Probes::showDiffuseCubemaps", "" ); + EVisibility.addOption( "Probes: Contribution", "$Probes::showProbeContrib", "" ); + EVisibility.addOption( "Frustum Lock", "$Scene::lockCull", "" ); EVisibility.addOption( "Disable Zone Culling", "$Scene::disableZoneCulling", "" ); EVisibility.addOption( "Disable Terrain Occlusion", "$Scene::disableTerrainOcclusion", "" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs index 912ff7a35..e86dfd7e7 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -55,6 +55,11 @@ function EWCreatorWindow::init( %this ) %this.registerMissionObject( "PointLight", "Point Light" ); %this.registerMissionObject( "SpotLight", "Spot Light" ); + + %this.registerMissionObject( "BoxEnvironmentProbe", "Box Environment Probe" ); + %this.registerMissionObject( "SphereEnvironmentProbe", "Sphere Environment Probe" ); + %this.registerMissionObject( "Skylight", "Skylight" ); + %this.registerMissionObject( "GroundCover", "Ground Cover" ); %this.registerMissionObject( "TerrainBlock", "Terrain Block" ); %this.registerMissionObject( "GroundPlane", "Ground Plane" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs index 2ec8e17f3..2a5f12a5c 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/interfaces/terrainMaterialDlg.ed.cs @@ -294,6 +294,28 @@ function TerrainMaterialDlg::changeNormal( %this ) //----------------------------------------------------------------------------- +function TerrainMaterialDlg::changecomposite( %this ) +{ + %ctrl = %this-->compositeTexCtrl; + %file = %ctrl.bitmap; + if( getSubStr( %file, 0 , 6 ) $= "tools/" ) + %file = ""; + + %file = TerrainMaterialDlg._selectTextureFileDialog( %file ); + if( %file $= "" ) + { + if( %ctrl.bitmap !$= "" ) + %file = %ctrl.bitmap; + else + %file = "tools/materialEditor/gui/unknownImage"; + } + + %file = makeRelativePath( %file, getMainDotCsDir() ); + %ctrl.setBitmap( %file ); +} + +//----------------------------------------------------------------------------- + function TerrainMaterialDlg::newMat( %this ) { // Create a unique material name. @@ -394,7 +416,12 @@ function TerrainMaterialDlg::setActiveMaterial( %this, %mat ) %this-->normTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); }else{ %this-->normTexCtrl.setBitmap( %mat.normalMap ); - } + } + if (%mat.compositeMap $= ""){ + %this-->compositeTexCtrl.setBitmap( "tools/materialEditor/gui/unknownImage" ); + }else{ + %this-->compositeTexCtrl.setBitmap( %mat.compositeMap ); + } %this-->detSizeCtrl.setText( %mat.detailSize ); %this-->baseSizeCtrl.setText( %mat.diffuseSize ); %this-->detStrengthCtrl.setText( %mat.detailStrength ); @@ -448,6 +475,11 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) }else{ %newMacro = %this-->macroTexCtrl.bitmap; } + if (%this-->compositeTexCtrl.bitmap $= "tools/materialEditor/gui/unknownImage"){ + %newComposite = ""; + }else{ + %newComposite = %this-->compositeTexCtrl.bitmap; + } %detailSize = %this-->detSizeCtrl.getText(); %diffuseSize = %this-->baseSizeCtrl.getText(); %detailStrength = %this-->detStrengthCtrl.getText(); @@ -466,6 +498,7 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) %mat.diffuseMap $= %newDiffuse && %mat.normalMap $= %newNormal && %mat.detailMap $= %newDetail && + %mat.compositeMap $= %newComposite && %mat.macroMap $= %newMacro && %mat.detailSize == %detailSize && %mat.diffuseSize == %diffuseSize && @@ -497,7 +530,8 @@ function TerrainMaterialDlg::saveDirtyMaterial( %this, %mat ) } %mat.diffuseMap = %newDiffuse; - %mat.normalMap = %newNormal; + %mat.normalMap = %newNormal; + %mat.compositeMap = %newComposite; %mat.detailMap = %newDetail; %mat.macroMap = %newMacro; %mat.detailSize = %detailSize; @@ -544,6 +578,7 @@ function TerrainMaterialDlg::snapshotMaterials( %this ) diffuseMap = %mat.diffuseMap; normalMap = %mat.normalMap; detailMap = %mat.detailMap; + compositeMap = %mat.compositeMap; macroMap = %mat.macroMap; detailSize = %mat.detailSize; diffuseSize = %mat.diffuseSize; @@ -578,6 +613,7 @@ function TerrainMaterialDlg::restoreMaterials( %this ) %mat.diffuseMap = %obj.diffuseMap; %mat.normalMap = %obj.normalMap; %mat.detailMap = %obj.detailMap; + %mat.compositeMap = %obj.compositeMap; %mat.macroMap = %obj.macroMap; %mat.detailSize = %obj.detailSize; %mat.diffuseSize = %obj.diffuseSize; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/lightViz.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/lightViz.cs index 574063460..ebfc22e44 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/lightViz.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/lightViz.cs @@ -61,39 +61,109 @@ function toggleColorBufferViz( %enable ) } } -new ShaderData( AL_SpecMapShader ) +//roughness map display (matinfo.b) +new ShaderData( AL_RoughMapShader ) { - DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl"; - DXPixelShaderFile = "./shaders/dbgSpecMapVisualizeP.hlsl"; + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgRoughMapVisualizeP.hlsl"; - OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl"; - OGLPixelShaderFile = "./shaders/dbgSpecMapVisualizeP.glsl"; + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgRoughMapVisualizeP.glsl"; samplerNames[0] = "matinfoTex"; pixVersion = 2.0; }; -singleton PostEffect( AL_SpecMapVisualize ) +singleton PostEffect( AL_RoughMapVisualize ) { - shader = AL_SpecMapShader; + shader = AL_RoughMapShader; stateBlock = AL_DefaultVisualizeState; texture[0] = "#matinfo"; target = "$backBuffer"; renderPriority = 9999; }; -/// Toggles the visualization of the AL lighting specular power buffer. -function toggleSpecMapViz( %enable ) +function toggleRoughMapViz( %enable ) { if ( %enable $= "" ) { - $AL_SpecMapShaderVar = AL_SpecMapVisualize.isEnabled() ? false : true; - AL_SpecMapVisualize.toggle(); + $AL_RoughMapShaderVar = AL_RoughMapVisualize.isEnabled() ? false : true; + AL_RoughMapVisualize.toggle(); } else if ( %enable ) - AL_SpecMapVisualize.enable(); + AL_RoughMapVisualize.enable(); else if ( !%enable ) - AL_SpecMapVisualize.disable(); + AL_RoughMapVisualize.disable(); +} + +//metalness map display (matinfo.a) +new ShaderData( AL_MetalMapShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgMetalMapVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgMetalMapVisualizeP.glsl"; + + samplerNames[0] = "matinfoTex"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_MetalMapVisualize ) +{ + shader = AL_MetalMapShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#matinfo"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function toggleMetalMapViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_MetalMapShaderVar = AL_MetalMapVisualize.isEnabled() ? false : true; + AL_MetalMapVisualize.toggle(); + } + else if ( %enable ) + AL_MetalMapVisualize.enable(); + else if ( !%enable ) + AL_MetalMapVisualize.disable(); +} + +//Light map display (indirectLighting) +new ShaderData( AL_LightMapShader ) +{ + DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl"; + DXPixelShaderFile = "shaders/common/lighting/advanced/dbgLightMapVisualizeP.hlsl"; + + OGLVertexShaderFile = "shaders/common/postFx/gl/postFxV.glsl"; + OGLPixelShaderFile = "shaders/common/lighting/advanced/gl/dbgLightMapVisualizeP.glsl"; + + samplerNames[0] = "specularLightingBuffer"; + pixVersion = 2.0; +}; + +singleton PostEffect( AL_LightMapVisualize ) +{ + shader = AL_LightMapShader; + stateBlock = AL_DefaultVisualizeState; + texture[0] = "#specularLighting"; + target = "$backBuffer"; + renderPriority = 9999; +}; + +function toggleLightMapViz( %enable ) +{ + if ( %enable $= "" ) + { + $AL_LightMapShaderVar = AL_LightMapVisualize.isEnabled() ? false : true; + AL_LightMapVisualize.toggle(); + } + else if ( %enable ) + AL_LightMapVisualize.enable(); + else if ( !%enable ) + AL_LightMapVisualize.disable(); } new GFXStateBlockData( AL_DepthVisualizeState ) diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs index 8886b8eb9..c77e1ba10 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/lighting.ed.cs @@ -61,3 +61,8 @@ function EditorLightingMenu::onMenuSelect( %this ) //%selSize = EWorldEditor.getSelectionSize(); %this.enableItem( 1, true /*%selSize == 1*/ ); } + +function updateReflectionProbes() +{ + Canvas.pushDialog(ProbeBakeDlg); +} \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs index bb5f9cf4d..7f87df251 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs @@ -322,6 +322,8 @@ function EditorGui::buildMenus(%this) item[0] = "Full Relight" TAB "Alt L" TAB "Editor.lightScene(\"\", forceAlways);"; item[1] = "Toggle ShadowViz" TAB "" TAB "toggleShadowViz();"; item[2] = "-"; + item[3] = "Update Reflection Probes" TAB "" TAB "updateReflectionProbes();"; + item[4] = "-"; // NOTE: The light managers will be inserted as the // last menu items in EditorLightingMenu::onAdd(). diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs new file mode 100644 index 000000000..9c561e0bf --- /dev/null +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/probeBake.ed.cs @@ -0,0 +1,56 @@ +function ProbeBakeDlg::onWake(%this) +{ + //set up + ProbeBakeDlg_ProbeResList.add( "32" ); + ProbeBakeDlg_ProbeResList.add( "64" ); + ProbeBakeDlg_ProbeResList.add( "128" ); + ProbeBakeDlg_ProbeResList.add( "256" ); + ProbeBakeDlg_ProbeResList.add( "512" ); + ProbeBakeDlg_ProbeResList.add( "1024" ); + ProbeBakeDlg_ProbeResList.add( "2048" ); + + ProbeBakeDlg_ProbeResList.setSelected( 1, false ); + + ProbeBakeDlg_NumIterTxt.setText("1"); +} + +function ProbeBakeDlg_RunBake::onClick(%this) +{ + %boxProbeIds = parseMissionGroupForIds("BoxEnvironmentProbe", ""); + %sphereProbeIds = parseMissionGroupForIds("SphereEnvironmentProbe", ""); + %skylightIds = parseMissionGroupForIds("Skylight", ""); + + %probeIds = rtrim(ltrim(%boxProbeIds SPC %sphereProbeIds)); + %probeIds = rtrim(ltrim(%probeIds SPC %skylightIds)); + %probeCount = getWordCount(%probeIds); + + %numIter = ProbeBakeDlg_NumIterTxt.getText(); + $pref::ReflectionProbes::BakeResolution = ProbeBakeDlg_ProbeResList.getText(); + %progressStep = 100 / (%numIter * %probeCount); + %currentProgressValue = 0; + + ProbeBakeDlg_Progress.setValue(%currentProgressValue); + Canvas.repaint(); + + for(%iter=0; %iter < %numIter; %iter++) + { + $pref::ReflectionProbes::RenderWithProbes = false; + + if(%iter != 0) + $pref::ReflectionProbes::RenderWithProbes = true; + + for(%i=0; %i < %probeCount; %i++) + { + %probe = getWord(%probeIds, %i); + + $pref::ReflectionProbes::CurrentLevelPath = filePath($Server::MissionFile) @ "/" @ fileBase($Server::MissionFile) @ "/probes/"; + ProbeBin.bakeProbe(%probe); + + %currentProgressValue += %progressStep; + ProbeBakeDlg_Progress.setValue(%currentProgressValue); + Canvas.repaint(); + } + } + + EWorldEditor.isDirty = true; +} \ No newline at end of file