diff --git a/Templates/BaseGame/game/core/Core.cs b/Templates/BaseGame/game/core/Core.cs
new file mode 100644
index 000000000..480c0331c
--- /dev/null
+++ b/Templates/BaseGame/game/core/Core.cs
@@ -0,0 +1,145 @@
+
+function CoreModule::onCreate(%this)
+{
+
+ // ----------------------------------------------------------------------------
+ // Initialize core sub system functionality such as audio, the Canvas, PostFX,
+ // rendermanager, light managers, etc.
+ //
+ // Note that not all of these need to be initialized before the client, although
+ // the audio should and the canvas definitely needs to be. I've put things here
+ // to distinguish between the purpose and functionality of the various client
+ // scripts. Game specific script isn't needed until we reach the shell menus
+ // and start a game or connect to a server. We get the various subsystems ready
+ // to go, and then use initClient() to handle the rest of the startup sequence.
+ //
+ // If this is too convoluted we can reduce this complexity after futher testing
+ // to find exactly which subsystems should be readied before kicking things off.
+ // ----------------------------------------------------------------------------
+
+ ModuleDatabase.LoadExplicit( "Core_Rendering" );
+ ModuleDatabase.LoadExplicit( "Core_Utility" );
+ ModuleDatabase.LoadExplicit( "Core_GUI" );
+ ModuleDatabase.LoadExplicit( "CoreModule" );
+ ModuleDatabase.LoadExplicit( "Core_Lighting" );
+ ModuleDatabase.LoadExplicit( "Core_SFX" );
+ ModuleDatabase.LoadExplicit( "Core_PostFX" );
+ ModuleDatabase.LoadExplicit( "Core_VR" );
+ ModuleDatabase.LoadExplicit( "Core_VR" );
+ ModuleDatabase.LoadExplicit( "Core_ClientServer" );
+
+ %prefPath = getPrefpath();
+ if ( isFile( %prefPath @ "/clientPrefs.cs" ) )
+ exec( %prefPath @ "/clientPrefs.cs" );
+ else
+ exec("data/defaults.cs");
+
+ %der = $pref::Video::displayDevice;
+
+ //We need to hook the missing/warn material stuff early, so do it here
+ /*$Core::MissingTexturePath = "core/images/missingTexture";
+ $Core::UnAvailableTexturePath = "core/images/unavailable";
+ $Core::WarningTexturePath = "core/images/warnMat";
+ $Core::CommonShaderPath = "core/shaders";
+
+ /*%classList = enumerateConsoleClasses( "Component" );
+
+ foreach$( %componentClass in %classList )
+ {
+ echo("Native Component of type: " @ %componentClass);
+ }*/
+
+ //exec("./helperFunctions.cs");
+
+ // We need some of the default GUI profiles in order to get the canvas and
+ // other aspects of the GUI system ready.
+ //exec("./profiles.cs");
+
+ //This is a bit of a shortcut, but we'll load the client's default settings to ensure all the prefs get initialized correctly
+
+
+ // Initialization of the various subsystems requires some of the preferences
+ // to be loaded... so do that first.
+ /*exec("./globals.cs");
+
+ exec("./canvas.cs");
+ exec("./cursor.cs");
+
+ exec("./renderManager.cs");
+ exec("./lighting.cs");
+
+ exec("./audio.cs");
+ exec("./sfx/audioAmbience.cs");
+ exec("./sfx/audioData.cs");
+ exec("./sfx/audioDescriptions.cs");
+ exec("./sfx/audioEnvironments.cs");
+ exec("./sfx/audioStates.cs");
+
+ exec("./parseArgs.cs");
+
+ // Materials and Shaders for rendering various object types
+ exec("./gfxData/commonMaterialData.cs");
+ exec("./gfxData/shaders.cs");
+ exec("./gfxData/terrainBlock.cs");
+ exec("./gfxData/water.cs");
+ exec("./gfxData/scatterSky.cs");
+ exec("./gfxData/clouds.cs");
+
+ // Initialize all core post effects.
+ exec("./postFx.cs");
+
+ //VR stuff
+ exec("./oculusVR.cs");*/
+
+ // Seed the random number generator.
+ setRandomSeed();
+
+ // Parse the command line arguments
+ echo("\n--------- Parsing Arguments ---------");
+ parseArgs();
+
+ // The canvas needs to be initialized before any gui scripts are run since
+ // some of the controls assume that the canvas exists at load time.
+ createCanvas($appName);
+
+ //load canvas
+ //exec("./console/main.cs");
+
+ ModuleDatabase.LoadExplicit( "Core_Console" );
+
+ // Init the physics plugin.
+ physicsInit();
+
+ sfxStartup();
+
+ // Set up networking.
+ setNetPort(0);
+
+ // Start processing file change events.
+ startFileChangeNotifications();
+
+ // If we have editors, initialize them here as well
+ if (isToolBuild())
+ {
+ if(isFile("tools/main.cs") && !$isDedicated)
+ exec("tools/main.cs");
+
+ ModuleDatabase.scanModules( "tools", false );
+ ModuleDatabase.LoadGroup( "Tools" );
+ }
+}
+
+function CoreModule::onDestroy(%this)
+{
+
+}
+
+//-----------------------------------------------------------------------------
+// Called when the engine is shutting down.
+function onExit()
+{
+ // Stop file change events.
+ stopFileChangeNotifications();
+
+ ModuleDatabase.UnloadExplicit( "Game" );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/Core.module b/Templates/BaseGame/game/core/Core.module
new file mode 100644
index 000000000..c7ab7b64b
--- /dev/null
+++ b/Templates/BaseGame/game/core/Core.module
@@ -0,0 +1,19 @@
+
+
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs
new file mode 100644
index 000000000..51a7fbe76
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.cs
@@ -0,0 +1,112 @@
+
+// The general flow of a gane - server's creation, loading and hosting clients, and then destruction is as follows:
+
+// First, a client will always create a server in the event that they want to host a single player
+// game. Torque3D treats even single player connections as a soft multiplayer game, with some stuff
+// in the networking short-circuited to sidestep around lag and packet transmission times.
+
+// initServer() is called, loading the default server scripts.
+// After that, if this is a dedicated server session, initDedicated() is called, otherwise initClient is called
+// to prep a playable client session.
+
+// When a local game is started - a listen server - via calling StartGame() a server is created and then the client is
+// connected to it via createAndConnectToLocalServer().
+
+function Core_ClientServer::create( %this )
+{
+ echo("\n--------- Initializing Directory: scripts ---------");
+ exec( "./scripts/client/client.cs" );
+ exec( "./scripts/server/server.cs" );
+
+ $Game::MissionGroup = "MissionGroup";
+
+ initServer();
+
+ %dbList = new ArrayObject(DatablockFilesList);
+
+ // Start up in either client, or dedicated server mode
+ if ($Server::Dedicated)
+ {
+ initDedicated();
+ }
+ else
+ {
+ initClient();
+ }
+}
+
+function Core_ClientServer::destroy( %this )
+{
+ // Ensure that we are disconnected and/or the server is destroyed.
+ // This prevents crashes due to the SceneGraph being deleted before
+ // the objects it contains.
+ if ($Server::Dedicated)
+ destroyServer();
+ else
+ disconnect();
+
+ // Destroy the physics plugin.
+ //physicsDestroy();
+
+ sfxShutdown();
+
+ echo("Exporting client prefs");
+ %prefPath = getPrefpath();
+ export("$pref::*", %prefPath @ "/clientPrefs.cs", false);
+
+ echo("Exporting server prefs");
+ export("$Pref::Server::*", %prefPath @ "/serverPrefs.cs", false);
+ BanList::Export(%prefPath @ "/banlist.cs");
+}
+
+//-----------------------------------------------------------------------------
+function StartGame( %mission, %hostingType )
+{
+ if( %mission $= "" )
+ {
+ %id = CL_levelList.getSelectedId();
+ %mission = getField(CL_levelList.getRowTextById(%id), 1);
+ //error("Cannot start a level with no level selected!");
+ }
+
+ if (%hostingType !$= "")
+ {
+ %serverType = %hostingType;
+ }
+ else
+ {
+ if ($pref::HostMultiPlayer)
+ %serverType = "MultiPlayer";
+ else
+ %serverType = "SinglePlayer";
+ }
+
+ // Show the loading screen immediately.
+ if ( isObject( LoadingGui ) )
+ {
+ Canvas.setContent("LoadingGui");
+ LoadingProgress.setValue(1);
+ LoadingProgressTxt.setValue("LOADING MISSION FILE");
+ Canvas.repaint();
+ }
+
+ createAndConnectToLocalServer( %serverType, %mission );
+}
+
+function JoinGame( %serverIndex )
+{
+ // The server info index is stored in the row along with the
+ // rest of displayed info.
+ if( setServerInfo( %serverIndex ) )
+ {
+ Canvas.setContent("LoadingGui");
+ LoadingProgress.setValue(1);
+ LoadingProgressTxt.setValue("WAITING FOR SERVER");
+ Canvas.repaint();
+
+ %conn = new GameConnection(ServerConnection);
+ %conn.setConnectArgs($pref::Player::Name);
+ %conn.setJoinPassword($Client::Password);
+ %conn.connect($ServerInfo::Address);
+ }
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/Core_ClientServer.module b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.module
new file mode 100644
index 000000000..ac86bbcd5
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/Core_ClientServer.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/client.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/client.cs
new file mode 100644
index 000000000..590119935
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/client/client.cs
@@ -0,0 +1,29 @@
+function initClient()
+{
+ echo("\n--------- Initializing " @ $appName @ ": Client Scripts ---------");
+
+ // Make sure this variable reflects the correct state.
+ $Server::Dedicated = false;
+
+ // Game information used to query the master server
+ $Client::GameTypeQuery = $appName;
+ $Client::MissionTypeQuery = "Any";
+
+ exec( "./message.cs" );
+ exec( "./connectionToServer.cs" );
+ exec( "./levelDownload.cs" );
+ exec( "./levelLoad.cs" );
+
+ //load prefs
+ %prefPath = getPrefpath();
+ if ( isFile( %prefPath @ "/clientPrefs.cs" ) )
+ exec( %prefPath @ "/clientPrefs.cs" );
+ else
+ exec( "data/defaults.cs" );
+
+ loadMaterials();
+
+ // Copy saved script prefs into C++ code.
+ setDefaultFov( $pref::Player::defaultFov );
+ setZoomSpeed( $pref::Player::zoomSpeed );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs
new file mode 100644
index 000000000..693c7fff7
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs
@@ -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.
+//-----------------------------------------------------------------------------
+
+// Functions dealing with connecting to a server
+
+//----------------------------------------------------------------------------
+// GameConnection client callbacks
+//----------------------------------------------------------------------------
+// Called on the new connection object after connect() succeeds.
+function GameConnection::onConnectionAccepted(%this)
+{
+ // Startup the physX world on the client before any
+ // datablocks and objects are ghosted over.
+ physicsInitWorld( "client" );
+}
+
+function GameConnection::initialControlSet(%this)
+{
+ echo ("*** Initial Control Object");
+
+ // The first control object has been set by the server
+ // and we are now ready to go.
+
+ // first check if the editor is active
+ if (!isToolBuild() || !isMethod("Editor", "checkActiveLoadDone") || !Editor::checkActiveLoadDone())
+ {
+ if (Canvas.getContent() != PlayGui.getId())
+ Canvas.setContent(PlayGui);
+ }
+}
+
+function GameConnection::onControlObjectChange(%this)
+{
+ echo ("*** Control Object Changed");
+
+ // Reset the current FOV to match the new object
+ // and turn off any current zoom.
+ resetCurrentFOV();
+ turnOffZoom();
+}
+
+function GameConnection::onConnectionError(%this, %msg)
+{
+ // General connection error, usually raised by ghosted objects
+ // initialization problems, such as missing files. We'll display
+ // the server's connection error message.
+ disconnectedCleanup();
+ MessageBoxOK( "DISCONNECT", $ServerConnectionErrorMessage @ " (" @ %msg @ ")" );
+}
+
+//-----------------------------------------------------------------------------
+// Server connection error
+//-----------------------------------------------------------------------------
+addMessageCallback( 'MsgConnectionError', handleConnectionErrorMessage );
+
+function handleConnectionErrorMessage(%msgType, %msgString, %msgError)
+{
+ // On connect the server transmits a message to display if there
+ // are any problems with the connection. Most connection errors
+ // are game version differences, so hopefully the server message
+ // will tell us where to get the latest version of the game.
+ $ServerConnectionErrorMessage = %msgError;
+}
+
+//-----------------------------------------------------------------------------
+// Disconnect
+//-----------------------------------------------------------------------------
+
+function disconnect()
+{
+ // We need to stop the client side simulation
+ // else physics resources will not cleanup properly.
+ physicsStopSimulation( "client" );
+
+ // Delete the connection if it's still there.
+ if (isObject(ServerConnection))
+ ServerConnection.delete();
+
+ disconnectedCleanup();
+
+ // Call destroyServer in case we're hosting
+ destroyServer();
+}
+
+function disconnectedCleanup()
+{
+ // End mission, if it's running.
+
+ if( $Client::missionRunning )
+ clientEndMission();
+
+ // Disable mission lighting if it's going, this is here
+ // in case we're disconnected while the mission is loading.
+
+ $lightingMission = false;
+ $sceneLighting::terminateLighting = true;
+
+ // Back to the launch screen
+ if (isObject( MainMenuGui ))
+ Canvas.setContent( MainMenuGui );
+
+ // Before we destroy the client physics world
+ // make sure all ServerConnection objects are deleted.
+ if(isObject(ServerConnection))
+ {
+ ServerConnection.deleteAllObjects();
+ }
+
+ // We can now delete the client physics simulation.
+ physicsDestroyWorld( "client" );
+}
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs
new file mode 100644
index 000000000..dd70e31ea
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/client/levelDownload.cs
@@ -0,0 +1,185 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Mission Loading
+// The client portion of the client/server mission loading process
+//-----------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// Loading Phases:
+// Phase 1: Transmit Datablocks
+// Transmit targets
+// Phase 2: Transmit Ghost Objects
+// Phase 3: Start Game
+//
+// The server invokes the client MissionStartPhase[1-3] function to request
+// permission to start each phase. When a client is ready for a phase,
+// it responds with MissionStartPhase[1-3]Ack.
+
+//----------------------------------------------------------------------------
+// Phase 1
+//----------------------------------------------------------------------------
+function clientCmdMissionStartPhase1(%seq, %missionName)
+{
+ // These need to come after the cls.
+ echo ("*** New Mission: " @ %missionName);
+ echo ("*** Phase 1: Download Datablocks & Targets");
+
+ //Prep the postFX stuff
+ // Load the post effect presets for this mission.
+ %path = filePath( %missionName ) @ "/" @ fileBase( %missionName ) @ $PostFXManager::fileExtension;
+
+ if ( isScriptFile( %path ) )
+ {
+ postFXManager::loadPresetHandler( %path );
+ }
+ else
+ {
+ PostFXManager::settingsApplyDefaultPreset();
+ }
+
+ onMissionDownloadPhase("LOADING DATABLOCKS");
+
+ commandToServer('MissionStartPhase1Ack', %seq);
+}
+
+function onDataBlockObjectReceived(%index, %total)
+{
+ onMissionDownloadProgress(%index / %total);
+}
+
+//----------------------------------------------------------------------------
+// Phase 2
+//----------------------------------------------------------------------------
+function clientCmdMissionStartPhase2(%seq,%missionName)
+{
+ onPhaseComplete();
+ echo ("*** Phase 2: Download Ghost Objects");
+
+ onMissionDownloadPhase("LOADING OBJECTS");
+
+ commandToServer('MissionStartPhase2Ack', %seq);
+}
+
+function onGhostAlwaysStarted(%ghostCount)
+{
+ $ghostCount = %ghostCount;
+ $ghostsRecvd = 0;
+}
+
+function onGhostAlwaysObjectReceived()
+{
+ $ghostsRecvd++;
+ onMissionDownloadProgress($ghostsRecvd / $ghostCount);
+}
+
+//----------------------------------------------------------------------------
+// Phase 3
+//----------------------------------------------------------------------------
+function clientCmdMissionStartPhase3(%seq,%missionName)
+{
+ onPhaseComplete();
+ StartClientReplication();
+ StartFoliageReplication();
+
+ // Load the static mission decals.
+ if(isFile(%missionName @ ".decals"))
+ decalManagerLoad( %missionName @ ".decals" );
+
+ echo ("*** Phase 3: Mission Lighting");
+ $MSeq = %seq;
+ $Client::MissionFile = %missionName;
+
+ // Need to light the mission before we are ready.
+ // The sceneLightingComplete function will complete the handshake
+ // once the scene lighting is done.
+ if (lightScene("sceneLightingComplete", ""))
+ {
+ echo("Lighting mission....");
+ schedule(1, 0, "updateLightingProgress");
+
+ onMissionDownloadPhase("LIGHTING MISSION");
+
+ $lightingMission = true;
+ }
+}
+
+function updateLightingProgress()
+{
+ onMissionDownloadProgress($SceneLighting::lightingProgress);
+ if ($lightingMission)
+ $lightingProgressThread = schedule(1, 0, "updateLightingProgress");
+}
+
+function sceneLightingComplete()
+{
+ echo("Mission lighting done");
+ $lightingMission = false;
+
+ onPhaseComplete("STARTING MISSION");
+
+ // The is also the end of the mission load cycle.
+ commandToServer('MissionStartPhase3Ack', $MSeq);
+}
+
+//----------------------------------------------------------------------------
+// Helper functions
+//----------------------------------------------------------------------------
+function connect(%server)
+{
+ %conn = new GameConnection(ServerConnection);
+ RootGroup.add(ServerConnection);
+ %conn.setConnectArgs($pref::Player::Name);
+ %conn.setJoinPassword($Client::Password);
+ %conn.connect(%server);
+}
+
+function onMissionDownloadPhase(%phase)
+{
+ if ( !isObject( LoadingProgress ) )
+ return;
+
+ LoadingProgress.setValue(0);
+ LoadingProgressTxt.setValue(%phase);
+ Canvas.repaint();
+}
+
+function onMissionDownloadProgress(%progress)
+{
+ if ( !isObject( LoadingProgress ) )
+ return;
+
+ LoadingProgress.setValue(%progress);
+ Canvas.repaint(33);
+}
+
+function onPhaseComplete(%text)
+{
+ if ( !isObject( LoadingProgress ) )
+ return;
+
+ if(%text !$= "")
+ LoadingProgressTxt.setValue(%text);
+
+ LoadingProgress.setValue( 1 );
+ Canvas.repaint();
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/levelLoad.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/levelLoad.cs
new file mode 100644
index 000000000..c3fd04280
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/client/levelLoad.cs
@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+// Whether the local client is currently running a mission.
+$Client::missionRunning = false;
+
+// Sequence number for currently running mission.
+$Client::missionSeq = -1;
+
+
+// Called when mission is started.
+function clientStartMission()
+{
+ // The client recieves a mission start right before
+ // being dropped into the game.
+ physicsStartSimulation( "client" );
+
+ // Start game audio effects channels.
+
+ AudioChannelEffects.play();
+
+ // Create client mission cleanup group.
+
+ new SimGroup( ClientMissionCleanup );
+
+ // Done.
+
+ $Client::missionRunning = true;
+}
+
+// Called when mission is ended (either through disconnect or
+// mission end client command).
+function clientEndMission()
+{
+ // Stop physics simulation on client.
+ physicsStopSimulation( "client" );
+
+ // Stop game audio effects channels.
+
+ AudioChannelEffects.stop();
+
+ // Delete all the decals.
+ decalManagerClear();
+
+ // Delete client mission cleanup group.
+ if( isObject( ClientMissionCleanup ) )
+ ClientMissionCleanup.delete();
+
+ clearClientPaths();
+
+ // Done.
+ $Client::missionRunning = false;
+}
+
+//----------------------------------------------------------------------------
+// Mission start / end events sent from the server
+//----------------------------------------------------------------------------
+
+function clientCmdMissionStart(%seq)
+{
+ clientStartMission();
+ $Client::missionSeq = %seq;
+}
+
+function clientCmdMissionEnd( %seq )
+{
+ if( $Client::missionRunning && $Client::missionSeq == %seq )
+ {
+ clientEndMission();
+ $Client::missionSeq = -1;
+ }
+}
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/message.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/message.cs
new file mode 100644
index 000000000..c532d50d9
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/client/message.cs
@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// Functions that process commands sent from the server.
+
+// Game event descriptions, which may or may not include text messages, can be
+// sent using the message* functions in core/scripts/server/message.cs. Those
+// functions do commandToClient with the tag ServerMessage, which invokes the
+// function below.
+
+// For ServerMessage messages, the client can install callbacks that will be
+// run, according to the "type" of the message.
+
+function clientCmdServerMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
+{
+ // Get the message type; terminates at any whitespace.
+ %tag = getWord(%msgType, 0);
+
+ // First see if there is a callback installed that doesn't have a type;
+ // if so, that callback is always executed when a message arrives.
+ for (%i = 0; (%func = $MSGCB["", %i]) !$= ""; %i++) {
+ call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10);
+ }
+
+ // Next look for a callback for this particular type of ServerMessage.
+ if (%tag !$= "") {
+ for (%i = 0; (%func = $MSGCB[%tag, %i]) !$= ""; %i++) {
+ call(%func, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10);
+ }
+ }
+}
+
+// Called by the client to install a callback for a particular type of
+// ServerMessage.
+function addMessageCallback(%msgType, %func)
+{
+ for (%i = 0; (%afunc = $MSGCB[%msgType, %i]) !$= ""; %i++) {
+ // If it already exists as a callback for this type,
+ // nothing to do.
+ if (%afunc $= %func) {
+ return;
+ }
+ }
+ // Set it up.
+ $MSGCB[%msgType, %i] = %func;
+}
+
+// The following is the callback that will be executed for every ServerMessage,
+// because we're going to install it without a specified type. Any type-
+// specific callbacks will be executed afterward.
+
+// This just invokes onServerMessage, which can be overridden by the game
+function onServerMessage(%a, %b, %c, %d, %e, %f, %g, %h, %i)
+{
+ echo("onServerMessage: ");
+ if(%a !$= "") echo(" +- a: " @ %a);
+ if(%b !$= "") echo(" +- b: " @ %b);
+ if(%c !$= "") echo(" +- c: " @ %c);
+ if(%d !$= "") echo(" +- d: " @ %d);
+ if(%e !$= "") echo(" +- e: " @ %e);
+ if(%f !$= "") echo(" +- f: " @ %f);
+ if(%g !$= "") echo(" +- g: " @ %g);
+ if(%h !$= "") echo(" +- h: " @ %h);
+ if(%i !$= "") echo(" +- i: " @ %i);
+}
+
+function defaultMessageCallback(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10)
+{
+ onServerMessage(detag(%msgString));
+}
+
+// Register that default message handler now.
+addMessageCallback("", defaultMessageCallback);
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/audio.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/audio.cs
new file mode 100644
index 000000000..67b2fbf5e
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/audio.cs
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+
+function ServerPlay2D(%profile)
+{
+ // Play the given sound profile on every client.
+ // The sounds will be transmitted as an event, not attached to any object.
+ for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
+ ClientGroup.getObject(%idx).play2D(%profile);
+}
+
+function ServerPlay3D(%profile,%transform)
+{
+ // Play the given sound profile at the given position on every client
+ // The sound will be transmitted as an event, not attached to any object.
+ for(%idx = 0; %idx < ClientGroup.getCount(); %idx++)
+ ClientGroup.getObject(%idx).play3D(%profile,%transform);
+}
+
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/commands.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/commands.cs
new file mode 100644
index 000000000..85a08cc47
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/commands.cs
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Misc. server commands avialable to clients
+//-----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// Debug commands
+//----------------------------------------------------------------------------
+
+function serverCmdNetSimulateLag( %client, %msDelay, %packetLossPercent )
+{
+ if ( %client.isAdmin )
+ %client.setSimulatedNetParams( %packetLossPercent / 100.0, %msDelay );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/connectionToClient.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/connectionToClient.cs
new file mode 100644
index 000000000..38709c971
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/connectionToClient.cs
@@ -0,0 +1,178 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+// This script function is called before a client connection
+// is accepted. Returning "" will accept the connection,
+// anything else will be sent back as an error to the client.
+// All the connect args are passed also to onConnectRequest
+//
+function GameConnection::onConnectRequest( %client, %netAddress, %name )
+{
+ echo("Connect request from: " @ %netAddress);
+ if($Server::PlayerCount >= $pref::Server::MaxPlayers)
+ return "CR_SERVERFULL";
+ return "";
+}
+
+//-----------------------------------------------------------------------------
+// This script function is the first called on a client accept
+function GameConnection::onConnect( %this, %clientData )
+{
+ // Send down the connection error info, the client is responsible for
+ // displaying this message if a connection error occurs.
+ messageClient(%this, 'MsgConnectionError', "", $Pref::Server::ConnectionError);
+
+ // Send mission information to the client
+ sendLoadInfoToClient(%this);
+
+ // Simulated client lag for testing...
+ // %client.setSimulatedNetParams(0.1, 30);
+
+ // Get the client's unique id:
+ // %authInfo = %client.getAuthInfo();
+ // %client.guid = getField(%authInfo, 3);
+ %this.guid = 0;
+ addToServerGuidList(%this.guid);
+
+ // Set admin status
+ if (%this.getAddress() $= "local")
+ {
+ %this.isAdmin = true;
+ %this.isSuperAdmin = true;
+ }
+ else
+ {
+ %this.isAdmin = false;
+ %this.isSuperAdmin = false;
+ }
+
+ echo("CADD: "@ %this @" "@ %this.getAddress());
+
+ // If the mission is running, go ahead download it to the client
+ if ($missionRunning)
+ {
+ %this.loadMission();
+ }
+ else if ($Server::LoadFailMsg !$= "")
+ {
+ messageClient(%this, 'MsgLoadFailed', $Server::LoadFailMsg);
+ }
+
+ %this.connectData = %clientData;
+
+ $Server::PlayerCount++;
+}
+
+//-----------------------------------------------------------------------------
+// A player's name could be obtained from the auth server, but for
+// now we use the one passed from the client.
+// %realName = getField( %authInfo, 0 );
+//
+function GameConnection::setPlayerName(%client,%name)
+{
+ %client.sendGuid = 0;
+
+ // Minimum length requirements
+ %name = trim( strToPlayerName( %name ) );
+ if ( strlen( %name ) < 3 )
+ %name = "Poser";
+
+ // Make sure the alias is unique, we'll hit something eventually
+ if (!isNameUnique(%name))
+ {
+ %isUnique = false;
+ for (%suffix = 1; !%isUnique; %suffix++) {
+ %nameTry = %name @ "." @ %suffix;
+ %isUnique = isNameUnique(%nameTry);
+ }
+ %name = %nameTry;
+ }
+
+ // Tag the name with the "smurf" color:
+ %client.nameBase = %name;
+ %client.playerName = addTaggedString("\cp\c8" @ %name @ "\co");
+}
+
+function isNameUnique(%name)
+{
+ %count = ClientGroup.getCount();
+ for ( %i = 0; %i < %count; %i++ )
+ {
+ %test = ClientGroup.getObject( %i );
+ %rawName = stripChars( detag( getTaggedString( %test.playerName ) ), "\cp\co\c6\c7\c8\c9" );
+ if ( strcmp( %name, %rawName ) == 0 )
+ return false;
+ }
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// This function is called when a client drops for any reason
+//
+function GameConnection::onDrop(%client, %reason)
+{
+ %entityIds = parseMissionGroupForIds("Entity", "");
+ %entityCount = getWordCount(%entityIds);
+
+ for(%i=0; %i < %entityCount; %i++)
+ {
+ %entity = getWord(%entityIds, %i);
+
+ for(%e=0; %e < %entity.getCount(); %e++)
+ {
+ %child = %entity.getObject(%e);
+ if(%child.getClassName() $= "Entity")
+ %entityIds = %entityIds SPC %child.getID();
+ }
+
+ %entity.notify("onClientDisconnect", %client);
+ }
+
+ if($missionRunning)
+ theLevelInfo.onClientLeaveGame();
+
+ removeFromServerGuidList( %client.guid );
+
+ $Server::PlayerCount--;
+}
+
+//-----------------------------------------------------------------------------
+
+function GameConnection::startMission(%this)
+{
+ // Inform the client the mission starting
+ commandToClient(%this, 'MissionStart', $missionSequence);
+}
+
+
+function GameConnection::endMission(%this)
+{
+ // Inform the client the mission is done. Note that if this is
+ // called as part of the server destruction routine, the client will
+ // actually never see this comment since the client connection will
+ // be destroyed before another round of command processing occurs.
+ // In this case, the client will only see the disconnect from the server
+ // and should manually trigger a mission cleanup.
+ commandToClient(%this, 'MissionEnd', $missionSequence);
+}
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/defaults.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/defaults.cs
new file mode 100644
index 000000000..28f54b841
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/defaults.cs
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//Firstly, set up our standard server prefs
+
+// List of master servers to query, each one is tried in order
+// until one responds
+$Pref::Server::RegionMask = 2;
+$pref::Master[0] = "2:master.garagegames.com:28002";
+
+// Information about the server
+$Pref::Server::Name = "Torque 3D Server";
+$Pref::Server::Info = "This is a Torque 3D server.";
+
+// The connection error message is transmitted to the client immediatly
+// on connection, if any further error occures during the connection
+// process, such as network traffic mismatch, or missing files, this error
+// message is display. This message should be replaced with information
+// usefull to the client, such as the url or ftp address of where the
+// latest version of the game can be obtained.
+$Pref::Server::ConnectionError =
+ "You do not have the correct version of "@$appName@" or "@
+ "the related art needed to play on this server, please contact "@
+ "the server administrator.";
+
+// The network port is also defined by the client, this value
+// overrides pref::net::port for dedicated servers
+$Pref::Server::Port = 28000;
+
+// If the password is set, clients must provide it in order
+// to connect to the server
+$Pref::Server::Password = "";
+
+// Password for admin clients
+$Pref::Server::AdminPassword = "";
+
+// Misc server settings.
+$Pref::Server::MaxPlayers = 64;
+$Pref::Server::TimeLimit = 20; // In minutes
+$Pref::Server::KickBanTime = 300; // specified in seconds
+$Pref::Server::BanTime = 1800; // specified in seconds
+$Pref::Server::FloodProtectionEnabled = 1;
+$Pref::Server::MaxChatLen = 120;
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/kickban.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/kickban.cs
new file mode 100644
index 000000000..f531d351b
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/kickban.cs
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+
+function kick(%client)
+{
+ messageAll( 'MsgAdminForce', '\c2The Admin has kicked %1.', %client.playerName);
+
+ if (!%client.isAIControlled())
+ BanList::add(%client.guid, %client.getAddress(), $Pref::Server::KickBanTime);
+ %client.delete("You have been kicked from this server");
+}
+
+function ban(%client)
+{
+ messageAll('MsgAdminForce', '\c2The Admin has banned %1.', %client.playerName);
+
+ if (!%client.isAIControlled())
+ BanList::add(%client.guid, %client.getAddress(), $Pref::Server::BanTime);
+ %client.delete("You have been banned from this server");
+}
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/levelDownload.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/levelDownload.cs
new file mode 100644
index 000000000..e33f80711
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/levelDownload.cs
@@ -0,0 +1,187 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Mission Loading
+// The server portion of the client/server mission loading process
+//-----------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+// Loading Phases:
+// Phase 1: Transmit Datablocks
+// Transmit targets
+// Phase 2: Transmit Ghost Objects
+// Phase 3: Start Game
+//
+// The server invokes the client MissionStartPhase[1-3] function to request
+// permission to start each phase. When a client is ready for a phase,
+// it responds with MissionStartPhase[1-3]Ack.
+
+//----------------------------------------------------------------------------
+// Phase 1
+//----------------------------------------------------------------------------
+function GameConnection::loadMission(%this)
+{
+ // Send over the information that will display the server info
+ // when we learn it got there, we'll send the data blocks
+ %this.currentPhase = 0;
+ if (%this.isAIControlled())
+ {
+ // Cut to the chase...
+ theLevelInfo.onEnterGame(%this);
+ }
+ else
+ {
+ commandToClient(%this, 'MissionStartPhase1', $missionSequence, $Server::MissionFile);
+
+ echo("*** Sending mission load to client: " @ $Server::MissionFile);
+ }
+}
+
+function serverCmdMissionStartPhase1Ack(%client, %seq)
+{
+ // Make sure to ignore calls from a previous mission load
+ if (%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 0)
+ return;
+
+ %client.currentPhase = 1;
+
+ // Start with the CRC
+ %client.setMissionCRC( $missionCRC );
+
+ // Send over the datablocks...
+ // OnDataBlocksDone will get called when have confirmation
+ // that they've all been received.
+ %client.transmitDataBlocks($missionSequence);
+}
+
+function GameConnection::onDataBlocksDone( %this, %missionSequence )
+{
+ // Make sure to ignore calls from a previous mission load
+ if (%missionSequence != $missionSequence || %this.currentPhase != 1)
+ return;
+
+ %this.currentPhase = 1.5;
+
+ // On to the next phase
+ commandToClient(%this, 'MissionStartPhase2', $missionSequence, $Server::MissionFile);
+}
+
+//----------------------------------------------------------------------------
+// Phase 2
+//----------------------------------------------------------------------------
+function serverCmdMissionStartPhase2Ack(%client, %seq)
+{
+ // Make sure to ignore calls from a previous mission load
+ if (%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 1.5)
+ return;
+
+ %client.currentPhase = 2;
+
+ // Update mod paths, this needs to get there before the objects.
+ %client.transmitPaths();
+
+ // Start ghosting objects to the client
+ %client.activateGhosting();
+}
+
+function GameConnection::clientWantsGhostAlwaysRetry(%client)
+{
+ if($MissionRunning)
+ %client.activateGhosting();
+}
+
+function GameConnection::onGhostAlwaysFailed(%client)
+{
+}
+
+function GameConnection::onGhostAlwaysObjectsReceived(%client)
+{
+ // Ready for next phase.
+ commandToClient(%client, 'MissionStartPhase3', $missionSequence, $Server::MissionFile);
+}
+
+//----------------------------------------------------------------------------
+// Phase 3
+//----------------------------------------------------------------------------
+function serverCmdMissionStartPhase3Ack(%client, %seq)
+{
+ // Make sure to ignore calls from a previous mission load
+ if(%seq != $missionSequence || !$MissionRunning || %client.currentPhase != 2)
+ return;
+
+ %client.currentPhase = 3;
+
+ // Server is ready to drop into the game
+ %entityIds = parseMissionGroupForIds("Entity", "");
+ %entityCount = getWordCount(%entityIds);
+
+ for(%i=0; %i < %entityCount; %i++)
+ {
+ %entity = getWord(%entityIds, %i);
+
+ for(%e=0; %e < %entity.getCount(); %e++)
+ {
+ %child = %entity.getObject(%e);
+ if(%child.getCLassName() $= "Entity")
+ %entityIds = %entityIds SPC %child.getID();
+ }
+
+ %entity.notify("onClientConnect", %client);
+ }
+
+ //Have any special game-play handling here
+ if(theLevelInfo.isMethod("onClientEnterGame"))
+ {
+ theLevelInfo.onClientEnterGame(%client);
+ }
+ else
+ {
+ //No Game mode class for the level info, so just spawn a default camera
+ // Set the control object to the default camera
+ if (!isObject(%client.camera))
+ {
+ if(!isObject(Observer))
+ {
+ datablock CameraData(Observer)
+ {
+ mode = "Observer";
+ };
+ }
+
+ //if (isDefined("$Game::DefaultCameraClass"))
+ %client.camera = spawnObject("Camera", Observer);
+ }
+
+ // If we have a camera then set up some properties
+ if (isObject(%client.camera))
+ {
+ MissionCleanup.add( %this.camera );
+ %client.camera.scopeToClient(%client);
+
+ %client.setControlObject(%client.camera);
+
+ %client.camera.setTransform("0 0 1 0 0 0 0");
+ }
+ }
+
+ %client.startMission();
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/levelInfo.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/levelInfo.cs
new file mode 100644
index 000000000..51df91204
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/levelInfo.cs
@@ -0,0 +1,197 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Loading info is text displayed on the client side while the mission
+// is being loaded. This information is extracted from the mission file
+// and sent to each the client as it joins.
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// clearLoadInfo
+//
+// Clears the mission info stored
+//------------------------------------------------------------------------------
+function clearLoadInfo()
+{
+ if (isObject(theLevelInfo))
+ theLevelInfo.delete();
+}
+
+//------------------------------------------------------------------------------
+// buildLoadInfo
+//
+// Extract the map description from the .mis file
+//------------------------------------------------------------------------------
+function buildLoadInfo( %mission )
+{
+ clearLoadInfo();
+
+ %infoObject = "";
+ %file = new FileObject();
+
+ if ( %file.openForRead( %mission ) ) {
+ %inInfoBlock = false;
+
+ while ( !%file.isEOF() ) {
+ %line = %file.readLine();
+ %line = trim( %line );
+
+ if( %line $= "new ScriptObject(MissionInfo) {" )
+ %inInfoBlock = true;
+ else if( %line $= "new LevelInfo(theLevelInfo) {" )
+ %inInfoBlock = true;
+ else if( %inInfoBlock && %line $= "};" ) {
+ %inInfoBlock = false;
+ %infoObject = %infoObject @ %line;
+ break;
+ }
+
+ if( %inInfoBlock )
+ %infoObject = %infoObject @ %line @ " ";
+ }
+
+ %file.close();
+ }
+ else
+ error("Level file " @ %mission @ " not found.");
+
+ // Will create the object "MissionInfo"
+ eval( %infoObject );
+ %file.delete();
+}
+
+//------------------------------------------------------------------------------
+// dumpLoadInfo
+//
+// Echo the mission information to the console
+//------------------------------------------------------------------------------
+function dumpLoadInfo()
+{
+ echo( "Level Name: " @ theLevelInfo.name );
+ echo( "Level Description:" );
+
+ for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ )
+ echo (" " @ theLevelInfo.desc[%i]);
+}
+
+//------------------------------------------------------------------------------
+// sendLoadInfoToClient
+//
+// Sends mission description to the client
+//------------------------------------------------------------------------------
+function sendLoadInfoToClient( %client )
+{
+ messageClient( %client, 'MsgLoadInfo', "", theLevelInfo.levelName );
+
+ // Send Mission Description a line at a time
+ for( %i = 0; theLevelInfo.desc[%i] !$= ""; %i++ )
+ messageClient( %client, 'MsgLoadDescripition', "", theLevelInfo.desc[%i] );
+
+ messageClient( %client, 'MsgLoadInfoDone' );
+}
+
+// A function used in order to easily parse the MissionGroup for classes . I'm pretty
+// sure at this point the function can be easily modified to search the any group as well.
+function parseMissionGroup( %className, %childGroup )
+{
+ if( getWordCount( %childGroup ) == 0)
+ %currentGroup = "MissionGroup";
+ else
+ %currentGroup = %childGroup;
+
+ for(%i = 0; %i < (%currentGroup).getCount(); %i++)
+ {
+ if( (%currentGroup).getObject(%i).getClassName() $= %className )
+ return true;
+
+ if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" )
+ {
+ if( parseMissionGroup( %className, (%currentGroup).getObject(%i).getId() ) )
+ return true;
+ }
+ }
+}
+
+//
+function parseMissionGroupForIds( %className, %childGroup )
+{
+ if( getWordCount( %childGroup ) == 0)
+ %currentGroup = $Game::MissionGroup;
+ else
+ %currentGroup = %childGroup;
+
+ for(%i = 0; %i < (%currentGroup).getCount(); %i++)
+ {
+ if( (%currentGroup).getObject(%i).getClassName() $= %className )
+ %classIds = %classIds @ (%currentGroup).getObject(%i).getId() @ " ";
+
+ if( (%currentGroup).getObject(%i).getClassName() $= "SimGroup" )
+ %classIds = %classIds @ parseMissionGroupForIds( %className, (%currentGroup).getObject(%i).getId());
+ }
+ return %classIds;
+}
+
+function getLevelInfo( %missionFile )
+{
+ clearLoadInfo();
+
+ %file = new FileObject();
+
+ %LevelInfoObject = "";
+
+ if ( %file.openForRead( %missionFile ) ) {
+ %inInfoBlock = false;
+
+ while ( !%file.isEOF() ) {
+ %line = %file.readLine();
+ %line = trim( %line );
+
+ if( %line $= "new ScriptObject(LevelInfo) {" )
+ %inInfoBlock = true;
+ else if( %line $= "new LevelInfo(theLevelInfo) {" )
+ %inInfoBlock = true;
+ else if( %inInfoBlock && %line $= "};" ) {
+ %inInfoBlock = false;
+ %LevelInfoObject = %LevelInfoObject @ %line;
+ break;
+ }
+
+ if( %inInfoBlock )
+ %LevelInfoObject = %LevelInfoObject @ %line @ " ";
+ }
+
+ %file.close();
+ }
+ %file.delete();
+
+ if( %LevelInfoObject !$= "" )
+ {
+ %LevelInfoObject = "%LevelInfoObject = " @ %LevelInfoObject;
+ eval( %LevelInfoObject );
+
+ return %LevelInfoObject;
+ }
+
+ // Didn't find our LevelInfo
+ return 0;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs
new file mode 100644
index 000000000..92801318d
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/levelLoad.cs
@@ -0,0 +1,181 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Mission Loading
+// The server portion of the client/server mission loading process
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// Server mission loading
+//-----------------------------------------------------------------------------
+// On every mission load except the first, there is a pause after
+// the initial mission info is downloaded to the client.
+$MissionLoadPause = 5000;
+
+//-----------------------------------------------------------------------------
+//This is the first call made by the server to kick the loading process off
+function loadMission( %missionName, %isFirstMission )
+{
+ endMission();
+ echo("*** LOADING MISSION: " @ %missionName);
+ echo("*** Stage 1 load");
+
+ // increment the mission sequence (used for ghost sequencing)
+ $missionSequence++;
+ $missionRunning = false;
+ $Server::MissionFile = %missionName;
+ $Server::LoadFailMsg = "";
+
+ // Extract mission info from the mission file,
+ // including the display name and stuff to send
+ // to the client.
+ buildLoadInfo( %missionName );
+
+ // Download mission info to the clients
+ %count = ClientGroup.getCount();
+ for( %cl = 0; %cl < %count; %cl++ )
+ {
+ %client = ClientGroup.getObject( %cl );
+
+ if (!%client.isAIControlled())
+ sendLoadInfoToClient(%client);
+ }
+
+ // Now that we've sent the LevelInfo to the clients
+ // clear it so that it won't conflict with the actual
+ // LevelInfo loaded in the level
+ clearLoadInfo();
+
+ // if this isn't the first mission, allow some time for the server
+ // to transmit information to the clients:
+ if( %isFirstMission || $Server::ServerType $= "SinglePlayer" )
+ loadMissionStage2();
+ else
+ schedule( $MissionLoadPause, ServerGroup, loadMissionStage2 );
+}
+
+//-----------------------------------------------------------------------------
+
+function loadMissionStage2()
+{
+ echo("*** Stage 2 load");
+
+ // Create the mission group off the ServerGroup
+ $instantGroup = ServerGroup;
+
+ // Make sure the mission exists
+ %file = $Server::MissionFile;
+
+ if( !isFile( %file ) )
+ {
+ $Server::LoadFailMsg = "Could not find mission \"" @ %file @ "\"";
+ }
+ else
+ {
+ // Calculate the mission CRC. The CRC is used by the clients
+ // to caching mission lighting.
+ $missionCRC = getFileCRC( %file );
+
+ // Exec the mission. The MissionGroup (loaded components) is added to the ServerGroup
+ exec(%file);
+
+ if( !isObject(MissionGroup) )
+ {
+ $Server::LoadFailMsg = "No 'MissionGroup' found in mission \"" @ %file @ "\".";
+ }
+ }
+
+ if( $Server::LoadFailMsg !$= "" )
+ {
+ // Inform clients that are already connected
+ for (%clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++)
+ messageClient(ClientGroup.getObject(%clientIndex), 'MsgLoadFailed', $Server::LoadFailMsg);
+ return;
+ }
+
+ // Set mission name.
+ if( isObject( theLevelInfo ) )
+ $Server::MissionName = theLevelInfo.levelName;
+
+ // Mission cleanup group. This is where run time components will reside. The MissionCleanup
+ // group will be added to the ServerGroup.
+ new SimGroup( MissionCleanup );
+
+ // Make the MissionCleanup group the place where all new objects will automatically be added.
+ $instantGroup = MissionCleanup;
+
+ // Construct MOD paths
+ pathOnMissionLoadDone();
+
+ // Mission loading done...
+ echo("*** Mission loaded");
+
+ // Start all the clients in the mission
+ $missionRunning = true;
+ for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ )
+ ClientGroup.getObject(%clientIndex).loadMission();
+
+ // Go ahead and launch the game
+ if(TheLevelInfo.isMethod("onMissionStart"))
+ TheLevelInfo.onMissionStart();
+}
+
+function endMission()
+{
+ if (!isObject( MissionGroup ))
+ return;
+
+ echo("*** ENDING MISSION");
+
+ // Inform the game code we're done.
+ TheLevelInfo.onMissionEnded();
+
+ // Inform the clients
+ for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
+ // clear ghosts and paths from all clients
+ %cl = ClientGroup.getObject( %clientIndex );
+ %cl.endMission();
+ %cl.resetGhosting();
+ %cl.clearPaths();
+ }
+
+ // Delete everything
+ MissionGroup.delete();
+ MissionCleanup.delete();
+
+ clearServerPaths();
+}
+
+function resetMission()
+{
+ echo("*** MISSION RESET");
+
+ // Remove any temporary mission objects
+ MissionCleanup.delete();
+ $instantGroup = ServerGroup;
+ new SimGroup( MissionCleanup );
+ $instantGroup = MissionCleanup;
+
+ clearServerPaths();
+ //
+ TheLevelInfo.onMissionReset();
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/message.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/message.cs
new file mode 100644
index 000000000..ebb1165aa
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/message.cs
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+function messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
+{
+ commandToClient(%client, 'ServerMessage', %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
+}
+
+function messageAll(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
+{
+ %count = ClientGroup.getCount();
+ for(%cl = 0; %cl < %count; %cl++)
+ {
+ %client = ClientGroup.getObject(%cl);
+ messageClient(%client, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
+ }
+}
+
+function messageAllExcept(%client, %team, %msgtype, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13)
+{
+ //can exclude a client, a team or both. A -1 value in either field will ignore that exclusion, so
+ //messageAllExcept(-1, -1, $Mesblah, 'Blah!'); will message everyone (since there shouldn't be a client -1 or client on team -1).
+ %count = ClientGroup.getCount();
+ for(%cl= 0; %cl < %count; %cl++)
+ {
+ %recipient = ClientGroup.getObject(%cl);
+ if((%recipient != %client) && (%recipient.team != %team))
+ messageClient(%recipient, %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13);
+ }
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs b/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs
new file mode 100644
index 000000000..17f127314
--- /dev/null
+++ b/Templates/BaseGame/game/core/clientServer/scripts/server/server.cs
@@ -0,0 +1,303 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function initServer()
+{
+ echo("\n--------- Initializing " @ $appName @ ": Server Scripts ---------");
+
+ //load prefs
+
+ //Force-load the defaults just so we don't have any mistakes
+ exec( "./defaults.cs" );
+
+ //Then, if the user has saved preferences, we load those over-top the defaults
+ %prefPath = getPrefpath();
+ if ( isFile( %prefPath @ "/serverPrefs.cs" ) )
+ exec( %prefPath @ "/serverPrefs.cs" );
+
+ exec( "./audio.cs" );
+ exec( "./commands.cs" );
+ exec( "./kickban.cs" );
+ exec( "./message.cs" );
+ exec( "./levelDownload.cs" );
+ exec( "./levelLoad.cs" );
+ exec( "./levelInfo.cs" );
+ exec( "./connectionToClient.cs" );
+
+ // Server::Status is returned in the Game Info Query and represents the
+ // current status of the server. This string sould be very short.
+ $Server::Status = "Unknown";
+
+ // Turn on testing/debug script functions
+ $Server::TestCheats = false;
+
+ // Specify where the mission files are.
+ $Server::MissionFileSpec = "data/levels/*.mis";
+}
+
+//-----------------------------------------------------------------------------
+function initDedicated()
+{
+ enableWinConsole(true);
+ echo("\n--------- Starting Dedicated Server ---------");
+
+ // Make sure this variable reflects the correct state.
+ $Server::Dedicated = true;
+
+ // The server isn't started unless a mission has been specified.
+ if ($missionArg !$= "") {
+ createServer("MultiPlayer", $missionArg);
+ }
+ else
+ echo("No mission specified (use -mission filename)");
+}
+
+/// Attempt to find an open port to initialize the server with
+function portInit(%port)
+{
+ %failCount = 0;
+ while(%failCount < 10 && !setNetPort(%port))
+ {
+ echo("Port init failed on port " @ %port @ " trying next port.");
+ %port++; %failCount++;
+ }
+}
+
+/// Create a server of the given type, load the given level, and then
+/// create a local client connection to the server.
+//
+/// @return true if successful.
+function createAndConnectToLocalServer( %serverType, %level )
+{
+ if( !createServer( %serverType, %level ) )
+ return false;
+
+ %conn = new GameConnection( ServerConnection );
+ RootGroup.add( ServerConnection );
+
+ %conn.setConnectArgs( $pref::Player::Name );
+ %conn.setJoinPassword( $Client::Password );
+
+ %result = %conn.connectLocal();
+ if( %result !$= "" )
+ {
+ %conn.delete();
+ destroyServer();
+
+ MessageBoxOK("Error starting local server!", "There was an error when trying to connect to the local server.");
+
+ if(isObject(MainMenuGui))
+ Canvas.setContent(MainMenuGui);
+
+ return false;
+ }
+
+ return true;
+}
+
+/// Create a server with either a "SinglePlayer" or "MultiPlayer" type
+/// Specify the level to load on the server
+function createServer(%serverType, %level)
+{
+ // Increase the server session number. This is used to make sure we're
+ // working with the server session we think we are.
+ $Server::Session++;
+
+ if (%level $= "")
+ {
+ error("createServer(): level name unspecified");
+ return false;
+ }
+
+ // Make sure our level name is relative so that it can send
+ // across the network correctly
+ %level = makeRelativePath(%level, getWorkingDirectory());
+
+ destroyServer();
+
+ $missionSequence = 0;
+ $Server::PlayerCount = 0;
+ $Server::ServerType = %serverType;
+ $Server::LoadFailMsg = "";
+ $Physics::isSinglePlayer = true;
+
+ // Setup for multi-player, the network must have been
+ // initialized before now.
+ if (%serverType $= "MultiPlayer")
+ {
+ $Physics::isSinglePlayer = false;
+
+ echo("Starting multiplayer mode");
+
+ // Make sure the network port is set to the correct pref.
+ portInit($Pref::Server::Port);
+ allowConnections(true);
+
+ if ($pref::Net::DisplayOnMaster !$= "Never" )
+ schedule(0,0,startHeartbeat);
+ }
+
+ // Let the game initialize some things now that the
+ // the server has been created
+ onServerCreated();
+
+ loadMission(%level, true);
+
+ $Game::running = true;
+
+ return true;
+}
+
+function onServerCreated()
+{
+ // Server::GameType is sent to the master server.
+ // This variable should uniquely identify your game and/or mod.
+ $Server::GameType = $appName;
+
+ // Server::MissionType sent to the master server. Clients can
+ // filter servers based on mission type.
+ // $Server::MissionType = "Deathmatch";
+
+ // GameStartTime is the sim time the game started. Used to calculated
+ // game elapsed time.
+ $Game::StartTime = 0;
+
+ // Create the server physics world.
+ physicsInitWorld( "server" );
+
+ physicsStartSimulation("server");
+
+ %cnt = DatablockFilesList.count();
+
+ loadDatablockFiles( DatablockFilesList, true );
+
+ %cnt = DatablockFilesList.count();
+
+ // Keep track of when the game started
+ $Game::StartTime = $Sim::Time;
+}
+
+/// Shut down the server
+function destroyServer()
+{
+ $Server::ServerType = "";
+ $Server::Running = false;
+
+ allowConnections(false);
+ stopHeartbeat();
+ $missionRunning = false;
+
+ // End any running levels and shut down the physics sim
+ onServerDestroyed();
+
+ //physicsDestroy();
+
+ // Delete all the server objects
+ if (isObject(ServerGroup))
+ ServerGroup.delete();
+
+ // Delete all the connections:
+ while (ClientGroup.getCount())
+ {
+ %client = ClientGroup.getObject(0);
+ %client.delete();
+ }
+
+ $Server::GuidList = "";
+
+ // Delete all the data blocks...
+ deleteDataBlocks();
+
+ // Save any server settings
+ %prefPath = getPrefpath();
+ echo( "Exporting server prefs..." );
+ export( "$Pref::Server::*", %prefPath@"/serverPrefs.cs", false );
+
+ BanList::Export(%prefPath@"/banlist.cs");
+
+ // Increase the server session number. This is used to make sure we're
+ // working with the server session we think we are.
+ $Server::Session++;
+}
+
+function onServerDestroyed()
+{
+ physicsStopSimulation("server");
+
+ if (!isObject( MissionGroup ))
+ return;
+
+ echo("*** ENDING MISSION");
+
+ // Inform the game code we're done.
+ if(TheLevelInfo.isMethod("onMissionEnded"))
+ TheLevelInfo.onMissionEnded();
+
+ // Inform the clients
+ for( %clientIndex = 0; %clientIndex < ClientGroup.getCount(); %clientIndex++ ) {
+ // clear ghosts and paths from all clients
+ %cl = ClientGroup.getObject( %clientIndex );
+ %cl.endMission();
+ %cl.resetGhosting();
+ %cl.clearPaths();
+ }
+
+ // Delete everything
+ MissionGroup.delete();
+ MissionCleanup.delete();
+
+ clearServerPaths();
+}
+
+/// Guid list maintenance functions
+function addToServerGuidList( %guid )
+{
+ %count = getFieldCount( $Server::GuidList );
+ for ( %i = 0; %i < %count; %i++ )
+ {
+ if ( getField( $Server::GuidList, %i ) == %guid )
+ return;
+ }
+
+ $Server::GuidList = $Server::GuidList $= "" ? %guid : $Server::GuidList TAB %guid;
+}
+
+function removeFromServerGuidList( %guid )
+{
+ %count = getFieldCount( $Server::GuidList );
+ for ( %i = 0; %i < %count; %i++ )
+ {
+ if ( getField( $Server::GuidList, %i ) == %guid )
+ {
+ $Server::GuidList = removeField( $Server::GuidList, %i );
+ return;
+ }
+ }
+}
+
+/// When the server is queried for information, the value of this function is
+/// returned as the status field of the query packet. This information is
+/// accessible as the ServerInfo::State variable.
+function onServerInfoQuery()
+{
+ return "Doing Ok";
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/Core_Components.cs b/Templates/BaseGame/game/core/components/Core_Components.cs
new file mode 100644
index 000000000..0b32d9d6b
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/Core_Components.cs
@@ -0,0 +1,8 @@
+
+function Core_Components::onCreate(%this)
+{
+}
+
+function Core_Components::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/Core_Components.module b/Templates/BaseGame/game/core/components/Core_Components.module
new file mode 100644
index 000000000..2c98b8091
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/Core_Components.module
@@ -0,0 +1,14 @@
+
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/RigidBodyComponent.asset.taml b/Templates/BaseGame/game/core/components/components/RigidBodyComponent.asset.taml
new file mode 100644
index 000000000..8e60db364
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/RigidBodyComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/animationComponent.asset.taml b/Templates/BaseGame/game/core/components/components/animationComponent.asset.taml
new file mode 100644
index 000000000..771d38e02
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/animationComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/cameraOrbiterComponent.asset.taml b/Templates/BaseGame/game/core/components/components/cameraOrbiterComponent.asset.taml
new file mode 100644
index 000000000..b615f2348
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/cameraOrbiterComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/collisionComponent.asset.taml b/Templates/BaseGame/game/core/components/components/collisionComponent.asset.taml
new file mode 100644
index 000000000..624bf9583
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/collisionComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/game/camera.asset.taml b/Templates/BaseGame/game/core/components/components/game/camera.asset.taml
new file mode 100644
index 000000000..ace880f7c
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/camera.asset.taml
@@ -0,0 +1,9 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/game/camera.cs b/Templates/BaseGame/game/core/components/components/game/camera.cs
new file mode 100644
index 000000000..b6f510c9d
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/camera.cs
@@ -0,0 +1,185 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function CameraComponent::onAdd(%this)
+{
+ %this.addComponentField(clientOwner, "The client that views this camera", "int", "1", "");
+
+ %test = %this.clientOwner;
+
+ %barf = ClientGroup.getCount();
+
+ %clientID = %this.getClientID();
+ if(%clientID && !isObject(%clientID.camera))
+ {
+ %this.scopeToClient(%clientID);
+ %this.setDirty();
+
+ %clientID.setCameraObject(%this.owner);
+ %clientID.setControlCameraFov(%this.FOV);
+
+ %clientID.camera = %this.owner;
+ }
+
+ %res = $pref::Video::mode;
+ %derp = 0;
+}
+
+function CameraComponent::onRemove(%this)
+{
+ %clientID = %this.getClientID();
+ if(%clientID)
+ %clientID.clearCameraObject();
+}
+
+function CameraComponent::onInspectorUpdate(%this)
+{
+ //if(%this.clientOwner)
+ //%this.clientOwner.setCameraObject(%this.owner);
+}
+
+function CameraComponent::getClientID(%this)
+{
+ return ClientGroup.getObject(%this.clientOwner-1);
+}
+
+function CameraComponent::isClientCamera(%this, %client)
+{
+ %clientID = ClientGroup.getObject(%this.clientOwner-1);
+
+ if(%client.getID() == %clientID)
+ return true;
+ else
+ return false;
+}
+
+function CameraComponent::onClientConnect(%this, %client)
+{
+ //if(%this.isClientCamera(%client) && !isObject(%client.camera))
+ //{
+ %this.scopeToClient(%client);
+ %this.setDirty();
+
+ %client.setCameraObject(%this.owner);
+ %client.setControlCameraFov(%this.FOV);
+
+ %client.camera = %this.owner;
+ //}
+ //else
+ //{
+ // echo("CONNECTED CLIENT IS NOT CAMERA OWNER!");
+ //}
+}
+
+function CameraComponent::onClientDisconnect(%this, %client)
+{
+ Parent::onClientDisconnect(%this, %client);
+
+ if(isClientCamera(%client)){
+ %this.clearScopeToClient(%client);
+ %client.clearCameraObject();
+ }
+}
+
+///
+///
+///
+
+function VRCameraComponent::onAdd(%this)
+{
+ %this.addComponentField(clientOwner, "The client that views this camera", "int", "1", "");
+
+ %test = %this.clientOwner;
+
+ %barf = ClientGroup.getCount();
+
+ %clientID = %this.getClientID();
+ if(%clientID && !isObject(%clientID.camera))
+ {
+ %this.scopeToClient(%clientID);
+ %this.setDirty();
+
+ %clientID.setCameraObject(%this.owner);
+ %clientID.setControlCameraFov(%this.FOV);
+
+ %clientID.camera = %this.owner;
+ }
+
+ %res = $pref::Video::mode;
+ %derp = 0;
+}
+
+function VRCameraComponent::onRemove(%this)
+{
+ %clientID = %this.getClientID();
+ if(%clientID)
+ %clientID.clearCameraObject();
+}
+
+function CameraComponent::onInspectorUpdate(%this)
+{
+ //if(%this.clientOwner)
+ //%this.clientOwner.setCameraObject(%this.owner);
+}
+
+function VRCameraComponent::getClientID(%this)
+{
+ return ClientGroup.getObject(%this.clientOwner-1);
+}
+
+function VRCameraComponent::isClientCamera(%this, %client)
+{
+ %clientID = ClientGroup.getObject(%this.clientOwner-1);
+
+ if(%client.getID() == %clientID)
+ return true;
+ else
+ return false;
+}
+
+function VRCameraComponent::onClientConnect(%this, %client)
+{
+ //if(%this.isClientCamera(%client) && !isObject(%client.camera))
+ //{
+ %this.scopeToClient(%client);
+ %this.setDirty();
+
+ %client.setCameraObject(%this.owner);
+ %client.setControlCameraFov(%this.FOV);
+
+ %client.camera = %this.owner;
+ //}
+ //else
+ //{
+ // echo("CONNECTED CLIENT IS NOT CAMERA OWNER!");
+ //}
+}
+
+function VRCameraComponent::onClientDisconnect(%this, %client)
+{
+ Parent::onClientDisconnect(%this, %client);
+
+ if(isClientCamera(%client)){
+ %this.clearScopeToClient(%client);
+ %client.clearCameraObject();
+ }
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/game/controlObject.asset.taml b/Templates/BaseGame/game/core/components/components/game/controlObject.asset.taml
new file mode 100644
index 000000000..7efa2d3a2
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/controlObject.asset.taml
@@ -0,0 +1,10 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/game/controlObject.cs b/Templates/BaseGame/game/core/components/components/game/controlObject.cs
new file mode 100644
index 000000000..7f477ecca
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/controlObject.cs
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//registerComponent("ControlObjectComponent", "Component", "Control Object", "Game", false, "Allows the behavior owner to operate as a camera.");
+
+function ControlObjectComponent::onAdd(%this)
+{
+ %this.addComponentField(clientOwner, "The shape to use for rendering", "int", "1", "");
+
+ %clientID = %this.getClientID();
+
+ if(%clientID && !isObject(%clientID.getControlObject()))
+ %clientID.setControlObject(%this.owner);
+}
+
+function ControlObjectComponent::onRemove(%this)
+{
+ %clientID = %this.getClientID();
+
+ if(%clientID)
+ %clientID.setControlObject(0);
+}
+
+function ControlObjectComponent::onClientConnect(%this, %client)
+{
+ if(%this.isControlClient(%client) && !isObject(%client.getControlObject()))
+ %client.setControlObject(%this.owner);
+}
+
+function ControlObjectComponent::onClientDisconnect(%this, %client)
+{
+ if(%this.isControlClient(%client))
+ %client.setControlObject(0);
+}
+
+function ControlObjectComponent::getClientID(%this)
+{
+ return ClientGroup.getObject(%this.clientOwner-1);
+}
+
+function ControlObjectComponent::isControlClient(%this, %client)
+{
+ %clientID = ClientGroup.getObject(%this.clientOwner-1);
+
+ if(%client.getID() == %clientID)
+ return true;
+ else
+ return false;
+}
+
+function ControlObjectComponent::onInspectorUpdate(%this, %field)
+{
+ %clientID = %this.getClientID();
+
+ if(%clientID && !isObject(%clientID.getControlObject()))
+ %clientID.setControlObject(%this.owner);
+}
+
+function switchControlObject(%client, %newControlEntity)
+{
+ if(!isObject(%client) || !isObject(%newControlEntity))
+ return error("SwitchControlObject: No client or target controller!");
+
+ %control = %newControlEntity.getComponent(ControlObjectComponent);
+
+ if(!isObject(%control))
+ return error("SwitchControlObject: Target controller has no conrol object behavior!");
+
+ %client.setControlObject(%newControlEntity);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/game/itemRotate.asset.taml b/Templates/BaseGame/game/core/components/components/game/itemRotate.asset.taml
new file mode 100644
index 000000000..3509f9153
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/itemRotate.asset.taml
@@ -0,0 +1,10 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/game/itemRotate.cs b/Templates/BaseGame/game/core/components/components/game/itemRotate.cs
new file mode 100644
index 000000000..947d19214
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/itemRotate.cs
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//registerComponent("ItemRotationComponent", "Component", "Item Rotation", "Game", false, "Rotates the entity around the z axis, like an item pickup.");
+
+function ItemRotationComponent::onAdd(%this)
+{
+ %this.addComponentField(rotationsPerMinute, "Number of rotations per minute", "float", "5", "");
+ %this.addComponentField(forward, "Rotate forward or backwards", "bool", "1", "");
+ %this.addComponentField(horizontal, "Rotate horizontal or verticle, true for horizontal", "bool", "1", "");
+}
+
+function ItemRotationComponent::Update(%this)
+{
+ %tickRate = 0.032;
+
+ //Rotations per second is calculated based on a standard update tick being 32ms. So we scale by the tick speed, then add that to our rotation to
+ //get a nice rotation speed.
+ if(%this.horizontal)
+ {
+ if(%this.forward)
+ %this.owner.rotation.z += ( ( 360 * %this.rotationsPerMinute ) / 60 ) * %tickRate;
+ else
+ %this.owner.rotation.z -= ( ( 360 * %this.rotationsPerMinute ) / 60 ) * %tickRate;
+ }
+ else
+ {
+ %this.owner.rotation.x += ( ( 360 * %this.rotationsPerMinute ) / 60 ) * %tickRate;
+ }
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/game/playerSpawner.asset.taml b/Templates/BaseGame/game/core/components/components/game/playerSpawner.asset.taml
new file mode 100644
index 000000000..e0024b8fb
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/playerSpawner.asset.taml
@@ -0,0 +1,10 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/game/playerSpawner.cs b/Templates/BaseGame/game/core/components/components/game/playerSpawner.cs
new file mode 100644
index 000000000..a7387eaf1
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/game/playerSpawner.cs
@@ -0,0 +1,78 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//registerComponent("PlayerSpawner", "Component",
+// "Player Spawner", "Game", false, "When a client connects, it spawns a player object for them and attaches them to it");
+
+function PlayerSpawner::onAdd(%this)
+{
+ %this.clientCount = 1;
+ %this.friendlyName = "Player Spawner";
+ %this.componentType = "Spawner";
+
+ %this.addComponentField("GameObjectName", "The name of the game object we spawn for the players", "gameObject", "PlayerObject");
+}
+
+function PlayerSpawner::onClientConnect(%this, %client)
+{
+ %playerObj = spawnGameObject(%this.GameObjectName, false);
+
+ if(!isObject(%playerObj))
+ return;
+
+ %playerObj.position = %this.owner.position;
+
+ %playerObj.notify("onClientConnect", %client);
+
+ switchControlObject(%client, %playerObj);
+ switchCamera(%client, %playerObj);
+
+ %client.player = %playerObj;
+ %client.camera = %playerObj;
+
+ %inventory = %playerObj.getComponent(InventoryController);
+
+ if(isObject(%inventory))
+ {
+ for(%i=0; %i<5; %i++)
+ {
+ %arrow = spawnGameObject(ArrowProjectile, false);
+
+ %inventory.addItem(%arrow);
+ }
+ }
+
+ %playerObj.position = %this.owner.position;
+ %playerObj.rotation = "0 0 0";
+
+ %this.clientCount++;
+}
+
+function PlayerSpawner::onClientDisConnect(%this, %client)
+{
+
+}
+
+function PlayerSpawner::getClientID(%this)
+{
+ return ClientGroup.getObject(%this.clientOwner-1);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/input/fpsControls.asset.taml b/Templates/BaseGame/game/core/components/components/input/fpsControls.asset.taml
new file mode 100644
index 000000000..cd0440055
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/input/fpsControls.asset.taml
@@ -0,0 +1,9 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/input/fpsControls.cs b/Templates/BaseGame/game/core/components/components/input/fpsControls.cs
new file mode 100644
index 000000000..8331e409d
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/input/fpsControls.cs
@@ -0,0 +1,247 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//registerComponent("FPSControls", "Component", "FPS Controls", "Input", false, "First Person Shooter-type controls");
+
+function FPSControls::onAdd(%this)
+{
+ //
+ %this.beginGroup("Keys");
+ %this.addComponentField(forwardKey, "Key to bind to vertical thrust", keybind, "keyboard w");
+ %this.addComponentField(backKey, "Key to bind to vertical thrust", keybind, "keyboard s");
+ %this.addComponentField(leftKey, "Key to bind to horizontal thrust", keybind, "keyboard a");
+ %this.addComponentField(rightKey, "Key to bind to horizontal thrust", keybind, "keyboard d");
+
+ %this.addComponentField(jump, "Key to bind to horizontal thrust", keybind, "keyboard space");
+ %this.endGroup();
+
+ %this.beginGroup("Mouse");
+ %this.addComponentField(pitchAxis, "Key to bind to horizontal thrust", keybind, "mouse yaxis");
+ %this.addComponentField(yawAxis, "Key to bind to horizontal thrust", keybind, "mouse xaxis");
+ %this.endGroup();
+
+ %this.addComponentField(moveSpeed, "Horizontal thrust force", float, 300.0);
+ %this.addComponentField(jumpStrength, "Vertical thrust force", float, 3.0);
+ //
+
+ %control = %this.owner.getComponent( ControlObjectComponent );
+ if(!%control)
+ return echo("SPECTATOR CONTROLS: No Control Object behavior!");
+
+ //%this.Physics = %this.owner.getComponent( PlayerPhysicsComponent );
+
+ //%this.Animation = %this.owner.getComponent( AnimationComponent );
+
+ //%this.Camera = %this.owner.getComponent( MountedCameraComponent );
+
+ //%this.Animation.playThread(0, "look");
+
+ %this.setupControls(%control.getClientID());
+}
+
+function FPSControls::onRemove(%this)
+{
+ Parent::onBehaviorRemove(%this);
+
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.forwardKey);
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.backKey);
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.leftKey);
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.rightKey);
+
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.pitchAxis);
+ commandToClient(%control.clientOwnerID, 'removeInput', %this.yawAxis);
+}
+
+function FPSControls::onBehaviorFieldUpdate(%this, %field)
+{
+ %controller = %this.owner.getBehavior( ControlObjectBehavior );
+ commandToClient(%controller.clientOwnerID, 'updateInput', %this.getFieldValue(%field), %field);
+}
+
+function FPSControls::onClientConnect(%this, %client)
+{
+ %this.setupControls(%client);
+}
+
+
+function FPSControls::setupControls(%this, %client)
+{
+ %control = %this.owner.getComponent( ControlObjectComponent );
+ if(!%control.isControlClient(%client))
+ {
+ echo("FPS CONTROLS: Client Did Not Match");
+ return;
+ }
+
+ %inputCommand = "FPSControls";
+
+ %test = %this.forwardKey;
+
+ /*SetInput(%client, %this.forwardKey.x, %this.forwardKey.y, %inputCommand@"_forwardKey");
+ SetInput(%client, %this.backKey.x, %this.backKey.y, %inputCommand@"_backKey");
+ SetInput(%client, %this.leftKey.x, %this.leftKey.y, %inputCommand@"_leftKey");
+ SetInput(%client, %this.rightKey.x, %this.rightKey.y, %inputCommand@"_rightKey");
+
+ SetInput(%client, %this.jump.x, %this.jump.y, %inputCommand@"_jump");
+
+ SetInput(%client, %this.pitchAxis.x, %this.pitchAxis.y, %inputCommand@"_pitchAxis");
+ SetInput(%client, %this.yawAxis.x, %this.yawAxis.y, %inputCommand@"_yawAxis");*/
+
+ SetInput(%client, "keyboard", "w", %inputCommand@"_forwardKey");
+ SetInput(%client, "keyboard", "s", %inputCommand@"_backKey");
+ SetInput(%client, "keyboard", "a", %inputCommand@"_leftKey");
+ SetInput(%client, "keyboard", "d", %inputCommand@"_rightKey");
+
+ SetInput(%client, "keyboard", "space", %inputCommand@"_jump");
+
+ SetInput(%client, "mouse", "yaxis", %inputCommand@"_pitchAxis");
+ SetInput(%client, "mouse", "xaxis", %inputCommand@"_yawAxis");
+
+ SetInput(%client, "keyboard", "f", %inputCommand@"_flashlight");
+
+}
+
+function FPSControls::onMoveTrigger(%this, %triggerID)
+{
+ //check if our jump trigger was pressed!
+ if(%triggerID == 2)
+ {
+ %this.owner.applyImpulse("0 0 0", "0 0 " @ %this.jumpStrength);
+ }
+}
+
+function FPSControls::Update(%this)
+{
+ return;
+
+ %moveVector = %this.owner.getMoveVector();
+ %moveRotation = %this.owner.getMoveRotation();
+
+ %this.Physics.moveVector = "0 0 0";
+
+ if(%moveVector.x != 0)
+ {
+ %fv = VectorNormalize(%this.owner.getRightVector());
+
+ %forMove = VectorScale(%fv, (%moveVector.x));// * (%this.moveSpeed * 0.032)));
+
+ //%this.Physics.velocity = VectorAdd(%this.Physics.velocity, %forMove);
+
+ %this.Physics.moveVector = VectorAdd(%this.Physics.moveVector, %forMove);
+
+ //if(%forMove > 0)
+ // %this.Animation.playThread(1, "run");
+ }
+ /*else
+ {
+ %fv = VectorNormalize(%this.owner.getRightVector());
+
+ %forMove = VectorScale(%fv, (%moveVector.x * (%this.moveSpeed * 0.032)));
+
+ if(%forMove <= 0)
+ %this.Animation.stopThread(1);
+
+ }*/
+
+ if(%moveVector.y != 0)
+ {
+ %fv = VectorNormalize(%this.owner.getForwardVector());
+
+ %forMove = VectorScale(%fv, (%moveVector.y));// * (%this.moveSpeed * 0.032)));
+
+ //%this.Physics.velocity = VectorAdd(%this.Physics.velocity, %forMove);
+
+ %this.Physics.moveVector = VectorAdd(%this.Physics.moveVector, %forMove);
+
+ //if(VectorLen(%this.Physics.velocity) < 2)
+ // %this.Physics.velocity = VectorAdd(%this.Physics.velocity, %forMove);
+ }
+
+ /*if(%moveVector.z)
+ {
+ %fv = VectorNormalize(%this.owner.getUpVector());
+
+ %forMove = VectorScale(%fv, (%moveVector.z * (%this.moveSpeed * 0.032)));
+
+ %this.Physics.velocity = VectorAdd(%this.Physics.velocity, %forMove);
+ }*/
+
+ if(%moveRotation.x != 0)
+ {
+ %look = mRadToDeg(%moveRotation.x) / 180;
+
+ //%this.Animation.setThreadPos(0, %look);
+
+ %this.owner.getComponent( MountedCameraComponent ).rotationOffset.x += mRadToDeg(%moveRotation.x);
+
+ //%this.Camera.rotationOffset.x += mRadToDeg(%moveRotation.x);
+ }
+ // %this.owner.rotation.x += mRadToDeg(%moveRotation.x);
+
+ if(%moveRotation.z != 0)
+ {
+ %zrot = mRadToDeg(%moveRotation.z);
+ %this.owner.getComponent( MountedCameraComponent ).rotationOffset.z += %zrot;
+ //%this.owner.rotation.z += %zrot;
+ }
+}
+
+//
+function FPSControls_forwardKey(%val)
+{
+ $mvForwardAction = %val;
+}
+
+function FPSControls_backKey(%val)
+{
+ $mvBackwardAction = %val;
+}
+
+function FPSControls_leftKey(%val)
+{
+ $mvLeftAction = %val;
+}
+
+function FPSControls_rightKey(%val)
+{
+ $mvRightAction = %val;
+}
+
+function FPSControls_yawAxis(%val)
+{
+ $mvYaw += getMouseAdjustAmount(%val);
+}
+
+function FPSControls_pitchAxis(%val)
+{
+ $mvPitch += getMouseAdjustAmount(%val);
+}
+
+function FPSControls_jump(%val)
+{
+ $mvTriggerCount2++;
+}
+
+function FPSControls_flashLight(%val)
+{
+ $mvTriggerCount3++;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/input/inputManager.cs b/Templates/BaseGame/game/core/components/components/input/inputManager.cs
new file mode 100644
index 000000000..c8123d1e3
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/input/inputManager.cs
@@ -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.
+//-----------------------------------------------------------------------------
+
+function SetInput(%client, %device, %key, %command, %bindMap, %behav)
+{
+ commandToClient(%client, 'SetInput', %device, %key, %command, %bindMap, %behav);
+}
+
+function RemoveInput(%client, %device, %key, %command, %bindMap)
+{
+ commandToClient(%client, 'removeInput', %device, %key, %command, %bindMap);
+}
+
+function clientCmdSetInput(%device, %key, %command, %bindMap, %behav)
+{
+ //if we're requesting a custom bind map, set that up
+ if(%bindMap $= "")
+ %bindMap = moveMap;
+
+ if (!isObject(%bindMap)){
+ new ActionMap(moveMap);
+ moveMap.push();
+ }
+
+ //get our local
+ //%localID = ServerConnection.resolveGhostID(%behav);
+
+ //%tmpl = %localID.getTemplate();
+ //%tmpl.insantiateNamespace(%tmpl.getName());
+
+ //first, check if we have an existing command
+ %oldBind = %bindMap.getBinding(%command);
+ if(%oldBind !$= "")
+ %bindMap.unbind(getField(%oldBind, 0), getField(%oldBind, 1));
+
+ //now, set the requested bind
+ %bindMap.bind(%device, %key, %command);
+}
+
+function clientCmdRemoveSpecCtrlInput(%device, %key, %bindMap)
+{
+ //if we're requesting a custom bind map, set that up
+ if(%bindMap $= "")
+ %bindMap = moveMap;
+
+ if (!isObject(%bindMap))
+ return;
+
+ %bindMap.unbind(%device, %key);
+}
+
+function clientCmdSetupClientBehavior(%bhvrGstID)
+{
+ %localID = ServerConnection.resolveGhostID(%bhvrGstID);
+ %tmpl = %localID.getTemplate();
+ %tmpl.insantiateNamespace(%tmpl.getName());
+}
+
+function getMouseAdjustAmount(%val)
+{
+ // based on a default camera FOV of 90'
+ return(%val * ($cameraFov / 90) * 0.01) * $pref::Input::LinkMouseSensitivity;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/components/components/meshComponent.asset.taml b/Templates/BaseGame/game/core/components/components/meshComponent.asset.taml
new file mode 100644
index 000000000..b41de171a
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/meshComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/playerControllerComponent.asset.taml b/Templates/BaseGame/game/core/components/components/playerControllerComponent.asset.taml
new file mode 100644
index 000000000..417f409e0
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/playerControllerComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/soundComponent.asset.taml b/Templates/BaseGame/game/core/components/components/soundComponent.asset.taml
new file mode 100644
index 000000000..a29bcc9ff
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/soundComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/stateMachineComponent.asset.taml b/Templates/BaseGame/game/core/components/components/stateMachineComponent.asset.taml
new file mode 100644
index 000000000..ff1d53cd8
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/stateMachineComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/components/components/triggerComponent.asset.taml b/Templates/BaseGame/game/core/components/components/triggerComponent.asset.taml
new file mode 100644
index 000000000..4fabc200c
--- /dev/null
+++ b/Templates/BaseGame/game/core/components/components/triggerComponent.asset.taml
@@ -0,0 +1,8 @@
+
diff --git a/Templates/BaseGame/game/core/console/Core_Console.cs b/Templates/BaseGame/game/core/console/Core_Console.cs
new file mode 100644
index 000000000..a93b149f4
--- /dev/null
+++ b/Templates/BaseGame/game/core/console/Core_Console.cs
@@ -0,0 +1,12 @@
+
+function Core_Console::onCreate(%this)
+{
+ exec("./scripts/profiles.cs");
+ exec("./scripts/console.cs");
+
+ exec("./guis/console.gui");
+}
+
+function Core_Console::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/console/Core_Console.module b/Templates/BaseGame/game/core/console/Core_Console.module
new file mode 100644
index 000000000..6927ba40e
--- /dev/null
+++ b/Templates/BaseGame/game/core/console/Core_Console.module
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/console/guis/console.gui b/Templates/BaseGame/game/core/console/guis/console.gui
new file mode 100644
index 000000000..c2f21eba9
--- /dev/null
+++ b/Templates/BaseGame/game/core/console/guis/console.gui
@@ -0,0 +1,191 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(ConsoleDlg) {
+ position = "0 0";
+ extent = "1024 768";
+ minExtent = "8 8";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "1";
+ helpTag = "0";
+
+ new GuiConsoleEditCtrl(ConsoleEntry) {
+ useSiblingScroller = "1";
+ historySize = "40";
+ tabComplete = "0";
+ sinkAllKeyEvents = "1";
+ password = "0";
+ passwordMask = "*";
+ maxLength = "255";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "0 750";
+ extent = "1024 18";
+ minExtent = "8 8";
+ horizSizing = "width";
+ vertSizing = "top";
+ profile = "ConsoleTextEditProfile";
+ visible = "1";
+ active = "1";
+ altCommand = "ConsoleEntry::eval();";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ 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 = "1 728";
+ extent = "1024 22";
+ minExtent = "8 2";
+ horizSizing = "width";
+ vertSizing = "top";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiBitmapCtrl() {
+ bitmap = "data/ui/art/hudfill.png";
+ color = "255 255 255 255";
+ wrap = "0";
+ position = "0 0";
+ extent = "1024 22";
+ minExtent = "8 2";
+ horizSizing = "width";
+ vertSizing = "bottom";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ConsoleDlgErrorFilterBtn) {
+ text = "Errors";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "2 2";
+ extent = "113 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ConsoleDlgWarnFilterBtn) {
+ text = "Warnings";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "119 2";
+ extent = "113 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ConsoleDlgNormalFilterBtn) {
+ text = "Normal Messages";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "236 2";
+ extent = "113 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiScrollCtrl() {
+ willFirstRespond = "1";
+ hScrollBar = "alwaysOn";
+ vScrollBar = "alwaysOn";
+ 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 0";
+ extent = "1024 730";
+ minExtent = "8 8";
+ horizSizing = "width";
+ vertSizing = "height";
+ profile = "ConsoleScrollProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ internalName = "Scroll";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiConsole(ConsoleMessageLogView) {
+ position = "1 1";
+ extent = "622 324";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiConsoleProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+};
+//--- OBJECT WRITE END ---
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/console/scripts/console.cs b/Templates/BaseGame/game/core/console/scripts/console.cs
new file mode 100644
index 000000000..201bcfb92
--- /dev/null
+++ b/Templates/BaseGame/game/core/console/scripts/console.cs
@@ -0,0 +1,137 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+GlobalActionMap.bind("keyboard", "tilde", "toggleConsole");
+
+function ConsoleEntry::eval()
+{
+ %text = trim(ConsoleEntry.getValue());
+ if(%text $= "")
+ return;
+
+ // If it's missing a trailing () and it's not a variable,
+ // append the parentheses.
+ if(strpos(%text, "(") == -1 && !isDefined(%text)) {
+ if(strpos(%text, "=") == -1 && strpos(%text, " ") == -1) {
+ if(strpos(%text, "{") == -1 && strpos(%text, "}") == -1) {
+ %text = %text @ "()";
+ }
+ }
+ }
+
+ // Append a semicolon if need be.
+ %pos = strlen(%text) - 1;
+ if(strpos(%text, ";", %pos) == -1 && strpos(%text, "}") == -1) {
+ %text = %text @ ";";
+ }
+
+ // Turn off warnings for assigning from void
+ // and evaluate the snippet.
+ if(!isDefined("$Con::warnVoidAssignment"))
+ %oldWarnVoidAssignment = true;
+ else
+ %oldWarnVoidAssignment = $Con::warnVoidAssignment;
+ $Con::warnVoidAssignment = false;
+
+ echo("==>" @ %text);
+ if( !startsWith(%text, "function ")
+ && !startsWith(%text, "datablock ")
+ && !startsWith(%text, "foreach(")
+ && !startsWith(%text, "foreach$(")
+ && !startsWith(%text, "if(")
+ && !startsWith(%text, "while(")
+ && !startsWith(%text, "for(")
+ && !startsWith(%text, "switch(")
+ && !startsWith(%text, "switch$("))
+ eval("%result = " @ %text);
+ else
+ eval(%text);
+ $Con::warnVoidAssignment = %oldWarnVoidAssignment;
+
+ ConsoleEntry.setValue("");
+
+ // Echo result.
+ if(%result !$= "")
+ echo(%result);
+}
+
+function ToggleConsole(%make)
+{
+ if (%make) {
+ if (ConsoleDlg.isAwake()) {
+ // Deactivate the console.
+ Canvas.popDialog(ConsoleDlg);
+ } else {
+ Canvas.pushDialog(ConsoleDlg, 99);
+ }
+ }
+}
+
+function ConsoleDlg::hideWindow(%this)
+{
+ %this-->Scroll.setVisible(false);
+}
+
+function ConsoleDlg::showWindow(%this)
+{
+ %this-->Scroll.setVisible(true);
+}
+
+function ConsoleDlg::onWake(%this)
+{
+ ConsoleDlgErrorFilterBtn.setStateOn(ConsoleMessageLogView.getErrorFilter());
+ ConsoleDlgWarnFilterBtn.setStateOn(ConsoleMessageLogView.getWarnFilter());
+ ConsoleDlgNormalFilterBtn.setStateOn(ConsoleMessageLogView.getNormalFilter());
+
+ ConsoleMessageLogView.refresh();
+}
+
+function ConsoleDlg::setAlpha( %this, %alpha)
+{
+ if (%alpha $= "")
+ ConsoleScrollProfile.fillColor = $ConsoleDefaultFillColor;
+ else
+ ConsoleScrollProfile.fillColor = getWords($ConsoleDefaultFillColor, 0, 2) SPC %alpha * 255.0;
+}
+
+function ConsoleDlgErrorFilterBtn::onClick(%this)
+{
+ ConsoleMessageLogView.toggleErrorFilter();
+}
+
+function ConsoleDlgWarnFilterBtn::onClick(%this)
+{
+
+ ConsoleMessageLogView.toggleWarnFilter();
+}
+
+function ConsoleDlgNormalFilterBtn::onClick(%this)
+{
+ ConsoleMessageLogView.toggleNormalFilter();
+}
+
+function ConsoleMessageLogView::onNewMessage(%this, %errorCount, %warnCount, %normalCount)
+{
+ ConsoleDlgErrorFilterBtn.setText("(" @ %errorCount @ ") Errors");
+ ConsoleDlgWarnFilterBtn.setText("(" @ %warnCount @ ") Warnings");
+ ConsoleDlgNormalFilterBtn.setText("(" @ %normalCount @ ") Messages");
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/console/scripts/profiles.cs b/Templates/BaseGame/game/core/console/scripts/profiles.cs
new file mode 100644
index 000000000..b83dd4fa7
--- /dev/null
+++ b/Templates/BaseGame/game/core/console/scripts/profiles.cs
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+if(!isObject(GuiConsoleProfile))
+new GuiControlProfile(GuiConsoleProfile)
+{
+ fontType = ($platform $= "macos") ? "Monaco" : "Lucida Console";
+ fontSize = ($platform $= "macos") ? 13 : 12;
+ fontColor = "255 255 255";
+ fontColorHL = "0 255 255";
+ fontColorNA = "255 0 0";
+ fontColors[6] = "100 100 100";
+ fontColors[7] = "100 100 0";
+ fontColors[8] = "0 0 100";
+ fontColors[9] = "0 100 0";
+ category = "Core";
+};
+
+if(!isObject(GuiConsoleTextProfile))
+new GuiControlProfile(GuiConsoleTextProfile)
+{
+ fontColor = "0 0 0";
+ autoSizeWidth = true;
+ autoSizeHeight = true;
+ textOffset = "2 2";
+ opaque = true;
+ fillColor = "255 255 255";
+ border = true;
+ borderThickness = 1;
+ borderColor = "0 0 0";
+ category = "Core";
+};
+
+if(!isObject(ConsoleScrollProfile))
+new GuiControlProfile(ConsoleScrollProfile : GuiScrollProfile)
+{
+ opaque = true;
+ fillColor = "0 0 0 175";
+ border = 1;
+ //borderThickness = 0;
+ borderColor = "0 0 0";
+ category = "Core";
+};
+
+if(!isObject(ConsoleTextEditProfile))
+new GuiControlProfile(ConsoleTextEditProfile : GuiTextEditProfile)
+{
+ fillColor = "242 241 240 255";
+ fillColorHL = "255 255 255";
+ category = "Core";
+};
diff --git a/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft
new file mode 100644
index 000000000..2b5649500
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 10 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft
new file mode 100644
index 000000000..5592716dd
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 12 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft
new file mode 100644
index 000000000..159010c68
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 14 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft
new file mode 100644
index 000000000..058fbb305
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 16 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft
new file mode 100644
index 000000000..968441ce3
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial 36 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft
new file mode 100644
index 000000000..60d7b0227
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 14 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft
new file mode 100644
index 000000000..f2140c4c4
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 16 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft b/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft
new file mode 100644
index 000000000..3460f7db9
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Arial Bold 18 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft
new file mode 100644
index 000000000..93ea13d02
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/ArialBold 14 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft b/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft
new file mode 100644
index 000000000..d4418f692
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/ArialItalic 14 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft b/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft
new file mode 100644
index 000000000..cdb46f5ba
Binary files /dev/null and b/Templates/BaseGame/game/core/fonts/Lucida Console 12 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/gui/Core_GUI.cs b/Templates/BaseGame/game/core/gui/Core_GUI.cs
new file mode 100644
index 000000000..dd15bf9ca
--- /dev/null
+++ b/Templates/BaseGame/game/core/gui/Core_GUI.cs
@@ -0,0 +1,11 @@
+
+function Core_GUI::onCreate(%this)
+{
+ exec("./scripts/profiles.cs");
+ exec("./scripts/canvas.cs");
+ exec("./scripts/cursor.cs");
+}
+
+function Core_GUI::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/gui/Core_GUI.module b/Templates/BaseGame/game/core/gui/Core_GUI.module
new file mode 100644
index 000000000..323d7cff2
--- /dev/null
+++ b/Templates/BaseGame/game/core/gui/Core_GUI.module
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/gui/images/button.png b/Templates/BaseGame/game/core/gui/images/button.png
new file mode 100644
index 000000000..1c7361e25
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/button.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/checkbox.png b/Templates/BaseGame/game/core/gui/images/checkbox.png
new file mode 100644
index 000000000..46e0ac959
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/checkbox.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/group-border.png b/Templates/BaseGame/game/core/gui/images/group-border.png
new file mode 100644
index 000000000..61234ae1f
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/group-border.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/inactive-overlay.png b/Templates/BaseGame/game/core/gui/images/inactive-overlay.png
new file mode 100644
index 000000000..feab83209
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/inactive-overlay.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/loadingbar.png b/Templates/BaseGame/game/core/gui/images/loadingbar.png
new file mode 100644
index 000000000..34f594403
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/loadingbar.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/scrollBar.png b/Templates/BaseGame/game/core/gui/images/scrollBar.png
new file mode 100644
index 000000000..e8c34dc85
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/scrollBar.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/textEdit.png b/Templates/BaseGame/game/core/gui/images/textEdit.png
new file mode 100644
index 000000000..5a65fac3c
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/textEdit.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/thumbHighlightButton.png b/Templates/BaseGame/game/core/gui/images/thumbHighlightButton.png
new file mode 100644
index 000000000..9d83b75f3
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/thumbHighlightButton.png differ
diff --git a/Templates/BaseGame/game/core/gui/images/window.png b/Templates/BaseGame/game/core/gui/images/window.png
new file mode 100644
index 000000000..d9e8006e4
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/images/window.png differ
diff --git a/Templates/BaseGame/game/core/gui/scripts/canvas.cs b/Templates/BaseGame/game/core/gui/scripts/canvas.cs
new file mode 100644
index 000000000..b38cdccca
--- /dev/null
+++ b/Templates/BaseGame/game/core/gui/scripts/canvas.cs
@@ -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.
+//-----------------------------------------------------------------------------
+
+function createCanvas(%windowTitle)
+{
+ if ($isDedicated)
+ {
+ GFXInit::createNullDevice();
+ return true;
+ }
+
+ // Create the Canvas
+ $GameCanvas = new GuiCanvas(Canvas)
+ {
+ displayWindow = $platform !$= "windows";
+ };
+
+ // Set the window title
+ if (isObject(Canvas))
+ {
+ Canvas.setWindowTitle(%windowTitle @ " - " @ $pref::Video::displayDevice);
+ configureCanvas();
+ }
+ else
+ {
+ error("Canvas creation failed. Shutting down.");
+ quit();
+ }
+}
+
+// Constants for referencing video resolution preferences
+$WORD::RES_X = 0;
+$WORD::RES_Y = 1;
+$WORD::FULLSCREEN = 2;
+$WORD::BITDEPTH = 3;
+$WORD::REFRESH = 4;
+$WORD::AA = 5;
+
+function configureCanvas()
+{
+ // Setup a good default if we don't have one already.
+ if ($pref::Video::Resolution $= "")
+ $pref::Video::Resolution = "800 600";
+ if ($pref::Video::FullScreen $= "")
+ $pref::Video::FullScreen = false;
+ if ($pref::Video::BitDepth $= "")
+ $pref::Video::BitDepth = "32";
+ if ($pref::Video::RefreshRate $= "")
+ $pref::Video::RefreshRate = "60";
+ if ($pref::Video::AA $= "")
+ $pref::Video::AA = "4";
+
+ %resX = $pref::Video::Resolution.x;
+ %resY = $pref::Video::Resolution.y;
+ %fs = $pref::Video::FullScreen;
+ %bpp = $pref::Video::BitDepth;
+ %rate = $pref::Video::RefreshRate;
+ %aa = $pref::Video::AA;
+
+ if($cliFullscreen !$= "") {
+ %fs = $cliFullscreen;
+ $cliFullscreen = "";
+ }
+
+ echo("--------------");
+ echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %aa @ "\"");
+
+ %deskRes = getDesktopResolution();
+ %deskResX = getWord(%deskRes, $WORD::RES_X);
+ %deskResY = getWord(%deskRes, $WORD::RES_Y);
+ %deskResBPP = getWord(%deskRes, 2);
+
+ // We shouldn't be getting this any more but just in case...
+ if (%bpp $= "Default")
+ %bpp = %deskResBPP;
+
+ // Make sure we are running at a valid resolution
+ if (%fs $= "0" || %fs $= "false")
+ {
+ // Windowed mode has to use the same bit depth as the desktop
+ %bpp = %deskResBPP;
+
+ // Windowed mode also has to run at a smaller resolution than the desktop
+ if ((%resX >= %deskResX) || (%resY >= %deskResY))
+ {
+ warn("Warning: The requested windowed resolution is equal to or larger than the current desktop resolution. Attempting to find a better resolution");
+
+ %resCount = Canvas.getModeCount();
+ for (%i = (%resCount - 1); %i >= 0; %i--)
+ {
+ %testRes = Canvas.getMode(%i);
+ %testResX = getWord(%testRes, $WORD::RES_X);
+ %testResY = getWord(%testRes, $WORD::RES_Y);
+ %testBPP = getWord(%testRes, $WORD::BITDEPTH);
+
+ if (%testBPP != %bpp)
+ continue;
+
+ if ((%testResX < %deskResX) && (%testResY < %deskResY))
+ {
+ // This will work as our new resolution
+ %resX = %testResX;
+ %resY = %testResY;
+
+ warn("Warning: Switching to \"" @ %resX SPC %resY SPC %bpp @ "\"");
+
+ break;
+ }
+ }
+ }
+ }
+
+ $pref::Video::Resolution = %resX SPC %resY;
+ $pref::Video::FullScreen = %fs;
+ $pref::Video::BitDepth = %bpp;
+ $pref::Video::RefreshRate = %rate;
+ $pref::Video::AA = %aa;
+
+ if (%fs == 1 || %fs $= "true")
+ %fsLabel = "Yes";
+ else
+ %fsLabel = "No";
+
+ echo("Accepted Mode: " NL
+ "--Resolution : " @ %resX SPC %resY NL
+ "--Full Screen : " @ %fsLabel NL
+ "--Bits Per Pixel : " @ %bpp NL
+ "--Refresh Rate : " @ %rate NL
+ "--AA TypeXLevel : " @ %aa NL
+ "--------------");
+
+ // Actually set the new video mode
+ Canvas.setVideoMode(%resX, %resY, %fs, %bpp, %rate, %aa);
+
+ commandToServer('setClientAspectRatio', %resX, %resY);
+
+ // AA piggybacks on the AA setting in $pref::Video::mode.
+ // We need to parse the setting between AA modes, and then it's level
+ // It's formatted as AATypexAALevel
+ // So, FXAAx4 or MLAAx2
+ if ( isObject( FXAA_PostEffect ) )
+ FXAA_PostEffect.isEnabled = ( %aa > 0 ) ? true : false;
+}
diff --git a/Templates/BaseGame/game/core/gui/scripts/cursor.cs b/Templates/BaseGame/game/core/gui/scripts/cursor.cs
new file mode 100644
index 000000000..f71bc023a
--- /dev/null
+++ b/Templates/BaseGame/game/core/gui/scripts/cursor.cs
@@ -0,0 +1,102 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------
+// Cursor toggle functions.
+//---------------------------------------------------------------------------------------------
+$cursorControlled = true;
+function showCursor()
+{
+ if ($cursorControlled)
+ lockMouse(false);
+ Canvas.cursorOn();
+}
+
+function hideCursor()
+{
+ if ($cursorControlled)
+ lockMouse(true);
+ Canvas.cursorOff();
+}
+
+//---------------------------------------------------------------------------------------------
+// In the CanvasCursor package we add some additional functionality to the built-in GuiCanvas
+// class, of which the global Canvas object is an instance. In this case, the behavior we want
+// is for the cursor to automatically display, except when the only guis visible want no
+// cursor - usually the in game interface.
+//---------------------------------------------------------------------------------------------
+package CanvasCursorPackage
+{
+
+//---------------------------------------------------------------------------------------------
+// checkCursor
+// The checkCursor method iterates through all the root controls on the canvas checking each
+// ones noCursor property. If the noCursor property exists as anything other than false or an
+// empty string on every control, the cursor will be hidden.
+//---------------------------------------------------------------------------------------------
+function GuiCanvas::checkCursor(%this)
+{
+ %count = %this.getCount();
+ for(%i = 0; %i < %count; %i++)
+ {
+ %control = %this.getObject(%i);
+ if ((%control.noCursor $= "") || !%control.noCursor)
+ {
+ showCursor();
+ return;
+ }
+ }
+ // If we get here, every control requested a hidden cursor, so we oblige.
+ hideCursor();
+}
+
+//---------------------------------------------------------------------------------------------
+// The following functions override the GuiCanvas defaults that involve changing the content
+// of the Canvas. Basically, all we are doing is adding a call to checkCursor to each one.
+//---------------------------------------------------------------------------------------------
+function GuiCanvas::setContent(%this, %ctrl)
+{
+ Parent::setContent(%this, %ctrl);
+ %this.checkCursor();
+}
+
+function GuiCanvas::pushDialog(%this, %ctrl, %layer, %center)
+{
+ Parent::pushDialog(%this, %ctrl, %layer, %center);
+ %this.checkCursor();
+}
+
+function GuiCanvas::popDialog(%this, %ctrl)
+{
+ Parent::popDialog(%this, %ctrl);
+ %this.checkCursor();
+}
+
+function GuiCanvas::popLayer(%this, %layer)
+{
+ Parent::popLayer(%this, %layer);
+ %this.checkCursor();
+}
+
+};
+
+activatePackage(CanvasCursorPackage);
diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 10 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 10 (ansi).uft
new file mode 100644
index 000000000..2b5649500
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 10 (ansi).uft differ
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
new file mode 100644
index 000000000..67a177016
Binary files /dev/null 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
new file mode 100644
index 000000000..f4f19745f
Binary files /dev/null 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 16 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 16 (ansi).uft
new file mode 100644
index 000000000..ec996019d
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 16 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 36 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 36 (ansi).uft
new file mode 100644
index 000000000..c0aa8165c
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial 36 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 14 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 14 (ansi).uft
new file mode 100644
index 000000000..4dbbddede
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/Arial Bold 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
new file mode 100644
index 000000000..fb096776f
Binary files /dev/null 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
new file mode 100644
index 000000000..1f8fdedd3
Binary files /dev/null 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
new file mode 100644
index 000000000..5bac0316e
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/ArialItalic 14 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/gui/scripts/fonts/Lucida Console 12 (ansi).uft b/Templates/BaseGame/game/core/gui/scripts/fonts/Lucida Console 12 (ansi).uft
new file mode 100644
index 000000000..e06fa806c
Binary files /dev/null and b/Templates/BaseGame/game/core/gui/scripts/fonts/Lucida Console 12 (ansi).uft differ
diff --git a/Templates/BaseGame/game/core/gui/scripts/profiles.cs b/Templates/BaseGame/game/core/gui/scripts/profiles.cs
new file mode 100644
index 000000000..a06ab94da
--- /dev/null
+++ b/Templates/BaseGame/game/core/gui/scripts/profiles.cs
@@ -0,0 +1,226 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Set font cache path if it doesn't already exist.
+if($Gui::fontCacheDirectory $= "")
+{
+ $Gui::fontCacheDirectory = expandFilename("./fonts");
+}
+
+// ----------------------------------------------------------------------------
+// GuiDefaultProfile is a special profile that all other profiles inherit
+// defaults from. It must exist.
+// ----------------------------------------------------------------------------
+
+if(!isObject(GuiDefaultProfile))
+new GuiControlProfile (GuiDefaultProfile)
+{
+ tab = false;
+ canKeyFocus = false;
+ hasBitmapArray = false;
+ mouseOverSelected = false;
+
+ // fill color
+ opaque = false;
+ fillColor = "242 241 240";
+ fillColorHL ="228 228 235";
+ fillColorSEL = "98 100 137";
+ fillColorNA = "255 255 255 ";
+
+ // border color
+ border = 0;
+ borderColor = "100 100 100";
+ borderColorHL = "50 50 50 50";
+ borderColorNA = "75 75 75";
+
+ // font
+ fontType = "Arial";
+ fontSize = 14;
+ fontCharset = ANSI;
+
+ fontColor = "0 0 0";
+ fontColorHL = "0 0 0";
+ fontColorNA = "0 0 0";
+ fontColorSEL= "255 255 255";
+
+ // bitmap information
+ bitmap = "";
+ bitmapBase = "";
+ textOffset = "0 0";
+
+ // used by guiTextControl
+ modal = true;
+ justify = "left";
+ autoSizeWidth = false;
+ autoSizeHeight = false;
+ returnTab = false;
+ numbersOnly = false;
+ cursorColor = "0 0 0 255";
+};
+
+if(!isObject(GuiToolTipProfile))
+new GuiControlProfile (GuiToolTipProfile)
+{
+ // fill color
+ fillColor = "239 237 222";
+
+ // border color
+ borderColor = "138 134 122";
+
+ // font
+ fontType = "Arial";
+ fontSize = 14;
+ fontColor = "0 0 0";
+
+ category = "Core";
+};
+
+if(!isObject(GuiWindowProfile))
+new GuiControlProfile (GuiWindowProfile)
+{
+ opaque = false;
+ border = 2;
+ fillColor = "242 241 240";
+ fillColorHL = "221 221 221";
+ fillColorNA = "200 200 200";
+ fontColor = "50 50 50";
+ fontColorHL = "0 0 0";
+ bevelColorHL = "255 255 255";
+ bevelColorLL = "0 0 0";
+ text = "untitled";
+ bitmap = "core/gui/images/window";
+ textOffset = "8 4";
+ hasBitmapArray = true;
+ justify = "left";
+ category = "Core";
+};
+
+
+if(!isObject(GuiTextEditProfile))
+new GuiControlProfile(GuiTextEditProfile)
+{
+ opaque = true;
+ bitmap = "core/gui/images/textEdit";
+ hasBitmapArray = true;
+ border = -2;
+ fillColor = "242 241 240 0";
+ fillColorHL = "255 255 255";
+ fontColor = "0 0 0";
+ fontColorHL = "255 255 255";
+ fontColorSEL = "98 100 137";
+ fontColorNA = "200 200 200";
+ textOffset = "4 2";
+ autoSizeWidth = false;
+ autoSizeHeight = true;
+ justify = "left";
+ tab = true;
+ canKeyFocus = true;
+ category = "Core";
+};
+
+if(!isObject(GuiScrollProfile))
+new GuiControlProfile(GuiScrollProfile)
+{
+ opaque = true;
+ fillcolor = "255 255 255";
+ fontColor = "0 0 0";
+ fontColorHL = "150 150 150";
+ border = true;
+ bitmap = "core/gui/images/scrollBar";
+ hasBitmapArray = true;
+ category = "Core";
+};
+
+if(!isObject(GuiOverlayProfile))
+new GuiControlProfile(GuiOverlayProfile)
+{
+ opaque = true;
+ fontColor = "0 0 0";
+ fontColorHL = "255 255 255";
+ fillColor = "0 0 0 100";
+ category = "Core";
+};
+
+if(!isObject(GuiCheckBoxProfile))
+new GuiControlProfile(GuiCheckBoxProfile)
+{
+ opaque = false;
+ fillColor = "232 232 232";
+ border = false;
+ borderColor = "100 100 100";
+ fontSize = 14;
+ fontColor = "20 20 20";
+ fontColorHL = "80 80 80";
+ fontColorNA = "200 200 200";
+ fixedExtent = true;
+ justify = "left";
+ bitmap = "core/gui/images/checkbox";
+ hasBitmapArray = true;
+ category = "Tools";
+};
+
+if( !isObject( GuiProgressProfile ) )
+new GuiControlProfile( GuiProgressProfile )
+{
+ opaque = false;
+ fillColor = "0 162 255 200";
+ border = true;
+ borderColor = "50 50 50 200";
+ category = "Core";
+};
+
+if( !isObject( GuiProgressBitmapProfile ) )
+new GuiControlProfile( GuiProgressBitmapProfile )
+{
+ border = false;
+ hasBitmapArray = true;
+ bitmap = "core/gui/images/loadingbar";
+ category = "Core";
+};
+
+if( !isObject( GuiProgressTextProfile ) )
+new GuiControlProfile( GuiProgressTextProfile )
+{
+ fontSize = "14";
+ fontType = "Arial";
+ fontColor = "0 0 0";
+ justify = "center";
+ category = "Core";
+};
+
+if( !isObject( GuiButtonProfile ) )
+new GuiControlProfile( GuiButtonProfile )
+{
+ opaque = true;
+ border = true;
+
+ fontColor = "50 50 50";
+ fontColorHL = "0 0 0";
+ fontColorNA = "200 200 200";
+ //fontColorSEL ="0 0 0";
+ fixedExtent = false;
+ justify = "center";
+ canKeyFocus = false;
+ bitmap = "core/gui/images/button";
+ hasBitmapArray = false;
+ category = "Core";
+};
diff --git a/Templates/BaseGame/game/core/lighting/Core_Lighting.cs b/Templates/BaseGame/game/core/lighting/Core_Lighting.cs
new file mode 100644
index 000000000..dc5680b84
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/Core_Lighting.cs
@@ -0,0 +1,20 @@
+
+function Core_Lighting::onCreate(%this)
+{
+ exec("./scripts/lighting.cs");
+
+ //Advanced/Deferred
+ exec("./scripts/advancedLighting_Shaders.cs");
+ exec("./scripts/deferredShading.cs");
+ exec("./scripts/advancedLighting_Init.cs");
+
+ //Basic/Forward
+ exec("./scripts/basicLighting_shadowFilter.cs");
+ exec("./scripts/shadowMaps_Init.cs");
+ exec("./scripts/basicLighting_Init.cs");
+
+}
+
+function Core_Lighting::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/lighting/Core_Lighting.module b/Templates/BaseGame/game/core/lighting/Core_Lighting.module
new file mode 100644
index 000000000..b4619a64a
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/Core_Lighting.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Init.cs b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Init.cs
new file mode 100644
index 000000000..c7d357bb8
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Init.cs
@@ -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.
+//-----------------------------------------------------------------------------
+
+///////////////////////////////////////////////////////////////////////////////
+// Default Prefs
+
+/*
+$pref::LightManager::sgAtlasMaxDynamicLights = "16";
+$pref::LightManager::sgDynamicShadowDetailSize = "0";
+$pref::LightManager::sgDynamicShadowQuality = "0";
+$pref::LightManager::sgLightingProfileAllowShadows = "1";
+$pref::LightManager::sgLightingProfileQuality = "0";
+$pref::LightManager::sgMaxBestLights = "10";
+$pref::LightManager::sgMultipleDynamicShadows = "1";
+$pref::LightManager::sgShowCacheStats = "0";
+$pref::LightManager::sgUseBloom = "";
+$pref::LightManager::sgUseDRLHighDynamicRange = "0";
+$pref::LightManager::sgUseDynamicRangeLighting = "0";
+$pref::LightManager::sgUseDynamicShadows = "1";
+$pref::LightManager::sgUseToneMapping = "";
+*/
+
+//exec( "./shaders.cs" );
+//exec( "./deferredShading.cs" );
+
+function onActivateAdvancedLM()
+{
+ // Enable the offscreen target so that AL will work
+ // with MSAA back buffers and for HDR rendering.
+ AL_FormatToken.enable();
+
+ // Activate Deferred Shading
+ AL_DeferredShading.enable();
+}
+
+function onDeactivateAdvancedLM()
+{
+ // Disable the offscreen render target.
+ AL_FormatToken.disable();
+
+ // Deactivate Deferred Shading
+ AL_DeferredShading.disable();
+}
+
+function setAdvancedLighting()
+{
+ setLightManager( "Advanced Lighting" );
+}
+
diff --git a/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs
new file mode 100644
index 000000000..a73598d9b
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/advancedLighting_Shaders.cs
@@ -0,0 +1,276 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+// Vector Light State
+new GFXStateBlockData( AL_VectorLightState )
+{
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendOne;
+ blendDest = GFXBlendOne;
+ blendOp = GFXBlendOpAdd;
+
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint; // G-buffer
+ mSamplerNames[0] = "deferredBuffer";
+ samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.)
+ mSamplerNames[1] = "shadowMap";
+ samplerStates[2] = SamplerClampPoint; // Shadow Map (Do not change this to linear, as all cards can not filter equally.)
+ mSamplerNames[2] = "dynamicShadowMap";
+ samplerStates[3] = SamplerClampLinear; // SSAO Mask
+ mSamplerNames[3] = "ssaoMask";
+ samplerStates[4] = SamplerWrapPoint; // Random Direction Map
+
+ cullDefined = true;
+ cullMode = GFXCullNone;
+
+ stencilDefined = true;
+ stencilEnable = true;
+ stencilFailOp = GFXStencilOpKeep;
+ stencilZFailOp = GFXStencilOpKeep;
+ stencilPassOp = GFXStencilOpKeep;
+ stencilFunc = GFXCmpLess;
+ stencilRef = 0;
+};
+
+// Vector Light Material
+new ShaderData( AL_VectorLightShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/farFrustumQuadV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/vectorLightP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/farFrustumQuadV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/vectorLightP.glsl";
+
+ samplerNames[0] = "$deferredBuffer";
+ samplerNames[1] = "$shadowMap";
+ samplerNames[2] = "$dynamicShadowMap";
+ samplerNames[3] = "$ssaoMask";
+ samplerNames[4] = "$gTapRotationTex";
+ samplerNames[5] = "$lightBuffer";
+ samplerNames[6] = "$colorBuffer";
+ samplerNames[7] = "$matInfoBuffer";
+
+ pixVersion = 3.0;
+};
+
+new CustomMaterial( AL_VectorLightMaterial )
+{
+ shader = AL_VectorLightShader;
+ stateBlock = AL_VectorLightState;
+
+ sampler["deferredBuffer"] = "#deferred";
+ sampler["shadowMap"] = "$dynamiclight";
+ sampler["dynamicShadowMap"] = "$dynamicShadowMap";
+ sampler["ssaoMask"] = "#ssaoMask";
+ sampler["lightBuffer"] = "#lightinfo";
+ sampler["colorBuffer"] = "#color";
+ sampler["matInfoBuffer"] = "#matinfo";
+
+ target = "lightinfo";
+
+ pixVersion = 3.0;
+};
+
+//------------------------------------------------------------------------------
+
+// Convex-geometry light states
+new GFXStateBlockData( AL_ConvexLightState )
+{
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendOne;
+ blendDest = GFXBlendOne;
+ blendOp = GFXBlendOpAdd;
+
+ zDefined = true;
+ zEnable = true;
+ zWriteEnable = false;
+ zFunc = GFXCmpGreaterEqual;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint; // G-buffer
+ mSamplerNames[0] = "deferredBuffer";
+ samplerStates[1] = SamplerClampPoint; // Shadow Map (Do not use linear, these are perspective projections)
+ mSamplerNames[1] = "shadowMap";
+ samplerStates[2] = SamplerClampPoint; // Shadow Map (Do not use linear, these are perspective projections)
+ mSamplerNames[2] = "dynamicShadowMap";
+ samplerStates[3] = SamplerClampLinear; // Cookie Map
+ samplerStates[4] = SamplerWrapPoint; // Random Direction Map
+
+ cullDefined = true;
+ cullMode = GFXCullCW;
+
+ stencilDefined = true;
+ stencilEnable = true;
+ stencilFailOp = GFXStencilOpKeep;
+ stencilZFailOp = GFXStencilOpKeep;
+ stencilPassOp = GFXStencilOpKeep;
+ stencilFunc = GFXCmpLess;
+ stencilRef = 0;
+};
+
+// Point Light Material
+new ShaderData( AL_PointLightShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/convexGeometryV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/pointLightP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/pointLightP.glsl";
+
+ samplerNames[0] = "$deferredBuffer";
+ samplerNames[1] = "$shadowMap";
+ samplerNames[2] = "$dynamicShadowMap";
+ samplerNames[3] = "$cookieMap";
+ samplerNames[4] = "$gTapRotationTex";
+ samplerNames[5] = "$lightBuffer";
+ samplerNames[6] = "$colorBuffer";
+ samplerNames[7] = "$matInfoBuffer";
+
+ pixVersion = 3.0;
+};
+
+new CustomMaterial( AL_PointLightMaterial )
+{
+ shader = AL_PointLightShader;
+ stateBlock = AL_ConvexLightState;
+
+ sampler["deferredBuffer"] = "#deferred";
+ sampler["shadowMap"] = "$dynamiclight";
+ sampler["dynamicShadowMap"] = "$dynamicShadowMap";
+ sampler["cookieMap"] = "$dynamiclightmask";
+ sampler["lightBuffer"] = "#lightinfo";
+ sampler["colorBuffer"] = "#color";
+ sampler["matInfoBuffer"] = "#matinfo";
+
+ target = "lightinfo";
+
+ pixVersion = 3.0;
+};
+
+// Spot Light Material
+new ShaderData( AL_SpotLightShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/convexGeometryV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/spotLightP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/spotLightP.glsl";
+
+ samplerNames[0] = "$deferredBuffer";
+ samplerNames[1] = "$shadowMap";
+ samplerNames[2] = "$dynamicShadowMap";
+ samplerNames[3] = "$cookieMap";
+ samplerNames[4] = "$gTapRotationTex";
+ samplerNames[5] = "$lightBuffer";
+ samplerNames[6] = "$colorBuffer";
+ samplerNames[7] = "$matInfoBuffer";
+
+ pixVersion = 3.0;
+};
+
+new CustomMaterial( AL_SpotLightMaterial )
+{
+ shader = AL_SpotLightShader;
+ stateBlock = AL_ConvexLightState;
+
+ sampler["deferredBuffer"] = "#deferred";
+ sampler["shadowMap"] = "$dynamiclight";
+ sampler["dynamicShadowMap"] = "$dynamicShadowMap";
+ sampler["cookieMap"] = "$dynamiclightmask";
+ sampler["lightBuffer"] = "#lightinfo";
+ sampler["colorBuffer"] = "#color";
+ sampler["matInfoBuffer"] = "#matinfo";
+
+ target = "lightinfo";
+
+ pixVersion = 3.0;
+};
+
+/// This material is used for generating deferred
+/// materials for objects that do not have materials.
+new Material( AL_DefaultDeferredMaterial )
+{
+ // We need something in the first pass else it
+ // won't create a proper material instance.
+ //
+ // We use color here because some objects may not
+ // have texture coords in their vertex format...
+ // for example like terrain.
+ //
+ diffuseColor[0] = "1 1 1 1";
+};
+
+/// This material is used for generating shadow
+/// materials for objects that do not have materials.
+new Material( AL_DefaultShadowMaterial )
+{
+ // We need something in the first pass else it
+ // won't create a proper material instance.
+ //
+ // We use color here because some objects may not
+ // have texture coords in their vertex format...
+ // for example like terrain.
+ //
+ diffuseColor[0] = "1 1 1 1";
+
+ // This is here mostly for terrain which uses
+ // this material to create its shadow material.
+ //
+ // At sunset/sunrise the sun is looking thru
+ // backsides of the terrain which often are not
+ // closed. By changing the material to be double
+ // sided we avoid holes in the shadowed geometry.
+ //
+ doubleSided = true;
+};
+
+// Particle System Point Light Material
+new ShaderData( AL_ParticlePointLightShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/particlePointLightV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/particlePointLightP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/convexGeometryV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/pointLightP.glsl";
+
+ samplerNames[0] = "$deferredBuffer";
+
+ pixVersion = 3.0;
+};
+
+new CustomMaterial( AL_ParticlePointLightMaterial )
+{
+ shader = AL_ParticlePointLightShader;
+ stateBlock = AL_ConvexLightState;
+
+ sampler["deferredBuffer"] = "#deferred";
+ target = "lightinfo";
+
+ pixVersion = 3.0;
+};
diff --git a/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs
new file mode 100644
index 000000000..99be20c5c
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_Init.cs
@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//exec( "./shadowFilter.cs" );
+
+singleton GFXStateBlockData( BL_ProjectedShadowSBData )
+{
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendDestColor;
+ blendDest = GFXBlendZero;
+
+ zDefined = true;
+ zEnable = true;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ vertexColorEnable = true;
+};
+
+singleton ShaderData( BL_ProjectedShadowShaderData )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/projectedShadowV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/projectedShadowP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/projectedShadowV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/projectedShadowP.glsl";
+
+ samplerNames[0] = "inputTex";
+
+ pixVersion = 2.0;
+};
+
+singleton CustomMaterial( BL_ProjectedShadowMaterial )
+{
+ sampler["inputTex"] = "$miscbuff";
+
+ shader = BL_ProjectedShadowShaderData;
+ stateBlock = BL_ProjectedShadowSBData;
+ version = 2.0;
+ forwardLit = true;
+};
+
+function onActivateBasicLM()
+{
+ // If HDR is enabled... enable the special format token.
+ if ( $platform !$= "macos" && HDRPostFx.isEnabled )
+ AL_FormatToken.enable();
+
+ // Create render pass for projected shadow.
+ new RenderPassManager( BL_ProjectedShadowRPM );
+
+ // Create the mesh bin and add it to the manager.
+ %meshBin = new RenderMeshMgr();
+ BL_ProjectedShadowRPM.addManager( %meshBin );
+
+ // Add both to the root group so that it doesn't
+ // end up in the MissionCleanup instant group.
+ RootGroup.add( BL_ProjectedShadowRPM );
+ RootGroup.add( %meshBin );
+}
+
+function onDeactivateBasicLM()
+{
+ // Delete the pass manager which also deletes the bin.
+ BL_ProjectedShadowRPM.delete();
+}
+
+function setBasicLighting()
+{
+ setLightManager( "Basic Lighting" );
+}
diff --git a/Templates/BaseGame/game/core/lighting/scripts/basicLighting_shadowFilter.cs b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_shadowFilter.cs
new file mode 100644
index 000000000..5aea7b607
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/basicLighting_shadowFilter.cs
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+singleton ShaderData( BL_ShadowFilterShaderV )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/basic/shadowFilterV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/basic/shadowFilterP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/basic/gl/shadowFilterV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/basic/gl/shadowFilterP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+
+ defines = "BLUR_DIR=float2(1.0,0.0)";
+
+ pixVersion = 2.0;
+};
+
+singleton ShaderData( BL_ShadowFilterShaderH : BL_ShadowFilterShaderV )
+{
+ defines = "BLUR_DIR=float2(0.0,1.0)";
+};
+
+
+singleton GFXStateBlockData( BL_ShadowFilterSB : PFX_DefaultStateBlock )
+{
+ colorWriteDefined=true;
+ colorWriteRed=false;
+ colorWriteGreen=false;
+ colorWriteBlue=false;
+ blendDefined = true;
+ blendEnable = true;
+};
+
+// NOTE: This is ONLY used in Basic Lighting, and
+// only directly by the ProjectedShadow. It is not
+// meant to be manually enabled like other PostEffects.
+singleton PostEffect( BL_ShadowFilterPostFx )
+{
+ // Blur vertically
+ shader = BL_ShadowFilterShaderV;
+ stateBlock = PFX_DefaultStateBlock;
+ targetClear = "PFXTargetClear_OnDraw";
+ targetClearColor = "0 0 0 0";
+ texture[0] = "$inTex";
+ target = "$outTex";
+
+ // Blur horizontal
+ new PostEffect()
+ {
+ shader = BL_ShadowFilterShaderH;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ };
+};
diff --git a/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs b/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs
new file mode 100644
index 000000000..5dbacd2e3
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/deferredShading.cs
@@ -0,0 +1,71 @@
+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";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/deferredColorShaderP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/deferredColorShaderP.glsl";
+
+ pixVersion = 2.0;
+};
+
+// Primary Deferred Shader
+new GFXStateBlockData( AL_DeferredShadingState : PFX_DefaultStateBlock )
+{
+ cullMode = GFXCullNone;
+
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendSrcAlpha;
+ blendDest = GFXBlendInvSrcAlpha;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerWrapLinear;
+ samplerStates[1] = SamplerWrapLinear;
+ samplerStates[2] = SamplerWrapLinear;
+ samplerStates[3] = SamplerWrapLinear;
+ samplerStates[4] = SamplerWrapLinear;
+};
+
+new ShaderData( AL_DeferredShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/deferredShadingP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/advanced/gl/deferredShadingP.glsl";
+
+ samplerNames[0] = "colorBufferTex";
+ samplerNames[1] = "lightDeferredTex";
+ samplerNames[2] = "matInfoTex";
+ samplerNames[3] = "deferredTex";
+
+ pixVersion = 2.0;
+};
+
+singleton PostEffect( AL_DeferredShading )
+{
+ renderTime = "PFXAfterBin";
+ renderBin = "SkyBin";
+ shader = AL_DeferredShader;
+ stateBlock = AL_DeferredShadingState;
+ texture[0] = "#color";
+ texture[1] = "#lightinfo";
+ texture[2] = "#matinfo";
+ texture[3] = "#deferred";
+
+ target = "$backBuffer";
+ renderPriority = 10000;
+ allowReflectPass = true;
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/lighting/scripts/lighting.cs b/Templates/BaseGame/game/core/lighting/scripts/lighting.cs
new file mode 100644
index 000000000..b7d4034ff
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/lighting.cs
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function initLightingSystems(%manager)
+{
+ echo( "\nInitializing Lighting Systems" );
+
+ // First exec the scripts for the different light managers
+ // in the lighting folder.
+ /*%pattern = "./lighting/*//*init.cs";
+ %file = findFirstFile( %pattern );
+ if ( %file $= "" )
+ {
+ // Try for DSOs next.
+ %pattern = "./lighting/*//*init.cs.dso";
+ %file = findFirstFile( %pattern );
+ }
+
+ while( %file !$= "" )
+ {
+ exec( %file );
+ %file = findNextFile( %pattern );
+ }*/
+
+ // Try the perfered one first.
+ %success = setLightManager(%manager);
+
+ // Did we completely fail to initialize a light manager?
+ if (!%success)
+ {
+ // If we completely failed to initialize a light
+ // manager then the 3d scene cannot be rendered.
+ quitWithErrorMessage( "Failed to set a light manager!" );
+ }
+}
+
+//---------------------------------------------------------------------------------------------
+
+function onLightManagerActivate( %lmName )
+{
+ // Call activation callbacks.
+ %activateNewFn = "onActivate" @ getWord( %lmName, 0 ) @ "LM";
+ if( isFunction( %activateNewFn ) )
+ eval( %activateNewFn @ "();" );
+}
+
+//---------------------------------------------------------------------------------------------
+
+function onLightManagerDeactivate( %lmName )
+{
+ // Call deactivation callback.
+ %deactivateOldFn = "onDeactivate" @ getWord( %lmName, 0 ) @ "LM";
+ if( isFunction( %deactivateOldFn ) )
+ eval( %deactivateOldFn @ "();" );
+}
diff --git a/Templates/BaseGame/game/core/lighting/scripts/shadowMaps_Init.cs b/Templates/BaseGame/game/core/lighting/scripts/shadowMaps_Init.cs
new file mode 100644
index 000000000..f4875bf08
--- /dev/null
+++ b/Templates/BaseGame/game/core/lighting/scripts/shadowMaps_Init.cs
@@ -0,0 +1,32 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+new ShaderData(BlurDepthShader)
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/lighting/shadowMap/boxFilterV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/lighting/shadowMap/boxFilterP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/lighting/shadowMap/gl/boxFilterV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/lighting/shadowMap/gl/boxFilterP.glsl";
+ pixVersion = 2.0;
+};
diff --git a/Templates/BaseGame/game/core/postFX/Core_PostFX.cs b/Templates/BaseGame/game/core/postFX/Core_PostFX.cs
new file mode 100644
index 000000000..d36d912ab
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/Core_PostFX.cs
@@ -0,0 +1,33 @@
+
+function Core_PostFX::onCreate(%this)
+{
+ //
+ exec("./scripts/postFx.cs");
+ /*exec("./scripts/postFxManager.gui.cs");
+ exec("./scripts/postFxManager.gui.settings.cs");
+ exec("./scripts/postFxManager.persistance.cs");
+
+ exec("./scripts/default.postfxpreset.cs");
+
+ exec("./scripts/caustics.cs");
+ exec("./scripts/chromaticLens.cs");
+ exec("./scripts/dof.cs");
+ exec("./scripts/edgeAA.cs");
+ exec("./scripts/flash.cs");
+ exec("./scripts/fog.cs");
+ exec("./scripts/fxaa.cs");
+ exec("./scripts/GammaPostFX.cs");
+ exec("./scripts/glow.cs");
+ exec("./scripts/hdr.cs");
+ exec("./scripts/lightRay.cs");
+ exec("./scripts/MLAA.cs");
+ exec("./scripts/MotionBlurFx.cs");
+ exec("./scripts/ovrBarrelDistortion.cs");
+ exec("./scripts/ssao.cs");
+ exec("./scripts/turbulence.cs");
+ exec("./scripts/vignette.cs");*/
+}
+
+function Core_PostFX::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/Core_PostFX.module b/Templates/BaseGame/game/core/postFX/Core_PostFX.module
new file mode 100644
index 000000000..627a32d94
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/Core_PostFX.module
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/guis/postFxManager.gui b/Templates/BaseGame/game/core/postFX/guis/postFxManager.gui
new file mode 100644
index 000000000..6a704eb65
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/guis/postFxManager.gui
@@ -0,0 +1,2755 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = new GuiControl(PostFXManager) {
+ position = "0 0";
+ extent = "1024 768";
+ minExtent = "8 8";
+ horizSizing = "width";
+ vertSizing = "height";
+ profile = "GuiModelessDialogProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "1";
+
+ new DbgFileView() {
+ position = "0 0";
+ extent = "8 2";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiWindowCtrl(ppOptionsWindow) {
+ text = "PostFX Manager";
+ resizeWidth = "0";
+ resizeHeight = "0";
+ canMove = "1";
+ canClose = "1";
+ canMinimize = "0";
+ canMaximize = "0";
+ canCollapse = "0";
+ closeCommand = "Canvas.popDialog(PostFXManager);";
+ edgeSnap = "0";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "306 216";
+ extent = "411 336";
+ minExtent = "8 8";
+ horizSizing = "center";
+ vertSizing = "center";
+ profile = "GuiWindowProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiBitmapBorderCtrl() {
+ position = "11 77";
+ extent = "390 216";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBorderProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTabBookCtrl(ppOptionsTabBook) {
+ tabPosition = "Top";
+ tabMargin = "7";
+ minTabWidth = "32";
+ tabHeight = "20";
+ allowReorder = "0";
+ defaultPage = "-1";
+ selectedPage = "1";
+ frontTabPadding = "0";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "11 58";
+ extent = "394 233";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBookProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTabPageCtrl(ppOptionsSSAOTab) {
+ fitBook = "0";
+ text = "SSAO";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "394 213";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Options for the Screen Space Ambient Occlusion postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiBitmapBorderCtrl() {
+ position = "12 30";
+ extent = "365 170";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBorderProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "1";
+ };
+ new GuiTabBookCtrl(ppOptionsSSAOOptions) {
+ tabPosition = "Top";
+ tabMargin = "7";
+ minTabWidth = "64";
+ tabHeight = "20";
+ allowReorder = "0";
+ defaultPage = "-1";
+ selectedPage = "2";
+ frontTabPadding = "0";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "12 11";
+ extent = "362 185";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBookProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTabPageCtrl(ppOptionsSSAOGeneralTab) {
+ fitBook = "0";
+ text = "General";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "362 165";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains general overall settings for the SSAO postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTextCtrl(ppOptionsSSAOOverallStrengthLabel) {
+ text = "Overall Strength";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "31 57";
+ extent = "77 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the overall strength of the Ambient Occlusion effect.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOBlurDepthLabel) {
+ text = "Blur (Softness)";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "38 85";
+ extent = "73 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the amount of softness in the SSAO, overall.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOBlurNormalLabel) {
+ text = "Blur (Normal Maps)";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "19 112";
+ extent = "92 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the amount of softness in the SSAO, in the normal maps.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiPopUpMenuCtrl(ppOptionsSSAOQuality) {
+ maxPopupHeight = "200";
+ sbUsesNAColor = "0";
+ reverseTextList = "0";
+ bitmapBounds = "16 16";
+ text = "Low";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "120 28";
+ extent = "211 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiPopUpMenuProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOQualityLabel) {
+ text = "Quality";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "76 29";
+ extent = "32 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOOverallStrength) {
+ range = "0 50";
+ ticks = "1000";
+ snap = "0";
+ value = "2";
+ position = "120 56";
+ extent = "211 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOBlurDepth) {
+ range = "0 0.3";
+ ticks = "1000";
+ snap = "0";
+ value = "0.001";
+ position = "120 86";
+ extent = "211 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOBlurNormal) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.95";
+ position = "119 113";
+ extent = "212 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsSSAONearTab) {
+ fitBook = "0";
+ text = "Near";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "362 165";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings for the near range ambient occlusion aspect of the SSAO postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiSliderCtrl(ppOptionsSSAONearRadius) {
+ range = "0.001 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.1";
+ position = "122 17";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAONearDepthMin) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.1";
+ position = "122 62";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAONearStrength) {
+ range = "0 20";
+ ticks = "1000";
+ snap = "0";
+ value = "6";
+ position = "122 39";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearRadiusLabel) {
+ text = "Radius";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "80 16";
+ extent = "34 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the near/small radius SSAO reach.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearStrengthLabel) {
+ text = "Strength";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "73 38";
+ extent = "41 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the near/small radius SSAO strength.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearDepthMinLabel) {
+ text = "Depth Min";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "66 61";
+ extent = "48 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the near/small radius SSAO minimum depth value.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearDepthMaxLabel) {
+ text = "Depth Max";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "62 85";
+ extent = "52 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the near/small radius SSAO maximum depth value.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAONearDepthMax) {
+ range = "0 50";
+ ticks = "1000";
+ snap = "0";
+ value = "1";
+ position = "122 86";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAONearToleranceNormal) {
+ range = "0 2";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "122 133";
+ extent = "103 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAONearTolerancePower) {
+ range = "0 2";
+ ticks = "1000";
+ snap = "0";
+ value = "1";
+ position = "246 133";
+ extent = "97 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearToleranceLabel2) {
+ text = "Tolerance / Power";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "24 132";
+ extent = "92 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAONearToleranceLabel1) {
+ text = "Normal Maps : ";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "19 113";
+ extent = "71 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsSSAOFarTab) {
+ fitBook = "0";
+ text = "Far";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "362 165";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings for the far range ambient occlusion aspect of the SSAO postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTextCtrl(ppOptionsSSAOFarRadiusLabel) {
+ text = "Radius";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "80 16";
+ extent = "34 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the far/large radius SSAO reach.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarRadius) {
+ range = "0.001 5";
+ ticks = "1000";
+ snap = "0";
+ value = "1";
+ position = "122 17";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOFarStrengthLabel) {
+ text = "Strength";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "73 38";
+ extent = "41 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the far/large radius SSAO strength.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarStrength) {
+ range = "0 20";
+ ticks = "1000";
+ snap = "0";
+ value = "10";
+ position = "122 39";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOFarDepthMinLabel) {
+ text = "Depth Min";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "66 61";
+ extent = "48 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the far/large radius SSAO minimum depth.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarDepthMin) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.2";
+ position = "122 62";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOFarDepthMaxLabel) {
+ text = "Depth Max";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "62 85";
+ extent = "52 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the far/large radius SSAO maximum.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarDepthMax) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "2";
+ position = "122 86";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsSSAOFarToleranceLabel1) {
+ text = "Normal Maps :";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "6 113";
+ extent = "72 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl() {
+ text = "Tolerance / Power";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "24 132";
+ extent = "90 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarToleranceNormal) {
+ range = "0 2";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "122 133";
+ extent = "100 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsSSAOFarTolerancePower) {
+ range = "0 2";
+ ticks = "1000";
+ snap = "0";
+ value = "2";
+ position = "239 133";
+ extent = "104 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnableSSAO) {
+ useInactiveState = "0";
+ text = "Enable";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "329 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable/Disable the SSAO postFX";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsHDRTab) {
+ fitBook = "0";
+ text = "HDR";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "394 213";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Options for the High Definition Range Lighting postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiBitmapBorderCtrl() {
+ position = "12 30";
+ extent = "363 172";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBorderProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "1";
+ };
+ new GuiTabBookCtrl(ppOptionsHDROptions) {
+ tabPosition = "Top";
+ tabMargin = "7";
+ minTabWidth = "64";
+ tabHeight = "20";
+ allowReorder = "0";
+ defaultPage = "-1";
+ selectedPage = "0";
+ frontTabPadding = "0";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "12 11";
+ extent = "365 195";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBookProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTabPageCtrl(ppOptionsHDRBrightnessTab) {
+ fitBook = "0";
+ text = "Brightness";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "365 175";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings related to the brightness of the HDR postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiSliderCtrl(ppOptionsHDRMinLuminance) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "132 77";
+ extent = "206 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 0";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRKeyValue) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.0459184";
+ position = "132 50";
+ extent = "206 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 0.0459184";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRKeyValueLabel) {
+ text = "Key Value";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "69 50";
+ extent = "52 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The tone mapping middle grey or exposure value used to adjust the overall \"balance\" of the image.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRMinLuminanceLabel) {
+ text = "Minimum Luminance";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "25 77";
+ extent = "96 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The minimum luminance value to allow when tone mapping the scene. This is particularly useful if your scene is very dark or has a black ambient color in places.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRWhiteCutoffLabel) {
+ text = "White Cutoff";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "56 104";
+ extent = "65 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The cutoff level for the white levels in the brightness.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRWhiteCutoff) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.52551";
+ position = "132 104";
+ extent = "206 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 0.52551";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRBrightnessAdaptRate) {
+ range = "0.1 10";
+ ticks = "1000";
+ snap = "0";
+ value = "2";
+ position = "132 132";
+ extent = "205 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRBrightnessAdaptRateLabel) {
+ text = "Brightness Adapt Rate";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "12 132";
+ extent = "109 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The speed at which the view adjusts to the new lighting in the environment.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRKeyValueLabel1) {
+ text = "Tone Mapping Contrast";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "10 24";
+ extent = "111 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Tone mapping contrast is the amount of scene to blend, with the tone mapped HDR scene. Lower values are recommended but higher values give a strong contrasted darker shadowed look.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRToneMappingAmount) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.265306";
+ position = "132 24";
+ extent = "206 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "value : 0.265306";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsHDRBloomTab) {
+ fitBook = "0";
+ text = "Bloom";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "365 175";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings related to the blooming aspect of the HDR postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiSliderCtrl(ppOptionsHDRBloomBlurMultiplier) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.502645";
+ position = "132 70";
+ extent = "199 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 0.502645";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRBloomBlurMean) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.510526";
+ position = "132 97";
+ extent = "200 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 0.510526";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRBloomBlurStdDev) {
+ range = "0 3";
+ ticks = "1000";
+ snap = "0";
+ value = "1.4127";
+ position = "132 123";
+ extent = "199 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 1.4127";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRBlurMultiplierLabel) {
+ text = "Blur Multiplier";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "59 70";
+ extent = "63 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The amount of blur to apply to the bloomed areas in the HDR.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRBlurMeanLabel) {
+ text = "Blur \"mean\" value";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "38 97";
+ extent = "84 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRBlurStandardDevianceLabel) {
+ text = "Blur \"Std Dev\" value";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "23 123";
+ extent = "99 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsHDRBloomBrightPassThresholdLabel) {
+ text = "Bright pass threshold";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "19 43";
+ extent = "103 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The bright pass threshold controls how bright the brightest areas of the scene are in the HDR.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsHDRBloomBlurBrightPassThreshold) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "1.60526";
+ position = "132 43";
+ extent = "200 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Value : 1.60526";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ppOptionsHDRBloom) {
+ useInactiveState = "0";
+ text = " Enable Bloom";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "250 9";
+ extent = "85 24";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enables or disables the bloom (glowing effect) of the HDR PostFX.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsHDRBloomEffectsTab) {
+ fitBook = "0";
+ text = "Effects";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "365 175";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings related to the effects the HDR postFX can offer";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiCheckBoxCtrl(ppOptionsHDREffectsBlueShift) {
+ useInactiveState = "0";
+ text = " Enable Color Shift";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "11 4";
+ extent = "117 24";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enables a scene tinting/Blue shift based on the color selected below.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBlend) {
+ baseColor = "1 0 0.0235294 1";
+ pickColor = "0 0 0 1";
+ selectorGap = "1";
+ displayMode = "BlendColor";
+ actionOnMove = "1";
+ showReticle = "1";
+ position = "10 29";
+ extent = "344 110";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Select a color";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiColorPickerCtrl(ppOptionsHDREffectsBlueShiftColorBaseColor) {
+ baseColor = "1 0 0.0235294 1";
+ pickColor = "0 0 0 1";
+ selectorGap = "1";
+ displayMode = "HorizColor";
+ actionOnMove = "1";
+ showReticle = "1";
+ position = "10 142";
+ extent = "343 21";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiDefaultProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Select a color";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ };
+ new GuiCheckBoxCtrl(ppOptionsHDRToneMapping) {
+ useInactiveState = "0";
+ text = " Enable Tone Mapping";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "18 8";
+ extent = "120 24";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enables or disabled tone mapping on the HDR. The tone mapping balanced the brightness levels during the HDR process. Recommended";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnableHDR) {
+ useInactiveState = "0";
+ text = "Enable";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "329 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable/Disable the HDR postFX (takes some time to initialise, be patient)";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnableHDRDebug) {
+ useInactiveState = "0";
+ text = "Debug";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "262 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsLightRaysTab) {
+ fitBook = "0";
+ text = "Light Rays";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "394 213";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Options for the Light Rays postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiSliderCtrl(ppOptionsLightRaysBrightScalar) {
+ range = "0 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.75";
+ position = "96 46";
+ extent = "264 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsLightRaysBrightnessScalarLabel) {
+ text = "Brightness";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 48";
+ extent = "87 15";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls how bright the rays and the object casting them are in the scene.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiSliderCtrl(ppOptionsLightRaysSampleScalar) {
+ range = "20 512";
+ ticks = "512";
+ snap = "0";
+ value = "40";
+ position = "96 75";
+ extent = "264 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiTextCtrl(ppOptionsLightRaysSampleScalarLabel) {
+ text = "Samples";
+ maxLength = "512";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 76";
+ extent = "87 15";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the number of samples for the shader.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiSliderCtrl(ppOptionsLightRaysDensityScalar) {
+ range = "0.01 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0.94";
+ position = "96 105";
+ extent = "264 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiTextCtrl(ppOptionsLightRaysDensityScalarLabel) {
+ text = "Density";
+ maxLength = "1000";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 106";
+ extent = "87 15";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the density of the rays.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiSliderCtrl(ppOptionsLightRaysWeightScalar) {
+ range = "0.1 10";
+ ticks = "1000";
+ snap = "0";
+ value = "5.65";
+ position = "96 135";
+ extent = "264 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiTextCtrl(ppOptionsLightRaysWeightScalarLabel) {
+ text = "Weight";
+ maxLength = "1000";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 136";
+ extent = "87 15";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the weight of the rays.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+
+ new GuiSliderCtrl(ppOptionsLightRaysDecayScalar) {
+ range = "0.01 1";
+ ticks = "1000";
+ snap = "0";
+ value = "1.0";
+ position = "96 165";
+ extent = "264 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+
+ new GuiTextCtrl(ppOptionsLightRaysDecayScalarLabel) {
+ text = "Decay";
+ maxLength = "1000";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 166";
+ extent = "87 15";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the decay of the rays.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnableLightRays) {
+ useInactiveState = "0";
+ text = "Enable";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "329 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable/Disable the light rays postFX";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsDOFTab) {
+ fitBook = "0";
+ text = "DOF";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "394 213";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Options for the Depth Of Field postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiBitmapBorderCtrl() {
+ position = "14 28";
+ extent = "362 170";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBorderProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "1";
+ };
+ new GuiTabBookCtrl() {
+ tabPosition = "Top";
+ tabMargin = "7";
+ minTabWidth = "64";
+ tabHeight = "20";
+ allowReorder = "0";
+ defaultPage = "-1";
+ selectedPage = "1";
+ frontTabPadding = "0";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "14 9";
+ extent = "360 189";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabBookProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTabPageCtrl(ppOptionsDOFGeneralTab) {
+ fitBook = "0";
+ text = "General";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "360 169";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "0";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains general settings related to the DOF system";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ //new GuiCheckBoxCtrl(ppOptionsDOFEnableDOF) {
+ //useInactiveState = "0";
+ //text = "Enable DOF";
+ //groupNum = "-1";
+ //buttonType = "ToggleButton";
+ //useMouseEvents = "0";
+ //position = "31 43";
+ //extent = "140 30";
+ //minExtent = "8 2";
+ //horizSizing = "right";
+ //vertSizing = "bottom";
+ //profile = "GuiCheckBoxProfile";
+ //visible = "1";
+ //active = "1";
+ //tooltipProfile = "GuiToolTipProfile";
+ //hovertime = "1000";
+ //isContainer = "0";
+ //canSave = "1";
+ //canSaveDynamicFields = "0";
+ //};
+ new GuiCheckBoxCtrl(ppOptionsDOFEnableAutoFocus) {
+ useInactiveState = "0";
+ text = "Enable Auto Focus";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "31 8";
+ extent = "140 30";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsDOFAutoFocusTab) {
+ fitBook = "0";
+ text = "Auto Focus";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 20";
+ extent = "360 169";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Contains settings related to the fine control of the auto focus system";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTextCtrl(ppOptionsDOFNearBlurMaxLabel) {
+ text = "Near Blur Max";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "36 8";
+ extent = "67 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The max allowed value of near blur";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFFarBlurMinSlider) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "120 8";
+ extent = "224 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsDOFFarBlurMaxLabel) {
+ text = "Far Blur Max";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "43 34";
+ extent = "60 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The max allowed value of far blur";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFFarBlurMaxSlider) {
+ range = "0 1";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "120 34";
+ extent = "224 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsDOFFocusRangeMinLabel) {
+ text = "Focus Range (Min)";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "13 61";
+ extent = "90 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The distance range around the focal distance that remains in focus (in meters, minimum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFFocusRangeMinSlider) {
+ range = "0.01 1e+003";
+ ticks = "1000";
+ snap = "0";
+ value = "0.01";
+ position = "120 61";
+ extent = "224 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsDOFFocusRangeMaxLabel) {
+ text = "Focus Range (Max)";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "9 88";
+ extent = "95 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "The distance range around the focal distance that remains in focus (in meters, maximum distance in focus) focal distance it is\r\ndependant on the visible distance set in your level";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFFocusRangeMaxSlider) {
+ range = "0.01 1e+003";
+ ticks = "1000";
+ snap = "0";
+ value = "0.01";
+ position = "119 87";
+ extent = "224 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsDOFBurCurveNearLabel) {
+ text = "Blur Curve Near";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "27 114";
+ extent = "77 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFBlurCurveNearSlider) {
+ range = "0 50";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "119 114";
+ extent = "225 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsDOFBlurCurveFarLabel) {
+ text = "Blur Curve Far";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "33 139";
+ extent = "70 16";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "A small number causes bluriness to increase gradually\r\nat distances closer than the focal distance. A large number causes bluriness to \r\nincrease quickly";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsDOFBlurCurveFarSlider) {
+ range = "0 50";
+ ticks = "1000";
+ snap = "0";
+ value = "0";
+ position = "119 141";
+ extent = "224 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnableDOF) {
+ useInactiveState = "0";
+ text = "Enable";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "329 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable/Disable the Depth of field postFX";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl(ppOptionsVignetteTab) {
+ fitBook = "0";
+ text = "Vignette";
+ maxLength = "1024";
+ docking = "Client";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "1";
+ anchorLeft = "1";
+ anchorRight = "1";
+ position = "0 40";
+ extent = "394 193";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Options for the Vignette postFX";
+ hovertime = "1000";
+ isContainer = "1";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ Enabled = "1";
+
+ new GuiCheckBoxCtrl(ppOptionsEnableVignette) {
+ text = "Enable";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "329 7";
+ extent = "53 20";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable/Disable the vignette postFX";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiSliderCtrl(ppOptionsVignetteVMax) {
+ range = "0.001 5";
+ ticks = "1000";
+ snap = "0";
+ value = "0.6";
+ position = "96 46";
+ extent = "221 17";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiSliderBoxProfile";
+ visible = "1";
+ active = "1";
+ variable = "$VignettePostEffect::VMax";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsVignetteVMaxLabel) {
+ text = "Radius";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "26 48";
+ extent = "41 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Controls the maximum exposure of vignetting.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ new GuiTabPageCtrl() {
+ fitBook = "0";
+ text = "Color Correction";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "8 27";
+ extent = "376 200";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTabPageProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ internalName = "ColorCorrectionTab";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+
+ new GuiTextCtrl() {
+ text = "Color Correction Ramp";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "6 7";
+ extent = "118 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() {
+ historySize = "0";
+ tabComplete = "0";
+ sinkAllKeyEvents = "0";
+ password = "0";
+ passwordMask = "*";
+ text = "core/postFX/images/null_color_ramp.png";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "6 29";
+ extent = "365 18";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextEditProfile";
+ visible = "1";
+ active = "1";
+ altCommand = "ppColorCorrection_selectFileHandler( $thisControl.getText() );";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "1";
+ internalName = "ColorCorrectionFileName";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiButtonCtrl() {
+ text = "Select...";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "252 54";
+ extent = "56 22";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "ppColorCorrection_selectFile();";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ internalName = "ColorCorrectionButton";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiButtonCtrl() {
+ text = "Reset";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "315 54";
+ extent = "56 22";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "ppColorCorrection_selectFileHandler( \"\" );";
+ tooltipProfile = "GuiToolTipProfile";
+ hovertime = "1000";
+ isContainer = "0";
+ internalName = "ColorCorrectionReset";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+ };
+ new GuiButtonCtrl(ppOptionsApply) {
+ text = "Apply";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "309 302";
+ extent = "93 23";
+ minExtent = "8 8";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "PostFXManager.settingsApplyAll(); Canvas.popDialog(PostFXManager);";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Apply the settings and close this dialog";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiButtonCtrl(ppOptionsSavePreset) {
+ text = "Save Preset...";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "111 302";
+ extent = "93 23";
+ minExtent = "8 8";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "PostFXManager.savePresetFile();";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Save the preset to a file to disk for later use (use postfx::applyPreset)";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiButtonCtrl(ppOptionsLoadPreset) {
+ text = "Load Preset...";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "12 302";
+ extent = "93 23";
+ minExtent = "8 8";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "PostFXManager.loadPresetFile();";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Load a post FX preset file from disk";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiCheckBoxCtrl(ppOptionsEnable) {
+ useInactiveState = "0";
+ text = "Enable PostFX System";
+ groupNum = "-1";
+ buttonType = "ToggleButton";
+ useMouseEvents = "0";
+ position = "13 24";
+ extent = "127 30";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiCheckBoxProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Enable or Disable the postFX system";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiPopUpMenuCtrl(ppOptionsQuality) {
+ maxPopupHeight = "200";
+ sbUsesNAColor = "0";
+ reverseTextList = "0";
+ bitmapBounds = "16 16";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "278 30";
+ extent = "122 21";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiPopUpMenuProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiTextCtrl(ppOptionsQualityLabel) {
+ text = "Quality";
+ maxLength = "1024";
+ margin = "0 0 0 0";
+ padding = "0 0 0 0";
+ anchorTop = "1";
+ anchorBottom = "0";
+ anchorLeft = "1";
+ anchorRight = "0";
+ position = "238 32";
+ extent = "39 12";
+ minExtent = "8 2";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiTextProfile";
+ visible = "1";
+ active = "1";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Used to adjust the quality/performance settings of the PostFX system. Some PostFX may not adhere to the settings in this dialog.";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ new GuiButtonCtrl(ppOptionsOk1) {
+ text = "Revert";
+ groupNum = "-1";
+ buttonType = "PushButton";
+ useMouseEvents = "0";
+ position = "210 302";
+ extent = "93 23";
+ minExtent = "8 8";
+ horizSizing = "right";
+ vertSizing = "bottom";
+ profile = "GuiButtonProfile";
+ visible = "1";
+ active = "1";
+ command = "postProcessOptionsDlg.applySettings(); Canvas.popDialog(postProcessOptionsDlg);";
+ tooltipProfile = "GuiToolTipProfile";
+ tooltip = "Revert any changes made since opening the dialog";
+ hovertime = "1000";
+ isContainer = "0";
+ canSave = "1";
+ canSaveDynamicFields = "0";
+ };
+ };
+};
+//--- OBJECT WRITE END ---
diff --git a/Templates/BaseGame/game/core/postFX/images/AreaMap33.dds b/Templates/BaseGame/game/core/postFX/images/AreaMap33.dds
new file mode 100644
index 000000000..e01982a94
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/AreaMap33.dds differ
diff --git a/Templates/BaseGame/game/core/postFX/images/caustics_1.png b/Templates/BaseGame/game/core/postFX/images/caustics_1.png
new file mode 100644
index 000000000..49821ad0f
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/caustics_1.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/caustics_2.png b/Templates/BaseGame/game/core/postFX/images/caustics_2.png
new file mode 100644
index 000000000..99097fa0e
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/caustics_2.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/inactive-overlay.png b/Templates/BaseGame/game/core/postFX/images/inactive-overlay.png
new file mode 100644
index 000000000..feab83209
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/inactive-overlay.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/materials.cs b/Templates/BaseGame/game/core/postFX/images/materials.cs
new file mode 100644
index 000000000..a13c751b3
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/images/materials.cs
@@ -0,0 +1,32 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton Material( Empty )
+{
+};
+
+singleton Material(WarningMaterial) {
+ detailMap[0] = "missingTexture";
+ diffuseColor[0] = "25 16 0";
+ emissive[0] = false;
+ translucent = false;
+};
diff --git a/Templates/BaseGame/game/core/postFX/images/missingTexture.png b/Templates/BaseGame/game/core/postFX/images/missingTexture.png
new file mode 100644
index 000000000..80a7874da
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/missingTexture.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/noise.png b/Templates/BaseGame/game/core/postFX/images/noise.png
new file mode 100644
index 000000000..ebff74256
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/noise.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/null_color_ramp.png b/Templates/BaseGame/game/core/postFX/images/null_color_ramp.png
new file mode 100644
index 000000000..5f5a52186
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/null_color_ramp.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/unavailable.png b/Templates/BaseGame/game/core/postFX/images/unavailable.png
new file mode 100644
index 000000000..9d818a376
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/unavailable.png differ
diff --git a/Templates/BaseGame/game/core/postFX/images/warnMat.dds b/Templates/BaseGame/game/core/postFX/images/warnMat.dds
new file mode 100644
index 000000000..ea99dcbd7
Binary files /dev/null and b/Templates/BaseGame/game/core/postFX/images/warnMat.dds differ
diff --git a/Templates/BaseGame/game/core/postFX/scripts/GammaPostFX.cs b/Templates/BaseGame/game/core/postFX/scripts/GammaPostFX.cs
new file mode 100644
index 000000000..293d44714
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/GammaPostFX.cs
@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( GammaShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gammaP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/gammaP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+ samplerNames[1] = "$colorCorrectionTex";
+
+ pixVersion = 2.0;
+};
+
+singleton GFXStateBlockData( GammaStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+};
+
+singleton PostEffect( GammaPostFX )
+{
+ isEnabled = true;
+ allowReflectPass = true;
+
+ renderTime = "PFXBeforeBin";
+ renderBin = "EditorBin";
+ renderPriority = 9998;
+
+ shader = GammaShader;
+ stateBlock = GammaStateBlock;
+
+ texture[0] = "$backBuffer";
+ texture[1] = $HDRPostFX::colorCorrectionRamp;
+ textureSRGB[1] = true;
+};
+
+function GammaPostFX::preProcess( %this )
+{
+ if ( %this.texture[1] !$= $HDRPostFX::colorCorrectionRamp )
+ %this.setTexture( 1, $HDRPostFX::colorCorrectionRamp );
+}
+
+function GammaPostFX::setShaderConsts( %this )
+{
+ %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5);
+ %this.setShaderConst( "$OneOverGamma", 1 / %clampedGamma );
+ %this.setShaderConst( "$Brightness", $pref::Video::Brightness );
+ %this.setShaderConst( "$Contrast", $pref::Video::Contrast );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/MLAA.cs b/Templates/BaseGame/game/core/postFX/scripts/MLAA.cs
new file mode 100644
index 000000000..491c98e4e
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/MLAA.cs
@@ -0,0 +1,186 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+// NOTE: This is currently disabled in favor of FXAA. See
+// core\scripts\client\canvas.cs if you want to re-enable it.
+
+singleton GFXStateBlockData( MLAA_EdgeDetectStateBlock : PFX_DefaultStateBlock )
+{
+ // Mark the edge pixels in stencil.
+ stencilDefined = true;
+ stencilEnable = true;
+ stencilPassOp = GFXStencilOpReplace;
+ stencilFunc = GFXCmpAlways;
+ stencilRef = 1;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+singleton ShaderData( MLAA_EdgeDetectionShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/offsetV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/edgeDetectionP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/offsetV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/edgeDetectionP.glsl";
+
+ samplerNames[0] = "$colorMapG";
+ samplerNames[1] = "$deferredMap";
+
+ pixVersion = 3.0;
+};
+
+singleton GFXStateBlockData( MLAA_BlendWeightCalculationStateBlock : PFX_DefaultStateBlock )
+{
+ // Here we want to process only marked pixels.
+ stencilDefined = true;
+ stencilEnable = true;
+ stencilPassOp = GFXStencilOpKeep;
+ stencilFunc = GFXCmpEqual;
+ stencilRef = 1;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampLinear;
+ samplerStates[2] = SamplerClampPoint;
+};
+
+singleton ShaderData( MLAA_BlendWeightCalculationShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/passthruV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/blendWeightCalculationP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/passthruV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/blendWeightCalculationP.glsl";
+
+ samplerNames[0] = "$edgesMap";
+ samplerNames[1] = "$edgesMapL";
+ samplerNames[2] = "$areaMap";
+
+ pixVersion = 3.0;
+};
+
+singleton GFXStateBlockData( MLAA_NeighborhoodBlendingStateBlock : PFX_DefaultStateBlock )
+{
+ // Here we want to process only marked pixels too.
+ stencilDefined = true;
+ stencilEnable = true;
+ stencilPassOp = GFXStencilOpKeep;
+ stencilFunc = GFXCmpEqual;
+ stencilRef = 1;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampLinear;
+ samplerStates[2] = SamplerClampPoint;
+};
+
+singleton ShaderData( MLAA_NeighborhoodBlendingShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/offsetV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/neighborhoodBlendingP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/offsetV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/mlaa/gl/neighborhoodBlendingP.glsl";
+
+ samplerNames[0] = "$blendMap";
+ samplerNames[1] = "$colorMapL";
+ samplerNames[2] = "$colorMap";
+
+ pixVersion = 3.0;
+};
+
+
+singleton PostEffect( MLAAFx )
+{
+ isEnabled = false;
+
+ allowReflectPass = false;
+ renderTime = "PFXAfterDiffuse";
+
+ texture[0] = "$backBuffer"; //colorMapG
+ texture[1] = "#deferred"; // Used for depth detection
+
+ target = "$outTex";
+ targetClear = PFXTargetClear_OnDraw;
+ targetClearColor = "0 0 0 0";
+
+ stateBlock = MLAA_EdgeDetectStateBlock;
+ shader = MLAA_EdgeDetectionShader;
+
+ // The luma calculation weights which can be user adjustable
+ // per-scene if nessasary. The default value of...
+ //
+ // 0.2126 0.7152 0.0722
+ //
+ // ... is the HDTV ITU-R Recommendation BT. 709.
+ lumaCoefficients = "0.2126 0.7152 0.0722";
+
+ // The tweakable color threshold used to select
+ // the range of edge pixels to blend.
+ threshold = 0.1;
+
+ // The depth delta threshold used to select
+ // the range of edge pixels to blend.
+ depthThreshold = 0.01;
+
+ new PostEffect()
+ {
+ internalName = "blendingWeightsCalculation";
+
+ target = "$outTex";
+ targetClear = PFXTargetClear_OnDraw;
+
+ shader = MLAA_BlendWeightCalculationShader;
+ stateBlock = MLAA_BlendWeightCalculationStateBlock;
+
+ texture[0] = "$inTex"; // Edges mask
+ texture[1] = "$inTex"; // Edges mask
+ texture[2] = "core/postFX/images/AreaMap33.dds";
+ };
+
+ new PostEffect()
+ {
+ internalName = "neighborhoodBlending";
+
+ shader = MLAA_NeighborhoodBlendingShader;
+ stateBlock = MLAA_NeighborhoodBlendingStateBlock;
+
+ texture[0] = "$inTex"; // Blend weights
+ texture[1] = "$backBuffer";
+ texture[2] = "$backBuffer";
+ };
+};
+
+function MLAAFx::setShaderConsts(%this)
+{
+ %this.setShaderConst("$lumaCoefficients", %this.lumaCoefficients);
+ %this.setShaderConst("$threshold", %this.threshold);
+ %this.setShaderConst("$depthThreshold", %this.depthThreshold);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/MotionBlurFx.cs b/Templates/BaseGame/game/core/postFX/scripts/MotionBlurFx.cs
new file mode 100644
index 000000000..6919cc5a7
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/MotionBlurFx.cs
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( PFX_MotionBlurShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl"; //we use the bare-bones postFxV.hlsl
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/motionBlurP.hlsl"; //new pixel shader
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/motionBlurP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+ samplerNames[1] = "$deferredTex";
+
+ pixVersion = 3.0;
+};
+
+singleton PostEffect(MotionBlurFX)
+{
+ isEnabled = false;
+
+ renderTime = "PFXAfterDiffuse";
+
+ shader = PFX_MotionBlurShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$backbuffer";
+ texture[1] = "#deferred";
+ target = "$backBuffer";
+};
+
+function MotionBlurFX::setShaderConsts(%this)
+{
+ %this.setShaderConst( "$velocityMultiplier", 3000 );
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/caustics.cs b/Templates/BaseGame/game/core/postFX/scripts/caustics.cs
new file mode 100644
index 000000000..7dcea20a5
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/caustics.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton GFXStateBlockData( PFX_CausticsStateBlock : PFX_DefaultStateBlock )
+{
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendOne;
+ blendDest = GFXBlendOne;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerWrapLinear;
+ samplerStates[2] = SamplerWrapLinear;
+};
+
+singleton ShaderData( PFX_CausticsShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/caustics/causticsP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/caustics/gl/causticsP.glsl";
+
+ samplerNames[0] = "$deferredTex";
+ samplerNames[1] = "$causticsTex0";
+ samplerNames[2] = "$causticsTex1";
+
+ pixVersion = 3.0;
+};
+
+singleton PostEffect( CausticsPFX )
+{
+ isEnabled = false;
+ renderTime = "PFXAfterDiffuse";
+ renderBin = "ObjTranslucentBin";
+ //renderPriority = 0.1;
+
+ shader = PFX_CausticsShader;
+ stateBlock = PFX_CausticsStateBlock;
+ texture[0] = "#deferred";
+ texture[1] = "core/postFX/images/caustics_1";
+ texture[2] = "core/postFX/images/caustics_2";
+ target = "$backBuffer";
+};
diff --git a/Templates/BaseGame/game/core/postFX/scripts/chromaticLens.cs b/Templates/BaseGame/game/core/postFX/scripts/chromaticLens.cs
new file mode 100644
index 000000000..06b8d3988
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/chromaticLens.cs
@@ -0,0 +1,77 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+///
+$CAPostFx::enabled = false;
+
+/// The lens distortion coefficient.
+$CAPostFx::distCoeffecient = -0.05;
+
+/// The cubic distortion value.
+$CAPostFx::cubeDistortionFactor = -0.1;
+
+/// The amount and direction of the maxium shift for
+/// the red, green, and blue channels.
+$CAPostFx::colorDistortionFactor = "0.005 -0.005 0.01";
+
+
+singleton GFXStateBlockData( PFX_DefaultChromaticLensStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+};
+
+singleton ShaderData( PFX_ChromaticLensShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/chromaticLens.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/chromaticLens.glsl";
+
+ samplerNames[0] = "$backBuffer";
+
+ pixVersion = 3.0;
+};
+
+singleton PostEffect( ChromaticLensPostFX )
+{
+ renderTime = "PFXAfterDiffuse";
+ renderPriority = 0.2;
+ isEnabled = false;
+ allowReflectPass = false;
+
+ shader = PFX_ChromaticLensShader;
+ stateBlock = PFX_DefaultChromaticLensStateBlock;
+ texture[0] = "$backBuffer";
+ target = "$backBuffer";
+};
+
+function ChromaticLensPostFX::setShaderConsts( %this )
+{
+ %this.setShaderConst( "$distCoeff", $CAPostFx::distCoeffecient );
+ %this.setShaderConst( "$cubeDistort", $CAPostFx::cubeDistortionFactor );
+ %this.setShaderConst( "$colorDistort", $CAPostFx::colorDistortionFactor );
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/default.postfxpreset.cs b/Templates/BaseGame/game/core/postFX/scripts/default.postfxpreset.cs
new file mode 100644
index 000000000..6054d52ee
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/default.postfxpreset.cs
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+$PostFXManager::Settings::EnableVignette = "1";
+$PostFXManager::Settings::EnableDOF = "1";
+$PostFXManager::Settings::EnabledSSAO = "1";
+$PostFXManager::Settings::EnableHDR = "1";
+$PostFXManager::Settings::EnableLightRays = "1";
+$PostFXManager::Settings::EnablePostFX = "1";
+$PostFXManager::Settings::Vignette::VMax = "0.6";
+$PostFXManager::Settings::DOF::BlurCurveFar = "";
+$PostFXManager::Settings::DOF::BlurCurveNear = "";
+$PostFXManager::Settings::DOF::BlurMax = "";
+$PostFXManager::Settings::DOF::BlurMin = "";
+$PostFXManager::Settings::DOF::EnableAutoFocus = "";
+$PostFXManager::Settings::DOF::EnableDOF = "";
+$PostFXManager::Settings::DOF::FocusRangeMax = "";
+$PostFXManager::Settings::DOF::FocusRangeMin = "";
+$PostFXManager::Settings::HDR::adaptRate = "2";
+$PostFXManager::Settings::HDR::blueShiftColor = "1.05 0.97 1.27";
+$PostFXManager::Settings::HDR::brightPassThreshold = "1";
+$PostFXManager::Settings::HDR::enableBloom = "1";
+$PostFXManager::Settings::HDR::enableBlueShift = "0";
+$PostFXManager::Settings::HDR::enableToneMapping = "0.5";
+$PostFXManager::Settings::HDR::gaussMean = "0";
+$PostFXManager::Settings::HDR::gaussMultiplier = "0.3";
+$PostFXManager::Settings::HDR::gaussStdDev = "0.8";
+$PostFXManager::Settings::HDR::keyValue = "0.18";
+$PostFXManager::Settings::HDR::minLuminace = "0.001";
+$PostFXManager::Settings::HDR::whiteCutoff = "1";
+$PostFXManager::Settings::LightRays::brightScalar = "0.75";
+$PostFXManager::Settings::LightRays::decay = "1.0";
+$PostFXManager::Settings::LightRays::density = "0.94";
+$PostFXManager::Settings::LightRays::numSamples = "40";
+$PostFXManager::Settings::LightRays::weight = "5.65";
+$PostFXManager::Settings::SSAO::blurDepthTol = "0.001";
+$PostFXManager::Settings::SSAO::blurNormalTol = "0.95";
+$PostFXManager::Settings::SSAO::lDepthMax = "2";
+$PostFXManager::Settings::SSAO::lDepthMin = "0.2";
+$PostFXManager::Settings::SSAO::lDepthPow = "0.2";
+$PostFXManager::Settings::SSAO::lNormalPow = "2";
+$PostFXManager::Settings::SSAO::lNormalTol = "-0.5";
+$PostFXManager::Settings::SSAO::lRadius = "1";
+$PostFXManager::Settings::SSAO::lStrength = "10";
+$PostFXManager::Settings::SSAO::overallStrength = "2";
+$PostFXManager::Settings::SSAO::quality = "0";
+$PostFXManager::Settings::SSAO::sDepthMax = "1";
+$PostFXManager::Settings::SSAO::sDepthMin = "0.1";
+$PostFXManager::Settings::SSAO::sDepthPow = "1";
+$PostFXManager::Settings::SSAO::sNormalPow = "1";
+$PostFXManager::Settings::SSAO::sNormalTol = "0";
+$PostFXManager::Settings::SSAO::sRadius = "0.1";
+$PostFXManager::Settings::SSAO::sStrength = "6";
+$PostFXManager::Settings::ColorCorrectionRamp = "core/postFX/images/null_color_ramp.png";
diff --git a/Templates/BaseGame/game/core/postFX/scripts/dof.cs b/Templates/BaseGame/game/core/postFX/scripts/dof.cs
new file mode 100644
index 000000000..736c288b2
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/dof.cs
@@ -0,0 +1,599 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+/*
+
+================================================================================
+ The DOFPostEffect API
+================================================================================
+
+DOFPostEffect::setFocalDist( %dist )
+
+@summary
+This method is for manually controlling the focus distance. It will have no
+effect if auto focus is currently enabled. Makes use of the parameters set by
+setFocusParams.
+
+@param dist
+float distance in meters
+
+--------------------------------------------------------------------------------
+
+DOFPostEffect::setAutoFocus( %enabled )
+
+@summary
+This method sets auto focus enabled or disabled. Makes use of the parameters set
+by setFocusParams. When auto focus is enabled it determines the focal depth
+by performing a raycast at the screen-center.
+
+@param enabled
+bool
+
+--------------------------------------------------------------------------------
+
+DOFPostEffect::setFocusParams( %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope )
+
+Set the parameters that control how the near and far equations are calculated
+from the focal distance. If you are not using auto focus you will need to call
+setFocusParams PRIOR to calling setFocalDist.
+
+@param nearBlurMax
+float between 0.0 and 1.0
+The max allowed value of near blur.
+
+@param farBlurMax
+float between 0.0 and 1.0
+The max allowed value of far blur.
+
+@param minRange/maxRange
+float in meters
+The distance range around the focal distance that remains in focus is a lerp
+between the min/maxRange using the normalized focal distance as the parameter.
+The point is to allow the focal range to expand as you focus farther away since this is
+visually appealing.
+
+Note: since min/maxRange are lerped by the "normalized" focal distance it is
+dependant on the visible distance set in your level.
+
+@param nearSlope
+float less than zero
+The slope of the near equation. A small number causes bluriness to increase gradually
+at distances closer than the focal distance. A large number causes bluriness to
+increase quickly.
+
+@param farSlope
+float greater than zero
+The slope of the far equation. A small number causes bluriness to increase gradually
+at distances farther than the focal distance. A large number causes bluriness to
+increase quickly.
+
+Note: To rephrase, the min/maxRange parameters control how much area around the
+focal distance is completely in focus where the near/farSlope parameters control
+how quickly or slowly bluriness increases at distances outside of that range.
+
+================================================================================
+ Examples
+================================================================================
+
+Example1: Turn on DOF while zoomed in with a weapon.
+
+NOTE: These are not real callbacks! Hook these up to your code where appropriate!
+
+function onSniperZoom()
+{
+ // Parameterize how you want DOF to look.
+ DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 );
+
+ // Turn on auto focus
+ DOFPostEffect.setAutoFocus( true );
+
+ // Turn on the PostEffect
+ DOFPostEffect.enable();
+}
+
+function onSniperUnzoom()
+{
+ // Turn off the PostEffect
+ DOFPostEffect.disable();
+}
+
+Example2: Manually control DOF with the mouse wheel.
+
+// Somewhere on startup...
+
+// Parameterize how you want DOF to look.
+DOFPostEffect.setFocusParams( 0.3, 0.3, 50, 500, -5, 5 );
+
+// Turn off auto focus
+DOFPostEffect.setAutoFocus( false );
+
+// Turn on the PostEffect
+DOFPostEffect.enable();
+
+
+NOTE: These are not real callbacks! Hook these up to your code where appropriate!
+
+function onMouseWheelUp()
+{
+ // Since setFocalDist is really just a wrapper to assign to the focalDist
+ // dynamic field we can shortcut and increment it directly.
+ DOFPostEffect.focalDist += 8;
+}
+
+function onMouseWheelDown()
+{
+ DOFPostEffect.focalDist -= 8;
+}
+*/
+
+/// This method is for manually controlling the focal distance. It will have no
+/// effect if auto focus is currently enabled. Makes use of the parameters set by
+/// setFocusParams.
+function DOFPostEffect::setFocalDist( %this, %dist )
+{
+ %this.focalDist = %dist;
+}
+
+/// This method sets auto focus enabled or disabled. Makes use of the parameters set
+/// by setFocusParams. When auto focus is enabled it determine the focal depth
+/// by performing a raycast at the screen-center.
+function DOFPostEffect::setAutoFocus( %this, %enabled )
+{
+ %this.autoFocusEnabled = %enabled;
+}
+
+/// Set the parameters that control how the near and far equations are calculated
+/// from the focal distance. If you are not using auto focus you will need to call
+/// setFocusParams PRIOR to calling setFocalDist.
+function DOFPostEffect::setFocusParams( %this, %nearBlurMax, %farBlurMax, %minRange, %maxRange, %nearSlope, %farSlope )
+{
+ %this.nearBlurMax = %nearBlurMax;
+ %this.farBlurMax = %farBlurMax;
+ %this.minRange = %minRange;
+ %this.maxRange = %maxRange;
+ %this.nearSlope = %nearSlope;
+ %this.farSlope = %farSlope;
+}
+
+/*
+
+More information...
+
+This DOF technique is based on this paper:
+http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html
+
+================================================================================
+1. Overview of how we represent "Depth of Field"
+================================================================================
+
+DOF is expressed as an amount of bluriness per pixel according to its depth.
+We represented this by a piecewise linear curve depicted below.
+
+Note: we also refer to "bluriness" as CoC ( circle of confusion ) which is the term
+used in the basis paper and in photography.
+
+
+X-axis (depth)
+x = 0.0----------------------------------------------x = 1.0
+
+Y-axis (bluriness)
+y = 1.0
+ |
+ | ____(x1,y1) (x4,y4)____
+ | (ns,nb)\ <--Line1 line2---> /(fe,fb)
+ | \ /
+ | \(x2,y2) (x3,y3)/
+ | (ne,0)------(fs,0)
+y = 0.0
+
+
+I have labeled the "corners" of this graph with (Xn,Yn) to illustrate that
+this is in fact a collection of line segments where the x/y of each point
+corresponds to the key below.
+
+key:
+ns - (n)ear blur (s)tart distance
+nb - (n)ear (b)lur amount (max value)
+ne - (n)ear blur (e)nd distance
+fs - (f)ar blur (s)tart distance
+fe - (f)ar blur (e)nd distance
+fb - (f)ar (b)lur amount (max value)
+
+Of greatest importance in this graph is Line1 and Line2. Where...
+L1 { (x1,y1), (x2,y2) }
+L2 { (x3,y3), (x4,y4) }
+
+Line one represents the amount of "near" blur given a pixels depth and line two
+represents the amount of "far" blur at that depth.
+
+Both these equations are evaluated for each pixel and then the larger of the two
+is kept. Also the output blur (for each equation) is clamped between 0 and its
+maximum allowable value.
+
+Therefore, to specify a DOF "qualify" you need to specify the near-blur-line,
+far-blur-line, and maximum near and far blur value.
+
+================================================================================
+2. Abstracting a "focal depth"
+================================================================================
+
+Although the shader(s) work in terms of a near and far equation it is more
+useful to express DOF as an adjustable focal depth and derive the other parameters
+"under the hood".
+
+Given a maximum near/far blur amount and a near/far slope we can calculate the
+near/far equations for any focal depth. We extend this to also support a range
+of depth around the focal depth that is also in focus and for that range to
+shrink or grow as the focal depth moves closer or farther.
+
+Keep in mind this is only one implementation and depending on the effect you
+desire you may which to express the relationship between focal depth and
+the shader paramaters different.
+
+*/
+
+//-----------------------------------------------------------------------------
+// GFXStateBlockData / ShaderData
+//-----------------------------------------------------------------------------
+
+singleton GFXStateBlockData( PFX_DefaultDOFStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampPoint;
+};
+
+singleton GFXStateBlockData( PFX_DOFCalcCoCStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+};
+
+singleton GFXStateBlockData( PFX_DOFDownSampleStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampPoint;
+};
+
+singleton GFXStateBlockData( PFX_DOFBlurStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+singleton GFXStateBlockData( PFX_DOFFinalStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+ samplerStates[2] = SamplerClampLinear;
+ samplerStates[3] = SamplerClampPoint;
+
+ blendDefined = true;
+ blendEnable = true;
+ blendDest = GFXBlendInvSrcAlpha;
+ blendSrc = GFXBlendOne;
+};
+
+singleton ShaderData( PFX_DOFDownSampleShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_DownSample_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_DownSample_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_DownSample_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_DownSample_P.glsl";
+
+ samplerNames[0] = "$colorSampler";
+ samplerNames[1] = "$depthSampler";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( PFX_DOFBlurYShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_Gausian_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_Gausian_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_Gausian_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_Gausian_P.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+
+ pixVersion = 2.0;
+ defines = "BLUR_DIR=float2(0.0,1.0)";
+};
+
+singleton ShaderData( PFX_DOFBlurXShader : PFX_DOFBlurYShader )
+{
+ defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+singleton ShaderData( PFX_DOFCalcCoCShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_CalcCoC_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_CalcCoC_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_CalcCoC_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_CalcCoC_P.glsl";
+
+ samplerNames[0] = "$shrunkSampler";
+ samplerNames[1] = "$blurredSampler";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( PFX_DOFSmallBlurShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_SmallBlur_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_SmallBlur_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_SmallBlur_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_SmallBlur_P.glsl";
+
+ samplerNames[0] = "$colorSampler";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( PFX_DOFFinalShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_Final_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/DOF_Final_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_Final_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/dof/gl/DOF_Final_P.glsl";
+
+ samplerNames[0] = "$colorSampler";
+ samplerNames[1] = "$smallBlurSampler";
+ samplerNames[2] = "$largeBlurSampler";
+ samplerNames[3] = "$depthSampler";
+
+ pixVersion = 3.0;
+};
+
+//-----------------------------------------------------------------------------
+// PostEffects
+//-----------------------------------------------------------------------------
+
+function DOFPostEffect::onAdd( %this )
+{
+ // The weighted distribution of CoC value to the three blur textures
+ // in the order small, medium, large. Most likely you will not need to
+ // change this value.
+ %this.setLerpDist( 0.2, 0.3, 0.5 );
+
+ // Fill out some default values but DOF really should not be turned on
+ // without actually specifying your own parameters!
+ %this.autoFocusEnabled = false;
+ %this.focalDist = 0.0;
+ %this.nearBlurMax = 0.5;
+ %this.farBlurMax = 0.5;
+ %this.minRange = 50;
+ %this.maxRange = 500;
+ %this.nearSlope = -5.0;
+ %this.farSlope = 5.0;
+}
+
+function DOFPostEffect::setLerpDist( %this, %d0, %d1, %d2 )
+{
+ %this.lerpScale = -1.0 / %d0 SPC -1.0 / %d1 SPC -1.0 / %d2 SPC 1.0 / %d2;
+ %this.lerpBias = 1.0 SPC ( 1.0 - %d2 ) / %d1 SPC 1.0 / %d2 SPC ( %d2 - 1.0 ) / %d2;
+}
+
+singleton PostEffect( DOFPostEffect )
+{
+ renderTime = "PFXAfterBin";
+ renderBin = "GlowBin";
+ renderPriority = 0.1;
+
+ shader = PFX_DOFDownSampleShader;
+ stateBlock = PFX_DOFDownSampleStateBlock;
+ texture[0] = "$backBuffer";
+ texture[1] = "#deferred";
+ target = "#shrunk";
+ targetScale = "0.25 0.25";
+
+ isEnabled = false;
+};
+
+singleton PostEffect( DOFBlurY )
+{
+ shader = PFX_DOFBlurYShader;
+ stateBlock = PFX_DOFBlurStateBlock;
+ texture[0] = "#shrunk";
+ target = "$outTex";
+};
+
+DOFPostEffect.add( DOFBlurY );
+
+singleton PostEffect( DOFBlurX )
+{
+ shader = PFX_DOFBlurXShader;
+ stateBlock = PFX_DOFBlurStateBlock;
+ texture[0] = "$inTex";
+ target = "#largeBlur";
+};
+
+DOFPostEffect.add( DOFBlurX );
+
+singleton PostEffect( DOFCalcCoC )
+{
+ shader = PFX_DOFCalcCoCShader;
+ stateBlock = PFX_DOFCalcCoCStateBlock;
+ texture[0] = "#shrunk";
+ texture[1] = "#largeBlur";
+ target = "$outTex";
+};
+
+DOFPostEffect.add( DOFCalcCoc );
+
+singleton PostEffect( DOFSmallBlur )
+{
+ shader = PFX_DOFSmallBlurShader;
+ stateBlock = PFX_DefaultDOFStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+};
+
+DOFPostEffect.add( DOFSmallBlur );
+
+singleton PostEffect( DOFFinalPFX )
+{
+ shader = PFX_DOFFinalShader;
+ stateBlock = PFX_DOFFinalStateBlock;
+ texture[0] = "$backBuffer";
+ texture[1] = "$inTex";
+ texture[2] = "#largeBlur";
+ texture[3] = "#deferred";
+ target = "$backBuffer";
+};
+
+DOFPostEffect.add( DOFFinalPFX );
+
+
+//-----------------------------------------------------------------------------
+// Scripts
+//-----------------------------------------------------------------------------
+
+function DOFPostEffect::setShaderConsts( %this )
+{
+ if ( %this.autoFocusEnabled )
+ %this.autoFocus();
+
+ %fd = %this.focalDist / $Param::FarDist;
+
+ %range = mLerp( %this.minRange, %this.maxRange, %fd ) / $Param::FarDist * 0.5;
+
+ // We work in "depth" space rather than real-world units for the
+ // rest of this method...
+
+ // Given the focal distance and the range around it we want in focus
+ // we can determine the near-end-distance and far-start-distance
+
+ %ned = getMax( %fd - %range, 0.0 );
+ %fsd = getMin( %fd + %range, 1.0 );
+
+ // near slope
+ %nsl = %this.nearSlope;
+
+ // Given slope of near blur equation and the near end dist and amount (x2,y2)
+ // solve for the y-intercept
+ // y = mx + b
+ // so...
+ // y - mx = b
+
+ %b = 0.0 - %nsl * %ned;
+
+ %eqNear = %nsl SPC %b SPC 0.0;
+
+ // Do the same for the far blur equation...
+
+ %fsl = %this.farSlope;
+
+ %b = 0.0 - %fsl * %fsd;
+
+ %eqFar = %fsl SPC %b SPC 1.0;
+
+ %this.setShaderConst( "$dofEqWorld", %eqNear );
+ DOFFinalPFX.setShaderConst( "$dofEqFar", %eqFar );
+
+ %this.setShaderConst( "$maxWorldCoC", %this.nearBlurMax );
+ DOFFinalPFX.setShaderConst( "$maxFarCoC", %this.farBlurMax );
+
+ DOFFinalPFX.setShaderConst( "$dofLerpScale", %this.lerpScale );
+ DOFFinalPFX.setShaderConst( "$dofLerpBias", %this.lerpBias );
+}
+
+function DOFPostEffect::autoFocus( %this )
+{
+ if ( !isObject( ServerConnection ) ||
+ !isObject( ServerConnection.getCameraObject() ) )
+ {
+ return;
+ }
+
+ %mask = $TypeMasks::StaticObjectType | $TypeMasks::TerrainObjectType;
+ %control = ServerConnection.getCameraObject();
+
+ %fvec = %control.getForwardVector();
+ %start = %control.getPosition();
+
+ %end = VectorAdd( %start, VectorScale( %fvec, $Param::FarDist ) );
+
+ // Use the client container for this ray cast.
+ %result = containerRayCast( %start, %end, %mask, %control, true );
+
+ %hitPos = getWords( %result, 1, 3 );
+
+ if ( %hitPos $= "" )
+ %focDist = $Param::FarDist;
+ else
+ %focDist = VectorDist( %hitPos, %start );
+
+ // For debuging
+ //$DOF::debug_dist = %focDist;
+ //$DOF::debug_depth = %focDist / $Param::FarDist;
+ //echo( "F: " @ %focDist SPC "D: " @ %delta );
+
+ %this.focalDist = %focDist;
+}
+
+
+// For debugging
+/*
+function reloadDOF()
+{
+ exec( "./dof.cs" );
+ DOFPostEffect.reload();
+ DOFPostEffect.disable();
+ DOFPostEffect.enable();
+}
+
+function dofMetricsCallback()
+{
+ return " | DOF |" @
+ " Dist: " @ $DOF::debug_dist @
+ " Depth: " @ $DOF::debug_depth;
+}
+*/
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/edgeAA.cs b/Templates/BaseGame/game/core/postFX/scripts/edgeAA.cs
new file mode 100644
index 000000000..c3b4263fa
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/edgeAA.cs
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+singleton GFXStateBlockData( PFX_DefaultEdgeAAStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ //samplerStates[1] = SamplerWrapPoint;
+};
+
+singleton ShaderData( PFX_EdgeAADetectShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/edgeDetectP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/gl/edgeDetectP.glsl";
+
+ samplerNames[0] = "$deferredBuffer";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( PFX_EdgeAAShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/edgeAAV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/edgeAAP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/gl/edgeAAV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/gl/edgeAAP.glsl";
+
+ samplerNames[0] = "$edgeBuffer";
+ samplerNames[1] = "$backBuffer";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( PFX_EdgeAADebugShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/dbgEdgeDisplayP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/edgeaa/gl/dbgEdgeDisplayP.glsl";
+
+ samplerNames[0] = "$edgeBuffer";
+
+ pixVersion = 3.0;
+};
+
+singleton PostEffect( EdgeDetectPostEffect )
+{
+ renderTime = "PFXBeforeBin";
+ renderBin = "ObjTranslucentBin";
+ //renderPriority = 0.1;
+ targetScale = "0.5 0.5";
+
+ shader = PFX_EdgeAADetectShader;
+ stateBlock = PFX_DefaultEdgeAAStateBlock;
+ texture[0] = "#deferred";
+ target = "#edge";
+
+ isEnabled = true;
+};
+
+singleton PostEffect( EdgeAAPostEffect )
+{
+ renderTime = "PFXAfterDiffuse";
+ //renderBin = "ObjTranslucentBin";
+ //renderPriority = 0.1;
+
+ shader = PFX_EdgeAAShader;
+ stateBlock = PFX_DefaultEdgeAAStateBlock;
+ texture[0] = "#edge";
+ texture[1] = "$backBuffer";
+ target = "$backBuffer";
+};
+
+singleton PostEffect( Debug_EdgeAAPostEffect )
+{
+ renderTime = "PFXAfterDiffuse";
+ //renderBin = "ObjTranslucentBin";
+ //renderPriority = 0.1;
+
+ shader = PFX_EdgeAADebugShader;
+ stateBlock = PFX_DefaultEdgeAAStateBlock;
+ texture[0] = "#edge";
+ target = "$backBuffer";
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/flash.cs b/Templates/BaseGame/game/core/postFX/scripts/flash.cs
new file mode 100644
index 000000000..1c97c6411
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/flash.cs
@@ -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.
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( PFX_FlashShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/flashP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/flashP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+
+ defines = "WHITE_COLOR=float4(1.0,1.0,1.0,0.0);MUL_COLOR=float4(1.0,0.25,0.25,0.0)";
+
+ pixVersion = 2.0;
+};
+
+singleton PostEffect( FlashFx )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ renderTime = "PFXAfterDiffuse";
+
+ shader = PFX_FlashShader;
+ texture[0] = "$backBuffer";
+ renderPriority = 10;
+ stateBlock = PFX_DefaultStateBlock;
+};
+
+function FlashFx::setShaderConsts( %this )
+{
+ if ( isObject( ServerConnection ) )
+ {
+ %this.setShaderConst( "$damageFlash", ServerConnection.getDamageFlash() );
+ %this.setShaderConst( "$whiteOut", ServerConnection.getWhiteOut() );
+ }
+ else
+ {
+ %this.setShaderConst( "$damageFlash", 0 );
+ %this.setShaderConst( "$whiteOut", 0 );
+ }
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/fog.cs b/Templates/BaseGame/game/core/postFX/scripts/fog.cs
new file mode 100644
index 000000000..4b9bfc663
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/fog.cs
@@ -0,0 +1,135 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Fog
+//------------------------------------------------------------------------------
+
+singleton ShaderData( FogPassShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/fogP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/fogP.glsl";
+
+ samplerNames[0] = "$deferredTex";
+
+ pixVersion = 2.0;
+};
+
+
+singleton GFXStateBlockData( FogPassStateBlock : PFX_DefaultStateBlock )
+{
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendSrcAlpha;
+ blendDest = GFXBlendInvSrcAlpha;
+};
+
+
+singleton PostEffect( FogPostFx )
+{
+ // We forward render the reflection pass
+ // so it does its own fogging.
+ allowReflectPass = false;
+
+ renderTime = "PFXBeforeBin";
+ renderBin = "ObjTranslucentBin";
+
+ shader = FogPassShader;
+ stateBlock = FogPassStateBlock;
+ texture[0] = "#deferred";
+
+ renderPriority = 5;
+
+ targetFormat = getBestHDRFormat();
+ isEnabled = true;
+};
+
+
+//------------------------------------------------------------------------------
+// UnderwaterFog
+//------------------------------------------------------------------------------
+
+singleton ShaderData( UnderwaterFogPassShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/underwaterFogP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/underwaterFogP.glsl";
+
+ samplerNames[0] = "$deferredTex";
+ samplerNames[1] = "$backbuffer";
+ samplerNames[2] = "$waterDepthGradMap";
+
+ pixVersion = 2.0;
+};
+
+
+singleton GFXStateBlockData( UnderwaterFogPassStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampPoint;
+ samplerStates[2] = SamplerClampLinear;
+};
+
+
+singleton PostEffect( UnderwaterFogPostFx )
+{
+ oneFrameOnly = true;
+ onThisFrame = false;
+
+ // Let the fog effect render during the
+ // reflection pass.
+ allowReflectPass = true;
+
+ renderTime = "PFXBeforeBin";
+ renderBin = "ObjTranslucentBin";
+
+ shader = UnderwaterFogPassShader;
+ stateBlock = UnderwaterFogPassStateBlock;
+ texture[0] = "#deferred";
+ texture[1] = "$backBuffer";
+ texture[2] = "#waterDepthGradMap";
+
+ // Needs to happen after the FogPostFx
+ renderPriority = 4;
+
+ isEnabled = true;
+};
+
+function UnderwaterFogPostFx::onEnabled( %this )
+{
+ TurbulenceFx.enable();
+ CausticsPFX.enable();
+ return true;
+}
+
+function UnderwaterFogPostFx::onDisabled( %this )
+{
+ TurbulenceFx.disable();
+ CausticsPFX.disable();
+ return false;
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/fxaa.cs b/Templates/BaseGame/game/core/postFX/scripts/fxaa.cs
new file mode 100644
index 000000000..4b81c6e19
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/fxaa.cs
@@ -0,0 +1,64 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "NVIDIA FXAA 3.11" by TIMOTHY LOTTES
+//
+// http://timothylottes.blogspot.com/
+//
+// The shader is tuned for the defaul quality and good performance.
+// See shaders\common\postFx\fxaa\fxaaP.hlsl to tweak the internal
+// quality and performance settings.
+
+singleton GFXStateBlockData( FXAA_StateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+singleton ShaderData( FXAA_ShaderData )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/fxaa/fxaaV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/fxaa/fxaaP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/fxaa/gl/fxaaV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/fxaa/gl/fxaaP.glsl";
+
+ samplerNames[0] = "$colorTex";
+
+ pixVersion = 3.0;
+};
+
+singleton PostEffect( FXAA_PostEffect )
+{
+ isEnabled = false;
+
+ allowReflectPass = false;
+ renderTime = "PFXAfterDiffuse";
+
+ texture[0] = "$backBuffer";
+
+ target = "$backBuffer";
+
+ stateBlock = FXAA_StateBlock;
+ shader = FXAA_ShaderData;
+};
+
diff --git a/Templates/BaseGame/game/core/postFX/scripts/glow.cs b/Templates/BaseGame/game/core/postFX/scripts/glow.cs
new file mode 100644
index 000000000..0f062f6f7
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/glow.cs
@@ -0,0 +1,184 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+singleton ShaderData( PFX_GlowBlurVertShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/glowBlurV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/glowBlurP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/glowBlurV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/glowBlurP.glsl";
+
+ defines = "BLUR_DIR=float2(0.0,1.0)";
+
+ samplerNames[0] = "$diffuseMap";
+
+ pixVersion = 2.0;
+};
+
+
+singleton ShaderData( PFX_GlowBlurHorzShader : PFX_GlowBlurVertShader )
+{
+ defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+
+singleton GFXStateBlockData( PFX_GlowCombineStateBlock : PFX_DefaultStateBlock )
+{
+ // Use alpha test to save some fillrate
+ // on the non-glowing areas of the scene.
+ alphaDefined = true;
+ alphaTestEnable = true;
+ alphaTestRef = 1;
+ alphaTestFunc = GFXCmpGreaterEqual;
+
+ // Do a one to one blend.
+ blendDefined = true;
+ blendEnable = true;
+ blendSrc = GFXBlendOne;
+ blendDest = GFXBlendOne;
+};
+
+
+singleton PostEffect( GlowPostFx )
+{
+ // Do not allow the glow effect to work in reflection
+ // passes by default so we don't do the extra drawing.
+ allowReflectPass = false;
+
+ renderTime = "PFXAfterBin";
+ renderBin = "GlowBin";
+ renderPriority = 1;
+
+ // First we down sample the glow buffer.
+ shader = PFX_PassthruShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "#glowbuffer";
+ target = "$outTex";
+ targetScale = "0.5 0.5";
+
+ isEnabled = true;
+
+ // Blur vertically
+ new PostEffect()
+ {
+ shader = PFX_GlowBlurVertShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ };
+
+ // Blur horizontally
+ new PostEffect()
+ {
+ shader = PFX_GlowBlurHorzShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ };
+
+ // Upsample and combine with the back buffer.
+ new PostEffect()
+ {
+ shader = PFX_PassthruShader;
+ stateBlock = PFX_GlowCombineStateBlock;
+ texture[0] = "$inTex";
+ target = "$backBuffer";
+ };
+};
+
+singleton ShaderData( PFX_VolFogGlowBlurVertShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/glowBlurV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/VolFogGlowP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/glowBlurV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/VolFogGlowP.glsl";
+
+ defines = "BLUR_DIR=float2(0.0,1.0)";
+ samplerNames[0] = "$diffuseMap";
+ pixVersion = 2.0;
+};
+singleton ShaderData( PFX_VolFogGlowBlurHorzShader : PFX_VolFogGlowBlurVertShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/glowBlurV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/VolFogGlowP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/glowBlurV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/VolFogGlowP.glsl";
+
+ defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+$VolFogGlowPostFx::glowStrength = 0.3;
+
+singleton PostEffect( VolFogGlowPostFx )
+{
+ // Do not allow the glow effect to work in reflection
+ // passes by default so we don't do the extra drawing.
+ allowReflectPass = false;
+ renderTime = "PFXAfterBin";
+ renderBin = "FogBin";
+ renderPriority = 1;
+ // First we down sample the glow buffer.
+ shader = PFX_PassthruShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$backbuffer";
+ target = "$outTex";
+ targetScale = "0.5 0.5";
+ isEnabled = true;
+ // Blur vertically
+ new PostEffect()
+ {
+ shader = PFX_VolFogGlowBlurVertShader;
+ stateBlock = PFX_DefaultStateBlock;
+ internalName = "vert";
+ texture[0] = "$inTex";
+ target = "$outTex";
+ };
+ // Blur horizontally
+ new PostEffect()
+ {
+ shader = PFX_VolFogGlowBlurHorzShader;
+ stateBlock = PFX_DefaultStateBlock;
+ internalName = "hor";
+ texture[0] = "$inTex";
+ target = "$outTex";
+ };
+ // Upsample and combine with the back buffer.
+ new PostEffect()
+ {
+ shader = PFX_PassthruShader;
+ stateBlock = PFX_GlowCombineStateBlock;
+ texture[0] = "$inTex";
+ target = "$backBuffer";
+ };
+};
+
+function VolFogGlowPostFx::setShaderConsts( %this )
+{
+ %vp=%this-->vert;
+ %vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+ %vp=%this-->hor;
+ %vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/hdr.cs b/Templates/BaseGame/game/core/postFX/scripts/hdr.cs
new file mode 100644
index 000000000..3b2de8b7b
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/hdr.cs
@@ -0,0 +1,529 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+/// Blends between the scene and the tone mapped scene.
+$HDRPostFX::enableToneMapping = 0.5;
+
+/// The tone mapping middle grey or exposure value used
+/// to adjust the overall "balance" of the image.
+///
+/// 0.18 is fairly common value.
+///
+$HDRPostFX::keyValue = 0.18;
+
+/// The minimum luninace value to allow when tone mapping
+/// the scene. Is particularly useful if your scene very
+/// dark or has a black ambient color in places.
+$HDRPostFX::minLuminace = 0.001;
+
+/// The lowest luminance value which is mapped to white. This
+/// is usually set to the highest visible luminance in your
+/// scene. By setting this to smaller values you get a contrast
+/// enhancement.
+$HDRPostFX::whiteCutoff = 1.0;
+
+/// The rate of adaptation from the previous and new
+/// average scene luminance.
+$HDRPostFX::adaptRate = 2.0;
+
+/// Blends between the scene and the blue shifted version
+/// of the scene for a cinematic desaturated night effect.
+$HDRPostFX::enableBlueShift = 0.0;
+
+/// The blue shift color value.
+$HDRPostFX::blueShiftColor = "1.05 0.97 1.27";
+
+
+/// Blends between the scene and the bloomed scene.
+$HDRPostFX::enableBloom = 1.0;
+
+/// The threshold luminace value for pixels which are
+/// considered "bright" and need to be bloomed.
+$HDRPostFX::brightPassThreshold = 1.0;
+
+/// These are used in the gaussian blur of the
+/// bright pass for the bloom effect.
+$HDRPostFX::gaussMultiplier = 0.3;
+$HDRPostFX::gaussMean = 0.0;
+$HDRPostFX::gaussStdDev = 0.8;
+
+/// The 1x255 color correction ramp texture used
+/// by both the HDR shader and the GammaPostFx shader
+/// for doing full screen color correction.
+$HDRPostFX::colorCorrectionRamp = "core/postFX/images/null_color_ramp.png";
+
+
+singleton ShaderData( HDR_BrightPassShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/brightPassFilterP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/brightPassFilterP.glsl";
+
+ samplerNames[0] = "$inputTex";
+ samplerNames[1] = "$luminanceTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_DownScale4x4Shader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/downScale4x4V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/downScale4x4P.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/downScale4x4V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/downScale4x4P.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 2.0;
+};
+
+singleton ShaderData( HDR_BloomGaussBlurHShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/bloomGaussBlurHP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/bloomGaussBlurHP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_BloomGaussBlurVShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/bloomGaussBlurVP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/bloomGaussBlurVP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_SampleLumShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/sampleLumInitialP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/sampleLumInitialP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_DownSampleLumShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/sampleLumIterativeP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/sampleLumIterativeP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_CalcAdaptedLumShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/calculateAdaptedLumP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/calculateAdaptedLumP.glsl";
+
+ samplerNames[0] = "$currLum";
+ samplerNames[1] = "$lastAdaptedLum";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( HDR_CombineShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/finalPassCombineP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/finalPassCombineP.glsl";
+
+ samplerNames[0] = "$sceneTex";
+ samplerNames[1] = "$luminanceTex";
+ samplerNames[2] = "$bloomTex";
+ samplerNames[3] = "$colorCorrectionTex";
+ samplerNames[4] = "deferredTex";
+
+ pixVersion = 3.0;
+};
+
+
+singleton GFXStateBlockData( HDR_SampleStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampPoint;
+};
+
+singleton GFXStateBlockData( HDR_DownSampleStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+};
+
+singleton GFXStateBlockData( HDR_CombineStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerClampLinear;
+ samplerStates[2] = SamplerClampLinear;
+ samplerStates[3] = SamplerClampLinear;
+};
+
+singleton GFXStateBlockData( HDRStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+ samplerStates[2] = SamplerClampLinear;
+ samplerStates[3] = SamplerClampLinear;
+
+ blendDefined = true;
+ blendDest = GFXBlendOne;
+ blendSrc = GFXBlendZero;
+
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ cullDefined = true;
+ cullMode = GFXCullNone;
+};
+
+
+function HDRPostFX::setShaderConsts( %this )
+{
+ %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold );
+ %this.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue );
+
+ %bloomH = %this-->bloomH;
+ %bloomH.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier );
+ %bloomH.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean );
+ %bloomH.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev );
+
+ %bloomV = %this-->bloomV;
+ %bloomV.setShaderConst( "$gaussMultiplier", $HDRPostFX::gaussMultiplier );
+ %bloomV.setShaderConst( "$gaussMean", $HDRPostFX::gaussMean );
+ %bloomV.setShaderConst( "$gaussStdDev", $HDRPostFX::gaussStdDev );
+
+ %minLuminace = $HDRPostFX::minLuminace;
+ if ( %minLuminace <= 0.0 )
+ {
+ // The min should never be pure zero else the
+ // log() in the shader will generate INFs.
+ %minLuminace = 0.00001;
+ }
+ %this-->adaptLum.setShaderConst( "$g_fMinLuminace", %minLuminace );
+
+ %this-->finalLum.setShaderConst( "$adaptRate", $HDRPostFX::adaptRate );
+
+ %combinePass = %this-->combinePass;
+ %combinePass.setShaderConst( "$g_fEnableToneMapping", $HDRPostFX::enableToneMapping );
+ %combinePass.setShaderConst( "$g_fMiddleGray", $HDRPostFX::keyValue );
+ %combinePass.setShaderConst( "$g_fBloomScale", $HDRPostFX::enableBloom );
+ %combinePass.setShaderConst( "$g_fEnableBlueShift", $HDRPostFX::enableBlueShift );
+ %combinePass.setShaderConst( "$g_fBlueShiftColor", $HDRPostFX::blueShiftColor );
+
+ %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5);
+ %combinePass.setShaderConst( "$g_fOneOverGamma", 1 / %clampedGamma );
+ %combinePass.setShaderConst( "$Brightness", $pref::Video::Brightness );
+ %combinePass.setShaderConst( "$Contrast", $pref::Video::Contrast );
+
+ %whiteCutoff = ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ) *
+ ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff );
+ %combinePass.setShaderConst( "$g_fWhiteCutoff", %whiteCutoff );
+}
+
+function HDRPostFX::preProcess( %this )
+{
+ %combinePass = %this-->combinePass;
+
+ if ( %combinePass.texture[3] !$= $HDRPostFX::colorCorrectionRamp )
+ %combinePass.setTexture( 3, $HDRPostFX::colorCorrectionRamp );
+}
+
+function HDRPostFX::onEnabled( %this )
+{
+ // See what HDR format would be best.
+ %format = getBestHDRFormat();
+ if ( %format $= "" || %format $= "GFXFormatR8G8B8A8" )
+ {
+ // We didn't get a valid HDR format... so fail.
+ return false;
+ }
+
+ // HDR does it's own gamma calculation so
+ // disable this postFx.
+ GammaPostFX.disable();
+
+ // Set the right global shader define for HDR.
+ if ( %format $= "GFXFormatR10G10B10A2" )
+ addGlobalShaderMacro( "TORQUE_HDR_RGB10" );
+ else if ( %format $= "GFXFormatR16G16B16A16" )
+ addGlobalShaderMacro( "TORQUE_HDR_RGB16" );
+
+ echo( "HDR FORMAT: " @ %format );
+
+ // Change the format of the offscreen surface
+ // to an HDR compatible format.
+ AL_FormatToken.format = %format;
+ setReflectFormat( %format );
+
+ // Reset the light manager which will ensure the new
+ // hdr encoding takes effect in all the shaders and
+ // that the offscreen surface is enabled.
+ resetLightManager();
+
+ return true;
+}
+
+function HDRPostFX::onDisabled( %this )
+{
+ // Enable a special GammaCorrection PostFX when this is disabled.
+ GammaPostFX.enable();
+
+ // Restore the non-HDR offscreen surface format.
+ %format = getBestHDRFormat();
+ AL_FormatToken.format = %format;
+ setReflectFormat( %format );
+
+ removeGlobalShaderMacro( "TORQUE_HDR_RGB10" );
+ removeGlobalShaderMacro( "TORQUE_HDR_RGB16" );
+
+ // Reset the light manager which will ensure the new
+ // hdr encoding takes effect in all the shaders.
+ resetLightManager();
+}
+
+singleton PostEffect( HDRPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ // Resolve the HDR before we render any editor stuff
+ // and before we resolve the scene to the backbuffer.
+ renderTime = "PFXBeforeBin";
+ renderBin = "EditorBin";
+ renderPriority = 9999;
+
+ // The bright pass generates a bloomed version of
+ // the scene for pixels which are brighter than a
+ // fixed threshold value.
+ //
+ // This is then used in the final HDR combine pass
+ // at the end of this post effect chain.
+ //
+
+ shader = HDR_BrightPassShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$backBuffer";
+ texture[1] = "#adaptedLum";
+ target = "$outTex";
+ targetFormat = "GFXFormatR16G16B16A16F";
+ targetScale = "0.5 0.5";
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ shader = HDR_DownScale4x4Shader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ targetFormat = "GFXFormatR16G16B16A16F";
+ targetScale = "0.25 0.25";
+ };
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ internalName = "bloomH";
+
+ shader = HDR_BloomGaussBlurHShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ targetFormat = "GFXFormatR16G16B16A16F";
+ };
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ internalName = "bloomV";
+
+ shader = HDR_BloomGaussBlurVShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "#bloomFinal";
+ targetFormat = "GFXFormatR16G16B16A16F";
+ };
+
+ // BrightPass End
+
+ // Now calculate the adapted luminance.
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ internalName = "adaptLum";
+
+ shader = HDR_SampleLumShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$backBuffer";
+ target = "$outTex";
+ targetScale = "0.0625 0.0625"; // 1/16th
+ targetFormat = "GFXFormatR16F";
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ shader = HDR_DownSampleLumShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ targetScale = "0.25 0.25"; // 1/4
+ targetFormat = "GFXFormatR16F";
+ };
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ shader = HDR_DownSampleLumShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ targetScale = "0.25 0.25"; // 1/4
+ targetFormat = "GFXFormatR16F";
+ };
+
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ shader = HDR_DownSampleLumShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ target = "$outTex";
+ targetScale = "0.25 0.25"; // At this point the target should be 1x1.
+ targetFormat = "GFXFormatR16F";
+ };
+
+ // Note that we're reading the adapted luminance
+ // from the previous frame when generating this new
+ // one... PostEffect takes care to manage that.
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ internalName = "finalLum";
+ shader = HDR_CalcAdaptedLumShader;
+ stateBlock = HDR_DownSampleStateBlock;
+ texture[0] = "$inTex";
+ texture[1] = "#adaptedLum";
+ target = "#adaptedLum";
+ targetFormat = "GFXFormatR16F";
+ targetClear = "PFXTargetClear_OnCreate";
+ targetClearColor = "1 1 1 1";
+ };
+ };
+
+ // Output the combined bloom and toned mapped
+ // version of the scene.
+ new PostEffect()
+ {
+ allowReflectPass = false;
+ internalName = "combinePass";
+
+ shader = HDR_CombineShader;
+ stateBlock = HDR_CombineStateBlock;
+ texture[0] = "$backBuffer";
+ texture[1] = "#adaptedLum";
+ texture[2] = "#bloomFinal";
+ texture[3] = $HDRPostFX::colorCorrectionRamp;
+ target = "$backBuffer";
+ };
+};
+
+singleton ShaderData( LuminanceVisShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/luminanceVisP.hlsl";
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/hdr/gl/luminanceVisP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 3.0;
+};
+
+singleton GFXStateBlockData( LuminanceVisStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+function LuminanceVisPostFX::setShaderConsts( %this )
+{
+ %this.setShaderConst( "$brightPassThreshold", $HDRPostFX::brightPassThreshold );
+}
+
+singleton PostEffect( LuminanceVisPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ // Render before we do any editor rendering.
+ renderTime = "PFXBeforeBin";
+ renderBin = "EditorBin";
+ renderPriority = 9999;
+
+ shader = LuminanceVisShader;
+ stateBlock = LuminanceVisStateBlock;
+ texture[0] = "$backBuffer";
+ target = "$backBuffer";
+ //targetScale = "0.0625 0.0625"; // 1/16th
+ //targetFormat = "GFXFormatR16F";
+};
+
+function LuminanceVisPostFX::onEnabled( %this )
+{
+ if ( !HDRPostFX.isEnabled() )
+ {
+ HDRPostFX.enable();
+ }
+
+ HDRPostFX.skip = true;
+
+ return true;
+}
+
+function LuminanceVisPostFX::onDisabled( %this )
+{
+ HDRPostFX.skip = false;
+}
+
diff --git a/Templates/BaseGame/game/core/postFX/scripts/lightRay.cs b/Templates/BaseGame/game/core/postFX/scripts/lightRay.cs
new file mode 100644
index 000000000..523b9bdea
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/lightRay.cs
@@ -0,0 +1,110 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+$LightRayPostFX::brightScalar = 0.75;
+$LightRayPostFX::numSamples = 40;
+$LightRayPostFX::density = 0.94;
+$LightRayPostFX::weight = 5.65;
+$LightRayPostFX::decay = 1.0;
+$LightRayPostFX::exposure = 0.0005;
+$LightRayPostFX::resolutionScale = 1.0;
+
+
+singleton ShaderData( LightRayOccludeShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/lightRay/lightRayOccludeP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/lightRay/gl/lightRayOccludeP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+ samplerNames[1] = "$deferredTex";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( LightRayShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/lightRay/lightRayP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/lightRay/gl/lightRayP.glsl";
+
+ samplerNames[0] = "$frameSampler";
+ samplerNames[1] = "$backBuffer";
+
+ pixVersion = 3.0;
+};
+
+singleton GFXStateBlockData( LightRayStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+};
+
+singleton PostEffect( LightRayPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ renderTime = "PFXBeforeBin";
+ renderBin = "EditorBin";
+ renderPriority = 10;
+
+ shader = LightRayOccludeShader;
+ stateBlock = LightRayStateBlock;
+ texture[0] = "$backBuffer";
+ texture[1] = "#deferred";
+ target = "$outTex";
+ targetFormat = "GFXFormatR16G16B16A16F";
+
+ new PostEffect()
+ {
+ shader = LightRayShader;
+ stateBlock = LightRayStateBlock;
+ internalName = "final";
+ texture[0] = "$inTex";
+ texture[1] = "$backBuffer";
+ target = "$backBuffer";
+ };
+};
+
+function LightRayPostFX::preProcess( %this )
+{
+ %this.targetScale = $LightRayPostFX::resolutionScale SPC $LightRayPostFX::resolutionScale;
+}
+
+function LightRayPostFX::setShaderConsts( %this )
+{
+ %this.setShaderConst( "$brightScalar", $LightRayPostFX::brightScalar );
+
+ %pfx = %this-->final;
+ %pfx.setShaderConst( "$numSamples", $LightRayPostFX::numSamples );
+ %pfx.setShaderConst( "$density", $LightRayPostFX::density );
+ %pfx.setShaderConst( "$weight", $LightRayPostFX::weight );
+ %pfx.setShaderConst( "$decay", $LightRayPostFX::decay );
+ %pfx.setShaderConst( "$exposure", $LightRayPostFX::exposure );
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/ovrBarrelDistortion.cs b/Templates/BaseGame/game/core/postFX/scripts/ovrBarrelDistortion.cs
new file mode 100644
index 000000000..1ea280863
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/ovrBarrelDistortion.cs
@@ -0,0 +1,167 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Only load these shaders if an Oculus VR device is present
+if(!isFunction(isOculusVRDeviceActive))
+ return;
+
+//-----------------------------------------------------------------------------
+// Shader data
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( OVRMonoToStereoShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/oculusvr/monoToStereoP.hlsl";
+
+ //OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.hlsl";
+ //OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/oculusvr/gl/monoToStereoP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+
+ pixVersion = 2.0;
+};
+
+singleton ShaderData( OVRBarrelDistortionShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/oculusvr/barrelDistortionP.hlsl";
+
+ //OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ //OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/oculusvr/gl/barrelDistortionP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+
+ pixVersion = 2.0;
+};
+
+singleton ShaderData( OVRBarrelDistortionChromaShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/oculusvr/barrelDistortionChromaP.hlsl";
+
+ pixVersion = 2.0;
+};
+
+//-----------------------------------------------------------------------------
+// GFX state blocks
+//-----------------------------------------------------------------------------
+
+singleton GFXStateBlockData( OVRBarrelDistortionStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+//-----------------------------------------------------------------------------
+// Barrel Distortion PostFx
+//
+// To be used with the Oculus Rift.
+// Expects a stereo pair to exist on the back buffer and then applies the
+// appropriate barrel distortion.
+//-----------------------------------------------------------------------------
+singleton BarrelDistortionPostEffect( OVRBarrelDistortionPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ renderTime = "PFXAfterDiffuse";
+ renderPriority = 100;
+
+ // The barrel distortion
+ shader = OVRBarrelDistortionShader;
+ stateBlock = OVRBarrelDistortionStateBlock;
+
+ texture[0] = "$backBuffer";
+
+ scaleOutput = 1.25;
+};
+
+//-----------------------------------------------------------------------------
+// Barrel Distortion with Chromatic Aberration Correction PostFx
+//
+// To be used with the Oculus Rift.
+// Expects a stereo pair to exist on the back buffer and then applies the
+// appropriate barrel distortion.
+// This version applies a chromatic aberration correction during the
+// barrel distortion.
+//-----------------------------------------------------------------------------
+singleton BarrelDistortionPostEffect( OVRBarrelDistortionChromaPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ renderTime = "PFXAfterDiffuse";
+ renderPriority = 100;
+
+ // The barrel distortion
+ shader = OVRBarrelDistortionChromaShader;
+ stateBlock = OVRBarrelDistortionStateBlock;
+
+ texture[0] = "$backBuffer";
+
+ scaleOutput = 1.25;
+};
+
+//-----------------------------------------------------------------------------
+// Barrel Distortion Mono PostFx
+//
+// To be used with the Oculus Rift.
+// Takes a non-stereo image and turns it into a stereo pair with barrel
+// distortion applied. Only a vertical slice around the center of the back
+// buffer is used to generate the pseudo stereo pair.
+//-----------------------------------------------------------------------------
+singleton PostEffect( OVRBarrelDistortionMonoPostFX )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+
+ renderTime = "PFXAfterDiffuse";
+ renderPriority = 100;
+
+ // Converts the mono display to a stereo one
+ shader = OVRMonoToStereoShader;
+ stateBlock = OVRBarrelDistortionStateBlock;
+
+ texture[0] = "$backBuffer";
+ target = "$outTex";
+
+ // The actual barrel distortion
+ new BarrelDistortionPostEffect(OVRBarrelDistortionMonoStage2PostFX)
+ {
+ shader = OVRBarrelDistortionShader;
+ stateBlock = OVRBarrelDistortionStateBlock;
+ texture[0] = "$inTex";
+ target = "$backBuffer";
+
+ scaleOutput = 1.25;
+ };
+
+};
+
+function OVRBarrelDistortionMonoPostFX::setShaderConsts( %this )
+{
+ %HMDIndex = 0;
+
+ %xOffsets = getOVRHMDEyeXOffsets(%HMDIndex);
+ %this.setShaderConst( "$LensXOffsets", %xOffsets );
+}
diff --git a/Templates/BaseGame/game/core/postFX/scripts/postFx.cs b/Templates/BaseGame/game/core/postFX/scripts/postFx.cs
new file mode 100644
index 000000000..fe931a994
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/postFx.cs
@@ -0,0 +1,88 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( PFX_PassthruShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/passthruP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/passthruP.glsl";
+
+ samplerNames[0] = "$inputTex";
+
+ pixVersion = 2.0;
+};
+
+function postFXInit()
+{
+ exec("core/postFX/guis/postFxManager.gui");
+
+ //Load the core postFX files themselves
+ if (!$Server::Dedicated)
+ {
+ //init the postFX
+ %pattern = "./*.cs";
+ %file = findFirstFile( %pattern );
+ if ( %file $= "" )
+ {
+ // Try for DSOs next.
+ %pattern = "core/postFX/*.cs.dso";
+ %file = findFirstFile( %pattern );
+ }
+
+ while( %file !$= "" )
+ {
+ exec( %file );
+ %file = findNextFile( %pattern );
+ }
+ }
+}
+
+function PostEffect::inspectVars( %this )
+{
+ %name = %this.getName();
+ %globals = "$" @ %name @ "::*";
+ inspectVars( %globals );
+}
+
+function PostEffect::viewDisassembly( %this )
+{
+ %file = %this.dumpShaderDisassembly();
+
+ if ( %file $= "" )
+ {
+ echo( "PostEffect::viewDisassembly - no shader disassembly found." );
+ }
+ else
+ {
+ echo( "PostEffect::viewDisassembly - shader disassembly file dumped ( " @ %file @ " )." );
+ openFile( %file );
+ }
+}
+
+// Return true if we really want the effect enabled.
+// By default this is the case.
+function PostEffect::onEnabled( %this )
+{
+ return true;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.cs b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.cs
new file mode 100644
index 000000000..a6b0f0f01
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.cs
@@ -0,0 +1,446 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+$PostFXManager::vebose = true;
+function postVerbose(%string)
+{
+ if($PostFXManager::vebose == true)
+ {
+ echo(%string);
+ }
+}
+
+function PostFXManager::onDialogPush( %this )
+{
+ //Apply the settings to the controls
+ postVerbose("% - PostFX Manager - Loading GUI.");
+
+ %this.settingsRefreshAll();
+}
+
+// :: Controls for the overall postFX manager dialog
+function ppOptionsEnable::onAction(%this)
+{
+ //Disable / Enable all PostFX
+
+ if(ppOptionsEnable.getValue())
+ {
+ %toEnable = true;
+ }
+ else
+ {
+ %toEnable = false;
+ }
+
+ PostFXManager.settingsSetEnabled(%toEnable);
+
+}
+
+function PostFXManager::getEnableResultFromControl(%this, %control)
+{
+ %toEnable = -1;
+ %bTest = %control.getValue();
+ if(%bTest == 1)
+ {
+ %toEnable = true;
+ }
+ else
+ {
+ %toEnable = false;
+ }
+
+ return %toEnable;
+}
+
+function ppOptionsEnableSSAO::onAction(%this)
+{
+ %toEnable = PostFXManager.getEnableResultFromControl(%this);
+ PostFXManager.settingsEffectSetEnabled("SSAO", %toEnable);
+}
+
+function ppOptionsEnableHDR::onAction(%this)
+{
+ %toEnable = PostFXManager.getEnableResultFromControl(%this);
+ PostFXManager.settingsEffectSetEnabled("HDR", %toEnable);
+}
+
+function ppOptionsEnableLightRays::onAction(%this)
+{
+ %toEnable = PostFXManager.getEnableResultFromControl(%this);
+ PostFXManager.settingsEffectSetEnabled("LightRays", %toEnable);
+}
+
+function ppOptionsEnableDOF::onAction(%this)
+{
+ %toEnable = PostFXManager.getEnableResultFromControl(%this);
+ PostFXManager.settingsEffectSetEnabled("DOF", %toEnable);
+}
+
+function ppOptionsEnableVignette::onAction(%this)
+{
+ %toEnable = PostFXManager.getEnableResultFromControl(%this);
+ PostFXManager.settingsEffectSetEnabled("Vignette", %toEnable);
+}
+
+function ppOptionsSavePreset::onClick(%this)
+{
+ //Stores the current settings into a preset file for loading and use later on
+}
+
+function ppOptionsLoadPreset::onClick(%this)
+{
+ //Loads and applies the settings from a postfxpreset file
+}
+
+
+//Other controls, Quality dropdown
+function ppOptionsSSAOQuality::onSelect( %this, %id, %text )
+{
+ if(%id > -1 && %id < 3)
+ {
+ $SSAOPostFx::quality = %id;
+ }
+}
+
+//SSAO Slider controls
+//General Tab
+function ppOptionsSSAOOverallStrength::onMouseDragged(%this)
+{
+ $SSAOPostFx::overallStrength = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAOBlurDepth::onMouseDragged(%this)
+{
+ $SSAOPostFx::blurDepthTol = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAOBlurNormal::onMouseDragged(%this)
+{
+ $SSAOPostFx::blurNormalTol = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+//Near Tab
+function ppOptionsSSAONearRadius::onMouseDragged(%this)
+{
+ $SSAOPostFx::sRadius = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAONearStrength::onMouseDragged(%this)
+{
+ $SSAOPostFx::sStrength = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAONearDepthMin::onMouseDragged(%this)
+{
+ $SSAOPostFx::sDepthMin = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAONearDepthMax::onMouseDragged(%this)
+{
+ $SSAOPostFx::sDepthMax = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAONearToleranceNormal::onMouseDragged(%this)
+{
+ $SSAOPostFx::sNormalTol = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsSSAONearTolerancePower::onMouseDragged(%this)
+{
+ $SSAOPostFx::sNormalPow = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+//Far Tab
+function ppOptionsSSAOFarRadius::onMouseDragged(%this)
+{
+ $SSAOPostFx::lRadius = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+function ppOptionsSSAOFarStrength::onMouseDragged(%this)
+{
+ $SSAOPostFx::lStrength = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+function ppOptionsSSAOFarDepthMin::onMouseDragged(%this)
+{
+ $SSAOPostFx::lDepthMin = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+function ppOptionsSSAOFarDepthMax::onMouseDragged(%this)
+{
+ $SSAOPostFx::lDepthMax = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+function ppOptionsSSAOFarToleranceNormal::onMouseDragged(%this)
+{
+ $SSAOPostFx::lNormalTol = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+function ppOptionsSSAOFarTolerancePower::onMouseDragged(%this)
+{
+ $SSAOPostFx::lNormalPow = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+//HDR Slider Controls
+//Brighness tab
+
+function ppOptionsHDRToneMappingAmount::onMouseDragged(%this)
+{
+
+ $HDRPostFX::enableToneMapping = %this.value;
+ %this.ToolTip = "value : " @ %this.value;
+}
+
+function ppOptionsHDRKeyValue::onMouseDragged(%this)
+{
+ $HDRPostFX::keyValue = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRMinLuminance::onMouseDragged(%this)
+{
+ $HDRPostFX::minLuminace = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRWhiteCutoff::onMouseDragged(%this)
+{
+ $HDRPostFX::whiteCutoff = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRBrightnessAdaptRate::onMouseDragged(%this)
+{
+ $HDRPostFX::adaptRate = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+//Blur tab
+function ppOptionsHDRBloomBlurBrightPassThreshold::onMouseDragged(%this)
+{
+ $HDRPostFX::brightPassThreshold = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRBloomBlurMultiplier::onMouseDragged(%this)
+{
+ $HDRPostFX::gaussMultiplier = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRBloomBlurMean::onMouseDragged(%this)
+{
+ $HDRPostFX::gaussMean = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRBloomBlurStdDev::onMouseDragged(%this)
+{
+ $HDRPostFX::gaussStdDev = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+function ppOptionsHDRBloom::onAction(%this)
+{
+ $HDRPostFX::enableBloom = %this.getValue();
+}
+
+function ppOptionsHDRToneMapping::onAction(%this)
+{
+ //$HDRPostFX::enableToneMapping = %this.getValue();
+}
+
+function ppOptionsHDREffectsBlueShift::onAction(%this)
+{
+ $HDRPostFX::enableBlueShift = %this.getValue();
+}
+
+
+//Controls for color range in blue Shift dialog
+
+function ppOptionsHDREffectsBlueShiftColorBlend::onAction(%this)
+{
+ $HDRPostFX::blueShiftColor = %this.PickColor;
+ %this.ToolTip = "Color Values : " @ %this.PickColor;
+}
+
+function ppOptionsHDREffectsBlueShiftColorBaseColor::onAction(%this)
+{
+ //This one feeds the one above
+ ppOptionsHDREffectsBlueShiftColorBlend.baseColor = %this.PickColor;
+ %this.ToolTip = "Color Values : " @ %this.PickColor;
+}
+
+
+//Light rays Brightness Slider Controls
+function ppOptionsLightRaysBrightScalar::onMouseDragged(%this)
+{
+ $LightRayPostFX::brightScalar = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Number of Samples Slider Control
+function ppOptionsLightRaysSampleScalar::onMouseDragged(%this)
+{
+ $LightRayPostFX::numSamples = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Density Slider Control
+function ppOptionsLightRaysDensityScalar::onMouseDragged(%this)
+{
+ $LightRayPostFX::density = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Weight Slider Control
+function ppOptionsLightRaysWeightScalar::onMouseDragged(%this)
+{
+ $LightRayPostFX::weight = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+//Light rays Decay Slider Control
+function ppOptionsLightRaysDecayScalar::onMouseDragged(%this)
+{
+ $LightRayPostFX::decay = %this.value;
+ %this.ToolTip = "Value : " @ %this.value;
+}
+
+
+function ppOptionsUpdateDOFSettings()
+{
+ DOFPostEffect.setFocusParams( $DOFPostFx::BlurMin, $DOFPostFx::BlurMax, $DOFPostFx::FocusRangeMin, $DOFPostFx::FocusRangeMax, -($DOFPostFx::BlurCurveNear), $DOFPostFx::BlurCurveFar );
+
+ DOFPostEffect.setAutoFocus( $DOFPostFx::EnableAutoFocus );
+ DOFPostEffect.setFocalDist(0);
+
+ if($PostFXManager::PostFX::EnableDOF)
+ {
+ DOFPostEffect.enable();
+ }
+ else
+ {
+ DOFPostEffect.disable();
+ }
+}
+
+//DOF General Tab
+//DOF Toggles
+function ppOptionsDOFEnableDOF::onAction(%this)
+{
+ $PostFXManager::PostFX::EnableDOF = %this.getValue();
+ ppOptionsUpdateDOFSettings();
+}
+
+
+function ppOptionsDOFEnableAutoFocus::onAction(%this)
+{
+ $DOFPostFx::EnableAutoFocus = %this.getValue();
+ DOFPostEffect.setAutoFocus( %this.getValue() );
+}
+
+//DOF AutoFocus Slider controls
+function ppOptionsDOFFarBlurMinSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::BlurMin = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsDOFFarBlurMaxSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::BlurMax = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsDOFFocusRangeMinSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::FocusRangeMin = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsDOFFocusRangeMaxSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::FocusRangeMax = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsDOFBlurCurveNearSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::BlurCurveNear = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsDOFBlurCurveFarSlider::onMouseDragged(%this)
+{
+ $DOFPostFx::BlurCurveFar = %this.value;
+ ppOptionsUpdateDOFSettings();
+}
+
+function ppOptionsEnableHDRDebug::onAction(%this)
+{
+ if ( %this.getValue() )
+ LuminanceVisPostFX.enable();
+ else
+ LuminanceVisPostFX.disable();
+}
+
+function ppOptionsUpdateVignetteSettings()
+{
+ if($PostFXManager::PostFX::EnableVignette)
+ {
+ VignettePostEffect.enable();
+ }
+ else
+ {
+ VignettePostEffect.disable();
+ }
+}
+
+function ppOptionsVignetteEnableVignette::onAction(%this)
+{
+ $PostFXManager::PostFX::EnableVignette = %this.getValue();
+ ppOptionsUpdateVignetteSettings();
+}
+
+function ppColorCorrection_selectFile()
+{
+ %filter = "Image Files (*.png, *.jpg, *.dds, *.bmp, *.gif, *.jng. *.tga)|*.png;*.jpg;*.dds;*.bmp;*.gif;*.jng;*.tga|All Files (*.*)|*.*|";
+ getLoadFilename( %filter, "ppColorCorrection_selectFileHandler");
+}
+
+function ppColorCorrection_selectFileHandler( %filename )
+{
+ if ( %filename $= "" || !isFile( %filename ) )
+ %filename = "core/postFX/images/null_color_ramp.png";
+ else
+ %filename = makeRelativePath( %filename, getMainDotCsDir() );
+
+ $HDRPostFX::colorCorrectionRamp = %filename;
+ PostFXManager-->ColorCorrectionFileName.Text = %filename;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.settings.cs b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.settings.cs
new file mode 100644
index 000000000..eefcd9b7e
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.gui.settings.cs
@@ -0,0 +1,439 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+$PostFXManager::defaultPreset = "./default.postfxpreset.cs";
+
+function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX)
+{
+ $PostFXManager::PostFX::Enabled = %bEnablePostFX;
+
+ //if to enable the postFX, apply the ones that are enabled
+ if ( %bEnablePostFX )
+ {
+ //SSAO, HDR, LightRays, DOF
+
+ if ( $PostFXManager::PostFX::EnableSSAO )
+ SSAOPostFx.enable();
+ else
+ SSAOPostFx.disable();
+
+ if ( $PostFXManager::PostFX::EnableHDR )
+ HDRPostFX.enable();
+ else
+ HDRPostFX.disable();
+
+ if ( $PostFXManager::PostFX::EnableLightRays )
+ LightRayPostFX.enable();
+ else
+ LightRayPostFX.disable();
+
+ if ( $PostFXManager::PostFX::EnableDOF )
+ DOFPostEffect.enable();
+ else
+ DOFPostEffect.disable();
+
+ if ( $PostFXManager::PostFX::EnableVignette )
+ VignettePostEffect.enable();
+ else
+ VignettePostEffect.disable();
+
+ postVerbose("% - PostFX Manager - PostFX enabled");
+ }
+ else
+ {
+ //Disable all postFX
+
+ SSAOPostFx.disable();
+ HDRPostFX.disable();
+ LightRayPostFX.disable();
+ DOFPostEffect.disable();
+ VignettePostEffect.disable();
+
+ postVerbose("% - PostFX Manager - PostFX disabled");
+ }
+
+ VolFogGlowPostFx.disable();
+}
+
+function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable)
+{
+ %postEffect = 0;
+
+ //Determine the postFX to enable, and apply the boolean
+ if(%sName $= "SSAO")
+ {
+ %postEffect = SSAOPostFx;
+ $PostFXManager::PostFX::EnableSSAO = %bEnable;
+ //$pref::PostFX::SSAO::Enabled = %bEnable;
+ }
+ else if(%sName $= "HDR")
+ {
+ %postEffect = HDRPostFX;
+ $PostFXManager::PostFX::EnableHDR = %bEnable;
+ //$pref::PostFX::HDR::Enabled = %bEnable;
+ }
+ else if(%sName $= "LightRays")
+ {
+ %postEffect = LightRayPostFX;
+ $PostFXManager::PostFX::EnableLightRays = %bEnable;
+ //$pref::PostFX::LightRays::Enabled = %bEnable;
+ }
+ else if(%sName $= "DOF")
+ {
+ %postEffect = DOFPostEffect;
+ $PostFXManager::PostFX::EnableDOF = %bEnable;
+ //$pref::PostFX::DOF::Enabled = %bEnable;
+ }
+ else if(%sName $= "Vignette")
+ {
+ %postEffect = VignettePostEffect;
+ $PostFXManager::PostFX::EnableVignette = %bEnable;
+ //$pref::PostFX::Vignette::Enabled = %bEnable;
+ }
+
+ // Apply the change
+ if ( %bEnable == true )
+ {
+ %postEffect.enable();
+ postVerbose("% - PostFX Manager - " @ %sName @ " enabled");
+ }
+ else
+ {
+ %postEffect.disable();
+ postVerbose("% - PostFX Manager - " @ %sName @ " disabled");
+ }
+}
+
+function PostFXManager::settingsRefreshSSAO(%this)
+{
+ //Apply the enabled flag
+ ppOptionsEnableSSAO.setValue($PostFXManager::PostFX::EnableSSAO);
+
+ //Add the items we need to display
+ ppOptionsSSAOQuality.clear();
+ ppOptionsSSAOQuality.add("Low", 0);
+ ppOptionsSSAOQuality.add("Medium", 1);
+ ppOptionsSSAOQuality.add("High", 2);
+
+ //Set the selected, after adding the items!
+ ppOptionsSSAOQuality.setSelected($SSAOPostFx::quality);
+
+ //SSAO - Set the values of the sliders, General Tab
+ ppOptionsSSAOOverallStrength.setValue($SSAOPostFx::overallStrength);
+ ppOptionsSSAOBlurDepth.setValue($SSAOPostFx::blurDepthTol);
+ ppOptionsSSAOBlurNormal.setValue($SSAOPostFx::blurNormalTol);
+
+ //SSAO - Set the values for the near tab
+ ppOptionsSSAONearDepthMax.setValue($SSAOPostFx::sDepthMax);
+ ppOptionsSSAONearDepthMin.setValue($SSAOPostFx::sDepthMin);
+ ppOptionsSSAONearRadius.setValue($SSAOPostFx::sRadius);
+ ppOptionsSSAONearStrength.setValue($SSAOPostFx::sStrength);
+ ppOptionsSSAONearToleranceNormal.setValue($SSAOPostFx::sNormalTol);
+ ppOptionsSSAONearTolerancePower.setValue($SSAOPostFx::sNormalPow);
+
+ //SSAO - Set the values for the far tab
+ ppOptionsSSAOFarDepthMax.setValue($SSAOPostFx::lDepthMax);
+ ppOptionsSSAOFarDepthMin.setValue($SSAOPostFx::lDepthMin);
+ ppOptionsSSAOFarRadius.setValue($SSAOPostFx::lRadius);
+ ppOptionsSSAOFarStrength.setValue($SSAOPostFx::lStrength);
+ ppOptionsSSAOFarToleranceNormal.setValue($SSAOPostFx::lNormalTol);
+ ppOptionsSSAOFarTolerancePower.setValue($SSAOPostFx::lNormalPow);
+}
+
+function PostFXManager::settingsRefreshHDR(%this)
+{
+ //Apply the enabled flag
+ ppOptionsEnableHDR.setValue($PostFXManager::PostFX::EnableHDR);
+
+ ppOptionsHDRBloom.setValue($HDRPostFX::enableBloom);
+ ppOptionsHDRBloomBlurBrightPassThreshold.setValue($HDRPostFX::brightPassThreshold);
+ ppOptionsHDRBloomBlurMean.setValue($HDRPostFX::gaussMean);
+ ppOptionsHDRBloomBlurMultiplier.setValue($HDRPostFX::gaussMultiplier);
+ ppOptionsHDRBloomBlurStdDev.setValue($HDRPostFX::gaussStdDev);
+ ppOptionsHDRBrightnessAdaptRate.setValue($HDRPostFX::adaptRate);
+ ppOptionsHDREffectsBlueShift.setValue($HDRPostFX::enableBlueShift);
+ ppOptionsHDREffectsBlueShiftColor.BaseColor = $HDRPostFX::blueShiftColor;
+ ppOptionsHDREffectsBlueShiftColor.PickColor = $HDRPostFX::blueShiftColor;
+ ppOptionsHDRKeyValue.setValue($HDRPostFX::keyValue);
+ ppOptionsHDRMinLuminance.setValue($HDRPostFX::minLuminace);
+ ppOptionsHDRToneMapping.setValue($HDRPostFX::enableToneMapping);
+ ppOptionsHDRToneMappingAmount.setValue($HDRPostFX::enableToneMapping);
+ ppOptionsHDRWhiteCutoff.setValue($HDRPostFX::whiteCutoff);
+
+ %this-->ColorCorrectionFileName.Text = $HDRPostFX::colorCorrectionRamp;
+}
+
+function PostFXManager::settingsRefreshLightrays(%this)
+{
+ //Apply the enabled flag
+ ppOptionsEnableLightRays.setValue($PostFXManager::PostFX::EnableLightRays);
+
+ ppOptionsLightRaysBrightScalar.setValue($LightRayPostFX::brightScalar);
+
+ ppOptionsLightRaysSampleScalar.setValue($LightRayPostFX::numSamples);
+ ppOptionsLightRaysDensityScalar.setValue($LightRayPostFX::density);
+ ppOptionsLightRaysWeightScalar.setValue($LightRayPostFX::weight);
+ ppOptionsLightRaysDecayScalar.setValue($LightRayPostFX::decay);
+}
+
+function PostFXManager::settingsRefreshDOF(%this)
+{
+ //Apply the enabled flag
+ ppOptionsEnableDOF.setValue($PostFXManager::PostFX::EnableDOF);
+
+
+ //ppOptionsDOFEnableDOF.setValue($PostFXManager::PostFX::EnableDOF);
+ ppOptionsDOFEnableAutoFocus.setValue($DOFPostFx::EnableAutoFocus);
+
+ ppOptionsDOFFarBlurMinSlider.setValue($DOFPostFx::BlurMin);
+ ppOptionsDOFFarBlurMaxSlider.setValue($DOFPostFx::BlurMax);
+
+ ppOptionsDOFFocusRangeMinSlider.setValue($DOFPostFx::FocusRangeMin);
+ ppOptionsDOFFocusRangeMaxSlider.setValue($DOFPostFx::FocusRangeMax);
+
+ ppOptionsDOFBlurCurveNearSlider.setValue($DOFPostFx::BlurCurveNear);
+ ppOptionsDOFBlurCurveFarSlider.setValue($DOFPostFx::BlurCurveFar);
+
+}
+
+function PostFXManager::settingsRefreshVignette(%this)
+{
+ //Apply the enabled flag
+ ppOptionsEnableVignette.setValue($PostFXManager::PostFX::EnableVignette);
+
+}
+
+function PostFXManager::settingsRefreshAll(%this)
+{
+ $PostFXManager::PostFX::Enabled = $pref::enablePostEffects;
+ $PostFXManager::PostFX::EnableSSAO = SSAOPostFx.isEnabled();
+ $PostFXManager::PostFX::EnableHDR = HDRPostFX.isEnabled();
+ $PostFXManager::PostFX::EnableLightRays = LightRayPostFX.isEnabled();
+ $PostFXManager::PostFX::EnableDOF = DOFPostEffect.isEnabled();
+ $PostFXManager::PostFX::EnableVignette = VignettePostEffect.isEnabled();
+
+ //For all the postFX here, apply the active settings in the system
+ //to the gui controls.
+
+ %this.settingsRefreshSSAO();
+ %this.settingsRefreshHDR();
+ %this.settingsRefreshLightrays();
+ %this.settingsRefreshDOF();
+ %this.settingsRefreshVignette();
+
+ ppOptionsEnable.setValue($PostFXManager::PostFX::Enabled);
+
+ postVerbose("% - PostFX Manager - GUI values updated.");
+}
+
+function PostFXManager::settingsApplyFromPreset(%this)
+{
+ postVerbose("% - PostFX Manager - Applying from preset");
+
+ //SSAO Settings
+ $SSAOPostFx::blurDepthTol = $PostFXManager::Settings::SSAO::blurDepthTol;
+ $SSAOPostFx::blurNormalTol = $PostFXManager::Settings::SSAO::blurNormalTol;
+ $SSAOPostFx::lDepthMax = $PostFXManager::Settings::SSAO::lDepthMax;
+ $SSAOPostFx::lDepthMin = $PostFXManager::Settings::SSAO::lDepthMin;
+ $SSAOPostFx::lDepthPow = $PostFXManager::Settings::SSAO::lDepthPow;
+ $SSAOPostFx::lNormalPow = $PostFXManager::Settings::SSAO::lNormalPow;
+ $SSAOPostFx::lNormalTol = $PostFXManager::Settings::SSAO::lNormalTol;
+ $SSAOPostFx::lRadius = $PostFXManager::Settings::SSAO::lRadius;
+ $SSAOPostFx::lStrength = $PostFXManager::Settings::SSAO::lStrength;
+ $SSAOPostFx::overallStrength = $PostFXManager::Settings::SSAO::overallStrength;
+ $SSAOPostFx::quality = $PostFXManager::Settings::SSAO::quality;
+ $SSAOPostFx::sDepthMax = $PostFXManager::Settings::SSAO::sDepthMax;
+ $SSAOPostFx::sDepthMin = $PostFXManager::Settings::SSAO::sDepthMin;
+ $SSAOPostFx::sDepthPow = $PostFXManager::Settings::SSAO::sDepthPow;
+ $SSAOPostFx::sNormalPow = $PostFXManager::Settings::SSAO::sNormalPow;
+ $SSAOPostFx::sNormalTol = $PostFXManager::Settings::SSAO::sNormalTol;
+ $SSAOPostFx::sRadius = $PostFXManager::Settings::SSAO::sRadius;
+ $SSAOPostFx::sStrength = $PostFXManager::Settings::SSAO::sStrength;
+
+ //HDR settings
+ $HDRPostFX::adaptRate = $PostFXManager::Settings::HDR::adaptRate;
+ $HDRPostFX::blueShiftColor = $PostFXManager::Settings::HDR::blueShiftColor;
+ $HDRPostFX::brightPassThreshold = $PostFXManager::Settings::HDR::brightPassThreshold;
+ $HDRPostFX::enableBloom = $PostFXManager::Settings::HDR::enableBloom;
+ $HDRPostFX::enableBlueShift = $PostFXManager::Settings::HDR::enableBlueShift;
+ $HDRPostFX::enableToneMapping = $PostFXManager::Settings::HDR::enableToneMapping;
+ $HDRPostFX::gaussMean = $PostFXManager::Settings::HDR::gaussMean;
+ $HDRPostFX::gaussMultiplier = $PostFXManager::Settings::HDR::gaussMultiplier;
+ $HDRPostFX::gaussStdDev = $PostFXManager::Settings::HDR::gaussStdDev;
+ $HDRPostFX::keyValue = $PostFXManager::Settings::HDR::keyValue;
+ $HDRPostFX::minLuminace = $PostFXManager::Settings::HDR::minLuminace;
+ $HDRPostFX::whiteCutoff = $PostFXManager::Settings::HDR::whiteCutoff;
+ $HDRPostFX::colorCorrectionRamp = $PostFXManager::Settings::ColorCorrectionRamp;
+
+ //Light rays settings
+ $LightRayPostFX::brightScalar = $PostFXManager::Settings::LightRays::brightScalar;
+
+ $LightRayPostFX::numSamples = $PostFXManager::Settings::LightRays::numSamples;
+ $LightRayPostFX::density = $PostFXManager::Settings::LightRays::density;
+ $LightRayPostFX::weight = $PostFXManager::Settings::LightRays::weight;
+ $LightRayPostFX::decay = $PostFXManager::Settings::LightRays::decay;
+
+ //DOF settings
+ $DOFPostFx::EnableAutoFocus = $PostFXManager::Settings::DOF::EnableAutoFocus;
+ $DOFPostFx::BlurMin = $PostFXManager::Settings::DOF::BlurMin;
+ $DOFPostFx::BlurMax = $PostFXManager::Settings::DOF::BlurMax;
+ $DOFPostFx::FocusRangeMin = $PostFXManager::Settings::DOF::FocusRangeMin;
+ $DOFPostFx::FocusRangeMax = $PostFXManager::Settings::DOF::FocusRangeMax;
+ $DOFPostFx::BlurCurveNear = $PostFXManager::Settings::DOF::BlurCurveNear;
+ $DOFPostFx::BlurCurveFar = $PostFXManager::Settings::DOF::BlurCurveFar;
+
+ //Vignette settings
+ $VignettePostEffect::VMax = $PostFXManager::Settings::Vignette::VMax;
+ $VignettePostEffect::VMin = $PostFXManager::Settings::Vignette::VMin;
+
+ if ( $PostFXManager::forceEnableFromPresets )
+ {
+ $PostFXManager::PostFX::Enabled = $PostFXManager::Settings::EnablePostFX;
+ $PostFXManager::PostFX::EnableDOF = $pref::PostFX::EnableDOF ? $PostFXManager::Settings::EnableDOF : false;
+ $PostFXManager::PostFX::EnableVignette = $pref::PostFX::EnableVignette ? $PostFXManager::Settings::EnableVignette : false;
+ $PostFXManager::PostFX::EnableLightRays = $pref::PostFX::EnableLightRays ? $PostFXManager::Settings::EnableLightRays : false;
+ $PostFXManager::PostFX::EnableHDR = $pref::PostFX::EnableHDR ? $PostFXManager::Settings::EnableHDR : false;
+ $PostFXManager::PostFX::EnableSSAO = $pref::PostFX::EnabledSSAO ? $PostFXManager::Settings::EnableSSAO : false;
+
+ %this.settingsSetEnabled( true );
+ }
+
+ //make sure we apply the correct settings to the DOF
+ ppOptionsUpdateDOFSettings();
+
+ // Update the actual GUI controls if its awake ( otherwise it will when opened ).
+ if ( PostFXManager.isAwake() )
+ %this.settingsRefreshAll();
+}
+
+function PostFXManager::settingsApplySSAO(%this)
+{
+ $PostFXManager::Settings::SSAO::blurDepthTol = $SSAOPostFx::blurDepthTol;
+ $PostFXManager::Settings::SSAO::blurNormalTol = $SSAOPostFx::blurNormalTol;
+ $PostFXManager::Settings::SSAO::lDepthMax = $SSAOPostFx::lDepthMax;
+ $PostFXManager::Settings::SSAO::lDepthMin = $SSAOPostFx::lDepthMin;
+ $PostFXManager::Settings::SSAO::lDepthPow = $SSAOPostFx::lDepthPow;
+ $PostFXManager::Settings::SSAO::lNormalPow = $SSAOPostFx::lNormalPow;
+ $PostFXManager::Settings::SSAO::lNormalTol = $SSAOPostFx::lNormalTol;
+ $PostFXManager::Settings::SSAO::lRadius = $SSAOPostFx::lRadius;
+ $PostFXManager::Settings::SSAO::lStrength = $SSAOPostFx::lStrength;
+ $PostFXManager::Settings::SSAO::overallStrength = $SSAOPostFx::overallStrength;
+ $PostFXManager::Settings::SSAO::quality = $SSAOPostFx::quality;
+ $PostFXManager::Settings::SSAO::sDepthMax = $SSAOPostFx::sDepthMax;
+ $PostFXManager::Settings::SSAO::sDepthMin = $SSAOPostFx::sDepthMin;
+ $PostFXManager::Settings::SSAO::sDepthPow = $SSAOPostFx::sDepthPow;
+ $PostFXManager::Settings::SSAO::sNormalPow = $SSAOPostFx::sNormalPow;
+ $PostFXManager::Settings::SSAO::sNormalTol = $SSAOPostFx::sNormalTol;
+ $PostFXManager::Settings::SSAO::sRadius = $SSAOPostFx::sRadius;
+ $PostFXManager::Settings::SSAO::sStrength = $SSAOPostFx::sStrength;
+
+ postVerbose("% - PostFX Manager - Settings Saved - SSAO");
+
+}
+
+function PostFXManager::settingsApplyHDR(%this)
+{
+ $PostFXManager::Settings::HDR::adaptRate = $HDRPostFX::adaptRate;
+ $PostFXManager::Settings::HDR::blueShiftColor = $HDRPostFX::blueShiftColor;
+ $PostFXManager::Settings::HDR::brightPassThreshold = $HDRPostFX::brightPassThreshold;
+ $PostFXManager::Settings::HDR::enableBloom = $HDRPostFX::enableBloom;
+ $PostFXManager::Settings::HDR::enableBlueShift = $HDRPostFX::enableBlueShift;
+ $PostFXManager::Settings::HDR::enableToneMapping = $HDRPostFX::enableToneMapping;
+ $PostFXManager::Settings::HDR::gaussMean = $HDRPostFX::gaussMean;
+ $PostFXManager::Settings::HDR::gaussMultiplier = $HDRPostFX::gaussMultiplier;
+ $PostFXManager::Settings::HDR::gaussStdDev = $HDRPostFX::gaussStdDev;
+ $PostFXManager::Settings::HDR::keyValue = $HDRPostFX::keyValue;
+ $PostFXManager::Settings::HDR::minLuminace = $HDRPostFX::minLuminace;
+ $PostFXManager::Settings::HDR::whiteCutoff = $HDRPostFX::whiteCutoff;
+ $PostFXManager::Settings::ColorCorrectionRamp = $HDRPostFX::colorCorrectionRamp;
+
+ postVerbose("% - PostFX Manager - Settings Saved - HDR");
+}
+
+function PostFXManager::settingsApplyLightRays(%this)
+{
+ $PostFXManager::Settings::LightRays::brightScalar = $LightRayPostFX::brightScalar;
+
+ $PostFXManager::Settings::LightRays::numSamples = $LightRayPostFX::numSamples;
+ $PostFXManager::Settings::LightRays::density = $LightRayPostFX::density;
+ $PostFXManager::Settings::LightRays::weight = $LightRayPostFX::weight;
+ $PostFXManager::Settings::LightRays::decay = $LightRayPostFX::decay;
+
+ postVerbose("% - PostFX Manager - Settings Saved - Light Rays");
+
+}
+
+function PostFXManager::settingsApplyDOF(%this)
+{
+ $PostFXManager::Settings::DOF::EnableAutoFocus = $DOFPostFx::EnableAutoFocus;
+ $PostFXManager::Settings::DOF::BlurMin = $DOFPostFx::BlurMin;
+ $PostFXManager::Settings::DOF::BlurMax = $DOFPostFx::BlurMax;
+ $PostFXManager::Settings::DOF::FocusRangeMin = $DOFPostFx::FocusRangeMin;
+ $PostFXManager::Settings::DOF::FocusRangeMax = $DOFPostFx::FocusRangeMax;
+ $PostFXManager::Settings::DOF::BlurCurveNear = $DOFPostFx::BlurCurveNear;
+ $PostFXManager::Settings::DOF::BlurCurveFar = $DOFPostFx::BlurCurveFar;
+
+ postVerbose("% - PostFX Manager - Settings Saved - DOF");
+
+}
+
+function PostFXManager::settingsApplyVignette(%this)
+{
+ $PostFXManager::Settings::Vignette::VMax = $VignettePostEffect::VMax;
+ $PostFXManager::Settings::Vignette::VMin = $VignettePostEffect::VMin;
+
+ postVerbose("% - PostFX Manager - Settings Saved - Vignette");
+
+}
+
+function PostFXManager::settingsApplyAll(%this, %sFrom)
+{
+ // Apply settings which control if effects are on/off altogether.
+ $PostFXManager::Settings::EnablePostFX = $PostFXManager::PostFX::Enabled;
+ $PostFXManager::Settings::EnableDOF = $PostFXManager::PostFX::EnableDOF;
+ $PostFXManager::Settings::EnableVignette = $PostFXManager::PostFX::EnableVignette;
+ $PostFXManager::Settings::EnableLightRays = $PostFXManager::PostFX::EnableLightRays;
+ $PostFXManager::Settings::EnableHDR = $PostFXManager::PostFX::EnableHDR;
+ $PostFXManager::Settings::EnableSSAO = $PostFXManager::PostFX::EnableSSAO;
+
+ // Apply settings should save the values in the system to the
+ // the preset structure ($PostFXManager::Settings::*)
+
+ // SSAO Settings
+ %this.settingsApplySSAO();
+ // HDR settings
+ %this.settingsApplyHDR();
+ // Light rays settings
+ %this.settingsApplyLightRays();
+ // DOF
+ %this.settingsApplyDOF();
+ // Vignette
+ %this.settingsApplyVignette();
+
+ postVerbose("% - PostFX Manager - All Settings applied to $PostFXManager::Settings");
+}
+
+function PostFXManager::settingsApplyDefaultPreset(%this)
+{
+ PostFXManager::loadPresetHandler($PostFXManager::defaultPreset);
+}
+
diff --git a/Templates/BaseGame/game/core/postFX/scripts/postFxManager.persistance.cs b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.persistance.cs
new file mode 100644
index 000000000..31fec95f1
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/postFxManager.persistance.cs
@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+// Used to name the saved files.
+$PostFXManager::fileExtension = ".postfxpreset.cs";
+
+// The filter string for file open/save dialogs.
+$PostFXManager::fileFilter = "Post Effect Presets|*.postfxpreset.cs";
+
+// Enable / disable PostFX when loading presets or just apply the settings?
+$PostFXManager::forceEnableFromPresets = true;
+
+//Load a preset file from the disk, and apply the settings to the
+//controls. If bApplySettings is true - the actual values in the engine
+//will be changed to reflect the settings from the file.
+function PostFXManager::loadPresetFile()
+{
+ //Show the dialog and set the flag
+ getLoadFilename($PostFXManager::fileFilter, "PostFXManager::loadPresetHandler");
+}
+
+function PostFXManager::loadPresetHandler( %filename )
+{
+ //Check the validity of the file
+ if ( isScriptFile( %filename ) )
+ {
+ %filename = expandFilename(%filename);
+ postVerbose("% - PostFX Manager - Executing " @ %filename);
+ exec(%filename);
+
+ PostFXManager.settingsApplyFromPreset();
+ }
+}
+
+//Save a preset file to the specified file. The extension used
+//is specified by $PostFXManager::fileExtension for on the fly
+//name changes to the extension used.
+
+function PostFXManager::savePresetFile(%this)
+{
+ %defaultFile = filePath($Client::MissionFile) @ "/" @ fileBase($Client::MissionFile);
+ getSaveFilename($PostFXManager::fileFilter, "PostFXManager::savePresetHandler", %defaultFile);
+}
+
+//Called from the PostFXManager::savePresetFile() function
+function PostFXManager::savePresetHandler( %filename )
+{
+ %filename = makeRelativePath( %filename, getMainDotCsDir() );
+ if(strStr(%filename, ".") == -1)
+ %filename = %filename @ $PostFXManager::fileExtension;
+
+ //Apply the current settings to the preset
+ PostFXManager.settingsApplyAll();
+
+ export("$PostFXManager::Settings::*", %filename, false);
+
+ postVerbose("% - PostFX Manager - Save complete. Preset saved at : " @ %filename);
+}
+
diff --git a/Templates/BaseGame/game/core/postFX/scripts/ssao.cs b/Templates/BaseGame/game/core/postFX/scripts/ssao.cs
new file mode 100644
index 000000000..5fe405a82
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/ssao.cs
@@ -0,0 +1,302 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+///
+$SSAOPostFx::overallStrength = 2.0;
+
+// TODO: Add small/large param docs.
+
+// The small radius SSAO settings.
+$SSAOPostFx::sRadius = 0.1;
+$SSAOPostFx::sStrength = 6.0;
+$SSAOPostFx::sDepthMin = 0.1;
+$SSAOPostFx::sDepthMax = 1.0;
+$SSAOPostFx::sDepthPow = 1.0;
+$SSAOPostFx::sNormalTol = 0.0;
+$SSAOPostFx::sNormalPow = 1.0;
+
+// The large radius SSAO settings.
+$SSAOPostFx::lRadius = 1.0;
+$SSAOPostFx::lStrength = 10.0;
+$SSAOPostFx::lDepthMin = 0.2;
+$SSAOPostFx::lDepthMax = 2.0;
+$SSAOPostFx::lDepthPow = 0.2;
+$SSAOPostFx::lNormalTol = -0.5;
+$SSAOPostFx::lNormalPow = 2.0;
+
+/// Valid values: 0, 1, 2
+$SSAOPostFx::quality = 0;
+
+///
+$SSAOPostFx::blurDepthTol = 0.001;
+
+///
+$SSAOPostFx::blurNormalTol = 0.95;
+
+///
+$SSAOPostFx::targetScale = "0.5 0.5";
+
+
+function SSAOPostFx::onAdd( %this )
+{
+ %this.wasVis = "Uninitialized";
+ %this.quality = "Uninitialized";
+}
+
+function SSAOPostFx::preProcess( %this )
+{
+ if ( $SSAOPostFx::quality !$= %this.quality )
+ {
+ %this.quality = mClamp( mRound( $SSAOPostFx::quality ), 0, 2 );
+
+ %this.setShaderMacro( "QUALITY", %this.quality );
+ }
+
+ %this.targetScale = $SSAOPostFx::targetScale;
+}
+
+function SSAOPostFx::setShaderConsts( %this )
+{
+ %this.setShaderConst( "$overallStrength", $SSAOPostFx::overallStrength );
+
+ // Abbreviate is s-small l-large.
+
+ %this.setShaderConst( "$sRadius", $SSAOPostFx::sRadius );
+ %this.setShaderConst( "$sStrength", $SSAOPostFx::sStrength );
+ %this.setShaderConst( "$sDepthMin", $SSAOPostFx::sDepthMin );
+ %this.setShaderConst( "$sDepthMax", $SSAOPostFx::sDepthMax );
+ %this.setShaderConst( "$sDepthPow", $SSAOPostFx::sDepthPow );
+ %this.setShaderConst( "$sNormalTol", $SSAOPostFx::sNormalTol );
+ %this.setShaderConst( "$sNormalPow", $SSAOPostFx::sNormalPow );
+
+ %this.setShaderConst( "$lRadius", $SSAOPostFx::lRadius );
+ %this.setShaderConst( "$lStrength", $SSAOPostFx::lStrength );
+ %this.setShaderConst( "$lDepthMin", $SSAOPostFx::lDepthMin );
+ %this.setShaderConst( "$lDepthMax", $SSAOPostFx::lDepthMax );
+ %this.setShaderConst( "$lDepthPow", $SSAOPostFx::lDepthPow );
+ %this.setShaderConst( "$lNormalTol", $SSAOPostFx::lNormalTol );
+ %this.setShaderConst( "$lNormalPow", $SSAOPostFx::lNormalPow );
+
+ %blur = %this->blurY;
+ %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol );
+ %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol );
+
+ %blur = %this->blurX;
+ %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol );
+ %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol );
+
+ %blur = %this->blurY2;
+ %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol );
+ %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol );
+
+ %blur = %this->blurX2;
+ %blur.setShaderConst( "$blurDepthTol", $SSAOPostFx::blurDepthTol );
+ %blur.setShaderConst( "$blurNormalTol", $SSAOPostFx::blurNormalTol );
+}
+
+function SSAOPostFx::onEnabled( %this )
+{
+ // This tells the AL shaders to reload and sample
+ // from our #ssaoMask texture target.
+ $AL::UseSSAOMask = true;
+
+ return true;
+}
+
+function SSAOPostFx::onDisabled( %this )
+{
+ $AL::UseSSAOMask = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// GFXStateBlockData / ShaderData
+//-----------------------------------------------------------------------------
+
+singleton GFXStateBlockData( SSAOStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+ samplerStates[1] = SamplerWrapLinear;
+ samplerStates[2] = SamplerClampPoint;
+};
+
+singleton GFXStateBlockData( SSAOBlurStateBlock : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampPoint;
+};
+
+singleton ShaderData( SSAOShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/SSAO_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/gl/SSAO_P.glsl";
+
+ samplerNames[0] = "$deferredMap";
+ samplerNames[1] = "$randNormalTex";
+ samplerNames[2] = "$powTable";
+
+ pixVersion = 3.0;
+};
+
+singleton ShaderData( SSAOBlurYShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/SSAO_Blur_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/SSAO_Blur_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/gl/SSAO_Blur_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/gl/SSAO_Blur_P.glsl";
+
+ samplerNames[0] = "$occludeMap";
+ samplerNames[1] = "$deferredMap";
+
+ pixVersion = 3.0;
+
+ defines = "BLUR_DIR=float2(0.0,1.0)";
+};
+
+singleton ShaderData( SSAOBlurXShader : SSAOBlurYShader )
+{
+ defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+//-----------------------------------------------------------------------------
+// PostEffects
+//-----------------------------------------------------------------------------
+
+singleton PostEffect( SSAOPostFx )
+{
+ allowReflectPass = false;
+
+ renderTime = "PFXBeforeBin";
+ renderBin = "AL_LightBinMgr";
+ renderPriority = 10;
+
+ shader = SSAOShader;
+ stateBlock = SSAOStateBlock;
+
+ texture[0] = "#deferred";
+ texture[1] = "core/postFX/images/noise.png";
+ texture[2] = "#ssao_pow_table";
+
+ target = "$outTex";
+ targetScale = "0.5 0.5";
+ targetViewport = "PFXTargetViewport_NamedInTexture0";
+
+ singleton PostEffect()
+ {
+ internalName = "blurY";
+
+ shader = SSAOBlurYShader;
+ stateBlock = SSAOBlurStateBlock;
+
+ texture[0] = "$inTex";
+ texture[1] = "#deferred";
+
+ target = "$outTex";
+ };
+
+ singleton PostEffect()
+ {
+ internalName = "blurX";
+
+ shader = SSAOBlurXShader;
+ stateBlock = SSAOBlurStateBlock;
+
+ texture[0] = "$inTex";
+ texture[1] = "#deferred";
+
+ target = "$outTex";
+ };
+
+ singleton PostEffect()
+ {
+ internalName = "blurY2";
+
+ shader = SSAOBlurYShader;
+ stateBlock = SSAOBlurStateBlock;
+
+ texture[0] = "$inTex";
+ texture[1] = "#deferred";
+
+ target = "$outTex";
+ };
+
+ singleton PostEffect()
+ {
+ internalName = "blurX2";
+
+ shader = SSAOBlurXShader;
+ stateBlock = SSAOBlurStateBlock;
+
+ texture[0] = "$inTex";
+ texture[1] = "#deferred";
+
+ // We write to a mask texture which is then
+ // read by the lighting shaders to mask ambient.
+ target = "#ssaoMask";
+ };
+};
+
+
+/// Just here for debug visualization of the
+/// SSAO mask texture used during lighting.
+singleton PostEffect( SSAOVizPostFx )
+{
+ allowReflectPass = false;
+
+ shader = PFX_PassthruShader;
+ stateBlock = PFX_DefaultStateBlock;
+
+ texture[0] = "#ssaoMask";
+
+ target = "$backbuffer";
+};
+
+singleton ShaderData( SSAOPowTableShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/SSAO_PowerTable_V.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/SSAO_PowerTable_P.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/gl/SSAO_PowerTable_V.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/ssao/gl/SSAO_PowerTable_P.glsl";
+
+ pixVersion = 2.0;
+};
+
+singleton PostEffect( SSAOPowTablePostFx )
+{
+ shader = SSAOPowTableShader;
+ stateBlock = PFX_DefaultStateBlock;
+
+ renderTime = "PFXTexGenOnDemand";
+
+ target = "#ssao_pow_table";
+
+ targetFormat = "GFXFormatR16F";
+ targetSize = "256 1";
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/postFX/scripts/turbulence.cs b/Templates/BaseGame/game/core/postFX/scripts/turbulence.cs
new file mode 100644
index 000000000..967c3b2bf
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/turbulence.cs
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton GFXStateBlockData( PFX_TurbulenceStateBlock : PFX_DefaultStateBlock)
+{
+ zDefined = false;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+singleton ShaderData( PFX_TurbulenceShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/turbulenceP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/gl/turbulenceP.glsl";
+
+ samplerNames[0] = "$inputTex";
+ pixVersion = 3.0;
+};
+
+singleton PostEffect( TurbulenceFx )
+{
+ isEnabled = false;
+ allowReflectPass = true;
+
+ renderTime = "PFXAfterDiffuse";
+ renderBin = "GlowBin";
+ renderPriority = 0.5; // Render after the glows themselves
+
+ shader = PFX_TurbulenceShader;
+ stateBlock=PFX_TurbulenceStateBlock;
+ texture[0] = "$backBuffer";
+ };
diff --git a/Templates/BaseGame/game/core/postFX/scripts/vignette.cs b/Templates/BaseGame/game/core/postFX/scripts/vignette.cs
new file mode 100644
index 000000000..d22f7d14a
--- /dev/null
+++ b/Templates/BaseGame/game/core/postFX/scripts/vignette.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+$VignettePostEffect::VMax = 0.6;
+$VignettePostEffect::VMin = 0.2;
+
+singleton ShaderData( VignetteShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/postFX/postFxV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/postFX/vignette/VignetteP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/postFX/gl/postFxV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/postFX/vignette/gl/VignetteP.glsl";
+
+ samplerNames[0] = "$backBuffer";
+
+ pixVersion = 2.0;
+};
+
+singleton PostEffect( VignettePostEffect )
+{
+ isEnabled = false;
+ allowReflectPass = false;
+ renderTime = "PFXAfterBin";
+ renderBin = "GlowBin";
+ shader = VignetteShader;
+ stateBlock = PFX_DefaultStateBlock;
+ texture[0] = "$backBuffer";
+ renderPriority = 10;
+};
+
+function VignettePostEffect::setShaderConsts(%this)
+{
+ %this.setShaderConst("$Vmax", $VignettePostEffect::VMax);
+ %this.setShaderConst("$Vmin", $VignettePostEffect::VMin);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.cs b/Templates/BaseGame/game/core/rendering/Core_Rendering.cs
new file mode 100644
index 000000000..d09e0cbe3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.cs
@@ -0,0 +1,20 @@
+
+function Core_Rendering::onCreate(%this)
+{
+ $Core::MissingTexturePath = "core/rendering/images/missingTexture";
+ $Core::UnAvailableTexturePath = "core/rendering/images/unavailable";
+ $Core::WarningTexturePath = "core/rendering/images/warnMat";
+ $Core::CommonShaderPath = "core/rendering/shaders";
+
+ exec("./scripts/renderManager.cs");
+ exec("./scripts/gfxData/clouds.cs");
+ exec("./scripts/gfxData/commonMaterialData.cs");
+ exec("./scripts/gfxData/scatterSky.cs");
+ exec("./scripts/gfxData/shaders.cs");
+ exec("./scripts/gfxData/terrainBlock.cs");
+ exec("./scripts/gfxData/water.cs");
+}
+
+function Core_Rendering::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/Core_Rendering.module b/Templates/BaseGame/game/core/rendering/Core_Rendering.module
new file mode 100644
index 000000000..9dbbfc33a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/Core_Rendering.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/images/materials.cs b/Templates/BaseGame/game/core/rendering/images/materials.cs
new file mode 100644
index 000000000..a13c751b3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/images/materials.cs
@@ -0,0 +1,32 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton Material( Empty )
+{
+};
+
+singleton Material(WarningMaterial) {
+ detailMap[0] = "missingTexture";
+ diffuseColor[0] = "25 16 0";
+ emissive[0] = false;
+ translucent = false;
+};
diff --git a/Templates/BaseGame/game/core/rendering/images/missingTexture.png b/Templates/BaseGame/game/core/rendering/images/missingTexture.png
new file mode 100644
index 000000000..80a7874da
Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/missingTexture.png differ
diff --git a/Templates/BaseGame/game/core/rendering/images/unavailable.png b/Templates/BaseGame/game/core/rendering/images/unavailable.png
new file mode 100644
index 000000000..9d818a376
Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/unavailable.png differ
diff --git a/Templates/BaseGame/game/core/rendering/images/warnMat.dds b/Templates/BaseGame/game/core/rendering/images/warnMat.dds
new file mode 100644
index 000000000..ea99dcbd7
Binary files /dev/null and b/Templates/BaseGame/game/core/rendering/images/warnMat.dds differ
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/clouds.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/clouds.cs
new file mode 100644
index 000000000..00d56d6d3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/clouds.cs
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// CloudLayer
+//------------------------------------------------------------------------------
+
+singleton ShaderData( CloudLayerShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/cloudLayerV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/cloudLayerP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/cloudLayerP.glsl";
+
+ samplerNames[0] = "$normalHeightMap";
+
+ pixVersion = 2.0;
+};
+
+//------------------------------------------------------------------------------
+// BasicClouds
+//------------------------------------------------------------------------------
+
+singleton ShaderData( BasicCloudsShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/basicCloudsV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/basicCloudsP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/basicCloudsP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+
+ pixVersion = 2.0;
+};
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/commonMaterialData.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/commonMaterialData.cs
new file mode 100644
index 000000000..c5d8ef5bc
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/commonMaterialData.cs
@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Anim flag settings - must match material.h
+// These cannot be enumed through script becuase it cannot
+// handle the "|" operation for combining them together
+// ie. Scroll | Wave does not work.
+//-----------------------------------------------------------------------------
+$scroll = 1;
+$rotate = 2;
+$wave = 4;
+$scale = 8;
+$sequence = 16;
+
+
+// Common stateblock definitions
+new GFXSamplerStateData(SamplerClampLinear)
+{
+ textureColorOp = GFXTOPModulate;
+ addressModeU = GFXAddressClamp;
+ addressModeV = GFXAddressClamp;
+ addressModeW = GFXAddressClamp;
+ magFilter = GFXTextureFilterLinear;
+ minFilter = GFXTextureFilterLinear;
+ mipFilter = GFXTextureFilterLinear;
+};
+
+new GFXSamplerStateData(SamplerClampPoint)
+{
+ textureColorOp = GFXTOPModulate;
+ addressModeU = GFXAddressClamp;
+ addressModeV = GFXAddressClamp;
+ addressModeW = GFXAddressClamp;
+ magFilter = GFXTextureFilterPoint;
+ minFilter = GFXTextureFilterPoint;
+ mipFilter = GFXTextureFilterPoint;
+};
+
+new GFXSamplerStateData(SamplerWrapLinear)
+{
+ textureColorOp = GFXTOPModulate;
+ addressModeU = GFXTextureAddressWrap;
+ addressModeV = GFXTextureAddressWrap;
+ addressModeW = GFXTextureAddressWrap;
+ magFilter = GFXTextureFilterLinear;
+ minFilter = GFXTextureFilterLinear;
+ mipFilter = GFXTextureFilterLinear;
+};
+
+new GFXSamplerStateData(SamplerWrapPoint)
+{
+ textureColorOp = GFXTOPModulate;
+ addressModeU = GFXTextureAddressWrap;
+ addressModeV = GFXTextureAddressWrap;
+ addressModeW = GFXTextureAddressWrap;
+ magFilter = GFXTextureFilterPoint;
+ minFilter = GFXTextureFilterPoint;
+ mipFilter = GFXTextureFilterPoint;
+};
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/scatterSky.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/scatterSky.cs
new file mode 100644
index 000000000..5add01d8b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/scatterSky.cs
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+new GFXStateBlockData( ScatterSkySBData )
+{
+ cullMode = "GFXCullNone";
+
+ zDefined = true;
+ zEnable = true;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+ samplerStates[1] = SamplerClampLinear;
+ vertexColorEnable = true;
+};
+
+singleton ShaderData( ScatterSkyShaderData )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/scatterSkyV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/scatterSkyP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/scatterSkyP.glsl";
+
+ samplerNames[0] = "$nightSky";
+
+ pixVersion = 2.0;
+};
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/shaders.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/shaders.cs
new file mode 100644
index 000000000..da3b7c864
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/shaders.cs
@@ -0,0 +1,152 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// This file contains shader data necessary for various engine utility functions
+//-----------------------------------------------------------------------------
+
+
+singleton ShaderData( ParticlesShaderData )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/particlesV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/particlesP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particlesV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particlesP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+ samplerNames[1] = "$deferredTex";
+ samplerNames[2] = "$paraboloidLightMap";
+
+ pixVersion = 2.0;
+};
+
+singleton ShaderData( OffscreenParticleCompositeShaderData )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/particleCompositeV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/particleCompositeP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/particleCompositeP.glsl";
+
+ samplerNames[0] = "$colorSource";
+ samplerNames[1] = "$edgeSource";
+
+ pixVersion = 2.0;
+};
+
+//-----------------------------------------------------------------------------
+// Planar Reflection
+//-----------------------------------------------------------------------------
+new ShaderData( ReflectBump )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectBumpP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectBumpP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+ samplerNames[1] = "$refractMap";
+ samplerNames[2] = "$bumpMap";
+
+ pixVersion = 2.0;
+};
+
+new ShaderData( Reflect )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/planarReflectV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/planarReflectP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/planarReflectP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+ samplerNames[1] = "$refractMap";
+
+ pixVersion = 1.4;
+};
+
+//-----------------------------------------------------------------------------
+// fxFoliageReplicator
+//-----------------------------------------------------------------------------
+new ShaderData( fxFoliageReplicatorShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/fxFoliageReplicatorP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/gl/fxFoliageReplicatorP.glsl";
+
+ samplerNames[0] = "$diffuseMap";
+ samplerNames[1] = "$alphaMap";
+
+ pixVersion = 1.4;
+};
+
+singleton ShaderData( VolumetricFogDeferredShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreP.glsl";
+
+ pixVersion = 3.0;
+};
+singleton ShaderData( VolumetricFogShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogP.glsl";
+
+ samplerNames[0] = "$deferredTex";
+ samplerNames[1] = "$depthBuffer";
+ samplerNames[2] = "$frontBuffer";
+ samplerNames[3] = "$density";
+
+ pixVersion = 3.0;
+};
+singleton ShaderData( VolumetricFogReflectionShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogPreV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/VFogRefl.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogPreV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/VolumetricFog/gl/VFogRefl.glsl";
+
+ pixVersion = 3.0;
+};
+singleton ShaderData( CubemapSaveShader )
+{
+ DXVertexShaderFile = "shaders/common/cubemapSaveV.hlsl";
+ DXPixelShaderFile = "shaders/common/cubemapSaveP.hlsl";
+
+ OGLVertexShaderFile = "shaders/common/gl/cubemapSaveV.glsl";
+ OGLPixelShaderFile = "shaders/common/gl/cubemapSaveP.glsl";
+
+ samplerNames[0] = "$cubemapTex";
+
+ pixVersion = 3.0;
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/terrainBlock.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/terrainBlock.cs
new file mode 100644
index 000000000..69802b1da
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/terrainBlock.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+/// Used when generating the blended base texture.
+singleton ShaderData( TerrainBlendShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/terrain/blendV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/terrain/blendP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/terrain/gl/blendP.glsl";
+
+ samplerNames[0] = "layerTex";
+ samplerNames[1] = "textureMap";
+
+ pixVersion = 2.0;
+};
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxData/water.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxData/water.cs
new file mode 100644
index 000000000..ec5e4be71
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxData/water.cs
@@ -0,0 +1,208 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+
+//-----------------------------------------------------------------------------
+// Water
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( WaterShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterP.glsl";
+
+ samplerNames[0] = "$bumpMap"; // noise
+ samplerNames[1] = "$deferredTex"; // #deferred
+ samplerNames[2] = "$reflectMap"; // $reflectbuff
+ samplerNames[3] = "$refractBuff"; // $backbuff
+ samplerNames[4] = "$skyMap"; // $cubemap
+ samplerNames[5] = "$foamMap"; // foam
+ samplerNames[6] = "$depthGradMap"; // depthMap ( color gradient )
+
+ pixVersion = 3.0;
+};
+
+new GFXSamplerStateData(WaterSampler)
+{
+ textureColorOp = GFXTOPModulate;
+ addressModeU = GFXAddressWrap;
+ addressModeV = GFXAddressWrap;
+ addressModeW = GFXAddressWrap;
+ magFilter = GFXTextureFilterLinear;
+ minFilter = GFXTextureFilterAnisotropic;
+ mipFilter = GFXTextureFilterLinear;
+ maxAnisotropy = 4;
+};
+
+singleton GFXStateBlockData( WaterStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = WaterSampler; // noise
+ samplerStates[1] = SamplerClampPoint; // #deferred
+ samplerStates[2] = SamplerClampLinear; // $reflectbuff
+ samplerStates[3] = SamplerClampPoint; // $backbuff
+ samplerStates[4] = SamplerWrapLinear; // $cubemap
+ samplerStates[5] = SamplerWrapLinear; // foam
+ samplerStates[6] = SamplerClampLinear; // depthMap ( color gradient )
+ cullDefined = true;
+ cullMode = "GFXCullCCW";
+};
+
+singleton GFXStateBlockData( UnderWaterStateBlock : WaterStateBlock )
+{
+ cullMode = "GFXCullCW";
+};
+
+singleton CustomMaterial( WaterMat )
+{
+ sampler["deferredTex"] = "#deferred";
+ sampler["reflectMap"] = "$reflectbuff";
+ sampler["refractBuff"] = "$backbuff";
+ // These samplers are set in code not here.
+ // This is to allow different WaterObject instances
+ // to use this same material but override these textures
+ // per instance.
+ //sampler["bumpMap"] = "";
+ //sampler["skyMap"] = "";
+ //sampler["foamMap"] = "";
+ //sampler["depthGradMap"] = "";
+
+ shader = WaterShader;
+ stateBlock = WaterStateBlock;
+ version = 3.0;
+
+ useAnisotropic[0] = true;
+};
+
+//-----------------------------------------------------------------------------
+// Underwater
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( UnderWaterShader : WaterShader )
+{
+ defines = "UNDERWATER";
+};
+
+singleton CustomMaterial( UnderwaterMat )
+{
+ // These samplers are set in code not here.
+ // This is to allow different WaterObject instances
+ // to use this same material but override these textures
+ // per instance.
+ //sampler["bumpMap"] = "core/art/water/noise02";
+ //sampler["foamMap"] = "core/art/water/foam";
+
+ sampler["deferredTex"] = "#deferred";
+ sampler["refractBuff"] = "$backbuff";
+
+ shader = UnderWaterShader;
+ stateBlock = UnderWaterStateBlock;
+ specular = "0.75 0.75 0.75 1.0";
+ specularPower = 48.0;
+ version = 3.0;
+};
+
+//-----------------------------------------------------------------------------
+// Basic Water
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( WaterBasicShader )
+{
+ DXVertexShaderFile = $Core::CommonShaderPath @ "/water/waterBasicV.hlsl";
+ DXPixelShaderFile = $Core::CommonShaderPath @ "/water/waterBasicP.hlsl";
+
+ OGLVertexShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicV.glsl";
+ OGLPixelShaderFile = $Core::CommonShaderPath @ "/water/gl/waterBasicP.glsl";
+
+ samplerNames[0] = "$bumpMap";
+ samplerNames[2] = "$reflectMap";
+ samplerNames[3] = "$refractBuff";
+ samplerNames[4] = "$skyMap";
+ samplerNames[5] = "$depthGradMap";
+
+ pixVersion = 2.0;
+};
+
+singleton GFXStateBlockData( WaterBasicStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = WaterSampler; // noise
+ samplerStates[2] = SamplerClampLinear; // $reflectbuff
+ samplerStates[3] = SamplerClampPoint; // $backbuff
+ samplerStates[4] = SamplerWrapLinear; // $cubemap
+ cullDefined = true;
+ cullMode = "GFXCullCCW";
+};
+
+singleton GFXStateBlockData( UnderWaterBasicStateBlock : WaterBasicStateBlock )
+{
+ cullMode = "GFXCullCW";
+};
+
+singleton CustomMaterial( WaterBasicMat )
+{
+ // These samplers are set in code not here.
+ // This is to allow different WaterObject instances
+ // to use this same material but override these textures
+ // per instance.
+ //sampler["bumpMap"] = "core/art/water/noise02";
+ //sampler["skyMap"] = "$cubemap";
+
+ //sampler["deferredTex"] = "#deferred";
+ sampler["reflectMap"] = "$reflectbuff";
+ sampler["refractBuff"] = "$backbuff";
+
+ cubemap = NewLevelSkyCubemap;
+ shader = WaterBasicShader;
+ stateBlock = WaterBasicStateBlock;
+ version = 2.0;
+};
+
+//-----------------------------------------------------------------------------
+// Basic UnderWater
+//-----------------------------------------------------------------------------
+
+singleton ShaderData( UnderWaterBasicShader : WaterBasicShader)
+{
+ defines = "UNDERWATER";
+};
+
+singleton CustomMaterial( UnderwaterBasicMat )
+{
+ // These samplers are set in code not here.
+ // This is to allow different WaterObject instances
+ // to use this same material but override these textures
+ // per instance.
+ //sampler["bumpMap"] = "core/art/water/noise02";
+ //samplers["skyMap"] = "$cubemap";
+
+ //sampler["deferredTex"] = "#deferred";
+ sampler["refractBuff"] = "$backbuff";
+
+ shader = UnderWaterBasicShader;
+ stateBlock = UnderWaterBasicStateBlock;
+ version = 2.0;
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.ATITechnologiesInc.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.ATITechnologiesInc.cs
new file mode 100644
index 000000000..10c6bdf5b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.ATITechnologiesInc.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// ATI Vendor Profile Script
+//
+// This script is responsible for setting global
+// capability strings based on the nVidia vendor.
+
+if(GFXCardProfiler::getVersion() < 64.44)
+{
+ $GFX::OutdatedDrivers = true;
+ $GFX::OutdatedDriversLink = "You can get newer drivers here..";
+}
+else
+{
+ $GFX::OutdatedDrivers = false;
+}
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.GeForce8600.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.GeForce8600.cs
new file mode 100644
index 000000000..328788dac
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.GeForce8600.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// nVidia Vendor Profile Script
+//
+// This script is responsible for setting global
+// capability strings based on the nVidia vendor.
+
+if(GFXCardProfiler::getVersion() < 1.2)
+{
+ $GFX::OutdatedDrivers = true;
+ $GFX::OutdatedDriversLink = "You can get newer drivers here..";
+}
+else
+{
+ $GFX::OutdatedDrivers = false;
+}
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs
new file mode 100644
index 000000000..5681b2f6d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.QuadroFXGo1000.cs
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// nVidia Vendor Profile Script
+//
+// This script is responsible for setting global
+// capability strings based on the nVidia vendor.
+
+if(GFXCardProfiler::getVersion() < 53.82)
+{
+ $GFX::OutdatedDrivers = true;
+ $GFX::OutdatedDriversLink = "You can get newer drivers here..";
+}
+else
+{
+ $GFX::OutdatedDrivers = false;
+}
+
+// Silly card has trouble with this!
+GFXCardProfiler::setCapability("autoMipmapLevel", false);
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.cs
new file mode 100644
index 000000000..b33b8d5d3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.NVIDIA.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// nVidia Vendor Profile Script
+//
+// This script is responsible for setting global
+// capability strings based on the nVidia vendor.
+
+if(GFXCardProfiler::getVersion() < 56.72)
+{
+ $GFX::OutdatedDrivers = true;
+ $GFX::OutdatedDriversLink = "You can get newer drivers here..";
+}
+else
+{
+ $GFX::OutdatedDrivers = false;
+}
diff --git a/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.cs b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.cs
new file mode 100644
index 000000000..e1e299341
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/gfxprofile/D3D9.cs
@@ -0,0 +1,26 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Direct3D 9 Renderer Profile Script
+//
+// This script is responsible for setting global
+// capability strings based on the D3D9 renderer type.
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs b/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs
new file mode 100644
index 000000000..4a80a45b1
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/scripts/renderManager.cs
@@ -0,0 +1,126 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+function initRenderManager()
+{
+ assert( !isObject( DiffuseRenderPassManager ), "initRenderManager() - DiffuseRenderPassManager already initialized!" );
+
+ new RenderPassManager( DiffuseRenderPassManager );
+
+ // This token, and the associated render managers, ensure that driver MSAA
+ // does not get used for Advanced Lighting renders. The 'AL_FormatResolve'
+ // PostEffect copies the result to the backbuffer.
+ new RenderFormatToken(AL_FormatToken)
+ {
+ enabled = "false";
+
+ //When hdr is enabled this will be changed to the appropriate format
+ format = "GFXFormatR8G8B8A8_SRGB";
+ depthFormat = "GFXFormatD24S8";
+ aaLevel = 0; // -1 = match backbuffer
+
+ // The contents of the back buffer before this format token is executed
+ // is provided in $inTex
+ copyEffect = "AL_FormatCopy";
+
+ // The contents of the render target created by this format token is
+ // provided in $inTex
+ resolveEffect = "AL_FormatCopy";
+ };
+ 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 RenderVistaMgr() { bintype = "Vista"; renderOrder = 0.15; processAddOrder = 0.15; } );
+
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(BeginBin) { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } );
+ // Normal mesh rendering.
+ DiffuseRenderPassManager.addManager( new RenderTerrainMgr(TerrainBin) { renderOrder = 0.4; processAddOrder = 0.4; basicOnly = true; } );
+ DiffuseRenderPassManager.addManager( new RenderMeshMgr(MeshBin) { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; basicOnly = true; } );
+ DiffuseRenderPassManager.addManager( new RenderImposterMgr(ImposterBin) { renderOrder = 0.56; processAddOrder = 0.56; } );
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjectBin) { bintype = "Object"; renderOrder = 0.6; processAddOrder = 0.6; } );
+
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(ShadowBin) { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } );
+ 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; } );
+
+ // We now render translucent objects that should handle
+ // their own fogging and lighting.
+
+ // Note that the fog effect is triggered before this bin.
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjTranslucentBin) { bintype = "ObjectTranslucent"; renderOrder = 1.0; processAddOrder = 1.0; } );
+
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(WaterBin) { bintype = "Water"; renderOrder = 1.2; processAddOrder = 1.2; } );
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(FoliageBin) { bintype = "Foliage"; renderOrder = 1.3; processAddOrder = 1.3; } );
+ DiffuseRenderPassManager.addManager( new RenderParticleMgr(ParticleBin) { renderOrder = 1.35; processAddOrder = 1.35; } );
+ DiffuseRenderPassManager.addManager( new RenderTranslucentMgr(TranslucentBin){ renderOrder = 1.4; processAddOrder = 1.4; } );
+
+ DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } );
+
+ // Note that the GlowPostFx is triggered after this bin.
+ DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } );
+
+ // We render any editor stuff from this bin. Note that the HDR is
+ // completed before this bin to keep editor elements from tone mapping.
+ DiffuseRenderPassManager.addManager( new RenderObjectMgr(EditorBin) { bintype = "Editor"; renderOrder = 1.6; processAddOrder = 1.6; } );
+
+ // Resolve format change token last.
+ DiffuseRenderPassManager.addManager( new RenderPassStateBin(FinalBin) { renderOrder = 1.7; stateToken = AL_FormatToken; } );
+}
+
+/// This is the Default PostFX state block. Put here to prevent any missing object
+/// errors for below dependencies
+singleton GFXStateBlockData( PFX_DefaultStateBlock )
+{
+ zDefined = true;
+ zEnable = false;
+ zWriteEnable = false;
+
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampLinear;
+};
+
+/// This post effect is used to copy data from the non-MSAA back-buffer to the
+/// device back buffer (which could be MSAA). It must be declared here so that
+/// it is initialized when 'AL_FormatToken' is initialzed.
+singleton GFXStateBlockData( AL_FormatTokenState : PFX_DefaultStateBlock )
+{
+ samplersDefined = true;
+ samplerStates[0] = SamplerClampPoint;
+};
+
+singleton PostEffect( AL_FormatCopy )
+{
+ // This PostEffect is used by 'AL_FormatToken' directly. It is never added to
+ // the PostEffectManager. Do not call enable() on it.
+ isEnabled = false;
+ allowReflectPass = true;
+
+ shader = PFX_PassthruShader;
+ stateBlock = AL_FormatTokenState;
+
+ texture[0] = "$inTex";
+ target = "$backbuffer";
+};
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogP.hlsl
new file mode 100644
index 000000000..7de14a87d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogP.hlsl
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final pixel shader V2.00
+#include "../shaderModel.hlsl"
+#include "../shaderModelAutoGen.hlsl"
+#include "../torque.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(depthBuffer, 1);
+TORQUE_UNIFORM_SAMPLER2D(frontBuffer, 2);
+TORQUE_UNIFORM_SAMPLER2D(density, 3);
+
+uniform float3 ambientColor;
+uniform float accumTime;
+uniform float4 fogColor;
+uniform float4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform float2 viewpoint;
+uniform float2 texscale;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform float numtiles;
+uniform float fadesize;
+uniform float2 PixelSize;
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 htpos : TEXCOORD0;
+ float2 uv0 : TEXCOORD1;
+};
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ float2 uvscreen=((IN.htpos.xy/IN.htpos.w) + 1.0 ) / 2.0;
+ uvscreen.y = 1.0 - uvscreen.y;
+
+ float obj_test = TORQUE_DEFERRED_UNCONDITION(deferredTex, uvscreen).w * preBias;
+ float depth = TORQUE_TEX2D(depthBuffer, uvscreen).r;
+ float front = TORQUE_TEX2D(frontBuffer, uvscreen).r;
+
+ if (depth <= front)
+ return float4(0,0,0,0);
+ else if ( obj_test < depth )
+ depth = obj_test;
+ if ( front >= 0.0)
+ depth -= front;
+
+ float diff = 1.0;
+ float3 col = fogColor.rgb;
+ if (textured != 0.0)
+ {
+ float2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+ float2 mod1 = TORQUE_TEX2D(density, (offset + (modspeed.xy*accumTime))).rg;
+ float2 mod2 = TORQUE_TEX2D(density, (offset + (modspeed.zw*accumTime))).rg;
+ diff = (mod2.r + mod1.r) * modstrength;
+ col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+ }
+
+ col *= ambientColor;
+
+ float4 resultColor = float4(col, 1.0 - saturate(exp(-fogDensity * depth * diff * fadesize)));
+
+ return hdrEncode(resultColor);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreP.hlsl
new file mode 100644
index 000000000..9d5060935
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreP.hlsl
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog deferred pixel shader V1.00
+#include "../shaderModel.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ float OUT;
+
+ clip( IN.pos.w );
+ OUT = IN.pos.w;
+
+ return float4(OUT,0,0,1);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreV.hlsl
new file mode 100644
index 000000000..b736e0d0d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogPreV.hlsl
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog deferred vertex shader V1.00
+
+#include "../shaderModel.hlsl"
+#include "../hlslStructs.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 pos : TEXCOORD0;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_P IN)
+{
+ ConnectData OUT;
+
+ OUT.hpos = mul(modelView, float4(IN.pos, 1.0));
+ OUT.pos = OUT.hpos;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogRefl.hlsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogRefl.hlsl
new file mode 100644
index 000000000..380233b5f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogRefl.hlsl
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Reflection pixel shader V1.00
+#include "../shaderModel.hlsl"
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ return float4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogV.hlsl
new file mode 100644
index 000000000..167f83946
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/VFogV.hlsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final vertex shader V1.00
+
+#include "../shaderModel.hlsl"
+#include "../hlslStructs.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 htpos : TEXCOORD0;
+ float2 uv0 : TEXCOORD1;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_PNTT IN)
+{
+ ConnectData OUT;
+
+ OUT.hpos = mul(modelView, float4(IN.pos,1.0));
+ OUT.htpos = OUT.hpos;
+ OUT.uv0 = IN.uv0;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogP.glsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogP.glsl
new file mode 100644
index 000000000..fcfa31244
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogP.glsl
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+
+uniform sampler2D deferredTex;
+uniform sampler2D depthBuffer;
+uniform sampler2D frontBuffer;
+uniform sampler2D density;
+
+uniform float accumTime;
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform vec4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform vec2 viewpoint;
+uniform vec2 texscale;
+uniform vec3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform vec2 PixelSize;
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+out vec4 OUT_col;
+
+void main()
+{
+ vec2 uvscreen=((IN_hpos.xy/IN_hpos.w) + 1.0 ) / 2.0;
+ uvscreen.y = 1.0 - uvscreen.y;
+
+ float obj_test = deferredUncondition( deferredTex, uvscreen).w * preBias;
+ float depth = tex2D(depthBuffer,uvscreen).r;
+ float front = tex2D(frontBuffer,uvscreen).r;
+
+ if (depth <= front)
+ {
+ OUT_col = vec4(0,0,0,0);
+ return;
+ }
+
+ else if ( obj_test < depth )
+ depth = obj_test;
+ if ( front >= 0.0)
+ depth -= front;
+
+ float diff = 1.0;
+ vec3 col = fogColor.rgb;
+ if (textured != 0.0)
+ {
+ vec2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+ vec2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+ vec2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+ diff = (mod2.r + mod1.r) * modstrength;
+ col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+ }
+
+ col *= ambientColor;
+
+ vec4 returnColor = vec4(col, 1.0 - saturate(exp(-fogDensity * depth * diff * fadesize)));
+
+ OUT_col = hdrEncode(returnColor);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreP.glsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreP.glsl
new file mode 100644
index 000000000..017ea6ef8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreP.glsl
@@ -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 "../../gl/hlslCompat.glsl"
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+
+out vec4 OUT_col;
+
+void main()
+{
+ float OUT;
+ clip( IN_hpos.w );
+ OUT = IN_hpos.w;
+
+ OUT_col = vec4(OUT,0,0,1);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreV.glsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreV.glsl
new file mode 100644
index 000000000..2f2a1318a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogPreV.glsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()
+{
+ vec4 inPos = IN_position;
+ inPos.w = 1.0;
+
+ OUT_hpos = tMul( modelView, inPos );
+
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogRefl.glsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogRefl.glsl
new file mode 100644
index 000000000..78e149fbf
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogRefl.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"
+
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = vec4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogV.glsl b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogV.glsl
new file mode 100644
index 000000000..57b3ba87e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/VolumetricFog/gl/VFogV.glsl
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()
+{
+ OUT_hpos = tMul(modelView, IN_position);
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/basicCloudsP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsP.hlsl
new file mode 100644
index 000000000..4b40e5e8c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsP.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 "torque.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ float4 col = TORQUE_TEX2D(diffuseMap, IN.texCoord);
+ return hdrEncode( col );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.hlsl
new file mode 100644
index 000000000..a176fdbcd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/basicCloudsV.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 "shaderModel.hlsl"
+
+struct CloudVert
+{
+ float3 pos : POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+uniform float4x4 modelview;
+uniform float2 texDirection;
+uniform float2 texOffset;
+uniform float accumTime;
+uniform float texScale;
+
+
+ConnectData main( CloudVert IN )
+{
+ ConnectData OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.pos,1.0));
+
+ float2 uv = IN.uv0;
+ uv += texOffset;
+ uv *= texScale;
+ uv += accumTime * texDirection;
+
+ OUT.texCoord = uv;
+
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/cloudLayerP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerP.hlsl
new file mode 100644
index 000000000..efa8fe0b4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerP.hlsl
@@ -0,0 +1,146 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "torque.hlsl"
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 texCoord12 : TEXCOORD0;
+ float4 texCoord34 : TEXCOORD1;
+ float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized
+ float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized
+ float worldDist : TEXCOORD4;
+};
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+TORQUE_UNIFORM_SAMPLER2D(normalHeightMap, 0);
+uniform float3 ambientColor;
+uniform float3 sunColor;
+uniform float cloudCoverage;
+uniform float3 cloudBaseColor;
+uniform float cloudExposure;
+
+//-----------------------------------------------------------------------------
+// Globals
+//-----------------------------------------------------------------------------
+// The per-color weighting to be used for luminance calculations in RGB order.
+static const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f);
+
+
+//-----------------------------------------------------------------------------
+// Functions
+//-----------------------------------------------------------------------------
+
+// Calculates the Rayleigh phase function
+float getRayleighPhase( float angle )
+{
+ return 0.75 * ( 1.0 + pow( angle, 2 ) );
+}
+
+// Returns the output rgb color given a texCoord and parameters it uses
+// for lighting calculation.
+float3 ComputeIllumination( float2 texCoord,
+ float3 vLightTS,
+ float3 vViewTS,
+ float3 vNormalTS )
+{
+ //return noiseNormal;
+ //return vNormalTS;
+
+ float3 vLightTSAdj = float3( -vLightTS.x, -vLightTS.y, vLightTS.z );
+
+ float dp = dot( vNormalTS, vLightTSAdj );
+
+ // Calculate the amount of illumination (lightTerm)...
+
+ // We do both a rim lighting effect and a halfLambertian lighting effect
+ // and combine the result.
+ float halfLambertTerm = saturate( pow( dp * 0.5 + 0.5, 1 ) );
+ float rimLightTerm = pow( ( 1.0 - dp ), 1.0 );
+ float lightTerm = saturate( halfLambertTerm * 1.0 + rimLightTerm * dp );
+ lightTerm *= 0.5;
+
+ // Use a simple RayleighPhase function to simulate single scattering towards
+ // the camera.
+ float angle = dot( vLightTS, vViewTS );
+ lightTerm *= getRayleighPhase( angle );
+
+ // Combine terms and colors into the output color.
+ //float3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor;
+ float3 lightColor = lerp( ambientColor, sunColor, lightTerm );
+ //lightColor = lerp( lightColor, ambientColor, cloudCoverage );
+ float3 finalColor = cloudBaseColor * lightColor;
+
+ return finalColor;
+}
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ // Normalize the interpolated vectors:
+ float3 vViewTS = normalize( IN.vViewTS );
+ float3 vLightTS = normalize( IN.vLightTS );
+
+ float4 cResultColor = float4( 0, 0, 0, 1 );
+
+ float2 texSample = IN.texCoord12.xy;
+
+ float4 noise1 = TORQUE_TEX2D( normalHeightMap, IN.texCoord12.zw );
+ noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
+ //return noise1;
+
+ float4 noise2 = TORQUE_TEX2D(normalHeightMap, IN.texCoord34.xy);
+ noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
+ //return noise2;
+
+ float3 noiseNormal = normalize( noise1 + noise2 ).xyz;
+ //return float4( noiseNormal, 1.0 );
+
+ float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 );
+
+ float3 vNormalTS = normalize( TORQUE_TEX2D(normalHeightMap, texSample).xyz * 2.0 - 1.0);
+ vNormalTS += noiseNormal;
+ vNormalTS = normalize( vNormalTS );
+
+ // Compute resulting color for the pixel:
+ cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
+
+ float coverage = ( cloudCoverage - 0.5 ) * 2.0;
+ cResultColor.a = TORQUE_TEX2D(normalHeightMap, texSample).a + coverage + noiseHeight;
+
+ if ( cloudCoverage > -1.0 )
+ cResultColor.a /= 1.0 + coverage;
+
+ cResultColor.a = saturate( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ) );
+
+ cResultColor.a = lerp( cResultColor.a, 0.0, 1.0 - pow(IN.worldDist,2.0) );
+
+ cResultColor.rgb *= cloudExposure;
+
+ return hdrEncode( cResultColor );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl
new file mode 100644
index 000000000..d60dd251d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/cloudLayerV.hlsl
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+#include "shaderModel.hlsl"
+
+struct CloudVert
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float3 binormal : BINORMAL;
+ float3 tangent : TANGENT;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 texCoord12 : TEXCOORD0;
+ float4 texCoord34 : TEXCOORD1;
+ float3 vLightTS : TEXCOORD2; // light vector in tangent space, denormalized
+ float3 vViewTS : TEXCOORD3; // view vector in tangent space, denormalized
+ float worldDist : TEXCOORD4;
+};
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform float4x4 modelview;
+uniform float3 eyePosWorld;
+uniform float3 sunVec;
+uniform float2 texOffset0;
+uniform float2 texOffset1;
+uniform float2 texOffset2;
+uniform float3 texScale;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( CloudVert IN )
+{
+ ConnectData OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.pos,1.0));
+ // Offset the uv so we don't have a seam directly over our head.
+ float2 uv = IN.uv0 + float2( 0.5, 0.5 );
+
+ OUT.texCoord12.xy = uv * texScale.x;
+ OUT.texCoord12.xy += texOffset0;
+
+ OUT.texCoord12.zw = uv * texScale.y;
+ OUT.texCoord12.zw += texOffset1;
+
+ OUT.texCoord34.xy = uv * texScale.z;
+ OUT.texCoord34.xy += texOffset2;
+
+ OUT.texCoord34.z = IN.pos.z;
+ OUT.texCoord34.w = 0.0;
+
+ // Transform the normal, tangent and binormal vectors from object space to
+ // homogeneous projection space:
+ float3 vNormalWS = -IN.normal;
+ float3 vTangentWS = -IN.tangent;
+ float3 vBinormalWS = -IN.binormal;
+
+ // Compute position in world space:
+ float4 vPositionWS = float4(IN.pos, 1.0) + float4(eyePosWorld, 1); //mul( IN.pos, objTrans );
+
+ // Compute and output the world view vector (unnormalized):
+ float3 vViewWS = eyePosWorld - vPositionWS.xyz;
+
+ // Compute denormalized light vector in world space:
+ float3 vLightWS = -sunVec;
+
+ // Normalize the light and view vectors and transform it to the tangent space:
+ float3x3 mWorldToTangent = float3x3( vTangentWS, vBinormalWS, vNormalWS );
+
+ // Propagate the view and the light vectors (in tangent space):
+ OUT.vLightTS = mul( vLightWS, mWorldToTangent );
+ OUT.vViewTS = mul( mWorldToTangent, vViewWS );
+
+ OUT.worldDist = saturate( pow( max( IN.pos.z, 0 ), 2 ) );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureP.hlsl
new file mode 100644
index 000000000..d0577428f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureP.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 Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+float4 main( Conn IN ) : TORQUE_TARGET0
+{
+ return float4(IN.color.rgb, IN.color.a * TORQUE_TEX2D(diffuseMap, IN.texCoord).a);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureV.hlsl
new file mode 100644
index 000000000..8bf4e88d8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/addColorTextureV.hlsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 Appdata
+{
+ float3 position : POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+uniform float4x4 modelview;
+
+Conn main( Appdata In )
+{
+ Conn Out;
+ Out.HPOS = mul(modelview, float4(In.position,1.0));
+ Out.color = In.color;
+ Out.texCoord = In.texCoord;
+ return Out;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorP.hlsl
new file mode 100644
index 000000000..dd9990e07
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorP.hlsl
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// 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 Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+};
+
+float4 main(Conn IN) : TORQUE_TARGET0
+{
+ return IN.color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorV.hlsl
new file mode 100644
index 000000000..d16dfb863
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/colorV.hlsl
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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 Appdata
+{
+ float3 position : POSITION;
+ float4 color : COLOR;
+};
+
+struct Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+};
+
+uniform float4x4 modelview;
+
+Conn main( Appdata In )
+{
+ Conn Out;
+ Out.HPOS = mul(modelview, float4(In.position,1.0));
+ Out.color = In.color;
+ return Out;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureP.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureP.glsl
new file mode 100644
index 000000000..b9a10adf3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureP.glsl
@@ -0,0 +1,32 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D diffuseMap;
+in vec4 color;
+in vec2 texCoord;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = vec4(color.rgb, color.a * texture(diffuseMap, texCoord).a);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureV.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureV.glsl
new file mode 100644
index 000000000..5d7f10168
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/addColorTextureV.glsl
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+in vec4 vColor;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+out vec4 color;
+out vec2 texCoord;
+
+void main()
+{
+ gl_Position = tMul(modelview, vPosition);
+ correctSSP(gl_Position);
+ color = vColor;
+ texCoord = vTexCoord0.st;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorP.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorP.glsl
new file mode 100644
index 000000000..f9dfc3d4f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorP.glsl
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+in vec4 color;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorV.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorV.glsl
new file mode 100644
index 000000000..895917b55
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/colorV.glsl
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+in vec4 vColor;
+
+uniform mat4 modelview;
+out vec4 color;
+
+void main()
+{
+ gl_Position = tMul(modelview, vPosition);
+ correctSSP(gl_Position);
+ color = vColor;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureP.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureP.glsl
new file mode 100644
index 000000000..c24b9db12
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureP.glsl
@@ -0,0 +1,32 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D diffuseMap;
+in vec4 color;
+in vec2 texCoord;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = texture(diffuseMap, texCoord) * color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureV.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureV.glsl
new file mode 100644
index 000000000..5d7f10168
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/modColorTextureV.glsl
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+in vec4 vColor;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+out vec4 color;
+out vec2 texCoord;
+
+void main()
+{
+ gl_Position = tMul(modelview, vPosition);
+ correctSSP(gl_Position);
+ color = vColor;
+ texCoord = vTexCoord0.st;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreP.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreP.glsl
new file mode 100644
index 000000000..770f8904d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreP.glsl
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D colorTarget0Texture ;
+
+vec4 main( vec2 ScreenPos : VPOS ) : COLOR0
+{
+ vec2 TexCoord = ScreenPos;
+ vec4 diffuse;
+ asm { tfetch2D diffuse, TexCoord, colorTarget0Texture, UnnormalizedTextureCoords = true };
+ return diffuse;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreV.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreV.glsl
new file mode 100644
index 000000000..e99d2e537
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/targetRestoreV.glsl
@@ -0,0 +1,22 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureP.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureP.glsl
new file mode 100644
index 000000000..50cef4bda
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureP.glsl
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D diffuseMap;
+in vec2 texCoord;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = texture(diffuseMap, texCoord);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureV.glsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureV.glsl
new file mode 100644
index 000000000..20dbb6f10
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/gl/textureV.glsl
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+out vec2 texCoord;
+
+void main()
+{
+ gl_Position = tMul(modelview, vPosition);
+ correctSSP(gl_Position);
+ texCoord = vTexCoord0.st;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureP.hlsl
new file mode 100644
index 000000000..63afec2a4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureP.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 Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+float4 main( Conn IN ) : TORQUE_TARGET0
+{
+ return TORQUE_TEX2D(diffuseMap, IN.texCoord) * IN.color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureV.hlsl
new file mode 100644
index 000000000..8bf4e88d8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/modColorTextureV.hlsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 Appdata
+{
+ float3 position : POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct Conn
+{
+ float4 HPOS : TORQUE_POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+uniform float4x4 modelview;
+
+Conn main( Appdata In )
+{
+ Conn Out;
+ Out.HPOS = mul(modelview, float4(In.position,1.0));
+ Out.color = In.color;
+ Out.texCoord = In.texCoord;
+ return Out;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreP.hlsl
new file mode 100644
index 000000000..9ef44f426
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreP.hlsl
@@ -0,0 +1,31 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D colorTarget0Texture : register(s0);
+
+float4 main( float2 ScreenPos : VPOS ) : COLOR0
+{
+ float2 TexCoord = ScreenPos;
+ float4 diffuse;
+ asm { tfetch2D diffuse, TexCoord, colorTarget0Texture, UnnormalizedTextureCoords = true };
+ return diffuse;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreV.hlsl
new file mode 100644
index 000000000..3c4aefaec
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/targetRestoreV.hlsl
@@ -0,0 +1,26 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+float4 main( const float2 inPosition : POSITION ) : POSITION
+{
+ return float4( inPosition, 0, 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureP.hlsl
new file mode 100644
index 000000000..82dbd4ce9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureP.hlsl
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+float4 main(Conn IN) : TORQUE_TARGET0
+{
+ return TORQUE_TEX2D(diffuseMap, IN.texCoord);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureV.hlsl
new file mode 100644
index 000000000..204cf9514
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fixedFunction/textureV.hlsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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 Appdata
+{
+ float3 position : POSITION;
+ float4 color : COLOR;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+uniform float4x4 modelview;
+
+Conn main( Appdata In )
+{
+ Conn Out;
+ Out.hpos = mul(modelview, float4(In.position, 1.0));
+ Out.texCoord = In.texCoord;
+ return Out;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/foliage.hlsl b/Templates/BaseGame/game/core/rendering/shaders/foliage.hlsl
new file mode 100644
index 000000000..9952c29d6
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/foliage.hlsl
@@ -0,0 +1,186 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// CornerId corresponds to this arrangement
+// from the perspective of the camera.
+//
+// 3 ---- 2
+// | |
+// 0 ---- 1
+//
+
+#define MAX_COVERTYPES 8
+
+uniform float2 gc_fadeParams;
+uniform float2 gc_windDir;
+uniform float3 gc_camRight;
+uniform float3 gc_camUp;
+uniform float4 gc_typeRects[MAX_COVERTYPES];
+
+// .x = gust length
+// .y = premultiplied simulation time and gust frequency
+// .z = gust strength
+uniform float3 gc_gustInfo;
+
+// .x = premultiplied simulation time and turbulance frequency
+// .y = turbulance strength
+uniform float2 gc_turbInfo;
+
+
+static float sCornerRight[4] = { -0.5, 0.5, 0.5, -0.5 };
+
+static float sCornerUp[4] = { 0, 0, 1, 1 };
+
+static float sMovableCorner[4] = { 0, 0, 1, 1 };
+
+static float2 sUVCornerExtent[4] =
+{
+ float2( 0, 1 ),
+ float2( 1, 1 ),
+ float2( 1, 0 ),
+ float2( 0, 0 )
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// The following wind effect was derived from the GPU Gems 3 chapter...
+//
+// "Vegetation Procedural Animation and Shading in Crysis"
+// by Tiago Sousa, Crytek
+//
+
+float2 smoothCurve( float2 x )
+{
+ return x * x * ( 3.0 - 2.0 * x );
+}
+
+float2 triangleWave( float2 x )
+{
+ return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
+}
+
+float2 smoothTriangleWave( float2 x )
+{
+ return smoothCurve( triangleWave( x ) );
+}
+
+float windTurbulence( float bbPhase, float frequency, float strength )
+{
+ // We create the input value for wave generation from the frequency and phase.
+ float2 waveIn = bbPhase.xx + frequency.xx;
+
+ // We use two square waves to generate the effect which
+ // is then scaled by the overall strength.
+ float2 waves = ( frac( waveIn.xy * float2( 1.975, 0.793 ) ) * 2.0 - 1.0 );
+ waves = smoothTriangleWave( waves );
+
+ // Sum up the two waves into a single wave.
+ return ( waves.x + waves.y ) * strength;
+}
+
+float2 windEffect( float bbPhase,
+ float2 windDirection,
+ float gustLength,
+ float gustFrequency,
+ float gustStrength,
+ float turbFrequency,
+ float turbStrength )
+{
+ // Calculate the ambient wind turbulence.
+ float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength );
+
+ // We simulate the overall gust via a sine wave.
+ float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0, 1 );
+ float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence );
+
+ // Return the final directional wind effect.
+ return gustOffset.xx * windDirection.xy;
+}
+
+void foliageProcessVert( inout float3 position,
+ inout float4 diffuse,
+ inout float4 texCoord,
+ inout float3 normal,
+ inout float3 T,
+ in float3 eyePos )
+{
+ // Assign the normal and tagent values.
+ //normal = float3( 0, 0, 1 );//cross( gc_camUp, gc_camRight );
+ T = gc_camRight;
+
+ // Pull out local vars we need for work.
+ int corner = ( diffuse.a * 255.0f ) + 0.5f;
+ float2 size = texCoord.xy;
+ int type = texCoord.z;
+
+ // The billboarding is based on the camera direction.
+ float3 rightVec = gc_camRight * sCornerRight[corner];
+ float3 upVec = gc_camUp * sCornerUp[corner];
+
+ // Figure out the corner position.
+ float3 outPos = ( upVec * size.y ) + ( rightVec * size.x );
+ float len = length( outPos.xyz );
+
+ // We derive the billboard phase used for wind calculations from its position.
+ float bbPhase = dot( position.xyz, 1 );
+
+ // Get the overall wind gust and turbulence effects.
+ float3 wind;
+ wind.xy = windEffect( bbPhase,
+ gc_windDir,
+ gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z,
+ gc_turbInfo.x, gc_turbInfo.y );
+ wind.z = 0;
+
+ // Add the summed wind effect into the point.
+ outPos.xyz += wind.xyz * texCoord.w;
+
+ // Do a simple spherical clamp to keep the foliage
+ // from stretching too much by wind effect.
+ outPos.xyz = normalize( outPos.xyz ) * len;
+
+ // Move the point into world space.
+ position += outPos;
+
+ // Grab the uv set and setup the texture coord.
+ float4 uvSet = gc_typeRects[type];
+ texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
+ texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
+
+ // Animate the normal to get lighting changes
+ // across the the wind swept foliage.
+ //
+ // TODO: Expose the 10x as a factor to control
+ // how much the wind effects the lighting on the grass.
+ //
+ normal.xy += wind.xy * ( 10.0 * texCoord.w );
+ normal = normalize( normal );
+
+ // Get the alpha fade value.
+
+ float fadeStart = gc_fadeParams.x;
+ float fadeEnd = gc_fadeParams.y;
+ const float fadeRange = fadeEnd - fadeStart;
+
+ float dist = distance( eyePos, position.xyz ) - fadeStart;
+ diffuse.a = 1 - clamp( dist / fadeRange, 0, 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorP.hlsl
new file mode 100644
index 000000000..a8bb68e28
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorP.hlsl
@@ -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 "shdrConsts.h"
+#include "shaderModel.hlsl"
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 outTexCoord : TEXCOORD0;
+ float4 color : COLOR0;
+ float4 groundAlphaCoeff : COLOR1;
+ float2 alphaLookup : TEXCOORD1;
+};
+
+struct Fragout
+{
+ float4 col : TORQUE_TARGET0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+TORQUE_UNIFORM_SAMPLER2D(alphaMap, 1);
+
+uniform float4 groundAlpha;
+uniform float4 ambient;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main( ConnectData IN )
+{
+ Fragout OUT;
+
+ float4 alpha = TORQUE_TEX2D(alphaMap, IN.alphaLookup);
+ OUT.col = float4( ambient.rgb * IN.lum.rgb, 1.0 ) * TORQUE_TEX2D(diffuseMap, IN.texCoord);
+ OUT.col.a = OUT.col.a * min(alpha, groundAlpha + IN.groundAlphaCoeff.x).x;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorV.hlsl
new file mode 100644
index 000000000..70ec9ff4c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/fxFoliageReplicatorV.hlsl
@@ -0,0 +1,129 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+#include "shaderModel.hlsl"
+
+struct VertData
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float2 texCoord : TEXCOORD0;
+ float2 waveScale : TEXCOORD1;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 outTexCoord : TEXCOORD0;
+ float4 color : COLOR0;
+ float4 groundAlphaCoeff : COLOR1;
+ float2 alphaLookup : TEXCOORD1;
+};
+
+uniform float4x4 projection : register(C0);
+uniform float4x4 world : register(C4);
+uniform float GlobalSwayPhase : register(C8);
+uniform float SwayMagnitudeSide : register(C9);
+uniform float SwayMagnitudeFront : register(C10);
+uniform float GlobalLightPhase : register(C11);
+uniform float LuminanceMagnitude : register(C12);
+uniform float LuminanceMidpoint : register(C13);
+uniform float DistanceRange : register(C14);
+uniform float3 CameraPos : register(C15);
+uniform float TrueBillboard : register(C16);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertData IN )
+{
+ ConnectData OUT;
+
+ // Init a transform matrix to be used in the following steps
+ float4x4 trans = 0;
+ trans[0][0] = 1;
+ trans[1][1] = 1;
+ trans[2][2] = 1;
+ trans[3][3] = 1;
+ trans[0][3] = IN.position.x;
+ trans[1][3] = IN.position.y;
+ trans[2][3] = IN.position.z;
+
+ // Billboard transform * world matrix
+ float4x4 o = world;
+ o = mul(o, trans);
+
+ // Keep only the up axis result and position transform.
+ // This gives us "cheating" cylindrical billboarding.
+ o[0][0] = 1;
+ o[1][0] = 0;
+ o[2][0] = 0;
+ o[3][0] = 0;
+ o[0][1] = 0;
+ o[1][1] = 1;
+ o[2][1] = 0;
+ o[3][1] = 0;
+
+ // Unless the user specified TrueBillboard,
+ // in which case we want the z axis to also be camera facing.
+
+#ifdef TRUE_BILLBOARD
+
+ o[0][2] = 0;
+ o[1][2] = 0;
+ o[2][2] = 1;
+ o[3][2] = 0;
+
+#endif
+
+ // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier,
+ // the y coordinate determines if this vertex actually sways or not.
+ float xSway, ySway;
+ float wavePhase = GlobalSwayPhase * IN.waveScale.x;
+ sincos(wavePhase, ySway, xSway);
+ xSway = xSway * IN.waveScale.y * SwayMagnitudeSide;
+ ySway = ySway * IN.waveScale.y * SwayMagnitudeFront;
+ float4 p;
+ p = mul(o, float4(IN.normal.x + xSway, ySway, IN.normal.z, 1));
+
+ // Project the point
+ OUT.hpos = mul(projection, p);
+
+ // Lighting
+ float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + IN.normal.y);
+
+ // Alpha
+ float3 worldPos = IN.position;
+ float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange;
+ alpha = clamp(alpha, 0.0f, 1.0f); //pass it through
+
+ OUT.alphaLookup = float2(alpha, 0.0f);
+ OUT.groundAlphaCoeff = all(IN.normal.z);
+ OUT.outTexCoord = IN.texCoord;
+ OUT.color = float4(Luminance, Luminance, Luminance, 1.0f);
+
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsP.glsl
new file mode 100644
index 000000000..5b3f50519
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsP.glsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "hlslCompat.glsl"
+
+//ConnectData
+in vec2 texCoord;
+#define IN_texCoord texCoord
+
+
+uniform sampler2D diffuseMap ;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 col = texture( diffuseMap, IN_texCoord );
+ OUT_col = hdrEncode( col );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl
new file mode 100644
index 000000000..cccbafa8c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/basicCloudsV.glsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+//CloudVert
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define IN_pos vPosition
+#define IN_uv0 vTexCoord0
+
+uniform mat4 modelview;
+uniform float accumTime;
+uniform float texScale;
+uniform vec2 texDirection;
+uniform vec2 texOffset;
+
+out vec2 texCoord;
+#define OUT_texCoord texCoord
+
+void main()
+{
+ gl_Position = tMul(modelview, IN_pos);
+
+ vec2 uv = IN_uv0;
+ uv += texOffset;
+ uv *= texScale;
+ uv += accumTime * texDirection;
+
+ OUT_texCoord = uv;
+
+ correctSSP(gl_Position);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/blurP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/blurP.glsl
new file mode 100644
index 000000000..a27538762
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/blurP.glsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//*****************************************************************************
+// Glow Shader
+//*****************************************************************************
+uniform vec4 kernel;
+uniform sampler2D diffuseMap;
+
+in vec2 texc0, texc1, texc2, texc3;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = texture(diffuseMap, texc0) * kernel.x;
+ OUT_col += texture(diffuseMap, texc1) * kernel.y;
+ OUT_col += texture(diffuseMap, texc2) * kernel.z;
+ OUT_col += texture(diffuseMap, texc3) * kernel.w;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/blurV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/blurV.glsl
new file mode 100644
index 000000000..1bfb0cd1b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/blurV.glsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//*****************************************************************************
+// Glow shader
+//*****************************************************************************
+
+in vec4 vPosition;
+in vec4 vColor;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+uniform vec2 offset0, offset1, offset2, offset3;
+
+out vec2 texc0, texc1, texc2, texc3;
+
+void main()
+{
+ gl_Position = modelview * vPosition;
+
+ vec2 tc = vTexCoord0.st;
+ tc.y = 1.0 - tc.y;
+
+ texc0 = tc + offset0;
+ texc1 = tc + offset1;
+ texc2 = tc + offset2;
+ texc3 = tc + offset3;
+ gl_Position.y *= -1;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerP.glsl
new file mode 100644
index 000000000..877a132da
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerP.glsl
@@ -0,0 +1,147 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+#include "torque.glsl"
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+//ConnectData
+in vec4 texCoord12;
+#define IN_texCoord12 texCoord12
+in vec4 texCoord34;
+#define IN_texCoord34 texCoord34
+in vec3 vLightTS; // light vector in tangent space, denormalized
+#define IN_vLightTS vLightTS
+in vec3 vViewTS; // view vector in tangent space, denormalized
+#define IN_vViewTS vViewTS
+in float worldDist;
+#define IN_worldDist worldDist
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform sampler2D normalHeightMap;
+uniform vec3 ambientColor;
+uniform vec3 sunColor;
+uniform float cloudCoverage;
+uniform vec3 cloudBaseColor;
+uniform float cloudExposure;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Globals
+//-----------------------------------------------------------------------------
+// The per-color weighting to be used for luminance calculations in RGB order.
+const vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.7154f, 0.0721f);
+
+
+//-----------------------------------------------------------------------------
+// Functions
+//-----------------------------------------------------------------------------
+
+// Calculates the Rayleigh phase function
+float getRayleighPhase( float angle )
+{
+ return 0.75 * ( 1.0 + pow( angle, 2.0 ) );
+}
+
+// Returns the output rgb color given a texCoord and parameters it uses
+// for lighting calculation.
+vec3 ComputeIllumination( vec2 texCoord,
+ vec3 vLightTS,
+ vec3 vViewTS,
+ vec3 vNormalTS )
+{
+ //return noiseNormal;
+ //return vNormalTS;
+
+ vec3 vLightTSAdj = vec3( -vLightTS.x, -vLightTS.y, vLightTS.z );
+
+ float dp = dot( vNormalTS, vLightTSAdj );
+
+ // Calculate the amount of illumination (lightTerm)...
+
+ // We do both a rim lighting effect and a halfLambertian lighting effect
+ // and combine the result.
+ float halfLambertTerm = clamp( pow( dp * 0.5 + 0.5, 1.0 ), 0.0, 1.0 );
+ float rimLightTerm = pow( ( 1.0 - dp ), 1.0 );
+ float lightTerm = clamp( halfLambertTerm * 1.0 + rimLightTerm * dp, 0.0, 1.0 );
+ lightTerm *= 0.5;
+
+ // Use a simple RayleighPhase function to simulate single scattering towards
+ // the camera.
+ float angle = dot( vLightTS, vViewTS );
+ lightTerm *= getRayleighPhase( angle );
+
+ // Combine terms and colors into the output color.
+ //vec3 lightColor = ( lightTerm * sunColor * fOcclusionShadow ) + ambientColor;
+ vec3 lightColor = mix( ambientColor, sunColor, lightTerm );
+ //lightColor = mix( lightColor, ambientColor, cloudCoverage );
+ vec3 finalColor = cloudBaseColor * lightColor;
+
+ return finalColor;
+}
+
+void main()
+{
+ // Normalize the interpolated vectors:
+ vec3 vViewTS = normalize( vViewTS );
+ vec3 vLightTS = normalize( vLightTS );
+
+ vec4 cResultColor = vec4( 0, 0, 0, 1 );
+
+ vec2 texSample = IN_texCoord12.xy;
+
+ vec4 noise1 = texture( normalHeightMap, IN_texCoord12.zw );
+ noise1 = normalize( ( noise1 - 0.5 ) * 2.0 );
+ //return noise1;
+
+ vec4 noise2 = texture( normalHeightMap, IN_texCoord34.xy );
+ noise2 = normalize( ( noise2 - 0.5 ) * 2.0 );
+ //return noise2;
+
+ vec3 noiseNormal = normalize( noise1 + noise2 ).xyz;
+ //return vec4( noiseNormal, 1.0 );
+
+ float noiseHeight = noise1.a * noise2.a * ( cloudCoverage / 2.0 + 0.5 );
+
+ vec3 vNormalTS = normalize( texture( normalHeightMap, texSample ).xyz * 2.0 - 1.0 );
+ vNormalTS += noiseNormal;
+ vNormalTS = normalize( vNormalTS );
+
+ // Compute resulting color for the pixel:
+ cResultColor.rgb = ComputeIllumination( texSample, vLightTS, vViewTS, vNormalTS );
+
+ float coverage = ( cloudCoverage - 0.5 ) * 2.0;
+ cResultColor.a = texture( normalHeightMap, texSample ).a + coverage + noiseHeight;
+
+ if ( cloudCoverage > -1.0 )
+ cResultColor.a /= 1.0 + coverage;
+
+ cResultColor.a = clamp( cResultColor.a * pow( saturate(cloudCoverage), 0.25 ), 0.0, 1.0 );
+
+ cResultColor.a = mix( cResultColor.a, 0.0, 1.0 - pow(IN_worldDist,2.0) );
+
+ OUT_col = hdrEncode(cResultColor);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl
new file mode 100644
index 000000000..395c6f286
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/cloudLayerV.glsl
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec3 vNormal;
+in vec3 vBinormal;
+in vec3 vTangent;
+in vec2 vTexCoord0;
+
+out vec4 texCoord12;
+#define OUT_texCoord12 texCoord12
+out vec4 texCoord34;
+#define OUT_texCoord34 texCoord34
+out vec3 vLightTS; // light vector in tangent space, denormalized
+#define OUT_vLightTS vLightTS
+out vec3 vViewTS; // view vector in tangent space, denormalized
+#define OUT_vViewTS vViewTS
+out float worldDist;
+#define OUT_worldDist worldDist
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform mat4 modelview;
+uniform vec3 eyePosWorld;
+uniform vec3 sunVec;
+uniform vec2 texOffset0;
+uniform vec2 texOffset1;
+uniform vec2 texOffset2;
+uniform vec3 texScale;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec4 IN_pos = vPosition;
+ vec3 IN_normal = vNormal;
+ vec3 IN_binormal = vBinormal;
+ vec3 IN_tangent = vTangent;
+ vec2 IN_uv0 = vTexCoord0.st;
+
+ gl_Position = modelview * IN_pos;
+
+ // Offset the uv so we don't have a seam directly over our head.
+ vec2 uv = IN_uv0 + vec2( 0.5, 0.5 );
+
+ OUT_texCoord12.xy = uv * texScale.x;
+ OUT_texCoord12.xy += texOffset0;
+
+ OUT_texCoord12.zw = uv * texScale.y;
+ OUT_texCoord12.zw += texOffset1;
+
+ OUT_texCoord34.xy = uv * texScale.z;
+ OUT_texCoord34.xy += texOffset2;
+
+ OUT_texCoord34.z = IN_pos.z;
+ OUT_texCoord34.w = 0.0;
+
+ // Transform the normal, tangent and binormal vectors from object space to
+ // homogeneous projection space:
+ vec3 vNormalWS = -IN_normal;
+ vec3 vTangentWS = -IN_tangent;
+ vec3 vBinormalWS = -IN_binormal;
+
+ // Compute position in world space:
+ vec4 vPositionWS = IN_pos + vec4( eyePosWorld, 1 ); //tMul( IN_pos, objTrans );
+
+ // Compute and output the world view vector (unnormalized):
+ vec3 vViewWS = eyePosWorld - vPositionWS.xyz;
+
+ // Compute denormalized light vector in world space:
+ vec3 vLightWS = -sunVec;
+
+ // Normalize the light and view vectors and transform it to the IN_tangent space:
+ mat3 mWorldToTangent = mat3( vTangentWS, vBinormalWS, vNormalWS );
+
+ // Propagate the view and the light vectors (in tangent space):
+ OUT_vLightTS = vLightWS * mWorldToTangent;
+ OUT_vViewTS = mWorldToTangent * vViewWS;
+
+ OUT_worldDist = clamp( pow( max( IN_pos.z, 0 ), 2 ), 0.0, 1.0 );
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/foliage.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/foliage.glsl
new file mode 100644
index 000000000..38b66e767
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/foliage.glsl
@@ -0,0 +1,186 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// CornerId corresponds to this arrangement
+// from the perspective of the camera.
+//
+// 3 ---- 2
+// | |
+// 0 ---- 1
+//
+
+#define MAX_COVERTYPES 8
+
+uniform vec3 gc_camRight;
+uniform vec3 gc_camUp;
+uniform vec4 gc_typeRects[MAX_COVERTYPES];
+uniform vec2 gc_fadeParams;
+uniform vec2 gc_windDir;
+
+// .x = gust length
+// .y = premultiplied simulation time and gust frequency
+// .z = gust strength
+uniform vec3 gc_gustInfo;
+
+// .x = premultiplied simulation time and turbulance frequency
+// .y = turbulance strength
+uniform vec2 gc_turbInfo;
+
+
+const float sCornerRight[4] = float[]( -0.5, 0.5, 0.5, -0.5 );
+
+const float sCornerUp[4] = float[]( 0, 0, 1, 1 );
+
+const float sMovableCorner[4] = float[]( 0, 0, 1, 1 );
+
+const vec2 sUVCornerExtent[4] = vec2[]
+(
+ vec2( 0, 1 ),
+ vec2( 1, 1 ),
+ vec2( 1, 0 ),
+ vec2( 0, 0 )
+);
+
+
+///////////////////////////////////////////////////////////////////////////////
+// The following wind effect was derived from the GPU Gems 3 chapter...
+//
+// "Vegetation Procedural Animation and Shading in Crysis"
+// by Tiago Sousa, Crytek
+//
+
+vec2 smoothCurve( vec2 x )
+{
+ return x * x * ( 3.0 - 2.0 * x );
+}
+
+vec2 triangleWave( vec2 x )
+{
+ return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
+}
+
+vec2 smoothTriangleWave( vec2 x )
+{
+ return smoothCurve( triangleWave( x ) );
+}
+
+float windTurbulence( float bbPhase, float frequency, float strength )
+{
+ // We create the input value for wave generation from the frequency and phase.
+ vec2 waveIn = vec2( bbPhase + frequency );
+
+ // We use two square waves to generate the effect which
+ // is then scaled by the overall strength.
+ vec2 waves = ( fract( waveIn.xy * vec2( 1.975, 0.793 ) ) * 2.0 - 1.0 );
+ waves = smoothTriangleWave( waves );
+
+ // Sum up the two waves into a single wave.
+ return ( waves.x + waves.y ) * strength;
+}
+
+vec2 windEffect( float bbPhase,
+ vec2 windDirection,
+ float gustLength,
+ float gustFrequency,
+ float gustStrength,
+ float turbFrequency,
+ float turbStrength )
+{
+ // Calculate the ambient wind turbulence.
+ float turbulence = windTurbulence( bbPhase, turbFrequency, turbStrength );
+
+ // We simulate the overall gust via a sine wave.
+ float gustPhase = clamp( sin( ( bbPhase - gustFrequency ) / gustLength ) , 0.0, 1.0 );
+ float gustOffset = ( gustPhase * gustStrength ) + ( ( 0.2 + gustPhase ) * turbulence );
+
+ // Return the final directional wind effect.
+ return vec2(gustOffset) * windDirection.xy;
+}
+
+void foliageProcessVert( inout vec3 position,
+ inout vec4 diffuse,
+ inout vec4 texCoord,
+ inout vec3 normal,
+ inout vec3 T,
+ in vec3 eyePos )
+{
+ // Assign the normal and tagent values.
+ //normal = vec3( 0, 0, 1 );//cross( gc_camUp, gc_camRight );
+ T = gc_camRight;
+
+ // Pull out local vars we need for work.
+ int corner = int( ( diffuse.a * 255.0 ) + 0.5 );
+ vec2 size = texCoord.xy;
+ int type = int( texCoord.z );
+
+ // The billboarding is based on the camera direction.
+ vec3 rightVec = gc_camRight * sCornerRight[corner];
+ vec3 upVec = gc_camUp * sCornerUp[corner];
+
+ // Figure out the corner position.
+ vec3 outPos = ( upVec * size.y ) + ( rightVec * size.x );
+ float len = length( outPos.xyz );
+
+ // We derive the billboard phase used for wind calculations from its position.
+ float bbPhase = dot( position.xyz, vec3( 1.0 ) );
+
+ // Get the overall wind gust and turbulence effects.
+ vec3 wind;
+ wind.xy = windEffect( bbPhase,
+ gc_windDir,
+ gc_gustInfo.x, gc_gustInfo.y, gc_gustInfo.z,
+ gc_turbInfo.x, gc_turbInfo.y );
+ wind.z = 0.0;
+
+ // Add the summed wind effect into the point.
+ outPos.xyz += wind.xyz * texCoord.w;
+
+ // Do a simple spherical clamp to keep the foliage
+ // from stretching too much by wind effect.
+ outPos.xyz = normalize( outPos.xyz ) * len;
+
+ // Move the point into world space.
+ position += outPos;
+
+ // Grab the uv set and setup the texture coord.
+ vec4 uvSet = gc_typeRects[type];
+ texCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
+ texCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
+
+ // Animate the normal to get lighting changes
+ // across the the wind swept foliage.
+ //
+ // TODO: Expose the 10x as a factor to control
+ // how much the wind effects the lighting on the grass.
+ //
+ normal.xy += wind.xy * ( 10.0 * texCoord.w );
+ normal = normalize( normal );
+
+ // Get the alpha fade value.
+
+ float fadeStart = gc_fadeParams.x;
+ float fadeEnd = gc_fadeParams.y;
+ float fadeRange = fadeEnd - fadeStart;
+
+ float dist = distance( eyePos, position.xyz ) - fadeStart;
+ diffuse.a = 1.0 - clamp( dist / fadeRange, 0.0, 1.0 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorP.glsl
new file mode 100644
index 000000000..b4d591486
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorP.glsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+uniform sampler2D diffuseMap, alphaMap;
+uniform vec4 groundAlpha;
+
+in vec4 color, groundAlphaCoeff;
+in vec2 outTexCoord, alphaLookup;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec4 alpha = texture(alphaMap, alphaLookup);
+ OUT_col = color * texture(diffuseMap, outTexCoord);
+ OUT_col.a = OUT_col.a * min(alpha, groundAlpha + groundAlphaCoeff.x).x;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorV.glsl
new file mode 100644
index 000000000..c8dcf1ddb
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/fxFoliageReplicatorV.glsl
@@ -0,0 +1,99 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+in vec4 vPosition;
+in vec3 vNormal;
+in vec4 vColor;
+in vec2 vTexCoord0;
+in vec2 vTexCoord1;
+in vec2 vTexCoord2;
+
+uniform mat4 projection, world;
+uniform vec3 CameraPos;
+uniform float GlobalSwayPhase, SwayMagnitudeSide, SwayMagnitudeFront,
+ GlobalLightPhase, LuminanceMagnitude, LuminanceMidpoint, DistanceRange;
+
+out vec4 color, groundAlphaCoeff;
+out vec2 outTexCoord, alphaLookup;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ // Init a transform matrix to be used in the following steps
+ mat4 trans = mat4(0.0);
+ trans[0][0] = 1.0;
+ trans[1][1] = 1.0;
+ trans[2][2] = 1.0;
+ trans[3][3] = 1.0;
+ trans[3][0] = vPosition.x;
+ trans[3][1] = vPosition.y;
+ trans[3][2] = vPosition.z;
+
+ // Billboard transform * world matrix
+ mat4 o = world;
+ o = o * trans;
+
+ // Keep only the up axis result and position transform.
+ // This gives us "cheating" cylindrical billboarding.
+ o[0][0] = 1.0;
+ o[0][1] = 0.0;
+ o[0][2] = 0.0;
+ o[0][3] = 0.0;
+ o[1][0] = 0.0;
+ o[1][1] = 1.0;
+ o[1][2] = 0.0;
+ o[1][3] = 0.0;
+
+ // Handle sway. Sway is stored in a texture coord. The x coordinate is the sway phase multiplier,
+ // the y coordinate determines if this vertex actually sways or not.
+ float xSway, ySway;
+ float wavePhase = GlobalSwayPhase * vTexCoord1.x;
+ ySway = sin(wavePhase);
+ xSway = cos(wavePhase);
+ xSway = xSway * vTexCoord1.y * SwayMagnitudeSide;
+ ySway = ySway * vTexCoord1.y * SwayMagnitudeFront;
+ vec4 p;
+ p = o * vec4(vNormal.x + xSway, ySway, vNormal.z, 1.0);
+
+ // Project the point
+ gl_Position = projection * p;
+
+ // Lighting
+ float Luminance = LuminanceMidpoint + LuminanceMagnitude * cos(GlobalLightPhase + vNormal.y);
+
+ // Alpha
+ vec3 worldPos = vec3(vPosition.x, vPosition.y, vPosition.z);
+ float alpha = abs(distance(worldPos, CameraPos)) / DistanceRange;
+ alpha = clamp(alpha, 0.0, 1.0); //pass it through
+
+ alphaLookup = vec2(alpha, 0.0);
+ bool alphaCoeff = bool(vNormal.z);
+ groundAlphaCoeff = vec4(float(alphaCoeff));
+ outTexCoord = vTexCoord0.st;
+ color = vec4(Luminance, Luminance, Luminance, 1.0);
+ gl_Position.y *= -1;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/guiMaterialV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/guiMaterialV.glsl
new file mode 100644
index 000000000..de3845ee7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/guiMaterialV.glsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4x4 modelview;
+
+out vec4 hpos;
+out vec2 uv0;
+
+
+void main()
+{
+ hpos = vec4( modelview * vPosition );
+ gl_Position = hpos;
+
+ uv0 = vTexCoord0.st;
+ gl_Position.y *= -1;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/hlslCompat.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/hlslCompat.glsl
new file mode 100644
index 000000000..b9a6e76d7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/hlslCompat.glsl
@@ -0,0 +1,101 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// These are some simple wrappers for simple
+// HLSL compatibility.
+
+#define float4 vec4
+#define float3 vec3
+#define float2 vec2
+
+#define half float
+#define half2 vec2
+#define half3 vec3
+#define half4 vec4
+
+#define float4x4 mat4
+#define float3x3 mat3
+#define float2x2 mat2
+
+#define texCUBE texture
+#define tex2D texture
+#define tex1D texture
+#define tex2Dproj textureProj
+#define tex2Dlod( sampler, texCoord ) textureLod(sampler, texCoord.xy, texCoord.w)
+
+#define samplerCUBE samplerCube
+
+#define frac fract
+
+#define lerp mix
+
+void tSetMatrixRow(inout float3x3 m, int row, float3 value)
+{
+ m[0][row] = value.x;
+ m[1][row] = value.y;
+ m[2][row] = value.z;
+}
+
+void tSetMatrixRow(inout float4x4 m, int row, float4 value)
+{
+ m[0][row] = value.x;
+ m[1][row] = value.y;
+ m[2][row] = value.z;
+ m[3][row] = value.w;
+}
+
+#define tGetMatrix3Row(matrix, row) float3(matrix[0][row], matrix[1][row], matrix[2][row])
+#define tGetMatrix4Row(matrix, row) float4(matrix[0][row], matrix[1][row], matrix[2][row], matrix[3][row])
+
+float3x3 float4x4to3x3(float4x4 m)
+{
+ return float3x3( vec3(m[0]).xyz, m[1].xyz, m[2].xyz);
+}
+
+float3x3 float4x4to3x3_(float4x4 m)
+{
+ return float3x3( vec3(m[0]), m[1].xyz, m[2].xyz);
+}
+
+mat4 mat4FromRow( float r0c0, float r0c1, float r0c2, float r0c3,
+ float r1c0, float r1c1, float r1c2, float r1c3,
+ float r2c0, float r2c1, float r2c2, float r2c3,
+ float r3c0, float r3c1, float r3c2, float r3c3 )
+{
+ return mat4( r0c0, r1c0, r2c0, r3c0,
+ r0c1, r1c1, r2c1, r3c1,
+ r0c2, r1c2, r2c2, r3c2,
+ r0c3, r1c3, r2c3, r3c3 );
+}
+
+
+#define saturate( val ) clamp( val, 0.0, 1.0 )
+
+#define round( n ) (sign( n ) * floor( abs( n ) + 0.5 ))
+
+#define tMul(a, b) (a*b)
+
+#define correctSSP(vec) vec.y *= -1
+
+#ifdef TORQUE_PIXEL_SHADER
+ void clip(float a) { if(a < 0) discard;}
+#endif
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/imposter.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/imposter.glsl
new file mode 100644
index 000000000..20bc62688
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/imposter.glsl
@@ -0,0 +1,161 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+
+#define IMPOSTER_MAX_UVS 64
+
+
+void imposter_v(
+ // These parameters usually come from the vertex.
+ vec3 center,
+ int corner,
+ float halfSize,
+ vec3 imposterUp,
+ vec3 imposterRight,
+
+ // These are from the imposter shader constant.
+ int numEquatorSteps,
+ int numPolarSteps,
+ float polarAngle,
+ bool includePoles,
+
+ // Other shader constants.
+ vec3 camPos,
+ vec4 uvs[IMPOSTER_MAX_UVS],
+
+ // The outputs of this function.
+ out vec3 outWsPosition,
+ out vec2 outTexCoord,
+ out mat3 outWorldToTangent
+ )
+{
+
+ float M_HALFPI_F = 1.57079632679489661923;
+ float M_PI_F = 3.14159265358979323846;
+ float M_2PI_F = 6.28318530717958647692;
+
+
+ float sCornerRight[4];// = float[]( -1.0, 1.0, 1.0, -1.0 );
+ sCornerRight[0] = -1.0;
+ sCornerRight[1] = 1.0;
+ sCornerRight[2] = 1.0;
+ sCornerRight[3] = -1.0;
+ float sCornerUp[4];// = float[]( -1.0, -1.0, 1.0, 1.0 );
+ sCornerUp[0] = -1.0;
+ sCornerUp[1] = -1.0;
+ sCornerUp[2] = 1.0;
+ sCornerUp[3] = 1.0;
+ vec2 sUVCornerExtent[4];// = vec2[](vec2( 0.0, 1.0 ), vec2( 1.0, 1.0 ), vec2( 1.0, 0.0 ), vec2( 0.0, 0.0 ));
+ sUVCornerExtent[0] = vec2( 0.0, 1.0 );
+ sUVCornerExtent[1] = vec2( 1.0, 1.0 );
+ sUVCornerExtent[2] = vec2( 1.0, 0.0 );
+ sUVCornerExtent[3] = vec2( 0.0, 0.0 );
+
+ // TODO: This could all be calculated on the CPU.
+ float equatorStepSize = M_2PI_F / float( numEquatorSteps );
+ float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001;
+ float polarStepSize = M_PI_F / float( numPolarSteps );
+ float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001;
+
+ // The vector between the camera and the billboard.
+ vec3 lookVec = normalize( camPos - center );
+
+ // Generate the camera up and right vectors from
+ // the object transform and camera forward.
+ vec3 camUp = imposterUp;
+ vec3 camRight = cross( -lookVec, camUp );
+
+ // The billboarding is based on the camera directions.
+ vec3 rightVec = camRight * sCornerRight[corner];
+ vec3 upVec = camUp * sCornerUp[corner];
+
+ float lookPitch = acos( dot( imposterUp, lookVec ) );
+
+ // First check to see if we need to render the top billboard.
+ int index;
+ /*
+ if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) )
+ {
+ index = numEquatorSteps * 3;
+
+ // When we render the top/bottom billboard we always use
+ // a fixed vector that matches the rotation of the object.
+ rightVec = vec3( 1, 0, 0 ) * sCornerRight[corner];
+ upVec = vec3( 0, 1, 0 ) * sCornerUp[corner];
+
+ if ( lookPitch > sPi - polarAngle )
+ {
+ upVec = -upVec;
+ index++;
+ }
+ }
+ else
+ */
+ {
+ // Calculate the rotation around the z axis then add the
+ // equator half step. This gets the images to switch a
+ // half step before the captured angle is met.
+ float lookAzimuth = atan( lookVec.y, lookVec.x );
+ float azimuth = atan( imposterRight.y, imposterRight.x );
+ float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep;
+
+ // The y rotation is calculated from the look vector and
+ // the object up vector.
+ float rotY = lookPitch - polarHalfStep;
+
+ // TODO: How can we do this without conditionals?
+ // Normalize the result to 0 to 2PI.
+ if ( rotZ < 0.0 )
+ rotZ += M_2PI_F;
+ if ( rotZ > M_2PI_F )
+ rotZ -= M_2PI_F;
+ if ( rotY < 0.0 )
+ rotY += M_2PI_F;
+ if ( rotY > M_PI_F ) // Not M_2PI_F?
+ rotY -= M_2PI_F;
+
+ float polarIdx = round( abs( rotY ) / polarStepSize );
+
+ // Get the index to the start of the right polar
+ // images for this viewing angle.
+ int numPolarOffset = int( float( numEquatorSteps ) * polarIdx );
+
+ // Calculate the final image index for lookup
+ // of the texture coords.
+ index = int( rotZ / equatorStepSize ) + numPolarOffset;
+ }
+
+ // Generate the final world space position.
+ outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize );
+
+ // Grab the uv set and setup the texture coord.
+ vec4 uvSet = uvs[index];
+ outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
+ outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
+
+ // Needed for normal mapping and lighting.
+ outWorldToTangent[0] = vec3( 1, 0, 0 );
+ outWorldToTangent[1] = vec3( 0, 1, 0 );
+ outWorldToTangent[2] = vec3( 0, 0, -1 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl
new file mode 100644
index 000000000..804ab1e3b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/lighting.glsl
@@ -0,0 +1,249 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+#ifndef TORQUE_SHADERGEN
+
+// These are the uniforms used by most lighting shaders.
+
+uniform vec4 inLightPos[3];
+uniform vec4 inLightInvRadiusSq;
+uniform vec4 inLightColor[4];
+
+#ifndef TORQUE_BL_NOSPOTLIGHT
+ uniform vec4 inLightSpotDir[3];
+ uniform vec4 inLightSpotAngle;
+ uniform vec4 inLightSpotFalloff;
+#endif
+
+uniform vec4 ambient;
+#define ambientCameraFactor 0.3
+uniform float specularPower;
+uniform vec4 specularColor;
+
+#endif // !TORQUE_SHADERGEN
+
+
+void compute4Lights( vec3 wsView,
+ vec3 wsPosition,
+ vec3 wsNormal,
+ vec4 shadowMask,
+
+ #ifdef TORQUE_SHADERGEN
+
+ vec4 inLightPos[3],
+ vec4 inLightInvRadiusSq,
+ vec4 inLightColor[4],
+ vec4 inLightSpotDir[3],
+ vec4 inLightSpotAngle,
+ vec4 inLightSpotFalloff,
+ float specularPower,
+ vec4 specularColor,
+
+ #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;
+}
+
+
+// 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 )
+{
+ // (R.V)^c
+ float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye );
+
+ // Return the specular factor.
+ return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
+}
+
+/// 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)
+{
+ vec3 specularColor = vec3(specular);
+ bool metalness = getFlag(matInfo.r, 3);
+ if ( metalness )
+ {
+ specularColor = 0.04 * (1 - specular) + diffuseColor * specular;
+ }
+
+ //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);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeP.glsl
new file mode 100644
index 000000000..e33c9bd97
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeP.glsl
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "hlslCompat.glsl"
+
+in vec4 offscreenPos;
+in vec4 backbufferPos;
+
+#define IN_offscreenPos offscreenPos
+#define IN_backbufferPos backbufferPos
+
+uniform sampler2D colorSource;
+uniform vec4 offscreenTargetParams;
+
+#ifdef TORQUE_LINEAR_DEPTH
+#define REJECT_EDGES
+uniform sampler2D edgeSource;
+uniform vec4 edgeTargetParams;
+#endif
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Off-screen particle source screenspace position in XY
+ // Back-buffer screenspace position in ZW
+ vec4 ssPos = vec4(offscreenPos.xy / offscreenPos.w, backbufferPos.xy / backbufferPos.w);
+
+ vec4 uvScene = ( ssPos + 1.0 ) / 2.0;
+ uvScene.yw = 1.0 - uvScene.yw;
+ uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams);
+
+#ifdef REJECT_EDGES
+ // Cut out particles along the edges, this will create the stencil mask
+ uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams);
+ float edge = texture( edgeSource, uvScene.zw ).r;
+ clip( -edge );
+#endif
+
+ // Sample offscreen target and return
+ OUT_col = texture( colorSource, uvScene.xy );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeV.glsl
new file mode 100644
index 000000000..8c8f840d1
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/particleCompositeV.glsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+in vec2 vTexCoord0;
+#define uvCoord vTexCoord0
+
+out vec4 offscreenPos;
+out vec4 backbufferPos;
+
+#define OUT_hpos gl_Position
+#define OUT_offscreenPos offscreenPos
+#define OUT_backbufferPos backbufferPos
+
+uniform vec4 screenRect; // point, extent
+
+void main()
+{
+ OUT_hpos = vec4(uvCoord.xy, 1.0, 1.0);
+ OUT_hpos.xy *= screenRect.zw;
+ OUT_hpos.xy += screenRect.xy;
+
+ OUT_backbufferPos = OUT_hpos;
+ OUT_offscreenPos = OUT_hpos;
+
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/particlesP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/particlesP.glsl
new file mode 100644
index 000000000..cf35e5f1b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/particlesP.glsl
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "hlslCompat.glsl"
+
+// With advanced lighting we get soft particles.
+#ifdef TORQUE_LINEAR_DEPTH
+ #define SOFTPARTICLES
+#endif
+
+#ifdef SOFTPARTICLES
+
+ #include "shadergen:/autogenConditioners.h"
+
+ uniform float oneOverSoftness;
+ uniform float oneOverFar;
+ uniform sampler2D deferredTex;
+ //uniform vec3 vEye;
+ uniform vec4 deferredTargetParams;
+#endif
+
+#define CLIP_Z // TODO: Make this a proper macro
+
+in vec4 color;
+in vec2 uv0;
+in vec4 pos;
+
+#define IN_color color
+#define IN_uv0 uv0
+#define IN_pos pos
+
+uniform sampler2D diffuseMap;
+
+uniform sampler2D paraboloidLightMap;
+
+vec4 lmSample( vec3 nrm )
+{
+ bool calcBack = (nrm.z < 0.0);
+ if ( calcBack )
+ nrm.z = nrm.z * -1.0;
+
+ vec2 lmCoord;
+ lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5;
+ lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5);
+
+
+ // If this is the back, offset in the atlas
+ if ( calcBack )
+ lmCoord.x += 1.0;
+
+ // Atlasing front and back maps, so scale
+ lmCoord.x *= 0.5;
+
+ return texture(paraboloidLightMap, lmCoord);
+}
+
+
+uniform float alphaFactor;
+uniform float alphaScale;
+
+out vec4 OUT_col;
+
+void main()
+{
+ float softBlend = 1;
+
+ #ifdef SOFTPARTICLES
+ vec2 tc = IN_pos.xy * vec2(1.0, -1.0) / IN_pos.w;
+ tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), deferredTargetParams);
+
+ float sceneDepth = deferredUncondition( deferredTex, tc ).w;
+ float depth = IN_pos.w * oneOverFar;
+ float diff = sceneDepth - depth;
+ #ifdef CLIP_Z
+ // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer
+ // When drawing high-res, though, we want to be able to take advantage of hi-z
+ // so this is #ifdef'd out
+ //clip(diff);
+ #endif
+ softBlend = saturate( diff * oneOverSoftness );
+ #endif
+
+ vec4 diffuse = texture( diffuseMap, IN_uv0 );
+
+ //OUT_col = vec4( lmSample(vec3(0, 0, -1)).rgb, IN_color.a * diffuse.a * softBlend * alphaScale);
+
+ // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha)
+ vec3 colorScale = ( alphaFactor < 0.0 ? IN_color.rgb * diffuse.rgb : vec3( alphaFactor > 0.0 ? IN_color.a * diffuse.a * alphaFactor * softBlend : softBlend ) );
+
+ OUT_col = hdrEncode( vec4( IN_color.rgb * diffuse.rgb * colorScale,
+ IN_color.a * diffuse.a * softBlend * alphaScale ) );
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/particlesV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/particlesV.glsl
new file mode 100644
index 000000000..3d75a6fb6
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/particlesV.glsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec4 vColor;
+in vec2 vTexCoord0;
+
+#define In_pos vPosition
+#define In_color vColor
+#define In_uv0 vTexCoord0
+
+out vec4 color;
+out vec2 uv0;
+out vec4 pos;
+
+#define OUT_hpos gl_Position
+#define OUT_color color
+#define OUT_uv0 uv0
+#define OUT_pos pos
+
+uniform mat4 modelViewProj;
+uniform mat4 fsModelViewProj;
+
+void main()
+{
+ OUT_hpos = tMul( modelViewProj, In_pos );
+ OUT_pos = tMul( fsModelViewProj, In_pos );
+ OUT_color = In_color;
+ OUT_uv0 = In_uv0;
+
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpP.glsl
new file mode 100644
index 000000000..db4250487
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpP.glsl
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+uniform sampler2D diffuseMap, refractMap, bumpMap;
+uniform vec4 shadeColor;
+
+in vec2 TEX0;
+in vec4 TEX1;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Fade edges of axis for texcoord passed in
+//-----------------------------------------------------------------------------
+float fadeAxis( float val )
+{
+ // Fades from 1.0 to 0.0 when less than 0.1
+ float fadeLow = clamp( val * 10.0, 0.0, 1.0 );
+
+ // Fades from 1.0 to 0.0 when greater than 0.9
+ float fadeHigh = 1.0 - clamp( (val - 0.9) * 10.0, 0.0, 1.0 );
+
+ return fadeLow * fadeHigh;
+}
+
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec3 bumpNorm = texture( bumpMap, TEX0 ).rgb * 2.0 - 1.0;
+ vec2 offset = vec2( bumpNorm.x, bumpNorm.y );
+ vec4 texIndex = TEX1;
+
+ // The fadeVal is used to "fade" the distortion at the edges of the screen.
+ // This is done so it won't sample the reflection texture out-of-bounds and create artifacts
+ // Note - this can be done more efficiently with a texture lookup
+ float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w );
+
+ const float distortion = 0.2;
+ texIndex.xy += offset * distortion * fadeVal;
+
+ vec4 diffuseColor = texture( diffuseMap, TEX0 );
+ vec4 reflectColor = textureProj( refractMap, texIndex );
+
+ OUT_col = diffuseColor + reflectColor * diffuseColor.a;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpV.glsl
new file mode 100644
index 000000000..90bcd27d8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectBumpV.glsl
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+
+out vec2 TEX0;
+out vec4 TEX1;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0,
+ 0.0, -0.5, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.5, 0.5, 0.0, 1.0);
+
+ gl_Position = modelview * vPosition;
+
+ TEX0 = vTexCoord0.st;
+
+ TEX1 = texGenTest * gl_Position;
+ TEX1.y = -TEX1.y;
+ gl_Position.y *= -1;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectP.glsl
new file mode 100644
index 000000000..384c16188
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectP.glsl
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+uniform sampler2D diffuseMap, refractMap;
+uniform vec4 shadeColor;
+
+in vec2 TEX0;
+in vec4 TEX1;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec4 diffuseColor = texture( diffuseMap, TEX0 );
+ vec4 reflectColor = textureProj( refractMap, TEX1 );
+
+ OUT_col = diffuseColor + reflectColor * diffuseColor.a;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectV.glsl
new file mode 100644
index 000000000..ba2484f66
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/planarReflectV.glsl
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+
+out vec2 TEX0;
+out vec4 TEX1;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ mat4 texGenTest = mat4(0.5, 0.0, 0.0, 0.0,
+ 0.0, -0.5, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.5, 0.5, 0.0, 1.0);
+
+ gl_Position = modelview * vPosition;
+
+ TEX0 = vTexCoord0;
+
+ TEX1 = texGenTest * gl_Position;
+ TEX1.y = -TEX1.y;
+
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/precipP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/precipP.glsl
new file mode 100644
index 000000000..102d0b0aa
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/precipP.glsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+uniform sampler2D diffuseMap;
+
+in vec4 color;
+in vec2 texCoord;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ OUT_col = texture(diffuseMap, texCoord) * color;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/precipV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/precipV.glsl
new file mode 100644
index 000000000..29f921630
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/precipV.glsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+uniform vec3 cameraPos, ambient;
+uniform vec2 fadeStartEnd;
+
+out vec4 color;
+out vec2 texCoord;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ gl_Position = modelview * vPosition;
+ texCoord = vTexCoord0.st;
+ color = vec4( ambient.r, ambient.g, ambient.b, 1.0 );
+
+ // Do we need to do a distance fade?
+ if ( fadeStartEnd.x < fadeStartEnd.y )
+ {
+
+ float distance = length( cameraPos - vPosition.xyz );
+ color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0.0, 1.0 ) - 1.0 );
+ }
+ gl_Position.y *= -1;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowP.glsl
new file mode 100644
index 000000000..9b0ff0d0b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowP.glsl
@@ -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.
+//-----------------------------------------------------------------------------
+
+in vec2 texCoord;
+in vec4 color;
+in float fade;
+
+out vec4 OUT_col;
+
+uniform sampler2D inputTex;
+uniform vec4 ambient;
+
+
+void main()
+{
+ float shadow = texture( inputTex, texCoord ).a * color.a;
+ OUT_col = ( ambient * shadow ) + ( 1 - shadow );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowV.glsl
new file mode 100644
index 000000000..c8b6d2a92
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/projectedShadowV.glsl
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec4 vColor;
+in vec2 vTexCoord0;
+in vec2 vTexCoord1;
+
+out vec2 texCoord;
+out vec4 color;
+out float fade;
+
+uniform mat4 modelview;
+uniform float shadowLength;
+uniform vec3 shadowCasterPosition;
+
+void main()
+{
+ gl_Position = modelview * vec4(vPosition.xyz, 1.0);
+
+ color = vColor;
+ texCoord = vTexCoord0.st;
+
+ float fromCasterDist = length(vPosition.xyz - shadowCasterPosition) - shadowLength;
+ fade = 1.0 - clamp( fromCasterDist / shadowLength , 0.0, 1.0 );
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyP.glsl
new file mode 100644
index 000000000..6d4e3ea75
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyP.glsl
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "hlslCompat.glsl"
+
+
+// Conn
+in vec4 rayleighColor;
+#define IN_rayleighColor rayleighColor
+in vec4 mieColor;
+#define IN_mieColor mieColor
+in vec3 v3Direction;
+#define IN_v3Direction v3Direction
+in vec3 pos;
+#define IN_pos pos
+
+uniform samplerCube nightSky ;
+uniform vec4 nightColor;
+uniform vec2 nightInterpAndExposure;
+uniform float useCubemap;
+uniform vec3 lightDir;
+uniform vec3 sunDir;
+
+out vec4 OUT_col;
+
+void main()
+{
+
+ float fCos = dot( lightDir, IN_v3Direction ) / length(IN_v3Direction);
+ float fCos2 = fCos*fCos;
+
+ float g = -0.991;
+ float g2 = -0.991 * -0.991;
+
+ float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
+
+ vec4 color = IN_rayleighColor + fMiePhase * IN_mieColor;
+ color.a = color.b;
+
+ vec4 nightSkyColor = texture(nightSky, -v3Direction);
+ nightSkyColor = mix(nightColor, nightSkyColor, useCubemap);
+
+ float fac = dot( normalize( pos ), sunDir );
+ fac = max( nightInterpAndExposure.y, pow( clamp( fac, 0.0, 1.0 ), 2 ) );
+ OUT_col = mix( color, nightSkyColor, nightInterpAndExposure.y );
+
+ OUT_col.a = 1;
+
+ OUT_col = clamp(OUT_col, 0.0, 1.0);
+
+ OUT_col = hdrEncode( OUT_col );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyV.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyV.glsl
new file mode 100644
index 000000000..5780d2df9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/scatterSkyV.glsl
@@ -0,0 +1,154 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslCompat.glsl"
+
+// The scale equation calculated by Vernier's Graphical Analysis
+float vernierScale(float fCos)
+{
+ float x = 1.0 - fCos;
+ float x5 = x * 5.25;
+ float x5p6 = (-6.80 + x5);
+ float xnew = (3.83 + x * x5p6);
+ float xfinal = (0.459 + x * xnew);
+ float xfinal2 = -0.00287 + x * xfinal;
+ float outx = exp( xfinal2 );
+ return 0.25 * outx;
+}
+
+in vec4 vPosition;
+
+// This is the shader input vertex structure.
+#define IN_position vPosition
+
+// This is the shader output data.
+out vec4 rayleighColor;
+#define OUT_rayleighColor rayleighColor
+out vec4 mieColor;
+#define OUT_mieColor mieColor
+out vec3 v3Direction;
+#define OUT_v3Direction v3Direction
+out vec3 pos;
+#define OUT_pos pos
+
+uniform mat4 modelView;
+uniform vec4 misc;
+uniform vec4 sphereRadii;
+uniform vec4 scatteringCoeffs;
+uniform vec3 camPos;
+uniform vec3 lightDir;
+uniform vec4 invWaveLength;
+uniform vec4 colorize;
+
+vec3 desaturate(const vec3 color, const float desaturation)
+{
+ const vec3 gray_conv = vec3 (0.30, 0.59, 0.11);
+ return mix(color, vec3(dot(gray_conv , color)), desaturation);
+}
+
+void main()
+{
+ // Pull some variables out:
+ float camHeight = misc.x;
+ float camHeightSqr = misc.y;
+
+ float scale = misc.z;
+ float scaleOverScaleDepth = misc.w;
+
+ float outerRadius = sphereRadii.x;
+ float outerRadiusSqr = sphereRadii.y;
+
+ float innerRadius = sphereRadii.z;
+ float innerRadiusSqr = sphereRadii.w;
+
+ float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun
+ float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI
+
+ float mieBrightness = scatteringCoeffs.z; // Km * ESun
+ float mie4PI = scatteringCoeffs.w; // Km * 4 * PI
+
+ // Get the ray from the camera to the vertex,
+ // and its length (which is the far point of the ray
+ // passing through the atmosphere).
+ vec3 v3Pos = vec3(IN_position / 6378000.0);// / outerRadius;
+ vec3 newCamPos = vec3( 0, 0, camHeight );
+ v3Pos.z += innerRadius;
+ vec3 v3Ray = v3Pos.xyz - newCamPos;
+ float fFar = length(v3Ray);
+ v3Ray /= fFar;
+
+ // Calculate the ray's starting position,
+ // then calculate its scattering offset.
+ vec3 v3Start = newCamPos;
+ float fHeight = length(v3Start);
+ float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
+ float fStartAngle = dot(v3Ray, v3Start) / fHeight;
+
+ float fStartOffset = fDepth * vernierScale( fStartAngle );
+
+ // Initialize the scattering loop variables.
+ float fSampleLength = fFar / 2.0;
+ float fScaledLength = fSampleLength * scale;
+ vec3 v3SampleRay = v3Ray * fSampleLength;
+ vec3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
+
+ // Now loop through the sample rays
+ vec3 v3FrontColor = vec3(0.0, 0.0, 0.0);
+ for(int i=0; i<2; i++)
+ {
+ float fHeight = length(v3SamplePoint);
+ float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight));
+ float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
+ float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
+
+ float vscale3 = vernierScale( fCameraAngle );
+ float vscale2 = vernierScale( fLightAngle );
+
+ float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
+ vec3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
+ v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
+ v3SamplePoint += v3SampleRay;
+ }
+
+ // Finally, scale the Mie and Rayleigh colors
+ // and set up the varying variables for the pixel shader.
+ gl_Position = modelView * IN_position;
+ OUT_mieColor.rgb = v3FrontColor * mieBrightness;
+ OUT_mieColor.a = 1.0;
+ OUT_rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
+ OUT_rayleighColor.a = 1.0;
+ OUT_v3Direction = newCamPos - v3Pos.xyz;
+ OUT_pos = IN_position.xyz;
+
+#ifdef USE_COLORIZE
+
+ OUT_rayleighColor.rgb = desaturate(OUT_rayleighColor.rgb, 1) * colorize.a;
+
+ OUT_rayleighColor.r *= colorize.r;
+ OUT_rayleighColor.g *= colorize.g;
+ OUT_rayleighColor.b *= colorize.b;
+
+#endif
+
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl
new file mode 100644
index 000000000..6e369bd5e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/torque.glsl
@@ -0,0 +1,339 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _TORQUE_GLSL_
+#define _TORQUE_GLSL_
+
+
+float M_HALFPI_F = 1.57079632679489661923;
+float M_PI_F = 3.14159265358979323846;
+float M_2PI_F = 6.28318530717958647692;
+
+/// Calculate fog based on a start and end positions in worldSpace.
+float computeSceneFog( vec3 startPos,
+ vec3 endPos,
+ float fogDensity,
+ float fogDensityOffset,
+ float fogHeightFalloff )
+{
+ float f = length( startPos - endPos ) - fogDensityOffset;
+ float h = 1.0 - ( endPos.z * fogHeightFalloff );
+ return exp( -fogDensity * f * h );
+}
+
+
+/// Calculate fog based on a start and end position and a height.
+/// Positions do not need to be in worldSpace but height does.
+float computeSceneFog( vec3 startPos,
+ vec3 endPos,
+ float height,
+ float fogDensity,
+ float fogDensityOffset,
+ float fogHeightFalloff )
+{
+ float f = length( startPos - endPos ) - fogDensityOffset;
+ float h = 1.0 - ( height * fogHeightFalloff );
+ return exp( -fogDensity * f * h );
+}
+
+
+/// Calculate fog based on a distance, height is not used.
+float computeSceneFog( float dist, float fogDensity, float fogDensityOffset )
+{
+ float f = dist - fogDensityOffset;
+ return exp( -fogDensity * f );
+}
+
+
+/// Convert a vec4 uv in viewport space to render target space.
+vec2 viewportCoordToRenderTarget( vec4 inCoord, vec4 rtParams )
+{
+ vec2 outCoord = inCoord.xy / inCoord.w;
+ outCoord = ( outCoord * rtParams.zw ) + rtParams.xy;
+ return outCoord;
+}
+
+
+/// Convert a vec2 uv in viewport space to render target space.
+vec2 viewportCoordToRenderTarget( vec2 inCoord, vec4 rtParams )
+{
+ vec2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy;
+ return outCoord;
+}
+
+
+/// Convert a vec4 quaternion into a 3x3 matrix.
+mat3x3 quatToMat( vec4 quat )
+{
+ float xs = quat.x * 2.0;
+ float ys = quat.y * 2.0;
+ float zs = quat.z * 2.0;
+
+ float wx = quat.w * xs;
+ float wy = quat.w * ys;
+ float wz = quat.w * zs;
+
+ float xx = quat.x * xs;
+ float xy = quat.x * ys;
+ float xz = quat.x * zs;
+
+ float yy = quat.y * ys;
+ float yz = quat.y * zs;
+ float zz = quat.z * zs;
+
+ mat3x3 mat;
+
+ mat[0][0] = 1.0 - (yy + zz);
+ mat[1][0] = xy - wz;
+ mat[2][0] = xz + wy;
+
+ mat[0][1] = xy + wz;
+ mat[1][1] = 1.0 - (xx + zz);
+ mat[2][1] = yz - wx;
+
+ mat[0][2] = xz - wy;
+ mat[1][2] = yz + wx;
+ mat[2][2] = 1.0 - (xx + yy);
+
+ return mat;
+}
+
+
+/// The number of additional substeps we take when refining
+/// the results of the offset parallax mapping function below.
+///
+/// You should turn down the number of steps if your needing
+/// more performance out of your parallax surfaces. Increasing
+/// the number doesn't yeild much better results and is rarely
+/// worth the additional cost.
+///
+#define PARALLAX_REFINE_STEPS 3
+
+/// Performs fast parallax offset mapping using
+/// multiple refinement steps.
+///
+/// @param texMap The texture map whos alpha channel we sample the parallax depth.
+/// @param texCoord The incoming texture coordinate for sampling the parallax depth.
+/// @param negViewTS The negative view vector in tangent space.
+/// @param depthScale The parallax factor used to scale the depth result.
+///
+vec2 parallaxOffset( sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale )
+{
+ float depth = texture( texMap, texCoord ).a/(PARALLAX_REFINE_STEPS*2);
+ vec2 offset = negViewTS.xy * vec2( depth * depthScale )/vec2(PARALLAX_REFINE_STEPS*2);
+
+ for ( int i=0; i < PARALLAX_REFINE_STEPS; i++ )
+ {
+ depth = ( depth + texture( texMap, texCoord + offset ).a )/(PARALLAX_REFINE_STEPS*2);
+ offset = negViewTS.xy * vec2( depth * depthScale )/vec2(PARALLAX_REFINE_STEPS*2);
+ }
+
+ return offset;
+}
+
+/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
+vec2 parallaxOffsetDxtnm(sampler2D texMap, vec2 texCoord, vec3 negViewTS, float depthScale)
+{
+ float depth = texture(texMap, texCoord).r/(PARALLAX_REFINE_STEPS*2);
+ vec2 offset = negViewTS.xy * vec2(depth * depthScale)/vec2(PARALLAX_REFINE_STEPS*2);
+
+ for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
+ {
+ depth = (depth + texture(texMap, texCoord + offset).r)/(PARALLAX_REFINE_STEPS*2);
+ offset = negViewTS.xy * vec2(depth * depthScale)/vec2(PARALLAX_REFINE_STEPS*2);
+ }
+
+ return offset;
+}
+
+
+/// The maximum value for 16bit per component integer HDR encoding.
+const float HDR_RGB16_MAX = 100.0;
+/// The maximum value for 10bit per component integer HDR encoding.
+const float HDR_RGB10_MAX = 4.0;
+
+/// Encodes an HDR color for storage into a target.
+vec3 hdrEncode( vec3 _sample )
+{
+ #if defined( TORQUE_HDR_RGB16 )
+
+ return _sample / HDR_RGB16_MAX;
+
+ #elif defined( TORQUE_HDR_RGB10 )
+
+ return _sample / HDR_RGB10_MAX;
+
+ #else
+
+ // No encoding.
+ return _sample;
+
+ #endif
+}
+
+/// Encodes an HDR color for storage into a target.
+vec4 hdrEncode( vec4 _sample )
+{
+ return vec4( hdrEncode( _sample.rgb ), _sample.a );
+}
+
+/// Decodes an HDR color from a target.
+vec3 hdrDecode( vec3 _sample )
+{
+ #if defined( TORQUE_HDR_RGB16 )
+
+ return _sample * HDR_RGB16_MAX;
+
+ #elif defined( TORQUE_HDR_RGB10 )
+
+ return _sample * HDR_RGB10_MAX;
+
+ #else
+
+ // No encoding.
+ return _sample;
+
+ #endif
+}
+
+/// Decodes an HDR color from a target.
+vec4 hdrDecode( vec4 _sample )
+{
+ return vec4( hdrDecode( _sample.rgb ), _sample.a );
+}
+
+/// Returns the luminance for an HDR pixel.
+float hdrLuminance( vec3 _sample )
+{
+ // There are quite a few different ways to
+ // calculate luminance from an rgb value.
+ //
+ // If you want to use a different technique
+ // then plug it in here.
+ //
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Max component luminance.
+ //
+ //float lum = max( _sample.r, max( _sample.g, _sample.b ) );
+
+ ////////////////////////////////////////////////////////////////////////////
+ // The perceptual relative luminance.
+ //
+ // See http://en.wikipedia.org/wiki/Luminance_(relative)
+ //
+ const vec3 RELATIVE_LUMINANCE = vec3( 0.2126, 0.7152, 0.0722 );
+ float lum = dot( _sample, RELATIVE_LUMINANCE );
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // The average component luminance.
+ //
+ //const vec3 AVERAGE_LUMINANCE = vec3( 0.3333, 0.3333, 0.3333 );
+ //float lum = dot( _sample, AVERAGE_LUMINANCE );
+
+ return lum;
+}
+
+#ifdef TORQUE_PIXEL_SHADER
+/// Called from the visibility feature to do screen
+/// door transparency for fading of objects.
+void fizzle(vec2 vpos, float visibility)
+{
+ // NOTE: The magic values below are what give us
+ // the nice even pattern during the fizzle.
+ //
+ // These values can be changed to get different
+ // patterns... some better than others.
+ //
+ // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 }
+ // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 }
+ //
+ // I'm sure there are many more patterns here to
+ // discover for different effects.
+
+ mat2x2 m = mat2x2( vpos.x, vpos.y, 0.916, 0.350 );
+ if( (visibility - fract( determinant( m ) )) < 0 ) //if(a < 0) discard;
+ discard;
+}
+#endif //TORQUE_PIXEL_SHADER
+
+/// Basic assert macro. If the condition fails, then the shader will output color.
+/// @param condition This should be a bvec[2-4]. If any items is false, condition is considered to fail.
+/// @param color The color that should be outputted if the condition fails.
+/// @note This macro will only work in the void main() method of a pixel shader.
+#define assert(condition, color) { if(!any(condition)) { OUT_col = color; return; } }
+
+// Deferred Shading: Material Info Flag Check
+bool getFlag(float flags, float num)
+{
+ float process = round(flags * 255);
+ float squareNum = pow(2.0, num);
+ return (mod(process, pow(2.0, squareNum)) >= squareNum);
+}
+
+// #define TORQUE_STOCK_GAMMA
+#ifdef TORQUE_STOCK_GAMMA
+// Sample in linear space. Decodes gamma.
+vec4 toLinear(vec4 tex)
+{
+ return tex;
+}
+// Encodes gamma.
+vec4 toGamma(vec4 tex)
+{
+ return tex;
+}
+vec3 toLinear(vec3 tex)
+{
+ return tex;
+}
+// Encodes gamma.
+vec3 toGamma(vec3 tex)
+{
+ return tex;
+}
+#else
+// Sample in linear space. Decodes gamma.
+vec4 toLinear(vec4 tex)
+{
+ return vec4(pow(abs(tex.rgb), vec3(2.2)), tex.a);
+}
+// Encodes gamma.
+vec4 toGamma(vec4 tex)
+{
+ return vec4(pow(abs(tex.rgb), vec3(1.0/2.2)), tex.a);
+}
+// Sample in linear space. Decodes gamma.
+vec3 toLinear(vec3 tex)
+{
+ return pow(abs(tex), vec3(2.2));
+}
+// Encodes gamma.
+vec3 toGamma(vec3 tex)
+{
+ return pow(abs(tex), vec3(1.0/2.2));
+}
+#endif //
+
+#endif // _TORQUE_GLSL_
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/wavesP.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/wavesP.glsl
new file mode 100644
index 000000000..06c8a1a28
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/wavesP.glsl
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+uniform sampler2D diffMap;
+uniform sampler2D bumpMap;
+uniform samplerCube cubeMap;
+uniform vec4 specularColor;
+uniform float specularPower;
+uniform vec4 ambient;
+uniform float accumTime;
+
+in vec2 TEX0;
+in vec4 outLightVec;
+in vec3 outPos;
+in vec3 outEyePos;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec2 texOffset;
+ float sinOffset1 = sin( accumTime * 1.5 + TEX0.y * 6.28319 * 3.0 ) * 0.03;
+ float sinOffset2 = sin( accumTime * 3.0 + TEX0.y * 6.28319 ) * 0.04;
+
+ texOffset.x = TEX0.x + sinOffset1 + sinOffset2;
+ texOffset.y = TEX0.y + cos( accumTime * 3.0 + TEX0.x * 6.28319 * 2.0 ) * 0.05;
+
+ vec4 bumpNorm = texture(bumpMap, texOffset) * 2.0 - 1.0;
+ vec4 diffuse = texture(diffMap, texOffset);
+
+ OUT_col = diffuse * (clamp(dot(outLightVec.xyz, bumpNorm.xyz), 0.0, 1.0) + ambient);
+
+ vec3 eyeVec = normalize(outEyePos - outPos);
+ vec3 halfAng = normalize(eyeVec + outLightVec.xyz);
+ float specular = clamp(dot(bumpNorm.xyz, halfAng), 0.0, 1.0) * outLightVec.w;
+ specular = pow(specular, specularPower);
+ OUT_col += specularColor * specular;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/gl/wind.glsl b/Templates/BaseGame/game/core/rendering/shaders/gl/wind.glsl
new file mode 100644
index 000000000..0ddb492b9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/gl/wind.glsl
@@ -0,0 +1,101 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//
+// A tip of the hat....
+//
+// The following wind effects were derived from the GPU Gems
+// 3 chapter "Vegetation Procedural Animation and Shading in Crysis"
+// by Tiago Sousa of Crytek.
+//
+
+vec4 smoothCurve( vec4 x )
+{
+ return x * x * ( 3.0 - 2.0 * x );
+}
+
+vec4 triangleWave( vec4 x )
+{
+ return abs( fract( x + 0.5 ) * 2.0 - 1.0 );
+}
+
+vec4 smoothTriangleWave( vec4 x )
+{
+ return smoothCurve( triangleWave( x ) );
+}
+
+vec3 windTrunkBending( vec3 vPos, vec2 vWind, float fBendFactor )
+{
+ // Smooth the bending factor and increase
+ // the near by height limit.
+ fBendFactor += 1.0;
+ fBendFactor *= fBendFactor;
+ fBendFactor = fBendFactor * fBendFactor - fBendFactor;
+
+ // Displace the vert.
+ vec3 vNewPos = vPos;
+ vNewPos.xy += vWind * fBendFactor;
+
+ // Limit the length which makes the bend more
+ // spherical and prevents stretching.
+ float fLength = length( vPos );
+ vPos = normalize( vNewPos ) * fLength;
+
+ return vPos;
+}
+
+vec3 windBranchBending( vec3 vPos,
+ vec3 vNormal,
+
+ float fTime,
+ float fWindSpeed,
+
+ float fBranchPhase,
+ float fBranchAmp,
+ float fBranchAtten,
+
+ float fDetailPhase,
+ float fDetailAmp,
+ float fDetailFreq,
+
+ float fEdgeAtten )
+{
+ float fVertPhase = dot( vPos, vec3( fDetailPhase + fBranchPhase ) );
+
+ vec2 vWavesIn = fTime + vec2( fVertPhase, fBranchPhase );
+
+ vec4 vWaves = ( fract( vWavesIn.xxyy *
+ vec4( 1.975, 0.793, 0.375, 0.193 ) ) *
+ 2.0 - 1.0 ) * fWindSpeed * fDetailFreq;
+
+ vWaves = smoothTriangleWave( vWaves );
+
+ vec2 vWavesSum = vWaves.xz + vWaves.yw;
+
+ // We want the branches to bend both up and down.
+ vWavesSum.y = 1.0 - ( vWavesSum.y * 2.0 );
+
+ vPos += vWavesSum.xxy * vec3( fEdgeAtten * fDetailAmp * vNormal.xy,
+ fBranchAtten * fBranchAmp );
+
+ return vPos;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/guiMaterialV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/guiMaterialV.hlsl
new file mode 100644
index 000000000..5d725338f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/guiMaterialV.hlsl
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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 "hlslStructs.hlsl"
+#include "shaderModel.hlsl"
+
+struct MaterialDecoratorConnectV
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+uniform float4x4 modelview : register(C0);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+MaterialDecoratorConnectV main( VertexIn_PCT IN )
+{
+ MaterialDecoratorConnectV OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.pos,1.0));
+ OUT.uv0 = IN.uv0;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.h b/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.h
new file mode 100644
index 000000000..6a57e4db7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.h
@@ -0,0 +1,116 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// The purpose of this file is to get all of our HLSL structures into one place.
+// Please use the structures here instead of redefining input and output structures
+// in each shader file. If structures are added, please adhere to the naming convention.
+
+//------------------------------------------------------------------------------
+// Vertex Input Structures
+//
+// These structures map to FVFs/Vertex Declarations in Torque. See gfxStructs.h
+//------------------------------------------------------------------------------
+
+// Notes
+//
+// Position should be specified as a float4. Right now our vertex structures in
+// the engine output float3s for position. This does NOT mean that the POSITION
+// binding should be float3, because it will assign 0 to the w coordinate, which
+// results in the vertex not getting translated when it is transformed.
+
+struct VertexIn_P
+{
+ float4 pos : POSITION;
+};
+
+struct VertexIn_PT
+{
+ float4 pos : POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PTTT
+{
+ float4 pos : POSITION;
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+};
+
+struct VertexIn_PC
+{
+ float4 pos : POSITION;
+ float4 color : DIFFUSE;
+};
+
+struct VertexIn_PNC
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+ float4 color : DIFFUSE;
+};
+
+struct VertexIn_PCT
+{
+ float4 pos : POSITION;
+ float4 color : DIFFUSE;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PN
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+};
+
+struct VertexIn_PNT
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNTT
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNCT
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+ float4 color : DIFFUSE;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNTTTB
+{
+ float4 pos : POSITION;
+ float3 normal : NORMAL;
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float3 T : TEXCOORD2;
+ float3 B : TEXCOORD3;
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.hlsl b/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.hlsl
new file mode 100644
index 000000000..ce0ca305c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/hlslStructs.hlsl
@@ -0,0 +1,114 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// The purpose of this file is to get all of our HLSL structures into one place.
+// Please use the structures here instead of redefining input and output structures
+// in each shader file. If structures are added, please adhere to the naming convention.
+
+//------------------------------------------------------------------------------
+// Vertex Input Structures
+//
+// These structures map to FVFs/Vertex Declarations in Torque. See gfxStructs.h
+//------------------------------------------------------------------------------
+
+// Notes
+//
+// Position should be specified as a float3 as our vertex structures in
+// the engine output float3s for position.
+
+struct VertexIn_P
+{
+ float3 pos : POSITION;
+};
+
+struct VertexIn_PT
+{
+ float3 pos : POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PTTT
+{
+ float3 pos : POSITION;
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+};
+
+struct VertexIn_PC
+{
+ float3 pos : POSITION;
+ float4 color : DIFFUSE;
+};
+
+struct VertexIn_PNC
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float4 color : DIFFUSE;
+};
+
+struct VertexIn_PCT
+{
+ float3 pos : POSITION;
+ float4 color : DIFFUSE;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PN
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+};
+
+struct VertexIn_PNT
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNTT
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float3 tangent : TANGENT;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNCT
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float4 color : DIFFUSE;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct VertexIn_PNTTTB
+{
+ float3 pos : POSITION;
+ float3 normal : NORMAL;
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float3 T : TEXCOORD2;
+ float3 B : TEXCOORD3;
+};
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/imposter.hlsl b/Templates/BaseGame/game/core/rendering/shaders/imposter.hlsl
new file mode 100644
index 000000000..bc700ba03
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/imposter.hlsl
@@ -0,0 +1,149 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+
+static float sCornerRight[4] = { -1, 1, 1, -1 };
+static float sCornerUp[4] = { -1, -1, 1, 1 };
+static float2 sUVCornerExtent[4] =
+{
+ float2( 0, 1 ),
+ float2( 1, 1 ),
+ float2( 1, 0 ),
+ float2( 0, 0 )
+};
+
+#define IMPOSTER_MAX_UVS 64
+
+
+void imposter_v(
+ // These parameters usually come from the vertex.
+ float3 center,
+ int corner,
+ float halfSize,
+ float3 imposterUp,
+ float3 imposterRight,
+
+ // These are from the imposter shader constant.
+ int numEquatorSteps,
+ int numPolarSteps,
+ float polarAngle,
+ bool includePoles,
+
+ // Other shader constants.
+ float3 camPos,
+ float4 uvs[IMPOSTER_MAX_UVS],
+
+ // The outputs of this function.
+ out float3 outWsPosition,
+ out float2 outTexCoord,
+ out float3x3 outWorldToTangent
+ )
+{
+ // TODO: This could all be calculated on the CPU.
+ float equatorStepSize = M_2PI_F / numEquatorSteps;
+ float equatorHalfStep = ( equatorStepSize / 2.0 ) - 0.0001;
+ float polarStepSize = M_PI_F / numPolarSteps;
+ float polarHalfStep = ( polarStepSize / 2.0 ) - 0.0001;
+
+ // The vector between the camera and the billboard.
+ float3 lookVec = normalize( camPos - center );
+
+ // Generate the camera up and right vectors from
+ // the object transform and camera forward.
+ float3 camUp = imposterUp;
+ float3 camRight = normalize( cross( -lookVec, camUp ) );
+
+ // The billboarding is based on the camera directions.
+ float3 rightVec = camRight * sCornerRight[corner];
+ float3 upVec = camUp * sCornerUp[corner];
+
+ float lookPitch = acos( dot( imposterUp, lookVec ) );
+
+ // First check to see if we need to render the top billboard.
+ int index;
+ /*
+ if ( includePoles && ( lookPitch < polarAngle || lookPitch > sPi - polarAngle ) )
+ {
+ index = numEquatorSteps * 3;
+
+ // When we render the top/bottom billboard we always use
+ // a fixed vector that matches the rotation of the object.
+ rightVec = float3( 1, 0, 0 ) * sCornerRight[corner];
+ upVec = float3( 0, 1, 0 ) * sCornerUp[corner];
+
+ if ( lookPitch > sPi - polarAngle )
+ {
+ upVec = -upVec;
+ index++;
+ }
+ }
+ else
+ */
+ {
+ // Calculate the rotation around the z axis then add the
+ // equator half step. This gets the images to switch a
+ // half step before the captured angle is met.
+ float lookAzimuth = atan2( lookVec.y, lookVec.x );
+ float azimuth = atan2( imposterRight.y, imposterRight.x );
+ float rotZ = ( lookAzimuth - azimuth ) + equatorHalfStep;
+
+ // The y rotation is calculated from the look vector and
+ // the object up vector.
+ float rotY = lookPitch - polarHalfStep;
+
+ // TODO: How can we do this without conditionals?
+ // Normalize the result to 0 to 2PI.
+ if ( rotZ < 0 )
+ rotZ += M_2PI_F;
+ if ( rotZ > M_2PI_F )
+ rotZ -= M_2PI_F;
+ if ( rotY < 0 )
+ rotY += M_2PI_F;
+ if ( rotY > M_PI_F ) // Not M_2PI_F?
+ rotY -= M_2PI_F;
+
+ float polarIdx = round( abs( rotY ) / polarStepSize );
+
+ // Get the index to the start of the right polar
+ // images for this viewing angle.
+ int numPolarOffset = numEquatorSteps * polarIdx;
+
+ // Calculate the final image index for lookup
+ // of the texture coords.
+ index = ( rotZ / equatorStepSize ) + numPolarOffset;
+ }
+
+ // Generate the final world space position.
+ outWsPosition = center + ( upVec * halfSize ) + ( rightVec * halfSize );
+
+ // Grab the uv set and setup the texture coord.
+ float4 uvSet = uvs[index];
+ outTexCoord.x = uvSet.x + ( uvSet.z * sUVCornerExtent[corner].x );
+ outTexCoord.y = uvSet.y + ( uvSet.w * sUVCornerExtent[corner].y );
+
+ // Needed for normal mapping and lighting.
+ outWorldToTangent[0] = float3( 1, 0, 0 );
+ outWorldToTangent[1] = float3( 0, 1, 0 );
+ outWorldToTangent[2] = float3( 0, 0, -1 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl
new file mode 100644
index 000000000..a41b8a873
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting.hlsl
@@ -0,0 +1,249 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+#ifndef TORQUE_SHADERGEN
+
+// These are the uniforms used by most lighting shaders.
+
+uniform float4 inLightPos[3];
+uniform float4 inLightInvRadiusSq;
+uniform float4 inLightColor[4];
+
+#ifndef TORQUE_BL_NOSPOTLIGHT
+ uniform float4 inLightSpotDir[3];
+ uniform float4 inLightSpotAngle;
+ uniform float4 inLightSpotFalloff;
+#endif
+
+uniform float4 ambient;
+#define ambientCameraFactor 0.3
+uniform float specularPower;
+uniform float4 specularColor;
+
+#endif // !TORQUE_SHADERGEN
+
+
+void compute4Lights( float3 wsView,
+ float3 wsPosition,
+ float3 wsNormal,
+ float4 shadowMask,
+
+ #ifdef TORQUE_SHADERGEN
+
+ float4 inLightPos[3],
+ float4 inLightInvRadiusSq,
+ float4 inLightColor[4],
+ float4 inLightSpotDir[3],
+ float4 inLightSpotAngle,
+ float4 inLightSpotFalloff,
+ float specularPower,
+ float4 specularColor,
+
+ #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;
+}
+
+
+// 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 )
+{
+ // (R.V)^c
+ float specVal = dot( normalize( -reflect( toLight, normal ) ), toEye );
+
+ // Return the specular factor.
+ return pow( max( specVal, 0.00001f ), AL_ConstantSpecularPower );
+}
+
+/// 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)
+{
+ float3 specularColor = float3(specular, specular, specular);
+ bool metalness = getFlag(matInfo.r, 3);
+ if ( metalness )
+ {
+ specularColor = 0.04 * (1 - specular) + diffuseColor * specular;
+ }
+
+ //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);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl
new file mode 100644
index 000000000..064fcffa6
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/convexGeometryV.hlsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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 "../../hlslStructs.hlsl"
+#include "../../shaderModel.hlsl"
+
+struct VertData
+{
+ float3 pos : POSITION;
+ float4 color : COLOR;
+};
+
+struct ConvexConnectV
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 wsEyeDir : TEXCOORD0;
+ float4 ssPos : TEXCOORD1;
+ float4 vsEyeDir : TEXCOORD2;
+};
+
+ConvexConnectV main( VertData IN,
+ uniform float4x4 modelview,
+ uniform float4x4 objTrans,
+ uniform float4x4 worldViewOnly,
+ uniform float3 eyePosWorld )
+{
+ 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/core/rendering/shaders/lighting/advanced/deferredClearGBufferP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredClearGBufferP.hlsl
new file mode 100644
index 000000000..5ae05896e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredClearGBufferP.hlsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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 Conn
+{
+ float4 hpos : TORQUE_POSITION;
+};
+
+struct Fragout
+{
+ float4 col : TORQUE_TARGET0;
+ float4 col1 : TORQUE_TARGET1;
+ float4 col2 : TORQUE_TARGET2;
+};
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main( Conn IN )
+{
+ Fragout OUT;
+
+ // Clear Deferred Buffer ( Normals/Depth );
+ OUT.col = float4(1.0, 1.0, 1.0, 1.0);
+
+ // Clear Color Buffer.
+ OUT.col1 = float4(0.0, 0.0, 0.0, 1.0);
+
+ // Clear Material Info Buffer.
+ OUT.col2 = float4(0.0, 0.0, 0.0, 1.0);
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredClearGBufferV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredClearGBufferV.hlsl
new file mode 100644
index 000000000..20ba4d509
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredClearGBufferV.hlsl
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// 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 Appdata
+{
+ float3 pos : POSITION;
+ float4 color : COLOR;
+};
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+};
+
+uniform float4x4 modelview;
+
+Conn main( Appdata In )
+{
+ Conn Out;
+ Out.hpos = float4(In.pos,1.0);
+ return Out;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredColorShaderP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredColorShaderP.hlsl
new file mode 100644
index 000000000..d91d2eb38
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredColorShaderP.hlsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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 Fragout
+{
+ float4 col : TORQUE_TARGET0;
+ float4 col1 : TORQUE_TARGET1;
+ float4 col2 : TORQUE_TARGET2;
+};
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main( )
+{
+ Fragout OUT;
+
+ OUT.col = float4(0.0, 0.0, 0.0, 0.0);
+ OUT.col1 = float4(1.0, 1.0, 1.0, 1.0);
+
+ // Draw on color buffer.
+ OUT.col2 = float4(1.0, 0.0, 0.0, 1.0);
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredShadingP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredShadingP.hlsl
new file mode 100644
index 000000000..ebd9ed72b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/deferredShadingP.hlsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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 "../../shaderModelAutoGen.hlsl"
+#include "../../postfx/postFx.hlsl"
+#include "../../torque.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(colorBufferTex,0);
+TORQUE_UNIFORM_SAMPLER2D(lightDeferredTex,1);
+TORQUE_UNIFORM_SAMPLER2D(matInfoTex,2);
+TORQUE_UNIFORM_SAMPLER2D(deferredTex,3);
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 lightBuffer = TORQUE_TEX2D( lightDeferredTex, IN.uv0 );
+ float4 colorBuffer = TORQUE_TEX2D( colorBufferTex, IN.uv0 );
+ float4 matInfo = TORQUE_TEX2D( matInfoTex, IN.uv0 );
+ float specular = saturate(lightBuffer.a);
+ float depth = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 ).w;
+
+ if (depth>0.9999)
+ return float4(0,0,0,0);
+
+ // Diffuse Color Altered by Metalness
+ bool metalness = getFlag(matInfo.r, 3);
+ if ( metalness )
+ {
+ colorBuffer *= (1.0 - colorBuffer.a);
+ }
+
+ colorBuffer += float4(specular, specular, specular, 1.0);
+ colorBuffer *= float4(lightBuffer.rgb, 1.0);
+
+ return hdrEncode( float4(colorBuffer.rgb, 1.0) );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuad.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuad.hlsl
new file mode 100644
index 000000000..543e21677
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuad.hlsl
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------------
+// 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 FarFrustumQuadConnectV
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv0 : TEXCOORD0;
+ float3 wsEyeRay : TEXCOORD1;
+ float3 vsEyeRay : TEXCOORD2;
+};
+
+struct FarFrustumQuadConnectP
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv0 : TEXCOORD0;
+ float3 wsEyeRay : TEXCOORD1;
+ float3 vsEyeRay : TEXCOORD2;
+};
+
+
+float2 getUVFromSSPos( float3 ssPos, float4 rtParams )
+{
+ float2 outPos = ( ssPos.xy + 1.0 ) / 2.0;
+ outPos.y = 1.0 - outPos.y;
+ outPos = ( outPos * rtParams.zw ) + rtParams.xy;
+ return outPos;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl
new file mode 100644
index 000000000..0167d901a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/farFrustumQuadV.hlsl
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// 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 "../../hlslStructs.hlsl"
+#include "farFrustumQuad.hlsl"
+
+
+FarFrustumQuadConnectV main( VertexIn_PNTT IN,
+ uniform float4 rtParams0 )
+{
+ FarFrustumQuadConnectV OUT;
+
+ OUT.hpos = float4( IN.uv0, 0, 1 );
+
+ // Get a RT-corrected UV from the SS coord
+ OUT.uv0 = getUVFromSSPos( OUT.hpos.xyz, rtParams0 );
+
+ // Interpolators will generate eye rays the
+ // from far-frustum corners.
+ OUT.wsEyeRay = IN.tangent;
+ OUT.vsEyeRay = IN.normal;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/convexGeometryV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/convexGeometryV.glsl
new file mode 100644
index 000000000..1807ac43f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/convexGeometryV.glsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 vPosition;
+
+#define IN_pos vPosition
+
+out vec4 wsEyeDir;
+out vec4 ssPos;
+out vec4 vsEyeDir;
+
+#define OUT_hpos gl_Position
+#define OUT_wsEyeDir wsEyeDir
+#define OUT_ssPos ssPos
+#define OUT_vsEyeDir vsEyeDir
+
+uniform mat4 modelview;
+uniform mat4 objTrans;
+uniform mat4 worldViewOnly;
+uniform vec3 eyePosWorld;
+
+void main()
+{
+ OUT_hpos = tMul( modelview, IN_pos );
+ OUT_wsEyeDir = tMul( objTrans, IN_pos ) - vec4( eyePosWorld, 0.0 );
+ OUT_vsEyeDir = tMul( worldViewOnly, IN_pos );
+ OUT_ssPos = OUT_hpos;
+
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredClearGBufferP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredClearGBufferP.glsl
new file mode 100644
index 000000000..b58f347bb
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredClearGBufferP.glsl
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+out vec4 OUT_col;
+out vec4 OUT_col1;
+out vec4 OUT_col2;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ // Clear Deferred Buffer ( Normals/Depth );
+ OUT_col = vec4(1.0, 1.0, 1.0, 1.0);
+
+ // Clear Color Buffer.
+ OUT_col1 = vec4(0.0, 0.0, 0.0, 1.0);
+
+ // Clear Material Info Buffer.
+ OUT_col2 = vec4(0.0, 0.0, 0.0, 1.0);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredColorShaderP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredColorShaderP.glsl
new file mode 100644
index 000000000..85c553089
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredColorShaderP.glsl
@@ -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.
+//-----------------------------------------------------------------------------
+
+layout (location = 0) out vec4 col;
+layout (location = 1) out vec4 col1;
+layout (location = 2) out vec4 col2;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ col = vec4(0.0, 0.0, 0.0, 0.0);
+ col1 = vec4(1.0, 1.0, 1.0, 1.0);
+
+ // Draw on color buffer.
+ col2 = vec4(1.0, 0.0, 0.0, 1.0);
+}
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
new file mode 100644
index 000000000..0234d5fd1
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/deferredShadingP.glsl
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+// 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 lightDeferredTex;
+uniform sampler2D matInfoTex;
+uniform sampler2D deferredTex;
+
+out vec4 OUT_col;
+
+void main()
+{
+ float depth = deferredUncondition( deferredTex, uv0 ).w;
+ if (depth>0.9999)
+ {
+ 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);
+
+ // Diffuse Color Altered by Metalness
+ bool metalness = getFlag(matInfo.r, 3);
+ if ( metalness )
+ {
+ colorBuffer *= (1.0 - colorBuffer.a);
+ }
+
+ colorBuffer += vec4(specular, specular, specular, 1.0);
+ colorBuffer *= vec4(lightBuffer.rgb, 1.0);
+
+ OUT_col = hdrEncode( vec4(colorBuffer.rgb, 1.0) );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuad.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuad.glsl
new file mode 100644
index 000000000..76054eb09
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuad.glsl
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+vec2 getUVFromSSPos( vec3 ssPos, vec4 rtParams )
+{
+ vec2 outPos = ( ssPos.xy + 1.0 ) / 2.0;
+ outPos.y = 1.0 - outPos.y;
+ outPos = ( outPos * rtParams.zw ) + rtParams.xy;
+ return outPos;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuadV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuadV.glsl
new file mode 100644
index 000000000..a80e856ed
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/farFrustumQuadV.glsl
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// 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 "farFrustumQuad.glsl"
+
+in vec4 vPosition;
+in vec3 vNormal;
+in vec3 vTangent;
+in vec2 vTexCoord0;
+
+uniform vec4 rtParams0;
+out vec4 hpos;
+out vec2 uv0;
+out vec3 wsEyeRay;
+out vec3 vsEyeRay;
+
+void main()
+{
+ hpos = vec4( vTexCoord0, 0, 1 );
+
+ // Get a RT-corrected UV from the SS coord
+ uv0 = getUVFromSSPos( hpos.xyz, rtParams0 );
+ gl_Position = hpos;
+
+ // Interpolators will generate eye rays the
+ // from far-frustum corners.
+ wsEyeRay = vTangent;
+ vsEyeRay = vNormal;
+
+ correctSSP(gl_Position);
+}
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
new file mode 100644
index 000000000..08af9231b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/lightingUtils.glsl
@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+float attenuate( vec4 lightColor, vec2 attParams, float dist )
+{
+ // We're summing the results of a scaled constant,
+ // linear, and quadratic attenuation.
+
+ #ifdef ACCUMULATE_LUV
+ return lightColor.w * ( 1.0 - dot( attParams, vec2( dist, dist * dist ) ) );
+ #else
+ return 1.0 - dot( attParams, vec2( dist, dist * 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 );
+ 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;
+}
\ No newline at end of file
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
new file mode 100644
index 000000000..80869de25
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/pointLightP.glsl
@@ -0,0 +1,273 @@
+//-----------------------------------------------------------------------------
+// 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 "lightingUtils.glsl"
+#include "../../../gl/lighting.glsl"
+#include "../../shadowMap/shadowMapIO_GLSL.h"
+#include "softShadow.glsl"
+#include "../../../gl/torque.glsl"
+
+in vec4 wsEyeDir;
+in vec4 ssPos;
+in vec4 vsEyeDir;
+in vec4 color;
+
+#ifdef USE_COOKIE_TEX
+
+/// The texture for cookie rendering.
+uniform samplerCube cookieMap ;
+
+#endif
+
+
+#ifdef SHADOW_CUBE
+
+ vec3 decodeShadowCoord( vec3 shadowCoord )
+ {
+ return shadowCoord;
+ }
+
+ vec4 shadowSample( samplerCube shadowMap, vec3 shadowCoord )
+ {
+ return texture( shadowMap, shadowCoord );
+ }
+
+#else
+
+ vec3 decodeShadowCoord( vec3 paraVec )
+ {
+ // Flip y and z
+ paraVec = paraVec.xzy;
+
+ #ifndef SHADOW_PARABOLOID
+
+ bool calcBack = (paraVec.z < 0.0);
+ if ( calcBack )
+ {
+ paraVec.z = paraVec.z * -1.0;
+
+ #ifdef SHADOW_DUALPARABOLOID
+ paraVec.x = -paraVec.x;
+ #endif
+ }
+
+ #endif
+
+ vec3 shadowCoord;
+ shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5;
+ shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5);
+ shadowCoord.z = 0;
+
+ // adjust the co-ordinate slightly if it is near the extent of the paraboloid
+ // 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;
+
+ #ifndef SHADOW_PARABOLOID
+
+ // If this is the back, offset in the atlas
+ if ( calcBack )
+ shadowCoord.x += 1.0;
+
+ // Atlasing front and back maps, so scale
+ shadowCoord.x *= 0.5;
+
+ #endif
+
+ return shadowCoord;
+ }
+
+#endif
+
+uniform sampler2D deferredBuffer;
+
+#ifdef SHADOW_CUBE
+ uniform samplerCube shadowMap;
+#else
+ uniform sampler2D shadowMap;
+ uniform sampler2D dynamicShadowMap;
+#endif
+
+uniform sampler2D lightBuffer;
+uniform sampler2D colorBuffer;
+uniform sampler2D matInfoBuffer;
+
+uniform vec4 rtParams0;
+
+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 shadowSoftness;
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Compute scene UV
+ vec3 ssPos = ssPos.xyz / ssPos.w;
+ vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
+
+ // Emissive.
+ vec4 matInfo = texture( matInfoBuffer, uvScene );
+ bool emissive = getFlag( matInfo.r, 0 );
+ if ( emissive )
+ {
+ OUT_col = vec4(0.0, 0.0, 0.0, 0.0);
+ return;
+ }
+
+ vec4 colorSample = texture( colorBuffer, uvScene );
+ vec3 subsurface = vec3(0.0,0.0,0.0);
+ if (getFlag( matInfo.r, 1 ))
+ {
+ 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 );
+
+ #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 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 );
+
+ float shadowed = min(static_shadowed, dynamic_shadowed);
+ #endif
+
+ #endif // !NO_SHADOW
+
+ vec3 lightcol = lightColor.rgb;
+ #ifdef USE_COOKIE_TEX
+
+ // Lookup the cookie sample.
+ vec4 cookie = texture( cookieMap, tMul( viewToLightProj, -lightVec ) );
+
+ // Multiply the light with the cookie tex.
+ 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 ) );
+
+ #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);
+ }
+
+ OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/softShadow.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/softShadow.glsl
new file mode 100644
index 000000000..a14213946
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/softShadow.glsl
@@ -0,0 +1,159 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
+
+#define NUM_PRE_TAPS 4
+#define NUM_TAPS 12
+
+/// The non-uniform poisson disk used in the
+/// high quality shadow filtering.
+vec2 sNonUniformTaps[NUM_TAPS] = vec2[]
+(
+ // These first 4 taps are located around the edges
+ // of the disk and are used to predict fully shadowed
+ // or unshadowed areas.
+ vec2( 0.992833, 0.979309 ),
+ vec2( -0.998585, 0.985853 ),
+ vec2( 0.949299, -0.882562 ),
+ vec2( -0.941358, -0.893924 ),
+
+ // The rest of the samples.
+ vec2( 0.545055, -0.589072 ),
+ vec2( 0.346526, 0.385821 ),
+ vec2( -0.260183, 0.334412 ),
+ vec2( 0.248676, -0.679605 ),
+ vec2( -0.569502, -0.390637 ),
+ vec2( -0.614096, 0.212577 ),
+ vec2( -0.259178, 0.876272 ),
+ vec2( 0.649526, 0.864333 )
+);
+
+#else
+
+#define NUM_PRE_TAPS 5
+
+/// The non-uniform poisson disk used in the
+/// high quality shadow filtering.
+vec2 sNonUniformTaps[NUM_PRE_TAPS] = vec2[]
+(
+ vec2( 0.892833, 0.959309 ),
+ vec2( -0.941358, -0.873924 ),
+ vec2( -0.260183, 0.334412 ),
+ vec2( 0.348676, -0.679605 ),
+ vec2( -0.569502, -0.390637 )
+);
+
+#endif
+
+
+/// The texture used to do per-pixel pseudorandom
+/// rotations of the filter taps.
+uniform sampler2D gTapRotationTex ;
+
+
+float softShadow_sampleTaps( sampler2D shadowMap,
+ vec2 sinCos,
+ vec2 shadowPos,
+ float filterRadius,
+ float distToLight,
+ float esmFactor,
+ int startTap,
+ int endTap )
+{
+ float shadow = 0;
+
+ vec2 tap = vec2(0);
+ for ( int t = startTap; t < endTap; t++ )
+ {
+ tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
+ tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
+ float occluder = tex2Dlod( shadowMap, vec4( shadowPos + tap, 0, 0 ) ).r;
+
+ float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
+ shadow += esm / float( endTap - startTap );
+ }
+
+ return shadow;
+}
+
+
+float softShadow_filter( sampler2D shadowMap,
+ vec2 vpos,
+ vec2 shadowPos,
+ float filterRadius,
+ float distToLight,
+ float dotNL,
+ float esmFactor )
+{
+ #ifndef SOFTSHADOW
+
+ // If softshadow is undefined then we skip any complex
+ // filtering... just do a single sample ESM.
+
+ float occluder = tex2Dlod( shadowMap, vec4( shadowPos, 0, 0 ) ).r;
+ float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
+
+ #else
+
+ // Lookup the random rotation for this screen pixel.
+ vec2 sinCos = ( tex2Dlod( gTapRotationTex, vec4( vpos * 16, 0, 0 ) ).rg - 0.5 ) * 2;
+
+ // Do the prediction taps first.
+ float shadow = softShadow_sampleTaps( shadowMap,
+ sinCos,
+ shadowPos,
+ filterRadius,
+ distToLight,
+ esmFactor,
+ 0,
+ NUM_PRE_TAPS );
+
+ // We live with only the pretap results if we don't
+ // have high quality shadow filtering enabled.
+ #ifdef SOFTSHADOW_HIGH_QUALITY
+
+ // Only do the expensive filtering if we're really
+ // in a partially shadowed area.
+ if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 )
+ {
+ shadow += softShadow_sampleTaps( shadowMap,
+ sinCos,
+ shadowPos,
+ filterRadius,
+ distToLight,
+ esmFactor,
+ NUM_PRE_TAPS,
+ NUM_TAPS );
+
+ // This averages the taps above with the results
+ // of the prediction samples.
+ shadow *= 0.5;
+ }
+
+ #endif // SOFTSHADOW_HIGH_QUALITY
+
+ #endif // SOFTSHADOW
+
+ return shadow;
+}
\ No newline at end of file
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
new file mode 100644
index 000000000..5fcf1b19c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/spotLightP.glsl
@@ -0,0 +1,210 @@
+//-----------------------------------------------------------------------------
+// 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 "farFrustumQuad.glsl"
+#include "lightingUtils.glsl"
+#include "../../shadowMap/shadowMapIO_GLSL.h"
+#include "shadergen:/autogenConditioners.h"
+#include "softShadow.glsl"
+#include "../../../gl/lighting.glsl"
+#include "../../../gl/torque.glsl"
+
+in vec4 wsEyeDir;
+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.
+uniform sampler2D cookieMap;
+
+#endif
+
+uniform sampler2D deferredBuffer;
+uniform sampler2D shadowMap;
+uniform sampler2D dynamicShadowMap;
+
+uniform sampler2D lightBuffer;
+uniform sampler2D colorBuffer;
+uniform sampler2D matInfoBuffer;
+
+uniform vec4 rtParams0;
+
+uniform vec3 lightPosition;
+uniform vec4 lightColor;
+uniform float lightBrightness;
+uniform float lightRange;
+uniform vec2 lightAttenuation;
+uniform vec3 lightDirection;
+uniform vec4 lightSpotParams;
+uniform vec4 lightMapParams;
+
+uniform vec4 vsFarPlane;
+uniform mat4 viewToLightProj;
+uniform mat4 dynamicViewToLightProj;
+
+uniform vec4 lightParams;
+uniform float shadowSoftness;
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Compute scene UV
+ vec3 ssPos = IN_ssPos.xyz / IN_ssPos.w;
+ vec2 uvScene = getUVFromSSPos( ssPos, rtParams0 );
+
+ // Emissive.
+ vec4 matInfo = texture( matInfoBuffer, uvScene );
+ bool emissive = getFlag( matInfo.r, 0 );
+ if ( emissive )
+ {
+ OUT_col = vec4(0.0, 0.0, 0.0, 0.0);
+ return;
+ }
+
+ vec4 colorSample = texture( colorBuffer, uvScene );
+ vec3 subsurface = vec3(0.0,0.0,0.0);
+ if (getFlag( matInfo.r, 1 ))
+ {
+ 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 );
+
+ // Get the shadow texture coordinate
+ vec4 pxlPosLightProj = tMul( viewToLightProj, vec4( viewSpacePos, 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
+
+ // Get a linear depth from the light source.
+ 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 shadowed = min(static_shadowed, dynamic_shadowed);
+ #endif // !NO_SHADOW
+
+ vec3 lightcol = lightColor.rgb;
+ #ifdef USE_COOKIE_TEX
+
+ // Lookup the cookie sample.
+ vec4 cookie = texture( cookieMap, shadowCoord );
+
+ // Multiply the light with the cookie tex.
+ 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 ) );
+
+ #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);
+ }
+
+ OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att);
+}
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
new file mode 100644
index 000000000..142e58b10
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/gl/vectorLightP.glsl
@@ -0,0 +1,327 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "lightingUtils.glsl"
+#include "../../shadowMap/shadowMapIO_GLSL.h"
+#include "softShadow.glsl"
+
+in vec4 hpos;
+in vec2 uv0;
+in vec3 wsEyeRay;
+in vec3 vsEyeRay;
+
+uniform sampler2D shadowMap;
+uniform sampler2D dynamicShadowMap;
+
+#ifdef USE_SSAO_MASK
+uniform sampler2D ssaoMask ;
+uniform vec4 rtParams3;
+#endif
+
+uniform sampler2D deferredBuffer;
+uniform sampler2D lightBuffer;
+uniform sampler2D colorBuffer;
+uniform sampler2D matInfoBuffer;
+uniform vec3 lightDirection;
+uniform vec4 lightColor;
+uniform float lightBrightness;
+uniform vec4 lightAmbient;
+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 overDarkPSSM;
+uniform float shadowSoftness;
+
+//static shadowMap
+uniform mat4x4 worldToLightProj;
+uniform vec4 scaleX;
+uniform vec4 scaleY;
+uniform vec4 offsetX;
+uniform vec4 offsetY;
+uniform vec4 farPlaneScalePSSM;
+
+//dynamic shadowMap
+uniform mat4x4 dynamicWorldToLightProj;
+uniform vec4 dynamicScaleX;
+uniform vec4 dynamicScaleY;
+uniform vec4 dynamicOffsetX;
+uniform vec4 dynamicOffsetY;
+uniform vec4 dynamicFarPlaneScalePSSM;
+
+vec4 AL_VectorLightShadowCast( sampler2D _sourceshadowMap,
+ vec2 _texCoord,
+ mat4 _worldToLightProj,
+ vec4 _worldPos,
+ vec4 _scaleX, vec4 _scaleY,
+ vec4 _offsetX, vec4 _offsetY,
+ vec4 _farPlaneScalePSSM,
+ vec4 _atlasXOffset, vec4 _atlasYOffset,
+ vec2 _atlasScale,
+ float _shadowSoftness,
+ float _dotNL ,
+ vec4 _overDarkPSSM
+)
+{
+
+ // Compute shadow map coordinate
+ vec4 pxlPosLightProj = tMul(_worldToLightProj, _worldPos);
+ vec2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
+
+ // 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 );
+ shadowCoordX *= _scaleX;
+ shadowCoordY *= _scaleY;
+ shadowCoordX += _offsetX;
+ shadowCoordY += _offsetY;
+ farPlaneDists *= _farPlaneScalePSSM;
+
+ // If the shadow sample is within -1..1 and the distance
+ // to the light for this pixel is less than the far plane
+ // of the split, use it.
+ vec4 finalMask;
+ if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
+ shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
+ farPlaneDists.x < 1.0 )
+ finalMask = vec4(1, 0, 0, 0);
+
+ else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
+ shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
+ farPlaneDists.y < 1.0 )
+ finalMask = vec4(0, 1, 0, 0);
+
+ else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
+ shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
+ farPlaneDists.z < 1.0 )
+ finalMask = vec4(0, 0, 1, 0);
+
+ else
+ finalMask = vec4(0, 0, 0, 1);
+
+ vec3 debugColor = vec3(0);
+
+ #ifdef NO_SHADOW
+ debugColor = vec3(1.0);
+ #endif
+
+ #ifdef PSSM_DEBUG_RENDER
+ if ( finalMask.x > 0 )
+ debugColor += vec3( 1, 0, 0 );
+ else if ( finalMask.y > 0 )
+ debugColor += vec3( 0, 1, 0 );
+ else if ( finalMask.z > 0 )
+ debugColor += vec3( 0, 0, 1 );
+ else if ( finalMask.w > 0 )
+ debugColor += vec3( 1, 1, 0 );
+ #endif
+
+ // Here we know what split we're sampling from, so recompute the _texCoord location
+ // Yes, we could just use the result from above, but doing it this way actually saves
+ // shader instructions.
+ vec2 finalScale;
+ finalScale.x = dot(finalMask, _scaleX);
+ finalScale.y = dot(finalMask, _scaleY);
+
+ vec2 finalOffset;
+ finalOffset.x = dot(finalMask, _offsetX);
+ finalOffset.y = dot(finalMask, _offsetY);
+
+ vec2 shadowCoord;
+ shadowCoord = baseShadowCoord * finalScale;
+ shadowCoord += finalOffset;
+
+ // 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);
+
+ shadowCoord *= _atlasScale;
+ shadowCoord += aOffset;
+
+ // Each split has a different far plane, take this into account.
+ float farPlaneScale = dot( _farPlaneScalePSSM, finalMask );
+ distToLight *= farPlaneScale;
+
+ return vec4(debugColor,
+ 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;
+ }
+
+ vec4 colorSample = texture( colorBuffer, uv0 );
+ vec3 subsurface = vec3(0.0,0.0,0.0);
+ if (getFlag( matInfo.r, 1 ))
+ {
+ 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, uv0 );
+ vec3 normal = deferredSample.rgb;
+ float depth = deferredSample.a;
+
+ // 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
+
+ #ifdef NO_SHADOW
+
+ // Fully unshadowed.
+ float shadowed = 1.0;
+
+ #ifdef PSSM_DEBUG_RENDER
+ debugColor = vec3(1.0);
+ #endif
+
+ #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);
+ 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;
+ #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 ) );
+
+ // temp for debugging. uncomment one or the other.
+ //float shadowed = static_shadowed;
+ //float shadowed = dynamic_shadowed;
+ float shadowed = min(static_shadowed, dynamic_shadowed);
+
+ #ifdef PSSM_DEBUG_RENDER
+ if ( fadeOutAmt > 1.0 )
+ debugColor = vec3(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);
+ }
+
+ // Sample the AO texture.
+ #ifdef USE_SSAO_MASK
+ float ao = 1.0 - texture( ssaoMask, viewportCoordToRenderTarget( uv0.xy, rtParams3 ) ).r;
+ addToResult *= ao;
+ #endif
+
+ #ifdef PSSM_DEBUG_RENDER
+ lightColorOut = debugColor;
+ #endif
+
+ OUT_col = AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/lightingUtils.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/lightingUtils.hlsl
new file mode 100644
index 000000000..2bff18999
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/lightingUtils.hlsl
@@ -0,0 +1,51 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+float attenuate( float4 lightColor, float2 attParams, float dist )
+{
+ // We're summing the results of a scaled constant,
+ // linear, and quadratic attenuation.
+
+ #ifdef ACCUMULATE_LUV
+ return lightColor.w * ( 1.0 - dot( attParams, float2( dist, dist * dist ) ) );
+ #else
+ return 1.0 - dot( attParams, float2( dist, dist * dist ) );
+ #endif
+}
+
+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;
+}
+
+float3 getDistanceVectorToPlane( float negFarPlaneDotEye, float3 direction, float4 plane )
+{
+ float denum = dot( plane.xyz, direction.xyz );
+ float t = negFarPlaneDotEye / denum;
+
+ return direction.xyz * t;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightP.hlsl
new file mode 100644
index 000000000..a0156eb85
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightP.hlsl
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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 "farFrustumQuad.hlsl"
+#include "lightingUtils.hlsl"
+#include "../../lighting.hlsl"
+#include "../../shaderModel.hlsl"
+#include "../../shaderModelAutoGen.hlsl"
+
+
+struct ConvexConnectP
+{
+ float4 pos : TORQUE_POSITION;
+ float4 ssPos : TEXCOORD0;
+ float3 vsEyeDir : TEXCOORD1;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
+
+uniform float4 lightPosition;
+uniform float4 lightColor;
+uniform float lightRange;
+uniform float4 vsFarPlane;
+uniform float4 rtParams0;
+
+float4 main( ConvexConnectP IN ) : TORQUE_TARGET0
+{
+ // Compute scene UV
+ float3 ssPos = IN.ssPos.xyz / IN.ssPos.w;
+ float2 uvScene = getUVFromSSPos(ssPos, rtParams0);
+
+ // 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, vsFarPlane);
+ float3 viewSpacePos = eyeRay * depth;
+
+ // Build light vec, get length, clip pixel if needed
+ float3 lightVec = lightPosition.xyz - viewSpacePos;
+ float lenLightV = length(lightVec);
+ clip(lightRange - lenLightV);
+
+ // Do a very simple falloff instead of real attenuation
+ float atten = 1.0 - saturate(lenLightV / lightRange);
+
+ // Normalize lightVec
+ lightVec /= lenLightV;
+
+ // N.L * Attenuation
+ float Sat_NL_Att = saturate(dot(lightVec, normal)) * atten;
+
+ // Output, no specular
+ return lightinfoCondition(lightColor.rgb, Sat_NL_Att, 0.0, 0.0);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightV.hlsl
new file mode 100644
index 000000000..faa2ec115
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/particlePointLightV.hlsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 "../../hlslStructs.hlsl"
+#include "../../shaderModel.hlsl"
+
+struct ConvexConnectV
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 ssPos : TEXCOORD0;
+ float3 vsEyeDir : TEXCOORD1;
+};
+
+uniform float4x4 viewProj;
+uniform float4x4 view;
+uniform float3 particlePosWorld;
+uniform float lightRange;
+
+ConvexConnectV main( VertexIn_P IN )
+{
+ ConvexConnectV OUT;
+ float4 pos = float4(IN.pos, 0.0);
+ float4 vPosWorld = pos + float4(particlePosWorld, 0.0) + pos * lightRange;
+ OUT.hpos = mul(viewProj, vPosWorld);
+ OUT.vsEyeDir = mul(view, vPosWorld);
+ OUT.ssPos = OUT.hpos;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl
new file mode 100644
index 000000000..317feb0b3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/pointLightP.hlsl
@@ -0,0 +1,277 @@
+//-----------------------------------------------------------------------------
+// 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 "../../shaderModelAutoGen.hlsl"
+
+#include "farFrustumQuad.hlsl"
+#include "lightingUtils.hlsl"
+#include "../../lighting.hlsl"
+#include "../shadowMap/shadowMapIO_HLSL.h"
+#include "softShadow.hlsl"
+#include "../../torque.hlsl"
+
+struct ConvexConnectP
+{
+ float4 pos : TORQUE_POSITION;
+ float4 wsEyeDir : TEXCOORD0;
+ float4 ssPos : TEXCOORD1;
+ float4 vsEyeDir : TEXCOORD2;
+};
+
+
+#ifdef USE_COOKIE_TEX
+
+/// The texture for cookie rendering.
+TORQUE_UNIFORM_SAMPLERCUBE(cookieMap, 3);
+
+#endif
+
+
+#ifdef SHADOW_CUBE
+
+ float3 decodeShadowCoord( float3 shadowCoord )
+ {
+ return shadowCoord;
+ }
+
+ float4 shadowSample( TORQUE_SAMPLERCUBE(shadowMap), float3 shadowCoord )
+ {
+ return TORQUE_TEXCUBE( shadowMap, shadowCoord );
+ }
+
+#else
+
+ float3 decodeShadowCoord( float3 paraVec )
+ {
+ // Flip y and z
+ paraVec = paraVec.xzy;
+
+ #ifndef SHADOW_PARABOLOID
+
+ bool calcBack = (paraVec.z < 0.0);
+ if ( calcBack )
+ {
+ paraVec.z = paraVec.z * -1.0;
+
+ #ifdef SHADOW_DUALPARABOLOID
+ paraVec.x = -paraVec.x;
+ #endif
+ }
+
+ #endif
+
+ float3 shadowCoord;
+ shadowCoord.x = (paraVec.x / (2*(1 + paraVec.z))) + 0.5;
+ shadowCoord.y = 1-((paraVec.y / (2*(1 + paraVec.z))) + 0.5);
+ shadowCoord.z = 0;
+
+ // adjust the co-ordinate slightly if it is near the extent of the paraboloid
+ // 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;
+
+ #ifndef SHADOW_PARABOLOID
+
+ // If this is the back, offset in the atlas
+ if ( calcBack )
+ shadowCoord.x += 1.0;
+
+ // Atlasing front and back maps, so scale
+ shadowCoord.x *= 0.5;
+
+ #endif
+
+ return shadowCoord;
+ }
+
+#endif
+
+TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
+
+#ifdef SHADOW_CUBE
+TORQUE_UNIFORM_SAMPLERCUBE(shadowMap, 1);
+#else
+TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
+TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap, 2);
+#endif
+
+TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5);
+TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6);
+TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7);
+
+uniform float4 rtParams0;
+uniform float4 lightColor;
+
+uniform float lightBrightness;
+uniform float3 lightPosition;
+
+uniform float4 lightMapParams;
+uniform float4 vsFarPlane;
+uniform float4 lightParams;
+
+uniform float lightRange;
+uniform float shadowSoftness;
+uniform float2 lightAttenuation;
+
+uniform float3x3 viewToLightProj;
+uniform float3x3 dynamicViewToLightProj;
+
+float4 main( ConvexConnectP IN ) : TORQUE_TARGET0
+{
+ // 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;
+
+ // Build light vec, get length, clip pixel if needed
+ float3 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 );
+
+ #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 = 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
+
+ #endif // !NO_SHADOW
+
+ float3 lightcol = lightColor.rgb;
+ #ifdef USE_COOKIE_TEX
+
+ // Lookup the cookie sample.
+ float4 cookie = TORQUE_TEXCUBE( cookieMap, mul( viewToLightProj, -lightVec ) );
+
+ // Multiply the light with the cookie tex.
+ 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 ) );
+
+ #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);
+ }
+
+ return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/softShadow.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/softShadow.hlsl
new file mode 100644
index 000000000..0faf3e1fb
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/softShadow.hlsl
@@ -0,0 +1,158 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+#if defined( SOFTSHADOW ) && defined( SOFTSHADOW_HIGH_QUALITY )
+
+#define NUM_PRE_TAPS 4
+#define NUM_TAPS 12
+
+/// The non-uniform poisson disk used in the
+/// high quality shadow filtering.
+static float2 sNonUniformTaps[NUM_TAPS] =
+{
+ // These first 4 taps are located around the edges
+ // of the disk and are used to predict fully shadowed
+ // or unshadowed areas.
+ { 0.992833, 0.979309 },
+ { -0.998585, 0.985853 },
+ { 0.949299, -0.882562 },
+ { -0.941358, -0.893924 },
+
+ // The rest of the samples.
+ { 0.545055, -0.589072 },
+ { 0.346526, 0.385821 },
+ { -0.260183, 0.334412 },
+ { 0.248676, -0.679605 },
+ { -0.569502, -0.390637 },
+ { -0.614096, 0.212577 },
+ { -0.259178, 0.876272 },
+ { 0.649526, 0.864333 },
+};
+
+#else
+
+#define NUM_PRE_TAPS 5
+
+/// The non-uniform poisson disk used in the
+/// high quality shadow filtering.
+static float2 sNonUniformTaps[NUM_PRE_TAPS] =
+{
+ { 0.892833, 0.959309 },
+ { -0.941358, -0.873924 },
+ { -0.260183, 0.334412 },
+ { 0.348676, -0.679605 },
+ { -0.569502, -0.390637 },
+};
+
+#endif
+
+
+/// The texture used to do per-pixel pseudorandom
+/// rotations of the filter taps.
+TORQUE_UNIFORM_SAMPLER2D(gTapRotationTex, 4);
+
+float softShadow_sampleTaps( TORQUE_SAMPLER2D(shadowMap1),
+ float2 sinCos,
+ float2 shadowPos,
+ float filterRadius,
+ float distToLight,
+ float esmFactor,
+ int startTap,
+ int endTap )
+{
+ float shadow = 0;
+
+ float2 tap = 0;
+ for ( int t = startTap; t < endTap; t++ )
+ {
+ tap.x = ( sNonUniformTaps[t].x * sinCos.y - sNonUniformTaps[t].y * sinCos.x ) * filterRadius;
+ tap.y = ( sNonUniformTaps[t].y * sinCos.y + sNonUniformTaps[t].x * sinCos.x ) * filterRadius;
+ float occluder = TORQUE_TEX2DLOD( shadowMap1, float4( shadowPos + tap, 0, 0 ) ).r;
+
+ float esm = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
+ shadow += esm / float( endTap - startTap );
+ }
+
+ return shadow;
+}
+
+
+float softShadow_filter( TORQUE_SAMPLER2D(shadowMap),
+ float2 vpos,
+ float2 shadowPos,
+ float filterRadius,
+ float distToLight,
+ float dotNL,
+ float esmFactor )
+{
+ #ifndef SOFTSHADOW
+
+ // If softshadow is undefined then we skip any complex
+ // filtering... just do a single sample ESM.
+
+ float occluder = TORQUE_TEX2DLOD(shadowMap, float4(shadowPos, 0, 0)).r;
+ float shadow = saturate( exp( esmFactor * ( occluder - distToLight ) ) );
+
+ #else
+ // Lookup the random rotation for this screen pixel.
+ float2 sinCos = ( TORQUE_TEX2DLOD(gTapRotationTex, float4(vpos * 16, 0, 0)).rg - 0.5) * 2;
+
+ // Do the prediction taps first.
+ float shadow = softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap),
+ sinCos,
+ shadowPos,
+ filterRadius,
+ distToLight,
+ esmFactor,
+ 0,
+ NUM_PRE_TAPS );
+
+ // We live with only the pretap results if we don't
+ // have high quality shadow filtering enabled.
+ #ifdef SOFTSHADOW_HIGH_QUALITY
+
+ // Only do the expensive filtering if we're really
+ // in a partially shadowed area.
+ if ( shadow * ( 1.0 - shadow ) * max( dotNL, 0 ) > 0.06 )
+ {
+ shadow += softShadow_sampleTaps( TORQUE_SAMPLER2D_MAKEARG(shadowMap),
+ sinCos,
+ shadowPos,
+ filterRadius,
+ distToLight,
+ esmFactor,
+ NUM_PRE_TAPS,
+ NUM_TAPS );
+
+ // This averages the taps above with the results
+ // of the prediction samples.
+ shadow *= 0.5;
+ }
+
+ #endif // SOFTSHADOW_HIGH_QUALITY
+
+ #endif // SOFTSHADOW
+
+ return shadow;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl
new file mode 100644
index 000000000..196286dc2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/spotLightP.hlsl
@@ -0,0 +1,209 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../shaderModelAutoGen.hlsl"
+
+#include "farFrustumQuad.hlsl"
+#include "lightingUtils.hlsl"
+#include "../../lighting.hlsl"
+#include "../shadowMap/shadowMapIO_HLSL.h"
+#include "softShadow.hlsl"
+#include "../../torque.hlsl"
+
+struct ConvexConnectP
+{
+ float4 pos : TORQUE_POSITION;
+ float4 wsEyeDir : TEXCOORD0;
+ float4 ssPos : TEXCOORD1;
+ float4 vsEyeDir : TEXCOORD2;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
+TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
+TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap,2);
+
+#ifdef USE_COOKIE_TEX
+
+/// The texture for cookie rendering.
+TORQUE_UNIFORM_SAMPLER2D(cookieMap, 3);
+
+#endif
+
+TORQUE_UNIFORM_SAMPLER2D(lightBuffer, 5);
+TORQUE_UNIFORM_SAMPLER2D(colorBuffer, 6);
+TORQUE_UNIFORM_SAMPLER2D(matInfoBuffer, 7);
+
+uniform float4 rtParams0;
+
+uniform float lightBrightness;
+uniform float3 lightPosition;
+
+uniform float4 lightColor;
+
+uniform float lightRange;
+uniform float3 lightDirection;
+
+uniform float4 lightSpotParams;
+uniform float4 lightMapParams;
+uniform float4 vsFarPlane;
+uniform float4x4 viewToLightProj;
+uniform float4 lightParams;
+uniform float4x4 dynamicViewToLightProj;
+
+uniform float2 lightAttenuation;
+uniform float shadowSoftness;
+
+float4 main( ConvexConnectP IN ) : TORQUE_TARGET0
+{
+ // 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;
+
+ // Build light vec, get length, clip pixel if needed
+ float3 lightToPxlVec = viewSpacePos - lightPosition;
+ float lenLightV = length( lightToPxlVec );
+ lightToPxlVec /= lenLightV;
+
+ //lightDirection = float3( -lightDirection.xy, lightDirection.z ); //float3( 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 );
+
+ // 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;
+
+ // 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
+
+ // Get a linear depth from the light source.
+ float distToLight = pxlPosLightProj.z / lightRange;
+
+ 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;
+ #ifdef USE_COOKIE_TEX
+
+ // Lookup the cookie sample.
+ float4 cookie = TORQUE_TEX2D( cookieMap, shadowCoord );
+
+ // Multiply the light with the cookie tex.
+ 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 ) );
+
+ #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);
+ }
+
+ return AL_DeferredOutput(lightColorOut+subsurface*(1.0-Sat_NL_Att), colorSample.rgb, matInfo, addToResult, specular, Sat_NL_Att);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl
new file mode 100644
index 000000000..c5efde242
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/advanced/vectorLightP.hlsl
@@ -0,0 +1,328 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../shaderModelAutoGen.hlsl"
+
+#include "farFrustumQuad.hlsl"
+#include "../../torque.hlsl"
+#include "../../lighting.hlsl"
+#include "lightingUtils.hlsl"
+#include "../shadowMap/shadowMapIO_HLSL.h"
+#include "softShadow.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(deferredBuffer, 0);
+TORQUE_UNIFORM_SAMPLER2D(shadowMap, 1);
+TORQUE_UNIFORM_SAMPLER2D(dynamicShadowMap, 2);
+
+#ifdef USE_SSAO_MASK
+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);
+
+uniform float lightBrightness;
+uniform float3 lightDirection;
+
+uniform float4 lightColor;
+uniform float4 lightAmbient;
+
+uniform float shadowSoftness;
+uniform float3 eyePosWorld;
+
+uniform float4 atlasXOffset;
+uniform float4 atlasYOffset;
+uniform float4 zNearFarInvNearFar;
+uniform float4 lightMapParams;
+uniform float4 farPlaneScalePSSM;
+uniform float4 overDarkPSSM;
+
+uniform float2 fadeStartLength;
+uniform float2 atlasScale;
+
+uniform float4x4 eyeMat;
+
+// Static Shadows
+uniform float4x4 worldToLightProj;
+uniform float4 scaleX;
+uniform float4 scaleY;
+uniform float4 offsetX;
+uniform float4 offsetY;
+// Dynamic Shadows
+uniform float4x4 dynamicWorldToLightProj;
+uniform float4 dynamicScaleX;
+uniform float4 dynamicScaleY;
+uniform float4 dynamicOffsetX;
+uniform float4 dynamicOffsetY;
+uniform float4 dynamicFarPlaneScalePSSM;
+
+float4 AL_VectorLightShadowCast( TORQUE_SAMPLER2D(sourceShadowMap),
+ float2 texCoord,
+ float4x4 worldToLightProj,
+ float4 worldPos,
+ float4 scaleX,
+ float4 scaleY,
+ float4 offsetX,
+ float4 offsetY,
+ float4 farPlaneScalePSSM,
+ float4 atlasXOffset,
+ float4 atlasYOffset,
+ float2 atlasScale,
+ float shadowSoftness,
+ float dotNL ,
+ float4 overDarkPSSM)
+{
+ // Compute shadow map coordinate
+ float4 pxlPosLightProj = mul(worldToLightProj, worldPos);
+ float2 baseShadowCoord = pxlPosLightProj.xy / pxlPosLightProj.w;
+
+ // 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.
+ float4 shadowCoordX = baseShadowCoord.xxxx;
+ float4 shadowCoordY = baseShadowCoord.yyyy;
+ float4 farPlaneDists = distToLight.xxxx;
+ shadowCoordX *= scaleX;
+ shadowCoordY *= scaleY;
+ shadowCoordX += offsetX;
+ shadowCoordY += offsetY;
+ farPlaneDists *= farPlaneScalePSSM;
+
+ // If the shadow sample is within -1..1 and the distance
+ // to the light for this pixel is less than the far plane
+ // of the split, use it.
+ float4 finalMask;
+ if ( shadowCoordX.x > -0.99 && shadowCoordX.x < 0.99 &&
+ shadowCoordY.x > -0.99 && shadowCoordY.x < 0.99 &&
+ farPlaneDists.x < 1.0 )
+ finalMask = float4(1, 0, 0, 0);
+
+ else if ( shadowCoordX.y > -0.99 && shadowCoordX.y < 0.99 &&
+ shadowCoordY.y > -0.99 && shadowCoordY.y < 0.99 &&
+ farPlaneDists.y < 1.0 )
+ finalMask = float4(0, 1, 0, 0);
+
+ else if ( shadowCoordX.z > -0.99 && shadowCoordX.z < 0.99 &&
+ shadowCoordY.z > -0.99 && shadowCoordY.z < 0.99 &&
+ farPlaneDists.z < 1.0 )
+ finalMask = float4(0, 0, 1, 0);
+
+ else
+ finalMask = float4(0, 0, 0, 1);
+
+ float3 debugColor = float3(0,0,0);
+
+ #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 );
+ else if ( finalMask.y > 0 )
+ debugColor += float3( 0, 1, 0 );
+ else if ( finalMask.z > 0 )
+ debugColor += float3( 0, 0, 1 );
+ else if ( finalMask.w > 0 )
+ debugColor += float3( 1, 1, 0 );
+ #endif
+
+ // Here we know what split we're sampling from, so recompute the texcoord location
+ // Yes, we could just use the result from above, but doing it this way actually saves
+ // shader instructions.
+ float2 finalScale;
+ finalScale.x = dot(finalMask, scaleX);
+ finalScale.y = dot(finalMask, scaleY);
+
+ float2 finalOffset;
+ finalOffset.x = dot(finalMask, offsetX);
+ finalOffset.y = dot(finalMask, offsetY);
+
+ float2 shadowCoord;
+ shadowCoord = baseShadowCoord * finalScale;
+ shadowCoord += finalOffset;
+
+ // Convert to texcoord space
+ shadowCoord = 0.5 * shadowCoord + float2(0.5, 0.5);
+ shadowCoord.y = 1.0f - shadowCoord.y;
+
+ // Move around inside of atlas
+ float2 aOffset;
+ aOffset.x = dot(finalMask, atlasXOffset);
+ aOffset.y = dot(finalMask, atlasYOffset);
+
+ shadowCoord *= atlasScale;
+ shadowCoord += aOffset;
+
+ // Each split has a different far plane, take this into account.
+ 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 ) ) );
+};
+
+float4 main( FarFrustumQuadConnectP IN ) : TORQUE_TARGET0
+{
+ // 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);
+ }
+ // 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);
+
+ #ifdef PSSM_DEBUG_RENDER
+ float3 debugColor = float3(0,0,0);
+ #endif
+
+ #ifdef NO_SHADOW
+
+ // Fully unshadowed.
+ float shadowed = 1.0;
+
+ #ifdef PSSM_DEBUG_RENDER
+ debugColor = float3(1.0,1.0,1.0);
+ #endif
+
+ #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);
+
+ 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;
+ #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);
+
+ #ifdef PSSM_DEBUG_RENDER
+ if ( fadeOutAmt > 1.0 )
+ debugColor = 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.
+ #ifdef USE_SSAO_MASK
+ float ao = 1.0 - TORQUE_TEX2D( ssaoMask, viewportCoordToRenderTarget( IN.uv0.xy, rtParams3 ) ).r;
+ addToResult *= ao;
+ #endif
+
+ #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);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterP.glsl
new file mode 100644
index 000000000..9b510e0cf
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterP.glsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+uniform sampler2D diffuseMap;
+
+in vec2 uv;
+
+uniform vec2 oneOverTargetSize;
+
+const float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );
+const float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = texture( diffuseMap, uv ) * weight[0];
+
+ for ( int i=1; i < 3; i++ )
+ {
+ vec2 _sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
+ OUT_col += texture( diffuseMap, uv + _sample ) * weight[i];
+ OUT_col += texture( diffuseMap, uv - _sample ) * weight[i];
+ }
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterV.glsl
new file mode 100644
index 000000000..67b5f1378
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/gl/shadowFilterV.glsl
@@ -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 "../../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform vec4 rtParams0;
+
+out vec2 uv;
+
+void main()
+{
+ gl_Position = vPosition;
+ uv = viewportCoordToRenderTarget( vTexCoord0.st, rtParams0 );
+ gl_Position.y *= -1; //correct ssp
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterP.hlsl
new file mode 100644
index 000000000..cf819eed3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterP.hlsl
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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 "../../postFx/postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv : TEXCOORD0;
+};
+
+static float offset[3] = { 0.0, 1.3846153846, 3.2307692308 };
+static float weight[3] = { 0.2270270270, 0.3162162162, 0.0702702703 };
+
+uniform float2 oneOverTargetSize;
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+ float4 OUT = TORQUE_TEX2D( diffuseMap, IN.uv ) * weight[0];
+
+ for ( int i=1; i < 3; i++ )
+ {
+ float2 sample = (BLUR_DIR * offset[i]) * oneOverTargetSize;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv + sample ) * weight[i];
+ OUT += TORQUE_TEX2D(diffuseMap, IN.uv - sample) * weight[i];
+ }
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterV.hlsl
new file mode 100644
index 000000000..d0838016b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/basic/shadowFilterV.hlsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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 "../../postFx/postFx.hlsl"
+#include "../../torque.hlsl"
+
+float4 rtParams0;
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv : TEXCOORD0;
+};
+
+VertToPix main( PFXVert IN )
+{
+ VertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1.0);
+ OUT.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterP.hlsl
new file mode 100644
index 000000000..a187c3c63
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterP.hlsl
@@ -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.
+//-----------------------------------------------------------------------------
+
+//*****************************************************************************
+// Box Filter
+//*****************************************************************************
+#include "../ShaderModel.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 tex0 : TEXCOORD0;
+};
+
+// If not defined from ShaderData then define
+// the default blur kernel size here.
+//#ifndef blurSamples
+// #define blurSamples 4
+//#endif
+
+float log_conv ( float x0, float X, float y0, float Y )
+{
+ return (X + log(x0 + (y0 * exp(Y - X))));
+}
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap0, 0);
+uniform float texSize : register(C0);
+uniform float2 blurDimension : register(C2);
+uniform float2 blurBoundaries : register(C3);
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ // 5x5
+ if (IN.tex0.x <= blurBoundaries.x)
+ {
+ float texelSize = 1.2f / texSize;
+ float2 sampleOffset = texelSize * blurDimension;
+ //float2 offset = 0.5 * float( blurSamples ) * sampleOffset;
+
+ float2 texCoord = IN.tex0;
+
+ float accum = log_conv(0.3125, TORQUE_TEX2D(diffuseMap0, texCoord - sampleOffset), 0.375, tex2D(diffuseMap0, texCoord));
+ accum = log_conv(1, accum, 0.3125, TORQUE_TEX2D(diffuseMap0, texCoord + sampleOffset));
+
+ return accum;
+ } else {
+ // 3x3
+ if (IN.tex0.x <= blurBoundaries.y)
+ {
+ float texelSize = 1.3f / texSize;
+ float2 sampleOffset = texelSize * blurDimension;
+ //float2 offset = 0.5 * float( blurSamples ) * sampleOffset;
+
+ float2 texCoord = IN.tex0;
+ float accum = log_conv(0.5, tex2D(diffuseMap0, texCoord - sampleOffset), 0.5, tex2D(diffuseMap0, texCoord + sampleOffset));
+
+ return accum;
+ } else {
+ return TORQUE_TEX2D(diffuseMap0, IN.tex0);
+ }
+ }
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterV.hlsl
new file mode 100644
index 000000000..3679e41bb
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/boxFilterV.hlsl
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//*****************************************************************************
+// Box Filter
+//*****************************************************************************
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+#include "../ShaderModel.hlsl"
+
+struct VertData
+{
+ float3 position : POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 tex0 : TEXCOORD0;
+};
+
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertData IN,
+ uniform float4x4 modelview : register(C0))
+{
+ ConnectData OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.position,1.0));
+ OUT.tex0 = IN.texCoord;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterP.glsl
new file mode 100644
index 000000000..d4e05132b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterP.glsl
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define blurSamples 4.0
+
+uniform sampler2D diffuseMap0;
+uniform float texSize;
+uniform vec2 blurDimension;
+
+in vec2 tex0;
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Preshader
+ float TexelSize = 1.0 / texSize;
+ vec2 SampleOffset = TexelSize * blurDimension;
+ vec2 Offset = 0.5 * float(blurSamples - 1.0) * SampleOffset;
+
+ vec2 BaseTexCoord = tex0 - Offset;
+
+ vec4 accum = vec4(0.0, 0.0, 0.0, 0.0);
+ for(int i = 0; i < int(blurSamples); i++)
+ {
+ accum += texture(diffuseMap0, BaseTexCoord + float(i) * SampleOffset);
+ }
+ accum /= blurSamples;
+ OUT_col = accum;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterV.glsl b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterV.glsl
new file mode 100644
index 000000000..9fc436f6c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/gl/boxFilterV.glsl
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform mat4 modelview;
+
+out vec2 tex0;
+
+void main()
+{
+ gl_Position = modelview * vPosition;
+ tex0 = vTexCoord0.st;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO.h b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO.h
new file mode 100644
index 000000000..84ef6b6a8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO.h
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//#define SM_Fmt_R8G8B8A8
+
+#define pkDepthBitShft 65536.0
+#define pkDepthChanMax 256.0
+#define bias -0.5/255.0
+#define coeff 0.9999991
+//#define coeff 1.0
+
+float4 encodeShadowMap( float depth )
+{
+#if defined(SM_Fmt_R8G8B8A8)
+ return frac( float4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + bias;
+
+ //float4 packedValue = frac((depth / coeff) * 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 depth;
+#endif
+}
+
+float decodeShadowMap( float4 smSample )
+{
+#if defined(SM_Fmt_R8G8B8A8)
+ return dot( smSample, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
+#else
+ return smSample.x;
+#endif
+}
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
new file mode 100644
index 000000000..10d69b834
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_GLSL.h
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//#define SM_Fmt_R8G8B8A8
+
+#define pkDepthBitShft 65536.0
+#define pkDepthChanMax 256.0
+#define bias -0.5/255.0
+#define coeff 0.9999991
+//#define coeff 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);
+
+ //float4 packedValue = frac((depth / coeff) * 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);
+#endif
+}
+
+float decodeShadowMap( vec4 smSample )
+{
+#if defined(SM_Fmt_R8G8B8A8)
+ return dot( smSample, vec4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
+#else
+ return smSample.x;
+#endif
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_HLSL.h b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_HLSL.h
new file mode 100644
index 000000000..84ef6b6a8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/lighting/shadowMap/shadowMapIO_HLSL.h
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//#define SM_Fmt_R8G8B8A8
+
+#define pkDepthBitShft 65536.0
+#define pkDepthChanMax 256.0
+#define bias -0.5/255.0
+#define coeff 0.9999991
+//#define coeff 1.0
+
+float4 encodeShadowMap( float depth )
+{
+#if defined(SM_Fmt_R8G8B8A8)
+ return frac( float4(1.0, 255.0, 65025.0, 160581375.0) * depth ) + bias;
+
+ //float4 packedValue = frac((depth / coeff) * 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 depth;
+#endif
+}
+
+float decodeShadowMap( float4 smSample )
+{
+#if defined(SM_Fmt_R8G8B8A8)
+ return dot( smSample, float4(1.0, 1/255.0, 1/65025.0, 1/160581375.0) );
+#else
+ return smSample.x;
+#endif
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/particleCompositeP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/particleCompositeP.hlsl
new file mode 100644
index 000000000..6e26ddbdb
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/particleCompositeP.hlsl
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "shaderModel.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(colorSource, 0);
+uniform float4 offscreenTargetParams;
+
+#ifdef TORQUE_LINEAR_DEPTH
+#define REJECT_EDGES
+TORQUE_UNIFORM_SAMPLER2D(edgeSource, 1);
+uniform float4 edgeTargetParams;
+#endif
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 offscreenPos : TEXCOORD0;
+ float4 backbufferPos : TEXCOORD1;
+};
+
+
+float4 main(Conn IN) : TORQUE_TARGET0
+{
+ // Off-screen particle source screenspace position in XY
+ // Back-buffer screenspace position in ZW
+ float4 ssPos = float4(IN.offscreenPos.xy / IN.offscreenPos.w, IN.backbufferPos.xy / IN.backbufferPos.w);
+
+ float4 uvScene = ( ssPos + 1.0 ) / 2.0;
+ uvScene.yw = 1.0 - uvScene.yw;
+ uvScene.xy = viewportCoordToRenderTarget(uvScene.xy, offscreenTargetParams);
+
+#ifdef REJECT_EDGES
+ // Cut out particles along the edges, this will create the stencil mask
+ uvScene.zw = viewportCoordToRenderTarget(uvScene.zw, edgeTargetParams);
+ float edge = TORQUE_TEX2D( edgeSource, uvScene.zw ).r;
+ clip( -edge );
+#endif
+
+ // Sample offscreen target and return
+ return TORQUE_TEX2D( colorSource, uvScene.xy );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/particleCompositeV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/particleCompositeV.hlsl
new file mode 100644
index 000000000..c4c51204a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/particleCompositeV.hlsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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 Vertex
+{
+ float3 pos : POSITION;
+ float4 uvCoord : COLOR0;
+};
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 offscreenPos : TEXCOORD0;
+ float4 backbufferPos : TEXCOORD1;
+};
+
+uniform float4 screenRect; // point, extent
+
+Conn main(Vertex IN)
+{
+ Conn OUT;
+
+ OUT.hpos = float4(IN.uvCoord.xy, 1.0, 1.0);
+ OUT.hpos.xy *= screenRect.zw;
+ OUT.hpos.xy += screenRect.xy;
+
+ OUT.backbufferPos = OUT.hpos;
+ OUT.offscreenPos = OUT.hpos;
+
+ return OUT;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/particlesP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/particlesP.hlsl
new file mode 100644
index 000000000..155107d8b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/particlesP.hlsl
@@ -0,0 +1,109 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "shaderModel.hlsl"
+// With advanced lighting we get soft particles.
+#ifdef TORQUE_LINEAR_DEPTH
+ #define SOFTPARTICLES
+#endif
+
+#ifdef SOFTPARTICLES
+
+ #include "shaderModelAutoGen.hlsl"
+
+ uniform float oneOverSoftness;
+ uniform float oneOverFar;
+ TORQUE_UNIFORM_SAMPLER2D(deferredTex, 1);
+ //uniform float3 vEye;
+ uniform float4 deferredTargetParams;
+#endif
+
+#define CLIP_Z // TODO: Make this a proper macro
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : TEXCOORD0;
+ float2 uv0 : TEXCOORD1;
+ float4 pos : TEXCOORD2;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+TORQUE_UNIFORM_SAMPLER2D(paraboloidLightMap, 2);
+
+float4 lmSample( float3 nrm )
+{
+ bool calcBack = (nrm.z < 0.0);
+ if ( calcBack )
+ nrm.z = nrm.z * -1.0;
+
+ float2 lmCoord;
+ lmCoord.x = (nrm.x / (2*(1 + nrm.z))) + 0.5;
+ lmCoord.y = 1-((nrm.y / (2*(1 + nrm.z))) + 0.5);
+
+
+ // If this is the back, offset in the atlas
+ if ( calcBack )
+ lmCoord.x += 1.0;
+
+ // Atlasing front and back maps, so scale
+ lmCoord.x *= 0.5;
+
+ return TORQUE_TEX2D(paraboloidLightMap, lmCoord);
+}
+
+
+uniform float alphaFactor;
+uniform float alphaScale;
+
+float4 main( Conn IN ) : TORQUE_TARGET0
+{
+ float softBlend = 1;
+
+ #ifdef SOFTPARTICLES
+ float2 tc = IN.pos.xy * float2(1.0, -1.0) / IN.pos.w;
+ tc = viewportCoordToRenderTarget(saturate( ( tc + 1.0 ) * 0.5 ), deferredTargetParams);
+
+ float sceneDepth = TORQUE_DEFERRED_UNCONDITION(deferredTex, tc).w;
+ float depth = IN.pos.w * oneOverFar;
+ float diff = sceneDepth - depth;
+ #ifdef CLIP_Z
+ // If drawing offscreen, this acts as the depth test, since we don't line up with the z-buffer
+ // When drawing high-res, though, we want to be able to take advantage of hi-z
+ // so this is #ifdef'd out
+ //clip(diff);
+ #endif
+ softBlend = saturate( diff * oneOverSoftness );
+ #endif
+
+ float4 diffuse = TORQUE_TEX2D( diffuseMap, IN.uv0 );
+
+ //return float4( lmSample(float3(0, 0, -1)).rgb, IN.color.a * diffuse.a * softBlend * alphaScale);
+
+ // Scale output color by the alpha factor (turn LerpAlpha into pre-multiplied alpha)
+ float3 colorScale = ( alphaFactor < 0.0 ? IN.color.rgb * diffuse.rgb : ( alphaFactor > 0.0 ? IN.color.a * diffuse.a * alphaFactor * softBlend : softBlend ) );
+
+ return hdrEncode( float4( IN.color.rgb * diffuse.rgb * colorScale,
+ IN.color.a * diffuse.a * softBlend * alphaScale ) );
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/particlesV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/particlesV.hlsl
new file mode 100644
index 000000000..dbeff0cc2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/particlesV.hlsl
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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 Vertex
+{
+ float3 pos : POSITION;
+ float4 color : COLOR0;
+ float2 uv0 : TEXCOORD0;
+};
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : TEXCOORD0;
+ float2 uv0 : TEXCOORD1;
+ float4 pos : TEXCOORD2;
+};
+
+
+uniform float4x4 modelViewProj;
+uniform float4x4 fsModelViewProj;
+
+Conn main( Vertex In )
+{
+ Conn Out;
+
+ Out.hpos = mul( modelViewProj, float4(In.pos,1.0) );
+ Out.pos = mul(fsModelViewProj, float4(In.pos, 1.0) );
+ Out.color = In.color;
+ Out.uv0 = In.uv0;
+
+ return Out;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpP.hlsl
new file mode 100644
index 000000000..d18331fb6
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpP.hlsl
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+#include "shaderModel.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 tex2 : TEXCOORD1;
+};
+
+
+struct Fragout
+{
+ float4 col : TORQUE_TARGET0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(texMap, 0);
+TORQUE_UNIFORM_SAMPLER2D(refractMap, 1);
+TORQUE_UNIFORM_SAMPLER2D(bumpMap, 2);
+
+
+//-----------------------------------------------------------------------------
+// Fade edges of axis for texcoord passed in
+//-----------------------------------------------------------------------------
+float fadeAxis( float val )
+{
+ // Fades from 1.0 to 0.0 when less than 0.1
+ float fadeLow = saturate( val * 10.0 );
+
+ // Fades from 1.0 to 0.0 when greater than 0.9
+ float fadeHigh = 1.0 - saturate( (val - 0.9) * 10.0 );
+
+ return fadeLow * fadeHigh;
+}
+
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main( ConnectData IN )
+{
+ Fragout OUT;
+
+ float3 bumpNorm = TORQUE_TEX2D( bumpMap, IN.tex2 ) * 2.0 - 1.0;
+ float2 offset = float2( bumpNorm.x, bumpNorm.y );
+ float4 texIndex = IN.texCoord;
+
+ // The fadeVal is used to "fade" the distortion at the edges of the screen.
+ // This is done so it won't sample the reflection texture out-of-bounds and create artifacts
+ // Note - this can be done more efficiently with a texture lookup
+ float fadeVal = fadeAxis( texIndex.x / texIndex.w ) * fadeAxis( texIndex.y / texIndex.w );
+
+ const float distortion = 0.2;
+ texIndex.xy += offset * distortion * fadeVal;
+
+ float4 reflectColor = TORQUE_TEX2DPROJ( refractMap, texIndex );
+ float4 diffuseColor = TORQUE_TEX2D( texMap, IN.tex2 );
+
+ OUT.col = diffuseColor + reflectColor * diffuseColor.a;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpV.hlsl
new file mode 100644
index 000000000..d45adb574
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/planarReflectBumpV.hlsl
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "shdrConsts.h"
+#include "shaderModel.hlsl"
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct VertData
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float2 texCoord : TEXCOORD0;
+ float2 lmCoord : TEXCOORD1;
+ float3 T : TEXCOORD2;
+ float3 B : TEXCOORD3;
+};
+
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 texCoord : TEXCOORD0;
+ float2 tex2 : TEXCOORD1;
+};
+
+uniform float4x4 modelview;
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertData IN )
+{
+ ConnectData OUT;
+ OUT.hpos = mul(modelview, float4(IN.position,1.0));
+
+ float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ OUT.texCoord = mul( texGenTest, OUT.hpos );
+
+ OUT.tex2 = IN.texCoord;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/planarReflectP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/planarReflectP.hlsl
new file mode 100644
index 000000000..43b420544
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/planarReflectP.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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+#include "shaderModel.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 tex2 : TEXCOORD1;
+};
+
+
+struct Fragout
+{
+ float4 col : TORQUE_TARGET0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(texMap, 0);
+TORQUE_UNIFORM_SAMPLER2D(refractMap, 1);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main( ConnectData IN )
+{
+ Fragout OUT;
+
+ float4 diffuseColor = TORQUE_TEX2D( texMap, IN.texCoord );
+ float4 reflectColor = TORQUE_TEX2DPROJ(refractMap, IN.tex2);
+
+ OUT.col = diffuseColor + reflectColor * diffuseColor.a;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/planarReflectV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/planarReflectV.hlsl
new file mode 100644
index 000000000..1f2ca9d4f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/planarReflectV.hlsl
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "hlslStructs.hlsl"
+#include "shaderModel.hlsl"
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 tex2 : TEXCOORD1;
+};
+
+uniform float4x4 modelview;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertexIn_PNTTTB IN )
+{
+ ConnectData OUT;
+ OUT.hpos = mul(modelview, float4(IN.pos,1.0));
+
+ float4x4 texGenTest = { 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ OUT.texCoord = IN.uv0;
+ OUT.tex2 = mul( texGenTest, OUT.hpos );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/VolFogGlowP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/VolFogGlowP.hlsl
new file mode 100644
index 000000000..c3adb3b55
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/VolFogGlowP.hlsl
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+// http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+#include "./postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+uniform float strength;
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+ float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+ float4 OUT = 0;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w;
+
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ float3 rgb2lum = float3( 0.30, 0.59, 0.11 );
+ OUT.a = dot( OUT.rgb, rgb2lum );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/causticsP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/causticsP.hlsl
new file mode 100644
index 000000000..8c8abd480
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/causticsP.hlsl
@@ -0,0 +1,77 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+#include "../../shaderModelAutoGen.hlsl"
+
+uniform float accumTime;
+uniform float3 eyePosWorld;
+uniform float4 rtParams0;
+uniform float4 waterFogPlane;
+
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(causticsTex0, 1);
+TORQUE_UNIFORM_SAMPLER2D(causticsTex1, 2);
+
+float distanceToPlane(float4 plane, float3 pos)
+{
+ return (plane.x * pos.x + plane.y * pos.y + plane.z * pos.z) + plane.w;
+}
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ //Sample the pre-pass
+ float4 deferred = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 );
+
+ //Get depth
+ float depth = deferred.w;
+ if(depth > 0.9999)
+ return float4(0,0,0,0);
+
+ //Get world position
+ float3 pos = eyePosWorld + IN.wsEyeRay * depth;
+
+ // Check the water depth
+ float waterDepth = -distanceToPlane(waterFogPlane, pos);
+ if(waterDepth < 0)
+ return float4(0,0,0,0);
+ waterDepth = saturate(waterDepth);
+
+ //Use world position X and Y to calculate caustics UV
+ float2 causticsUV0 = (abs(pos.xy * 0.25) % float2(1, 1));
+ float2 causticsUV1 = (abs(pos.xy * 0.2) % float2(1, 1));
+
+ //Animate uvs
+ float timeSin = sin(accumTime);
+ causticsUV0.xy += float2(accumTime*0.1, timeSin*0.2);
+ causticsUV1.xy -= float2(accumTime*0.15, timeSin*0.15);
+
+ //Sample caustics texture
+ float4 caustics = TORQUE_TEX2D(causticsTex0, causticsUV0);
+ caustics *= TORQUE_TEX2D(causticsTex1, causticsUV1);
+
+ //Use normal Z to modulate caustics
+ //float waterDepth = 1 - saturate(pos.z + waterFogPlane.w + 1);
+ caustics *= saturate(deferred.z) * pow(abs(1-depth), 64) * waterDepth;
+
+ return caustics;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/gl/causticsP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/gl/causticsP.glsl
new file mode 100644
index 000000000..d002fd7e1
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/caustics/gl/causticsP.glsl
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+#include "shadergen:/autogenConditioners.h"
+
+uniform vec3 eyePosWorld;
+uniform vec4 rtParams0;
+uniform vec4 waterFogPlane;
+uniform float accumTime;
+
+uniform sampler2D deferredTex;
+uniform sampler2D causticsTex0;
+uniform sampler2D causticsTex1;
+uniform vec2 targetSize;
+
+out vec4 OUT_col;
+
+float distanceToPlane(vec4 plane, vec3 pos)
+{
+ return (plane.x * pos.x + plane.y * pos.y + plane.z * pos.z) + plane.w;
+}
+
+void main()
+{
+ //Sample the pre-pass
+ vec4 deferred = deferredUncondition( deferredTex, IN_uv0 );
+
+ //Get depth
+ float depth = deferred.w;
+ if(depth > 0.9999)
+ {
+ OUT_col = vec4(0,0,0,0);
+ return;
+ }
+
+ //Get world position
+ vec3 pos = eyePosWorld + IN_wsEyeRay * depth;
+
+ // Check the water depth
+ float waterDepth = -distanceToPlane(waterFogPlane, pos);
+ if(waterDepth < 0)
+ {
+ OUT_col = vec4(0,0,0,0);
+ return;
+ }
+ waterDepth = saturate(waterDepth);
+
+ //Use world position X and Y to calculate caustics UV
+ vec2 causticsUV0 = mod(abs(pos.xy * 0.25), vec2(1, 1));
+ vec2 causticsUV1 = mod(abs(pos.xy * 0.2), vec2(1, 1));
+
+ //Animate uvs
+ float timeSin = sin(accumTime);
+ causticsUV0.xy += vec2(accumTime*0.1, timeSin*0.2);
+ causticsUV1.xy -= vec2(accumTime*0.15, timeSin*0.15);
+
+ //Sample caustics texture
+ vec4 caustics = texture(causticsTex0, causticsUV0);
+ caustics *= texture(causticsTex1, causticsUV1);
+
+ //Use normal Z to modulate caustics
+ //float waterDepth = 1 - saturate(pos.z + waterFogPlane.w + 1);
+ caustics *= saturate(deferred.z) * pow(1-depth, 64) * waterDepth;
+
+ OUT_col = caustics;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/chromaticLens.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/chromaticLens.hlsl
new file mode 100644
index 000000000..8fdca72b7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/chromaticLens.hlsl
@@ -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.
+//-----------------------------------------------------------------------------
+
+// Based on 'Cubic Lens Distortion HLSL Shader' by François Tarlier
+// www.francois-tarlier.com/blog/index.php/2009/11/cubic-lens-distortion-shader
+
+#include "./postFx.hlsl"
+#include "./../torque.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+uniform float distCoeff;
+uniform float cubeDistort;
+uniform float3 colorDistort;
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float2 tex = IN.uv0;
+
+ float f = 0;
+ float r2 = (tex.x - 0.5) * (tex.x - 0.5) + (tex.y - 0.5) * (tex.y - 0.5);
+
+ // Only compute the cubic distortion if necessary.
+ if ( cubeDistort == 0.0 )
+ f = 1 + r2 * distCoeff;
+ else
+ f = 1 + r2 * (distCoeff + cubeDistort * sqrt(r2));
+
+ // Distort each color channel seperately to get a chromatic distortion effect.
+ float3 outColor;
+ float3 distort = f.xxx + colorDistort;
+
+ for ( int i=0; i < 3; i++ )
+ {
+ float x = distort[i] * ( tex.x - 0.5 ) + 0.5;
+ float y = distort[i] * ( tex.y - 0.5 ) + 0.5;
+ outColor[i] = TORQUE_TEX2DLOD( backBuffer, float4(x,y,0,0) )[i];
+ }
+
+ return float4( outColor.rgb, 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_P.hlsl
new file mode 100644
index 000000000..2f5835fc2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_P.hlsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+
+// These are set by the game engine.
+TORQUE_UNIFORM_SAMPLER2D(shrunkSampler, 0); // Output of DofDownsample()
+TORQUE_UNIFORM_SAMPLER2D(blurredSampler, 1); // Blurred version of the shrunk sampler
+
+
+// This is the pixel shader function that calculates the actual
+// value used for the near circle of confusion.
+// "texCoords" are 0 at the bottom left pixel and 1 at the top right.
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float3 color;
+ float coc;
+ half4 blurred;
+ half4 shrunk;
+
+ shrunk = half4(TORQUE_TEX2D( shrunkSampler, IN.uv0 ));
+ blurred = half4(TORQUE_TEX2D( blurredSampler, IN.uv1 ));
+ color = shrunk.rgb;
+ //coc = shrunk.a;
+ //coc = blurred.a;
+ //coc = max( blurred.a, shrunk.a );
+ coc = 2 * max( blurred.a, shrunk.a ) - shrunk.a;
+
+
+ //return float4( coc.rrr, 1.0 );
+ //return float4( color, 1.0 );
+ return float4( color, coc );
+ //return float4( 1.0, 0.0, 1.0, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_V.hlsl
new file mode 100644
index 000000000..8131e45cd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_CalcCoC_V.hlsl
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+uniform float4 rtParams0;
+uniform float4 rtParams1;
+uniform float4 rtParams2;
+uniform float4 rtParams3;
+
+PFXVertToPix main( PFXVert IN )
+{
+ PFXVertToPix OUT;
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv;
+ OUT.uv1 = IN.uv;
+ OUT.uv2 = IN.uv;
+ OUT.uv3 = IN.uv;
+ */
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv + rtParams0.xy;
+ OUT.uv1 = IN.uv + rtParams1.xy;
+ OUT.uv2 = IN.uv + rtParams2.xy;
+ OUT.uv3 = IN.uv + rtParams3.xy;
+ */
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv * rtParams0.zw;
+ OUT.uv1 = IN.uv * rtParams1.zw;
+ OUT.uv2 = IN.uv * rtParams2.zw;
+ OUT.uv3 = IN.uv * rtParams3.zw;
+ */
+
+
+ OUT.hpos = float4(IN.pos,1.0);
+ OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 );
+ OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 );
+ OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 );
+
+
+ OUT.wsEyeRay = IN.wsEyeRay;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_P.hlsl
new file mode 100644
index 000000000..907c3d122
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_P.hlsl
@@ -0,0 +1,143 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../shaderModelAutoGen.hlsl"
+
+// These are set by the game engine.
+// The render target size is one-quarter the scene rendering size.
+TORQUE_UNIFORM_SAMPLER2D(colorSampler, 0);
+TORQUE_UNIFORM_SAMPLER2D(depthSampler, 1);
+uniform float2 dofEqWorld;
+uniform float2 targetSize;
+uniform float depthOffset;
+uniform float maxWorldCoC;
+//uniform float2 dofEqWeapon;
+//uniform float2 dofRowDelta; // float2( 0, 0.25 / renderTargetHeight )
+
+struct Pixel
+{
+ float4 position : TORQUE_POSITION;
+ float2 tcColor0 : TEXCOORD0;
+ float2 tcColor1 : TEXCOORD1;
+ float2 tcDepth0 : TEXCOORD2;
+ float2 tcDepth1 : TEXCOORD3;
+ float2 tcDepth2 : TEXCOORD4;
+ float2 tcDepth3 : TEXCOORD5;
+};
+
+half4 main( Pixel IN ) : TORQUE_TARGET0
+{
+ //return float4( 1.0, 0.0, 1.0, 1.0 );
+
+ float2 dofRowDelta = float2( 0, 0.25 / targetSize.y );
+
+ //float2 dofEqWorld = float2( -60, 1.0 );
+
+ half3 color;
+ half maxCoc;
+ float4 depth;
+ half4 viewCoc;
+ half4 sceneCoc;
+ half4 curCoc;
+ half4 coc;
+ float2 rowOfs[4];
+
+ // "rowOfs" reduces how many moves PS2.0 uses to emulate swizzling.
+ rowOfs[0] = 0;
+ rowOfs[1] = dofRowDelta.xy;
+ rowOfs[2] = dofRowDelta.xy * 2;
+ rowOfs[3] = dofRowDelta.xy * 3;
+
+ // Use bilinear filtering to average 4 color samples for free.
+ color = 0;
+ color += half3(TORQUE_TEX2D( colorSampler, IN.tcColor0.xy + rowOfs[0] ).rgb);
+ color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor1.xy + rowOfs[0]).rgb);
+ color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor0.xy + rowOfs[2]).rgb);
+ color += half3(TORQUE_TEX2D(colorSampler, IN.tcColor1.xy + rowOfs[2]).rgb);
+ color /= 4;
+
+ //declare thse here to save doing it in each loop below
+ half4 zero4 = half4(0, 0, 0, 0);
+ coc = zero4;
+ half4 dofEqWorld4X = half4(dofEqWorld.xxxx);
+ half4 dofEqWorld4Y = half4(dofEqWorld.yyyy);
+ half4 maxWorldCoC4 = half4(maxWorldCoC, maxWorldCoC, maxWorldCoC, maxWorldCoC);
+ // Process 4 samples at a time to use vector hardware efficiently.
+ // The CoC will be 1 if the depth is negative, so use "min" to pick
+ // between "sceneCoc" and "viewCoc".
+ [unroll] // coc[i] causes this anyway
+ for (int i = 0; i < 4; i++)
+ {
+ depth[0] = TORQUE_DEFERRED_UNCONDITION(depthSampler, (IN.tcDepth0.xy + rowOfs[i])).w;
+ depth[1] = TORQUE_DEFERRED_UNCONDITION(depthSampler, (IN.tcDepth1.xy + rowOfs[i])).w;
+ depth[2] = TORQUE_DEFERRED_UNCONDITION(depthSampler, (IN.tcDepth2.xy + rowOfs[i])).w;
+ depth[3] = TORQUE_DEFERRED_UNCONDITION(depthSampler, (IN.tcDepth3.xy + rowOfs[i])).w;
+
+ coc = max(coc, clamp(dofEqWorld4X * half4(depth)+dofEqWorld4Y, zero4, maxWorldCoC4));
+ }
+
+ /*
+ depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[0] ).r;
+ depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[0] ).r;
+ depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[0] ).r;
+ depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[0] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = curCoc;
+
+ depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[1] ).r;
+ depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[1] ).r;
+ depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[1] ).r;
+ depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[1] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+
+ depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[2] ).r;
+ depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[2] ).r;
+ depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[2] ).r;
+ depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[2] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+
+ depth[0] = TORQUE_TEX2D( depthSampler, pixel.tcDepth0.xy + rowOfs[3] ).r;
+ depth[1] = TORQUE_TEX2D( depthSampler, pixel.tcDepth1.xy + rowOfs[3] ).r;
+ depth[2] = TORQUE_TEX2D( depthSampler, pixel.tcDepth2.xy + rowOfs[3] ).r;
+ depth[3] = TORQUE_TEX2D( depthSampler, pixel.tcDepth3.xy + rowOfs[3] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+ */
+
+ maxCoc = max( max( coc[0], coc[1] ), max( coc[2], coc[3] ) );
+
+ //return half4( 1.0, 0.0, 1.0, 1.0 );
+ return half4( color, maxCoc );
+ //return half4( color, 1.0f );
+ //return half4( maxCoc.rrr, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_V.hlsl
new file mode 100644
index 000000000..0b3ec01e2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_DownSample_V.hlsl
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+struct Vert
+{
+ float3 pos : POSITION;
+ float2 tc : TEXCOORD0;
+ float3 wsEyeRay : TEXCOORD1;
+};
+
+struct Pixel
+{
+ float4 position : TORQUE_POSITION;
+ float2 tcColor0 : TEXCOORD0;
+ float2 tcColor1 : TEXCOORD1;
+ float2 tcDepth0 : TEXCOORD2;
+ float2 tcDepth1 : TEXCOORD3;
+ float2 tcDepth2 : TEXCOORD4;
+ float2 tcDepth3 : TEXCOORD5;
+};
+
+uniform float4 rtParams0;
+uniform float2 oneOverTargetSize;
+
+Pixel main( Vert IN )
+{
+ Pixel OUT;
+ OUT.position = float4(IN.pos,1.0);
+
+ float2 uv = viewportCoordToRenderTarget( IN.tc, rtParams0 );
+ //OUT.position = mul( IN.pos, modelView );
+ OUT.tcColor1 = uv + float2( +1.0, -0.0 ) * oneOverTargetSize;
+ OUT.tcColor0 = uv + float2( -1.0, -0.0 ) * oneOverTargetSize;
+ OUT.tcDepth0 = uv + float2( -0.5, -0.0 ) * oneOverTargetSize;
+ OUT.tcDepth1 = uv + float2( -1.5, -0.0 ) * oneOverTargetSize;
+ OUT.tcDepth2 = uv + float2( +1.5, -0.0 ) * oneOverTargetSize;
+ OUT.tcDepth3 = uv + float2( +2.5, -0.0 ) * oneOverTargetSize;
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_P.hlsl
new file mode 100644
index 000000000..9a7cb3d5e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_P.hlsl
@@ -0,0 +1,145 @@
+//-----------------------------------------------------------------------------
+// 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 "../../shaderModelAutoGen.hlsl"
+#include "./../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(colorSampler,0); // Original source image
+TORQUE_UNIFORM_SAMPLER2D(smallBlurSampler,1); // Output of SmallBlurPS()
+TORQUE_UNIFORM_SAMPLER2D(largeBlurSampler,2); // Blurred output of DofDownsample()
+TORQUE_UNIFORM_SAMPLER2D(depthSampler,3);
+
+uniform float2 oneOverTargetSize;
+uniform float4 dofLerpScale;
+uniform float4 dofLerpBias;
+uniform float3 dofEqFar;
+uniform float maxFarCoC;
+
+//static float d0 = 0.1;
+//static float d1 = 0.1;
+//static float d2 = 0.8;
+//static float4 dofLerpScale = float4( -1.0 / d0, -1.0 / d1, -1.0 / d2, 1.0 / d2 );
+//static float4 dofLerpBias = float4( 1.0, (1.0 - d2) / d1, 1.0 / d2, (d2 - 1.0) / d2 );
+//static float3 dofEqFar = float3( 2.0, 0.0, 1.0 );
+
+float4 tex2Doffset(TORQUE_SAMPLER2D(s), float2 tc, float2 offset)
+{
+ return TORQUE_TEX2D( s, tc + offset * oneOverTargetSize );
+}
+
+half3 GetSmallBlurSample( float2 tc )
+{
+ half3 sum;
+ const half weight = 4.0 / 17;
+ sum = 0; // Unblurred sample done by alpha blending
+ //sum += weight * tex2Doffset( colorSampler, tc, float2( 0, 0 ) ).rgb;
+ sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(+0.5, -1.5)).rgb);
+ sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(-1.5, -0.5)).rgb);
+ sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(-0.5, +1.5)).rgb);
+ sum += weight * half3(tex2Doffset(TORQUE_SAMPLER2D_MAKEARG(colorSampler), tc, float2(+1.5, +0.5)).rgb);
+ return sum;
+}
+
+half4 InterpolateDof( half3 small, half3 med, half3 large, half t )
+{
+ //t = 2;
+ half4 weights;
+ half3 color;
+ half alpha;
+
+ // Efficiently calculate the cross-blend weights for each sample.
+ // Let the unblurred sample to small blur fade happen over distance
+ // d0, the small to medium blur over distance d1, and the medium to
+ // large blur over distance d2, where d0 + d1 + d2 = 1.
+ //float4 dofLerpScale = float4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 );
+ //float4 dofLerpBias = float4( 1, (1 � d2) / d1, 1 / d2, (d2 � 1) / d2 );
+
+ weights = half4(saturate( t * dofLerpScale + dofLerpBias ));
+ weights.yz = min( weights.yz, 1 - weights.xy );
+
+ // Unblurred sample with weight "weights.x" done by alpha blending
+ color = weights.y * small + weights.z * med + weights.w * large;
+ //color = med;
+ alpha = dot( weights.yzw, half3( 16.0 / 17, 1.0, 1.0 ) );
+ //alpha = 0.0;
+
+ return half4( color, alpha );
+}
+
+half4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ //return half4( 1,0,1,1 );
+ //return half4( TORQUE_TEX2D( colorSampler, IN.uv0 ).rgb, 1.0 );
+ //return half4( TORQUE_TEX2D( colorSampler, texCoords ).rgb, 0 );
+ half3 small;
+ half4 med;
+ half3 large;
+ half depth;
+ half nearCoc;
+ half farCoc;
+ half coc;
+
+ small = GetSmallBlurSample( IN.uv0 );
+ //small = half3( 1,0,0 );
+ //return half4( small, 1.0 );
+ med = half4(TORQUE_TEX2D( smallBlurSampler, IN.uv1 ));
+ //med.rgb = half3( 0,1,0 );
+ //return half4(med.rgb, 0.0);
+ large = half3(TORQUE_TEX2D(largeBlurSampler, IN.uv2).rgb);
+ //large = half3( 0,0,1 );
+ //return large;
+ //return half4(large.rgb,1.0);
+ nearCoc = med.a;
+
+ // Since the med blur texture is screwed up currently
+ // replace it with the large, but this needs to be fixed.
+ //med.rgb = large;
+
+ //nearCoc = 0;
+ depth = half(TORQUE_DEFERRED_UNCONDITION( depthSampler, IN.uv3 ).w);
+ //return half4(depth.rrr,1);
+ //return half4(nearCoc.rrr,1.0);
+
+ if (depth > 0.999 )
+ {
+ coc = nearCoc; // We don't want to blur the sky.
+ //coc = 0;
+ }
+ else
+ {
+ // dofEqFar.x and dofEqFar.y specify the linear ramp to convert
+ // to depth for the distant out-of-focus region.
+ // dofEqFar.z is the ratio of the far to the near blur radius.
+ farCoc = half(clamp( dofEqFar.x * depth + dofEqFar.y, 0.0, maxFarCoC ));
+ coc = half(max( nearCoc, farCoc * dofEqFar.z ));
+ //coc = nearCoc;
+ }
+
+ //coc = nearCoc;
+ //coc = farCoc;
+ //return half4(coc.rrr,0.5);
+ //return half4(farCoc.rrr,1);
+ //return half4(nearCoc.rrr,1);
+
+ //return half4( 1,0,1,0 );
+ return InterpolateDof( small, med.rgb, large, coc );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_V.hlsl
new file mode 100644
index 000000000..86c93701a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Final_V.hlsl
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+uniform float4 rtParams0;
+uniform float4 rtParams1;
+uniform float4 rtParams2;
+uniform float4 rtParams3;
+uniform float2 oneOverTargetSize;
+
+PFXVertToPix main( PFXVert IN )
+{
+ PFXVertToPix OUT;
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv;
+ OUT.uv1 = IN.uv;
+ OUT.uv2 = IN.uv;
+ OUT.uv3 = IN.uv;
+ */
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv + rtParams0.xy;
+ OUT.uv1 = IN.uv + rtParams1.xy;
+ OUT.uv2 = IN.uv + rtParams2.xy;
+ OUT.uv3 = IN.uv + rtParams3.xy;
+ */
+
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv * rtParams0.zw;
+ OUT.uv1 = IN.uv * rtParams1.zw;
+ OUT.uv2 = IN.uv * rtParams2.zw;
+ OUT.uv3 = IN.uv * rtParams3.zw;
+ */
+
+
+ OUT.hpos = float4(IN.pos,1.0);
+ OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 ); // + float2( -5, 1 ) * oneOverTargetSize;
+ OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 );
+ OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 );
+
+
+ OUT.wsEyeRay = IN.wsEyeRay;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_P.hlsl
new file mode 100644
index 000000000..f4d29f3e1
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_P.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 "./../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+ float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5 / 1.3; //25f;
+
+ float4 OUT = 0;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w;
+
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ //float3 rgb2lum = float3( 0.30, 0.59, 0.11 );
+ //OUT.a = dot( OUT.rgb, rgb2lum );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_V.hlsl
new file mode 100644
index 000000000..b2d4582e0
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Gausian_V.hlsl
@@ -0,0 +1,80 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+
+uniform float4 rtParams0;
+uniform float2 texSize0;
+uniform float2 oneOverTargetSize;
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+VertToPix main( PFXVert IN )
+{
+ VertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1.0);
+
+ IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+
+ // I don't know why this offset is necessary, but it is.
+ //IN.uv = IN.uv * oneOverTargetSize;
+
+ OUT.uv0 = IN.uv + ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT.uv1 = IN.uv + ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT.uv2 = IN.uv + ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT.uv3 = IN.uv + ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ OUT.uv4 = IN.uv - ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT.uv5 = IN.uv - ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT.uv6 = IN.uv - ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT.uv7 = IN.uv - ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ /*
+ OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 );
+ OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 );
+ OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 );
+
+ OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 );
+ OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 );
+ OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 );
+ OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 );
+ */
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Passthrough_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Passthrough_V.hlsl
new file mode 100644
index 000000000..8131e45cd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_Passthrough_V.hlsl
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+uniform float4 rtParams0;
+uniform float4 rtParams1;
+uniform float4 rtParams2;
+uniform float4 rtParams3;
+
+PFXVertToPix main( PFXVert IN )
+{
+ PFXVertToPix OUT;
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv;
+ OUT.uv1 = IN.uv;
+ OUT.uv2 = IN.uv;
+ OUT.uv3 = IN.uv;
+ */
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv + rtParams0.xy;
+ OUT.uv1 = IN.uv + rtParams1.xy;
+ OUT.uv2 = IN.uv + rtParams2.xy;
+ OUT.uv3 = IN.uv + rtParams3.xy;
+ */
+
+ /*
+ OUT.hpos = IN.pos;
+ OUT.uv0 = IN.uv * rtParams0.zw;
+ OUT.uv1 = IN.uv * rtParams1.zw;
+ OUT.uv2 = IN.uv * rtParams2.zw;
+ OUT.uv3 = IN.uv * rtParams3.zw;
+ */
+
+
+ OUT.hpos = float4(IN.pos,1.0);
+ OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 );
+ OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 );
+ OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 );
+
+
+ OUT.wsEyeRay = IN.wsEyeRay;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_P.hlsl
new file mode 100644
index 000000000..175525a91
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_P.hlsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// This vertex and pixel shader applies a 3 x 3 blur to the image in
+// colorMapSampler, which is the same size as the render target.
+// The sample weights are 1/16 in the corners, 2/16 on the edges,
+// and 4/16 in the center.
+#include "../../shaderModel.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(colorSampler, 0); // Output of DofNearCoc()
+
+struct Pixel
+{
+ float4 position : TORQUE_POSITION;
+ float4 texCoords : TEXCOORD0;
+};
+
+float4 main( Pixel IN ) : TORQUE_TARGET0
+{
+ float4 color;
+ color = 0.0;
+ color += TORQUE_TEX2D( colorSampler, IN.texCoords.xz );
+ color += TORQUE_TEX2D( colorSampler, IN.texCoords.yz );
+ color += TORQUE_TEX2D( colorSampler, IN.texCoords.xw );
+ color += TORQUE_TEX2D( colorSampler, IN.texCoords.yw );
+ return color / 4.0;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_V.hlsl
new file mode 100644
index 000000000..3edb1ec2a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/DOF_SmallBlur_V.hlsl
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// This vertex and pixel shader applies a 3 x 3 blur to the image in
+// colorMapSampler, which is the same size as the render target.
+// The sample weights are 1/16 in the corners, 2/16 on the edges,
+// and 4/16 in the center.
+
+#include "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+struct Vert
+{
+ float3 position : POSITION;
+ float2 texCoords : TEXCOORD0;
+};
+
+struct Pixel
+{
+ float4 position : TORQUE_POSITION;
+ float4 texCoords : TEXCOORD0;
+};
+
+uniform float2 oneOverTargetSize;
+uniform float4 rtParams0;
+
+Pixel main( Vert IN )
+{
+ Pixel OUT;
+ const float4 halfPixel = { -0.5, 0.5, -0.5, 0.5 };
+ OUT.position = float4(IN.position,1.0); //Transform_ObjectToClip( IN.position );
+
+ //float2 uv = IN.texCoords + rtParams0.xy;
+ float2 uv = viewportCoordToRenderTarget( IN.texCoords, rtParams0 );
+ OUT.texCoords = uv.xxyy + halfPixel * oneOverTargetSize.xxyy;
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_P.glsl
new file mode 100644
index 000000000..38cb099c4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_P.glsl
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+// These are set by the game engine.
+uniform sampler2D shrunkSampler; // Output of DofDownsample()
+uniform sampler2D blurredSampler; // Blurred version of the shrunk sampler
+
+out vec4 OUT_col;
+
+// This is the pixel shader function that calculates the actual
+// value used for the near circle of confusion.
+// "texCoords" are 0 at the bottom left pixel and 1 at the top right.
+void main()
+{
+ vec3 color;
+ float coc;
+ half4 blurred;
+ half4 shrunk;
+
+ shrunk = texture( shrunkSampler, IN_uv0 );
+ blurred = texture( blurredSampler, IN_uv1 );
+ color = shrunk.rgb;
+ //coc = shrunk.a;
+ //coc = blurred.a;
+ //coc = max( blurred.a, shrunk.a );
+ coc = 2 * max( blurred.a, shrunk.a ) - shrunk.a;
+
+
+ //OUT_col = vec4( coc.rrr, 1.0 );
+ //OUT_col = vec4( color, 1.0 );
+ OUT_col = vec4( color, coc );
+ //OUT_col = vec4( 1.0, 0.0, 1.0, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_V.glsl
new file mode 100644
index 000000000..d02ce6551
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_CalcCoC_V.glsl
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+#include "../../gl/postFX.glsl"
+
+uniform vec4 rtParams0;
+uniform vec4 rtParams1;
+uniform vec4 rtParams2;
+uniform vec4 rtParams3;
+
+void main()
+{
+ /*
+ OUT_hpos = IN.pos;
+ OUT_uv0 = IN_uv;
+ OUT_uv1 = IN_uv;
+ OUT_uv2 = IN_uv;
+ OUT_uv3 = IN_uv;
+ */
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv + rtParams0.xy;
+ OUT_uv1 = IN_uv + rtParams1.xy;
+ OUT_uv2 = IN_uv + rtParams2.xy;
+ OUT_uv3 = IN_uv + rtParams3.xy;
+ */
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv * rtParams0.zw;
+ OUT_uv1 = IN_uv * rtParams1.zw;
+ OUT_uv2 = IN_uv * rtParams2.zw;
+ OUT_uv3 = IN_uv * rtParams3.zw;
+ */
+
+
+ OUT_hpos = IN_pos;
+ OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 );
+ OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 );
+ OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 );
+
+
+ OUT_wsEyeRay = IN_wsEyeRay;
+
+ correctSSP(gl_Position);;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_P.glsl
new file mode 100644
index 000000000..f3c093f31
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_P.glsl
@@ -0,0 +1,143 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+// These are set by the game engine.
+// The render target size is one-quarter the scene rendering size.
+uniform sampler2D colorSampler;
+uniform sampler2D depthSampler;
+uniform vec2 dofEqWorld;
+uniform float depthOffset;
+uniform vec2 targetSize;
+uniform float maxWorldCoC;
+//uniform vec2 dofEqWeapon;
+//uniform vec2 dofRowDelta; // vec2( 0, 0.25 / renderTargetHeight )
+
+in vec2 tcColor0;
+#define IN_tcColor0 tcColor0
+in vec2 tcColor1;
+#define IN_tcColor1 tcColor1
+in vec2 tcDepth0;
+#define IN_tcDepth0 tcDepth0
+in vec2 tcDepth1;
+#define IN_tcDepth1 tcDepth1
+in vec2 tcDepth2;
+#define IN_tcDepth2 tcDepth2
+in vec2 tcDepth3;
+#define IN_tcDepth3 tcDepth3
+
+out vec4 OUT_col;
+
+void main()
+{
+ //return vec4( 1.0, 0.0, 1.0, 1.0 );
+
+ vec2 dofRowDelta = vec2( 0, 0.25 / targetSize.y );
+
+ //vec2 dofEqWorld = vec2( -60, 1.0 );
+
+ half3 color;
+ half maxCoc;
+ vec4 depth;
+ half4 viewCoc;
+ half4 sceneCoc;
+ half4 curCoc;
+ half4 coc;
+ vec2 rowOfs[4];
+
+ // "rowOfs" reduces how many moves PS2.0 uses to emulate swizzling.
+ rowOfs[0] = vec2(0);
+ rowOfs[1] = dofRowDelta.xy;
+ rowOfs[2] = dofRowDelta.xy * 2;
+ rowOfs[3] = dofRowDelta.xy * 3;
+
+ // Use bilinear filtering to average 4 color samples for free.
+ color = half3(0);
+ color += texture( colorSampler, IN_tcColor0.xy + rowOfs[0] ).rgb;
+ color += texture( colorSampler, IN_tcColor1.xy + rowOfs[0] ).rgb;
+ color += texture( colorSampler, IN_tcColor0.xy + rowOfs[2] ).rgb;
+ color += texture( colorSampler, IN_tcColor1.xy + rowOfs[2] ).rgb;
+ color /= 4;
+
+ // Process 4 samples at a time to use vector hardware efficiently.
+ // The CoC will be 1 if the depth is negative, so use "min" to pick
+ // between "sceneCoc" and "viewCoc".
+
+ coc = half4(0);
+ for ( int i = 0; i < 4; i++ )
+ {
+ depth[0] = deferredUncondition( depthSampler, ( IN_tcDepth0.xy + rowOfs[i] ) ).w;
+ depth[1] = deferredUncondition( depthSampler, ( IN_tcDepth1.xy + rowOfs[i] ) ).w;
+ depth[2] = deferredUncondition( depthSampler, ( IN_tcDepth2.xy + rowOfs[i] ) ).w;
+ depth[3] = deferredUncondition( depthSampler, ( IN_tcDepth3.xy + rowOfs[i] ) ).w;
+
+ // @todo OPENGL INTEL need review
+ coc = max( coc, clamp( half4(dofEqWorld.x) * depth + half4(dofEqWorld.y), half4(0.0), half4(maxWorldCoC) ) );
+ }
+
+ /*
+ depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[0] ).r;
+ depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[0] ).r;
+ depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[0] ).r;
+ depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[0] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = curCoc;
+
+ depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[1] ).r;
+ depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[1] ).r;
+ depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[1] ).r;
+ depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[1] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+
+ depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[2] ).r;
+ depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[2] ).r;
+ depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[2] ).r;
+ depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[2] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+
+ depth[0] = texture( depthSampler, pixel.tcDepth0.xy + rowOfs[3] ).r;
+ depth[1] = texture( depthSampler, pixel.tcDepth1.xy + rowOfs[3] ).r;
+ depth[2] = texture( depthSampler, pixel.tcDepth2.xy + rowOfs[3] ).r;
+ depth[3] = texture( depthSampler, pixel.tcDepth3.xy + rowOfs[3] ).r;
+ viewCoc = saturate( dofEqWeapon.x * -depth + dofEqWeapon.y );
+ sceneCoc = saturate( dofEqWorld.x * depth + dofEqWorld.y );
+ curCoc = min( viewCoc, sceneCoc );
+ coc = max( coc, curCoc );
+ */
+
+ maxCoc = max( max( coc[0], coc[1] ), max( coc[2], coc[3] ) );
+
+ //OUT_col = half4( 1.0, 0.0, 1.0, 1.0 );
+ OUT_col = half4( color, maxCoc );
+ //OUT_col = half4( color, 1.0f );
+ //OUT_col = half4( maxCoc.rrr, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_V.glsl
new file mode 100644
index 000000000..b8e840c9e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_DownSample_V.glsl
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+in vec3 vTexCoord1;
+
+#define IN_pos vPosition
+#define IN_tc vTexCoord0
+#define IN_wsEyeRay vTexCoord1
+
+#define OUT_position gl_Position
+
+out vec2 tcColor0;
+#define OUT_tcColor0 tcColor0
+out vec2 tcColor1;
+#define OUT_tcColor1 tcColor1
+out vec2 tcDepth0;
+#define OUT_tcDepth0 tcDepth0
+out vec2 tcDepth1;
+#define OUT_tcDepth1 tcDepth1
+out vec2 tcDepth2;
+#define OUT_tcDepth2 tcDepth2
+out vec2 tcDepth3;
+#define OUT_tcDepth3 tcDepth3
+
+
+uniform vec4 rtParams0;
+uniform vec2 oneOverTargetSize;
+
+void main()
+{
+ OUT_position = IN_pos;
+
+ vec2 uv = viewportCoordToRenderTarget( IN_tc, rtParams0 );
+ //OUT_position = tMul( IN_pos, modelView );
+ OUT_tcColor1 = uv + vec2( +1.0, -0.0 ) * oneOverTargetSize;
+ OUT_tcColor0 = uv + vec2( -1.0, -0.0 ) * oneOverTargetSize;
+ OUT_tcDepth0 = uv + vec2( -0.5, -0.0 ) * oneOverTargetSize;
+ OUT_tcDepth1 = uv + vec2( -1.5, -0.0 ) * oneOverTargetSize;
+ OUT_tcDepth2 = uv + vec2( +1.5, -0.0 ) * oneOverTargetSize;
+ OUT_tcDepth3 = uv + vec2( +2.5, -0.0 ) * oneOverTargetSize;
+
+ correctSSP(gl_Position);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_P.glsl
new file mode 100644
index 000000000..9b976ba1e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_P.glsl
@@ -0,0 +1,147 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D colorSampler; // Original source image
+uniform sampler2D smallBlurSampler; // Output of SmallBlurPS()
+uniform sampler2D largeBlurSampler; // Blurred output of DofDownsample()
+uniform sampler2D depthSampler; //
+uniform vec2 oneOverTargetSize;
+uniform vec4 dofLerpScale;
+uniform vec4 dofLerpBias;
+uniform vec3 dofEqFar;
+uniform float maxFarCoC;
+
+//static float d0 = 0.1;
+//static float d1 = 0.1;
+//static float d2 = 0.8;
+//static vec4 dofLerpScale = vec4( -1.0 / d0, -1.0 / d1, -1.0 / d2, 1.0 / d2 );
+//static vec4 dofLerpBias = vec4( 1.0, (1.0 - d2) / d1, 1.0 / d2, (d2 - 1.0) / d2 );
+//static vec3 dofEqFar = vec3( 2.0, 0.0, 1.0 );
+
+out vec4 OUT_col;
+
+vec4 tex2Doffset( sampler2D s, vec2 tc, vec2 offset )
+{
+ return texture( s, tc + offset * oneOverTargetSize );
+}
+
+half3 GetSmallBlurSample( vec2 tc )
+{
+ half3 sum;
+ const half weight = 4.0 / 17;
+ sum = half3(0); // Unblurred sample done by alpha blending
+ //sum += weight * tex2Doffset( colorSampler, tc, vec2( 0, 0 ) ).rgb;
+ sum += weight * tex2Doffset( colorSampler, tc, vec2( +0.5, -1.5 ) ).rgb;
+ sum += weight * tex2Doffset( colorSampler, tc, vec2( -1.5, -0.5 ) ).rgb;
+ sum += weight * tex2Doffset( colorSampler, tc, vec2( -0.5, +1.5 ) ).rgb;
+ sum += weight * tex2Doffset( colorSampler, tc, vec2( +1.5, +0.5 ) ).rgb;
+ return sum;
+}
+
+half4 InterpolateDof( half3 small, half3 med, half3 large, half t )
+{
+ //t = 2;
+ half4 weights;
+ half3 color;
+ half alpha;
+
+ // Efficiently calculate the cross-blend weights for each sample.
+ // Let the unblurred sample to small blur fade happen over distance
+ // d0, the small to medium blur over distance d1, and the medium to
+ // large blur over distance d2, where d0 + d1 + d2 = 1.
+ //vec4 dofLerpScale = vec4( -1 / d0, -1 / d1, -1 / d2, 1 / d2 );
+ //vec4 dofLerpBias = vec4( 1, (1 – d2) / d1, 1 / d2, (d2 – 1) / d2 );
+
+ weights = saturate( t * dofLerpScale + dofLerpBias );
+ weights.yz = min( weights.yz, 1 - weights.xy );
+
+ // Unblurred sample with weight "weights.x" done by alpha blending
+ color = weights.y * small + weights.z * med + weights.w * large;
+ //color = med;
+ alpha = dot( weights.yzw, half3( 16.0 / 17, 1.0, 1.0 ) );
+ //alpha = 0.0;
+
+ return half4( color, alpha );
+}
+
+void main()
+{
+ //return half4( 1,0,1,1 );
+ //return half4( texture( colorSampler, IN_uv0 ).rgb, 1.0 );
+ //return half4( texture( colorSampler, texCoords ).rgb, 0 );
+ half3 small;
+ half4 med;
+ half3 large;
+ half depth;
+ half nearCoc;
+ half farCoc;
+ half coc;
+
+ small = GetSmallBlurSample( IN_uv0 );
+ //small = half3( 1,0,0 );
+ //return half4( small, 1.0 );
+ med = texture( smallBlurSampler, IN_uv1 );
+ //med.rgb = half3( 0,1,0 );
+ //return half4(med.rgb, 0.0);
+ large = texture( largeBlurSampler, IN_uv2 ).rgb;
+ //large = half3( 0,0,1 );
+ //return large;
+ //return half4(large.rgb,1.0);
+ nearCoc = med.a;
+
+ // Since the med blur texture is screwed up currently
+ // replace it with the large, but this needs to be fixed.
+ //med.rgb = large;
+
+ //nearCoc = 0;
+ depth = deferredUncondition( depthSampler, IN_uv3 ).w;
+ //return half4(depth.rrr,1);
+ //return half4(nearCoc.rrr,1.0);
+
+ if (depth > 0.999 )
+ {
+ coc = nearCoc; // We don't want to blur the sky.
+ //coc = 0;
+ }
+ else
+ {
+ // dofEqFar.x and dofEqFar.y specify the linear ramp to convert
+ // to depth for the distant out-of-focus region.
+ // dofEqFar.z is the ratio of the far to the near blur radius.
+ farCoc = clamp( dofEqFar.x * depth + dofEqFar.y, 0.0, maxFarCoC );
+ coc = max( nearCoc, farCoc * dofEqFar.z );
+ //coc = nearCoc;
+ }
+
+ //coc = nearCoc;
+ //coc = farCoc;
+ //return half4(coc.rrr,0.5);
+ //return half4(farCoc.rrr,1);
+ //return half4(nearCoc.rrr,1);
+
+ //return half4( 1,0,1,0 );
+ OUT_col = InterpolateDof( small, med.rgb, large, coc );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_V.glsl
new file mode 100644
index 000000000..abc91246e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Final_V.glsl
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+#include "../../gl/postFX.glsl"
+
+uniform vec4 rtParams0;
+uniform vec4 rtParams1;
+uniform vec4 rtParams2;
+uniform vec4 rtParams3;
+uniform vec2 oneOverTargetSize;
+
+void main()
+{
+ /*
+ OUT.hpos = IN_pos;
+ OUT_uv0 = IN_uv;
+ OUT_uv1 = IN_uv;
+ OUT_uv2 = IN_uv;
+ OUT_uv3 = IN_uv;
+ */
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv + rtParams0.xy;
+ OUT_uv1 = IN_uv + rtParams1.xy;
+ OUT_uv2 = IN_uv + rtParams2.xy;
+ OUT_uv3 = IN_uv + rtParams3.xy;
+ */
+
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv * rtParams0.zw;
+ OUT_uv1 = IN_uv * rtParams1.zw;
+ OUT_uv2 = IN_uv * rtParams2.zw;
+ OUT_uv3 = IN_uv * rtParams3.zw;
+ */
+
+
+ OUT_hpos = IN_pos;
+ OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 ); // + vec2( -5, 1 ) * oneOverTargetSize;
+ OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 );
+ OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 );
+
+
+ OUT_wsEyeRay = IN_wsEyeRay;
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_P.glsl
new file mode 100644
index 000000000..61e7697af
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_P.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"
+
+in vec3 wsEyeRay;
+#define IN_wsEyeRay wsEyeRay
+in vec2 uv0;
+#define IN_uv0 uv0
+in vec2 uv1;
+#define IN_uv1 uv1
+in vec2 uv2;
+#define IN_uv2 uv2
+in vec2 uv3;
+#define IN_uv3 uv3
+in vec2 uv4;
+#define IN_uv4 uv4
+in vec2 uv5;
+#define IN_uv5 uv5
+in vec2 uv6;
+#define IN_uv6 uv6
+in vec2 uv7;
+#define IN_uv7 uv7
+
+out vec4 OUT_col;
+
+uniform sampler2D diffuseMap;
+
+void main()
+{
+ vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * 0.5 / 1.3; //25f;
+
+ OUT_col = vec4(0);
+ OUT_col += texture( diffuseMap, IN_uv0 ) * kernel.x;
+ OUT_col += texture( diffuseMap, IN_uv1 ) * kernel.y;
+ OUT_col += texture( diffuseMap, IN_uv2 ) * kernel.z;
+ OUT_col += texture( diffuseMap, IN_uv3 ) * kernel.w;
+
+ OUT_col += texture( diffuseMap, IN_uv4 ) * kernel.x;
+ OUT_col += texture( diffuseMap, IN_uv5 ) * kernel.y;
+ OUT_col += texture( diffuseMap, IN_uv6 ) * kernel.z;
+ OUT_col += texture( diffuseMap, IN_uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ //vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 );
+ //OUT_col.a = dot( OUT_col.rgb, rgb2lum );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_V.glsl
new file mode 100644
index 000000000..c77e23c53
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Gausian_V.glsl
@@ -0,0 +1,91 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+in vec3 vTexCoord1;
+
+#define IN_pos vPosition
+#define _IN_uv vTexCoord0
+#define IN_wsEyeRay vTexCoord1
+
+#define OUT_hpos gl_Position
+out vec3 wsEyeRay;
+#define OUT_wsEyeRay wsEyeRay
+out vec2 uv0;
+#define OUT_uv0 uv0
+out vec2 uv1;
+#define OUT_uv1 uv1
+out vec2 uv2;
+#define OUT_uv2 uv2
+out vec2 uv3;
+#define OUT_uv3 uv3
+out vec2 uv4;
+#define OUT_uv4 uv4
+out vec2 uv5;
+#define OUT_uv5 uv5
+out vec2 uv6;
+#define OUT_uv6 uv6
+out vec2 uv7;
+#define OUT_uv7 uv7
+
+uniform vec2 texSize0;
+uniform vec4 rtParams0;
+uniform vec2 oneOverTargetSize;
+
+
+void main()
+{
+ OUT_hpos = IN_pos;
+
+ vec2 IN_uv = viewportCoordToRenderTarget( _IN_uv, rtParams0 );
+
+ // I don't know why this offset is necessary, but it is.
+ //IN_uv = IN_uv * oneOverTargetSize;
+
+ OUT_uv0 = IN_uv + ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT_uv1 = IN_uv + ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT_uv2 = IN_uv + ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT_uv3 = IN_uv + ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ OUT_uv4 = IN_uv - ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT_uv5 = IN_uv - ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT_uv6 = IN_uv - ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT_uv7 = IN_uv - ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ /*
+ OUT_uv0 = viewportCoordToRenderTarget( OUT_uv0, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( OUT_uv1, rtParams0 );
+ OUT_uv2 = viewportCoordToRenderTarget( OUT_uv2, rtParams0 );
+ OUT_uv3 = viewportCoordToRenderTarget( OUT_uv3, rtParams0 );
+
+ OUT_uv4 = viewportCoordToRenderTarget( OUT_uv4, rtParams0 );
+ OUT_uv5 = viewportCoordToRenderTarget( OUT_uv5, rtParams0 );
+ OUT_uv6 = viewportCoordToRenderTarget( OUT_uv6, rtParams0 );
+ OUT_uv7 = viewportCoordToRenderTarget( OUT_uv7, rtParams0 );
+ */
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Passthrough_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Passthrough_V.glsl
new file mode 100644
index 000000000..bd02fb7d4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_Passthrough_V.glsl
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+#include "../../gl/postFX.glsl"
+
+uniform vec4 rtParams0;
+uniform vec4 rtParams1;
+uniform vec4 rtParams2;
+uniform vec4 rtParams3;
+
+void main()
+{
+ /*
+ OUT.hpos = IN_pos;
+ OUT_uv0 = IN_uv;
+ OUT_uv1 = IN_uv;
+ OUT_uv2 = IN_uv;
+ OUT_uv3 = IN_uv;
+ */
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv + rtParams0.xy;
+ OUT_uv1 = IN_uv + rtParams1.xy;
+ OUT_uv2 = IN_uv + rtParams2.xy;
+ OUT_uv3 = IN_uv + rtParams3.xy;
+ */
+
+ /*
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv * rtParams0.zw;
+ OUT_uv1 = IN_uv * rtParams1.zw;
+ OUT_uv2 = IN_uv * rtParams2.zw;
+ OUT_uv3 = IN_uv * rtParams3.zw;
+ */
+
+
+ OUT_hpos = IN_pos;
+ OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 );
+ OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 );
+ OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 );
+
+
+ OUT_wsEyeRay = IN_wsEyeRay;
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_P.glsl
new file mode 100644
index 000000000..ae94edd78
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_P.glsl
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// This vertex and pixel shader applies a 3 x 3 blur to the image in
+// colorMapSampler, which is the same size as the render target.
+// The sample weights are 1/16 in the corners, 2/16 on the edges,
+// and 4/16 in the center.
+
+#include "../../../gl/hlslCompat.glsl"
+
+uniform sampler2D colorSampler; // Output of DofNearCoc()
+
+in vec4 texCoords;
+#define IN_texCoords texCoords
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 color;
+ color = vec4(0.0);
+ color += texture( colorSampler, IN_texCoords.xz );
+ color += texture( colorSampler, IN_texCoords.yz );
+ color += texture( colorSampler, IN_texCoords.xw );
+ color += texture( colorSampler, IN_texCoords.yw );
+ OUT_col = color / 4.0;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_V.glsl
new file mode 100644
index 000000000..413abd352
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/dof/gl/DOF_SmallBlur_V.glsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// This vertex and pixel shader applies a 3 x 3 blur to the image in
+// colorMapSampler, which is the same size as the render target.
+// The sample weights are 1/16 in the corners, 2/16 on the edges,
+// and 4/16 in the center.
+
+#include "../../../gl/hlslCompat.glsl"
+#include "../../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define IN_position vPosition
+#define IN_texCoords vTexCoord0
+
+#define OUT_position gl_Position
+out vec4 texCoords;
+#define OUT_texCoords texCoords
+
+uniform vec2 oneOverTargetSize;
+uniform vec4 rtParams0;
+
+void main()
+{
+ const vec4 halfPixel = vec4( -0.5, 0.5, -0.5, 0.5 );
+ OUT_position = IN_position; //Transform_ObjectToClip( IN_position );
+
+ //vec2 uv = IN_texCoords + rtParams0.xy;
+ vec2 uv = viewportCoordToRenderTarget( IN_texCoords, rtParams0 );
+ OUT_texCoords = uv.xxyy + halfPixel * oneOverTargetSize.xxyy;
+
+ correctSSP(gl_Position);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/dbgEdgeDisplayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/dbgEdgeDisplayP.hlsl
new file mode 100644
index 000000000..fbd529031
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/dbgEdgeDisplayP.hlsl
@@ -0,0 +1,30 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(edgeBuffer);
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ return float4( TORQUE_TEX2D( edgeBuffer, IN.uv0 ).rrr, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAP.hlsl
new file mode 100644
index 000000000..f5a71687d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAP.hlsl
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(edgeBuffer,0);
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 1);
+uniform float2 targetSize;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float2 pixelSize = 1.0 / targetSize;
+
+ // Sample edge buffer, bail if not on an edge
+ float edgeSample = TORQUE_TEX2D(edgeBuffer, IN.uv0).r;
+ clip(edgeSample - 1e-6);
+
+ // Ok we're on an edge, so multi-tap sample, average, and return
+ float2 offsets[9] = {
+ float2( 0.0, 0.0),
+ float2(-1.0, -1.0),
+ float2( 0.0, -1.0),
+ float2( 1.0, -1.0),
+ float2( 1.0, 0.0),
+ float2( 1.0, 1.0),
+ float2( 0.0, 1.0),
+ float2(-1.0, 1.0),
+ float2(-1.0, 0.0),
+ };
+
+ float4 accumColor = 0;
+ for(int i = 0; i < 9; i++)
+ {
+ // Multiply the intensity of the edge, by the UV, so that things which maybe
+ // aren't quite full edges get sub-pixel sampling to reduce artifacts
+
+ // Scaling offsets by 0.5 to reduce the range bluriness from extending to
+ // far outward from the edge.
+
+ float2 offsetUV = IN.uv1 + edgeSample * ( offsets[i] * 0.5 ) * pixelSize;//rtWidthHeightInvWidthNegHeight.zw;
+ //offsetUV *= 0.999;
+ accumColor += TORQUE_TEX2D(backBuffer, offsetUV);
+ }
+ accumColor /= 9.0;
+
+ return accumColor;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAV.hlsl
new file mode 100644
index 000000000..4718b40f5
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeAAV.hlsl
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+
+uniform float4 rtParams0;
+uniform float4 rtParams1;
+uniform float4 rtParams2;
+uniform float4 rtParams3;
+
+PFXVertToPix main( PFXVert IN )
+{
+ PFXVertToPix OUT;
+
+ OUT.hpos = IN.pos;
+ OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( IN.uv, rtParams1 );
+ OUT.uv2 = viewportCoordToRenderTarget( IN.uv, rtParams2 );
+ OUT.uv3 = viewportCoordToRenderTarget( IN.uv, rtParams3 );
+
+ OUT.wsEyeRay = IN.wsEyeRay;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeDetectP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeDetectP.hlsl
new file mode 100644
index 000000000..c8bfb2153
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/edgeDetectP.hlsl
@@ -0,0 +1,93 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+#include "../../shaderModelAutoGen.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(deferredBuffer,0);
+
+// GPU Gems 3, pg 443-444
+float GetEdgeWeight(float2 uv0, in float2 targetSize)
+{
+ float2 offsets[9] = {
+ float2( 0.0, 0.0),
+ float2(-1.0, -1.0),
+ float2( 0.0, -1.0),
+ float2( 1.0, -1.0),
+ float2( 1.0, 0.0),
+ float2( 1.0, 1.0),
+ float2( 0.0, 1.0),
+ float2(-1.0, 1.0),
+ float2(-1.0, 0.0),
+ };
+
+
+ float2 PixelSize = 1.0 / targetSize;
+
+ float Depth[9];
+ float3 Normal[9];
+
+ [unroll] //no getting around this, may as well save the annoying warning message
+ for(int i = 0; i < 9; i++)
+ {
+ float2 uv = uv0 + offsets[i] * PixelSize;
+ float4 gbSample = TORQUE_DEFERRED_UNCONDITION( deferredBuffer, uv );
+ Depth[i] = gbSample.a;
+ Normal[i] = gbSample.rgb;
+ }
+
+ float4 Deltas1 = float4(Depth[1], Depth[2], Depth[3], Depth[4]);
+ float4 Deltas2 = float4(Depth[5], Depth[6], Depth[7], Depth[8]);
+
+ Deltas1 = abs(Deltas1 - Depth[0]);
+ Deltas2 = abs(Depth[0] - Deltas2);
+
+ float4 maxDeltas = max(Deltas1, Deltas2);
+ float4 minDeltas = max(min(Deltas1, Deltas2), 0.00001);
+
+ float4 depthResults = step(minDeltas * 25.0, maxDeltas);
+
+ Deltas1.x = dot(Normal[1], Normal[0]);
+ Deltas1.y = dot(Normal[2], Normal[0]);
+ Deltas1.z = dot(Normal[3], Normal[0]);
+ Deltas1.w = dot(Normal[4], Normal[0]);
+
+ Deltas2.x = dot(Normal[5], Normal[0]);
+ Deltas2.y = dot(Normal[6], Normal[0]);
+ Deltas2.z = dot(Normal[7], Normal[0]);
+ Deltas2.w = dot(Normal[8], Normal[0]);
+
+ Deltas1 = abs(Deltas1 - Deltas2);
+
+ float4 normalResults = step(0.4, Deltas1);
+
+ normalResults = max(normalResults, depthResults);
+
+ return dot(normalResults, float4(1.0, 1.0, 1.0, 1.0)) * 0.25;
+}
+
+uniform float2 targetSize;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ return GetEdgeWeight(IN.uv0, targetSize);//rtWidthHeightInvWidthNegHeight.zw);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/dbgEdgeDisplayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/dbgEdgeDisplayP.glsl
new file mode 100644
index 000000000..ccc3b8ba5
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/dbgEdgeDisplayP.glsl
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec2 uv0;
+#define IN_uv0 uv0
+
+uniform sampler2D edgeBuffer;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = vec4( texture( edgeBuffer, IN_uv0 ).rrr, 1.0 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAP.glsl
new file mode 100644
index 000000000..216dc8725
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAP.glsl
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D edgeBuffer;
+uniform sampler2D backBuffer;
+uniform vec2 targetSize;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec2 pixelSize = 1.0 / targetSize;
+
+ // Sample edge buffer, bail if not on an edge
+ float edgeSample = texture(edgeBuffer, IN_uv0).r;
+ clip(edgeSample - 1e-6);
+
+ // Ok we're on an edge, so multi-tap sample, average, and return
+ vec2 offsets[9] = vec2[](
+ vec2( 0.0, 0.0),
+ vec2(-1.0, -1.0),
+ vec2( 0.0, -1.0),
+ vec2( 1.0, -1.0),
+ vec2( 1.0, 0.0),
+ vec2( 1.0, 1.0),
+ vec2( 0.0, 1.0),
+ vec2(-1.0, 1.0),
+ vec2(-1.0, 0.0)
+ );
+
+ vec4 accumColor = vec4(0.0);
+ for(int i = 0; i < 9; i++)
+ {
+ // Multiply the intensity of the edge, by the UV, so that things which maybe
+ // aren't quite full edges get sub-pixel sampling to reduce artifacts
+
+ // Scaling offsets by 0.5 to reduce the range bluriness from extending to
+ // far outward from the edge.
+
+ vec2 offsetUV = IN_uv1 + edgeSample * ( offsets[i] * 0.5 ) * pixelSize;//rtWidthHeightInvWidthNegHeight.zw;
+ //offsetUV *= 0.999;
+ accumColor+= texture(backBuffer, offsetUV);
+ }
+ accumColor /= 9.0;
+
+ OUT_col = accumColor;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAV.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAV.glsl
new file mode 100644
index 000000000..975532272
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeAAV.glsl
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+#include "../../gl/postFX.glsl"
+
+uniform vec4 rtParams0;
+uniform vec4 rtParams1;
+uniform vec4 rtParams2;
+uniform vec4 rtParams3;
+
+void main()
+{
+ OUT_hpos = IN_pos;
+ OUT_uv0 = viewportCoordToRenderTarget( IN_uv, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( IN_uv, rtParams1 );
+ OUT_uv2 = viewportCoordToRenderTarget( IN_uv, rtParams2 );
+ OUT_uv3 = viewportCoordToRenderTarget( IN_uv, rtParams3 );
+
+ OUT_wsEyeRay = IN_wsEyeRay;
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeDetectP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeDetectP.glsl
new file mode 100644
index 000000000..02507eee8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/edgeaa/gl/edgeDetectP.glsl
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+// GPU Gems 3, pg 443-444
+float GetEdgeWeight(vec2 uv0, in sampler2D deferredBuffer, in vec2 targetSize)
+{
+ vec2 offsets[9] = vec2[](
+ vec2( 0.0, 0.0),
+ vec2(-1.0, -1.0),
+ vec2( 0.0, -1.0),
+ vec2( 1.0, -1.0),
+ vec2( 1.0, 0.0),
+ vec2( 1.0, 1.0),
+ vec2( 0.0, 1.0),
+ vec2(-1.0, 1.0),
+ vec2(-1.0, 0.0)
+ );
+
+
+ vec2 PixelSize = 1.0 / targetSize;
+
+ float Depth[9];
+ vec3 Normal[9];
+
+ for(int i = 0; i < 9; i++)
+ {
+ vec2 uv = uv0 + offsets[i] * PixelSize;
+ vec4 gbSample = deferredUncondition( deferredBuffer, uv );
+ Depth[i] = gbSample.a;
+ Normal[i] = gbSample.rgb;
+ }
+
+ vec4 Deltas1 = vec4(Depth[1], Depth[2], Depth[3], Depth[4]);
+ vec4 Deltas2 = vec4(Depth[5], Depth[6], Depth[7], Depth[8]);
+
+ Deltas1 = abs(Deltas1 - Depth[0]);
+ Deltas2 = abs(Depth[0] - Deltas2);
+
+ vec4 maxDeltas = max(Deltas1, Deltas2);
+ vec4 minDeltas = max(min(Deltas1, Deltas2), 0.00001);
+
+ vec4 depthResults = step(minDeltas * 25.0, maxDeltas);
+
+ Deltas1.x = dot(Normal[1], Normal[0]);
+ Deltas1.y = dot(Normal[2], Normal[0]);
+ Deltas1.z = dot(Normal[3], Normal[0]);
+ Deltas1.w = dot(Normal[4], Normal[0]);
+
+ Deltas2.x = dot(Normal[5], Normal[0]);
+ Deltas2.y = dot(Normal[6], Normal[0]);
+ Deltas2.z = dot(Normal[7], Normal[0]);
+ Deltas2.w = dot(Normal[8], Normal[0]);
+
+ Deltas1 = abs(Deltas1 - Deltas2);
+
+ vec4 normalResults = step(0.4, Deltas1);
+
+ normalResults = max(normalResults, depthResults);
+
+ return dot(normalResults, vec4(1.0, 1.0, 1.0, 1.0)) * 0.25;
+}
+
+in vec2 uv0;
+#define IN_uv0 uv0
+
+uniform sampler2D deferredBuffer;
+uniform vec2 targetSize;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = vec4( GetEdgeWeight(IN_uv0, deferredBuffer, targetSize ) );//rtWidthHeightInvWidthNegHeight.zw);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/flashP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/flashP.hlsl
new file mode 100644
index 000000000..93daf3c26
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/flashP.hlsl
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFx.hlsl"
+#include "../torque.hlsl"
+
+uniform float damageFlash;
+uniform float whiteOut;
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+
+float4 main(PFXVertToPix IN) : TORQUE_TARGET0
+{
+ float4 color1 = TORQUE_TEX2D(backBuffer, IN.uv0);
+ float4 color2 = color1 * MUL_COLOR;
+ float4 damage = lerp(color1,color2,damageFlash);
+ return lerp(damage,WHITE_COLOR,whiteOut);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl
new file mode 100644
index 000000000..9f3500f67
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fogP.hlsl
@@ -0,0 +1,47 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFx.hlsl"
+#include "./../torque.hlsl"
+#include "./../shaderModelAutoGen.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 0);
+uniform float3 eyePosWorld;
+uniform float4 fogColor;
+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 );
+
+ float factor = computeSceneFog( eyePosWorld,
+ eyePosWorld + ( IN.wsEyeRay * depth ),
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ return hdrEncode( float4( fogColor.rgb, 1.0 - saturate( factor ) ) );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/Fxaa3_11.h b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/Fxaa3_11.h
new file mode 100644
index 000000000..9ca7627d4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/Fxaa3_11.h
@@ -0,0 +1,2047 @@
+/*============================================================================
+
+
+ NVIDIA FXAA 3.11 by TIMOTHY LOTTES
+
+
+------------------------------------------------------------------------------
+COPYRIGHT (C) 2010, 2011 NVIDIA CORPORATION. ALL RIGHTS RESERVED.
+------------------------------------------------------------------------------
+TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
+*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA
+OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR
+CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
+LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION,
+OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE
+THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+------------------------------------------------------------------------------
+ INTEGRATION CHECKLIST
+------------------------------------------------------------------------------
+(1.)
+In the shader source, setup defines for the desired configuration.
+When providing multiple shaders (for different presets),
+simply setup the defines differently in multiple files.
+Example,
+
+ #define FXAA_PC 1
+ #define FXAA_HLSL_5 1
+ #define FXAA_QUALITY__PRESET 12
+
+Or,
+
+ #define FXAA_360 1
+
+Or,
+
+ #define FXAA_PS3 1
+
+Etc.
+
+(2.)
+Then include this file,
+
+ include "Fxaa3_11.h"
+
+(3.)
+Then call the FXAA pixel shader from within your desired shader.
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
+As for FXAA 3.11 all inputs for all shaders are the same
+to enable easy porting between platforms.
+
+ return FxaaPixelShader(...);
+
+(4.)
+Insure pass prior to FXAA outputs RGBL (see next section).
+Or use,
+
+ #define FXAA_GREEN_AS_LUMA 1
+
+(5.)
+Setup engine to provide the following constants
+which are used in the FxaaPixelShader() inputs,
+
+ FxaaFloat2 fxaaQualityRcpFrame,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ FxaaFloat fxaaQualitySubpix,
+ FxaaFloat fxaaQualityEdgeThreshold,
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ FxaaFloat4 fxaaConsole360ConstDir
+
+Look at the FXAA Quality FxaaPixelShader() for docs on inputs.
+
+(6.)
+Have FXAA vertex shader run as a full screen triangle,
+and output "pos" and "fxaaConsolePosPos"
+such that inputs in the pixel shader provide,
+
+ // {xy} = center of pixel
+ FxaaFloat2 pos,
+
+ // {xy__} = upper left of pixel
+ // {__zw} = lower right of pixel
+ FxaaFloat4 fxaaConsolePosPos,
+
+(7.)
+Insure the texture sampler(s) used by FXAA are set to bilinear filtering.
+
+
+------------------------------------------------------------------------------
+ INTEGRATION - RGBL AND COLORSPACE
+------------------------------------------------------------------------------
+FXAA3 requires RGBL as input unless the following is set,
+
+ #define FXAA_GREEN_AS_LUMA 1
+
+In which case the engine uses green in place of luma,
+and requires RGB input is in a non-linear colorspace.
+
+RGB should be LDR (low dynamic range).
+Specifically do FXAA after tonemapping.
+
+RGB data as returned by a texture fetch can be non-linear,
+or linear when FXAA_GREEN_AS_LUMA is not set.
+Note an "sRGB format" texture counts as linear,
+because the result of a texture fetch is linear data.
+Regular "RGBA8" textures in the sRGB colorspace are non-linear.
+
+If FXAA_GREEN_AS_LUMA is not set,
+luma must be stored in the alpha channel prior to running FXAA.
+This luma should be in a perceptual space (could be gamma 2.0).
+Example pass before FXAA where output is gamma 2.0 encoded,
+
+ color.rgb = ToneMap(color.rgb); // linear color output
+ color.rgb = sqrt(color.rgb); // gamma 2.0 color output
+ return color;
+
+To use FXAA,
+
+ color.rgb = ToneMap(color.rgb); // linear color output
+ color.rgb = sqrt(color.rgb); // gamma 2.0 color output
+ color.a = dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114)); // compute luma
+ return color;
+
+Another example where output is linear encoded,
+say for instance writing to an sRGB formated render target,
+where the render target does the conversion back to sRGB after blending,
+
+ color.rgb = ToneMap(color.rgb); // linear color output
+ return color;
+
+To use FXAA,
+
+ color.rgb = ToneMap(color.rgb); // linear color output
+ color.a = sqrt(dot(color.rgb, FxaaFloat3(0.299, 0.587, 0.114))); // compute luma
+ return color;
+
+Getting luma correct is required for the algorithm to work correctly.
+
+
+------------------------------------------------------------------------------
+ BEING LINEARLY CORRECT?
+------------------------------------------------------------------------------
+Applying FXAA to a framebuffer with linear RGB color will look worse.
+This is very counter intuitive, but happends to be true in this case.
+The reason is because dithering artifacts will be more visiable
+in a linear colorspace.
+
+
+------------------------------------------------------------------------------
+ COMPLEX INTEGRATION
+------------------------------------------------------------------------------
+Q. What if the engine is blending into RGB before wanting to run FXAA?
+
+A. In the last opaque pass prior to FXAA,
+ have the pass write out luma into alpha.
+ Then blend into RGB only.
+ FXAA should be able to run ok
+ assuming the blending pass did not any add aliasing.
+ This should be the common case for particles and common blending passes.
+
+A. Or use FXAA_GREEN_AS_LUMA.
+
+============================================================================*/
+
+/*============================================================================
+
+ INTEGRATION KNOBS
+
+============================================================================*/
+//
+// FXAA_PS3 and FXAA_360 choose the console algorithm (FXAA3 CONSOLE).
+// FXAA_360_OPT is a prototype for the new optimized 360 version.
+//
+// 1 = Use API.
+// 0 = Don't use API.
+//
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_PS3
+ #define FXAA_PS3 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_360
+ #define FXAA_360 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_360_OPT
+ #define FXAA_360_OPT 0
+#endif
+/*==========================================================================*/
+#ifndef FXAA_PC
+ //
+ // FXAA Quality
+ // The high quality PC algorithm.
+ //
+ #define FXAA_PC 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_PC_CONSOLE
+ //
+ // The console algorithm for PC is included
+ // for developers targeting really low spec machines.
+ // Likely better to just run FXAA_PC, and use a really low preset.
+ //
+ #define FXAA_PC_CONSOLE 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GLSL_120
+ #define FXAA_GLSL_120 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GLSL_130
+ #define FXAA_GLSL_130 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_3
+ #define FXAA_HLSL_3 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_4
+ #define FXAA_HLSL_4 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_HLSL_5
+ #define FXAA_HLSL_5 0
+#endif
+/*==========================================================================*/
+#ifndef FXAA_GREEN_AS_LUMA
+ //
+ // For those using non-linear color,
+ // and either not able to get luma in alpha, or not wanting to,
+ // this enables FXAA to run using green as a proxy for luma.
+ // So with this enabled, no need to pack luma in alpha.
+ //
+ // This will turn off AA on anything which lacks some amount of green.
+ // Pure red and blue or combination of only R and B, will get no AA.
+ //
+ // Might want to lower the settings for both,
+ // fxaaConsoleEdgeThresholdMin
+ // fxaaQualityEdgeThresholdMin
+ // In order to insure AA does not get turned off on colors
+ // which contain a minor amount of green.
+ //
+ // 1 = On.
+ // 0 = Off.
+ //
+ #define FXAA_GREEN_AS_LUMA 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_EARLY_EXIT
+ //
+ // Controls algorithm's early exit path.
+ // On PS3 turning this ON adds 2 cycles to the shader.
+ // On 360 turning this OFF adds 10ths of a millisecond to the shader.
+ // Turning this off on console will result in a more blurry image.
+ // So this defaults to on.
+ //
+ // 1 = On.
+ // 0 = Off.
+ //
+ #define FXAA_EARLY_EXIT 1
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_DISCARD
+ //
+ // Only valid for PC OpenGL currently.
+ // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
+ //
+ // 1 = Use discard on pixels which don't need AA.
+ // For APIs which enable concurrent TEX+ROP from same surface.
+ // 0 = Return unchanged color on pixels which don't need AA.
+ //
+ #define FXAA_DISCARD 0
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_FAST_PIXEL_OFFSET
+ //
+ // Used for GLSL 120 only.
+ //
+ // 1 = GL API supports fast pixel offsets
+ // 0 = do not use fast pixel offsets
+ //
+ #ifdef GL_EXT_gpu_shader4
+ #define FXAA_FAST_PIXEL_OFFSET 1
+ #endif
+ #ifdef GL_NV_gpu_shader5
+ #define FXAA_FAST_PIXEL_OFFSET 1
+ #endif
+ #ifdef GL_ARB_gpu_shader5
+ #define FXAA_FAST_PIXEL_OFFSET 1
+ #endif
+ #ifndef FXAA_FAST_PIXEL_OFFSET
+ #define FXAA_FAST_PIXEL_OFFSET 0
+ #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_GATHER4_ALPHA
+ //
+ // 1 = API supports gather4 on alpha channel.
+ // 0 = API does not support gather4 on alpha channel.
+ //
+ #if (FXAA_HLSL_5 == 1)
+ #define FXAA_GATHER4_ALPHA 1
+ #endif
+ #ifdef GL_ARB_gpu_shader5
+ #define FXAA_GATHER4_ALPHA 1
+ #endif
+ #ifdef GL_NV_gpu_shader5
+ #define FXAA_GATHER4_ALPHA 1
+ #endif
+ #ifndef FXAA_GATHER4_ALPHA
+ #define FXAA_GATHER4_ALPHA 0
+ #endif
+#endif
+
+/*============================================================================
+ FXAA CONSOLE PS3 - TUNING KNOBS
+============================================================================*/
+#ifndef FXAA_CONSOLE__PS3_EDGE_SHARPNESS
+ //
+ // Consoles the sharpness of edges on PS3 only.
+ // Non-PS3 tuning is done with shader input.
+ //
+ // Due to the PS3 being ALU bound,
+ // there are only two safe values here: 4 and 8.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ //
+ // 8.0 is sharper
+ // 4.0 is softer
+ // 2.0 is really soft (good for vector graphics inputs)
+ //
+ #if 1
+ #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 8.0
+ #endif
+ #if 0
+ #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 4.0
+ #endif
+ #if 0
+ #define FXAA_CONSOLE__PS3_EDGE_SHARPNESS 2.0
+ #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#ifndef FXAA_CONSOLE__PS3_EDGE_THRESHOLD
+ //
+ // Only effects PS3.
+ // Non-PS3 tuning is done with shader input.
+ //
+ // The minimum amount of local contrast required to apply algorithm.
+ // The console setting has a different mapping than the quality setting.
+ //
+ // This only applies when FXAA_EARLY_EXIT is 1.
+ //
+ // Due to the PS3 being ALU bound,
+ // there are only two safe values here: 0.25 and 0.125.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ //
+ // 0.125 leaves less aliasing, but is softer
+ // 0.25 leaves more aliasing, and is sharper
+ //
+ #if 1
+ #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.125
+ #else
+ #define FXAA_CONSOLE__PS3_EDGE_THRESHOLD 0.25
+ #endif
+#endif
+
+/*============================================================================
+ FXAA QUALITY - TUNING KNOBS
+------------------------------------------------------------------------------
+NOTE the other tuning knobs are now in the shader function inputs!
+============================================================================*/
+#ifndef FXAA_QUALITY__PRESET
+ //
+ // Choose the quality preset.
+ // This needs to be compiled into the shader as it effects code.
+ // Best option to include multiple presets is to
+ // in each shader define the preset, then include this file.
+ //
+ // OPTIONS
+ // -----------------------------------------------------------------------
+ // 10 to 15 - default medium dither (10=fastest, 15=highest quality)
+ // 20 to 29 - less dither, more expensive (20=fastest, 29=highest quality)
+ // 39 - no dither, very expensive
+ //
+ // NOTES
+ // -----------------------------------------------------------------------
+ // 12 = slightly faster then FXAA 3.9 and higher edge quality (default)
+ // 13 = about same speed as FXAA 3.9 and better than 12
+ // 23 = closest to FXAA 3.9 visually and performance wise
+ // _ = the lowest digit is directly related to performance
+ // _ = the highest digit is directly related to style
+ //
+ #define FXAA_QUALITY__PRESET 12
+#endif
+
+
+/*============================================================================
+
+ FXAA QUALITY - PRESETS
+
+============================================================================*/
+
+/*============================================================================
+ FXAA QUALITY - MEDIUM DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 10)
+ #define FXAA_QUALITY__PS 3
+ #define FXAA_QUALITY__P0 1.5
+ #define FXAA_QUALITY__P1 3.0
+ #define FXAA_QUALITY__P2 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 11)
+ #define FXAA_QUALITY__PS 4
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 3.0
+ #define FXAA_QUALITY__P3 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 12)
+ #define FXAA_QUALITY__PS 5
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 4.0
+ #define FXAA_QUALITY__P4 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 13)
+ #define FXAA_QUALITY__PS 6
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 4.0
+ #define FXAA_QUALITY__P5 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 14)
+ #define FXAA_QUALITY__PS 7
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 4.0
+ #define FXAA_QUALITY__P6 12.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 15)
+ #define FXAA_QUALITY__PS 8
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 4.0
+ #define FXAA_QUALITY__P7 12.0
+#endif
+
+/*============================================================================
+ FXAA QUALITY - LOW DITHER PRESETS
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 20)
+ #define FXAA_QUALITY__PS 3
+ #define FXAA_QUALITY__P0 1.5
+ #define FXAA_QUALITY__P1 2.0
+ #define FXAA_QUALITY__P2 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 21)
+ #define FXAA_QUALITY__PS 4
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 22)
+ #define FXAA_QUALITY__PS 5
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 23)
+ #define FXAA_QUALITY__PS 6
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 24)
+ #define FXAA_QUALITY__PS 7
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 3.0
+ #define FXAA_QUALITY__P6 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 25)
+ #define FXAA_QUALITY__PS 8
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 4.0
+ #define FXAA_QUALITY__P7 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 26)
+ #define FXAA_QUALITY__PS 9
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 2.0
+ #define FXAA_QUALITY__P7 4.0
+ #define FXAA_QUALITY__P8 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 27)
+ #define FXAA_QUALITY__PS 10
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 2.0
+ #define FXAA_QUALITY__P7 2.0
+ #define FXAA_QUALITY__P8 4.0
+ #define FXAA_QUALITY__P9 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 28)
+ #define FXAA_QUALITY__PS 11
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 2.0
+ #define FXAA_QUALITY__P7 2.0
+ #define FXAA_QUALITY__P8 2.0
+ #define FXAA_QUALITY__P9 4.0
+ #define FXAA_QUALITY__P10 8.0
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_QUALITY__PRESET == 29)
+ #define FXAA_QUALITY__PS 12
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.5
+ #define FXAA_QUALITY__P2 2.0
+ #define FXAA_QUALITY__P3 2.0
+ #define FXAA_QUALITY__P4 2.0
+ #define FXAA_QUALITY__P5 2.0
+ #define FXAA_QUALITY__P6 2.0
+ #define FXAA_QUALITY__P7 2.0
+ #define FXAA_QUALITY__P8 2.0
+ #define FXAA_QUALITY__P9 2.0
+ #define FXAA_QUALITY__P10 4.0
+ #define FXAA_QUALITY__P11 8.0
+#endif
+
+/*============================================================================
+ FXAA QUALITY - EXTREME QUALITY
+============================================================================*/
+#if (FXAA_QUALITY__PRESET == 39)
+ #define FXAA_QUALITY__PS 12
+ #define FXAA_QUALITY__P0 1.0
+ #define FXAA_QUALITY__P1 1.0
+ #define FXAA_QUALITY__P2 1.0
+ #define FXAA_QUALITY__P3 1.0
+ #define FXAA_QUALITY__P4 1.0
+ #define FXAA_QUALITY__P5 1.5
+ #define FXAA_QUALITY__P6 2.0
+ #define FXAA_QUALITY__P7 2.0
+ #define FXAA_QUALITY__P8 2.0
+ #define FXAA_QUALITY__P9 2.0
+ #define FXAA_QUALITY__P10 4.0
+ #define FXAA_QUALITY__P11 8.0
+#endif
+
+
+
+/*============================================================================
+
+ API PORTING
+
+============================================================================*/
+#if (FXAA_GLSL_120 == 1) || (FXAA_GLSL_130 == 1)
+ #define FxaaBool bool
+ #define FxaaDiscard discard
+ #define FxaaFloat float
+ #define FxaaFloat2 vec2
+ #define FxaaFloat3 vec3
+ #define FxaaFloat4 vec4
+ #define FxaaHalf float
+ #define FxaaHalf2 vec2
+ #define FxaaHalf3 vec3
+ #define FxaaHalf4 vec4
+ #define FxaaInt2 ivec2
+ #define FxaaSat(x) clamp(x, 0.0, 1.0)
+ #define FxaaTex sampler2D
+#else
+ #define FxaaBool bool
+ #define FxaaDiscard clip(-1)
+ #define FxaaFloat float
+ #define FxaaFloat2 float2
+ #define FxaaFloat3 float3
+ #define FxaaFloat4 float4
+ #define FxaaHalf half
+ #define FxaaHalf2 half2
+ #define FxaaHalf3 half3
+ #define FxaaHalf4 half4
+ #define FxaaSat(x) saturate(x)
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_GLSL_120 == 1)
+ // Requires,
+ // #version 120
+ // And at least,
+ // #extension GL_EXT_gpu_shader4 : enable
+ // (or set FXAA_FAST_PIXEL_OFFSET 1 to work like DX9)
+ #define FxaaTexTop(t, p) texture2DLod(t, p, 0.0)
+ #if (FXAA_FAST_PIXEL_OFFSET == 1)
+ #define FxaaTexOff(t, p, o, r) texture2DLodOffset(t, p, 0.0, o)
+ #else
+ #define FxaaTexOff(t, p, o, r) texture2DLod(t, p + (o * r), 0.0)
+ #endif
+ #if (FXAA_GATHER4_ALPHA == 1)
+ // use #extension GL_ARB_gpu_shader5 : enable
+ #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+ #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+ #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+ #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+ #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_GLSL_130 == 1)
+ // Requires "#version 130" or better
+ #define FxaaTexTop(t, p) textureLod(t, p, 0.0)
+ #define FxaaTexOff(t, p, o, r) textureLodOffset(t, p, 0.0, o)
+ #if (FXAA_GATHER4_ALPHA == 1)
+ // use #extension GL_ARB_gpu_shader5 : enable
+ #define FxaaTexAlpha4(t, p) textureGather(t, p, 3)
+ #define FxaaTexOffAlpha4(t, p, o) textureGatherOffset(t, p, o, 3)
+ #define FxaaTexGreen4(t, p) textureGather(t, p, 1)
+ #define FxaaTexOffGreen4(t, p, o) textureGatherOffset(t, p, o, 1)
+ #endif
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_3 == 1) || (FXAA_360 == 1) || (FXAA_PS3 == 1)
+ #define FxaaInt2 float2
+ #define FxaaTex sampler2D
+ #define FxaaTexTop(t, p) tex2Dlod(t, float4(p, 0.0, 0.0))
+ #define FxaaTexOff(t, p, o, r) tex2Dlod(t, float4(p + (o * r), 0, 0))
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_4 == 1)
+ #define FxaaInt2 int2
+ struct FxaaTex { SamplerState smpl; Texture2D tex; };
+ #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+ #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+#endif
+/*--------------------------------------------------------------------------*/
+#if (FXAA_HLSL_5 == 1)
+ #define FxaaInt2 int2
+ struct FxaaTex { SamplerState smpl; Texture2D tex; };
+ #define FxaaTexTop(t, p) t.tex.SampleLevel(t.smpl, p, 0.0)
+ #define FxaaTexOff(t, p, o, r) t.tex.SampleLevel(t.smpl, p, 0.0, o)
+ #define FxaaTexAlpha4(t, p) t.tex.GatherAlpha(t.smpl, p)
+ #define FxaaTexOffAlpha4(t, p, o) t.tex.GatherAlpha(t.smpl, p, o)
+ #define FxaaTexGreen4(t, p) t.tex.GatherGreen(t.smpl, p)
+ #define FxaaTexOffGreen4(t, p, o) t.tex.GatherGreen(t.smpl, p, o)
+#endif
+
+
+/*============================================================================
+ GREEN AS LUMA OPTION SUPPORT FUNCTION
+============================================================================*/
+#if (FXAA_GREEN_AS_LUMA == 0)
+ FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.w; }
+#else
+ FxaaFloat FxaaLuma(FxaaFloat4 rgba) { return rgba.y; }
+#endif
+
+
+
+
+/*============================================================================
+
+ FXAA3 QUALITY - PC
+
+============================================================================*/
+#if (FXAA_PC == 1)
+/*--------------------------------------------------------------------------*/
+FxaaFloat4 FxaaPixelShader(
+ //
+ // Use noperspective interpolation here (turn off perspective interpolation).
+ // {xy} = center of pixel
+ FxaaFloat2 pos,
+ //
+ // Used only for FXAA Console, and not used on the 360 version.
+ // Use noperspective interpolation here (turn off perspective interpolation).
+ // {xy__} = upper left of pixel
+ // {__zw} = lower right of pixel
+ FxaaFloat4 fxaaConsolePosPos,
+ //
+ // Input color texture.
+ // {rgb_} = color in linear or perceptual color space
+ // if (FXAA_GREEN_AS_LUMA == 0)
+ // {___a} = luma in perceptual color space (not linear)
+ FxaaTex tex,
+ //
+ // Only used on the optimized 360 version of FXAA Console.
+ // For everything but 360, just use the same input here as for "tex".
+ // For 360, same texture, just alias with a 2nd sampler.
+ // This sampler needs to have an exponent bias of -1.
+ FxaaTex fxaaConsole360TexExpBiasNegOne,
+ //
+ // Only used on the optimized 360 version of FXAA Console.
+ // For everything but 360, just use the same input here as for "tex".
+ // For 360, same texture, just alias with a 3nd sampler.
+ // This sampler needs to have an exponent bias of -2.
+ FxaaTex fxaaConsole360TexExpBiasNegTwo,
+ //
+ // Only used on FXAA Quality.
+ // This must be from a constant/uniform.
+ // {x_} = 1.0/screenWidthInPixels
+ // {_y} = 1.0/screenHeightInPixels
+ FxaaFloat2 fxaaQualityRcpFrame,
+ //
+ // Only used on FXAA Console.
+ // This must be from a constant/uniform.
+ // This effects sub-pixel AA quality and inversely sharpness.
+ // Where N ranges between,
+ // N = 0.50 (default)
+ // N = 0.33 (sharper)
+ // {x___} = -N/screenWidthInPixels
+ // {_y__} = -N/screenHeightInPixels
+ // {__z_} = N/screenWidthInPixels
+ // {___w} = N/screenHeightInPixels
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ //
+ // Only used on FXAA Console.
+ // Not used on 360, but used on PS3 and PC.
+ // This must be from a constant/uniform.
+ // {x___} = -2.0/screenWidthInPixels
+ // {_y__} = -2.0/screenHeightInPixels
+ // {__z_} = 2.0/screenWidthInPixels
+ // {___w} = 2.0/screenHeightInPixels
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ //
+ // Only used on FXAA Console.
+ // Only used on 360 in place of fxaaConsoleRcpFrameOpt2.
+ // This must be from a constant/uniform.
+ // {x___} = 8.0/screenWidthInPixels
+ // {_y__} = 8.0/screenHeightInPixels
+ // {__z_} = -4.0/screenWidthInPixels
+ // {___w} = -4.0/screenHeightInPixels
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__SUBPIX define.
+ // It is here now to allow easier tuning.
+ // Choose the amount of sub-pixel aliasing removal.
+ // This can effect sharpness.
+ // 1.00 - upper limit (softer)
+ // 0.75 - default amount of filtering
+ // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+ // 0.25 - almost off
+ // 0.00 - completely off
+ FxaaFloat fxaaQualitySubpix,
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
+ // It is here now to allow easier tuning.
+ // The minimum amount of local contrast required to apply algorithm.
+ // 0.333 - too little (faster)
+ // 0.250 - low quality
+ // 0.166 - default
+ // 0.125 - high quality
+ // 0.063 - overkill (slower)
+ FxaaFloat fxaaQualityEdgeThreshold,
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
+ // It is here now to allow easier tuning.
+ // Trims the algorithm from processing darks.
+ // 0.0833 - upper limit (default, the start of visible unfiltered edges)
+ // 0.0625 - high quality (faster)
+ // 0.0312 - visible limit (slower)
+ // Special notes when using FXAA_GREEN_AS_LUMA,
+ // Likely want to set this to zero.
+ // As colors that are mostly not-green
+ // will appear very dark in the green channel!
+ // Tune by looking at mostly non-green content,
+ // then start at zero and increase until aliasing is a problem.
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ //
+ // Only used on FXAA Console.
+ // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
+ // It is here now to allow easier tuning.
+ // This does not effect PS3, as this needs to be compiled in.
+ // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
+ // Due to the PS3 being ALU bound,
+ // there are only three safe values here: 2 and 4 and 8.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ // For all other platforms can be a non-power of two.
+ // 8.0 is sharper (default!!!)
+ // 4.0 is softer
+ // 2.0 is really soft (good only for vector graphics inputs)
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ //
+ // Only used on FXAA Console.
+ // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD define.
+ // It is here now to allow easier tuning.
+ // This does not effect PS3, as this needs to be compiled in.
+ // Use FXAA_CONSOLE__PS3_EDGE_THRESHOLD for PS3.
+ // Due to the PS3 being ALU bound,
+ // there are only two safe values here: 1/4 and 1/8.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ // The console setting has a different mapping than the quality setting.
+ // Other platforms can use other values.
+ // 0.125 leaves less aliasing, but is softer (default!!!)
+ // 0.25 leaves more aliasing, and is sharper
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ //
+ // Only used on FXAA Console.
+ // This used to be the FXAA_CONSOLE__EDGE_THRESHOLD_MIN define.
+ // It is here now to allow easier tuning.
+ // Trims the algorithm from processing darks.
+ // The console setting has a different mapping than the quality setting.
+ // This only applies when FXAA_EARLY_EXIT is 1.
+ // This does not apply to PS3,
+ // PS3 was simplified to avoid more shader instructions.
+ // 0.06 - faster but more aliasing in darks
+ // 0.05 - default
+ // 0.04 - slower and less aliasing in darks
+ // Special notes when using FXAA_GREEN_AS_LUMA,
+ // Likely want to set this to zero.
+ // As colors that are mostly not-green
+ // will appear very dark in the green channel!
+ // Tune by looking at mostly non-green content,
+ // then start at zero and increase until aliasing is a problem.
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ //
+ // Extra constants for 360 FXAA Console only.
+ // Use zeros or anything else for other platforms.
+ // These must be in physical constant registers and NOT immedates.
+ // Immedates will result in compiler un-optimizing.
+ // {xyzw} = float4(1.0, -1.0, 0.25, -0.25)
+ FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+ FxaaFloat2 posM;
+ posM.x = pos.x;
+ posM.y = pos.y;
+ #if (FXAA_GATHER4_ALPHA == 1)
+ #if (FXAA_DISCARD == 0)
+ FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ #define lumaM rgbyM.w
+ #else
+ #define lumaM rgbyM.y
+ #endif
+ #endif
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ FxaaFloat4 luma4A = FxaaTexAlpha4(tex, posM);
+ FxaaFloat4 luma4B = FxaaTexOffAlpha4(tex, posM, FxaaInt2(-1, -1));
+ #else
+ FxaaFloat4 luma4A = FxaaTexGreen4(tex, posM);
+ FxaaFloat4 luma4B = FxaaTexOffGreen4(tex, posM, FxaaInt2(-1, -1));
+ #endif
+ #if (FXAA_DISCARD == 1)
+ #define lumaM luma4A.w
+ #endif
+ #define lumaE luma4A.z
+ #define lumaS luma4A.x
+ #define lumaSE luma4A.y
+ #define lumaNW luma4B.w
+ #define lumaN luma4B.z
+ #define lumaW luma4B.x
+ #else
+ FxaaFloat4 rgbyM = FxaaTexTop(tex, posM);
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ #define lumaM rgbyM.w
+ #else
+ #define lumaM rgbyM.y
+ #endif
+ FxaaFloat lumaS = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0, 1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 0), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaN = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 0,-1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 0), fxaaQualityRcpFrame.xy));
+ #endif
+/*--------------------------------------------------------------------------*/
+ FxaaFloat maxSM = max(lumaS, lumaM);
+ FxaaFloat minSM = min(lumaS, lumaM);
+ FxaaFloat maxESM = max(lumaE, maxSM);
+ FxaaFloat minESM = min(lumaE, minSM);
+ FxaaFloat maxWN = max(lumaN, lumaW);
+ FxaaFloat minWN = min(lumaN, lumaW);
+ FxaaFloat rangeMax = max(maxWN, maxESM);
+ FxaaFloat rangeMin = min(minWN, minESM);
+ FxaaFloat rangeMaxScaled = rangeMax * fxaaQualityEdgeThreshold;
+ FxaaFloat range = rangeMax - rangeMin;
+ FxaaFloat rangeMaxClamped = max(fxaaQualityEdgeThresholdMin, rangeMaxScaled);
+ FxaaBool earlyExit = range < rangeMaxClamped;
+/*--------------------------------------------------------------------------*/
+ if(earlyExit)
+ #if (FXAA_DISCARD == 1)
+ FxaaDiscard;
+ #else
+ return rgbyM;
+ #endif
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_GATHER4_ALPHA == 0)
+ FxaaFloat lumaNW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1,-1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaSE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1, 1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2( 1,-1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+ #else
+ FxaaFloat lumaNE = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(1, -1), fxaaQualityRcpFrame.xy));
+ FxaaFloat lumaSW = FxaaLuma(FxaaTexOff(tex, posM, FxaaInt2(-1, 1), fxaaQualityRcpFrame.xy));
+ #endif
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaNS = lumaN + lumaS;
+ FxaaFloat lumaWE = lumaW + lumaE;
+ FxaaFloat subpixRcpRange = 1.0/range;
+ FxaaFloat subpixNSWE = lumaNS + lumaWE;
+ FxaaFloat edgeHorz1 = (-2.0 * lumaM) + lumaNS;
+ FxaaFloat edgeVert1 = (-2.0 * lumaM) + lumaWE;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaNESE = lumaNE + lumaSE;
+ FxaaFloat lumaNWNE = lumaNW + lumaNE;
+ FxaaFloat edgeHorz2 = (-2.0 * lumaE) + lumaNESE;
+ FxaaFloat edgeVert2 = (-2.0 * lumaN) + lumaNWNE;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaNWSW = lumaNW + lumaSW;
+ FxaaFloat lumaSWSE = lumaSW + lumaSE;
+ FxaaFloat edgeHorz4 = (abs(edgeHorz1) * 2.0) + abs(edgeHorz2);
+ FxaaFloat edgeVert4 = (abs(edgeVert1) * 2.0) + abs(edgeVert2);
+ FxaaFloat edgeHorz3 = (-2.0 * lumaW) + lumaNWSW;
+ FxaaFloat edgeVert3 = (-2.0 * lumaS) + lumaSWSE;
+ FxaaFloat edgeHorz = abs(edgeHorz3) + edgeHorz4;
+ FxaaFloat edgeVert = abs(edgeVert3) + edgeVert4;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat subpixNWSWNESE = lumaNWSW + lumaNESE;
+ FxaaFloat lengthSign = fxaaQualityRcpFrame.x;
+ FxaaBool horzSpan = edgeHorz >= edgeVert;
+ FxaaFloat subpixA = subpixNSWE * 2.0 + subpixNWSWNESE;
+/*--------------------------------------------------------------------------*/
+ if(!horzSpan) lumaN = lumaW;
+ if(!horzSpan) lumaS = lumaE;
+ if(horzSpan) lengthSign = fxaaQualityRcpFrame.y;
+ FxaaFloat subpixB = (subpixA * (1.0/12.0)) - lumaM;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat gradientN = lumaN - lumaM;
+ FxaaFloat gradientS = lumaS - lumaM;
+ FxaaFloat lumaNN = lumaN + lumaM;
+ FxaaFloat lumaSS = lumaS + lumaM;
+ FxaaBool pairN = abs(gradientN) >= abs(gradientS);
+ FxaaFloat gradient = max(abs(gradientN), abs(gradientS));
+ if(pairN) lengthSign = -lengthSign;
+ FxaaFloat subpixC = FxaaSat(abs(subpixB) * subpixRcpRange);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat2 posB;
+ posB.x = posM.x;
+ posB.y = posM.y;
+ FxaaFloat2 offNP;
+ offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
+ offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
+ if(!horzSpan) posB.x += lengthSign * 0.5;
+ if( horzSpan) posB.y += lengthSign * 0.5;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat2 posN;
+ posN.x = posB.x - offNP.x * FXAA_QUALITY__P0;
+ posN.y = posB.y - offNP.y * FXAA_QUALITY__P0;
+ FxaaFloat2 posP;
+ posP.x = posB.x + offNP.x * FXAA_QUALITY__P0;
+ posP.y = posB.y + offNP.y * FXAA_QUALITY__P0;
+ FxaaFloat subpixD = ((-2.0)*subpixC) + 3.0;
+ FxaaFloat lumaEndN = FxaaLuma(FxaaTexTop(tex, posN));
+ FxaaFloat subpixE = subpixC * subpixC;
+ FxaaFloat lumaEndP = FxaaLuma(FxaaTexTop(tex, posP));
+/*--------------------------------------------------------------------------*/
+ if(!pairN) lumaNN = lumaSS;
+ FxaaFloat gradientScaled = gradient * 1.0/4.0;
+ FxaaFloat lumaMM = lumaM - lumaNN * 0.5;
+ FxaaFloat subpixF = subpixD * subpixE;
+ FxaaBool lumaMLTZero = lumaMM < 0.0;
+/*--------------------------------------------------------------------------*/
+ lumaEndN -= lumaNN * 0.5;
+ lumaEndP -= lumaNN * 0.5;
+ FxaaBool doneN = abs(lumaEndN) >= gradientScaled;
+ FxaaBool doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P1;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P1;
+ FxaaBool doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P1;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P1;
+/*--------------------------------------------------------------------------*/
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P2;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P2;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P2;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P2;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 3)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P3;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P3;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P3;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P3;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 4)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P4;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P4;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P4;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P4;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 5)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P5;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P5;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P5;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P5;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 6)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P6;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P6;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P6;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P6;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 7)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P7;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P7;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P7;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P7;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 8)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P8;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P8;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P8;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P8;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 9)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P9;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P9;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P9;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P9;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 10)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P10;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P10;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P10;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P10;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 11)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P11;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P11;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P11;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P11;
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_QUALITY__PS > 12)
+ if(doneNP) {
+ if(!doneN) lumaEndN = FxaaLuma(FxaaTexTop(tex, posN.xy));
+ if(!doneP) lumaEndP = FxaaLuma(FxaaTexTop(tex, posP.xy));
+ if(!doneN) lumaEndN = lumaEndN - lumaNN * 0.5;
+ if(!doneP) lumaEndP = lumaEndP - lumaNN * 0.5;
+ doneN = abs(lumaEndN) >= gradientScaled;
+ doneP = abs(lumaEndP) >= gradientScaled;
+ if(!doneN) posN.x -= offNP.x * FXAA_QUALITY__P12;
+ if(!doneN) posN.y -= offNP.y * FXAA_QUALITY__P12;
+ doneNP = (!doneN) || (!doneP);
+ if(!doneP) posP.x += offNP.x * FXAA_QUALITY__P12;
+ if(!doneP) posP.y += offNP.y * FXAA_QUALITY__P12;
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+ #endif
+/*--------------------------------------------------------------------------*/
+ }
+/*--------------------------------------------------------------------------*/
+ FxaaFloat dstN = posM.x - posN.x;
+ FxaaFloat dstP = posP.x - posM.x;
+ if(!horzSpan) dstN = posM.y - posN.y;
+ if(!horzSpan) dstP = posP.y - posM.y;
+/*--------------------------------------------------------------------------*/
+ FxaaBool goodSpanN = (lumaEndN < 0.0) != lumaMLTZero;
+ FxaaFloat spanLength = (dstP + dstN);
+ FxaaBool goodSpanP = (lumaEndP < 0.0) != lumaMLTZero;
+ FxaaFloat spanLengthRcp = 1.0/spanLength;
+/*--------------------------------------------------------------------------*/
+ FxaaBool directionN = dstN < dstP;
+ FxaaFloat dst = min(dstN, dstP);
+ FxaaBool goodSpan = directionN ? goodSpanN : goodSpanP;
+ FxaaFloat subpixG = subpixF * subpixF;
+ FxaaFloat pixelOffset = (dst * (-spanLengthRcp)) + 0.5;
+ FxaaFloat subpixH = subpixG * fxaaQualitySubpix;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat pixelOffsetGood = goodSpan ? pixelOffset : 0.0;
+ FxaaFloat pixelOffsetSubpix = max(pixelOffsetGood, subpixH);
+ if(!horzSpan) posM.x += pixelOffsetSubpix * lengthSign;
+ if( horzSpan) posM.y += pixelOffsetSubpix * lengthSign;
+ #if (FXAA_DISCARD == 1)
+ return FxaaTexTop(tex, posM);
+ #else
+ return FxaaFloat4(FxaaTexTop(tex, posM).xyz, lumaM);
+ #endif
+}
+/*==========================================================================*/
+#endif
+
+
+
+
+/*============================================================================
+
+ FXAA3 CONSOLE - PC VERSION
+
+------------------------------------------------------------------------------
+Instead of using this on PC, I'd suggest just using FXAA Quality with
+ #define FXAA_QUALITY__PRESET 10
+Or
+ #define FXAA_QUALITY__PRESET 20
+Either are higher qualilty and almost as fast as this on modern PC GPUs.
+============================================================================*/
+#if (FXAA_PC_CONSOLE == 1)
+/*--------------------------------------------------------------------------*/
+FxaaFloat4 FxaaPixelShader(
+ // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+ FxaaFloat2 pos,
+ FxaaFloat4 fxaaConsolePosPos,
+ FxaaTex tex,
+ FxaaTex fxaaConsole360TexExpBiasNegOne,
+ FxaaTex fxaaConsole360TexExpBiasNegTwo,
+ FxaaFloat2 fxaaQualityRcpFrame,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ FxaaFloat fxaaQualitySubpix,
+ FxaaFloat fxaaQualityEdgeThreshold,
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaNw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xy));
+ FxaaFloat lumaSw = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.xw));
+ FxaaFloat lumaNe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zy));
+ FxaaFloat lumaSe = FxaaLuma(FxaaTexTop(tex, fxaaConsolePosPos.zw));
+/*--------------------------------------------------------------------------*/
+ FxaaFloat4 rgbyM = FxaaTexTop(tex, pos.xy);
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ FxaaFloat lumaM = rgbyM.w;
+ #else
+ FxaaFloat lumaM = rgbyM.y;
+ #endif
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaMaxNwSw = max(lumaNw, lumaSw);
+ lumaNe += 1.0/384.0;
+ FxaaFloat lumaMinNwSw = min(lumaNw, lumaSw);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaMaxNeSe = max(lumaNe, lumaSe);
+ FxaaFloat lumaMinNeSe = min(lumaNe, lumaSe);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaMax = max(lumaMaxNeSe, lumaMaxNwSw);
+ FxaaFloat lumaMin = min(lumaMinNeSe, lumaMinNwSw);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaMaxScaled = lumaMax * fxaaConsoleEdgeThreshold;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat lumaMinM = min(lumaMin, lumaM);
+ FxaaFloat lumaMaxScaledClamped = max(fxaaConsoleEdgeThresholdMin, lumaMaxScaled);
+ FxaaFloat lumaMaxM = max(lumaMax, lumaM);
+ FxaaFloat dirSwMinusNe = lumaSw - lumaNe;
+ FxaaFloat lumaMaxSubMinM = lumaMaxM - lumaMinM;
+ FxaaFloat dirSeMinusNw = lumaSe - lumaNw;
+ if(lumaMaxSubMinM < lumaMaxScaledClamped) return rgbyM;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat2 dir;
+ dir.x = dirSwMinusNe + dirSeMinusNw;
+ dir.y = dirSwMinusNe - dirSeMinusNw;
+/*--------------------------------------------------------------------------*/
+ FxaaFloat2 dir1 = normalize(dir.xy);
+ FxaaFloat4 rgbyN1 = FxaaTexTop(tex, pos.xy - dir1 * fxaaConsoleRcpFrameOpt.zw);
+ FxaaFloat4 rgbyP1 = FxaaTexTop(tex, pos.xy + dir1 * fxaaConsoleRcpFrameOpt.zw);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat dirAbsMinTimesC = min(abs(dir1.x), abs(dir1.y)) * fxaaConsoleEdgeSharpness;
+ FxaaFloat2 dir2 = clamp(dir1.xy / dirAbsMinTimesC, -2.0, 2.0);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat4 rgbyN2 = FxaaTexTop(tex, pos.xy - dir2 * fxaaConsoleRcpFrameOpt2.zw);
+ FxaaFloat4 rgbyP2 = FxaaTexTop(tex, pos.xy + dir2 * fxaaConsoleRcpFrameOpt2.zw);
+/*--------------------------------------------------------------------------*/
+ FxaaFloat4 rgbyA = rgbyN1 + rgbyP1;
+ FxaaFloat4 rgbyB = ((rgbyN2 + rgbyP2) * 0.25) + (rgbyA * 0.25);
+/*--------------------------------------------------------------------------*/
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ FxaaBool twoTap = (rgbyB.w < lumaMin) || (rgbyB.w > lumaMax);
+ #else
+ FxaaBool twoTap = (rgbyB.y < lumaMin) || (rgbyB.y > lumaMax);
+ #endif
+ if(twoTap) rgbyB.xyz = rgbyA.xyz * 0.5;
+ return rgbyB; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+ FXAA3 CONSOLE - 360 PIXEL SHADER
+
+------------------------------------------------------------------------------
+This optimized version thanks to suggestions from Andy Luedke.
+Should be fully tex bound in all cases.
+As of the FXAA 3.11 release, I have still not tested this code,
+however I fixed a bug which was in both FXAA 3.9 and FXAA 3.10.
+And note this is replacing the old unoptimized version.
+If it does not work, please let me know so I can fix it.
+============================================================================*/
+#if (FXAA_360 == 1)
+/*--------------------------------------------------------------------------*/
+[reduceTempRegUsage(4)]
+float4 FxaaPixelShader(
+ // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+ FxaaFloat2 pos,
+ FxaaFloat4 fxaaConsolePosPos,
+ FxaaTex tex,
+ FxaaTex fxaaConsole360TexExpBiasNegOne,
+ FxaaTex fxaaConsole360TexExpBiasNegTwo,
+ FxaaFloat2 fxaaQualityRcpFrame,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ FxaaFloat fxaaQualitySubpix,
+ FxaaFloat fxaaQualityEdgeThreshold,
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+ float4 lumaNwNeSwSe;
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ asm {
+ tfetch2D lumaNwNeSwSe.w___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe._w__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe.__w_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe.___w, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
+ };
+ #else
+ asm {
+ tfetch2D lumaNwNeSwSe.y___, tex, pos.xy, OffsetX = -0.5, OffsetY = -0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe._y__, tex, pos.xy, OffsetX = 0.5, OffsetY = -0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe.__y_, tex, pos.xy, OffsetX = -0.5, OffsetY = 0.5, UseComputedLOD=false
+ tfetch2D lumaNwNeSwSe.___y, tex, pos.xy, OffsetX = 0.5, OffsetY = 0.5, UseComputedLOD=false
+ };
+ #endif
+/*--------------------------------------------------------------------------*/
+ lumaNwNeSwSe.y += 1.0/384.0;
+ float2 lumaMinTemp = min(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
+ float2 lumaMaxTemp = max(lumaNwNeSwSe.xy, lumaNwNeSwSe.zw);
+ float lumaMin = min(lumaMinTemp.x, lumaMinTemp.y);
+ float lumaMax = max(lumaMaxTemp.x, lumaMaxTemp.y);
+/*--------------------------------------------------------------------------*/
+ float4 rgbyM = tex2Dlod(tex, float4(pos.xy, 0.0, 0.0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ float lumaMinM = min(lumaMin, rgbyM.w);
+ float lumaMaxM = max(lumaMax, rgbyM.w);
+ #else
+ float lumaMinM = min(lumaMin, rgbyM.y);
+ float lumaMaxM = max(lumaMax, rgbyM.y);
+ #endif
+ if((lumaMaxM - lumaMinM) < max(fxaaConsoleEdgeThresholdMin, lumaMax * fxaaConsoleEdgeThreshold)) return rgbyM;
+/*--------------------------------------------------------------------------*/
+ float2 dir;
+ dir.x = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.yyxx);
+ dir.y = dot(lumaNwNeSwSe, fxaaConsole360ConstDir.xyxy);
+ dir = normalize(dir);
+/*--------------------------------------------------------------------------*/
+ float4 dir1 = dir.xyxy * fxaaConsoleRcpFrameOpt.xyzw;
+/*--------------------------------------------------------------------------*/
+ float4 dir2;
+ float dirAbsMinTimesC = min(abs(dir.x), abs(dir.y)) * fxaaConsoleEdgeSharpness;
+ dir2 = saturate(fxaaConsole360ConstDir.zzww * dir.xyxy / dirAbsMinTimesC + 0.5);
+ dir2 = dir2 * fxaaConsole360RcpFrameOpt2.xyxy + fxaaConsole360RcpFrameOpt2.zwzw;
+/*--------------------------------------------------------------------------*/
+ float4 rgbyN1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.xy, 0.0, 0.0));
+ float4 rgbyP1 = tex2Dlod(fxaaConsole360TexExpBiasNegOne, float4(pos.xy + dir1.zw, 0.0, 0.0));
+ float4 rgbyN2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.xy, 0.0, 0.0));
+ float4 rgbyP2 = tex2Dlod(fxaaConsole360TexExpBiasNegTwo, float4(pos.xy + dir2.zw, 0.0, 0.0));
+/*--------------------------------------------------------------------------*/
+ float4 rgbyA = rgbyN1 + rgbyP1;
+ float4 rgbyB = rgbyN2 + rgbyP2 + rgbyA * 0.5;
+/*--------------------------------------------------------------------------*/
+ float4 rgbyR = ((FxaaLuma(rgbyB) - lumaMax) > 0.0) ? rgbyA : rgbyB;
+ rgbyR = ((FxaaLuma(rgbyB) - lumaMin) > 0.0) ? rgbyR : rgbyA;
+ return rgbyR; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+ FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (NO EARLY EXIT)
+
+==============================================================================
+The code below does not exactly match the assembly.
+I have a feeling that 12 cycles is possible, but was not able to get there.
+Might have to increase register count to get full performance.
+Note this shader does not use perspective interpolation.
+
+Use the following cgc options,
+
+ --fenable-bx2 --fastmath --fastprecision --nofloatbindings
+
+------------------------------------------------------------------------------
+ NVSHADERPERF OUTPUT
+------------------------------------------------------------------------------
+For reference and to aid in debug, output of NVShaderPerf should match this,
+
+Shader to schedule:
+ 0: texpkb h0.w(TRUE), v5.zyxx, #0
+ 2: addh h2.z(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
+ 4: texpkb h0.w(TRUE), v5.xwxx, #0
+ 6: addh h0.z(TRUE), -h2, h0.w
+ 7: texpkb h1.w(TRUE), v5, #0
+ 9: addh h0.x(TRUE), h0.z, -h1.w
+ 10: addh h3.w(TRUE), h0.z, h1
+ 11: texpkb h2.w(TRUE), v5.zwzz, #0
+ 13: addh h0.z(TRUE), h3.w, -h2.w
+ 14: addh h0.x(TRUE), h2.w, h0
+ 15: nrmh h1.xz(TRUE), h0_n
+ 16: minh_m8 h0.x(TRUE), |h1|, |h1.z|
+ 17: maxh h4.w(TRUE), h0, h1
+ 18: divx h2.xy(TRUE), h1_n.xzzw, h0_n
+ 19: movr r1.zw(TRUE), v4.xxxy
+ 20: madr r2.xz(TRUE), -h1, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zzww, r1.zzww
+ 22: minh h5.w(TRUE), h0, h1
+ 23: texpkb h0(TRUE), r2.xzxx, #0
+ 25: madr r0.zw(TRUE), h1.xzxz, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w), r1
+ 27: maxh h4.x(TRUE), h2.z, h2.w
+ 28: texpkb h1(TRUE), r0.zwzz, #0
+ 30: addh_d2 h1(TRUE), h0, h1
+ 31: madr r0.xy(TRUE), -h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 33: texpkb h0(TRUE), r0, #0
+ 35: minh h4.z(TRUE), h2, h2.w
+ 36: fenct TRUE
+ 37: madr r1.xy(TRUE), h2, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 39: texpkb h2(TRUE), r1, #0
+ 41: addh_d2 h0(TRUE), h0, h2
+ 42: maxh h2.w(TRUE), h4, h4.x
+ 43: minh h2.x(TRUE), h5.w, h4.z
+ 44: addh_d2 h0(TRUE), h0, h1
+ 45: slth h2.x(TRUE), h0.w, h2
+ 46: sgth h2.w(TRUE), h0, h2
+ 47: movh h0(TRUE), h0
+ 48: addx.c0 rc(TRUE), h2, h2.w
+ 49: movh h0(c0.NE.x), h1
+
+IPU0 ------ Simplified schedule: --------
+Pass | Unit | uOp | PC: Op
+-----+--------+------+-------------------------
+ 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+ | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+ | SCB1 | add | 2: ADDh h2.z, h0.--w-, const.--x-;
+ | | |
+ 2 | SCT0/1 | mov | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
+ | TEX | txl | 4: TXLr h0.w, g[TEX1].xwxx, const.xxxx, TEX0;
+ | SCB1 | add | 6: ADDh h0.z,-h2, h0.--w-;
+ | | |
+ 3 | SCT0/1 | mov | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0;
+ | TEX | txl | 7: TXLr h1.w, g[TEX1], const.xxxx, TEX0;
+ | SCB0 | add | 9: ADDh h0.x, h0.z---,-h1.w---;
+ | SCB1 | add | 10: ADDh h3.w, h0.---z, h1;
+ | | |
+ 4 | SCT0/1 | mov | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+ | TEX | txl | 11: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+ | SCB0 | add | 14: ADDh h0.x, h2.w---, h0;
+ | SCB1 | add | 13: ADDh h0.z, h3.--w-,-h2.--w-;
+ | | |
+ 5 | SCT1 | mov | 15: NRMh h1.xz, h0;
+ | SRB | nrm | 15: NRMh h1.xz, h0;
+ | SCB0 | min | 16: MINh*8 h0.x, |h1|, |h1.z---|;
+ | SCB1 | max | 17: MAXh h4.w, h0, h1;
+ | | |
+ 6 | SCT0 | div | 18: DIVx h2.xy, h1.xz--, h0;
+ | SCT1 | mov | 19: MOVr r1.zw, g[TEX0].--xy;
+ | SCB0 | mad | 20: MADr r2.xz,-h1, const.z-w-, r1.z-w-;
+ | SCB1 | min | 22: MINh h5.w, h0, h1;
+ | | |
+ 7 | SCT0/1 | mov | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0;
+ | TEX | txl | 23: TXLr h0, r2.xzxx, const.xxxx, TEX0;
+ | SCB0 | max | 27: MAXh h4.x, h2.z---, h2.w---;
+ | SCB1 | mad | 25: MADr r0.zw, h1.--xz, const, r1;
+ | | |
+ 8 | SCT0/1 | mov | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0;
+ | TEX | txl | 28: TXLr h1, r0.zwzz, const.xxxx, TEX0;
+ | SCB0/1 | add | 30: ADDh/2 h1, h0, h1;
+ | | |
+ 9 | SCT0 | mad | 31: MADr r0.xy,-h2, const.xy--, r1.zw--;
+ | SCT1 | mov | 33: TXLr h0, r0, const.zzzz, TEX0;
+ | TEX | txl | 33: TXLr h0, r0, const.zzzz, TEX0;
+ | SCB1 | min | 35: MINh h4.z, h2, h2.--w-;
+ | | |
+ 10 | SCT0 | mad | 37: MADr r1.xy, h2, const.xy--, r1.zw--;
+ | SCT1 | mov | 39: TXLr h2, r1, const.zzzz, TEX0;
+ | TEX | txl | 39: TXLr h2, r1, const.zzzz, TEX0;
+ | SCB0/1 | add | 41: ADDh/2 h0, h0, h2;
+ | | |
+ 11 | SCT0 | min | 43: MINh h2.x, h5.w---, h4.z---;
+ | SCT1 | max | 42: MAXh h2.w, h4, h4.---x;
+ | SCB0/1 | add | 44: ADDh/2 h0, h0, h1;
+ | | |
+ 12 | SCT0 | set | 45: SLTh h2.x, h0.w---, h2;
+ | SCT1 | set | 46: SGTh h2.w, h0, h2;
+ | SCB0/1 | mul | 47: MOVh h0, h0;
+ | | |
+ 13 | SCT0 | mad | 48: ADDxc0_s rc, h2, h2.w---;
+ | SCB0/1 | mul | 49: MOVh h0(NE0.xxxx), h1;
+
+Pass SCT TEX SCB
+ 1: 0% 100% 25%
+ 2: 0% 100% 25%
+ 3: 0% 100% 50%
+ 4: 0% 100% 50%
+ 5: 0% 0% 50%
+ 6: 100% 0% 75%
+ 7: 0% 100% 75%
+ 8: 0% 100% 100%
+ 9: 0% 100% 25%
+ 10: 0% 100% 100%
+ 11: 50% 0% 100%
+ 12: 50% 0% 100%
+ 13: 25% 0% 100%
+
+MEAN: 17% 61% 67%
+
+Pass SCT0 SCT1 TEX SCB0 SCB1
+ 1: 0% 0% 100% 0% 100%
+ 2: 0% 0% 100% 0% 100%
+ 3: 0% 0% 100% 100% 100%
+ 4: 0% 0% 100% 100% 100%
+ 5: 0% 0% 0% 100% 100%
+ 6: 100% 100% 0% 100% 100%
+ 7: 0% 0% 100% 100% 100%
+ 8: 0% 0% 100% 100% 100%
+ 9: 0% 0% 100% 0% 100%
+ 10: 0% 0% 100% 100% 100%
+ 11: 100% 100% 0% 100% 100%
+ 12: 100% 100% 0% 100% 100%
+ 13: 100% 0% 0% 100% 100%
+
+MEAN: 30% 23% 61% 76% 100%
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
+Results 13 cycles, 3 r regs, 923,076,923 pixels/s
+============================================================================*/
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 0)
+/*--------------------------------------------------------------------------*/
+#pragma regcount 7
+#pragma disablepc all
+#pragma option O3
+#pragma option OutColorPrec=fp16
+#pragma texformat default RGBA8
+/*==========================================================================*/
+half4 FxaaPixelShader(
+ // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+ FxaaFloat2 pos,
+ FxaaFloat4 fxaaConsolePosPos,
+ FxaaTex tex,
+ FxaaTex fxaaConsole360TexExpBiasNegOne,
+ FxaaTex fxaaConsole360TexExpBiasNegTwo,
+ FxaaFloat2 fxaaQualityRcpFrame,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ FxaaFloat fxaaQualitySubpix,
+ FxaaFloat fxaaQualityEdgeThreshold,
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+// (1)
+ half4 dir;
+ half4 lumaNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ lumaNe.w += half(1.0/512.0);
+ dir.x = -lumaNe.w;
+ dir.z = -lumaNe.w;
+ #else
+ lumaNe.y += half(1.0/512.0);
+ dir.x = -lumaNe.y;
+ dir.z = -lumaNe.y;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (2)
+ half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ dir.x += lumaSw.w;
+ dir.z += lumaSw.w;
+ #else
+ dir.x += lumaSw.y;
+ dir.z += lumaSw.y;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (3)
+ half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ dir.x -= lumaNw.w;
+ dir.z += lumaNw.w;
+ #else
+ dir.x -= lumaNw.y;
+ dir.z += lumaNw.y;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (4)
+ half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ dir.x += lumaSe.w;
+ dir.z -= lumaSe.w;
+ #else
+ dir.x += lumaSe.y;
+ dir.z -= lumaSe.y;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (5)
+ half4 dir1_pos;
+ dir1_pos.xy = normalize(dir.xyz).xz;
+ half dirAbsMinTimesC = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
+/*--------------------------------------------------------------------------*/
+// (6)
+ half4 dir2_pos;
+ dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimesC, half(-2.0), half(2.0));
+ dir1_pos.zw = pos.xy;
+ dir2_pos.zw = pos.xy;
+ half4 temp1N;
+ temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+/*--------------------------------------------------------------------------*/
+// (7)
+ temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
+ half4 rgby1;
+ rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+/*--------------------------------------------------------------------------*/
+// (8)
+ rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
+ rgby1 = (temp1N + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (9)
+ half4 temp2N;
+ temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+ temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
+/*--------------------------------------------------------------------------*/
+// (10)
+ half4 rgby2;
+ rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+ rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
+ rgby2 = (temp2N + rgby2) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (11)
+ // compilier moves these scalar ops up to other cycles
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaMin = min(min(lumaNw.w, lumaSw.w), min(lumaNe.w, lumaSe.w));
+ half lumaMax = max(max(lumaNw.w, lumaSw.w), max(lumaNe.w, lumaSe.w));
+ #else
+ half lumaMin = min(min(lumaNw.y, lumaSw.y), min(lumaNe.y, lumaSe.y));
+ half lumaMax = max(max(lumaNw.y, lumaSw.y), max(lumaNe.y, lumaSe.y));
+ #endif
+ rgby2 = (rgby2 + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (12)
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ bool twoTapLt = rgby2.w < lumaMin;
+ bool twoTapGt = rgby2.w > lumaMax;
+ #else
+ bool twoTapLt = rgby2.y < lumaMin;
+ bool twoTapGt = rgby2.y > lumaMax;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (13)
+ if(twoTapLt || twoTapGt) rgby2 = rgby1;
+/*--------------------------------------------------------------------------*/
+ return rgby2; }
+/*==========================================================================*/
+#endif
+
+
+
+/*============================================================================
+
+ FXAA3 CONSOLE - OPTIMIZED PS3 PIXEL SHADER (WITH EARLY EXIT)
+
+==============================================================================
+The code mostly matches the assembly.
+I have a feeling that 14 cycles is possible, but was not able to get there.
+Might have to increase register count to get full performance.
+Note this shader does not use perspective interpolation.
+
+Use the following cgc options,
+
+ --fenable-bx2 --fastmath --fastprecision --nofloatbindings
+
+Use of FXAA_GREEN_AS_LUMA currently adds a cycle (16 clks).
+Will look at fixing this for FXAA 3.12.
+------------------------------------------------------------------------------
+ NVSHADERPERF OUTPUT
+------------------------------------------------------------------------------
+For reference and to aid in debug, output of NVShaderPerf should match this,
+
+Shader to schedule:
+ 0: texpkb h0.w(TRUE), v5.zyxx, #0
+ 2: addh h2.y(TRUE), h0.w, constant(0.001953, 0.000000, 0.000000, 0.000000).x
+ 4: texpkb h1.w(TRUE), v5.xwxx, #0
+ 6: addh h0.x(TRUE), h1.w, -h2.y
+ 7: texpkb h2.w(TRUE), v5.zwzz, #0
+ 9: minh h4.w(TRUE), h2.y, h2
+ 10: maxh h5.x(TRUE), h2.y, h2.w
+ 11: texpkb h0.w(TRUE), v5, #0
+ 13: addh h3.w(TRUE), -h0, h0.x
+ 14: addh h0.x(TRUE), h0.w, h0
+ 15: addh h0.z(TRUE), -h2.w, h0.x
+ 16: addh h0.x(TRUE), h2.w, h3.w
+ 17: minh h5.y(TRUE), h0.w, h1.w
+ 18: nrmh h2.xz(TRUE), h0_n
+ 19: minh_m8 h2.w(TRUE), |h2.x|, |h2.z|
+ 20: divx h4.xy(TRUE), h2_n.xzzw, h2_n.w
+ 21: movr r1.zw(TRUE), v4.xxxy
+ 22: maxh h2.w(TRUE), h0, h1
+ 23: fenct TRUE
+ 24: madr r0.xy(TRUE), -h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
+ 26: texpkb h0(TRUE), r0, #0
+ 28: maxh h5.x(TRUE), h2.w, h5
+ 29: minh h5.w(TRUE), h5.y, h4
+ 30: madr r1.xy(TRUE), h2.xzzw, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).zwzz, r1.zwzz
+ 32: texpkb h2(TRUE), r1, #0
+ 34: addh_d2 h2(TRUE), h0, h2
+ 35: texpkb h1(TRUE), v4, #0
+ 37: maxh h5.y(TRUE), h5.x, h1.w
+ 38: minh h4.w(TRUE), h1, h5
+ 39: madr r0.xy(TRUE), -h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 41: texpkb h0(TRUE), r0, #0
+ 43: addh_m8 h5.z(TRUE), h5.y, -h4.w
+ 44: madr r2.xy(TRUE), h4, constant(cConst5.x, cConst5.y, cConst5.z, cConst5.w).xyxx, r1.zwzz
+ 46: texpkb h3(TRUE), r2, #0
+ 48: addh_d2 h0(TRUE), h0, h3
+ 49: addh_d2 h3(TRUE), h0, h2
+ 50: movh h0(TRUE), h3
+ 51: slth h3.x(TRUE), h3.w, h5.w
+ 52: sgth h3.w(TRUE), h3, h5.x
+ 53: addx.c0 rc(TRUE), h3.x, h3
+ 54: slth.c0 rc(TRUE), h5.z, h5
+ 55: movh h0(c0.NE.w), h2
+ 56: movh h0(c0.NE.x), h1
+
+IPU0 ------ Simplified schedule: --------
+Pass | Unit | uOp | PC: Op
+-----+--------+------+-------------------------
+ 1 | SCT0/1 | mov | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+ | TEX | txl | 0: TXLr h0.w, g[TEX1].zyxx, const.xxxx, TEX0;
+ | SCB0 | add | 2: ADDh h2.y, h0.-w--, const.-x--;
+ | | |
+ 2 | SCT0/1 | mov | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
+ | TEX | txl | 4: TXLr h1.w, g[TEX1].xwxx, const.xxxx, TEX0;
+ | SCB0 | add | 6: ADDh h0.x, h1.w---,-h2.y---;
+ | | |
+ 3 | SCT0/1 | mov | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+ | TEX | txl | 7: TXLr h2.w, g[TEX1].zwzz, const.xxxx, TEX0;
+ | SCB0 | max | 10: MAXh h5.x, h2.y---, h2.w---;
+ | SCB1 | min | 9: MINh h4.w, h2.---y, h2;
+ | | |
+ 4 | SCT0/1 | mov | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0;
+ | TEX | txl | 11: TXLr h0.w, g[TEX1], const.xxxx, TEX0;
+ | SCB0 | add | 14: ADDh h0.x, h0.w---, h0;
+ | SCB1 | add | 13: ADDh h3.w,-h0, h0.---x;
+ | | |
+ 5 | SCT0 | mad | 16: ADDh h0.x, h2.w---, h3.w---;
+ | SCT1 | mad | 15: ADDh h0.z,-h2.--w-, h0.--x-;
+ | SCB0 | min | 17: MINh h5.y, h0.-w--, h1.-w--;
+ | | |
+ 6 | SCT1 | mov | 18: NRMh h2.xz, h0;
+ | SRB | nrm | 18: NRMh h2.xz, h0;
+ | SCB1 | min | 19: MINh*8 h2.w, |h2.---x|, |h2.---z|;
+ | | |
+ 7 | SCT0 | div | 20: DIVx h4.xy, h2.xz--, h2.ww--;
+ | SCT1 | mov | 21: MOVr r1.zw, g[TEX0].--xy;
+ | SCB1 | max | 22: MAXh h2.w, h0, h1;
+ | | |
+ 8 | SCT0 | mad | 24: MADr r0.xy,-h2.xz--, const.zw--, r1.zw--;
+ | SCT1 | mov | 26: TXLr h0, r0, const.xxxx, TEX0;
+ | TEX | txl | 26: TXLr h0, r0, const.xxxx, TEX0;
+ | SCB0 | max | 28: MAXh h5.x, h2.w---, h5;
+ | SCB1 | min | 29: MINh h5.w, h5.---y, h4;
+ | | |
+ 9 | SCT0 | mad | 30: MADr r1.xy, h2.xz--, const.zw--, r1.zw--;
+ | SCT1 | mov | 32: TXLr h2, r1, const.xxxx, TEX0;
+ | TEX | txl | 32: TXLr h2, r1, const.xxxx, TEX0;
+ | SCB0/1 | add | 34: ADDh/2 h2, h0, h2;
+ | | |
+ 10 | SCT0/1 | mov | 35: TXLr h1, g[TEX0], const.xxxx, TEX0;
+ | TEX | txl | 35: TXLr h1, g[TEX0], const.xxxx, TEX0;
+ | SCB0 | max | 37: MAXh h5.y, h5.-x--, h1.-w--;
+ | SCB1 | min | 38: MINh h4.w, h1, h5;
+ | | |
+ 11 | SCT0 | mad | 39: MADr r0.xy,-h4, const.xy--, r1.zw--;
+ | SCT1 | mov | 41: TXLr h0, r0, const.zzzz, TEX0;
+ | TEX | txl | 41: TXLr h0, r0, const.zzzz, TEX0;
+ | SCB0 | mad | 44: MADr r2.xy, h4, const.xy--, r1.zw--;
+ | SCB1 | add | 43: ADDh*8 h5.z, h5.--y-,-h4.--w-;
+ | | |
+ 12 | SCT0/1 | mov | 46: TXLr h3, r2, const.xxxx, TEX0;
+ | TEX | txl | 46: TXLr h3, r2, const.xxxx, TEX0;
+ | SCB0/1 | add | 48: ADDh/2 h0, h0, h3;
+ | | |
+ 13 | SCT0/1 | mad | 49: ADDh/2 h3, h0, h2;
+ | SCB0/1 | mul | 50: MOVh h0, h3;
+ | | |
+ 14 | SCT0 | set | 51: SLTh h3.x, h3.w---, h5.w---;
+ | SCT1 | set | 52: SGTh h3.w, h3, h5.---x;
+ | SCB0 | set | 54: SLThc0 rc, h5.z---, h5;
+ | SCB1 | add | 53: ADDxc0_s rc, h3.---x, h3;
+ | | |
+ 15 | SCT0/1 | mul | 55: MOVh h0(NE0.wwww), h2;
+ | SCB0/1 | mul | 56: MOVh h0(NE0.xxxx), h1;
+
+Pass SCT TEX SCB
+ 1: 0% 100% 25%
+ 2: 0% 100% 25%
+ 3: 0% 100% 50%
+ 4: 0% 100% 50%
+ 5: 50% 0% 25%
+ 6: 0% 0% 25%
+ 7: 100% 0% 25%
+ 8: 0% 100% 50%
+ 9: 0% 100% 100%
+ 10: 0% 100% 50%
+ 11: 0% 100% 75%
+ 12: 0% 100% 100%
+ 13: 100% 0% 100%
+ 14: 50% 0% 50%
+ 15: 100% 0% 100%
+
+MEAN: 26% 60% 56%
+
+Pass SCT0 SCT1 TEX SCB0 SCB1
+ 1: 0% 0% 100% 100% 0%
+ 2: 0% 0% 100% 100% 0%
+ 3: 0% 0% 100% 100% 100%
+ 4: 0% 0% 100% 100% 100%
+ 5: 100% 100% 0% 100% 0%
+ 6: 0% 0% 0% 0% 100%
+ 7: 100% 100% 0% 0% 100%
+ 8: 0% 0% 100% 100% 100%
+ 9: 0% 0% 100% 100% 100%
+ 10: 0% 0% 100% 100% 100%
+ 11: 0% 0% 100% 100% 100%
+ 12: 0% 0% 100% 100% 100%
+ 13: 100% 100% 0% 100% 100%
+ 14: 100% 100% 0% 100% 100%
+ 15: 100% 100% 0% 100% 100%
+
+MEAN: 33% 33% 60% 86% 80%
+Fragment Performance Setup: Driver RSX Compiler, GPU RSX, Flags 0x5
+Results 15 cycles, 3 r regs, 800,000,000 pixels/s
+============================================================================*/
+#if (FXAA_PS3 == 1) && (FXAA_EARLY_EXIT == 1)
+/*--------------------------------------------------------------------------*/
+#pragma regcount 7
+#pragma disablepc all
+#pragma option O2
+#pragma option OutColorPrec=fp16
+#pragma texformat default RGBA8
+/*==========================================================================*/
+half4 FxaaPixelShader(
+ // See FXAA Quality FxaaPixelShader() source for docs on Inputs!
+ FxaaFloat2 pos,
+ FxaaFloat4 fxaaConsolePosPos,
+ FxaaTex tex,
+ FxaaTex fxaaConsole360TexExpBiasNegOne,
+ FxaaTex fxaaConsole360TexExpBiasNegTwo,
+ FxaaFloat2 fxaaQualityRcpFrame,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt,
+ FxaaFloat4 fxaaConsoleRcpFrameOpt2,
+ FxaaFloat4 fxaaConsole360RcpFrameOpt2,
+ FxaaFloat fxaaQualitySubpix,
+ FxaaFloat fxaaQualityEdgeThreshold,
+ FxaaFloat fxaaQualityEdgeThresholdMin,
+ FxaaFloat fxaaConsoleEdgeSharpness,
+ FxaaFloat fxaaConsoleEdgeThreshold,
+ FxaaFloat fxaaConsoleEdgeThresholdMin,
+ FxaaFloat4 fxaaConsole360ConstDir
+) {
+/*--------------------------------------------------------------------------*/
+// (1)
+ half4 rgbyNe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zy, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaNe = rgbyNe.w + half(1.0/512.0);
+ #else
+ half lumaNe = rgbyNe.y + half(1.0/512.0);
+ #endif
+/*--------------------------------------------------------------------------*/
+// (2)
+ half4 lumaSw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xw, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaSwNegNe = lumaSw.w - lumaNe;
+ #else
+ half lumaSwNegNe = lumaSw.y - lumaNe;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (3)
+ half4 lumaNw = h4tex2Dlod(tex, half4(fxaaConsolePosPos.xy, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaMaxNwSw = max(lumaNw.w, lumaSw.w);
+ half lumaMinNwSw = min(lumaNw.w, lumaSw.w);
+ #else
+ half lumaMaxNwSw = max(lumaNw.y, lumaSw.y);
+ half lumaMinNwSw = min(lumaNw.y, lumaSw.y);
+ #endif
+/*--------------------------------------------------------------------------*/
+// (4)
+ half4 lumaSe = h4tex2Dlod(tex, half4(fxaaConsolePosPos.zw, 0, 0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half dirZ = lumaNw.w + lumaSwNegNe;
+ half dirX = -lumaNw.w + lumaSwNegNe;
+ #else
+ half dirZ = lumaNw.y + lumaSwNegNe;
+ half dirX = -lumaNw.y + lumaSwNegNe;
+ #endif
+/*--------------------------------------------------------------------------*/
+// (5)
+ half3 dir;
+ dir.y = 0.0;
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ dir.x = lumaSe.w + dirX;
+ dir.z = -lumaSe.w + dirZ;
+ half lumaMinNeSe = min(lumaNe, lumaSe.w);
+ #else
+ dir.x = lumaSe.y + dirX;
+ dir.z = -lumaSe.y + dirZ;
+ half lumaMinNeSe = min(lumaNe, lumaSe.y);
+ #endif
+/*--------------------------------------------------------------------------*/
+// (6)
+ half4 dir1_pos;
+ dir1_pos.xy = normalize(dir).xz;
+ half dirAbsMinTimes8 = min(abs(dir1_pos.x), abs(dir1_pos.y)) * half(FXAA_CONSOLE__PS3_EDGE_SHARPNESS);
+/*--------------------------------------------------------------------------*/
+// (7)
+ half4 dir2_pos;
+ dir2_pos.xy = clamp(dir1_pos.xy / dirAbsMinTimes8, half(-2.0), half(2.0));
+ dir1_pos.zw = pos.xy;
+ dir2_pos.zw = pos.xy;
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaMaxNeSe = max(lumaNe, lumaSe.w);
+ #else
+ half lumaMaxNeSe = max(lumaNe, lumaSe.y);
+ #endif
+/*--------------------------------------------------------------------------*/
+// (8)
+ half4 temp1N;
+ temp1N.xy = dir1_pos.zw - dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+ temp1N = h4tex2Dlod(tex, half4(temp1N.xy, 0.0, 0.0));
+ half lumaMax = max(lumaMaxNwSw, lumaMaxNeSe);
+ half lumaMin = min(lumaMinNwSw, lumaMinNeSe);
+/*--------------------------------------------------------------------------*/
+// (9)
+ half4 rgby1;
+ rgby1.xy = dir1_pos.zw + dir1_pos.xy * fxaaConsoleRcpFrameOpt.zw;
+ rgby1 = h4tex2Dlod(tex, half4(rgby1.xy, 0.0, 0.0));
+ rgby1 = (temp1N + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (10)
+ half4 rgbyM = h4tex2Dlod(tex, half4(pos.xy, 0.0, 0.0));
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ half lumaMaxM = max(lumaMax, rgbyM.w);
+ half lumaMinM = min(lumaMin, rgbyM.w);
+ #else
+ half lumaMaxM = max(lumaMax, rgbyM.y);
+ half lumaMinM = min(lumaMin, rgbyM.y);
+ #endif
+/*--------------------------------------------------------------------------*/
+// (11)
+ half4 temp2N;
+ temp2N.xy = dir2_pos.zw - dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+ temp2N = h4tex2Dlod(tex, half4(temp2N.xy, 0.0, 0.0));
+ half4 rgby2;
+ rgby2.xy = dir2_pos.zw + dir2_pos.xy * fxaaConsoleRcpFrameOpt2.zw;
+ half lumaRangeM = (lumaMaxM - lumaMinM) / FXAA_CONSOLE__PS3_EDGE_THRESHOLD;
+/*--------------------------------------------------------------------------*/
+// (12)
+ rgby2 = h4tex2Dlod(tex, half4(rgby2.xy, 0.0, 0.0));
+ rgby2 = (temp2N + rgby2) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (13)
+ rgby2 = (rgby2 + rgby1) * 0.5;
+/*--------------------------------------------------------------------------*/
+// (14)
+ #if (FXAA_GREEN_AS_LUMA == 0)
+ bool twoTapLt = rgby2.w < lumaMin;
+ bool twoTapGt = rgby2.w > lumaMax;
+ #else
+ bool twoTapLt = rgby2.y < lumaMin;
+ bool twoTapGt = rgby2.y > lumaMax;
+ #endif
+ bool earlyExit = lumaRangeM < lumaMax;
+ bool twoTap = twoTapLt || twoTapGt;
+/*--------------------------------------------------------------------------*/
+// (15)
+ if(twoTap) rgby2 = rgby1;
+ if(earlyExit) rgby2 = rgbyM;
+/*--------------------------------------------------------------------------*/
+ return rgby2; }
+/*==========================================================================*/
+#endif
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl
new file mode 100644
index 000000000..269bfea67
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaP.hlsl
@@ -0,0 +1,143 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+#define FXAA_PC 1
+#if (TORQUE_SM <= 30)
+#define FXAA_HLSL_3 1
+#elif TORQUE_SM < 49
+#define FXAA_HLSL_4 1
+#elif TORQUE_SM >=50
+#define FXAA_HLSL_5 1
+#endif
+#define FXAA_QUALITY__PRESET 12
+#define FXAA_GREEN_AS_LUMA 1
+
+#include "Fxaa3_11.h"
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(colorTex, 0);
+
+uniform float2 oneOverTargetSize;
+
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+#if (TORQUE_SM >= 10 && TORQUE_SM <=30)
+ FxaaTex tex = colorTex;
+#elif TORQUE_SM >=40
+ FxaaTex tex;
+ tex.smpl = colorTex;
+ tex.tex = texture_colorTex;
+#endif
+
+ return FxaaPixelShader(
+
+ IN.uv0, // vertex position
+
+ 0, // Unused... console stuff
+
+ tex, // The color back buffer
+
+ tex, // Used for 360 optimization
+
+ tex, // Used for 360 optimization
+
+ oneOverTargetSize,
+
+ 0, // Unused... console stuff
+
+ 0, // Unused... console stuff
+
+ 0, // Unused... console stuff
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__SUBPIX define.
+ // It is here now to allow easier tuning.
+ // Choose the amount of sub-pixel aliasing removal.
+ // This can effect sharpness.
+ // 1.00 - upper limit (softer)
+ // 0.75 - default amount of filtering
+ // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+ // 0.25 - almost off
+ // 0.00 - completely off
+ 0.75,
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
+ // It is here now to allow easier tuning.
+ // The minimum amount of local contrast required to apply algorithm.
+ // 0.333 - too little (faster)
+ // 0.250 - low quality
+ // 0.166 - default
+ // 0.125 - high quality
+ // 0.063 - overkill (slower)
+ 0.166,
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
+ // It is here now to allow easier tuning.
+ // Trims the algorithm from processing darks.
+ // 0.0833 - upper limit (default, the start of visible unfiltered edges)
+ // 0.0625 - high quality (faster)
+ // 0.0312 - visible limit (slower)
+ // Special notes when using FXAA_GREEN_AS_LUMA,
+ // Likely want to set this to zero.
+ // As colors that are mostly not-green
+ // will appear very dark in the green channel!
+ // Tune by looking at mostly non-green content,
+ // then start at zero and increase until aliasing is a problem.
+ 0,
+
+ //
+ // Only used on FXAA Console.
+ // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
+ // It is here now to allow easier tuning.
+ // This does not effect PS3, as this needs to be compiled in.
+ // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
+ // Due to the PS3 being ALU bound,
+ // there are only three safe values here: 2 and 4 and 8.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ // For all other platforms can be a non-power of two.
+ // 8.0 is sharper (default!!!)
+ // 4.0 is softer
+ // 2.0 is really soft (good only for vector graphics inputs)
+ 8,
+
+ 0, // Unused... console stuff
+
+ 0, // Unused... console stuff
+
+ 0 // Unused... console stuff
+
+ );
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaV.hlsl
new file mode 100644
index 000000000..f2974c587
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/fxaaV.hlsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "./../postFx.hlsl"
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 uv0 : TEXCOORD0;
+};
+
+uniform float4 rtParams0;
+
+VertToPix main( PFXVert IN )
+{
+ VertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1);
+ OUT.uv0 = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaP.glsl
new file mode 100644
index 000000000..19d76ef42
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaP.glsl
@@ -0,0 +1,125 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define FXAA_PC 1
+#define FXAA_GLSL_130 1
+#define FXAA_QUALITY__PRESET 12
+#define FXAA_GREEN_AS_LUMA 1
+
+#include "../Fxaa3_11.h"
+#include "../../../gl/hlslCompat.glsl"
+
+uniform sampler2D colorTex ;
+uniform vec2 oneOverTargetSize;
+
+in vec4 hpos;
+in vec2 uv0;
+
+out vec4 OUT_col;
+
+void main()
+{
+ OUT_col = FxaaPixelShader(
+
+ uv0, // vertex position
+
+ vec4(0), // Unused... console stuff
+
+ colorTex, // The color back buffer
+
+ colorTex, // Used for 360 optimization
+
+ colorTex, // Used for 360 optimization
+
+ oneOverTargetSize,
+
+ vec4(0), // Unused... console stuff
+
+ vec4(0), // Unused... console stuff
+
+ vec4(0), // Unused... console stuff
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__SUBPIX define.
+ // It is here now to allow easier tuning.
+ // Choose the amount of sub-pixel aliasing removal.
+ // This can effect sharpness.
+ // 1.00 - upper limit (softer)
+ // 0.75 - default amount of filtering
+ // 0.50 - lower limit (sharper, less sub-pixel aliasing removal)
+ // 0.25 - almost off
+ // 0.00 - completely off
+ 0.75,
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD define.
+ // It is here now to allow easier tuning.
+ // The minimum amount of local contrast required to apply algorithm.
+ // 0.333 - too little (faster)
+ // 0.250 - low quality
+ // 0.166 - default
+ // 0.125 - high quality
+ // 0.063 - overkill (slower)
+ 0.166,
+
+ //
+ // Only used on FXAA Quality.
+ // This used to be the FXAA_QUALITY__EDGE_THRESHOLD_MIN define.
+ // It is here now to allow easier tuning.
+ // Trims the algorithm from processing darks.
+ // 0.0833 - upper limit (default, the start of visible unfiltered edges)
+ // 0.0625 - high quality (faster)
+ // 0.0312 - visible limit (slower)
+ // Special notes when using FXAA_GREEN_AS_LUMA,
+ // Likely want to set this to zero.
+ // As colors that are mostly not-green
+ // will appear very dark in the green channel!
+ // Tune by looking at mostly non-green content,
+ // then start at zero and increase until aliasing is a problem.
+ 0,
+
+ //
+ // Only used on FXAA Console.
+ // This used to be the FXAA_CONSOLE__EDGE_SHARPNESS define.
+ // It is here now to allow easier tuning.
+ // This does not effect PS3, as this needs to be compiled in.
+ // Use FXAA_CONSOLE__PS3_EDGE_SHARPNESS for PS3.
+ // Due to the PS3 being ALU bound,
+ // there are only three safe values here: 2 and 4 and 8.
+ // These options use the shaders ability to a free *|/ by 2|4|8.
+ // For all other platforms can be a non-power of two.
+ // 8.0 is sharper (default!!!)
+ // 4.0 is softer
+ // 2.0 is really soft (good only for vector graphics inputs)
+ 8,
+
+ 0, // Unused... console stuff
+
+ 0, // Unused... console stuff
+
+ vec4(0) // Unused... console stuff
+
+ );
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaV.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaV.glsl
new file mode 100644
index 000000000..55d445d91
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/fxaa/gl/fxaaV.glsl
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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 "../../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform vec4 rtParams0;
+
+out vec4 hpos;
+out vec2 uv0;
+
+void main()
+{
+ gl_Position = vPosition;
+ hpos = gl_Position;
+ uv0 = viewportCoordToRenderTarget( vTexCoord0, rtParams0 );
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl
new file mode 100644
index 000000000..1e13d068b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gammaP.hlsl
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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 "shadergen:/autogenConditioners.h"
+#include "./postFx.hlsl"
+#include "../torque.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+TORQUE_UNIFORM_SAMPLER1D(colorCorrectionTex, 1);
+
+uniform float OneOverGamma;
+uniform float Brightness;
+uniform float Contrast;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 color = TORQUE_TEX2D(backBuffer, IN.uv0.xy);
+
+ // Apply the color correction.
+ color.r = TORQUE_TEX1D( colorCorrectionTex, color.r ).r;
+ color.g = TORQUE_TEX1D( colorCorrectionTex, color.g ).g;
+ color.b = TORQUE_TEX1D( colorCorrectionTex, color.b ).b;
+
+ // Apply contrast
+ color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f;
+
+ // Apply brightness
+ color.rgb += Brightness;
+
+ return color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/VolFogGlowP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/VolFogGlowP.glsl
new file mode 100644
index 000000000..01b072dd9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/VolFogGlowP.glsl
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2014 R.G.S. - Richards Game Studio, the Netherlands
+// http://www.richardsgamestudio.com/
+//
+// If you find this code useful or you are feeling particularly generous I
+// would ask that you please go to http://www.richardsgamestudio.com/ then
+// choose Donations from the menu on the left side and make a donation to
+// Richards Game Studio. It will be highly appreciated.
+//
+// The MIT License:
+//
+// 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.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog Glow postFx pixel shader V1.00
+
+uniform sampler2D diffuseMap;
+uniform float strength;
+
+out vec4 OUT_col;
+
+in vec2 uv0;
+in vec2 uv1;
+in vec2 uv2;
+in vec2 uv3;
+
+in vec2 uv4;
+in vec2 uv5;
+in vec2 uv6;
+in vec2 uv7;
+
+void main()
+{
+ vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * strength;
+
+ OUT_col = vec4(0);
+ OUT_col += texture( diffuseMap, uv0 ) * kernel.x;
+ OUT_col += texture( diffuseMap, uv1 ) * kernel.y;
+ OUT_col += texture( diffuseMap, uv2 ) * kernel.z;
+ OUT_col += texture( diffuseMap, uv3 ) * kernel.w;
+
+ OUT_col += texture( diffuseMap, uv4 ) * kernel.x;
+ OUT_col += texture( diffuseMap, uv5 ) * kernel.y;
+ OUT_col += texture( diffuseMap, uv6 ) * kernel.z;
+ OUT_col += texture( diffuseMap, uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 );
+ OUT_col.a = dot( OUT_col.rgb, rgb2lum );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/chromaticLens.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/chromaticLens.glsl
new file mode 100644
index 000000000..fdb85ba00
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/chromaticLens.glsl
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Based on 'Cubic Lens Distortion HLSL Shader' by François Tarlier
+// www.francois-tarlier.com/blog/index.php/2009/11/cubic-lens-distortion-shader
+
+#include "./postFX.glsl"
+#include "../../gl/torque.glsl"
+#include "../../gl/hlslCompat.glsl"
+
+uniform sampler2D backBuffer;
+uniform float distCoeff;
+uniform float cubeDistort;
+uniform vec3 colorDistort;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec2 tex = IN_uv0;
+
+ float f = 0;
+ float r2 = (tex.x - 0.5) * (tex.x - 0.5) + (tex.y - 0.5) * (tex.y - 0.5);
+
+ // Only compute the cubic distortion if necessary.
+ if ( cubeDistort == 0.0 )
+ f = 1 + r2 * distCoeff;
+ else
+ f = 1 + r2 * (distCoeff + cubeDistort * sqrt(r2));
+
+ // Distort each color channel seperately to get a chromatic distortion effect.
+ vec3 outColor;
+ vec3 distort = vec3(f) + colorDistort;
+
+ for ( int i=0; i < 3; i++ )
+ {
+ float x = distort[i] * ( tex.x - 0.5 ) + 0.5;
+ float y = distort[i] * ( tex.y - 0.5 ) + 0.5;
+ outColor[i] = tex2Dlod( backBuffer, vec4(x,y,0,0) )[i];
+ }
+
+ OUT_col = vec4( outColor.rgb, 1 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/flashP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/flashP.glsl
new file mode 100644
index 000000000..fc5072e6d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/flashP.glsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFX.glsl"
+#include "../../gl/torque.glsl"
+#include "../../gl/hlslCompat.glsl"
+
+uniform float damageFlash;
+uniform float whiteOut;
+uniform sampler2D backBuffer;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 color1 = texture(backBuffer, IN_uv0);
+ vec4 color2 = color1 * MUL_COLOR;
+ vec4 damage = mix(color1,color2,damageFlash);
+ OUT_col = mix(damage,WHITE_COLOR,whiteOut);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/fogP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/fogP.glsl
new file mode 100644
index 000000000..c2fe32fe4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/fogP.glsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+
+uniform sampler2D deferredTex ;
+uniform vec3 eyePosWorld;
+uniform vec4 fogColor;
+uniform vec3 fogData;
+uniform vec4 rtParams0;
+
+in vec2 uv0;
+in vec3 wsEyeRay;
+
+out vec4 OUT_col;
+
+void main()
+{
+ //vec2 deferredCoord = ( uv0.xy * rtParams0.zw ) + rtParams0.xy;
+ float depth = deferredUncondition( deferredTex, uv0 ).w;
+ //return vec4( depth, 0, 0, 0.7 );
+
+ float factor = computeSceneFog( eyePosWorld,
+ eyePosWorld + ( wsEyeRay * depth ),
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ OUT_col = hdrEncode( vec4( fogColor.rgb, 1.0 - saturate( factor ) ) );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/gammaP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/gammaP.glsl
new file mode 100644
index 000000000..04533e494
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/gammaP.glsl
@@ -0,0 +1,54 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+#include "shadergen:/autogenConditioners.h"
+
+uniform sampler2D backBuffer;
+uniform sampler1D colorCorrectionTex;
+
+uniform float OneOverGamma;
+uniform float Brightness;
+uniform float Contrast;
+
+in vec2 uv0;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 color = texture(backBuffer, uv0.xy);
+
+ // Apply the color correction.
+ color.r = texture( colorCorrectionTex, color.r ).r;
+ color.g = texture( colorCorrectionTex, color.g ).g;
+ color.b = texture( colorCorrectionTex, color.b ).b;
+
+ // Apply contrast
+ color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f;
+
+ // Apply brightness
+ color.rgb += Brightness;
+
+ OUT_col = color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurP.glsl
new file mode 100644
index 000000000..9ebca32fa
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurP.glsl
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+uniform sampler2D diffuseMap ;
+
+in vec4 hpos; //POSITION;
+in vec2 uv0; //TEXCOORD0;
+in vec2 uv1; //TEXCOORD1;
+in vec2 uv2; //TEXCOORD2;
+in vec2 uv3; //TEXCOORD3;
+in vec2 uv4; //TEXCOORD4;
+in vec2 uv5; //TEXCOORD5;
+in vec2 uv6; //TEXCOORD6;
+in vec2 uv7; //TEXCOORD7;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ) * 0.5f;
+
+ OUT_col = vec4(0);
+ OUT_col += texture( diffuseMap, uv0 ) * kernel.x;
+ OUT_col += texture( diffuseMap, uv1 ) * kernel.y;
+ OUT_col += texture( diffuseMap, uv2 ) * kernel.z;
+ OUT_col += texture( diffuseMap, uv3 ) * kernel.w;
+
+ OUT_col += texture( diffuseMap, uv4 ) * kernel.x;
+ OUT_col += texture( diffuseMap, uv5 ) * kernel.y;
+ OUT_col += texture( diffuseMap, uv6 ) * kernel.z;
+ OUT_col += texture( diffuseMap, uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ vec3 rgb2lum = vec3( 0.30, 0.59, 0.11 );
+ OUT_col.a = dot( OUT_col.rgb, rgb2lum );
+
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurV.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurV.glsl
new file mode 100644
index 000000000..70445d7fe
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/glowBlurV.glsl
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+uniform vec2 texSize0;
+
+out vec4 hpos; //POSITION;
+out vec2 uv0; //TEXCOORD0;
+out vec2 uv1; //TEXCOORD1;
+out vec2 uv2; //TEXCOORD2;
+out vec2 uv3; //TEXCOORD3;
+out vec2 uv4; //TEXCOORD4;
+out vec2 uv5; //TEXCOORD5;
+out vec2 uv6; //TEXCOORD6;
+out vec2 uv7; //TEXCOORD7;
+
+void main()
+{
+ gl_Position = vPosition;
+ hpos = gl_Position;
+
+ vec2 uv = vTexCoord0 + (0.5f / texSize0);
+
+ uv0 = uv + ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ uv1 = uv + ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ uv2 = uv + ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ uv3 = uv + ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ uv4 = uv - ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ uv5 = uv - ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ uv6 = uv - ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ uv7 = uv - ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/motionBlurP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/motionBlurP.glsl
new file mode 100644
index 000000000..8077d4124
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/gl/motionBlurP.glsl
@@ -0,0 +1,78 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "postFX.glsl"
+
+#undef IN_uv0
+#define _IN_uv0 uv0
+
+uniform mat4 matPrevScreenToWorld;
+uniform mat4 matWorldToScreen;
+
+// Passed in from setShaderConsts()
+uniform float velocityMultiplier;
+
+uniform sampler2D backBuffer;
+uniform sampler2D deferredTex;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec2 IN_uv0 = _IN_uv0;
+ float samples = 5;
+
+ // First get the deferred texture for uv channel 0
+ vec4 deferred = deferredUncondition( deferredTex, IN_uv0 );
+
+ // Next extract the depth
+ float depth = deferred.a;
+
+ // Create the screen position
+ vec4 screenPos = vec4(IN_uv0.x*2-1, IN_uv0.y*2-1, depth*2-1, 1);
+
+ // Calculate the world position
+ vec4 D = tMul(screenPos, matWorldToScreen);
+ vec4 worldPos = D / D.w;
+
+ // Now calculate the previous screen position
+ vec4 previousPos = tMul( worldPos, matPrevScreenToWorld );
+ previousPos /= previousPos.w;
+
+ // Calculate the XY velocity
+ vec2 velocity = ((screenPos - previousPos) / velocityMultiplier).xy;
+
+ // Generate the motion blur
+ vec4 color = texture(backBuffer, IN_uv0);
+ IN_uv0 += velocity;
+
+ for(int i = 1; i 0 )
+ {
+ rayStart.z -= ( startSide );
+ //return vec4( 1, 0, 0, 1 );
+ }
+
+ vec3 hitPos;
+ vec3 ray = rayEnd - rayStart;
+ float rayLen = length( ray );
+ vec3 rayDir = normalize( ray );
+
+ float endSide = dot( plane.xyz, rayEnd ) + plane.w;
+ float planeDist;
+
+ if ( endSide < -0.005 )
+ {
+ //return vec4( 0, 0, 1, 1 );
+ hitPos = rayEnd;
+ planeDist = endSide;
+ }
+ else
+ {
+ //return vec4( 0, 0, 0, 0 );
+ float den = dot( ray, plane.xyz );
+
+ // Parallal to the plane, return the endPnt.
+ //if ( den == 0.0f )
+ // return endPnt;
+
+ float dist = -( dot( plane.xyz, rayStart ) + plane.w ) / den;
+ if ( dist < 0.0 )
+ dist = 0.0;
+ //return vec4( 1, 0, 0, 1 );
+ //return vec4( ( dist ).rrr, 1 );
+
+
+ hitPos = mix( rayStart, rayEnd, dist );
+
+ planeDist = dist;
+ }
+
+ float delta = length( hitPos - rayStart );
+
+ float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * ( delta - FOG_DENSITY_OFFSET ) ) );
+ //return vec4( fogAmt.rrr, 1 );
+
+ // Calculate the water "base" color based on depth.
+ vec4 fogColor = waterColor * texture( waterDepthGradMap, saturate( delta / waterDepthGradMax ) );
+ // Modulate baseColor by the ambientColor.
+ fogColor *= vec4( ambientColor.rgb, 1 );
+
+ vec3 inColor = hdrDecode( texture( backbuffer, IN_uv0 ).rgb );
+ inColor.rgb *= 1.0 - saturate( abs( planeDist ) / WET_DEPTH ) * WET_DARKENING;
+ //return vec4( inColor, 1 );
+
+ vec3 outColor = mix( inColor, fogColor.rgb, fogAmt );
+
+ OUT_col = vec4( hdrEncode( outColor ), 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurP.hlsl
new file mode 100644
index 000000000..80f8ed02d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurP.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 "./postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+ float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ) * 0.5f;
+
+ float4 OUT = 0;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv0 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv1 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv2 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv3 ) * kernel.w;
+
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv4 ) * kernel.x;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv5 ) * kernel.y;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv6 ) * kernel.z;
+ OUT += TORQUE_TEX2D( diffuseMap, IN.uv7 ) * kernel.w;
+
+ // Calculate a lumenance value in the alpha so we
+ // can use alpha test to save fillrate.
+ float3 rgb2lum = float3( 0.30, 0.59, 0.11 );
+ OUT.a = dot( OUT.rgb, rgb2lum );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurV.hlsl
new file mode 100644
index 000000000..b8f5cf9c2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/glowBlurV.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 "./postFx.hlsl"
+#include "./../torque.hlsl"
+
+
+uniform float2 texSize0;
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+VertToPix main( PFXVert IN )
+{
+ VertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1.0);
+
+ float2 uv = IN.uv + (0.5f / texSize0);
+
+ OUT.uv0 = uv + ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT.uv1 = uv + ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT.uv2 = uv + ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT.uv3 = uv + ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ OUT.uv4 = uv - ( ( BLUR_DIR * 3.5f ) / texSize0 );
+ OUT.uv5 = uv - ( ( BLUR_DIR * 2.5f ) / texSize0 );
+ OUT.uv6 = uv - ( ( BLUR_DIR * 1.5f ) / texSize0 );
+ OUT.uv7 = uv - ( ( BLUR_DIR * 0.5f ) / texSize0 );
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurHP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurHP.hlsl
new file mode 100644
index 000000000..77f4b9915
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurHP.hlsl
@@ -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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float2 oneOverTargetSize;
+uniform float gaussMultiplier;
+uniform float gaussMean;
+uniform float gaussStdDev;
+
+#define PI 3.141592654
+
+float computeGaussianValue( float x, float mean, float std_deviation )
+{
+ // The gaussian equation is defined as such:
+ /*
+ -(x - mean)^2
+ -------------
+ 1.0 2*std_dev^2
+ f(x,mean,std_dev) = -------------------- * e^
+ sqrt(2*pi*std_dev^2)
+
+ */
+
+ float tmp = ( 1.0f / sqrt( 2.0f * PI * std_deviation * std_deviation ) );
+ float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) );
+ return tmp * tmp2;
+}
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };
+ float offset = 0;
+ float weight = 0;
+ float x = 0;
+ float fI = 0;
+
+ for( int i = 0; i < 9; i++ )
+ {
+ fI = (float)i;
+ offset = (i - 4.0) * oneOverTargetSize.x;
+ x = (i - 4.0) / 4.0;
+ weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev );
+ color += (TORQUE_TEX2D( inputTex, IN.uv0 + float2( offset, 0.0f ) ) * weight );
+ }
+
+ return float4( color.rgb, 1.0f );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurVP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurVP.hlsl
new file mode 100644
index 000000000..8381f6a5d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/bloomGaussBlurVP.hlsl
@@ -0,0 +1,67 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float2 oneOverTargetSize;
+uniform float gaussMultiplier;
+uniform float gaussMean;
+uniform float gaussStdDev;
+
+#define D3DX_PI 3.141592654
+
+float computeGaussianValue( float x, float mean, float std_deviation )
+{
+ // The gaussian equation is defined as such:
+ /*
+ -(x - mean)^2
+ -------------
+ 1.0 2*std_dev^2
+ f(x,mean,std_dev) = -------------------- * e^
+ sqrt(2*pi*std_dev^2)
+
+ */
+ float tmp = ( 1.0f / sqrt( 2.0f * D3DX_PI * std_deviation * std_deviation ) );
+ float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) );
+ return tmp * tmp2;
+}
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 color = { 0.0f, 0.0f, 0.0f, 0.0f };
+ float offset = 0;
+ float weight = 0;
+ float x = 0;
+ float fI = 0;
+
+ for( int i = 0; i < 9; i++ )
+ {
+ fI = (float)i;
+ offset = (fI - 4.0) * oneOverTargetSize.y;
+ x = (fI - 4.0) / 4.0;
+ weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev );
+ color += (TORQUE_TEX2D( inputTex, IN.uv0 + float2( 0.0f, offset ) ) * weight );
+ }
+
+ return float4( color.rgb, 1.0f );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/brightPassFilterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/brightPassFilterP.hlsl
new file mode 100644
index 000000000..9a8a93e97
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/brightPassFilterP.hlsl
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+#include "../../torque.hlsl"
+
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(luminanceTex, 1);
+uniform float2 oneOverTargetSize;
+uniform float brightPassThreshold;
+uniform float g_fMiddleGray;
+
+static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f);
+
+
+static float2 gTapOffsets[4] =
+{
+ { -0.5, 0.5 }, { 0.5, -0.5 },
+ { -0.5, -0.5 }, { 0.5, 0.5 }
+};
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 average = { 0.0f, 0.0f, 0.0f, 0.0f };
+
+ // Combine and average 4 samples from the source HDR texture.
+ for( int i = 0; i < 4; i++ )
+ average += hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * oneOverTargetSize ) ) );
+ average *= 0.25f;
+
+ // Determine the brightness of this particular pixel.
+ float adaptedLum = TORQUE_TEX2D( luminanceTex, float2( 0.5f, 0.5f ) ).r;
+ float lum = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( average.rgb );
+ //float lum = hdrLuminance( average.rgb );
+
+ // Determine whether this pixel passes the test...
+ if ( lum < brightPassThreshold )
+ average = float4( 0.0f, 0.0f, 0.0f, 1.0f );
+
+ // Write the colour to the bright-pass render target
+ return hdrEncode( average );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/calculateAdaptedLumP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/calculateAdaptedLumP.hlsl
new file mode 100644
index 000000000..0f895070a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/calculateAdaptedLumP.hlsl
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(currLum, 0);
+TORQUE_UNIFORM_SAMPLER2D(lastAdaptedLum, 1);
+
+uniform float adaptRate;
+uniform float deltaTime;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float fAdaptedLum = TORQUE_TEX2D( lastAdaptedLum, float2(0.5f, 0.5f) ).r;
+ float fCurrentLum = TORQUE_TEX2D( currLum, float2(0.5f, 0.5f) ).r;
+
+ // The user's adapted luminance level is simulated by closing the gap between
+ // adapted luminance and current luminance by 2% every frame, based on a
+ // 30 fps rate. This is not an accurate model of human adaptation, which can
+ // take longer than half an hour.
+ float diff = fCurrentLum - fAdaptedLum;
+ float fNewAdaptation = fAdaptedLum + ( diff * ( 1.0 - exp( -deltaTime * adaptRate ) ) );
+
+ return float4( fNewAdaptation, 0.0, 0.0, 1.0f );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4P.hlsl
new file mode 100644
index 000000000..01998af0b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4P.hlsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "../../shdrConsts.h"
+#include "../postFx.hlsl"
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+struct VertIn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 texCoords[8] : TEXCOORD0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+float4 main( VertIn IN) : TORQUE_TARGET0
+{
+ // We calculate the texture coords
+ // in the vertex shader as an optimization.
+ float4 sample = 0.0f;
+ for ( int i = 0; i < 8; i++ )
+ {
+ sample += TORQUE_TEX2D( inputTex, IN.texCoords[i].xy );
+ sample += TORQUE_TEX2D( inputTex, IN.texCoords[i].zw );
+ }
+
+ return sample / 16;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4V.hlsl
new file mode 100644
index 000000000..c9a34b7f4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/downScale4x4V.hlsl
@@ -0,0 +1,138 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "../../shdrConsts.h"
+#include "../postFx.hlsl"
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 texCoords[8] : TEXCOORD0;
+};
+
+uniform float2 targetSize;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Conn main( PFXVert In )
+{
+ Conn Out;
+
+ Out.hpos = float4(In.pos,1.0);
+
+ // Sample from the 16 surrounding points. Since the center point will be in
+ // the exact center of 16 texels, a 0.5f offset is needed to specify a texel
+ // center.
+ float2 texSize = float2( 1.0 / (targetSize.x - 1.0), 1.0 / (targetSize.y - 1.0) );
+
+ float4 uv;
+ uv.xy = In.uv.xy;
+ uv.zw = In.uv.xy;
+
+ Out.texCoords[0] = uv;
+ Out.texCoords[0].x += texSize.x;
+ Out.texCoords[0].y += texSize.y;
+ Out.texCoords[0].z += texSize.x;
+ Out.texCoords[0].w += texSize.y;
+ Out.texCoords[0].x += ( 0 - 1.5 ) * texSize.x;
+ Out.texCoords[0].y += ( 0 - 1.5 ) * texSize.y;
+ Out.texCoords[0].z += ( 1 - 1.5 ) * texSize.x;
+ Out.texCoords[0].w += ( 0 - 1.5 ) * texSize.y;
+
+ Out.texCoords[1] = uv;
+ Out.texCoords[1].x += texSize.x;
+ Out.texCoords[1].y += texSize.y;
+ Out.texCoords[1].z += texSize.x;
+ Out.texCoords[1].w += texSize.y;
+ Out.texCoords[1].x += ( 2 - 1.5 ) * texSize.x;
+ Out.texCoords[1].y += ( 0 - 1.5 ) * texSize.y;
+ Out.texCoords[1].z += ( 3 - 1.5 ) * texSize.x;
+ Out.texCoords[1].w += ( 0 - 1.5 ) * texSize.y;
+
+ Out.texCoords[2] = uv;
+ Out.texCoords[2].x += texSize.x;
+ Out.texCoords[2].y += texSize.y;
+ Out.texCoords[2].z += texSize.x;
+ Out.texCoords[2].w += texSize.y;
+ Out.texCoords[2].x += ( 0 - 1.5 ) * texSize.x;
+ Out.texCoords[2].y += ( 1 - 1.5 ) * texSize.y;
+ Out.texCoords[2].z += ( 1 - 1.5 ) * texSize.x;
+ Out.texCoords[2].w += ( 1 - 1.5 ) * texSize.y;
+
+ Out.texCoords[3] = uv;
+ Out.texCoords[3].x += texSize.x;
+ Out.texCoords[3].y += texSize.y;
+ Out.texCoords[3].z += texSize.x;
+ Out.texCoords[3].w += texSize.y;
+ Out.texCoords[3].x += ( 2 - 1.5 ) * texSize.x;
+ Out.texCoords[3].y += ( 1 - 1.5 ) * texSize.y;
+ Out.texCoords[3].z += ( 3 - 1.5 ) * texSize.x;
+ Out.texCoords[3].w += ( 1 - 1.5 ) * texSize.y;
+
+ Out.texCoords[4] = uv;
+ Out.texCoords[4].x += texSize.x;
+ Out.texCoords[4].y += texSize.y;
+ Out.texCoords[4].z += texSize.x;
+ Out.texCoords[4].w += texSize.y;
+ Out.texCoords[4].x += ( 0 - 1.5 ) * texSize.x;
+ Out.texCoords[4].y += ( 2 - 1.5 ) * texSize.y;
+ Out.texCoords[4].z += ( 1 - 1.5 ) * texSize.x;
+ Out.texCoords[4].w += ( 2 - 1.5 ) * texSize.y;
+
+ Out.texCoords[5] = uv;
+ Out.texCoords[5].x += texSize.x;
+ Out.texCoords[5].y += texSize.y;
+ Out.texCoords[5].z += texSize.x;
+ Out.texCoords[5].w += texSize.y;
+ Out.texCoords[5].x += ( 2 - 1.5 ) * texSize.x;
+ Out.texCoords[5].y += ( 2 - 1.5 ) * texSize.y;
+ Out.texCoords[5].z += ( 3 - 1.5 ) * texSize.x;
+ Out.texCoords[5].w += ( 2 - 1.5 ) * texSize.y;
+
+ Out.texCoords[6] = uv;
+ Out.texCoords[6].x += texSize.x;
+ Out.texCoords[6].y += texSize.y;
+ Out.texCoords[6].z += texSize.x;
+ Out.texCoords[6].w += texSize.y;
+ Out.texCoords[6].x += ( 0 - 1.5 ) * texSize.x;
+ Out.texCoords[6].y += ( 3 - 1.5 ) * texSize.y;
+ Out.texCoords[6].z += ( 1 - 1.5 ) * texSize.x;
+ Out.texCoords[6].w += ( 3 - 1.5 ) * texSize.y;
+
+ Out.texCoords[7] = uv;
+ Out.texCoords[7].x += texSize.x;
+ Out.texCoords[7].y += texSize.y;
+ Out.texCoords[7].z += texSize.x;
+ Out.texCoords[7].w += texSize.y;
+ Out.texCoords[7].x += ( 2 - 1.5 ) * texSize.x;
+ Out.texCoords[7].y += ( 3 - 1.5 ) * texSize.y;
+ Out.texCoords[7].z += ( 3 - 1.5 ) * texSize.x;
+ Out.texCoords[7].w += ( 3 - 1.5 ) * texSize.y;
+
+ return Out;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl
new file mode 100644
index 000000000..07f7276c3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/finalPassCombineP.hlsl
@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../postFx.hlsl"
+#include "../../shaderModelAutoGen.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(sceneTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(luminanceTex, 1);
+TORQUE_UNIFORM_SAMPLER2D(bloomTex, 2);
+TORQUE_UNIFORM_SAMPLER1D(colorCorrectionTex, 3);
+
+uniform float2 texSize0;
+uniform float2 texSize2;
+
+uniform float g_fEnableToneMapping;
+uniform float g_fMiddleGray;
+uniform float g_fWhiteCutoff;
+uniform float g_fEnableBlueShift;
+
+uniform float3 g_fBlueShiftColor;
+uniform float g_fBloomScale;
+uniform float g_fOneOverGamma;
+uniform float Brightness;
+uniform float Contrast;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 sample = hdrDecode( TORQUE_TEX2D( sceneTex, IN.uv0 ) );
+ float adaptedLum = TORQUE_TEX2D( luminanceTex, float2( 0.5f, 0.5f ) ).r;
+ float4 bloom = TORQUE_TEX2D( bloomTex, IN.uv0 );
+
+ // For very low light conditions, the rods will dominate the perception
+ // of light, and therefore color will be desaturated and shifted
+ // towards blue.
+ if ( g_fEnableBlueShift > 0.0f )
+ {
+ const float3 LUMINANCE_VECTOR = float3(0.2125f, 0.7154f, 0.0721f);
+
+ // Define a linear blending from -1.5 to 2.6 (log scale) which
+ // determines the lerp amount for blue shift
+ float coef = 1.0f - ( adaptedLum + 1.5 ) / 4.1;
+ coef = saturate( coef * g_fEnableBlueShift );
+
+ // Lerp between current color and blue, desaturated copy
+ float3 rodColor = dot( sample.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor;
+ sample.rgb = lerp( sample.rgb, rodColor, coef );
+
+ rodColor = dot( bloom.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor;
+ bloom.rgb = lerp( bloom.rgb, rodColor, coef );
+ }
+
+ // 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;
+
+ return sample;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurHP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurHP.glsl
new file mode 100644
index 000000000..1d9a2df3e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurHP.glsl
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex ;
+uniform vec2 oneOverTargetSize;
+uniform float gaussMultiplier;
+uniform float gaussMean;
+uniform float gaussStdDev;
+
+out vec4 OUT_col;
+
+#define PI 3.141592654
+
+float computeGaussianValue( float x, float mean, float std_deviation )
+{
+ // The gaussian equation is defined as such:
+ /*
+ -(x - mean)^2
+ -------------
+ 1.0 2*std_dev^2
+ f(x,mean,std_dev) = -------------------- * e^
+ sqrt(2*pi*std_dev^2)
+
+ */
+
+ float tmp = ( 1.0f / sqrt( 2.0f * PI * std_deviation * std_deviation ) );
+ float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) );
+ return tmp * tmp2;
+}
+
+void main()
+{
+ vec4 color = vec4( 0.0f, 0.0f, 0.0f, 0.0f );
+ float offset = 0;
+ float weight = 0;
+ float x = 0;
+ float fI = 0;
+
+ for( int i = 0; i < 9; i++ )
+ {
+ fI = float(i);
+ offset = (i - 4.0) * oneOverTargetSize.x;
+ x = (i - 4.0) / 4.0;
+ weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev );
+ color += (texture( inputTex, IN_uv0 + vec2( offset, 0.0f ) ) * weight );
+ }
+
+ OUT_col = vec4( color.rgb, 1.0f );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurVP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurVP.glsl
new file mode 100644
index 000000000..68f34b164
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/bloomGaussBlurVP.glsl
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex ;
+uniform vec2 oneOverTargetSize;
+uniform float gaussMultiplier;
+uniform float gaussMean;
+uniform float gaussStdDev;
+
+out vec4 OUT_col;
+
+#define D3DX_PI 3.141592654
+
+float computeGaussianValue( float x, float mean, float std_deviation )
+{
+ // The gaussian equation is defined as such:
+ /*
+ -(x - mean)^2
+ -------------
+ 1.0 2*std_dev^2
+ f(x,mean,std_dev) = -------------------- * e^
+ sqrt(2*pi*std_dev^2)
+
+ */
+ float tmp = ( 1.0f / sqrt( 2.0f * D3DX_PI * std_deviation * std_deviation ) );
+ float tmp2 = exp( ( -( ( x - mean ) * ( x - mean ) ) ) / ( 2.0f * std_deviation * std_deviation ) );
+ return tmp * tmp2;
+}
+
+void main()
+{
+ vec4 color = vec4( 0.0f, 0.0f, 0.0f, 0.0f );
+ float offset = 0;
+ float weight = 0;
+ float x = 0;
+ float fI = 0;
+
+ for( int i = 0; i < 9; i++ )
+ {
+ fI = float(i);
+ offset = (fI - 4.0) * oneOverTargetSize.y;
+ x = (fI - 4.0) / 4.0;
+ weight = gaussMultiplier * computeGaussianValue( x, gaussMean, gaussStdDev );
+ color += (texture( inputTex, IN_uv0 + vec2( 0.0f, offset ) ) * weight );
+ }
+
+ OUT_col = vec4( color.rgb, 1.0f );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/brightPassFilterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/brightPassFilterP.glsl
new file mode 100644
index 000000000..f220ca1e7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/brightPassFilterP.glsl
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex ;
+uniform sampler2D luminanceTex ;
+uniform vec2 oneOverTargetSize;
+uniform float brightPassThreshold;
+uniform float g_fMiddleGray;
+
+const vec3 LUMINANCE_VECTOR = vec3(0.3125f, 0.6154f, 0.0721f);
+
+out vec4 OUT_col;
+
+
+const vec2 gTapOffsets[4] = vec2[]
+(
+ vec2( -0.5, 0.5 ), vec2( 0.5, -0.5 ),
+ vec2( -0.5, -0.5 ), vec2( 0.5, 0.5 )
+);
+
+void main()
+{
+ vec4 average = vec4( 0.0f, 0.0f, 0.0f, 0.0f );
+
+ // Combine and average 4 samples from the source HDR texture.
+ for( int i = 0; i < 4; i++ )
+ average += hdrDecode( texture( inputTex, IN_uv0 + ( gTapOffsets[i] * oneOverTargetSize ) ) );
+ average *= 0.25f;
+
+ // Determine the brightness of this particular pixel.
+ float adaptedLum = texture( luminanceTex, vec2( 0.5f, 0.5f ) ).r;
+ float lum = (g_fMiddleGray / (adaptedLum + 0.0001)) * hdrLuminance( average.rgb );
+ //float lum = hdrLuminance( average.rgb );
+
+ // Determine whether this pixel passes the test...
+ if ( lum < brightPassThreshold )
+ average = vec4( 0.0f, 0.0f, 0.0f, 1.0f );
+
+ // Write the colour to the bright-pass render target
+ OUT_col = hdrEncode( average );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/calculateAdaptedLumP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/calculateAdaptedLumP.glsl
new file mode 100644
index 000000000..96ee9d6df
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/calculateAdaptedLumP.glsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D currLum;
+uniform sampler2D lastAdaptedLum;
+
+uniform float adaptRate;
+uniform float deltaTime;
+
+out vec4 OUT_col;
+
+void main()
+{
+ float fAdaptedLum = texture( lastAdaptedLum, vec2(0.5f, 0.5f) ).r;
+ float fCurrentLum = texture( currLum, vec2(0.5f, 0.5f) ).r;
+
+ // The user's adapted luminance level is simulated by closing the gap between
+ // adapted luminance and current luminance by 2% every frame, based on a
+ // 30 fps rate. This is not an accurate model of human adaptation, which can
+ // take longer than half an hour.
+ float diff = fCurrentLum - fAdaptedLum;
+ float fNewAdaptation = fAdaptedLum + ( diff * ( 1.0 - exp( -deltaTime * adaptRate ) ) );
+
+ OUT_col = vec4( fNewAdaptation, 0.0, 0.0, 1.0f );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4P.glsl
new file mode 100644
index 000000000..131671760
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4P.glsl
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_GLSL
+#include "../../../shdrConsts.h"
+#include "../../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+
+in vec4 texCoords[8];
+#define IN_texCoords texCoords
+
+uniform sampler2D inputTex;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ // We calculate the texture coords
+ // in the vertex shader as an optimization.
+ vec4 _sample = vec4(0.0f);
+ for ( int i = 0; i < 8; i++ )
+ {
+ _sample += texture( inputTex, IN_texCoords[i].xy );
+ _sample += texture( inputTex, IN_texCoords[i].zw );
+ }
+
+ OUT_col = _sample / 16;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4V.glsl
new file mode 100644
index 000000000..51f1da896
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/downScale4x4V.glsl
@@ -0,0 +1,141 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_GLSL
+#include "../../../shdrConsts.h"
+#include "../../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define In_pos vPosition
+#define In_uv vTexCoord0
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+out vec4 texCoords[8];
+#define Out_texCoords texCoords
+
+#define Out_hpos gl_Position
+
+uniform vec2 targetSize;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ Out_hpos = In_pos;
+
+ // Sample from the 16 surrounding points. Since the center point will be in
+ // the exact center of 16 texels, a 0.5f offset is needed to specify a texel
+ // center.
+ vec2 texSize = vec2( 1.0 / (targetSize.x - 1.0), 1.0 / (targetSize.y - 1.0) );
+
+ vec4 uv;
+ uv.xy = In_uv.xy;
+ uv.zw = In_uv.xy;
+
+ Out_texCoords[0] = uv;
+ Out_texCoords[0].x += texSize.x;
+ Out_texCoords[0].y += texSize.y;
+ Out_texCoords[0].z += texSize.x;
+ Out_texCoords[0].w += texSize.y;
+ Out_texCoords[0].x += ( 0 - 1.5 ) * texSize.x;
+ Out_texCoords[0].y += ( 0 - 1.5 ) * texSize.y;
+ Out_texCoords[0].z += ( 1 - 1.5 ) * texSize.x;
+ Out_texCoords[0].w += ( 0 - 1.5 ) * texSize.y;
+
+ Out_texCoords[1] = uv;
+ Out_texCoords[1].x += texSize.x;
+ Out_texCoords[1].y += texSize.y;
+ Out_texCoords[1].z += texSize.x;
+ Out_texCoords[1].w += texSize.y;
+ Out_texCoords[1].x += ( 2 - 1.5 ) * texSize.x;
+ Out_texCoords[1].y += ( 0 - 1.5 ) * texSize.y;
+ Out_texCoords[1].z += ( 3 - 1.5 ) * texSize.x;
+ Out_texCoords[1].w += ( 0 - 1.5 ) * texSize.y;
+
+ Out_texCoords[2] = uv;
+ Out_texCoords[2].x += texSize.x;
+ Out_texCoords[2].y += texSize.y;
+ Out_texCoords[2].z += texSize.x;
+ Out_texCoords[2].w += texSize.y;
+ Out_texCoords[2].x += ( 0 - 1.5 ) * texSize.x;
+ Out_texCoords[2].y += ( 1 - 1.5 ) * texSize.y;
+ Out_texCoords[2].z += ( 1 - 1.5 ) * texSize.x;
+ Out_texCoords[2].w += ( 1 - 1.5 ) * texSize.y;
+
+ Out_texCoords[3] = uv;
+ Out_texCoords[3].x += texSize.x;
+ Out_texCoords[3].y += texSize.y;
+ Out_texCoords[3].z += texSize.x;
+ Out_texCoords[3].w += texSize.y;
+ Out_texCoords[3].x += ( 2 - 1.5 ) * texSize.x;
+ Out_texCoords[3].y += ( 1 - 1.5 ) * texSize.y;
+ Out_texCoords[3].z += ( 3 - 1.5 ) * texSize.x;
+ Out_texCoords[3].w += ( 1 - 1.5 ) * texSize.y;
+
+ Out_texCoords[4] = uv;
+ Out_texCoords[4].x += texSize.x;
+ Out_texCoords[4].y += texSize.y;
+ Out_texCoords[4].z += texSize.x;
+ Out_texCoords[4].w += texSize.y;
+ Out_texCoords[4].x += ( 0 - 1.5 ) * texSize.x;
+ Out_texCoords[4].y += ( 2 - 1.5 ) * texSize.y;
+ Out_texCoords[4].z += ( 1 - 1.5 ) * texSize.x;
+ Out_texCoords[4].w += ( 2 - 1.5 ) * texSize.y;
+
+ Out_texCoords[5] = uv;
+ Out_texCoords[5].x += texSize.x;
+ Out_texCoords[5].y += texSize.y;
+ Out_texCoords[5].z += texSize.x;
+ Out_texCoords[5].w += texSize.y;
+ Out_texCoords[5].x += ( 2 - 1.5 ) * texSize.x;
+ Out_texCoords[5].y += ( 2 - 1.5 ) * texSize.y;
+ Out_texCoords[5].z += ( 3 - 1.5 ) * texSize.x;
+ Out_texCoords[5].w += ( 2 - 1.5 ) * texSize.y;
+
+ Out_texCoords[6] = uv;
+ Out_texCoords[6].x += texSize.x;
+ Out_texCoords[6].y += texSize.y;
+ Out_texCoords[6].z += texSize.x;
+ Out_texCoords[6].w += texSize.y;
+ Out_texCoords[6].x += ( 0 - 1.5 ) * texSize.x;
+ Out_texCoords[6].y += ( 3 - 1.5 ) * texSize.y;
+ Out_texCoords[6].z += ( 1 - 1.5 ) * texSize.x;
+ Out_texCoords[6].w += ( 3 - 1.5 ) * texSize.y;
+
+ Out_texCoords[7] = uv;
+ Out_texCoords[7].x += texSize.x;
+ Out_texCoords[7].y += texSize.y;
+ Out_texCoords[7].z += texSize.x;
+ Out_texCoords[7].w += texSize.y;
+ Out_texCoords[7].x += ( 2 - 1.5 ) * texSize.x;
+ Out_texCoords[7].y += ( 3 - 1.5 ) * texSize.y;
+ Out_texCoords[7].z += ( 3 - 1.5 ) * texSize.x;
+ Out_texCoords[7].w += ( 3 - 1.5 ) * texSize.y;
+
+ correctSSP(gl_Position);
+}
+
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
new file mode 100644
index 000000000..4b173d4d3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/finalPassCombineP.glsl
@@ -0,0 +1,97 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+#include "../../gl/postFX.glsl"
+#include "shadergen:/autogenConditioners.h"
+
+uniform sampler2D sceneTex;
+uniform sampler2D luminanceTex;
+uniform sampler2D bloomTex;
+uniform sampler1D colorCorrectionTex;
+
+uniform vec2 texSize0;
+uniform vec2 texSize2;
+
+uniform float g_fEnableToneMapping;
+uniform float g_fMiddleGray;
+uniform float g_fWhiteCutoff;
+
+uniform float g_fEnableBlueShift;
+uniform vec3 g_fBlueShiftColor;
+
+uniform float g_fBloomScale;
+
+uniform float g_fOneOverGamma;
+uniform float Brightness;
+uniform float Contrast;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 _sample = hdrDecode( texture( sceneTex, IN_uv0 ) );
+ float adaptedLum = texture( luminanceTex, vec2( 0.5f, 0.5f ) ).r;
+ vec4 bloom = texture( bloomTex, IN_uv0 );
+
+ // For very low light conditions, the rods will dominate the perception
+ // of light, and therefore color will be desaturated and shifted
+ // towards blue.
+ if ( g_fEnableBlueShift > 0.0f )
+ {
+ const vec3 LUMINANCE_VECTOR = vec3(0.2125f, 0.7154f, 0.0721f);
+
+ // Define a linear blending from -1.5 to 2.6 (log scale) which
+ // determines the mix amount for blue shift
+ float coef = 1.0f - ( adaptedLum + 1.5 ) / 4.1;
+ coef = saturate( coef * g_fEnableBlueShift );
+
+ // Lerp between current color and blue, desaturated copy
+ vec3 rodColor = dot( _sample.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor;
+ _sample.rgb = mix( _sample.rgb, rodColor, coef );
+
+ rodColor = dot( bloom.rgb, LUMINANCE_VECTOR ) * g_fBlueShiftColor;
+ bloom.rgb = mix( bloom.rgb, rodColor, coef );
+ }
+
+ // 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;
+
+ OUT_col = _sample;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/luminanceVisP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/luminanceVisP.glsl
new file mode 100644
index 000000000..ee9c28c87
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/luminanceVisP.glsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex;
+uniform float brightPassThreshold;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 _sample = hdrDecode( texture( inputTex, IN_uv0 ) );
+
+ // Determine the brightness of this particular pixel.
+ float lum = hdrLuminance( _sample.rgb );
+
+ // Write the colour to the bright-pass render target
+ OUT_col = ( vec4( lum.rrr, 1 ) );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumInitialP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumInitialP.glsl
new file mode 100644
index 000000000..8a2b9b318
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumInitialP.glsl
@@ -0,0 +1,62 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+#include "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex;
+uniform vec2 texSize0;
+
+uniform float g_fMinLuminace;
+
+out vec4 OUT_col;
+
+const vec2 gTapOffsets[9] = vec2[]
+(
+ vec2( -1.0, -1.0 ), vec2( 0.0, -1.0 ), vec2( 1.0, -1.0 ),
+ vec2( -1.0, 0.0 ), vec2( 0.0, 0.0 ), vec2( 1.0, 0.0 ),
+ vec2( -1.0, 1.0 ), vec2( 0.0, 1.0 ), vec2( 1.0, 1.0 )
+);
+
+
+void main()
+{
+ vec2 tsize = 1.0 / texSize0;
+
+ vec3 _sample;
+ float average = 0.0;
+
+ for ( int i = 0; i < 9; i++ )
+ {
+ // Decode the hdr value.
+ _sample = hdrDecode( texture( inputTex, IN_uv0 + ( gTapOffsets[i] * tsize ) ).rgb );
+
+ // Get the luminance and add it to the average.
+ float lum = max( hdrLuminance( _sample ), g_fMinLuminace );
+ average += log( lum );
+ }
+
+ average = exp( average / 9.0 );
+
+ OUT_col = vec4( average, 0.0, 0.0, 1.0 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumIterativeP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumIterativeP.glsl
new file mode 100644
index 000000000..2e800d612
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/gl/sampleLumIterativeP.glsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D inputTex;
+uniform vec2 oneOverTargetSize;
+
+out vec4 OUT_col;
+
+const vec2 gTapOffsets[16] = vec2[]
+(
+ vec2( -1.5, -1.5 ), vec2( -0.5, -1.5 ), vec2( 0.5, -1.5 ), vec2( 1.5, -1.5 ),
+ vec2( -1.5, -0.5 ), vec2( -0.5, -0.5 ), vec2( 0.5, -0.5 ), vec2( 1.5, -0.5 ),
+ vec2( -1.5, 0.5 ), vec2( -0.5, 0.5 ), vec2( 0.5, 0.5 ), vec2( 1.5, 0.5 ),
+ vec2( -1.5, 1.5 ), vec2( -0.5, 1.5 ), vec2( 0.5, 1.5 ), vec2( 1.5, 1.5 )
+);
+
+void main()
+{
+ vec2 pixelSize = oneOverTargetSize;
+
+ float average = 0.0;
+
+ for ( int i = 0; i < 16; i++ )
+ {
+ float lum = texture( inputTex, IN_uv0 + ( gTapOffsets[i] * pixelSize ) ).r;
+ average += lum;
+ }
+
+ OUT_col = vec4( average / 16.0, 0.0, 0.0, 1.0 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/luminanceVisP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/luminanceVisP.hlsl
new file mode 100644
index 000000000..505d1b825
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/luminanceVisP.hlsl
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+#include "../../torque.hlsl"
+
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float brightPassThreshold;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 sample = hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 ) );
+
+ // Determine the brightness of this particular pixel.
+ float lum = hdrLuminance( sample.rgb );
+
+ // Write the colour to the bright-pass render target
+ return ( float4( lum.rrr, 1 ) );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumInitialP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumInitialP.hlsl
new file mode 100644
index 000000000..2e23ece1f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumInitialP.hlsl
@@ -0,0 +1,59 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float2 texSize0;
+
+uniform float g_fMinLuminace;
+
+static float2 gTapOffsets[9] =
+{
+ { -1.0, -1.0 }, { 0.0, -1.0 }, { 1.0, -1.0 },
+ { -1.0, 0.0 }, { 0.0, 0.0 }, { 1.0, 0.0 },
+ { -1.0, 1.0 }, { 0.0, 1.0 }, { 1.0, 1.0 }
+};
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float2 tsize = 1.0 / texSize0;
+
+ float3 sample;
+ float average = 0.0;
+
+ for ( int i = 0; i < 9; i++ )
+ {
+ // Decode the hdr value.
+ sample = hdrDecode( TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * tsize ) ).rgb );
+
+ // Get the luminance and add it to the average.
+ float lum = max( hdrLuminance( sample ), g_fMinLuminace );
+ average += log( lum );
+ }
+
+ average = exp( average / 9.0 );
+
+ return float4( average, 0.0, 0.0, 1.0 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumIterativeP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumIterativeP.hlsl
new file mode 100644
index 000000000..46ed6fc70
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/hdr/sampleLumIterativeP.hlsl
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float2 oneOverTargetSize;
+
+
+static float2 gTapOffsets[16] =
+{
+ { -1.5, -1.5 }, { -0.5, -1.5 }, { 0.5, -1.5 }, { 1.5, -1.5 },
+ { -1.5, -0.5 }, { -0.5, -0.5 }, { 0.5, -0.5 }, { 1.5, -0.5 },
+ { -1.5, 0.5 }, { -0.5, 0.5 }, { 0.5, 0.5 }, { 1.5, 0.5 },
+ { -1.5, 1.5 }, { -0.5, 1.5 }, { 0.5, 1.5 }, { 1.5, 1.5 }
+};
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float2 pixelSize = oneOverTargetSize;
+
+ float average = 0.0;
+
+ for ( int i = 0; i < 16; i++ )
+ {
+ float lum = TORQUE_TEX2D( inputTex, IN.uv0 + ( gTapOffsets[i] * pixelSize ) ).r;
+ average += lum;
+ }
+
+ return float4( average / 16.0, 0.0, 0.0, 1.0 );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayOccludeP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayOccludeP.glsl
new file mode 100644
index 000000000..59f5f4bbf
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayOccludeP.glsl
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D backBuffer; // The original backbuffer.
+uniform sampler2D deferredTex; // The pre-pass depth and normals.
+
+uniform float brightScalar;
+
+const vec3 LUMINANCE_VECTOR = vec3(0.3125f, 0.6154f, 0.0721f);
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 col = vec4( 0, 0, 0, 1 );
+
+ // Get the depth at this pixel.
+ float depth = deferredUncondition( deferredTex, IN_uv0 ).w;
+
+ // If the depth is equal to 1.0, read from the backbuffer
+ // and perform the exposure calculation on the result.
+ if ( depth >= 0.999 )
+ {
+ col = texture( backBuffer, IN_uv0 );
+
+ //col = 1 - exp(-120000 * col);
+ col += dot( vec3(col), LUMINANCE_VECTOR ) + 0.0001f;
+ col *= brightScalar;
+ }
+
+ OUT_col = col;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayP.glsl
new file mode 100644
index 000000000..6d78f4eae
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/gl/lightRayP.glsl
@@ -0,0 +1,94 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+uniform sampler2D frameSampler;
+uniform sampler2D backBuffer;
+
+uniform vec3 camForward;
+uniform vec3 lightDirection;
+uniform vec2 screenSunPos;
+uniform vec2 oneOverTargetSize;
+uniform int numSamples;
+uniform float density;
+uniform float weight;
+uniform float decay;
+uniform float exposure;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 texCoord = vec4( IN_uv0.xy, 0, 0 );
+
+ // Store initial sample.
+ half3 color = half3(texture( frameSampler, texCoord.xy ).rgb);
+
+ // Store original bb color.
+ vec4 bbCol = texture( backBuffer, IN_uv1 );
+
+ // Set up illumination decay factor.
+ half illuminationDecay = 1.0;
+
+ float amount = saturate( dot( -lightDirection, camForward ) );
+
+ int samples = int(numSamples * amount);
+
+ if ( samples <= 0 )
+ {
+ OUT_col = bbCol;
+ return;
+ }
+
+ // Calculate vector from pixel to light source in screen space.
+ half2 deltaTexCoord = half2( texCoord.xy - screenSunPos );
+
+ // Divide by number of samples and scale by control factor.
+ deltaTexCoord *= 1.0 / half(samples * density);
+
+ // Evaluate summation from Equation 3 NUM_SAMPLES iterations.
+ for ( int i = 0; i < samples; i++ )
+ {
+ // Step sample location along ray.
+ texCoord.xy -= deltaTexCoord;
+
+ // Retrieve sample at new location.
+ half3 sample_ = half3(tex2Dlod( frameSampler, texCoord ));
+
+ // Apply sample attenuation scale/decay factors.
+ sample_ *= illuminationDecay * weight;
+
+ // Accumulate combined color.
+ color += sample_;
+
+ // Update exponential decay factor.
+ illuminationDecay *= decay;
+ }
+
+ //return saturate( amount ) * color * Exposure;
+ //return bbCol * decay;
+
+ // Output final color with a further scale control factor.
+ OUT_col = saturate( amount ) * vec4( color * exposure, 1 ) + bbCol;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayOccludeP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayOccludeP.hlsl
new file mode 100644
index 000000000..5db6ecb5b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayOccludeP.hlsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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 "../../shaderModelAutoGen.hlsl"
+#include "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 1);
+
+uniform float brightScalar;
+
+static const float3 LUMINANCE_VECTOR = float3(0.3125f, 0.6154f, 0.0721f);
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 col = float4( 0, 0, 0, 1 );
+
+ // Get the depth at this pixel.
+ float depth = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 ).w;
+
+ // If the depth is equal to 1.0, read from the backbuffer
+ // and perform the exposure calculation on the result.
+ if ( depth >= 0.999 )
+ {
+ col = TORQUE_TEX2D( backBuffer, IN.uv0 );
+
+ //col = 1 - exp(-120000 * col);
+ col += dot( col.rgb, LUMINANCE_VECTOR ) + 0.0001f;
+ col *= brightScalar;
+ }
+
+ return col;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayP.hlsl
new file mode 100644
index 000000000..032894710
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/lightRay/lightRayP.hlsl
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(frameSampler, 0);
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 1);
+
+
+uniform float3 camForward;
+uniform int numSamples;
+uniform float3 lightDirection;
+uniform float density;
+uniform float2 screenSunPos;
+uniform float2 oneOverTargetSize;
+uniform float weight;
+uniform float decay;
+uniform float exposure;
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float4 texCoord = float4( IN.uv0.xy, 0, 0 );
+
+ // Store initial sample.
+ half3 color = (half3)TORQUE_TEX2D( frameSampler, texCoord.xy ).rgb;
+
+ // Store original bb color.
+ float4 bbCol = TORQUE_TEX2D( backBuffer, IN.uv1 );
+
+ // Set up illumination decay factor.
+ half illuminationDecay = 1.0;
+
+ float amount = saturate( dot( -lightDirection, camForward ) );
+
+ int samples = numSamples * amount;
+
+ if ( samples <= 0 )
+ return bbCol;
+
+ // Calculate vector from pixel to light source in screen space.
+ half2 deltaTexCoord = (half2)( texCoord.xy - screenSunPos );
+
+ // Divide by number of samples and scale by control factor.
+ deltaTexCoord *= (half)(1.0 / samples * density);
+
+ // Evaluate summation from Equation 3 NUM_SAMPLES iterations.
+ for ( int i = 0; i < samples; i++ )
+ {
+ // Step sample location along ray.
+ texCoord.xy -= deltaTexCoord;
+
+ // Retrieve sample at new location.
+ half3 sample = (half3)TORQUE_TEX2DLOD( frameSampler, texCoord );
+
+ // Apply sample attenuation scale/decay factors.
+ sample *= half(illuminationDecay * weight);
+
+ // Accumulate combined color.
+ color += sample;
+
+ // Update exponential decay factor.
+ illuminationDecay *= half(decay);
+ }
+
+ //return saturate( amount ) * color * Exposure;
+ //return bbCol * decay;
+
+ // Output final color with a further scale control factor.
+ return saturate( amount ) * float4( color * exposure, 1 ) + bbCol;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/blendWeightCalculationP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/blendWeightCalculationP.hlsl
new file mode 100644
index 000000000..2c4777c36
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/blendWeightCalculationP.hlsl
@@ -0,0 +1,78 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform sampler2D edgesMap : register(S0);
+uniform sampler2D edgesMapL : register(S1);
+uniform sampler2D areaMap : register(S2);
+
+#include "./functions.hlsl"
+
+
+float4 main(float2 texcoord : TEXCOORD0) : COLOR0
+{
+ float4 areas = 0.0;
+
+ float2 e = tex2D(edgesMap, texcoord).rg;
+
+ [branch]
+ if (e.g) // Edge at north
+ {
+ // Search distances to the left and to the right:
+ float2 d = float2(SearchXLeft(texcoord), SearchXRight(texcoord));
+
+ // Now fetch the crossing edges. Instead of sampling between edgels, we
+ // sample at -0.25, to be able to discern what value has each edgel:
+ float4 coords = mad(float4(d.x, -0.25, d.y + 1.0, -0.25),
+ PIXEL_SIZE.xyxy, texcoord.xyxy);
+ float e1 = tex2Dlevel0(edgesMapL, coords.xy).r;
+ float e2 = tex2Dlevel0(edgesMapL, coords.zw).r;
+
+ // Ok, we know how this pattern looks like, now it is time for getting
+ // the actual area:
+ areas.rg = Area(abs(d), e1, e2);
+ }
+
+ [branch]
+ if (e.r) // Edge at west
+ {
+ // Search distances to the top and to the bottom:
+ float2 d = float2(SearchYUp(texcoord), SearchYDown(texcoord));
+
+ // Now fetch the crossing edges (yet again):
+ float4 coords = mad(float4(-0.25, d.x, -0.25, d.y + 1.0),
+ PIXEL_SIZE.xyxy, texcoord.xyxy);
+ float e1 = tex2Dlevel0(edgesMapL, coords.xy).g;
+ float e2 = tex2Dlevel0(edgesMapL, coords.zw).g;
+
+ // Get the area for this direction:
+ areas.ba = Area(abs(d), e1, e2);
+ }
+
+ return areas;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/edgeDetectionP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/edgeDetectionP.hlsl
new file mode 100644
index 000000000..7d5c7f057
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/edgeDetectionP.hlsl
@@ -0,0 +1,72 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "shadergen:/autogenConditioners.h"
+
+uniform sampler2D colorMapG : register(S0);
+uniform sampler2D deferredMap : register(S1);
+
+uniform float3 lumaCoefficients;
+uniform float threshold;
+uniform float depthThreshold;
+
+
+float4 main( float2 texcoord : TEXCOORD0,
+ float4 offset[2]: TEXCOORD1) : COLOR0
+{
+ // Luma calculation requires gamma-corrected colors (texture 'colorMapG').
+ //
+ // Note that there is a lot of overlapped luma calculations; performance
+ // can be improved if this luma calculation is performed in the main pass,
+ // which may give you an edge if used in conjunction with a z deferred.
+
+ float L = dot(tex2D(colorMapG, texcoord).rgb, lumaCoefficients);
+
+ float Lleft = dot(tex2D(colorMapG, offset[0].xy).rgb, lumaCoefficients);
+ float Ltop = dot(tex2D(colorMapG, offset[0].zw).rgb, lumaCoefficients);
+ float Lright = dot(tex2D(colorMapG, offset[1].xy).rgb, lumaCoefficients);
+ float Lbottom = dot(tex2D(colorMapG, offset[1].zw).rgb, lumaCoefficients);
+
+ float4 delta = abs(L.xxxx - float4(Lleft, Ltop, Lright, Lbottom));
+ float4 edges = step(threshold, delta);
+
+ // Add depth edges to color edges
+ float D = deferredUncondition(deferredMap, texcoord).w;
+ float Dleft = deferredUncondition(deferredMap, offset[0].xy).w;
+ float Dtop = deferredUncondition(deferredMap, offset[0].zw).w;
+ float Dright = deferredUncondition(deferredMap, offset[1].xy).w;
+ float Dbottom = deferredUncondition(deferredMap, offset[1].zw).w;
+
+ delta = abs(D.xxxx - float4(Dleft, Dtop, Dright, Dbottom));
+ edges += step(depthThreshold, delta);
+
+ if (dot(edges, 1.0) == 0.0)
+ discard;
+
+ return edges;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/functions.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/functions.hlsl
new file mode 100644
index 000000000..9935a5e30
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/functions.hlsl
@@ -0,0 +1,145 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform float2 texSize0;
+
+#if !defined(PIXEL_SIZE)
+#define PIXEL_SIZE (1.0 / texSize0)
+#define MAX_SEARCH_STEPS 8
+#define MAX_DISTANCE 33
+#endif
+
+// Typical Multiply-Add operation to ease translation to assembly code.
+
+float4 mad(float4 m, float4 a, float4 b)
+{
+ #if defined(XBOX)
+ float4 result;
+ asm {
+ mad result, m, a, b
+ };
+ return result;
+ #else
+ return m * a + b;
+ #endif
+}
+
+
+// This one just returns the first level of a mip map chain, which allow us to
+// avoid the nasty ddx/ddy warnings, even improving the performance a little
+// bit.
+float4 tex2Dlevel0(sampler2D map, float2 texcoord)
+{
+ return tex2Dlod(map, float4(texcoord, 0.0, 0.0));
+}
+
+
+// Same as above, this eases translation to assembly code;
+float4 tex2Doffset(sampler2D map, float2 texcoord, float2 offset)
+{
+ #if defined(XBOX) && MAX_SEARCH_STEPS < 6
+ float4 result;
+ float x = offset.x;
+ float y = offset.y;
+ asm {
+ tfetch2D result, texcoord, map, OffsetX = x, OffsetY = y
+ };
+ return result;
+ #else
+ return tex2Dlevel0(map, texcoord + PIXEL_SIZE * offset);
+ #endif
+}
+
+
+// Ok, we have the distance and both crossing edges, can you please return
+// the float2 blending weights?
+float2 Area(float2 distance, float e1, float e2)
+{
+ // * By dividing by areaSize - 1.0 below we are implicitely offsetting to
+ // always fall inside of a pixel
+ // * Rounding prevents bilinear access precision problems
+ float areaSize = MAX_DISTANCE * 5.0;
+ float2 pixcoord = MAX_DISTANCE * round(4.0 * float2(e1, e2)) + distance;
+ float2 texcoord = pixcoord / (areaSize - 1.0);
+ return tex2Dlevel0(areaMap, texcoord).rg;
+}
+
+
+// Search functions for the 2nd pass.
+float SearchXLeft(float2 texcoord)
+{
+ // We compare with 0.9 to prevent bilinear access precision problems.
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g;
+ [flatten] if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchXRight(float2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0)).g;
+ [flatten] if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchYUp(float2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r;
+ [flatten] if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchYDown(float2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, float2(i, 0.0).yx).r;
+ [flatten] if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/blendWeightCalculationP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/blendWeightCalculationP.glsl
new file mode 100644
index 000000000..af01ce6f9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/blendWeightCalculationP.glsl
@@ -0,0 +1,83 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "../../../gl/hlslCompat.glsl"
+
+in vec2 texcoord;
+
+uniform sampler2D edgesMap;
+uniform sampler2D edgesMapL;
+uniform sampler2D areaMap;
+
+out vec4 OUT_col;
+
+#include "./functions.glsl"
+
+
+void main()
+{
+ vec4 areas = vec4(0.0);
+
+ vec2 e = texture(edgesMap, texcoord).rg;
+
+ //[branch]
+ if (bool(e.g)) // Edge at north
+ {
+ // Search distances to the left and to the right:
+ vec2 d = vec2(SearchXLeft(texcoord), SearchXRight(texcoord));
+
+ // Now fetch the crossing edges. Instead of sampling between edgels, we
+ // sample at -0.25, to be able to discern what value has each edgel:
+ vec4 coords = mad(vec4(d.x, -0.25, d.y + 1.0, -0.25),
+ PIXEL_SIZE.xyxy, texcoord.xyxy);
+ float e1 = tex2Dlevel0(edgesMapL, coords.xy).r;
+ float e2 = tex2Dlevel0(edgesMapL, coords.zw).r;
+
+ // Ok, we know how this pattern looks like, now it is time for getting
+ // the actual area:
+ areas.rg = Area(abs(d), e1, e2);
+ }
+
+ //[branch]
+ if (bool(e.r)) // Edge at west
+ {
+ // Search distances to the top and to the bottom:
+ vec2 d = vec2(SearchYUp(texcoord), SearchYDown(texcoord));
+
+ // Now fetch the crossing edges (yet again):
+ vec4 coords = mad(vec4(-0.25, d.x, -0.25, d.y + 1.0),
+ PIXEL_SIZE.xyxy, texcoord.xyxy);
+ float e1 = tex2Dlevel0(edgesMapL, coords.xy).g;
+ float e2 = tex2Dlevel0(edgesMapL, coords.zw).g;
+
+ // Get the area for this direction:
+ areas.ba = Area(abs(d), e1, e2);
+ }
+
+ OUT_col = areas;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/edgeDetectionP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/edgeDetectionP.glsl
new file mode 100644
index 000000000..d964a28a4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/edgeDetectionP.glsl
@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "../../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+
+uniform sampler2D colorMapG;
+uniform sampler2D deferredMap;
+
+uniform vec3 lumaCoefficients;
+uniform float threshold;
+uniform float depthThreshold;
+
+in vec2 texcoord;
+in vec4 offset[2];
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Luma calculation requires gamma-corrected colors (texture 'colorMapG').
+ //
+ // Note that there is a lot of overlapped luma calculations; performance
+ // can be improved if this luma calculation is performed in the main pass,
+ // which may give you an edge if used in conjunction with a z deferred.
+
+ float L = dot(texture(colorMapG, texcoord).rgb, lumaCoefficients);
+
+ float Lleft = dot(texture(colorMapG, offset[0].xy).rgb, lumaCoefficients);
+ float Ltop = dot(texture(colorMapG, offset[0].zw).rgb, lumaCoefficients);
+ float Lright = dot(texture(colorMapG, offset[1].xy).rgb, lumaCoefficients);
+ float Lbottom = dot(texture(colorMapG, offset[1].zw).rgb, lumaCoefficients);
+
+ vec4 delta = abs(vec4(L) - vec4(Lleft, Ltop, Lright, Lbottom));
+ vec4 edges = step(threshold, delta);
+
+ // Add depth edges to color edges
+ float D = deferredUncondition(deferredMap, texcoord).w;
+ float Dleft = deferredUncondition(deferredMap, offset[0].xy).w;
+ float Dtop = deferredUncondition(deferredMap, offset[0].zw).w;
+ float Dright = deferredUncondition(deferredMap, offset[1].xy).w;
+ float Dbottom = deferredUncondition(deferredMap, offset[1].zw).w;
+
+ delta = abs(vec4(D) - vec4(Dleft, Dtop, Dright, Dbottom));
+ edges += step(depthThreshold, delta);
+
+ if (dot(edges, vec4(1.0)) == 0.0)
+ discard;
+
+ OUT_col = edges;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/functions.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/functions.glsl
new file mode 100644
index 000000000..3ff56fb1a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/functions.glsl
@@ -0,0 +1,145 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform vec2 texSize0;
+
+#if !defined(PIXEL_SIZE)
+#define PIXEL_SIZE (1.0 / texSize0)
+#define MAX_SEARCH_STEPS 8
+#define MAX_DISTANCE 33
+#endif
+
+// Typical Multiply-Add operation to ease translation to assembly code.
+
+vec4 mad(vec4 m, vec4 a, vec4 b)
+{
+ #if defined(XBOX)
+ vec4 result;
+ asm {
+ mad result, m, a, b
+ };
+ return result;
+ #else
+ return m * a + b;
+ #endif
+}
+
+
+// This one just returns the first level of a mip map chain, which allow us to
+// avoid the nasty ddx/ddy warnings, even improving the performance a little
+// bit.
+vec4 tex2Dlevel0(sampler2D map, vec2 texcoord)
+{
+ return tex2Dlod(map, vec4(texcoord, 0.0, 0.0));
+}
+
+
+// Same as above, this eases translation to assembly code;
+vec4 tex2Doffset(sampler2D map, vec2 texcoord, vec2 offset)
+{
+ #if defined(XBOX) && MAX_SEARCH_STEPS < 6
+ vec4 result;
+ float x = offset.x;
+ float y = offset.y;
+ asm {
+ tfetch2D result, texcoord, map, OffsetX = x, OffsetY = y
+ };
+ return result;
+ #else
+ return tex2Dlevel0(map, texcoord + PIXEL_SIZE * offset);
+ #endif
+}
+
+
+// Ok, we have the distance and both crossing edges, can you please return
+// the vec2 blending weights?
+vec2 Area(vec2 distance, float e1, float e2)
+{
+ // * By dividing by areaSize - 1.0 below we are implicitely offsetting to
+ // always fall inside of a pixel
+ // * Rounding prevents bilinear access precision problems
+ float areaSize = MAX_DISTANCE * 5.0;
+ vec2 pixcoord = MAX_DISTANCE * round(4.0 * vec2(e1, e2)) + distance;
+ vec2 texcoord = pixcoord / (areaSize - 1.0);
+ return tex2Dlevel0(areaMap, texcoord).rg;
+}
+
+
+// Search functions for the 2nd pass.
+float SearchXLeft(vec2 texcoord)
+{
+ // We compare with 0.9 to prevent bilinear access precision problems.
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0)).g;
+ /*[flatten]*/ if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchXRight(vec2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0)).g;
+ /*[flatten]*/ if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchYUp(vec2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = -1.5; i > -2.0 * MAX_SEARCH_STEPS; i -= 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0).yx).r;
+ /*[flatten]*/ if (e < 0.9) break;
+ }
+ return max(i + 1.5 - 2.0 * e, -2.0 * MAX_SEARCH_STEPS);
+}
+
+// Search functions for the 2nd pass.
+float SearchYDown(vec2 texcoord)
+{
+ float i;
+ float e = 0.0;
+ for (i = 1.5; i < 2.0 * MAX_SEARCH_STEPS; i += 2.0)
+ {
+ e = tex2Doffset(edgesMapL, texcoord, vec2(i, 0.0).yx).r;
+ /*[flatten]*/ if (e < 0.9) break;
+ }
+ return min(i - 1.5 + 2.0 * e, 2.0 * MAX_SEARCH_STEPS);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/neighborhoodBlendingP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/neighborhoodBlendingP.glsl
new file mode 100644
index 000000000..eddbcc47c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/neighborhoodBlendingP.glsl
@@ -0,0 +1,88 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "../../../gl/hlslCompat.glsl"
+
+in vec2 texcoord;
+in vec4 offset[2];
+
+uniform sampler2D blendMap;
+uniform sampler2D colorMapL;
+uniform sampler2D colorMap;
+
+// Dummy sampers to please include.
+uniform sampler2D areaMap;
+uniform sampler2D edgesMapL;
+#include "./functions.glsl"
+
+out vec4 OUT_col;
+
+void main()
+{
+ // Fetch the blending weights for current pixel:
+ vec4 topLeft = texture(blendMap, texcoord);
+ float bottom = texture(blendMap, offset[1].zw).g;
+ float right = texture(blendMap, offset[1].xy).a;
+ vec4 a = vec4(topLeft.r, bottom, topLeft.b, right);
+
+ // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
+ // a weighted average, where the weight of each line is 'a' cubed, which
+ // favors blending and works well in practice.
+ vec4 w = a * a * a;
+
+ // There is some blending weight with a value greater than 0.0?
+ float sum = dot(w, vec4(1.0));
+ if (sum < 1e-5)
+ discard;
+
+ vec4 color = vec4(0.0);
+
+ // Add the contributions of the possible 4 lines that can cross this pixel:
+ #ifdef BILINEAR_FILTER_TRICK
+ vec4 coords = mad(vec4( 0.0, -a.r, 0.0, a.g), PIXEL_SIZE.yyyy, texcoord.xyxy);
+ color = mad(texture(colorMapL, coords.xy), vec4(w.r), color);
+ color = mad(texture(colorMapL, coords.zw), vec4(w.g), color);
+
+ coords = mad(vec4(-a.b, 0.0, a.a, 0.0), PIXEL_SIZE.xxxx, texcoord.xyxy);
+ color = mad(texture(colorMapL, coords.xy), vec4(w.b), color);
+ color = mad(texture(colorMapL, coords.zw), vec4(w.a), color);
+ #else
+ vec4 C = texture(colorMap, texcoord);
+ vec4 Cleft = texture(colorMap, offset[0].xy);
+ vec4 Ctop = texture(colorMap, offset[0].zw);
+ vec4 Cright = texture(colorMap, offset[1].xy);
+ vec4 Cbottom = texture(colorMap, offset[1].zw);
+ color = mad(mix(C, Ctop, a.r), vec4(w.r), color);
+ color = mad(mix(C, Cbottom, a.g), vec4(w.g), color);
+ color = mad(mix(C, Cleft, a.b), vec4(w.b), color);
+ color = mad(mix(C, Cright, a.a), vec4(w.a), color);
+ #endif
+
+ // Normalize the resulting color and we are finished!
+ OUT_col = color / sum;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/offsetV.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/offsetV.glsl
new file mode 100644
index 000000000..53d927c29
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/offsetV.glsl
@@ -0,0 +1,57 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "../../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define IN_position vPosition
+#define IN_texcoord vTexCoord0
+
+#define OUT_position gl_Position
+out vec2 texcoord;
+#define OUT_texcoord texcoord
+out vec4 offset[2];
+#define OUT_offset offset
+
+uniform vec2 texSize0;
+
+void main()
+{
+ OUT_position = IN_position;
+ vec2 PIXEL_SIZE = 1.0 / texSize0;
+
+ OUT_texcoord = IN_texcoord;
+ OUT_texcoord.xy += PIXEL_SIZE * 0.5;
+
+ OUT_offset[0] = OUT_texcoord.xyxy + PIXEL_SIZE.xyxy * vec4(-1.0, 0.0, 0.0, -1.0);
+ OUT_offset[1] = OUT_texcoord.xyxy + PIXEL_SIZE.xyxy * vec4( 1.0, 0.0, 0.0, 1.0);
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/passthruV.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/passthruV.glsl
new file mode 100644
index 000000000..1aa64112c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/gl/passthruV.glsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+#include "../../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define IN_position vPosition
+#define IN_texcoord vTexCoord0
+
+#define OUT_position gl_Position
+out vec2 texcoord;
+#define OUT_texcoord texcoord
+
+uniform vec2 texSize0;
+
+void main()
+{
+ OUT_position = IN_position;
+ vec2 PIXEL_SIZE = 1.0 / texSize0;
+
+ OUT_texcoord = IN_texcoord;
+ texcoord.xy += PIXEL_SIZE * 0.5;
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/neighborhoodBlendingP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/neighborhoodBlendingP.hlsl
new file mode 100644
index 000000000..aaaacafe2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/neighborhoodBlendingP.hlsl
@@ -0,0 +1,84 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform sampler2D blendMap : register(S0);
+uniform sampler2D colorMapL : register(S1);
+uniform sampler2D colorMap : register(S2);
+
+// Dummy sampers to please include.
+sampler2D areaMap;
+sampler2D edgesMapL;
+#include "./functions.hlsl"
+
+
+float4 main( float2 texcoord : TEXCOORD0,
+ float4 offset[2]: TEXCOORD1 ) : COLOR0
+{
+ // Fetch the blending weights for current pixel:
+ float4 topLeft = tex2D(blendMap, texcoord);
+ float bottom = tex2D(blendMap, offset[1].zw).g;
+ float right = tex2D(blendMap, offset[1].xy).a;
+ float4 a = float4(topLeft.r, bottom, topLeft.b, right);
+
+ // Up to 4 lines can be crossing a pixel (one in each edge). So, we perform
+ // a weighted average, where the weight of each line is 'a' cubed, which
+ // favors blending and works well in practice.
+ float4 w = a * a * a;
+
+ // There is some blending weight with a value greater than 0.0?
+ float sum = dot(w, 1.0);
+ if (sum < 1e-5)
+ discard;
+
+ float4 color = 0.0;
+
+ // Add the contributions of the possible 4 lines that can cross this pixel:
+ #ifdef BILINEAR_FILTER_TRICK
+ float4 coords = mad(float4( 0.0, -a.r, 0.0, a.g), PIXEL_SIZE.yyyy, texcoord.xyxy);
+ color = mad(tex2D(colorMapL, coords.xy), w.r, color);
+ color = mad(tex2D(colorMapL, coords.zw), w.g, color);
+
+ coords = mad(float4(-a.b, 0.0, a.a, 0.0), PIXEL_SIZE.xxxx, texcoord.xyxy);
+ color = mad(tex2D(colorMapL, coords.xy), w.b, color);
+ color = mad(tex2D(colorMapL, coords.zw), w.a, color);
+ #else
+ float4 C = tex2D(colorMap, texcoord);
+ float4 Cleft = tex2D(colorMap, offset[0].xy);
+ float4 Ctop = tex2D(colorMap, offset[0].zw);
+ float4 Cright = tex2D(colorMap, offset[1].xy);
+ float4 Cbottom = tex2D(colorMap, offset[1].zw);
+ color = mad(lerp(C, Ctop, a.r), w.r, color);
+ color = mad(lerp(C, Cbottom, a.g), w.g, color);
+ color = mad(lerp(C, Cleft, a.b), w.b, color);
+ color = mad(lerp(C, Cright, a.a), w.a, color);
+ #endif
+
+ // Normalize the resulting color and we are finished!
+ return color / sum;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/offsetV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/offsetV.hlsl
new file mode 100644
index 000000000..d9c922afd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/offsetV.hlsl
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform float2 texSize0;
+
+void main( inout float4 position : POSITION0,
+ inout float2 texcoord : TEXCOORD0,
+ out float4 offset[2] : TEXCOORD1 )
+{
+ float2 PIXEL_SIZE = 1.0 / texSize0;
+
+ texcoord.xy += PIXEL_SIZE * 0.5;
+
+ offset[0] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4(-1.0, 0.0, 0.0, -1.0);
+ offset[1] = texcoord.xyxy + PIXEL_SIZE.xyxy * float4( 1.0, 0.0, 0.0, 1.0);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/passthruV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/passthruV.hlsl
new file mode 100644
index 000000000..24ef534fd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/mlaa/passthruV.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.
+//-----------------------------------------------------------------------------
+
+// An implementation of "Practical Morphological Anti-Aliasing" from
+// GPU Pro 2 by Jorge Jimenez, Belen Masia, Jose I. Echevarria,
+// Fernando Navarro, and Diego Gutierrez.
+//
+// http://www.iryoku.com/mlaa/
+
+
+uniform float2 texSize0;
+
+void main( inout float4 position : POSITION0,
+ inout float2 texcoord : TEXCOORD0)
+{
+ float2 PIXEL_SIZE = 1.0 / texSize0;
+ texcoord.xy += PIXEL_SIZE * 0.5;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/motionBlurP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/motionBlurP.hlsl
new file mode 100644
index 000000000..90b8f6f25
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/motionBlurP.hlsl
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFx.hlsl"
+#include "../torque.hlsl"
+#include "../shaderModelAutoGen.hlsl"
+
+uniform float4x4 matPrevScreenToWorld;
+uniform float4x4 matWorldToScreen;
+
+// Passed in from setShaderConsts()
+uniform float velocityMultiplier;
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 1);
+
+float4 main(PFXVertToPix IN) : TORQUE_TARGET0
+{
+ float samples = 5;
+
+ // First get the deferred texture for uv channel 0
+ float4 deferred = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 );
+
+ // Next extract the depth
+ float depth = deferred.a;
+
+ // Create the screen position
+ float4 screenPos = float4(IN.uv0.x*2-1, IN.uv0.y*2-1, depth*2-1, 1);
+
+ // Calculate the world position
+ float4 D = mul(screenPos, matWorldToScreen);
+ float4 worldPos = D / D.w;
+
+ // Now calculate the previous screen position
+ float4 previousPos = mul( worldPos, matPrevScreenToWorld );
+ previousPos /= previousPos.w;
+
+ // Calculate the XY velocity
+ float2 velocity = ((screenPos - previousPos) / velocityMultiplier).xy;
+
+ // Generate the motion blur
+ float4 color = TORQUE_TEX2D(backBuffer, IN.uv0);
+ IN.uv0 += velocity;
+
+ for(int i = 1; i blurNormalTol )
+ {
+ usedCount++;
+ total += weight;
+ occlusion += TORQUE_TEX2D( occludeMap, uv ).r * weight;
+ }
+ }
+}
+
+float4 main( VertToPix IN ) : TORQUE_TARGET0
+{
+ //float4 centerTap;
+ float4 centerTap = TORQUE_DEFERRED_UNCONDITION( deferredMap, IN.uv0.zw );
+
+ //return centerTap;
+
+ //float centerOcclude = TORQUE_TEX2D( occludeMap, IN.uv0.zw ).r;
+ //return float4( centerOcclude.rrr, 1 );
+
+ float4 kernel = float4( 0.175, 0.275, 0.375, 0.475 ); //25f;
+
+ float occlusion = 0;
+ int usedCount = 0;
+ float total = 0.0;
+
+ sample( IN.uv0.xy, kernel.x, centerTap, usedCount, occlusion, total );
+ sample( IN.uv1, kernel.y, centerTap, usedCount, occlusion, total );
+ sample( IN.uv2, kernel.z, centerTap, usedCount, occlusion, total );
+ sample( IN.uv3, kernel.w, centerTap, usedCount, occlusion, total );
+
+ sample( IN.uv4, kernel.x, centerTap, usedCount, occlusion, total );
+ sample( IN.uv5, kernel.y, centerTap, usedCount, occlusion, total );
+ sample( IN.uv6, kernel.z, centerTap, usedCount, occlusion, total );
+ sample( IN.uv7, kernel.w, centerTap, usedCount, occlusion, total );
+
+ occlusion += TORQUE_TEX2D( occludeMap, IN.uv0.zw ).r * 0.5;
+ total += 0.5;
+ //occlusion /= 3.0;
+
+ //occlusion /= (float)usedCount / 8.0;
+ occlusion /= total;
+
+ return float4( occlusion.rrr, 1 );
+
+
+ //return float4( 0,0,0,occlusion );
+
+ //float3 color = TORQUE_TEX2D( colorMap, IN.uv0.zw );
+
+ //return float4( color, occlusion );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_Blur_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_Blur_V.hlsl
new file mode 100644
index 000000000..6ab278900
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_Blur_V.hlsl
@@ -0,0 +1,86 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+
+uniform float2 texSize0;
+uniform float2 oneOverTargetSize;
+uniform float4 rtParams0;
+
+struct VertToPix
+{
+ float4 hpos : TORQUE_POSITION;
+
+ float4 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+
+ float2 uv4 : TEXCOORD4;
+ float2 uv5 : TEXCOORD5;
+ float2 uv6 : TEXCOORD6;
+ float2 uv7 : TEXCOORD7;
+};
+
+VertToPix main( PFXVert IN )
+{
+ VertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1.0);
+
+ IN.uv = viewportCoordToRenderTarget( IN.uv, rtParams0 );
+
+ //float4 step = float4( 3.5, 2.5, 1.5, 0.5 );
+ //float4 step = float4( 4.0, 3.0, 2.0, 1.0 );
+ float4 step = float4( 9.0, 5.0, 2.5, 0.5 );
+
+ // I don't know why this offset is necessary, but it is.
+ //IN.uv = IN.uv * oneOverTargetSize;
+
+ OUT.uv0.xy = IN.uv + ( ( BLUR_DIR * step.x ) / texSize0 );
+ OUT.uv1 = IN.uv + ( ( BLUR_DIR * step.y ) / texSize0 );
+ OUT.uv2 = IN.uv + ( ( BLUR_DIR * step.z ) / texSize0 );
+ OUT.uv3 = IN.uv + ( ( BLUR_DIR * step.w ) / texSize0 );
+
+ OUT.uv4 = IN.uv - ( ( BLUR_DIR * step.x ) / texSize0 );
+ OUT.uv5 = IN.uv - ( ( BLUR_DIR * step.y ) / texSize0 );
+ OUT.uv6 = IN.uv - ( ( BLUR_DIR * step.z ) / texSize0 );
+ OUT.uv7 = IN.uv - ( ( BLUR_DIR * step.w ) / texSize0 );
+
+ OUT.uv0.zw = IN.uv;
+
+ /*
+ OUT.uv0 = viewportCoordToRenderTarget( OUT.uv0, rtParams0 );
+ OUT.uv1 = viewportCoordToRenderTarget( OUT.uv1, rtParams0 );
+ OUT.uv2 = viewportCoordToRenderTarget( OUT.uv2, rtParams0 );
+ OUT.uv3 = viewportCoordToRenderTarget( OUT.uv3, rtParams0 );
+
+ OUT.uv4 = viewportCoordToRenderTarget( OUT.uv4, rtParams0 );
+ OUT.uv5 = viewportCoordToRenderTarget( OUT.uv5, rtParams0 );
+ OUT.uv6 = viewportCoordToRenderTarget( OUT.uv6, rtParams0 );
+ OUT.uv7 = viewportCoordToRenderTarget( OUT.uv7, rtParams0 );
+ */
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_P.hlsl
new file mode 100644
index 000000000..ff31a4b8b
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_P.hlsl
@@ -0,0 +1,272 @@
+//-----------------------------------------------------------------------------
+// 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 "../../shaderModelAutoGen.hlsl"
+#include "./../postFx.hlsl"
+
+#define DOSMALL
+#define DOLARGE
+
+TORQUE_UNIFORM_SAMPLER2D(deferredMap,0);
+TORQUE_UNIFORM_SAMPLER2D(randNormalTex,1);
+TORQUE_UNIFORM_SAMPLER1D(powTable,2);
+
+uniform float2 nearFar;
+uniform float2 worldToScreenScale;
+uniform float2 texSize0;
+uniform float2 texSize1;
+uniform float2 targetSize;
+
+// Script-set constants.
+
+uniform float overallStrength;
+
+uniform float sRadius;
+uniform float sStrength;
+uniform float sDepthMin;
+uniform float sDepthMax;
+uniform float sDepthPow;
+uniform float sNormalTol;
+uniform float sNormalPow;
+
+uniform float lRadius;
+uniform float lStrength;
+uniform float lDepthMin;
+uniform float lDepthMax;
+uniform float lDepthPow;
+uniform float lNormalTol;
+uniform float lNormalPow;
+
+
+#ifndef QUALITY
+ #define QUALITY 2
+#endif
+
+
+#if QUALITY == 0
+ #define sSampleCount 4
+ #define totalSampleCount 12
+#elif QUALITY == 1
+ #define sSampleCount 6
+ #define totalSampleCount 24
+#elif QUALITY == 2
+ #define sSampleCount 8
+ #define totalSampleCount 32
+#endif
+
+
+float getOcclusion( float depthDiff, float depthMin, float depthMax, float depthPow,
+ float normalDiff, float dt, float normalTol, float normalPow )
+{
+ if ( depthDiff < 0.0 )
+ return 0.0;
+
+ float delta = abs( depthDiff );
+
+ if ( delta < depthMin || delta > depthMax )
+ return 0.0;
+
+ delta = saturate( delta / depthMax );
+
+ if ( dt > 0.0 )
+ normalDiff *= dt;
+ else
+ normalDiff = 1.0;
+
+
+ normalDiff *= 1.0 - ( dt * 0.5 + 0.5 );
+
+ return ( 1.0 - TORQUE_TEX1D( powTable, delta ).r ) * normalDiff;
+}
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float3 ptSphere[32] =
+ {
+ float3( 0.295184, 0.077723, 0.068429 ),
+ float3( -0.271976, -0.365221, -0.838363 ),
+ float3( 0.547713, 0.467576, 0.488515 ),
+ float3( 0.662808, -0.031733, -0.584758 ),
+ float3( -0.025717, 0.218955, -0.657094 ),
+ float3( -0.310153, -0.365223, -0.370701 ),
+ float3( -0.101407, -0.006313, -0.747665 ),
+ float3( -0.769138, 0.360399, -0.086847 ),
+ float3( -0.271988, -0.275140, -0.905353 ),
+ float3( 0.096740, -0.566901, 0.700151 ),
+ float3( 0.562872, -0.735136, -0.094647 ),
+ float3( 0.379877, 0.359278, 0.190061 ),
+ float3( 0.519064, -0.023055, 0.405068 ),
+ float3( -0.301036, 0.114696, -0.088885 ),
+ float3( -0.282922, 0.598305, 0.487214 ),
+ float3( -0.181859, 0.251670, -0.679702 ),
+ float3( -0.191463, -0.635818, -0.512919 ),
+ float3( -0.293655, 0.427423, 0.078921 ),
+ float3( -0.267983, 0.680534, -0.132880 ),
+ float3( 0.139611, 0.319637, 0.477439 ),
+ float3( -0.352086, 0.311040, 0.653913 ),
+ float3( 0.321032, 0.805279, 0.487345 ),
+ float3( 0.073516, 0.820734, -0.414183 ),
+ float3( -0.155324, 0.589983, -0.411460 ),
+ float3( 0.335976, 0.170782, -0.527627 ),
+ float3( 0.463460, -0.355658, -0.167689 ),
+ float3( 0.222654, 0.596550, -0.769406 ),
+ float3( 0.922138, -0.042070, 0.147555 ),
+ float3( -0.727050, -0.329192, 0.369826 ),
+ float3( -0.090731, 0.533820, 0.463767 ),
+ float3( -0.323457, -0.876559, -0.238524 ),
+ float3( -0.663277, -0.372384, -0.342856 )
+ };
+
+ // Sample a random normal for reflecting the
+ // sphere vector later in our loop.
+ float4 noiseMapUV = float4( ( IN.uv1 * ( targetSize / texSize1 ) ).xy, 0, 0 );
+ float3 reflectNormal = normalize( TORQUE_TEX2DLOD( randNormalTex, noiseMapUV ).xyz * 2.0 - 1.0 );
+ //return float4( reflectNormal, 1 );
+
+ float4 deferred = TORQUE_DEFERRED_UNCONDITION( deferredMap, IN.uv0 );
+ float3 normal = deferred.xyz;
+ float depth = deferred.a;
+ //return float4( ( depth ).xxx, 1 );
+
+ // Early out if too far away.
+ if ( depth > 0.99999999 )
+ return float4( 0,0,0,0 );
+
+ // current fragment coords in screen space
+ float3 ep = float3( IN.uv0, depth );
+
+ float bl;
+ float3 baseRay, ray, se, occNorm, projRadius;
+ float normalDiff = 0;
+ float depthMin, depthMax, dt, depthDiff;
+ float4 occluderFragment;
+ int i;
+ float sOcclusion = 0.0;
+ float lOcclusion = 0.0;
+
+ //------------------------------------------------------------
+ // Small radius
+ //------------------------------------------------------------
+
+#ifdef DOSMALL
+
+ bl = 0.0;
+
+ projRadius.xy = ( float2( sRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 );
+ projRadius.z = sRadius / nearFar.y;
+
+ depthMin = projRadius.z * sDepthMin;
+ depthMax = projRadius.z * sDepthMax;
+
+ //float maxr = 1;
+ //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr );
+ //if ( radiusDepth.x < 1.0 / targetSize.x )
+ // return color;
+ //radiusDepth.xyz = 0.0009;
+ [unroll]
+ for ( i = 0; i < sSampleCount; i++ )
+ {
+ baseRay = reflect( ptSphere[i], reflectNormal );
+
+ dt = dot( baseRay.xyz, normal );
+
+ baseRay *= sign( dt );
+
+ ray = ( projRadius * baseRay.xzy );
+ ray.y = -ray.y;
+
+ se = ep + ray;
+
+ occluderFragment = TORQUE_DEFERRED_UNCONDITION( deferredMap, se.xy );
+
+ depthDiff = se.z - occluderFragment.a;
+
+ dt = dot( occluderFragment.xyz, baseRay.xyz );
+ normalDiff = dot( occluderFragment.xyz, normal );
+
+ bl += getOcclusion( depthDiff, depthMin, depthMax, sDepthPow, normalDiff, dt, sNormalTol, sNormalPow );
+ }
+
+ sOcclusion = sStrength * ( bl / (float)sSampleCount );
+
+#endif // DOSMALL
+
+
+ //------------------------------------------------------------
+ // Large radius
+ //------------------------------------------------------------
+
+#ifdef DOLARGE
+
+ bl = 0.0;
+
+ projRadius.xy = ( float2( lRadius.rr ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 );
+ projRadius.z = lRadius / nearFar.y;
+
+ depthMin = projRadius.z * lDepthMin;
+ depthMax = projRadius.z * lDepthMax;
+
+ //projRadius.xy = clamp( projRadius.xy, 0.0, 0.01 );
+ //float maxr = 1;
+ //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr );
+ //if ( radiusDepth.x < 1.0 / targetSize.x )
+ // return color;
+ //radiusDepth.xyz = 0.0009;
+ [unroll]
+ for ( i = sSampleCount; i < totalSampleCount; i++ )
+ {
+ baseRay = reflect( ptSphere[i], reflectNormal );
+
+ dt = dot( baseRay.xyz, normal );
+
+ baseRay *= sign( dt );
+
+ ray = ( projRadius * baseRay.xzy );
+ ray.y = -ray.y;
+
+ se = ep + ray;
+
+ occluderFragment = TORQUE_DEFERRED_UNCONDITION( deferredMap, se.xy );
+
+ depthDiff = se.z - occluderFragment.a;
+
+ normalDiff = dot( occluderFragment.xyz, normal );
+ dt = dot( occluderFragment.xyz, baseRay.xyz );
+
+ bl += getOcclusion( depthDiff, depthMin, depthMax, lDepthPow, normalDiff, dt, lNormalTol, lNormalPow );
+ }
+
+ lOcclusion = lStrength * ( bl / (float)( totalSampleCount - sSampleCount ) );
+
+#endif // DOLARGE
+
+ float occlusion = saturate( max( sOcclusion, lOcclusion ) * overallStrength );
+
+ // Note black is unoccluded and white is fully occluded. This
+ // seems backwards, but it makes it simple to deal with the SSAO
+ // being disabled in the lighting shaders.
+
+ return occlusion;
+}
+
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_P.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_P.hlsl
new file mode 100644
index 000000000..696947d3e
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_P.hlsl
@@ -0,0 +1,29 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float power = pow( max( IN.uv0.x, 0 ), 0.1 );
+ return float4( power, 0, 0, 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_V.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_V.hlsl
new file mode 100644
index 000000000..76f67e711
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/SSAO_PowerTable_V.hlsl
@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// 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 "./../postFx.hlsl"
+#include "./../../torque.hlsl"
+
+
+uniform float4 rtParams0;
+uniform float4 rtParams1;
+uniform float4 rtParams2;
+uniform float4 rtParams3;
+
+PFXVertToPix main( PFXVert IN )
+{
+ PFXVertToPix OUT;
+
+ OUT.hpos = float4(IN.pos,1.0);
+ OUT.uv0 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams0 );
+ OUT.uv1 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams1 );
+ OUT.uv2 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams2 );
+ OUT.uv3 = IN.uv; //viewportCoordToRenderTarget( IN.uv, rtParams3 );
+
+ OUT.wsEyeRay = IN.wsEyeRay;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_P.glsl
new file mode 100644
index 000000000..cae920af8
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_P.glsl
@@ -0,0 +1,108 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec4 uv0;
+#define IN_uv0 uv0
+in vec2 uv1;
+#define IN_uv1 uv1
+in vec2 uv2;
+#define IN_uv2 uv2
+in vec2 uv3;
+#define IN_uv3 uv3
+
+in vec2 uv4;
+#define IN_uv4 uv4
+in vec2 uv5;
+#define IN_uv5 uv5
+in vec2 uv6;
+#define IN_uv6 uv6
+in vec2 uv7;
+#define IN_uv7 uv7
+
+uniform sampler2D occludeMap ;
+uniform sampler2D deferredMap ;
+uniform float blurDepthTol;
+uniform float blurNormalTol;
+
+out vec4 OUT_col;
+
+void _sample( vec2 uv, float weight, vec4 centerTap, inout int usedCount, inout float occlusion, inout float total )
+{
+ //return;
+ vec4 tap = deferredUncondition( deferredMap, uv );
+
+ if ( abs( tap.a - centerTap.a ) < blurDepthTol )
+ {
+ if ( dot( tap.xyz, centerTap.xyz ) > blurNormalTol )
+ {
+ usedCount++;
+ total += weight;
+ occlusion += texture( occludeMap, uv ).r * weight;
+ }
+ }
+}
+
+void main()
+{
+ //vec4 centerTap;
+ vec4 centerTap = deferredUncondition( deferredMap, IN_uv0.zw );
+
+ //return centerTap;
+
+ //float centerOcclude = texture( occludeMap, IN_uv0.zw ).r;
+ //return vec4( centerOcclude.rrr, 1 );
+
+ vec4 kernel = vec4( 0.175, 0.275, 0.375, 0.475 ); //25f;
+
+ float occlusion = 0;
+ int usedCount = 0;
+ float total = 0.0;
+
+ _sample( IN_uv0.xy, kernel.x, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv1, kernel.y, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv2, kernel.z, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv3, kernel.w, centerTap, usedCount, occlusion, total );
+
+ _sample( IN_uv4, kernel.x, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv5, kernel.y, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv6, kernel.z, centerTap, usedCount, occlusion, total );
+ _sample( IN_uv7, kernel.w, centerTap, usedCount, occlusion, total );
+
+ occlusion += texture( occludeMap, IN_uv0.zw ).r * 0.5;
+ total += 0.5;
+ //occlusion /= 3.0;
+
+ //occlusion /= (float)usedCount / 8.0;
+ occlusion /= total;
+
+ OUT_col = vec4( vec3(occlusion), 1 );
+
+
+ //return vec4( 0,0,0,occlusion );
+
+ //vec3 color = texture( colorMap, IN_uv0.zw );
+
+ //return vec4( color, occlusion );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_V.glsl
new file mode 100644
index 000000000..45a52e890
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_Blur_V.glsl
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+#define IN_pos vPosition
+#define _IN_uv vTexCoord0
+
+uniform vec2 texSize0;
+uniform vec4 rtParams0;
+uniform vec2 oneOverTargetSize;
+
+#define OUT_hpos gl_Position
+
+out vec4 uv0;
+#define OUT_uv0 uv0
+out vec2 uv1;
+#define OUT_uv1 uv1
+out vec2 uv2;
+#define OUT_uv2 uv2
+out vec2 uv3;
+#define OUT_uv3 uv3
+
+out vec2 uv4;
+#define OUT_uv4 uv4
+out vec2 uv5;
+#define OUT_uv5 uv5
+out vec2 uv6;
+#define OUT_uv6 uv6
+out vec2 uv7;
+#define OUT_uv7 uv7
+
+
+void main()
+{
+ OUT_hpos = IN_pos;
+
+ vec2 IN_uv = viewportCoordToRenderTarget( _IN_uv, rtParams0 );
+
+ //vec4 step = vec4( 3.5, 2.5, 1.5, 0.5 );
+ //vec4 step = vec4( 4.0, 3.0, 2.0, 1.0 );
+ vec4 step = vec4( 9.0, 5.0, 2.5, 0.5 );
+
+ // I don't know why this offset is necessary, but it is.
+ //IN_uv = IN_uv * oneOverTargetSize;
+
+ OUT_uv0.xy = IN_uv + ( ( BLUR_DIR * step.x ) / texSize0 );
+ OUT_uv1 = IN_uv + ( ( BLUR_DIR * step.y ) / texSize0 );
+ OUT_uv2 = IN_uv + ( ( BLUR_DIR * step.z ) / texSize0 );
+ OUT_uv3 = IN_uv + ( ( BLUR_DIR * step.w ) / texSize0 );
+
+ OUT_uv4 = IN_uv - ( ( BLUR_DIR * step.x ) / texSize0 );
+ OUT_uv5 = IN_uv - ( ( BLUR_DIR * step.y ) / texSize0 );
+ OUT_uv6 = IN_uv - ( ( BLUR_DIR * step.z ) / texSize0 );
+ OUT_uv7 = IN_uv - ( ( BLUR_DIR * step.w ) / texSize0 );
+
+ OUT_uv0.zw = IN_uv;
+
+ /*
+ OUT_uv0 = viewportCoordToRenderTarget( OUT_uv0, rtParams0 );
+ OUT_uv1 = viewportCoordToRenderTarget( OUT_uv1, rtParams0 );
+ OUT_uv2 = viewportCoordToRenderTarget( OUT_uv2, rtParams0 );
+ OUT_uv3 = viewportCoordToRenderTarget( OUT_uv3, rtParams0 );
+
+ OUT_uv4 = viewportCoordToRenderTarget( OUT_uv4, rtParams0 );
+ OUT_uv5 = viewportCoordToRenderTarget( OUT_uv5, rtParams0 );
+ OUT_uv6 = viewportCoordToRenderTarget( OUT_uv6, rtParams0 );
+ OUT_uv7 = viewportCoordToRenderTarget( OUT_uv7, rtParams0 );
+ */
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_P.glsl
new file mode 100644
index 000000000..cfff88381
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_P.glsl
@@ -0,0 +1,278 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/postFX.glsl"
+
+#define DOSMALL
+#define DOLARGE
+
+uniform sampler2D deferredMap ;
+uniform sampler2D randNormalTex ;
+uniform sampler1D powTable ;
+
+uniform vec2 nearFar;
+uniform vec2 worldToScreenScale;
+uniform vec2 texSize0;
+uniform vec2 texSize1;
+uniform vec2 targetSize;
+
+// Script-set constants.
+
+uniform float overallStrength;
+
+uniform float sRadius;
+uniform float sStrength;
+uniform float sDepthMin;
+uniform float sDepthMax;
+uniform float sDepthPow;
+uniform float sNormalTol;
+uniform float sNormalPow;
+
+uniform float lRadius;
+uniform float lStrength;
+uniform float lDepthMin;
+uniform float lDepthMax;
+uniform float lDepthPow;
+uniform float lNormalTol;
+uniform float lNormalPow;
+
+out vec4 OUT_col;
+
+
+#ifndef QUALITY
+ #define QUALITY 2
+#endif
+
+
+#if QUALITY == 0
+ #define sSampleCount 4
+ #define totalSampleCount 12
+#elif QUALITY == 1
+ #define sSampleCount 6
+ #define totalSampleCount 24
+#elif QUALITY == 2
+ #define sSampleCount 8
+ #define totalSampleCount 32
+#endif
+
+
+float getOcclusion( float depthDiff, float depthMin, float depthMax, float depthPow,
+ float normalDiff, float dt, float normalTol, float normalPow )
+{
+ if ( depthDiff < 0.0 )
+ return 0.0;
+
+ float delta = abs( depthDiff );
+
+ if ( delta < depthMin || delta > depthMax )
+ return 0.0;
+
+ delta = saturate( delta / depthMax );
+
+ if ( dt > 0.0 )
+ normalDiff *= dt;
+ else
+ normalDiff = 1.0;
+
+
+ normalDiff *= 1.0 - ( dt * 0.5 + 0.5 );
+
+ return ( 1.0 - texture( powTable, delta ).r ) * normalDiff;
+}
+
+
+void main()
+{
+ const vec3 ptSphere[32] = vec3[]
+ (
+ vec3( 0.295184, 0.077723, 0.068429 ),
+ vec3( -0.271976, -0.365221, -0.838363 ),
+ vec3( 0.547713, 0.467576, 0.488515 ),
+ vec3( 0.662808, -0.031733, -0.584758 ),
+ vec3( -0.025717, 0.218955, -0.657094 ),
+ vec3( -0.310153, -0.365223, -0.370701 ),
+ vec3( -0.101407, -0.006313, -0.747665 ),
+ vec3( -0.769138, 0.360399, -0.086847 ),
+ vec3( -0.271988, -0.275140, -0.905353 ),
+ vec3( 0.096740, -0.566901, 0.700151 ),
+ vec3( 0.562872, -0.735136, -0.094647 ),
+ vec3( 0.379877, 0.359278, 0.190061 ),
+ vec3( 0.519064, -0.023055, 0.405068 ),
+ vec3( -0.301036, 0.114696, -0.088885 ),
+ vec3( -0.282922, 0.598305, 0.487214 ),
+ vec3( -0.181859, 0.251670, -0.679702 ),
+ vec3( -0.191463, -0.635818, -0.512919 ),
+ vec3( -0.293655, 0.427423, 0.078921 ),
+ vec3( -0.267983, 0.680534, -0.132880 ),
+ vec3( 0.139611, 0.319637, 0.477439 ),
+ vec3( -0.352086, 0.311040, 0.653913 ),
+ vec3( 0.321032, 0.805279, 0.487345 ),
+ vec3( 0.073516, 0.820734, -0.414183 ),
+ vec3( -0.155324, 0.589983, -0.411460 ),
+ vec3( 0.335976, 0.170782, -0.527627 ),
+ vec3( 0.463460, -0.355658, -0.167689 ),
+ vec3( 0.222654, 0.596550, -0.769406 ),
+ vec3( 0.922138, -0.042070, 0.147555 ),
+ vec3( -0.727050, -0.329192, 0.369826 ),
+ vec3( -0.090731, 0.533820, 0.463767 ),
+ vec3( -0.323457, -0.876559, -0.238524 ),
+ vec3( -0.663277, -0.372384, -0.342856 )
+ );
+
+ // Sample a random normal for reflecting the
+ // sphere vector later in our loop.
+ vec4 noiseMapUV = vec4( ( IN_uv1 * ( targetSize / texSize1 ) ).xy, 0, 0 );
+ vec3 reflectNormal = normalize( tex2Dlod( randNormalTex, noiseMapUV ).xyz * 2.0 - 1.0 );
+ //return vec4( reflectNormal, 1 );
+
+ vec4 deferred = deferredUncondition( deferredMap, IN_uv0 );
+ vec3 normal = deferred.xyz;
+ float depth = deferred.a;
+ //return vec4( ( depth ).xxx, 1 );
+
+ // Early out if too far away.
+ if ( depth > 0.99999999 )
+ {
+ OUT_col = vec4( 0,0,0,0 );
+ return;
+ }
+
+ // current fragment coords in screen space
+ vec3 ep = vec3( IN_uv0, depth );
+
+ float bl;
+ vec3 baseRay, ray, se, occNorm, projRadius;
+ float normalDiff = 0;
+ float depthMin, depthMax, dt, depthDiff;
+ vec4 occluderFragment;
+ int i;
+ float sOcclusion = 0.0;
+ float lOcclusion = 0.0;
+
+ //------------------------------------------------------------
+ // Small radius
+ //------------------------------------------------------------
+
+#ifdef DOSMALL
+
+ bl = 0.0;
+
+ projRadius.xy = ( vec2( sRadius ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 );
+ projRadius.z = sRadius / nearFar.y;
+
+ depthMin = projRadius.z * sDepthMin;
+ depthMax = projRadius.z * sDepthMax;
+
+ //float maxr = 1;
+ //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr );
+ //if ( radiusDepth.x < 1.0 / targetSize.x )
+ // return color;
+ //radiusDepth.xyz = 0.0009;
+
+ for ( i = 0; i < sSampleCount; i++ )
+ {
+ baseRay = reflect( ptSphere[i], reflectNormal );
+
+ dt = dot( baseRay.xyz, normal );
+
+ baseRay *= sign( dt );
+
+ ray = ( projRadius * baseRay.xzy );
+ ray.y = -ray.y;
+
+ se = ep + ray;
+
+ occluderFragment = deferredUncondition( deferredMap, se.xy );
+
+ depthDiff = se.z - occluderFragment.a;
+
+ dt = dot( occluderFragment.xyz, baseRay.xyz );
+ normalDiff = dot( occluderFragment.xyz, normal );
+
+ bl += getOcclusion( depthDiff, depthMin, depthMax, sDepthPow, normalDiff, dt, sNormalTol, sNormalPow );
+ }
+
+ sOcclusion = sStrength * ( bl / float(sSampleCount) );
+
+#endif // DOSMALL
+
+
+ //------------------------------------------------------------
+ // Large radius
+ //------------------------------------------------------------
+
+#ifdef DOLARGE
+
+ bl = 0.0;
+
+ projRadius.xy = ( vec2( lRadius ) / ( depth * nearFar.y ) ) * ( worldToScreenScale / texSize0 );
+ projRadius.z = lRadius / nearFar.y;
+
+ depthMin = projRadius.z * lDepthMin;
+ depthMax = projRadius.z * lDepthMax;
+
+ //projRadius.xy = clamp( projRadius.xy, 0.0, 0.01 );
+ //float maxr = 1;
+ //radiusDepth = clamp( radiusDepth, 0.0001, maxr.rrr );
+ //if ( radiusDepth.x < 1.0 / targetSize.x )
+ // return color;
+ //radiusDepth.xyz = 0.0009;
+
+ for ( i = sSampleCount; i < totalSampleCount; i++ )
+ {
+ baseRay = reflect( ptSphere[i], reflectNormal );
+
+ dt = dot( baseRay.xyz, normal );
+
+ baseRay *= sign( dt );
+
+ ray = ( projRadius * baseRay.xzy );
+ ray.y = -ray.y;
+
+ se = ep + ray;
+
+ occluderFragment = deferredUncondition( deferredMap, se.xy );
+
+ depthDiff = se.z - occluderFragment.a;
+
+ normalDiff = dot( occluderFragment.xyz, normal );
+ dt = dot( occluderFragment.xyz, baseRay.xyz );
+
+ bl += getOcclusion( depthDiff, depthMin, depthMax, lDepthPow, normalDiff, dt, lNormalTol, lNormalPow );
+ }
+
+ lOcclusion = lStrength * ( bl / float( totalSampleCount - sSampleCount ) );
+
+#endif // DOLARGE
+
+ float occlusion = saturate( max( sOcclusion, lOcclusion ) * overallStrength );
+
+ // Note black is unoccluded and white is fully occluded. This
+ // seems backwards, but it makes it simple to deal with the SSAO
+ // being disabled in the lighting shaders.
+
+ OUT_col = vec4(occlusion, vec3(0.0));
+}
+
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_P.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_P.glsl
new file mode 100644
index 000000000..4f49479ba
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_P.glsl
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+in vec2 uv0;
+#define IN_uv0 uv0
+
+out vec4 OUT_col;
+
+void main()
+{
+ float power = pow( max( IN_uv0.x, 0 ), 0.1 );
+ OUT_col = vec4( power, 0, 0, 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_V.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_V.glsl
new file mode 100644
index 000000000..a193f63ce
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/ssao/gl/SSAO_PowerTable_V.glsl
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../../gl/hlslCompat.glsl"
+#include "../../gl/postFX.glsl"
+
+void main()
+{
+ OUT_hpos = IN_pos;
+ OUT_uv0 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams0 );
+ OUT_uv1 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams1 );
+ OUT_uv2 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams2 );
+ OUT_uv3 = IN_uv; //viewportCoordToRenderTarget( IN_uv, rtParams3 );
+
+ OUT_wsEyeRay = IN_wsEyeRay;
+
+ correctSSP(gl_Position);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/turbulenceP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/turbulenceP.hlsl
new file mode 100644
index 000000000..c8c572ae7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/turbulenceP.hlsl
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFx.hlsl"
+
+uniform float accumTime;
+uniform float2 projectionOffset;
+uniform float4 targetViewport;
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ float speed = 2.0;
+ float distortion = 6.0;
+
+ float y = IN.uv0.y + (cos((IN.uv0.y+projectionOffset.y) * distortion + accumTime * speed) * 0.01);
+ float x = IN.uv0.x + (sin((IN.uv0.x+projectionOffset.x) * distortion + accumTime * speed) * 0.01);
+
+ // Clamp the calculated uv values to be within the target's viewport
+ y = clamp(y, targetViewport.y, targetViewport.w);
+ x = clamp(x, targetViewport.x, targetViewport.z);
+
+ return TORQUE_TEX2D(inputTex, float2(x, y));
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/underwaterFogP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/underwaterFogP.hlsl
new file mode 100644
index 000000000..aab43c45c
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/underwaterFogP.hlsl
@@ -0,0 +1,138 @@
+//-----------------------------------------------------------------------------
+// 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 "./postFx.hlsl"
+#include "../torque.hlsl"
+#include "../shaderModelAutoGen.hlsl"
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+// oceanFogData
+#define FOG_DENSITY waterFogData[0]
+#define FOG_DENSITY_OFFSET waterFogData[1]
+#define WET_DEPTH waterFogData[2]
+#define WET_DARKENING waterFogData[3]
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(backbuffer, 1);
+TORQUE_UNIFORM_SAMPLER1D(waterDepthGradMap, 2);
+
+uniform float3 eyePosWorld;
+uniform float waterDepthGradMax;
+uniform float3 ambientColor;
+uniform float4 waterColor;
+uniform float4 waterFogData;
+uniform float4 waterFogPlane;
+uniform float2 nearFar;
+uniform float4 rtParams0;
+
+
+float4 main( PFXVertToPix IN ) : TORQUE_TARGET0
+{
+ //float2 deferredCoord = IN.uv0;
+ //IN.uv0 = ( IN.uv0.xy * rtParams0.zw ) + rtParams0.xy;
+ float depth = TORQUE_DEFERRED_UNCONDITION( deferredTex, IN.uv0 ).w;
+ //return float4( depth.rrr, 1 );
+
+ // Skip fogging the extreme far plane so that
+ // the canvas clear color always appears.
+ //clip( 0.9 - depth );
+
+ // We assume that the eye position is below water because
+ // otherwise this shader/posteffect should not be active.
+
+ depth *= nearFar.y;
+
+ float3 eyeRay = normalize( IN.wsEyeRay );
+
+ float3 rayStart = eyePosWorld;
+ float3 rayEnd = eyePosWorld + ( eyeRay * depth );
+ //return float4( rayEnd, 1 );
+
+ float4 plane = waterFogPlane; //float4( 0, 0, 1, -waterHeight );
+ //plane.w -= 0.15;
+
+ float startSide = dot( plane.xyz, rayStart ) + plane.w;
+ if ( startSide > 0 )
+ {
+ rayStart.z -= ( startSide );
+ //return float4( 1, 0, 0, 1 );
+ }
+
+ float3 hitPos;
+ float3 ray = rayEnd - rayStart;
+ float rayLen = length( ray );
+ float3 rayDir = normalize( ray );
+
+ float endSide = dot( plane.xyz, rayEnd ) + plane.w;
+ float planeDist;
+
+ if ( endSide < -0.005 )
+ {
+ //return float4( 0, 0, 1, 1 );
+ hitPos = rayEnd;
+ planeDist = endSide;
+ }
+ else
+ {
+ //return float4( 0, 0, 0, 0 );
+ float den = dot( ray, plane.xyz );
+
+ // Parallal to the plane, return the endPnt.
+ //if ( den == 0.0f )
+ // return endPnt;
+
+ float dist = -( dot( plane.xyz, rayStart ) + plane.w ) / den;
+ if ( dist < 0.0 )
+ dist = 0.0;
+ //return float4( 1, 0, 0, 1 );
+ //return float4( ( dist ).rrr, 1 );
+
+
+ hitPos = lerp( rayStart, rayEnd, dist );
+
+ planeDist = dist;
+ }
+
+ float delta = length( hitPos - rayStart );
+
+ float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * ( delta - FOG_DENSITY_OFFSET ) ) );
+ //return float4( fogAmt.rrr, 1 );
+
+ // Calculate the water "base" color based on depth.
+ float4 fogColor = waterColor * TORQUE_TEX1D( waterDepthGradMap, saturate( delta / waterDepthGradMax ) );
+ // Modulate baseColor by the ambientColor.
+ fogColor *= float4( ambientColor.rgb, 1 );
+
+ float3 inColor = hdrDecode( TORQUE_TEX2D( backbuffer, IN.uv0 ).rgb );
+ inColor.rgb *= 1.0 - saturate( abs( planeDist ) / WET_DEPTH ) * WET_DARKENING;
+ //return float4( inColor, 1 );
+
+ float3 outColor = lerp( inColor, fogColor.rgb, fogAmt );
+
+ return float4( hdrEncode( outColor ), 1 );
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/VignetteP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/VignetteP.hlsl
new file mode 100644
index 000000000..c518a2145
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/VignetteP.hlsl
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// 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 "../postFx.hlsl"
+
+TORQUE_UNIFORM_SAMPLER2D(backBuffer, 0);
+uniform float Vmax;
+uniform float Vmin;
+
+float4 main(PFXVertToPix IN) : TORQUE_TARGET0
+{
+ float4 base = TORQUE_TEX2D(backBuffer, IN.uv0);
+ float dist = distance(IN.uv0, float2(0.5,0.5));
+ base.rgb *= smoothstep(Vmax, Vmin, dist);
+ return base;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/gl/VignetteP.glsl b/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/gl/VignetteP.glsl
new file mode 100644
index 000000000..35de95c34
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/postFX/vignette/gl/VignetteP.glsl
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+uniform sampler2D backBuffer;
+uniform float Vmax;
+uniform float Vmin;
+
+in vec2 uv0;
+#define IN_uv0 uv0
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 base = texture(backBuffer, IN_uv0);
+ float dist = distance(IN_uv0, vec2(0.5,0.5));
+ base.rgb *= smoothstep(Vmax, Vmin, dist);
+ OUT_col = base;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/precipP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/precipP.hlsl
new file mode 100644
index 000000000..069ba4992
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/precipP.hlsl
@@ -0,0 +1,53 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+#include "shaderModel.hlsl"
+
+struct Conn
+{
+ float4 position : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+struct Frag
+{
+ float4 col : TORQUE_TARGET0;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(diffuseMap, 0);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Frag main( Conn In)
+{
+ Frag Out;
+
+ Out.col = TORQUE_TEX2D(diffuseMap, In.texCoord) * In.color;
+
+ return Out;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/precipV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/precipV.hlsl
new file mode 100644
index 000000000..3c40942c7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/precipV.hlsl
@@ -0,0 +1,71 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//*****************************************************************************
+// Precipitation vertex shader
+//*****************************************************************************
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+#include "shaderModel.hlsl"
+
+struct Vert
+{
+ float3 position : POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+struct Conn
+{
+ float4 position : TORQUE_POSITION;
+ float2 texCoord : TEXCOORD0;
+ float4 color : COLOR0;
+};
+
+uniform float4x4 modelview : register(C0);
+uniform float2 fadeStartEnd : register(C4);
+uniform float3 cameraPos : register(C5);
+uniform float3 ambient : register(C6);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Conn main( Vert In )
+{
+ Conn Out;
+
+ Out.position = mul(modelview, float4(In.position,1.0));
+ Out.texCoord = In.texCoord;
+ Out.color = float4( ambient.r, ambient.g, ambient.b, 1 );
+
+ // Do we need to do a distance fade?
+ if ( fadeStartEnd.x < fadeStartEnd.y ) {
+
+ float distance = length( cameraPos - In.position );
+ Out.color.a = abs( clamp( ( distance - fadeStartEnd.x ) / ( fadeStartEnd.y - fadeStartEnd.x ), 0, 1 ) - 1 );
+ }
+
+ return Out;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/projectedShadowP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/projectedShadowP.hlsl
new file mode 100644
index 000000000..88713bd52
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/projectedShadowP.hlsl
@@ -0,0 +1,40 @@
+//-----------------------------------------------------------------------------
+// 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 Conn
+{
+ float4 position : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float fade : TEXCOORD1;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(inputTex, 0);
+uniform float4 ambient;
+
+float4 main( Conn IN ) : TORQUE_TARGET0
+{
+ float shadow = TORQUE_TEX2D( inputTex, IN.texCoord ).a * IN.color.a;
+ return ( ambient * shadow ) + ( 1 - shadow );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/projectedShadowV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/projectedShadowV.hlsl
new file mode 100644
index 000000000..38b1bd3e2
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/projectedShadowV.hlsl
@@ -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 "shaderModel.hlsl"
+
+struct Vert
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float3 T : TANGENT;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct Conn
+{
+ float4 position : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float fade : TEXCOORD1;
+};
+
+uniform float4x4 modelview;
+uniform float shadowLength;
+uniform float3 shadowCasterPosition;
+
+Conn main( Vert In )
+{
+ Conn Out;
+
+ // Decals are in world space.
+ Out.position = mul( modelview, float4( In.position, 1.0 ) );
+
+ Out.color = In.color;
+ Out.texCoord = In.texCoord;
+
+ float fromCasterDist = length( In.position - shadowCasterPosition ) - shadowLength;
+ Out.fade = 1.0 - saturate( fromCasterDist / shadowLength );
+
+ return Out;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderP.hlsl
new file mode 100644
index 000000000..f4c6c7b04
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderP.hlsl
@@ -0,0 +1,19 @@
+#define IN_HLSL
+#include "../shdrConsts.h"
+#include "../shaderModel.hlsl"
+
+struct v2f
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+float4 main(v2f IN) : TORQUE_TARGET0
+{
+ float fade = 1.0 - abs(IN.shiftdata.y - 0.5) * 2.0;
+ IN.color.xyz = IN.color.xyz + pow(fade, 4) / 10;
+ IN.color.a = IN.color.a * fade;
+ return IN.color;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderV.hlsl
new file mode 100644
index 000000000..1a6bc85e4
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/basicRibbonShaderV.hlsl
@@ -0,0 +1,35 @@
+#define IN_HLSL
+#include "../shdrConsts.h"
+#include "../shaderModel.hlsl"
+
+struct a2v
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+struct v2f
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+uniform float4x4 modelview;
+uniform float3 eyePos;
+
+v2f main(a2v IN)
+{
+ v2f OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.position, 1.0));
+ OUT.color = IN.color;
+ OUT.texCoord = IN.texCoord;
+ OUT.shiftdata = IN.shiftdata;
+
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderP.glsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderP.glsl
new file mode 100644
index 000000000..f3f83ce30
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderP.glsl
@@ -0,0 +1,20 @@
+#include "../../gl/hlslCompat.glsl"
+
+in float4 _hpos;
+in float2 _texCoord;
+in float2 _shiftdata;
+in float4 _color;
+
+#define IN_hpos _hpos
+#define IN_texCoord _texCoord
+#define IN_shiftdata _shiftdata
+#define IN_color _color
+
+out float4 OUT_col;
+
+void main()
+{
+ float fade = 1.0 - abs(IN_shiftdata.y - 0.5) * 2.0;
+ OUT_col.xyz = IN_color.xyz + pow(fade, 4) / 10;
+ OUT_col.a = IN_color.a * fade;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderV.glsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderV.glsl
new file mode 100644
index 000000000..9f6826d55
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/basicRibbonShaderV.glsl
@@ -0,0 +1,37 @@
+#include "../../gl/hlslCompat.glsl"
+
+in float2 vTexCoord0;
+in float2 vTexCoord1;
+in float3 vNormal;
+in float4 vPosition;
+in float4 vColor;
+
+#define IN_texCoord vTexCoord0
+#define IN_shiftdata vTexCoord1
+#define IN_normal vNormal
+#define IN_position vPosition
+#define IN_color vColor
+
+out float4 _hpos;
+out float2 _texCoord;
+out float2 _shiftdata;
+out float4 _color;
+
+#define OUT_hpos _hpos
+#define OUT_texCoord _texCoord
+#define OUT_shiftdata _shiftdata
+#define OUT_color _color
+
+uniform float4x4 modelview;
+uniform float3 eyePos;
+
+void main()
+{
+ OUT_hpos = tMul(modelview, IN_position);
+ OUT_color = IN_color;
+ OUT_texCoord = IN_texCoord;
+ OUT_shiftdata = IN_shiftdata;
+
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderP.glsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderP.glsl
new file mode 100644
index 000000000..cd3e72d43
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderP.glsl
@@ -0,0 +1,22 @@
+#include "../../gl/hlslCompat.glsl"
+#include "../../gl/torque.glsl"
+
+in float4 _hpos;
+in float2 _texCoord;
+in float2 _shiftdata;
+in float4 _color;
+
+#define IN_hpos _hpos
+#define IN_texCoord _texCoord
+#define IN_shiftdata _shiftdata
+#define IN_color _color
+
+out float4 OUT_col;
+uniform sampler2D ribTex;
+
+void main()
+{
+ float4 Tex = tex2D(ribTex,IN_texCoord);
+ Tex.a *= IN_color.a;
+ OUT_col = hdrEncode(Tex);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderV.glsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderV.glsl
new file mode 100644
index 000000000..9f6826d55
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/gl/texRibbonShaderV.glsl
@@ -0,0 +1,37 @@
+#include "../../gl/hlslCompat.glsl"
+
+in float2 vTexCoord0;
+in float2 vTexCoord1;
+in float3 vNormal;
+in float4 vPosition;
+in float4 vColor;
+
+#define IN_texCoord vTexCoord0
+#define IN_shiftdata vTexCoord1
+#define IN_normal vNormal
+#define IN_position vPosition
+#define IN_color vColor
+
+out float4 _hpos;
+out float2 _texCoord;
+out float2 _shiftdata;
+out float4 _color;
+
+#define OUT_hpos _hpos
+#define OUT_texCoord _texCoord
+#define OUT_shiftdata _shiftdata
+#define OUT_color _color
+
+uniform float4x4 modelview;
+uniform float3 eyePos;
+
+void main()
+{
+ OUT_hpos = tMul(modelview, IN_position);
+ OUT_color = IN_color;
+ OUT_texCoord = IN_texCoord;
+ OUT_shiftdata = IN_shiftdata;
+
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderP.hlsl
new file mode 100644
index 000000000..55bae76fd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderP.hlsl
@@ -0,0 +1,21 @@
+#define IN_HLSL
+#include "../shdrConsts.h"
+#include "../torque.hlsl"
+
+
+TORQUE_UNIFORM_SAMPLER2D(ribTex, 0);
+
+struct v2f
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+float4 main(v2f IN) : TORQUE_TARGET0
+{
+ float4 Tex = TORQUE_TEX2D(ribTex,IN.texCoord);
+ Tex.a *= IN.color.a;
+ return hdrEncode(Tex);
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderV.hlsl
new file mode 100644
index 000000000..2ce4f62fd
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/ribbons/texRibbonShaderV.hlsl
@@ -0,0 +1,35 @@
+#define IN_HLSL
+#include "../shdrConsts.h"
+#include "../shaderModel.hlsl"
+
+struct a2v
+{
+ float3 position : POSITION;
+ float4 color : COLOR0;
+ float3 normal : NORMAL;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+struct v2f
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 color : COLOR0;
+ float2 texCoord : TEXCOORD0;
+ float2 shiftdata : TEXCOORD1;
+};
+
+uniform float4x4 modelview;
+uniform float3 eyePos;
+
+v2f main(a2v IN)
+{
+ v2f OUT;
+
+ OUT.hpos = mul(modelview, float4(IN.position,1.0));
+ OUT.color = IN.color;
+ OUT.texCoord = IN.texCoord;
+ OUT.shiftdata = IN.shiftdata;
+
+ return OUT;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/scatterSkyP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/scatterSkyP.hlsl
new file mode 100644
index 000000000..84e0854e0
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/scatterSkyP.hlsl
@@ -0,0 +1,69 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "torque.hlsl"
+
+struct Conn
+{
+ float4 hpos : TORQUE_POSITION;
+ float4 rayleighColor : TEXCOORD0;
+ float4 mieColor : TEXCOORD1;
+ float3 v3Direction : TEXCOORD2;
+ float3 pos : TEXCOORD3;
+};
+
+TORQUE_UNIFORM_SAMPLERCUBE(nightSky, 0);
+uniform float4 nightColor;
+uniform float2 nightInterpAndExposure;
+uniform float useCubemap;
+uniform float3 lightDir;
+uniform float3 sunDir;
+
+float4 main( Conn In ) : TORQUE_TARGET0
+{
+
+ float fCos = dot( lightDir, In.v3Direction ) / length(In.v3Direction);
+ float fCos2 = fCos*fCos;
+
+ float g = -0.991;
+ float g2 = -0.991 * -0.991;
+
+ float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos2) / pow(abs(1.0 + g2 - 2.0*g*fCos), 1.5);
+
+ float4 color = In.rayleighColor + fMiePhase * In.mieColor;
+ color.a = color.b;
+
+ float4 Out;
+
+ float4 nightSkyColor = TORQUE_TEXCUBE(nightSky, -In.v3Direction);
+ nightSkyColor = lerp( nightColor, nightSkyColor, useCubemap );
+
+ float fac = dot( normalize( In.pos ), sunDir );
+ fac = max( nightInterpAndExposure.y, pow( saturate( fac ), 2 ) );
+ Out = lerp( color, nightSkyColor, nightInterpAndExposure.y );
+
+ Out.a = 1;
+ Out = saturate(Out);
+
+ return hdrEncode( Out );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/scatterSkyV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/scatterSkyV.hlsl
new file mode 100644
index 000000000..2052448db
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/scatterSkyV.hlsl
@@ -0,0 +1,157 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+// The scale equation calculated by Vernier's Graphical Analysis
+float vernierScale(float fCos)
+{
+ float x = 1.0 - fCos;
+ float x5 = x * 5.25;
+ float x5p6 = (-6.80 + x5);
+ float xnew = (3.83 + x * x5p6);
+ float xfinal = (0.459 + x * xnew);
+ float xfinal2 = -0.00287 + x * xfinal;
+ float outx = exp( xfinal2 );
+ return 0.25 * outx;
+}
+
+// This is the shader input vertex structure.
+struct Vert
+{
+ // .xyz = point
+ float3 position : POSITION;
+};
+
+// This is the shader output data.
+struct Conn
+{
+ float4 position : TORQUE_POSITION;
+ float4 rayleighColor : TEXCOORD0;
+ float4 mieColor : TEXCOORD1;
+ float3 v3Direction : TEXCOORD2;
+ float3 pos : TEXCOORD3;
+};
+
+float3 desaturate(const float3 color, const float desaturation)
+{
+ const float3 gray_conv = float3 (0.30, 0.59, 0.11);
+ return lerp(color, dot(gray_conv , color), desaturation);
+}
+
+uniform float4x4 modelView;
+uniform float4 misc;
+uniform float4 sphereRadii;
+uniform float4 scatteringCoeffs;
+uniform float4 colorize;
+uniform float3 camPos;
+uniform float3 lightDir;
+uniform float4 invWaveLength;
+
+Conn main( Vert In )
+{
+ // Pull some variables out:
+ float camHeight = misc.x;
+ float camHeightSqr = misc.y;
+
+ float scale = misc.z;
+ float scaleOverScaleDepth = misc.w;
+
+ float outerRadius = sphereRadii.x;
+ float outerRadiusSqr = sphereRadii.y;
+
+ float innerRadius = sphereRadii.z;
+ float innerRadiusSqr = sphereRadii.w;
+
+ float rayleighBrightness = scatteringCoeffs.x; // Kr * ESun
+ float rayleigh4PI = scatteringCoeffs.y; // Kr * 4 * PI
+
+ float mieBrightness = scatteringCoeffs.z; // Km * ESun
+ float mie4PI = scatteringCoeffs.w; // Km * 4 * PI
+
+ // Get the ray from the camera to the vertex,
+ // and its length (which is the far point of the ray
+ // passing through the atmosphere).
+ float4 v3Pos = float4(In.position,1.0) / 6378000.0; // outerRadius;
+ float3 newCamPos = float3( 0, 0, camHeight );
+ v3Pos.z += innerRadius;
+ float3 v3Ray = v3Pos.xyz - newCamPos;
+ float fFar = length(v3Ray);
+ v3Ray /= fFar;
+
+ // Calculate the ray's starting position,
+ // then calculate its scattering offset.
+ float3 v3Start = newCamPos;
+ float fHeight = length(v3Start);
+ float fDepth = exp(scaleOverScaleDepth * (innerRadius - camHeight));
+ float fStartAngle = dot(v3Ray, v3Start) / fHeight;
+
+ float fStartOffset = fDepth * vernierScale( fStartAngle );
+
+ // Initialize the scattering loop variables.
+ float fSampleLength = fFar / 2;
+ float fScaledLength = fSampleLength * scale;
+ float3 v3SampleRay = v3Ray * fSampleLength;
+ float3 v3SamplePoint = v3Start + v3SampleRay * 0.5;
+
+ // Now loop through the sample rays
+ float3 v3FrontColor = float3(0.0, 0.0, 0.0);
+ for(int i=0; i<2; i++)
+ {
+ float fHeight = length(v3SamplePoint);
+ float fDepth = exp(scaleOverScaleDepth * (innerRadius - fHeight));
+ float fLightAngle = dot(lightDir, v3SamplePoint) / fHeight;
+ float fCameraAngle = dot(v3Ray, v3SamplePoint) / fHeight;
+
+ float vscale3 = vernierScale( fCameraAngle );
+ float vscale2 = vernierScale( fLightAngle );
+
+ float fScatter = (fStartOffset + fDepth*(vscale2 - vscale3));
+ float3 v3Attenuate = exp(-fScatter * (invWaveLength.xyz * rayleigh4PI + mie4PI));
+ v3FrontColor += v3Attenuate * (fDepth * fScaledLength);
+ v3SamplePoint += v3SampleRay;
+ }
+
+ Conn Out;
+
+ // Finally, scale the Mie and Rayleigh colors
+ // and set up the varying variables for the pixel shader.
+ Out.position = mul( modelView, float4(In.position,1.0) );
+ Out.mieColor.rgb = v3FrontColor * mieBrightness;
+ Out.mieColor.a = 1.0f;
+ Out.rayleighColor.rgb = v3FrontColor * (invWaveLength.xyz * rayleighBrightness);
+ Out.rayleighColor.a = 1.0f;
+ Out.v3Direction = newCamPos - v3Pos.xyz;
+ Out.pos = In.position;
+
+#ifdef USE_COLORIZE
+
+ Out.rayleighColor.rgb = desaturate(Out.rayleighColor.rgb, 1) * colorize.a;
+
+ Out.rayleighColor.r *= colorize.r;
+ Out.rayleighColor.g *= colorize.g;
+ Out.rayleighColor.b *= colorize.b;
+
+#endif
+
+ return Out;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl
new file mode 100644
index 000000000..70ce3a02d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/shaderModel.hlsl
@@ -0,0 +1,97 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2015 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 _TORQUE_SHADERMODEL_
+#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
+
+ //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)
+
+ //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
+
+#endif // _TORQUE_SHADERMODEL_
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl b/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl
new file mode 100644
index 000000000..d70847e46
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/shaderModelAutoGen.hlsl
@@ -0,0 +1,35 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2015 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 _TORQUE_SHADERMODEL_AUTOGEN_
+#define _TORQUE_SHADERMODEL_AUTOGEN_
+
+#include "shadergen:/autogenConditioners.h"
+
+// 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
+
+#endif //_TORQUE_SHADERMODEL_AUTOGEN_
diff --git a/Templates/BaseGame/game/core/rendering/shaders/shdrConsts.h b/Templates/BaseGame/game/core/rendering/shaders/shdrConsts.h
new file mode 100644
index 000000000..8c262b76a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/shdrConsts.h
@@ -0,0 +1,117 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifdef IN_HLSL
+
+#define VC_WORLD_PROJ C0
+
+#define VC_TEX_TRANS1 C4
+#define VC_LIGHT_TRANS C8
+#define VC_OBJ_TRANS C12
+
+#define VC_CUBE_TRANS C16
+#define VC_CUBE_EYE_POS C19 // in cubemap space
+#define VC_EYE_POS C20 // in object space
+#define VC_MAT_SPECPOWER C21
+
+#define VC_FOGDATA C22
+
+#define VC_LIGHT_POS1 C23
+#define VC_LIGHT_DIR1 C24
+#define VC_LIGHT_DIFFUSE1 C25
+#define VC_LIGHT_SPEC1 C26
+
+#define VC_LIGHT_POS2 C27
+//#define VC_LIGHT_DIR2 C28
+//#define VC_LIGHT_DIFFUSE2 C29
+//#define VC_LIGHT_SPEC2 C30
+#define VC_LIGHT_TRANS2 C31
+
+//#define VC_LIGHT_POS4 C35
+//#define VC_LIGHT_DIR4 C36
+//#define VC_LIGHT_DIFFUSE4 C37
+//#define VC_LIGHT_SPEC4 C38
+
+#define VC_DETAIL_SCALE C40
+
+
+#define PC_MAT_SPECCOLOR C0
+#define PC_MAT_SPECPOWER C1
+#define PC_DIFF_COLOR C2
+#define PC_AMBIENT_COLOR C3
+#define PC_ACCUM_TIME C4
+#define PC_DIFF_COLOR2 C5
+#define PC_VISIBILITY C6
+#define PC_COLORMULTIPLY C7
+
+#define PC_USERDEF1 C8
+
+// Mirror of above. Couldn't be cleaner because HLSL doesn't support function macros
+#else
+
+#define VC_WORLD_PROJ 0
+
+#define VC_TEX_TRANS1 4
+#define VC_LIGHT_TRANS 8
+#define VC_OBJ_TRANS 12
+
+#define VC_CUBE_TRANS 16
+#define VC_CUBE_EYE_POS 19 // in cubemap space
+#define VC_EYE_POS 20 // in object space
+#define VC_MAT_SPECPOWER 21
+
+#define VC_FOGDATA 22
+
+#define VC_LIGHT_POS1 23
+#define VC_LIGHT_DIR1 24
+#define VC_LIGHT_DIFFUSE1 25
+#define VC_LIGHT_SPEC1 26
+
+#define VC_LIGHT_POS2 27
+//#define VC_LIGHT_DIR2 28
+//#define VC_LIGHT_DIFFUSE2 29
+//#define VC_LIGHT_SPEC2 30
+#define VC_LIGHT_TRANS2 31
+
+//#define VC_LIGHT_POS4 35
+//#define VC_LIGHT_DIR4 36
+//#define VC_LIGHT_DIFFUSE4 37
+//#define VC_LIGHT_SPEC4 38
+
+#define VC_DETAIL_SCALE 40
+
+
+
+#define PC_MAT_SPECCOLOR 0
+#define PC_MAT_SPECPOWER 1
+#define PC_DIFF_COLOR 2
+#define PC_AMBIENT_COLOR 3
+#define PC_ACCUM_TIME 4
+#define PC_DIFF_COLOR2 5
+#define PC_VISIBILITY 6
+#define PC_COLORMULTIPLY 7
+
+#define PC_USERDEF1 8
+
+#endif
+
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/blendP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/blendP.hlsl
new file mode 100644
index 000000000..aeef9d6e3
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/blendP.hlsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 "terrain.hlsl"
+#include "../shaderModel.hlsl"
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 layerCoord : TEXCOORD0;
+ float2 texCoord : TEXCOORD1;
+};
+
+TORQUE_UNIFORM_SAMPLER2D(layerTex, 0);
+TORQUE_UNIFORM_SAMPLER2D(textureMap, 1);
+
+uniform float texId;
+uniform float layerSize;
+
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ float4 layerSample = round( TORQUE_TEX2D( layerTex, IN.layerCoord ) * 255.0f );
+
+ float blend = calcBlend( texId, IN.layerCoord, layerSize, layerSample );
+
+ clip( blend - 0.0001 );
+
+ return float4( TORQUE_TEX2D(textureMap, IN.texCoord).rgb, blend);
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/blendV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/blendV.hlsl
new file mode 100644
index 000000000..9ccd33301
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/blendV.hlsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+/// The vertex shader used in the generation and caching of the
+/// base terrain texture.
+
+#include "../shaderModel.hlsl"
+
+struct VertData
+{
+ float3 position : POSITION;
+ float2 texCoord : TEXCOORD0;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+ float2 layerCoord : TEXCOORD0;
+ float2 texCoord : TEXCOORD1;
+};
+
+uniform float2 texScale;
+
+ConnectData main( VertData IN )
+{
+ ConnectData OUT;
+
+ OUT.hpos = float4( IN.position, 1 );
+ OUT.layerCoord = IN.texCoord;
+ OUT.texCoord = IN.texCoord * texScale;
+
+ return OUT;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendP.glsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendP.glsl
new file mode 100644
index 000000000..3189ea01d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendP.glsl
@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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 "../terrain.glsl"
+#include "../../gl/hlslCompat.glsl"
+
+in vec2 layerCoord;
+#define IN_layerCoord layerCoord
+in vec2 texCoord;
+#define IN_texCoord texCoord
+
+uniform sampler2D layerTex;
+uniform sampler2D textureMap;
+uniform float texId;
+uniform float layerSize;
+
+out vec4 OUT_col;
+
+void main()
+{
+ vec4 layerSample = round(texture( layerTex, IN_layerCoord ) * 255.0);
+
+ float blend = calcBlend( texId, IN_layerCoord, layerSize, layerSample );
+
+ if(blend - 0.0001 < 0.0)
+ discard;
+
+ OUT_col = vec4( texture( textureMap, IN_texCoord ).rgb, blend );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendV.glsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendV.glsl
new file mode 100644
index 000000000..dc7b7befa
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/gl/blendV.glsl
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+/// The vertex shader used in the generation and caching of the
+/// base terrain texture.
+
+in vec4 vPosition;
+in vec2 vTexCoord0;
+
+out vec2 layerCoord;
+out vec2 texCoord;
+
+uniform vec2 texScale;
+
+void main()
+{
+ gl_Position = vec4(vPosition.xyz, 1.0);
+ layerCoord = vTexCoord0.st;
+ texCoord = vTexCoord0.st * texScale;
+
+ gl_Position.y *= -1;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.glsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.glsl
new file mode 100644
index 000000000..756edd553
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.glsl
@@ -0,0 +1,52 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+float calcBlend( float texId, vec2 layerCoord, float layerSize, vec4 layerSample )
+{
+ // This is here to disable the blend if none of
+ // the neighbors equal the current id.
+ //
+ // We depend on the input layer samples being
+ // rounded to the correct integer ids.
+ //
+ vec4 diff = clamp( abs( layerSample - texId ), 0.0, 1.0 );
+ float noBlend = float(any( bvec4(1 - diff) ));
+
+ // Check if any of the layer samples
+ // match the current texture id.
+ vec4 factors = vec4(0);
+ for(int i = 0; i < 4; i++)
+ factors[i] = (layerSample[i] == texId) ? 1 : 0; // workaround for Intel
+
+ // This is a custom bilinear filter.
+
+ vec2 uv = layerCoord * layerSize;
+ vec2 xy = floor( uv );
+ vec2 ratio = uv - xy;
+ vec2 opposite = 1 - ratio;
+
+ float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y +
+ ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y;
+
+ return noBlend * blend;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.hlsl b/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.hlsl
new file mode 100644
index 000000000..b7c87e618
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/terrain/terrain.hlsl
@@ -0,0 +1,55 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+float calcBlend( float texId, float2 layerCoord, float layerSize, float4 layerSample )
+{
+ // This is here to disable the blend if none of
+ // the neighbors equal the current id.
+ //
+ // We depend on the input layer samples being
+ // rounded to the correct integer ids.
+ //
+ float4 diff = saturate( abs( layerSample - texId ) );
+ float noBlend = any( 1 - diff );
+
+ // Check if any of the layer samples
+ // match the current texture id.
+ float4 factors = 0;
+ [unroll]
+ for(int i = 0; i < 4; i++)
+ if(layerSample[i] == texId)
+ factors[i] = 1;
+
+ // This is a custom bilinear filter.
+
+ float2 uv = layerCoord * layerSize;
+ float2 xy = floor( uv );
+ float2 ratio = uv - xy;
+ float2 opposite = 1 - ratio;
+
+ // NOTE: This will optimize down to two lerp operations.
+ float blend = ( factors.b * opposite.x + factors.g * ratio.x ) * opposite.y +
+ ( factors.r * opposite.x + factors.a * ratio.x ) * ratio.y;
+
+ return noBlend * blend;
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl
new file mode 100644
index 000000000..7081c7153
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/torque.hlsl
@@ -0,0 +1,342 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _TORQUE_HLSL_
+#define _TORQUE_HLSL_
+
+#include "./shaderModel.hlsl"
+
+static float M_HALFPI_F = 1.57079632679489661923f;
+static float M_PI_F = 3.14159265358979323846f;
+static float M_2PI_F = 6.28318530717958647692f;
+
+
+/// Calculate fog based on a start and end positions in worldSpace.
+float computeSceneFog( float3 startPos,
+ float3 endPos,
+ float fogDensity,
+ float fogDensityOffset,
+ float fogHeightFalloff )
+{
+ float f = length( startPos - endPos ) - fogDensityOffset;
+ float h = 1.0 - ( endPos.z * fogHeightFalloff );
+ return exp( -fogDensity * f * h );
+}
+
+
+/// Calculate fog based on a start and end position and a height.
+/// Positions do not need to be in worldSpace but height does.
+float computeSceneFog( float3 startPos,
+ float3 endPos,
+ float height,
+ float fogDensity,
+ float fogDensityOffset,
+ float fogHeightFalloff )
+{
+ float f = length( startPos - endPos ) - fogDensityOffset;
+ float h = 1.0 - ( height * fogHeightFalloff );
+ return exp( -fogDensity * f * h );
+}
+
+
+/// Calculate fog based on a distance, height is not used.
+float computeSceneFog( float dist, float fogDensity, float fogDensityOffset )
+{
+ float f = dist - fogDensityOffset;
+ return exp( -fogDensity * f );
+}
+
+
+/// Convert a float4 uv in viewport space to render target space.
+float2 viewportCoordToRenderTarget( float4 inCoord, float4 rtParams )
+{
+ float2 outCoord = inCoord.xy / inCoord.w;
+ outCoord = ( outCoord * rtParams.zw ) + rtParams.xy;
+ return outCoord;
+}
+
+
+/// Convert a float2 uv in viewport space to render target space.
+float2 viewportCoordToRenderTarget( float2 inCoord, float4 rtParams )
+{
+ float2 outCoord = ( inCoord * rtParams.zw ) + rtParams.xy;
+ return outCoord;
+}
+
+
+/// Convert a float4 quaternion into a 3x3 matrix.
+float3x3 quatToMat( float4 quat )
+{
+ float xs = quat.x * 2.0f;
+ float ys = quat.y * 2.0f;
+ float zs = quat.z * 2.0f;
+
+ float wx = quat.w * xs;
+ float wy = quat.w * ys;
+ float wz = quat.w * zs;
+
+ float xx = quat.x * xs;
+ float xy = quat.x * ys;
+ float xz = quat.x * zs;
+
+ float yy = quat.y * ys;
+ float yz = quat.y * zs;
+ float zz = quat.z * zs;
+
+ float3x3 mat;
+
+ mat[0][0] = 1.0f - (yy + zz);
+ mat[0][1] = xy - wz;
+ mat[0][2] = xz + wy;
+
+ mat[1][0] = xy + wz;
+ mat[1][1] = 1.0f - (xx + zz);
+ mat[1][2] = yz - wx;
+
+ mat[2][0] = xz - wy;
+ mat[2][1] = yz + wx;
+ mat[2][2] = 1.0f - (xx + yy);
+
+ return mat;
+}
+
+
+/// The number of additional substeps we take when refining
+/// the results of the offset parallax mapping function below.
+///
+/// You should turn down the number of steps if your needing
+/// more performance out of your parallax surfaces. Increasing
+/// the number doesn't yeild much better results and is rarely
+/// worth the additional cost.
+///
+#define PARALLAX_REFINE_STEPS 3
+
+/// Performs fast parallax offset mapping using
+/// multiple refinement steps.
+///
+/// @param texMap The texture map whos alpha channel we sample the parallax depth.
+/// @param texCoord The incoming texture coordinate for sampling the parallax depth.
+/// @param negViewTS The negative view vector in tangent space.
+/// @param depthScale The parallax factor used to scale the depth result.
+///
+float2 parallaxOffset(TORQUE_SAMPLER2D(texMap), float2 texCoord, float3 negViewTS, float depthScale)
+{
+ float depth = TORQUE_TEX2D(texMap, texCoord).a/(PARALLAX_REFINE_STEPS*2);
+ float2 offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS);
+
+ for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
+ {
+ depth = (depth + TORQUE_TEX2D(texMap, texCoord + offset).a)/(PARALLAX_REFINE_STEPS*2);
+ offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS);
+ }
+
+ return offset;
+}
+
+/// Same as parallaxOffset but for dxtnm where depth is stored in the red channel instead of the alpha
+float2 parallaxOffsetDxtnm(TORQUE_SAMPLER2D(texMap), float2 texCoord, float3 negViewTS, float depthScale)
+{
+ float depth = TORQUE_TEX2D(texMap, texCoord).r/(PARALLAX_REFINE_STEPS*2);
+ float2 offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS*2);
+
+ for (int i = 0; i < PARALLAX_REFINE_STEPS; i++)
+ {
+ depth = (depth + TORQUE_TEX2D(texMap, texCoord + offset).r)/(PARALLAX_REFINE_STEPS*2);
+ offset = negViewTS.xy * (depth * depthScale)/(PARALLAX_REFINE_STEPS*2);
+ }
+
+ 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 )
+
+ return sample / HDR_RGB10_MAX;
+
+ #else
+
+ // No encoding.
+ return sample;
+
+ #endif
+}
+
+/// Encodes an HDR color for storage into a target.
+float4 hdrEncode( float4 sample )
+{
+ return float4( hdrEncode( sample.rgb ), sample.a );
+}
+
+/// 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 )
+
+ return sample * HDR_RGB10_MAX;
+
+ #else
+
+ // No encoding.
+ return sample;
+
+ #endif
+}
+
+/// Decodes an HDR color from a target.
+float4 hdrDecode( float4 sample )
+{
+ return float4( hdrDecode( sample.rgb ), sample.a );
+}
+
+/// Returns the luminance for an HDR pixel.
+float hdrLuminance( float3 sample )
+{
+ // There are quite a few different ways to
+ // calculate luminance from an rgb value.
+ //
+ // If you want to use a different technique
+ // then plug it in here.
+ //
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // Max component luminance.
+ //
+ //float lum = max( sample.r, max( sample.g, sample.b ) );
+
+ ////////////////////////////////////////////////////////////////////////////
+ // The perceptual relative luminance.
+ //
+ // See http://en.wikipedia.org/wiki/Luminance_(relative)
+ //
+ const float3 RELATIVE_LUMINANCE = float3( 0.2126, 0.7152, 0.0722 );
+ float lum = dot( sample, RELATIVE_LUMINANCE );
+
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // The average component luminance.
+ //
+ //const float3 AVERAGE_LUMINANCE = float3( 0.3333, 0.3333, 0.3333 );
+ //float lum = dot( sample, AVERAGE_LUMINANCE );
+
+ return lum;
+}
+
+/// Called from the visibility feature to do screen
+/// door transparency for fading of objects.
+void fizzle(float2 vpos, float visibility)
+{
+ // NOTE: The magic values below are what give us
+ // the nice even pattern during the fizzle.
+ //
+ // These values can be changed to get different
+ // patterns... some better than others.
+ //
+ // Horizontal Blinds - { vpos.x, 0.916, vpos.y, 0 }
+ // Vertical Lines - { vpos.x, 12.9898, vpos.y, 78.233 }
+ //
+ // I'm sure there are many more patterns here to
+ // discover for different effects.
+
+ float2x2 m = { vpos.x, 0.916, vpos.y, 0.350 };
+ clip( visibility - frac( determinant( m ) ) );
+}
+
+// Deferred Shading: Material Info Flag Check
+bool getFlag(float flags, int num)
+{
+ int process = round(flags * 255);
+ int squareNum = pow(2, 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)
+{
+ return float4(pow(abs(tex.rgb), 2.2), tex.a);
+}
+// Encodes gamma.
+float4 toGamma(float4 tex)
+{
+ return float4(pow(abs(tex.rgb), 1.0/2.2), tex.a);
+}
+// Sample in linear space. Decodes gamma.
+float3 toLinear(float3 tex)
+{
+ return pow(abs(tex.rgb), 2.2);
+}
+// Encodes gamma.
+float3 toGamma(float3 tex)
+{
+ return pow(abs(tex.rgb), 1.0/2.2);
+}
+#endif //
+
+#endif // _TORQUE_HLSL_
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicP.glsl b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicP.glsl
new file mode 100644
index 000000000..91bdb4137
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicP.glsl
@@ -0,0 +1,216 @@
+//-----------------------------------------------------------------------------
+// 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"
+#include "../../gl/hlslCompat.glsl"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+// miscParams
+#define FRESNEL_BIAS miscParams[0]
+#define FRESNEL_POWER miscParams[1]
+#define CLARITY miscParams[2]
+#define ISRIVER miscParams[3]
+
+// reflectParams
+#define REFLECT_PLANE_Z reflectParams[0]
+#define REFLECT_MIN_DIST reflectParams[1]
+#define REFLECT_MAX_DIST reflectParams[2]
+#define NO_REFLECT reflectParams[3]
+
+// distortionParams
+#define DISTORT_START_DIST distortionParams[0]
+#define DISTORT_END_DIST distortionParams[1]
+#define DISTORT_FULL_DEPTH distortionParams[2]
+
+// ConnectData.misc
+#define LIGHT_VEC IN_misc.xyz
+#define WORLD_Z IN_objPos.w
+
+// specularParams
+#define SPEC_POWER specularParams[3]
+#define SPEC_COLOR specularParams.xyz
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+in vec4 rippleTexCoord01;
+#define IN_rippleTexCoord01 rippleTexCoord01
+
+// TexCoord 2 for ripple texture lookup
+in vec2 rippleTexCoord2;
+#define IN_rippleTexCoord2 rippleTexCoord2
+
+// Screenspace vert position BEFORE wave transformation
+in vec4 posPreWave;
+#define IN_posPreWave posPreWave
+
+// Screenspace vert position AFTER wave transformation
+in vec4 posPostWave;
+#define IN_posPostWave posPostWave
+
+// Worldspace unit distance/depth of this vertex/pixel
+in float pixelDist;
+#define IN_pixelDist pixelDist
+
+in vec4 objPos;
+#define IN_objPos objPos
+
+in vec3 misc;
+#define IN_misc misc
+
+//-----------------------------------------------------------------------------
+// approximate Fresnel function
+//-----------------------------------------------------------------------------
+float fresnel(float NdotV, float bias, float power)
+{
+ return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
+}
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform sampler2D bumpMap;
+//uniform sampler2D deferredTex;
+uniform sampler2D reflectMap;
+uniform sampler2D refractBuff;
+uniform samplerCube skyMap;
+//uniform sampler2D foamMap;
+uniform vec4 baseColor;
+uniform vec4 miscParams;
+uniform vec4 reflectParams;
+uniform vec3 ambientColor;
+uniform vec3 eyePos;
+uniform vec3 distortionParams;
+uniform vec3 fogData;
+uniform vec4 fogColor;
+uniform vec4 rippleMagnitude;
+uniform vec4 specularParams;
+uniform mat4 modelMat;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ // Modulate baseColor by the ambientColor.
+ vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 );
+
+ // Get the bumpNorm...
+ vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
+ bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
+ bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
+
+ bumpNorm = normalize( bumpNorm );
+ bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w );
+
+ // We subtract a little from it so that we don't
+ // distort where the water surface intersects the
+ // camera near plane.
+ float distortAmt = saturate( IN_pixelDist / 1.0 ) * 0.8;
+
+ vec4 distortPos = IN_posPostWave;
+ distortPos.xy += bumpNorm.xy * distortAmt;
+
+ #ifdef UNDERWATER
+ OUT_col = hdrEncode( textureProj( refractBuff, distortPos ) );
+ #else
+
+ vec3 eyeVec = IN_objPos.xyz - eyePos;
+ eyeVec = tMul( mat3(modelMat), eyeVec );
+ vec3 reflectionVec = reflect( eyeVec, bumpNorm );
+
+ // Color that replaces the reflection color when we do not
+ // have one that is appropriate.
+ vec4 fakeColor = vec4(ambientColor,1);
+
+ // Use fakeColor for ripple-normals that are angled towards the camera
+ eyeVec = -eyeVec;
+ eyeVec = normalize( eyeVec );
+ float ang = saturate( dot( eyeVec, bumpNorm ) );
+ float fakeColorAmt = ang;
+
+ // Get reflection map color
+ vec4 refMapColor = hdrDecode( textureProj( reflectMap, distortPos ) );
+ // If we do not have a reflection texture then we use the cubemap.
+ refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT );
+
+ // Combine reflection color and fakeColor.
+ vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt );
+ //return refMapColor;
+
+ // Get refract color
+ vec4 refractColor = hdrDecode( textureProj( refractBuff, distortPos ) );
+
+ // calc "diffuse" color by lerping from the water color
+ // to refraction image based on the water clarity.
+ vec4 diffuseColor = mix( refractColor, waterBaseColor, 1.0f - CLARITY );
+
+ // fresnel calculation
+ float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
+ //return vec4( fresnelTerm.rrr, 1 );
+
+ // Also scale the frensel by our distance to the
+ // water surface. This removes the hard reflection
+ // when really close to the water surface.
+ fresnelTerm *= saturate( IN_pixelDist - 0.1 );
+
+ // Combine the diffuse color and reflection image via the
+ // fresnel term and set out output color.
+ vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm );
+
+ #ifdef WATER_SPEC
+
+ // Get some specular reflection.
+ vec3 newbump = bumpNorm;
+ newbump.xy *= 3.5;
+ newbump = normalize( bumpNorm );
+ half3 halfAng = normalize( eyeVec + -LIGHT_VEC );
+ float specular = saturate( dot( newbump, halfAng ) );
+ specular = pow( specular, SPEC_POWER );
+
+ OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx );
+
+ #else // Disable fogging if spec is on because otherwise we run out of instructions.
+
+ // Fog it.
+ float factor = computeSceneFog( eyePos,
+ IN_objPos.xyz,
+ WORLD_Z,
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ //OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
+
+ #endif
+
+ OUT_col = hdrEncode( OUT );
+
+#endif
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicV.glsl b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicV.glsl
new file mode 100644
index 000000000..e92c948e9
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterBasicV.glsl
@@ -0,0 +1,243 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+out vec4 rippleTexCoord01;
+#define OUT_rippleTexCoord01 rippleTexCoord01
+
+// TexCoord 2 for ripple texture lookup
+out vec2 rippleTexCoord2;
+#define OUT_rippleTexCoord2 rippleTexCoord2
+
+// Screenspace vert position BEFORE wave transformation
+out vec4 posPreWave;
+#define OUT_posPreWave posPreWave
+
+// Screenspace vert position AFTER wave transformation
+out vec4 posPostWave;
+#define OUT_posPostWave posPostWave
+
+// Worldspace unit distance/depth of this vertex/pixel
+out float pixelDist;
+#define OUT_pixelDist pixelDist
+
+out vec4 objPos;
+#define OUT_objPos objPos
+
+out vec3 misc;
+#define OUT_misc misc
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform mat4 modelMat;
+uniform mat4 modelview;
+uniform vec4 rippleMat[3];
+uniform vec3 eyePos;
+uniform vec2 waveDir[3];
+uniform vec2 waveData[3];
+uniform vec2 rippleDir[3];
+uniform vec2 rippleTexScale[3];
+uniform vec3 rippleSpeed;
+uniform vec3 inLightVec;
+uniform vec3 reflectNormal;
+uniform float gridElementSize;
+uniform float elapsedTime;
+uniform float undulateMaxDist;
+
+in vec4 vPosition;
+in vec3 vNormal;
+in vec2 vTexCoord0;
+in vec4 vTexCoord1;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec4 IN_position = vPosition;
+ vec3 IN_normal = vNormal;
+ vec2 IN_undulateData = vTexCoord0;
+ vec4 IN_horizonFactor = vTexCoord1;
+ vec4 OUT_hpos = vec4(0);
+
+ // use projection matrix for reflection / refraction texture coords
+ mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 );
+
+ // Move the vertex based on the horizonFactor if specified to do so for this vert.
+ // if ( IN_horizonFactor.z > 0 )
+ // {
+ // vec2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize;
+ // IN_position.xy += offsetXY;
+ // IN_undulateData += offsetXY;
+ // }
+
+ vec4 worldPos = tMul( modelMat, IN_position );
+
+ IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x );
+
+ //OUT_objPos = worldPos;
+ OUT_objPos.xyz = IN_position.xyz;
+ OUT_objPos.w = worldPos.z;
+
+ // Send pre-undulation screenspace position
+ OUT_posPreWave = tMul( modelview, IN_position );
+ OUT_posPreWave = tMul( texGen, OUT_posPreWave );
+
+ // Calculate the undulation amount for this vertex.
+ vec2 undulatePos = tMul( modelMat, vec4( IN_undulateData.xy, 0, 1 ) ).xy;
+ //if ( undulatePos.x < 0 )
+ // undulatePos = IN_position.xy;
+
+ float undulateAmt = 0.0;
+
+ undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
+ undulatePos.x * waveDir[0].x +
+ undulatePos.y * waveDir[0].y );
+ undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x +
+ undulatePos.x * waveDir[1].x +
+ undulatePos.y * waveDir[1].y );
+ undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
+ undulatePos.x * waveDir[2].x +
+ undulatePos.y * waveDir[2].y );
+
+ float undulateFade = 1;
+
+ // Scale down wave magnitude amount based on distance from the camera.
+ float dist = distance( IN_position.xyz, eyePos );
+ dist = clamp( dist, 1.0, undulateMaxDist );
+ undulateFade *= ( 1 - dist / undulateMaxDist );
+
+ // Also scale down wave magnitude if the camera is very very close.
+ undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 );
+
+ undulateAmt *= undulateFade;
+
+ //#endif
+ //undulateAmt = 0;
+
+ // Apply wave undulation to the vertex.
+ OUT_posPostWave = IN_position;
+ OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt;
+
+ // Save worldSpace position of this pixel/vert
+ //OUT_worldPos = OUT_posPostWave.xyz;
+ //OUT_worldPos = tMul( modelMat, OUT_posPostWave.xyz );
+ //OUT_worldPos.z += objTrans[2][2]; //91.16;
+
+ // OUT_misc.w = tMul( modelMat, OUT_fogPos ).z;
+ // if ( IN_horizonFactor.x > 0 )
+ // {
+ // vec3 awayVec = normalize( OUT_fogPos.xyz - eyePos );
+ // OUT_fogPos.xy += awayVec.xy * 1000.0;
+ // }
+
+ // Convert to screen
+ OUT_posPostWave = tMul( modelview, OUT_posPostWave ); // tMul( modelview, vec4( OUT_posPostWave.xyz, 1 ) );
+
+ // Setup the OUT position symantic variable
+ OUT_hpos = OUT_posPostWave; // tMul( modelview, vec4( IN_position.xyz, 1 ) ); //vec4( OUT_posPostWave.xyz, 1 );
+ //OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x );
+
+ // Save world space camera dist/depth of the outgoing pixel
+ OUT_pixelDist = OUT_hpos.z;
+
+ // Convert to reflection texture space
+ OUT_posPostWave = tMul( texGen, OUT_posPostWave );
+
+ vec2 txPos = undulatePos;
+ if ( bool(IN_horizonFactor.x) )
+ txPos = normalize( txPos ) * 50000.0;
+
+ // set up tex coordinates for the 3 interacting normal maps
+ OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0];
+ OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
+
+ mat2 texMat;
+ texMat[0][0] = rippleMat[0].x;
+ texMat[1][0] = rippleMat[0].y;
+ texMat[0][1] = rippleMat[0].z;
+ texMat[1][1] = rippleMat[0].w;
+ OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy );
+
+ OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1];
+ OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
+
+ texMat[0][0] = rippleMat[1].x;
+ texMat[1][0] = rippleMat[1].y;
+ texMat[0][1] = rippleMat[1].z;
+ texMat[1][1] = rippleMat[1].w;
+ OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw );
+
+ OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2];
+ OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
+
+ texMat[0][0] = rippleMat[2].x;
+ texMat[1][0] = rippleMat[2].y;
+ texMat[0][1] = rippleMat[2].z;
+ texMat[1][1] = rippleMat[2].w;
+ OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy );
+
+#ifdef WATER_SPEC
+
+ vec3 binormal = vec3( 1, 0, 0 );
+ vec3 tangent = vec3( 0, 1, 0 );
+ vec3 normal;
+ for ( int i = 0; i < 3; i++ )
+ {
+ binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x );
+ tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN_undulateData.x + waveDir[i].y * IN_undulateData.y + elapsedTime * waveData[i].x );
+ }
+
+ binormal = normalize( binormal );
+ tangent = normalize( tangent );
+ normal = cross( binormal, tangent );
+
+ mat3 worldToTangent;
+ worldToTangent[0] = binormal;
+ worldToTangent[1] = tangent;
+ worldToTangent[2] = normal;
+
+ worldToTangent = transpose(worldToTangent);
+
+ OUT_misc.xyz = tMul( inLightVec, modelMat );
+ OUT_misc.xyz = tMul( worldToTangent, OUT_misc.xyz );
+
+#else
+
+ OUT_misc.xyz = inLightVec;
+
+#endif
+
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterP.glsl b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterP.glsl
new file mode 100644
index 000000000..d4804245a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterP.glsl
@@ -0,0 +1,396 @@
+//-----------------------------------------------------------------------------
+// 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 "../../gl/torque.glsl"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+#define PIXEL_DIST IN_rippleTexCoord2.z
+// miscParams
+#define FRESNEL_BIAS miscParams[0]
+#define FRESNEL_POWER miscParams[1]
+// miscParams[2] is unused
+#define ISRIVER miscParams[3]
+
+// reflectParams
+#define REFLECT_PLANE_Z reflectParams[0]
+#define REFLECT_MIN_DIST reflectParams[1]
+#define REFLECT_MAX_DIST reflectParams[2]
+#define NO_REFLECT reflectParams[3]
+
+// fogParams
+#define FOG_DENSITY fogParams[0]
+#define FOG_DENSITY_OFFSET fogParams[1]
+
+// wetnessParams
+#define WET_DEPTH wetnessParams[0]
+#define WET_COLOR_FACTOR wetnessParams[1]
+
+// distortionParams
+#define DISTORT_START_DIST distortionParams[0]
+#define DISTORT_END_DIST distortionParams[1]
+#define DISTORT_FULL_DEPTH distortionParams[2]
+
+// foamParams
+#define FOAM_OPACITY foamParams[0]
+#define FOAM_MAX_DEPTH foamParams[1]
+#define FOAM_AMBIENT_LERP foamParams[2]
+#define FOAM_RIPPLE_INFLUENCE foamParams[3]
+
+// specularParams
+#define SPEC_POWER specularParams[3]
+#define SPEC_COLOR specularParams.xyz
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+//ConnectData IN
+
+in vec4 hpos;
+
+// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+in vec4 rippleTexCoord01;
+
+// xy is TexCoord 2 for ripple texture lookup
+// z is the Worldspace unit distance/depth of this vertex/pixel
+// w is amount of the crestFoam ( more at crest of waves ).
+in vec4 rippleTexCoord2;
+
+// Screenspace vert position BEFORE wave transformation
+in vec4 posPreWave;
+
+// Screenspace vert position AFTER wave transformation
+in vec4 posPostWave;
+
+// Objectspace vert position BEFORE wave transformation
+// w coord is world space z position.
+in vec4 objPos;
+
+in vec4 foamTexCoords;
+
+in mat3 tangentMat;
+
+
+#define IN_hpos hpos
+#define IN_rippleTexCoord01 rippleTexCoord01
+#define IN_rippleTexCoord2 rippleTexCoord2
+#define IN_posPreWave posPreWave
+#define IN_posPostWave posPostWave
+#define IN_objPos objPos
+#define IN_foamTexCoords foamTexCoords
+#define IN_tangentMat tangentMat
+
+//-----------------------------------------------------------------------------
+// approximate Fresnel function
+//-----------------------------------------------------------------------------
+float fresnel(float NdotV, float bias, float power)
+{
+ return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
+}
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform sampler2D bumpMap;
+uniform sampler2D deferredTex;
+uniform sampler2D reflectMap;
+uniform sampler2D refractBuff;
+uniform samplerCube skyMap;
+uniform sampler2D foamMap;
+uniform sampler1D depthGradMap;
+uniform vec4 specularParams;
+uniform vec4 baseColor;
+uniform vec4 miscParams;
+uniform vec2 fogParams;
+uniform vec4 reflectParams;
+uniform vec3 reflectNormal;
+uniform vec2 wetnessParams;
+uniform float farPlaneDist;
+uniform vec3 distortionParams;
+uniform vec4 foamParams;
+uniform vec3 ambientColor;
+uniform vec3 eyePos; // This is in object space!
+uniform vec3 fogData;
+uniform vec4 fogColor;
+uniform vec4 rippleMagnitude;
+uniform vec4 rtParams1;
+uniform float depthGradMax;
+uniform vec3 inLightVec;
+uniform mat4 modelMat;
+uniform vec4 sunColor;
+uniform float sunBrightness;
+uniform float reflectivity;
+
+out vec4 OUT_col;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ // Get the bumpNorm...
+ vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
+ bumpNorm += ( texture( bumpMap, IN_rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
+ bumpNorm += ( texture( bumpMap, IN_rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
+
+ bumpNorm = normalize( bumpNorm );
+ bumpNorm = mix( bumpNorm, vec3(0,0,1), 1.0 - rippleMagnitude.w );
+ bumpNorm = tMul( bumpNorm, IN_tangentMat );
+
+ // Get depth of the water surface (this pixel).
+ // Convert from WorldSpace to EyeSpace.
+ float pixelDepth = PIXEL_DIST / farPlaneDist;
+
+ vec2 deferredCoord = viewportCoordToRenderTarget( IN_posPostWave, rtParams1 );
+
+ float startDepth = deferredUncondition( deferredTex, deferredCoord ).w;
+
+ // The water depth in world units of the undistorted pixel.
+ float startDelta = ( startDepth - pixelDepth );
+ startDelta = max( startDelta, 0.0 );
+ startDelta *= farPlaneDist;
+
+ // Calculate the distortion amount for the water surface.
+ //
+ // We subtract a little from it so that we don't
+ // distort where the water surface intersects the
+ // camera near plane.
+ float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
+
+ // Scale down distortion in shallow water.
+ distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH );
+
+ // Do the intial distortion... we might remove it below.
+ vec2 distortDelta = bumpNorm.xy * distortAmt;
+ vec4 distortPos = IN_posPostWave;
+ distortPos.xy += distortDelta;
+
+ deferredCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ // Get deferred depth at the position of this distorted pixel.
+ float deferredDepth = deferredUncondition( deferredTex, deferredCoord ).w;
+ if ( deferredDepth > 0.99 )
+ deferredDepth = 5.0;
+
+ float delta = ( deferredDepth - pixelDepth ) * farPlaneDist;
+
+ if ( delta < 0.0 )
+ {
+ // If we got a negative delta then the distorted
+ // sample is above the water surface. Mask it out
+ // by removing the distortion.
+ distortPos = IN_posPostWave;
+ delta = startDelta;
+ distortAmt = 0;
+ }
+ else
+ {
+ float diff = ( deferredDepth - startDepth ) * farPlaneDist;
+
+ if ( diff < 0 )
+ {
+ distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
+ distortAmt *= saturate( delta / DISTORT_FULL_DEPTH );
+
+ distortDelta = bumpNorm.xy * distortAmt;
+
+ distortPos = IN_posPostWave;
+ distortPos.xy += distortDelta;
+
+ deferredCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ // Get deferred depth at the position of this distorted pixel.
+ deferredDepth = deferredUncondition( deferredTex, deferredCoord ).w;
+ if ( deferredDepth > 0.99 )
+ deferredDepth = 5.0;
+ delta = ( deferredDepth - pixelDepth ) * farPlaneDist;
+ }
+
+ if ( delta < 0.1 )
+ {
+ // If we got a negative delta then the distorted
+ // sample is above the water surface. Mask it out
+ // by removing the distortion.
+ distortPos = IN_posPostWave;
+ delta = startDelta;
+ distortAmt = 0;
+ }
+ }
+
+ vec4 temp = IN_posPreWave;
+ temp.xy += bumpNorm.xy * distortAmt;
+ vec2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 );
+
+ vec2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ vec4 fakeColor = vec4(ambientColor,1);
+ vec3 eyeVec = IN_objPos.xyz - eyePos;
+ eyeVec = tMul( mat3(modelMat), eyeVec );
+ eyeVec = tMul( IN_tangentMat, eyeVec );
+ vec3 reflectionVec = reflect( eyeVec, bumpNorm );
+
+ // Use fakeColor for ripple-normals that are angled towards the camera
+ eyeVec = -eyeVec;
+ eyeVec = normalize( eyeVec );
+ float ang = saturate( dot( eyeVec, bumpNorm ) );
+ float fakeColorAmt = ang;
+
+ // for verts far from the reflect plane z position
+ float rplaneDist = abs( REFLECT_PLANE_Z - IN_objPos.w );
+ rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 );
+ rplaneDist *= ISRIVER;
+ fakeColorAmt = max( fakeColorAmt, rplaneDist );
+
+#ifndef UNDERWATER
+
+ // Get foam color and amount
+ vec2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE;
+ vec4 IN_foamTexCoords = IN_foamTexCoords;
+ IN_foamTexCoords.xy += foamRippleOffset;
+ IN_foamTexCoords.zw += foamRippleOffset;
+
+ vec4 foamColor = texture( foamMap, IN_foamTexCoords.xy );
+ foamColor += texture( foamMap, IN_foamTexCoords.zw );
+ foamColor = saturate( foamColor );
+
+ // Modulate foam color by ambient color
+ // so we don't have glowing white foam at night.
+ foamColor.rgb = mix( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP );
+
+ float foamDelta = saturate( delta / FOAM_MAX_DEPTH );
+ float foamAmt = 1 - pow( foamDelta, 2 );
+
+ // Fade out the foam in very very low depth,
+ // this improves the shoreline a lot.
+ float diff = 0.8 - foamAmt;
+ if ( diff < 0.0 )
+ foamAmt -= foamAmt * abs( diff ) / 0.2;
+
+ foamAmt *= FOAM_OPACITY * foamColor.a;
+
+ foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a;
+
+ // Get reflection map color.
+ vec4 refMapColor = texture( reflectMap, reflectCoord );
+
+ // If we do not have a reflection texture then we use the cubemap.
+ refMapColor = mix( refMapColor, texture( skyMap, reflectionVec ), NO_REFLECT );
+
+ fakeColor = ( texture( skyMap, reflectionVec ) );
+ fakeColor.a = 1;
+ // Combine reflection color and fakeColor.
+ vec4 reflectColor = mix( refMapColor, fakeColor, fakeColorAmt );
+
+ // Get refract color
+ vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) );
+
+ // We darken the refraction color a bit to make underwater
+ // elements look wet. We fade out this darkening near the
+ // surface in order to not have hard water edges.
+ // @param WET_DEPTH The depth in world units at which full darkening will be recieved.
+ // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH
+ refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR );
+
+ // Add Water fog/haze.
+ float fogDelta = delta - FOG_DENSITY_OFFSET;
+
+ if ( fogDelta < 0.0 )
+ fogDelta = 0.0;
+ float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) );
+
+ // Calculate the water "base" color based on depth.
+ vec4 waterBaseColor = baseColor * texture( depthGradMap, saturate( delta / depthGradMax ) );
+
+ // Modulate baseColor by the ambientColor.
+ waterBaseColor *= vec4( ambientColor.rgb, 1 );
+
+ // calc "diffuse" color by lerping from the water color
+ // to refraction image based on the water clarity.
+ vec4 diffuseColor = mix( refractColor, waterBaseColor, fogAmt );
+
+ // fresnel calculation
+ float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
+
+ // Scale the frensel strength by fog amount
+ // so that parts that are very clear get very little reflection.
+ fresnelTerm *= fogAmt;
+
+ // Also scale the frensel by our distance to the
+ // water surface. This removes the hard reflection
+ // when really close to the water surface.
+ fresnelTerm *= saturate( PIXEL_DIST - 0.1 );
+
+ fresnelTerm *= reflectivity;
+
+ // Combine the diffuse color and reflection image via the
+ // fresnel term and set out output color.
+ vec4 OUT = mix( diffuseColor, reflectColor, fresnelTerm );
+
+ vec3 lightVec = inLightVec;
+
+ // Get some specular reflection.
+ vec3 newbump = bumpNorm;
+ newbump.xy *= 3.5;
+ newbump = normalize( newbump );
+ vec3 halfAng = normalize( eyeVec + -lightVec );
+ float specular = saturate( dot( newbump, halfAng ) );
+ specular = pow( specular, SPEC_POWER );
+
+ // Scale down specularity in very shallow water to improve the transparency of the shoreline.
+ specular *= saturate( delta / 2 );
+ OUT.rgb = OUT.rgb + ( SPEC_COLOR * vec3(specular) );
+
+#else
+
+ vec4 refractColor = hdrDecode( texture( refractBuff, refractCoord ) );
+ vec4 OUT = refractColor;
+
+#endif
+
+#ifndef UNDERWATER
+
+ OUT.rgb = OUT.rgb + foamColor.rgb;
+
+ float factor = computeSceneFog( eyePos,
+ IN_objPos.xyz,
+ IN_objPos.w,
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ OUT.rgb = mix( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
+
+ //OUT.rgb = fogColor.rgb;
+
+#endif
+
+ OUT.a = 1.0;
+
+ //return OUT;
+
+ OUT_col = hdrEncode( OUT );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterV.glsl b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterV.glsl
new file mode 100644
index 000000000..490af63a7
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/gl/waterV.glsl
@@ -0,0 +1,241 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct VertData
+{
+ vec4 position ;// POSITION;
+ vec3 normal ;// NORMAL;
+ vec2 undulateData ;// TEXCOORD0;
+ vec4 horizonFactor ;// TEXCOORD1;
+};
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+//VertData IN
+in vec4 vPosition;
+in vec3 vNormal;
+in vec2 vTexCoord0;
+in vec4 vTexCoord1;
+
+#define IN_position_ vPosition
+#define IN_normal vNormal
+#define IN_undulateData vTexCoord0
+#define IN_horizonFactor vTexCoord1
+
+//ConnectData OUT
+//
+ out vec4 hpos ;
+
+// TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+out vec4 rippleTexCoord01;
+
+ // xy is TexCoord 2 for ripple texture lookup
+ // z is the Worldspace unit distance/depth of this vertex/pixel
+ // w is amount of the crestFoam ( more at crest of waves ).
+ out vec4 rippleTexCoord2 ;
+
+// Screenspace vert position BEFORE wave transformation
+out vec4 posPreWave;
+
+// Screenspace vert position AFTER wave transformation
+out vec4 posPostWave;
+
+ // Objectspace vert position BEFORE wave transformation
+ // w coord is world space z position.
+ out vec4 objPos ;
+
+ out vec4 foamTexCoords ;
+
+ out mat3 tangentMat ;
+//
+
+#define OUT_hpos hpos
+#define OUT_rippleTexCoord01 rippleTexCoord01
+#define OUT_rippleTexCoord2 rippleTexCoord2
+#define OUT_posPreWave posPreWave
+#define OUT_posPostWave posPostWave
+#define OUT_objPos objPos
+#define OUT_foamTexCoords foamTexCoords
+#define OUT_tangentMat tangentMat
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform mat4 modelMat;
+uniform mat4 modelview;
+uniform vec4 rippleMat[3];
+uniform vec3 eyePos;
+uniform vec2 waveDir[3];
+uniform vec2 waveData[3];
+uniform vec2 rippleDir[3];
+uniform vec2 rippleTexScale[3];
+uniform vec3 rippleSpeed;
+uniform vec4 foamDir;
+uniform vec4 foamTexScale;
+uniform vec2 foamSpeed;
+uniform vec3 inLightVec;
+uniform float gridElementSize;
+uniform float elapsedTime;
+uniform float undulateMaxDist;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+void main()
+{
+ vec4 IN_position = IN_position_;
+
+ // use projection matrix for reflection / refraction texture coords
+ mat4 texGen = mat4FromRow( 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 );
+
+ IN_position.z = mix( IN_position.z, eyePos.z, IN_horizonFactor.x );
+
+ OUT_objPos = IN_position;
+ OUT_objPos.w = tMul( modelMat, IN_position ).z;
+
+ // Send pre-undulation screenspace position
+ OUT_posPreWave = tMul( modelview, IN_position );
+ OUT_posPreWave = tMul( texGen, OUT_posPreWave );
+
+ // Calculate the undulation amount for this vertex.
+ vec2 undulatePos = tMul( modelMat, vec4 ( IN_undulateData.xy, 0, 1 ) ).xy;
+ float undulateAmt = 0.0;
+
+ undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
+ undulatePos.x * waveDir[0].x +
+ undulatePos.y * waveDir[0].y );
+ undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x +
+ undulatePos.x * waveDir[1].x +
+ undulatePos.y * waveDir[1].y );
+ undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
+ undulatePos.x * waveDir[2].x +
+ undulatePos.y * waveDir[2].y );
+
+ float undulateFade = 1;
+
+ // Scale down wave magnitude amount based on distance from the camera.
+ float dist = distance( IN_position.xyz, eyePos );
+ dist = clamp( dist, 1.0, undulateMaxDist );
+ undulateFade *= ( 1 - dist / undulateMaxDist );
+
+ // Also scale down wave magnitude if the camera is very very close.
+ undulateFade *= saturate( ( distance( IN_position.xyz, eyePos ) - 0.5 ) / 10.0 );
+
+ undulateAmt *= undulateFade;
+
+ OUT_rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y );
+ OUT_rippleTexCoord2.w = saturate( OUT_rippleTexCoord2.w - 0.2 ) / 0.8;
+
+ // Apply wave undulation to the vertex.
+ OUT_posPostWave = IN_position;
+ OUT_posPostWave.xyz += IN_normal.xyz * undulateAmt;
+
+ // Convert to screen
+ OUT_posPostWave = tMul( modelview, OUT_posPostWave );
+
+ // Setup the OUT position symantic variable
+ OUT_hpos = OUT_posPostWave;
+ //OUT_hpos.z = mix( OUT_hpos.z, OUT_hpos.w, IN_horizonFactor.x );
+
+ // if ( IN_horizonFactor.x > 0 )
+ // {
+ // vec3 awayVec = normalize( OUT_objPos.xyz - eyePos );
+ // OUT_objPos.xy += awayVec.xy * 1000.0;
+ // }
+
+ // Save world space camera dist/depth of the outgoing pixel
+ OUT_rippleTexCoord2.z = OUT_hpos.z;
+
+ // Convert to reflection texture space
+ OUT_posPostWave = tMul( texGen, OUT_posPostWave );
+
+ vec2 txPos = undulatePos;
+ if ( bool(IN_horizonFactor.x) )
+ txPos = normalize( txPos ) * 50000.0;
+
+ // set up tex coordinates for the 3 interacting normal maps
+ OUT_rippleTexCoord01.xy = txPos * rippleTexScale[0];
+ OUT_rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
+
+ mat2 texMat;
+ texMat[0][0] = rippleMat[0].x;
+ texMat[1][0] = rippleMat[0].y;
+ texMat[0][1] = rippleMat[0].z;
+ texMat[1][1] = rippleMat[0].w;
+ OUT_rippleTexCoord01.xy = tMul( texMat, OUT_rippleTexCoord01.xy );
+
+ OUT_rippleTexCoord01.zw = txPos * rippleTexScale[1];
+ OUT_rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
+
+ texMat[0][0] = rippleMat[1].x;
+ texMat[1][0] = rippleMat[1].y;
+ texMat[0][1] = rippleMat[1].z;
+ texMat[1][1] = rippleMat[1].w;
+ OUT_rippleTexCoord01.zw = tMul( texMat, OUT_rippleTexCoord01.zw );
+
+ OUT_rippleTexCoord2.xy = txPos * rippleTexScale[2];
+ OUT_rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
+
+ texMat[0][0] = rippleMat[2].x;
+ texMat[1][0] = rippleMat[2].y;
+ texMat[0][1] = rippleMat[2].z;
+ texMat[1][1] = rippleMat[2].w;
+ OUT_rippleTexCoord2.xy = tMul( texMat, OUT_rippleTexCoord2.xy );
+
+ OUT_foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime;
+ OUT_foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime;
+
+
+ vec3 binormal = vec3 ( 1, 0, 0 );
+ vec3 tangent = vec3 ( 0, 1, 0 );
+ vec3 normal;
+ for ( int i = 0; i < 3; i++ )
+ {
+ binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
+ tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
+ }
+
+ binormal = binormal;
+ tangent = tangent;
+ normal = cross( binormal, tangent );
+
+ mat3 worldToTangent;
+ worldToTangent[0] = binormal;
+ worldToTangent[1] = tangent;
+ worldToTangent[2] = normal;
+
+ OUT_tangentMat = transpose(worldToTangent);
+
+ gl_Position = OUT_hpos;
+ correctSSP(gl_Position);
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicP.hlsl
new file mode 100644
index 000000000..9cacfdf7a
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicP.hlsl
@@ -0,0 +1,213 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+// miscParams
+#define FRESNEL_BIAS miscParams[0]
+#define FRESNEL_POWER miscParams[1]
+#define CLARITY miscParams[2]
+#define ISRIVER miscParams[3]
+
+// reflectParams
+#define REFLECT_PLANE_Z reflectParams[0]
+#define REFLECT_MIN_DIST reflectParams[1]
+#define REFLECT_MAX_DIST reflectParams[2]
+#define NO_REFLECT reflectParams[3]
+
+// distortionParams
+#define DISTORT_START_DIST distortionParams[0]
+#define DISTORT_END_DIST distortionParams[1]
+#define DISTORT_FULL_DEPTH distortionParams[2]
+
+// ConnectData.misc
+#define LIGHT_VEC IN.misc.xyz
+#define WORLD_Z IN.objPos.w
+
+// specularParams
+#define SPEC_POWER specularParams[3]
+#define SPEC_COLOR specularParams.xyz
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+
+ // TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+ float4 rippleTexCoord01 : TEXCOORD0;
+
+ // TexCoord 2 for ripple texture lookup
+ float2 rippleTexCoord2 : TEXCOORD1;
+
+ // Screenspace vert position BEFORE wave transformation
+ float4 posPreWave : TEXCOORD2;
+
+ // Screenspace vert position AFTER wave transformation
+ float4 posPostWave : TEXCOORD3;
+
+ // Worldspace unit distance/depth of this vertex/pixel
+ float pixelDist : TEXCOORD4;
+
+ // Objectspace vert position BEFORE wave transformation
+ // w coord is world space z position.
+ float4 objPos : TEXCOORD5;
+
+ float3 misc : TEXCOORD6;
+};
+
+//-----------------------------------------------------------------------------
+// approximate Fresnel function
+//-----------------------------------------------------------------------------
+float fresnel(float NdotV, float bias, float power)
+{
+ return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
+}
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+TORQUE_UNIFORM_SAMPLER2D(bumpMap,0);
+//uniform sampler2D deferredTex : register( S1 );
+TORQUE_UNIFORM_SAMPLER2D(reflectMap,2);
+TORQUE_UNIFORM_SAMPLER2D(refractBuff,3);
+TORQUE_UNIFORM_SAMPLERCUBE(skyMap,4);
+//uniform sampler foamMap : register( S5 );
+uniform float4 baseColor;
+uniform float4 miscParams;
+uniform float4 reflectParams;
+uniform float3 ambientColor;
+uniform float3 eyePos;
+uniform float3 distortionParams;
+uniform float3 fogData;
+uniform float4 fogColor;
+uniform float4 rippleMagnitude;
+uniform float4 specularParams;
+uniform float4x4 modelMat;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ // Modulate baseColor by the ambientColor.
+ float4 waterBaseColor = baseColor * float4( ambientColor.rgb, 1 );
+
+ // Get the bumpNorm...
+ float3 bumpNorm = ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
+ bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
+ bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord2 ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
+
+ bumpNorm = normalize( bumpNorm );
+ bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w );
+
+ // We subtract a little from it so that we don't
+ // distort where the water surface intersects the
+ // camera near plane.
+ float distortAmt = saturate( IN.pixelDist / 1.0 ) * 0.8;
+
+ float4 distortPos = IN.posPostWave;
+ distortPos.xy += bumpNorm.xy * distortAmt;
+
+ #ifdef UNDERWATER
+ return hdrEncode( TORQUE_TEX2DPROJ( refractBuff, distortPos ) );
+ #else
+
+ float3 eyeVec = IN.objPos.xyz - eyePos;
+ eyeVec = mul( (float3x3)modelMat, eyeVec );
+ float3 reflectionVec = reflect( eyeVec, bumpNorm );
+
+ // Color that replaces the reflection color when we do not
+ // have one that is appropriate.
+ float4 fakeColor = float4(ambientColor,1);
+
+ // Use fakeColor for ripple-normals that are angled towards the camera
+ eyeVec = -eyeVec;
+ eyeVec = normalize( eyeVec );
+ float ang = saturate( dot( eyeVec, bumpNorm ) );
+ float fakeColorAmt = ang;
+
+ // Get reflection map color
+ float4 refMapColor = hdrDecode( TORQUE_TEX2DPROJ( reflectMap, distortPos ) );
+ // If we do not have a reflection texture then we use the cubemap.
+ refMapColor = lerp( refMapColor, TORQUE_TEXCUBE( skyMap, reflectionVec ), NO_REFLECT );
+
+ // Combine reflection color and fakeColor.
+ float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt );
+ //return refMapColor;
+
+ // Get refract color
+ float4 refractColor = hdrDecode( TORQUE_TEX2DPROJ( refractBuff, distortPos ) );
+
+ // calc "diffuse" color by lerping from the water color
+ // to refraction image based on the water clarity.
+ float4 diffuseColor = lerp( refractColor, waterBaseColor, 1.0f - CLARITY );
+
+ // fresnel calculation
+ float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
+ //return float4( fresnelTerm.rrr, 1 );
+
+ // Also scale the frensel by our distance to the
+ // water surface. This removes the hard reflection
+ // when really close to the water surface.
+ fresnelTerm *= saturate( IN.pixelDist - 0.1 );
+
+ // Combine the diffuse color and reflection image via the
+ // fresnel term and set out output color.
+ float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm );
+
+ #ifdef WATER_SPEC
+
+ // Get some specular reflection.
+ float3 newbump = bumpNorm;
+ newbump.xy *= 3.5;
+ newbump = normalize( bumpNorm );
+ half3 halfAng = normalize( eyeVec + -LIGHT_VEC );
+ float specular = saturate( dot( newbump, halfAng ) );
+ specular = pow( specular, SPEC_POWER );
+
+ OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx );
+
+ #else // Disable fogging if spec is on because otherwise we run out of instructions.
+
+ // Fog it.
+ float factor = computeSceneFog( eyePos,
+ IN.objPos.xyz,
+ WORLD_Z,
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ //OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
+
+ #endif
+
+ return hdrEncode( OUT );
+
+#endif
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicV.hlsl
new file mode 100644
index 000000000..310647c90
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/waterBasicV.hlsl
@@ -0,0 +1,237 @@
+//-----------------------------------------------------------------------------
+// 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"
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct VertData
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float2 undulateData : TEXCOORD0;
+ float4 horizonFactor : TEXCOORD1;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+
+ // TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+ float4 rippleTexCoord01 : TEXCOORD0;
+
+ // TexCoord 2 for ripple texture lookup
+ float2 rippleTexCoord2 : TEXCOORD1;
+
+ // Screenspace vert position BEFORE wave transformation
+ float4 posPreWave : TEXCOORD2;
+
+ // Screenspace vert position AFTER wave transformation
+ float4 posPostWave : TEXCOORD3;
+
+ // Worldspace unit distance/depth of this vertex/pixel
+ float pixelDist : TEXCOORD4;
+
+ // Objectspace vert position BEFORE wave transformation
+ // w coord is world space z position.
+ float4 objPos : TEXCOORD5;
+
+ float3 misc : TEXCOORD6;
+};
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform float4x4 modelMat;
+uniform float4x4 modelview;
+uniform float4 rippleMat[3];
+uniform float3 eyePos;
+uniform float2 waveDir[3];
+uniform float2 waveData[3];
+uniform float2 rippleDir[3];
+uniform float2 rippleTexScale[3];
+uniform float3 rippleSpeed;
+uniform float3 inLightVec;
+uniform float3 reflectNormal;
+uniform float gridElementSize;
+uniform float elapsedTime;
+uniform float undulateMaxDist;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertData IN )
+{
+ ConnectData OUT;
+
+ // use projection matrix for reflection / refraction texture coords
+ float4x4 texGen = { 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ // Move the vertex based on the horizonFactor if specified to do so for this vert.
+ // if ( IN.horizonFactor.z > 0 )
+ // {
+ // float2 offsetXY = eyePos.xy - eyePos.xy % gridElementSize;
+ // IN.position.xy += offsetXY;
+ // IN.undulateData += offsetXY;
+ // }
+ float4 inPos = float4(IN.position, 1.0);
+ float4 worldPos = mul(modelMat, inPos);
+
+ IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x );
+
+ //OUT.objPos = worldPos;
+ OUT.objPos.xyz = IN.position;
+ OUT.objPos.w = worldPos.z;
+
+ // Send pre-undulation screenspace position
+ OUT.posPreWave = mul( modelview, inPos );
+ OUT.posPreWave = mul( texGen, OUT.posPreWave );
+
+ // Calculate the undulation amount for this vertex.
+ float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 )).xy;
+ //if ( undulatePos.x < 0 )
+ // undulatePos = IN.position.xy;
+
+ float undulateAmt = 0.0;
+
+ undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
+ undulatePos.x * waveDir[0].x +
+ undulatePos.y * waveDir[0].y );
+ undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x +
+ undulatePos.x * waveDir[1].x +
+ undulatePos.y * waveDir[1].y );
+ undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
+ undulatePos.x * waveDir[2].x +
+ undulatePos.y * waveDir[2].y );
+
+ float undulateFade = 1;
+
+ // Scale down wave magnitude amount based on distance from the camera.
+ float dist = distance( IN.position, eyePos );
+ dist = clamp( dist, 1.0, undulateMaxDist );
+ undulateFade *= ( 1 - dist / undulateMaxDist );
+
+ // Also scale down wave magnitude if the camera is very very close.
+ undulateFade *= saturate( ( distance( IN.position, eyePos ) - 0.5 ) / 10.0 );
+
+ undulateAmt *= undulateFade;
+
+ //#endif
+ //undulateAmt = 0;
+
+ // Apply wave undulation to the vertex.
+ OUT.posPostWave = inPos;
+ OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt;
+
+ // Save worldSpace position of this pixel/vert
+ //OUT.worldPos = OUT.posPostWave.xyz;
+ //OUT.worldPos = mul( modelMat, OUT.posPostWave.xyz );
+ //OUT.worldPos.z += objTrans[2][2]; //91.16;
+
+ // OUT.misc.w = mul( modelMat, OUT.fogPos ).z;
+ // if ( IN.horizonFactor.x > 0 )
+ // {
+ // float3 awayVec = normalize( OUT.fogPos.xyz - eyePos );
+ // OUT.fogPos.xy += awayVec.xy * 1000.0;
+ // }
+
+ // Convert to screen
+ OUT.posPostWave = mul( modelview, OUT.posPostWave ); // mul( modelview, float4( OUT.posPostWave.xyz, 1 ) );
+
+ // Setup the OUT position symantic variable
+ OUT.hpos = OUT.posPostWave; // mul( modelview, float4( IN.position.xyz, 1 ) ); //float4( OUT.posPostWave.xyz, 1 );
+ //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x );
+
+ // Save world space camera dist/depth of the outgoing pixel
+ OUT.pixelDist = OUT.hpos.z;
+
+ // Convert to reflection texture space
+ OUT.posPostWave = mul( texGen, OUT.posPostWave );
+
+ float2 txPos = undulatePos;
+ if ( IN.horizonFactor.x )
+ txPos = normalize( txPos ) * 50000.0;
+
+ // set up tex coordinates for the 3 interacting normal maps
+ OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0];
+ OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
+
+ float2x2 texMat;
+ texMat[0][0] = rippleMat[0].x;
+ texMat[0][1] = rippleMat[0].y;
+ texMat[1][0] = rippleMat[0].z;
+ texMat[1][1] = rippleMat[0].w;
+ OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy );
+
+ OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1];
+ OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
+
+ texMat[0][0] = rippleMat[1].x;
+ texMat[0][1] = rippleMat[1].y;
+ texMat[1][0] = rippleMat[1].z;
+ texMat[1][1] = rippleMat[1].w;
+ OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw );
+
+ OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2];
+ OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
+
+ texMat[0][0] = rippleMat[2].x;
+ texMat[0][1] = rippleMat[2].y;
+ texMat[1][0] = rippleMat[2].z;
+ texMat[1][1] = rippleMat[2].w;
+ OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy );
+
+#ifdef WATER_SPEC
+
+ float3 binormal = float3( 1, 0, 0 );
+ float3 tangent = float3( 0, 1, 0 );
+ float3 normal;
+ for ( int i = 0; i < 3; i++ )
+ {
+ binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x );
+ tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * IN.undulateData.x + waveDir[i].y * IN.undulateData.y + elapsedTime * waveData[i].x );
+ }
+
+ binormal = normalize( binormal );
+ tangent = normalize( tangent );
+ normal = cross( binormal, tangent );
+
+ float3x3 worldToTangent;
+ worldToTangent[0] = binormal;
+ worldToTangent[1] = tangent;
+ worldToTangent[2] = normal;
+
+ OUT.misc.xyz = mul( inLightVec, modelMat );
+ OUT.misc.xyz = mul( worldToTangent, OUT.misc.xyz );
+
+#else
+
+ OUT.misc.xyz = inLightVec;
+
+#endif
+
+ return OUT;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/waterP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/water/waterP.hlsl
new file mode 100644
index 000000000..59bdad05d
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/waterP.hlsl
@@ -0,0 +1,383 @@
+//-----------------------------------------------------------------------------
+// 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 "../shaderModelAutoGen.hlsl"
+#include "../torque.hlsl"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+#define PIXEL_DIST IN.rippleTexCoord2.z
+// miscParams
+#define FRESNEL_BIAS miscParams[0]
+#define FRESNEL_POWER miscParams[1]
+// miscParams[2] is unused
+#define ISRIVER miscParams[3]
+
+// reflectParams
+#define REFLECT_PLANE_Z reflectParams[0]
+#define REFLECT_MIN_DIST reflectParams[1]
+#define REFLECT_MAX_DIST reflectParams[2]
+#define NO_REFLECT reflectParams[3]
+
+// fogParams
+#define FOG_DENSITY fogParams[0]
+#define FOG_DENSITY_OFFSET fogParams[1]
+
+// wetnessParams
+#define WET_DEPTH wetnessParams[0]
+#define WET_COLOR_FACTOR wetnessParams[1]
+
+// distortionParams
+#define DISTORT_START_DIST distortionParams[0]
+#define DISTORT_END_DIST distortionParams[1]
+#define DISTORT_FULL_DEPTH distortionParams[2]
+
+// foamParams
+#define FOAM_OPACITY foamParams[0]
+#define FOAM_MAX_DEPTH foamParams[1]
+#define FOAM_AMBIENT_LERP foamParams[2]
+#define FOAM_RIPPLE_INFLUENCE foamParams[3]
+
+// specularParams
+#define SPEC_POWER specularParams[3]
+#define SPEC_COLOR specularParams.xyz
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+
+ // TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+ float4 rippleTexCoord01 : TEXCOORD0;
+
+ // xy is TexCoord 2 for ripple texture lookup
+ // z is the Worldspace unit distance/depth of this vertex/pixel
+ // w is amount of the crestFoam ( more at crest of waves ).
+ float4 rippleTexCoord2 : TEXCOORD1;
+
+ // Screenspace vert position BEFORE wave transformation
+ float4 posPreWave : TEXCOORD2;
+
+ // Screenspace vert position AFTER wave transformation
+ float4 posPostWave : TEXCOORD3;
+
+ // Objectspace vert position BEFORE wave transformation
+ // w coord is world space z position.
+ float4 objPos : TEXCOORD4;
+
+ float4 foamTexCoords : TEXCOORD5;
+
+ float3x3 tangentMat : TEXCOORD6;
+};
+
+//-----------------------------------------------------------------------------
+// approximate Fresnel function
+//-----------------------------------------------------------------------------
+float fresnel(float NdotV, float bias, float power)
+{
+ return bias + (1.0-bias)*pow(abs(1.0 - max(NdotV, 0)), power);
+}
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+TORQUE_UNIFORM_SAMPLER2D(bumpMap,0);
+TORQUE_UNIFORM_SAMPLER2D(deferredTex, 1);
+TORQUE_UNIFORM_SAMPLER2D(reflectMap, 2);
+TORQUE_UNIFORM_SAMPLER2D(refractBuff, 3);
+TORQUE_UNIFORM_SAMPLERCUBE(skyMap, 4);
+TORQUE_UNIFORM_SAMPLER2D(foamMap, 5);
+TORQUE_UNIFORM_SAMPLER1D(depthGradMap, 6);
+uniform float4 specularParams;
+uniform float4 baseColor;
+uniform float4 miscParams;
+uniform float2 fogParams;
+uniform float4 reflectParams;
+uniform float3 reflectNormal;
+uniform float2 wetnessParams;
+uniform float farPlaneDist;
+uniform float3 distortionParams;
+uniform float4 foamParams;
+uniform float3 ambientColor;
+uniform float3 eyePos; // This is in object space!
+uniform float3 fogData;
+uniform float4 fogColor;
+uniform float4 rippleMagnitude;
+uniform float4 rtParams1;
+uniform float depthGradMax;
+uniform float3 inLightVec;
+uniform float4x4 modelMat;
+uniform float4 sunColor;
+uniform float sunBrightness;
+uniform float reflectivity;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+float4 main( ConnectData IN ) : TORQUE_TARGET0
+{
+ // Get the bumpNorm...
+ float3 bumpNorm = ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x;
+ bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord01.zw ).rgb * 2.0 - 1.0 ) * rippleMagnitude.y;
+ bumpNorm += ( TORQUE_TEX2D( bumpMap, IN.rippleTexCoord2.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.z;
+
+ bumpNorm = normalize( bumpNorm );
+ bumpNorm = lerp( bumpNorm, float3(0,0,1), 1.0 - rippleMagnitude.w );
+ bumpNorm = mul( bumpNorm, IN.tangentMat );
+
+ // Get depth of the water surface (this pixel).
+ // Convert from WorldSpace to EyeSpace.
+ float pixelDepth = PIXEL_DIST / farPlaneDist;
+
+ float2 deferredCoord = viewportCoordToRenderTarget( IN.posPostWave, rtParams1 );
+
+ float startDepth = TORQUE_DEFERRED_UNCONDITION( deferredTex, deferredCoord ).w;
+
+ // The water depth in world units of the undistorted pixel.
+ float startDelta = ( startDepth - pixelDepth );
+ startDelta = max( startDelta, 0.0 );
+ startDelta *= farPlaneDist;
+
+ // Calculate the distortion amount for the water surface.
+ //
+ // We subtract a little from it so that we don't
+ // distort where the water surface intersects the
+ // camera near plane.
+ float distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
+
+ // Scale down distortion in shallow water.
+ distortAmt *= saturate( startDelta / DISTORT_FULL_DEPTH );
+
+ // Do the intial distortion... we might remove it below.
+ float2 distortDelta = bumpNorm.xy * distortAmt;
+ float4 distortPos = IN.posPostWave;
+ distortPos.xy += distortDelta;
+
+ deferredCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ // Get deferred depth at the position of this distorted pixel.
+ float deferredDepth = TORQUE_DEFERRED_UNCONDITION( deferredTex, deferredCoord ).w;
+ if ( deferredDepth > 0.99 )
+ deferredDepth = 5.0;
+
+ float delta = ( deferredDepth - pixelDepth ) * farPlaneDist;
+
+ if ( delta < 0.0 )
+ {
+ // If we got a negative delta then the distorted
+ // sample is above the water surface. Mask it out
+ // by removing the distortion.
+ distortPos = IN.posPostWave;
+ delta = startDelta;
+ distortAmt = 0;
+ }
+ else
+ {
+ float diff = ( deferredDepth - startDepth ) * farPlaneDist;
+
+ if ( diff < 0 )
+ {
+ distortAmt = saturate( ( PIXEL_DIST - DISTORT_START_DIST ) / DISTORT_END_DIST );
+ distortAmt *= saturate( delta / DISTORT_FULL_DEPTH );
+
+ distortDelta = bumpNorm.xy * distortAmt;
+
+ distortPos = IN.posPostWave;
+ distortPos.xy += distortDelta;
+
+ deferredCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ // Get deferred depth at the position of this distorted pixel.
+ deferredDepth = TORQUE_DEFERRED_UNCONDITION( deferredTex, deferredCoord ).w;
+ if ( deferredDepth > 0.99 )
+ deferredDepth = 5.0;
+ delta = ( deferredDepth - pixelDepth ) * farPlaneDist;
+ }
+
+ if ( delta < 0.1 )
+ {
+ // If we got a negative delta then the distorted
+ // sample is above the water surface. Mask it out
+ // by removing the distortion.
+ distortPos = IN.posPostWave;
+ delta = startDelta;
+ distortAmt = 0;
+ }
+ }
+
+ float4 temp = IN.posPreWave;
+ temp.xy += bumpNorm.xy * distortAmt;
+ float2 reflectCoord = viewportCoordToRenderTarget( temp, rtParams1 );
+
+ float2 refractCoord = viewportCoordToRenderTarget( distortPos, rtParams1 );
+
+ float4 fakeColor = float4(ambientColor,1);
+ float3 eyeVec = IN.objPos.xyz - eyePos;
+ eyeVec = mul( (float3x3)modelMat, eyeVec );
+ eyeVec = mul( IN.tangentMat, eyeVec );
+ float3 reflectionVec = reflect( eyeVec, bumpNorm );
+
+ // Use fakeColor for ripple-normals that are angled towards the camera
+ eyeVec = -eyeVec;
+ eyeVec = normalize( eyeVec );
+ float ang = saturate( dot( eyeVec, bumpNorm ) );
+ float fakeColorAmt = ang;
+
+ // for verts far from the reflect plane z position
+ float rplaneDist = abs( REFLECT_PLANE_Z - IN.objPos.w );
+ rplaneDist = saturate( ( rplaneDist - 1.0 ) / 2.0 );
+ rplaneDist *= ISRIVER;
+ fakeColorAmt = max( fakeColorAmt, rplaneDist );
+
+#ifndef UNDERWATER
+
+ // Get foam color and amount
+ float2 foamRippleOffset = bumpNorm.xy * FOAM_RIPPLE_INFLUENCE;
+ IN.foamTexCoords.xy += foamRippleOffset;
+ IN.foamTexCoords.zw += foamRippleOffset;
+
+ float4 foamColor = TORQUE_TEX2D( foamMap, IN.foamTexCoords.xy );
+ foamColor += TORQUE_TEX2D( foamMap, IN.foamTexCoords.zw );
+ foamColor = saturate( foamColor );
+
+ // Modulate foam color by ambient color
+ // so we don't have glowing white foam at night.
+ foamColor.rgb = lerp( foamColor.rgb, ambientColor.rgb, FOAM_AMBIENT_LERP );
+
+ float foamDelta = saturate( delta / FOAM_MAX_DEPTH );
+ float foamAmt = 1 - pow( foamDelta, 2 );
+
+ // Fade out the foam in very very low depth,
+ // this improves the shoreline a lot.
+ float diff = 0.8 - foamAmt;
+ if ( diff < 0.0 )
+ foamAmt -= foamAmt * abs( diff ) / 0.2;
+
+ foamAmt *= FOAM_OPACITY * foamColor.a;
+
+ foamColor.rgb *= FOAM_OPACITY * foamAmt * foamColor.a;
+
+ // Get reflection map color.
+ float4 refMapColor = TORQUE_TEX2D( reflectMap, reflectCoord );
+
+ // If we do not have a reflection texture then we use the cubemap.
+ refMapColor = lerp( refMapColor, TORQUE_TEXCUBE( skyMap, reflectionVec ), NO_REFLECT );
+
+ fakeColor = ( TORQUE_TEXCUBE( skyMap, reflectionVec ) );
+ fakeColor.a = 1;
+ // Combine reflection color and fakeColor.
+ float4 reflectColor = lerp( refMapColor, fakeColor, fakeColorAmt );
+
+ // Get refract color
+ float4 refractColor = hdrDecode( TORQUE_TEX2D( refractBuff, refractCoord ) );
+
+ // We darken the refraction color a bit to make underwater
+ // elements look wet. We fade out this darkening near the
+ // surface in order to not have hard water edges.
+ // @param WET_DEPTH The depth in world units at which full darkening will be recieved.
+ // @param WET_COLOR_FACTOR The refract color is scaled down by this amount when at WET_DEPTH
+ refractColor.rgb *= 1.0f - ( saturate( delta / WET_DEPTH ) * WET_COLOR_FACTOR );
+
+ // Add Water fog/haze.
+ float fogDelta = delta - FOG_DENSITY_OFFSET;
+
+ if ( fogDelta < 0.0 )
+ fogDelta = 0.0;
+ float fogAmt = 1.0 - saturate( exp( -FOG_DENSITY * fogDelta ) );
+
+ // Calculate the water "base" color based on depth.
+ float4 waterBaseColor = baseColor * TORQUE_TEX1D( depthGradMap, saturate( delta / depthGradMax ) );
+
+ // Modulate baseColor by the ambientColor.
+ waterBaseColor *= float4( ambientColor.rgb, 1 );
+
+ // calc "diffuse" color by lerping from the water color
+ // to refraction image based on the water clarity.
+ float4 diffuseColor = lerp( refractColor, waterBaseColor, fogAmt );
+
+ // fresnel calculation
+ float fresnelTerm = fresnel( ang, FRESNEL_BIAS, FRESNEL_POWER );
+
+ // Scale the frensel strength by fog amount
+ // so that parts that are very clear get very little reflection.
+ fresnelTerm *= fogAmt;
+
+ // Also scale the frensel by our distance to the
+ // water surface. This removes the hard reflection
+ // when really close to the water surface.
+ fresnelTerm *= saturate( PIXEL_DIST - 0.1 );
+
+ fresnelTerm *= reflectivity;
+
+ // Combine the diffuse color and reflection image via the
+ // fresnel term and set out output color.
+ float4 OUT = lerp( diffuseColor, reflectColor, fresnelTerm );
+
+ float3 lightVec = inLightVec;
+
+ // Get some specular reflection.
+ float3 newbump = bumpNorm;
+ newbump.xy *= 3.5;
+ newbump = normalize( newbump );
+ float3 halfAng = normalize( eyeVec + -lightVec );
+ float specular = saturate( dot( newbump, halfAng ) );
+ specular = pow( specular, SPEC_POWER );
+
+ // Scale down specularity in very shallow water to improve the transparency of the shoreline.
+ specular *= saturate( delta / 2 );
+ OUT.rgb = OUT.rgb + ( SPEC_COLOR * specular.xxx );
+
+#else
+
+ float4 refractColor = hdrDecode( TORQUE_TEX2D( refractBuff, refractCoord ) );
+ float4 OUT = refractColor;
+
+#endif
+
+#ifndef UNDERWATER
+
+ OUT.rgb = OUT.rgb + foamColor.rgb;
+
+ float factor = computeSceneFog( eyePos,
+ IN.objPos.xyz,
+ IN.objPos.w,
+ fogData.x,
+ fogData.y,
+ fogData.z );
+
+ OUT.rgb = lerp( OUT.rgb, fogColor.rgb, 1.0 - saturate( factor ) );
+
+ //OUT.rgb = fogColor.rgb;
+
+#endif
+
+ OUT.a = 1.0;
+
+ //return OUT;
+
+ return hdrEncode( OUT );
+}
diff --git a/Templates/BaseGame/game/core/rendering/shaders/water/waterV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/water/waterV.hlsl
new file mode 100644
index 000000000..c869f0e9f
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/water/waterV.hlsl
@@ -0,0 +1,216 @@
+//-----------------------------------------------------------------------------
+// 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"
+
+//-----------------------------------------------------------------------------
+// Structures
+//-----------------------------------------------------------------------------
+struct VertData
+{
+ float3 position : POSITION;
+ float3 normal : NORMAL;
+ float2 undulateData : TEXCOORD0;
+ float4 horizonFactor : TEXCOORD1;
+};
+
+struct ConnectData
+{
+ float4 hpos : TORQUE_POSITION;
+
+ // TexCoord 0 and 1 (xy,zw) for ripple texture lookup
+ float4 rippleTexCoord01 : TEXCOORD0;
+
+ // xy is TexCoord 2 for ripple texture lookup
+ // z is the Worldspace unit distance/depth of this vertex/pixel
+ // w is amount of the crestFoam ( more at crest of waves ).
+ float4 rippleTexCoord2 : TEXCOORD1;
+
+ // Screenspace vert position BEFORE wave transformation
+ float4 posPreWave : TEXCOORD2;
+
+ // Screenspace vert position AFTER wave transformation
+ float4 posPostWave : TEXCOORD3;
+
+ // Objectspace vert position BEFORE wave transformation
+ // w coord is world space z position.
+ float4 objPos : TEXCOORD4;
+
+ float4 foamTexCoords : TEXCOORD5;
+
+ float3x3 tangentMat : TEXCOORD6;
+};
+
+//-----------------------------------------------------------------------------
+// Uniforms
+//-----------------------------------------------------------------------------
+uniform float4x4 modelMat;
+uniform float4x4 modelview;
+uniform float4 rippleMat[3];
+uniform float3 eyePos;
+uniform float2 waveDir[3];
+uniform float2 waveData[3];
+uniform float2 rippleDir[3];
+uniform float2 rippleTexScale[3];
+uniform float3 rippleSpeed;
+uniform float4 foamDir;
+uniform float4 foamTexScale;
+uniform float2 foamSpeed;
+uniform float3 inLightVec;
+uniform float gridElementSize;
+uniform float elapsedTime;
+uniform float undulateMaxDist;
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+ConnectData main( VertData IN )
+{
+ ConnectData OUT;
+
+ // use projection matrix for reflection / refraction texture coords
+ float4x4 texGen = { 0.5, 0.0, 0.0, 0.5,
+ 0.0, -0.5, 0.0, 0.5,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0 };
+
+ IN.position.z = lerp( IN.position.z, eyePos.z, IN.horizonFactor.x );
+ float4 inPos = float4( IN.position, 1.0);
+ OUT.objPos = inPos;
+ OUT.objPos.w = mul( modelMat, inPos ).z;
+
+ // Send pre-undulation screenspace position
+ OUT.posPreWave = mul( modelview, inPos );
+ OUT.posPreWave = mul( texGen, OUT.posPreWave );
+
+ // Calculate the undulation amount for this vertex.
+ float2 undulatePos = mul( modelMat, float4( IN.undulateData.xy, 0, 1 ) ).xy;
+ float undulateAmt = 0.0;
+
+ undulateAmt += waveData[0].y * sin( elapsedTime * waveData[0].x +
+ undulatePos.x * waveDir[0].x +
+ undulatePos.y * waveDir[0].y );
+ undulateAmt += waveData[1].y * sin( elapsedTime * waveData[1].x +
+ undulatePos.x * waveDir[1].x +
+ undulatePos.y * waveDir[1].y );
+ undulateAmt += waveData[2].y * sin( elapsedTime * waveData[2].x +
+ undulatePos.x * waveDir[2].x +
+ undulatePos.y * waveDir[2].y );
+
+ float undulateFade = 1;
+
+ // Scale down wave magnitude amount based on distance from the camera.
+ float dist = distance( IN.position.xyz, eyePos );
+ dist = clamp( dist, 1.0, undulateMaxDist );
+ undulateFade *= ( 1 - dist / undulateMaxDist );
+
+ // Also scale down wave magnitude if the camera is very very close.
+ undulateFade *= saturate( ( distance( IN.position.xyz, eyePos ) - 0.5 ) / 10.0 );
+
+ undulateAmt *= undulateFade;
+
+ OUT.rippleTexCoord2.w = undulateAmt / ( waveData[0].y + waveData[1].y + waveData[2].y );
+ OUT.rippleTexCoord2.w = saturate( OUT.rippleTexCoord2.w - 0.2 ) / 0.8;
+
+ // Apply wave undulation to the vertex.
+ OUT.posPostWave = inPos;
+ OUT.posPostWave.xyz += IN.normal.xyz * undulateAmt;
+
+ // Convert to screen
+ OUT.posPostWave = mul( modelview, OUT.posPostWave );
+
+ // Setup the OUT position symantic variable
+ OUT.hpos = OUT.posPostWave;
+ //OUT.hpos.z = lerp( OUT.hpos.z, OUT.hpos.w, IN.horizonFactor.x );
+
+ // if ( IN.horizonFactor.x > 0 )
+ // {
+ // float3 awayVec = normalize( OUT.objPos.xyz - eyePos );
+ // OUT.objPos.xy += awayVec.xy * 1000.0;
+ // }
+
+ // Save world space camera dist/depth of the outgoing pixel
+ OUT.rippleTexCoord2.z = OUT.hpos.z;
+
+ // Convert to reflection texture space
+ OUT.posPostWave = mul( texGen, OUT.posPostWave );
+
+ float2 txPos = undulatePos;
+ if ( IN.horizonFactor.x )
+ txPos = normalize( txPos ) * 50000.0;
+
+ // set up tex coordinates for the 3 interacting normal maps
+ OUT.rippleTexCoord01.xy = txPos * rippleTexScale[0];
+ OUT.rippleTexCoord01.xy += rippleDir[0] * elapsedTime * rippleSpeed.x;
+
+ float2x2 texMat;
+ texMat[0][0] = rippleMat[0].x;
+ texMat[0][1] = rippleMat[0].y;
+ texMat[1][0] = rippleMat[0].z;
+ texMat[1][1] = rippleMat[0].w;
+ OUT.rippleTexCoord01.xy = mul( texMat, OUT.rippleTexCoord01.xy );
+
+ OUT.rippleTexCoord01.zw = txPos * rippleTexScale[1];
+ OUT.rippleTexCoord01.zw += rippleDir[1] * elapsedTime * rippleSpeed.y;
+
+ texMat[0][0] = rippleMat[1].x;
+ texMat[0][1] = rippleMat[1].y;
+ texMat[1][0] = rippleMat[1].z;
+ texMat[1][1] = rippleMat[1].w;
+ OUT.rippleTexCoord01.zw = mul( texMat, OUT.rippleTexCoord01.zw );
+
+ OUT.rippleTexCoord2.xy = txPos * rippleTexScale[2];
+ OUT.rippleTexCoord2.xy += rippleDir[2] * elapsedTime * rippleSpeed.z;
+
+ texMat[0][0] = rippleMat[2].x;
+ texMat[0][1] = rippleMat[2].y;
+ texMat[1][0] = rippleMat[2].z;
+ texMat[1][1] = rippleMat[2].w;
+ OUT.rippleTexCoord2.xy = mul( texMat, OUT.rippleTexCoord2.xy );
+
+ OUT.foamTexCoords.xy = txPos * foamTexScale.xy + foamDir.xy * foamSpeed.x * elapsedTime;
+ OUT.foamTexCoords.zw = txPos * foamTexScale.zw + foamDir.zw * foamSpeed.y * elapsedTime;
+
+
+ float3 binormal = float3( 1, 0, 0 );
+ float3 tangent = float3( 0, 1, 0 );
+ float3 normal;
+ for ( int i = 0; i < 3; i++ )
+ {
+ binormal.z += undulateFade * waveDir[i].x * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
+ tangent.z += undulateFade * waveDir[i].y * waveData[i].y * cos( waveDir[i].x * undulatePos.x + waveDir[i].y * undulatePos.y + elapsedTime * waveData[i].x );
+ }
+
+ binormal = binormal;
+ tangent = tangent;
+ normal = cross( binormal, tangent );
+
+ float3x3 worldToTangent;
+ worldToTangent[0] = binormal;
+ worldToTangent[1] = tangent;
+ worldToTangent[2] = normal;
+
+ OUT.tangentMat = worldToTangent;
+
+ return OUT;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/wavesP.hlsl b/Templates/BaseGame/game/core/rendering/shaders/wavesP.hlsl
new file mode 100644
index 000000000..c51eb4b89
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/wavesP.hlsl
@@ -0,0 +1,89 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "shdrConsts.h"
+#include "shaderModel.hlsl"
+
+//-----------------------------------------------------------------------------
+// Data
+//-----------------------------------------------------------------------------
+struct v2f
+{
+ float4 HPOS : TORQUE_POSITION;
+ float2 TEX0 : TEXCOORD0;
+ float4 tangentToCube0 : TEXCOORD1;
+ float4 tangentToCube1 : TEXCOORD2;
+ float4 tangentToCube2 : TEXCOORD3;
+ float4 lightVec : TEXCOORD4;
+ float3 pixPos : TEXCOORD5;
+ float3 eyePos : TEXCOORD6;
+};
+
+
+
+struct Fragout
+{
+ float4 col : TORQUE_TARGET0;
+};
+
+// Uniforms
+TORQUE_UNIFORM_SAMPLER2D(diffMap,0);
+//TORQUE_UNIFORM_SAMPLERCUBE(cubeMap, 1); not used?
+TORQUE_UNIFORM_SAMPLER2D(bumpMap,2);
+
+uniform float4 specularColor : register(PC_MAT_SPECCOLOR);
+uniform float4 ambient : register(PC_AMBIENT_COLOR);
+uniform float specularPower : register(PC_MAT_SPECPOWER);
+uniform float accumTime : register(PC_ACCUM_TIME);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Fragout main(v2f IN)
+{
+ Fragout OUT;
+
+ float2 texOffset;
+ float sinOffset1 = sin( accumTime * 1.5 + IN.TEX0.y * 6.28319 * 3.0 ) * 0.03;
+ float sinOffset2 = sin( accumTime * 3.0 + IN.TEX0.y * 6.28319 ) * 0.04;
+
+ texOffset.x = IN.TEX0.x + sinOffset1 + sinOffset2;
+ texOffset.y = IN.TEX0.y + cos( accumTime * 3.0 + IN.TEX0.x * 6.28319 * 2.0 ) * 0.05;
+
+
+ float4 bumpNorm = TORQUE_TEX2D( bumpMap, texOffset ) * 2.0 - 1.0;
+ float4 diffuse = TORQUE_TEX2D( diffMap, texOffset );
+
+ OUT.col = diffuse * (saturate( dot( IN.lightVec, bumpNorm.xyz ) ) + ambient);
+
+ float3 eyeVec = normalize(IN.eyePos - IN.pixPos);
+ float3 halfAng = normalize(eyeVec + IN.lightVec.xyz);
+ float specular = saturate( dot(bumpNorm, halfAng) ) * IN.lightVec.w;
+ specular = pow(abs(specular), specularPower);
+ OUT.col += specularColor * specular;
+
+
+
+ return OUT;
+}
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/wavesV.hlsl b/Templates/BaseGame/game/core/rendering/shaders/wavesV.hlsl
new file mode 100644
index 000000000..fccef9d25
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/wavesV.hlsl
@@ -0,0 +1,90 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#define IN_HLSL
+#include "shdrConsts.h"
+#include "hlslStructs.hlsl"
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+struct Conn
+{
+ float4 HPOS : POSITION;
+ float2 TEX0 : TEXCOORD0;
+ float4 tangentToCube0 : TEXCOORD1;
+ float4 tangentToCube1 : TEXCOORD2;
+ float4 tangentToCube2 : TEXCOORD3;
+ float4 outLightVec : TEXCOORD4;
+ float3 pos : TEXCOORD5;
+ float3 outEyePos : TEXCOORD6;
+
+};
+
+
+uniform float4x4 modelview : register(VC_WORLD_PROJ);
+uniform float3x3 cubeTrans : register(VC_CUBE_TRANS);
+uniform float3 cubeEyePos : register(VC_CUBE_EYE_POS);
+uniform float3 inLightVec : register(VC_LIGHT_DIR1);
+uniform float3 eyePos : register(VC_EYE_POS);
+
+//-----------------------------------------------------------------------------
+// Main
+//-----------------------------------------------------------------------------
+Conn main( VertexIn_PNTTTB In)
+{
+ Conn Out;
+
+ Out.HPOS = mul(modelview, float4(In.pos,1.0));
+ Out.TEX0 = In.uv0;
+
+
+ float3x3 objToTangentSpace;
+ objToTangentSpace[0] = In.T;
+ objToTangentSpace[1] = In.B;
+ objToTangentSpace[2] = In.normal;
+
+
+ Out.tangentToCube0.xyz = mul( objToTangentSpace, cubeTrans[0].xyz );
+ Out.tangentToCube1.xyz = mul( objToTangentSpace, cubeTrans[1].xyz );
+ Out.tangentToCube2.xyz = mul( objToTangentSpace, cubeTrans[2].xyz );
+
+ float3 pos = mul( cubeTrans, In.pos ).xyz;
+ float3 eye = cubeEyePos - pos;
+ normalize( eye );
+
+ Out.tangentToCube0.w = eye.x;
+ Out.tangentToCube1.w = eye.y;
+ Out.tangentToCube2.w = eye.z;
+
+ Out.outLightVec.xyz = -inLightVec;
+ Out.outLightVec.xyz = mul(objToTangentSpace, Out.outLightVec);
+ Out.pos = mul(objToTangentSpace, In.pos.xyz / 100.0);
+ Out.outEyePos.xyz = mul(objToTangentSpace, eyePos.xyz / 100.0);
+ Out.outLightVec.w = step( 0.0, dot( -inLightVec, In.normal ) );
+
+
+ return Out;
+}
+
+
diff --git a/Templates/BaseGame/game/core/rendering/shaders/wind.hlsl b/Templates/BaseGame/game/core/rendering/shaders/wind.hlsl
new file mode 100644
index 000000000..b3fee7721
--- /dev/null
+++ b/Templates/BaseGame/game/core/rendering/shaders/wind.hlsl
@@ -0,0 +1,101 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//
+// A tip of the hat....
+//
+// The following wind effects were derived from the GPU Gems
+// 3 chapter "Vegetation Procedural Animation and Shading in Crysis"
+// by Tiago Sousa of Crytek.
+//
+
+float4 smoothCurve( float4 x )
+{
+ return x * x * ( 3.0 - 2.0 * x );
+}
+
+float4 triangleWave( float4 x )
+{
+ return abs( frac( x + 0.5 ) * 2.0 - 1.0 );
+}
+
+float4 smoothTriangleWave( float4 x )
+{
+ return smoothCurve( triangleWave( x ) );
+}
+
+float3 windTrunkBending( float3 vPos, float2 vWind, float fBendFactor )
+{
+ // Smooth the bending factor and increase
+ // the near by height limit.
+ fBendFactor += 1.0;
+ fBendFactor *= fBendFactor;
+ fBendFactor = fBendFactor * fBendFactor - fBendFactor;
+
+ // Displace the vert.
+ float3 vNewPos = vPos;
+ vNewPos.xy += vWind * fBendFactor;
+
+ // Limit the length which makes the bend more
+ // spherical and prevents stretching.
+ float fLength = length( vPos );
+ vPos = normalize( vNewPos ) * fLength;
+
+ return vPos;
+}
+
+float3 windBranchBending( float3 vPos,
+ float3 vNormal,
+
+ float fTime,
+ float fWindSpeed,
+
+ float fBranchPhase,
+ float fBranchAmp,
+ float fBranchAtten,
+
+ float fDetailPhase,
+ float fDetailAmp,
+ float fDetailFreq,
+
+ float fEdgeAtten )
+{
+ float fVertPhase = dot( vPos, fDetailPhase + fBranchPhase );
+
+ float2 vWavesIn = fTime + float2( fVertPhase, fBranchPhase );
+
+ float4 vWaves = ( frac( vWavesIn.xxyy *
+ float4( 1.975, 0.793, 0.375, 0.193 ) ) *
+ 2.0 - 1.0 ) * fWindSpeed * fDetailFreq;
+
+ vWaves = smoothTriangleWave( vWaves );
+
+ float2 vWavesSum = vWaves.xz + vWaves.yw;
+
+ // We want the branches to bend both up and down.
+ vWavesSum.y = 1 - ( vWavesSum.y * 2 );
+
+ vPos += vWavesSum.xxy * float3( fEdgeAtten * fDetailAmp * vNormal.xy,
+ fBranchAtten * fBranchAmp );
+
+ return vPos;
+}
diff --git a/Templates/BaseGame/game/core/sfx/Core_SFX.cs b/Templates/BaseGame/game/core/sfx/Core_SFX.cs
new file mode 100644
index 000000000..acd5c6e08
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/Core_SFX.cs
@@ -0,0 +1,15 @@
+
+function Core_SFX::onCreate(%this)
+{
+ exec("./scripts/audio.cs");
+ exec("./scripts/audioData.cs");
+ exec("./scripts/audioAmbience.cs");
+ exec("./scripts/audioDescriptions.cs");
+ exec("./scripts/audioEnvironments.cs");
+ exec("./scripts/audioStates.cs");
+
+}
+
+function Core_SFX::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/sfx/Core_SFX.module b/Templates/BaseGame/game/core/sfx/Core_SFX.module
new file mode 100644
index 000000000..855fe2a11
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/Core_SFX.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audio.cs b/Templates/BaseGame/game/core/sfx/scripts/audio.cs
new file mode 100644
index 000000000..a5932de8f
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audio.cs
@@ -0,0 +1,436 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Source groups.
+//-----------------------------------------------------------------------------
+
+singleton SFXDescription( AudioMaster );
+singleton SFXSource( AudioChannelMaster )
+{
+ description = AudioMaster;
+};
+
+singleton SFXDescription( AudioChannel )
+{
+ sourceGroup = AudioChannelMaster;
+};
+
+singleton SFXSource( AudioChannelDefault )
+{
+ description = AudioChannel;
+};
+singleton SFXSource( AudioChannelGui )
+{
+ description = AudioChannel;
+};
+singleton SFXSource( AudioChannelEffects )
+{
+ description = AudioChannel;
+};
+singleton SFXSource( AudioChannelMessages )
+{
+ description = AudioChannel;
+};
+singleton SFXSource( AudioChannelMusic )
+{
+ description = AudioChannel;
+};
+
+// Set default playback states of the channels.
+
+AudioChannelMaster.play();
+AudioChannelDefault.play();
+
+AudioChannelGui.play();
+AudioChannelMusic.play();
+AudioChannelMessages.play();
+
+// Stop in-game effects channels.
+AudioChannelEffects.stop();
+
+//-----------------------------------------------------------------------------
+// Master SFXDescriptions.
+//-----------------------------------------------------------------------------
+
+// Master description for interface audio.
+singleton SFXDescription( AudioGui )
+{
+ volume = 1.0;
+ sourceGroup = AudioChannelGui;
+};
+
+// Master description for game effects audio.
+singleton SFXDescription( AudioEffect )
+{
+ volume = 1.0;
+ sourceGroup = AudioChannelEffects;
+};
+
+// Master description for audio in notifications.
+singleton SFXDescription( AudioMessage )
+{
+ volume = 1.0;
+ sourceGroup = AudioChannelMessages;
+};
+
+// Master description for music.
+singleton SFXDescription( AudioMusic )
+{
+ volume = 1.0;
+ sourceGroup = AudioChannelMusic;
+};
+
+//-----------------------------------------------------------------------------
+// SFX Functions.
+//-----------------------------------------------------------------------------
+
+/// This initializes the sound system device from
+/// the defaults in the $pref::SFX:: globals.
+function sfxStartup()
+{
+ echo( "\nsfxStartup..." );
+
+ // If we have a provider set, try initialize a device now.
+
+ if( $pref::SFX::provider !$= "" )
+ {
+ if( sfxInit() )
+ return;
+ else
+ {
+ // Force auto-detection.
+ $pref::SFX::autoDetect = true;
+ }
+ }
+
+ // If enabled autodetect a safe device.
+
+ if( ( !isDefined( "$pref::SFX::autoDetect" ) || $pref::SFX::autoDetect ) &&
+ sfxAutodetect() )
+ return;
+
+ // Failure.
+
+ error( " Failed to initialize device!\n\n" );
+
+ $pref::SFX::provider = "";
+ $pref::SFX::device = "";
+
+ return;
+}
+
+
+/// This initializes the sound system device from
+/// the defaults in the $pref::SFX:: globals.
+function sfxInit()
+{
+ // If already initialized, shut down the current device first.
+
+ if( sfxGetDeviceInfo() !$= "" )
+ sfxShutdown();
+
+ // Start it up!
+ %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers;
+ if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, %maxBuffers ) )
+ return false;
+
+ // This returns a tab seperated string with
+ // the initialized system info.
+ %info = sfxGetDeviceInfo();
+ $pref::SFX::provider = getField( %info, 0 );
+ $pref::SFX::device = getField( %info, 1 );
+ $pref::SFX::useHardware = getField( %info, 2 );
+ %useHardware = $pref::SFX::useHardware ? "Yes" : "No";
+ %maxBuffers = getField( %info, 3 );
+
+ echo( " Provider: " @ $pref::SFX::provider );
+ echo( " Device: " @ $pref::SFX::device );
+ echo( " Hardware: " @ %useHardware );
+ echo( " Max Buffers: " @ %maxBuffers );
+ echo( " " );
+
+ if( isDefined( "$pref::SFX::distanceModel" ) )
+ sfxSetDistanceModel( $pref::SFX::distanceModel );
+ if( isDefined( "$pref::SFX::dopplerFactor" ) )
+ sfxSetDopplerFactor( $pref::SFX::dopplerFactor );
+ if( isDefined( "$pref::SFX::rolloffFactor" ) )
+ sfxSetRolloffFactor( $pref::SFX::rolloffFactor );
+
+ // Restore master volume.
+
+ sfxSetMasterVolume( $pref::SFX::masterVolume );
+
+ // Restore channel volumes.
+
+ for( %channel = 0; %channel <= 8; %channel ++ )
+ sfxSetChannelVolume( %channel, $pref::SFX::channelVolume[ %channel ] );
+
+ return true;
+}
+
+
+/// Destroys the current sound system device.
+function sfxShutdown()
+{
+ // Store volume prefs.
+
+ $pref::SFX::masterVolume = sfxGetMasterVolume();
+
+ for( %channel = 0; %channel <= 8; %channel ++ )
+ $pref::SFX::channelVolume[ %channel ] = sfxGetChannelVolume( %channel );
+
+ // We're assuming here that a null info
+ // string means that no device is loaded.
+ if( sfxGetDeviceInfo() $= "" )
+ return;
+
+ sfxDeleteDevice();
+}
+
+
+/// Determines which of the two SFX providers is preferable.
+function sfxCompareProvider( %providerA, %providerB )
+{
+ if( %providerA $= %providerB )
+ return 0;
+
+ switch$( %providerA )
+ {
+ // Always prefer FMOD over anything else.
+ case "FMOD":
+ return 1;
+
+ // Prefer OpenAL over anything but FMOD.
+ case "OpenAL":
+ if( %providerB $= "FMOD" )
+ return -1;
+ else
+ return 1;
+
+ // choose XAudio over DirectSound
+ case "XAudio":
+ if( %providerB $= "FMOD" || %providerB $= "OpenAL" )
+ return -1;
+ else
+ return 0;
+
+ case "DirectSound":
+ if( %providerB !$= "FMOD" && %providerB !$= "OpenAL" && %providerB !$= "XAudio" )
+ return 1;
+ else
+ return -1;
+
+ default:
+ return -1;
+ }
+}
+
+
+/// Try to detect and initalize the best SFX device available.
+function sfxAutodetect()
+{
+ // Get all the available devices.
+
+ %devices = sfxGetAvailableDevices();
+
+ // Collect and sort the devices by preferentiality.
+
+ %deviceTrySequence = new ArrayObject();
+ %bestMatch = -1;
+ %count = getRecordCount( %devices );
+ for( %i = 0; %i < %count; %i ++ )
+ {
+ %info = getRecord( %devices, %i );
+ %provider = getField( %info, 0 );
+
+ %deviceTrySequence.push_back( %provider, %info );
+ }
+
+ %deviceTrySequence.sortfkd( "sfxCompareProvider" );
+
+ // Try the devices in order.
+
+ %count = %deviceTrySequence.count();
+ for( %i = 0; %i < %count; %i ++ )
+ {
+ %provider = %deviceTrySequence.getKey( %i );
+ %info = %deviceTrySequence.getValue( %i );
+
+ $pref::SFX::provider = %provider;
+ $pref::SFX::device = getField( %info, 1 );
+ $pref::SFX::useHardware = getField( %info, 2 );
+
+ // By default we've decided to avoid hardware devices as
+ // they are buggy and prone to problems.
+ $pref::SFX::useHardware = false;
+
+ if( sfxInit() )
+ {
+ $pref::SFX::autoDetect = false;
+ %deviceTrySequence.delete();
+ return true;
+ }
+ }
+
+ // Found no suitable device.
+
+ error( "sfxAutodetect - Could not initialize a valid SFX device." );
+
+ $pref::SFX::provider = "";
+ $pref::SFX::device = "";
+ $pref::SFX::useHardware = "";
+
+ %deviceTrySequence.delete();
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Backwards-compatibility with old channel system.
+//-----------------------------------------------------------------------------
+
+// Volume channel IDs for backwards-compatibility.
+
+$GuiAudioType = 1; // Interface.
+$SimAudioType = 2; // Game.
+$MessageAudioType = 3; // Notifications.
+$MusicAudioType = 4; // Music.
+
+$AudioChannels[ 0 ] = AudioChannelDefault;
+$AudioChannels[ $GuiAudioType ] = AudioChannelGui;
+$AudioChannels[ $SimAudioType ] = AudioChannelEffects;
+$AudioChannels[ $MessageAudioType ] = AudioChannelMessages;
+$AudioChannels[ $MusicAudioType ] = AudioChannelMusic;
+
+function sfxOldChannelToGroup( %channel )
+{
+ return $AudioChannels[ %channel ];
+}
+
+function sfxGroupToOldChannel( %group )
+{
+ %id = %group.getId();
+ for( %i = 0;; %i ++ )
+ if( !isObject( $AudioChannels[ %i ] ) )
+ return -1;
+ else if( $AudioChannels[ %i ].getId() == %id )
+ return %i;
+
+ return -1;
+}
+
+function sfxSetMasterVolume( %volume )
+{
+ AudioChannelMaster.setVolume( %volume );
+}
+
+function sfxGetMasterVolume( %volume )
+{
+ return AudioChannelMaster.getVolume();
+}
+
+function sfxStopAll( %channel )
+{
+ // Don't stop channel itself since that isn't quite what the function
+ // here intends.
+
+ %channel = sfxOldChannelToGroup( %channel );
+ if (isObject(%channel))
+ {
+ foreach( %source in %channel )
+ %source.stop();
+ }
+}
+
+function sfxGetChannelVolume( %channel )
+{
+ %obj = sfxOldChannelToGroup( %channel );
+ if( isObject( %obj ) )
+ return %obj.getVolume();
+}
+
+function sfxSetChannelVolume( %channel, %volume )
+{
+ %obj = sfxOldChannelToGroup( %channel );
+ if( isObject( %obj ) )
+ %obj.setVolume( %volume );
+}
+
+/*singleton SimSet( SFXPausedSet );
+
+
+/// Pauses the playback of active sound sources.
+///
+/// @param %channels An optional word list of channel indices or an empty
+/// string to pause sources on all channels.
+/// @param %pauseSet An optional SimSet which is filled with the paused
+/// sources. If not specified the global SfxSourceGroup
+/// is used.
+///
+/// @deprecated
+///
+function sfxPause( %channels, %pauseSet )
+{
+ // Did we get a set to populate?
+ if ( !isObject( %pauseSet ) )
+ %pauseSet = SFXPausedSet;
+
+ %count = SFXSourceSet.getCount();
+ for ( %i = 0; %i < %count; %i++ )
+ {
+ %source = SFXSourceSet.getObject( %i );
+
+ %channel = sfxGroupToOldChannel( %source.getGroup() );
+ if( %channels $= "" || findWord( %channels, %channel ) != -1 )
+ {
+ %source.pause();
+ %pauseSet.add( %source );
+ }
+ }
+}
+
+
+/// Resumes the playback of paused sound sources.
+///
+/// @param %pauseSet An optional SimSet which contains the paused sound
+/// sources to be resumed. If not specified the global
+/// SfxSourceGroup is used.
+/// @deprecated
+///
+function sfxResume( %pauseSet )
+{
+ if ( !isObject( %pauseSet ) )
+ %pauseSet = SFXPausedSet;
+
+ %count = %pauseSet.getCount();
+ for ( %i = 0; %i < %count; %i++ )
+ {
+ %source = %pauseSet.getObject( %i );
+ %source.play();
+ }
+
+ // Clear our pause set... the caller is left
+ // to clear his own if he passed one.
+ %pauseSet.clear();
+}*/
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.cs b/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.cs
new file mode 100644
index 000000000..8c2bf270c
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.cs
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+singleton SFXAmbience( AudioAmbienceDefault )
+{
+ environment = AudioEnvOff;
+};
+
+singleton SFXAmbience( AudioAmbienceOutside )
+{
+ environment = AudioEnvPlain;
+ states[ 0 ] = AudioLocationOutside;
+};
+
+singleton SFXAmbience( AudioAmbienceInside )
+{
+ environment = AudioEnvRoom;
+ states[ 0 ] = AudioLocationInside;
+};
+
+singleton SFXAmbience( AudioAmbienceUnderwater )
+{
+ environment = AudioEnvUnderwater;
+ states[ 0 ] = AudioLocationUnderwater;
+};
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioData.cs b/Templates/BaseGame/game/core/sfx/scripts/audioData.cs
new file mode 100644
index 000000000..8584ce50e
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audioData.cs
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Game specific audio descriptions. Always declare SFXDescription's (the type of sound)
+// before SFXProfile's (the sound itself) when creating new ones
+
+singleton SFXDescription(BulletFireDesc : AudioEffect )
+{
+ isLooping = false;
+ is3D = true;
+ ReferenceDistance = 10.0;
+ MaxDistance = 60.0;
+};
+
+singleton SFXDescription(BulletImpactDesc : AudioEffect )
+{
+ isLooping = false;
+ is3D = true;
+ ReferenceDistance = 10.0;
+ MaxDistance = 30.0;
+ volume = 0.4;
+ pitch = 1.4;
+};
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioDescriptions.cs b/Templates/BaseGame/game/core/sfx/scripts/audioDescriptions.cs
new file mode 100644
index 000000000..d682461cf
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audioDescriptions.cs
@@ -0,0 +1,143 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Always declare SFXDescription's (the type of sound) before SFXProfile's (the
+// sound itself) when creating new ones
+
+//-----------------------------------------------------------------------------
+// 3D Sounds
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Single shot sounds
+//-----------------------------------------------------------------------------
+
+singleton SFXDescription( AudioDefault3D : AudioEffect )
+{
+ is3D = true;
+ ReferenceDistance = 20.0;
+ MaxDistance = 100.0;
+};
+
+singleton SFXDescription( AudioSoft3D : AudioEffect )
+{
+ is3D = true;
+ ReferenceDistance = 20.0;
+ MaxDistance = 100.0;
+ volume = 0.4;
+};
+
+singleton SFXDescription( AudioClose3D : AudioEffect )
+{
+ is3D = true;
+ ReferenceDistance = 10.0;
+ MaxDistance = 60.0;
+};
+
+singleton SFXDescription( AudioClosest3D : AudioEffect )
+{
+ is3D = true;
+ ReferenceDistance = 5.0;
+ MaxDistance = 10.0;
+};
+
+//-----------------------------------------------------------------------------
+// Looping sounds
+//-----------------------------------------------------------------------------
+
+singleton SFXDescription( AudioDefaultLoop3D : AudioEffect )
+{
+ isLooping = true;
+ is3D = true;
+ ReferenceDistance = 20.0;
+ MaxDistance = 100.0;
+};
+
+singleton SFXDescription( AudioCloseLoop3D : AudioEffect )
+{
+ isLooping = true;
+ is3D = true;
+ ReferenceDistance = 18.0;
+ MaxDistance = 25.0;
+};
+
+singleton SFXDescription( AudioClosestLoop3D : AudioEffect )
+{
+ isLooping = true;
+ is3D = true;
+ ReferenceDistance = 5.0;
+ MaxDistance = 10.0;
+};
+
+//-----------------------------------------------------------------------------
+// 2d sounds
+//-----------------------------------------------------------------------------
+
+// Used for non-looping environmental sounds (like power on, power off)
+singleton SFXDescription( Audio2D : AudioEffect )
+{
+ isLooping = false;
+};
+
+// Used for Looping Environmental Sounds
+singleton SFXDescription( AudioLoop2D : AudioEffect )
+{
+ isLooping = true;
+};
+
+singleton SFXDescription( AudioStream2D : AudioEffect )
+{
+ isStreaming = true;
+};
+singleton SFXDescription( AudioStreamLoop2D : AudioEffect )
+{
+ isLooping = true;
+ isStreaming = true;
+};
+
+//-----------------------------------------------------------------------------
+// Music
+//-----------------------------------------------------------------------------
+
+singleton SFXDescription( AudioMusic2D : AudioMusic )
+{
+ isStreaming = true;
+};
+
+singleton SFXDescription( AudioMusicLoop2D : AudioMusic )
+{
+ isLooping = true;
+ isStreaming = true;
+};
+
+singleton SFXDescription( AudioMusic3D : AudioMusic )
+{
+ isStreaming = true;
+ is3D = true;
+};
+
+singleton SFXDescription( AudioMusicLoop3D : AudioMusic )
+{
+ isStreaming = true;
+ is3D = true;
+ isLooping = true;
+};
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioEnvironments.cs b/Templates/BaseGame/game/core/sfx/scripts/audioEnvironments.cs
new file mode 100644
index 000000000..671825b6b
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audioEnvironments.cs
@@ -0,0 +1,916 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Reverb environment presets.
+//
+// For customized presets, best derive from one of these presets.
+
+singleton SFXEnvironment( AudioEnvOff )
+{
+ envSize = "7.5";
+ envDiffusion = "1.0";
+ room = "-10000";
+ roomHF = "-10000";
+ roomLF = "0";
+ decayTime = "1.0";
+ decayHFRatio = "1.0";
+ decayLFRatio = "1.0";
+ reflections = "-2602";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "200";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "0.0";
+ density = "0.0";
+ flags = 0x33;
+};
+
+singleton SFXEnvironment( AudioEnvGeneric )
+{
+ envSize = "7.5";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-100";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.83";
+ decayLFRatio = "1.0";
+ reflections = "-2602";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "200";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvRoom )
+{
+ envSize = "1.9";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-454";
+ roomLF = "0";
+ decayTime = "0.4";
+ decayHFRatio = "0.83";
+ decayLFRatio = "1.0";
+ reflections = "-1646";
+ reflectionsDelay = "0.002";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "53";
+ reverbDelay = "0.003";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvPaddedCell )
+{
+ envSize = "1.4";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-6000";
+ roomLF = "0";
+ decayTime = "0.17";
+ decayHFRatio = "0.1";
+ decayLFRatio = "1.0";
+ reflections = "-1204";
+ reflectionsDelay = "0.001";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "207";
+ reverbDelay = "0.002";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvBathroom )
+{
+ envSize = "1.4";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-1200";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.54";
+ decayLFRatio = "1.0";
+ reflections = "-370";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "1030";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "60.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvLivingRoom )
+{
+ envSize = "2.5";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-6000";
+ roomLF = "0";
+ decayTime = "0.5";
+ decayHFRatio = "0.1";
+ decayLFRatio = "1.0";
+ reflections = "-1376";
+ reflectionsDelay = "0.003";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1104";
+ reverbDelay = "0.004";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvStoneRoom )
+{
+ envSize = "11.6";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "300";
+ roomLF = "0";
+ decayTime = "2.31";
+ decayHFRatio = "0.64";
+ decayLFRatio = "1.0";
+ reflections = "-711";
+ reflectionsDelay = "0.012";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "83";
+ reverbDelay = "0.017";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "-5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvAuditorium )
+{
+ envSize = "21.6";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-476";
+ roomLF = "0";
+ decayTime = "4.32";
+ decayHFRatio = "0.59";
+ decayLFRatio = "1.0";
+ reflections = "1";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-289";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvConcertHall )
+{
+ envSize = "19.6";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-500";
+ roomLF = "0";
+ decayTime = "3.92";
+ decayHFRatio = "0.7";
+ decayLFRatio = "1.0";
+ reflections = "-1230";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-2";
+ reverbDelay = "0.029";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvCave )
+{
+ envSize = "14.6";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "0";
+ roomLF = "0";
+ decayTime = "2.91";
+ decayHFRatio = "1.3";
+ decayLFRatio = "1.0";
+ reflections = "-602";
+ reflectionsDelay = "0.015";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-302";
+ reverbDelay = "0.022";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x1f;
+};
+
+singleton SFXEnvironment( AudioEnvArena )
+{
+ envSize = "36.2f";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-698";
+ roomLF = "0";
+ decayTime = "7.24";
+ decayHFRatio = "0.33";
+ decayLFRatio = "1.0";
+ reflections = "-1166";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "16";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvHangar )
+{
+ envSize = "50.3";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-1000";
+ roomLF = "0";
+ decayTime = "10.05";
+ decayHFRatio = "0.23";
+ decayLFRatio = "1.0";
+ reflections = "-602";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "198";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvCarpettedHallway )
+{
+ envSize = "1.9";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-4000";
+ roomLF = "0";
+ decayTime = "0.3";
+ decayHFRatio = "0.1";
+ decayLFRatio = "1.0";
+ reflections = "-1831";
+ reflectionsDelay = "0.002";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1630";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvHallway )
+{
+ envSize = "1.8";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-300";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.59";
+ decayLFRatio = "1.0";
+ reflections = "-1219";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "441";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvStoneCorridor )
+{
+ envSize = "13.5";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-237";
+ roomLF = "0";
+ decayTime = "2.7";
+ decayHFRatio = "0.79";
+ decayLFRatio = "1.0";
+ reflections = "-1214";
+ reflectionsDelay = "0.013";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "395";
+ reverbDelay = "0.02";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvAlley )
+{
+ envSize = "7.5";
+ envDiffusion = "0.3";
+ room = "-1000";
+ roomHF = "-270";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.86";
+ decayLFRatio = "1.0";
+ reflections = "-1204";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-4";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.125";
+ echoDepth = "0.95";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvForest )
+{
+ envSize = "38.0";
+ envDiffusion = "0.3";
+ room = "-1000";
+ roomHF = "-3300";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.54";
+ decayLFRatio = "1.0";
+ reflections = "-2560";
+ reflectionsDelay = "0.162";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-229";
+ reverbDelay = "0.088";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.125";
+ echoDepth = "1.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "79.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvCity )
+{
+ envSize = "7.5";
+ envDiffusion = "0.5";
+ room = "-1000";
+ roomHF = "-800";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.67";
+ decayLFRatio = "1.0";
+ reflections = "-2273";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1691";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "50.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvMountains )
+{
+ envSize = "100.0";
+ envDiffusion = "0.27";
+ room = "-1000";
+ roomHF = "-2500";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.21";
+ decayLFRatio = "1.0";
+ reflections = "-2780";
+ reflectionsDelay = "0.3";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1434";
+ reverbDelay = "0.1";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "1.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "27.0";
+ density = "100.0";
+ flags = 0x1f;
+};
+
+singleton SFXEnvironment( AudioEnvQuary )
+{
+ envSize = "17.5";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-1000";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.83";
+ decayLFRatio = "1.0";
+ reflections = "-10000";
+ reflectionsDelay = "0.061";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "500";
+ reverbDelay = "0.025";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.125";
+ echoDepth = "0.7";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvPlain )
+{
+ envSize = "42.5";
+ envDiffusion = "0.21";
+ room = "-1000";
+ roomHF = "-2000";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.5";
+ decayLFRatio = "1.0";
+ reflections = "-2466";
+ reflectionsDelay = "0.179";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1926";
+ reverbDelay = "0.1";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "1.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "21.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvParkingLot )
+{
+ envSize = "8.3";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "0";
+ roomLF = "0";
+ decayTime = "1.65";
+ decayHFRatio = "1.5";
+ decayLFRatio = "1.0";
+ reflections = "-1363";
+ reflectionsDelay = "0.008";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-1153";
+ reverbDelay = "0.012";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x1f;
+};
+
+singleton SFXEnvironment( AudioEnvSewerPipe )
+{
+ envSize = "1.7";
+ envDiffusion = "0.8";
+ room = "-1000";
+ roomHF = "-1000";
+ roomLF = "0";
+ decayTime = "2.81";
+ decayHFRatio = "0.14";
+ decayLFRatio = "1.0";
+ reflections = "429";
+ reflectionsDelay = "0.014";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "1023";
+ reverbDelay = "0.21";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "0.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "80.0";
+ density = "60.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvUnderwater )
+{
+ envSize = "1.8";
+ envDiffusion = "1.0";
+ room = "-1000";
+ roomHF = "-4000";
+ roomLF = "0";
+ decayTime = "1.49";
+ decayHFRatio = "0.1";
+ decayLFRatio = "1.0";
+ reflections = "-449";
+ reflectionsDelay = "0.007";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "1700";
+ reverbDelay = "0.011";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "1.18";
+ modulationDepth = "0.348";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x3f;
+};
+
+singleton SFXEnvironment( AudioEnvDrugged )
+{
+ envSize = "1.9";
+ envDiffusion = "0.5";
+ room = "-1000";
+ roomHF = "0";
+ roomLF = "0";
+ decayTime = "8.39";
+ decayHFRatio = "1.39";
+ decayLFRatio = "1.0";
+ reflections = "-115";
+ reflectionsDelay = "0.002";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "985";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "0.25";
+ modulationDepth = "1.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x1f;
+};
+
+singleton SFXEnvironment( AudioEnvDizzy )
+{
+ envSize = "1.8";
+ envDiffusion = "0.6";
+ room = "-1000.0";
+ roomHF = "-400";
+ roomLF = "0";
+ decayTime = "17.23";
+ decayHFRatio = "0.56";
+ decayLFRatio = "1.0";
+ reflections = "-1713";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "-613";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "1.0";
+ modulationTime = "0.81";
+ modulationDepth = "0.31";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x1f;
+};
+
+singleton SFXEnvironment( AudioEnvPsychotic )
+{
+ envSize = "1.0";
+ envDiffusion = "0.5";
+ room = "-1000";
+ roomHF = "-151";
+ roomLF = "0";
+ decayTime = "7.56";
+ decayHFRatio = "0.91";
+ decayLFRatio = "1.0";
+ reflections = "-626";
+ reflectionsDelay = "0.02";
+ reflectionsPan[ 0 ] = "0.0";
+ reflectionsPan[ 1 ] = "0.0";
+ reflectionsPan[ 2 ] = "0.0";
+ reverb = "774";
+ reverbDelay = "0.03";
+ reverbPan[ 0 ] = "0.0";
+ reverbPan[ 1 ] = "0.0";
+ reverbPan[ 2 ] = "0.0";
+ echoTime = "0.25";
+ echoDepth = "0.0";
+ modulationTime = "4.0";
+ modulationDepth = "1.0";
+ airAbsorptionHF = "-5.0";
+ HFReference = "5000.0";
+ LFReference = "250.0";
+ roomRolloffFactor = "0.0";
+ diffusion = "100.0";
+ density = "100.0";
+ flags = 0x1f;
+};
diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioStates.cs b/Templates/BaseGame/game/core/sfx/scripts/audioStates.cs
new file mode 100644
index 000000000..3ab55cf78
--- /dev/null
+++ b/Templates/BaseGame/game/core/sfx/scripts/audioStates.cs
@@ -0,0 +1,158 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Some state presets.
+
+
+/// Return the first active SFXState in the given SimSet/SimGroup.
+function sfxGetActiveStateInGroup( %group )
+{
+ %count = %group.getCount();
+ for( %i = 0; %i < %count; %i ++ )
+ {
+ %obj = %group.getObject( %i );
+ if( !%obj.isMemberOfClass( "SFXState" ) )
+ continue;
+
+ if( %obj.isActive() )
+ return %obj;
+ }
+
+ return 0;
+}
+
+
+//-----------------------------------------------------------------------------
+// Special audio state that will always and only be active when no other
+// state is active. Useful for letting slots apply specifically when no
+// other slot in a list applies.
+
+singleton SFXState( AudioStateNone ) {};
+
+AudioStateNone.activate();
+
+function SFXState::onActivate( %this )
+{
+ if( %this.getId() != AudioStateNone.getId() )
+ AudioStateNone.disable();
+}
+
+function SFXState::onDeactivate( %this )
+{
+ if( %this.getId() != AudioStateNone.getId() )
+ AudioStateNone.enable();
+}
+
+//-----------------------------------------------------------------------------
+// AudioStateExclusive class.
+//
+// Automatically deactivates sibling SFXStates in its parent SimGroup
+// when activated.
+
+function AudioStateExclusive::onActivate( %this )
+{
+ Parent::onActivate( %this );
+
+ %group = %this.parentGroup;
+ %count = %group.getCount();
+
+ for( %i = 0; %i < %count; %i ++ )
+ {
+ %obj = %group.getObject( %i );
+
+ if( %obj != %this && %obj.isMemberOfClass( "SFXState" ) && %obj.isActive() )
+ %obj.deactivate();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Location-dependent states.
+
+singleton SimGroup( AudioLocation );
+
+/// State when the listener is outside.
+singleton SFXState( AudioLocationOutside )
+{
+ parentGroup = AudioLocation;
+ className = "AudioStateExclusive";
+};
+
+/// State when the listener is submerged.
+singleton SFXState( AudioLocationUnderwater )
+{
+ parentGroup = AudioLocation;
+ className = "AudioStateExclusive";
+};
+
+/// State when the listener is indoors.
+singleton SFXState( AudioLocationInside )
+{
+ parentGroup = AudioLocation;
+ className = "AudioStateExclusive";
+};
+
+/// Return the currently active SFXState in AudioLocation.
+function sfxGetLocation()
+{
+ return sfxGetActiveStateInGroup( AudioLocation );
+}
+
+//-----------------------------------------------------------------------------
+// Mood-dependent states.
+
+singleton SimGroup( AudioMood );
+
+singleton SFXState( AudioMoodNeutral )
+{
+ parentGroup = AudioMood;
+ className = "AudioStateExclusive";
+};
+
+singleton SFXState( AudioMoodAggressive )
+{
+ parentGroup = AudioMood;
+ className = "AudioStateExclusive";
+};
+
+singleton SFXState( AudioMoodTense )
+{
+ parentGroup = AudioMood;
+ className = "AudioStateExclusive";
+};
+
+singleton SFXState( AudioMoodVictory )
+{
+ parentGroup = AudioMood;
+ className = "AudioStateExclusive";
+};
+
+singleton SFXState( AudioMoodCalm )
+{
+ parentGroup = AudioMood;
+ className = "AudioStateExclusive";
+};
+
+/// Return the currently active SFXState in AudioMood.
+function sfxGetMood()
+{
+ return sfxGetActiveStateInGroup( AudioMood );
+}
diff --git a/Templates/BaseGame/game/core/utility/Core_Utility.cs b/Templates/BaseGame/game/core/utility/Core_Utility.cs
new file mode 100644
index 000000000..d412f3544
--- /dev/null
+++ b/Templates/BaseGame/game/core/utility/Core_Utility.cs
@@ -0,0 +1,11 @@
+
+function Core_Utility::onCreate(%this)
+{
+ exec("./scripts/parseArgs.cs");
+ exec("./scripts/globals.cs");
+ exec("./scripts/helperFunctions.cs");
+}
+
+function Core_Utility::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/utility/Core_Utility.module b/Templates/BaseGame/game/core/utility/Core_Utility.module
new file mode 100644
index 000000000..cb6539040
--- /dev/null
+++ b/Templates/BaseGame/game/core/utility/Core_Utility.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/utility/scripts/globals.cs b/Templates/BaseGame/game/core/utility/scripts/globals.cs
new file mode 100644
index 000000000..fcf52390a
--- /dev/null
+++ b/Templates/BaseGame/game/core/utility/scripts/globals.cs
@@ -0,0 +1,102 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// DInput keyboard, mouse, and joystick prefs
+// ----------------------------------------------------------------------------
+
+$pref::Input::MouseEnabled = 1;
+$pref::Input::LinkMouseSensitivity = 1;
+$pref::Input::KeyboardEnabled = 1;
+$pref::Input::KeyboardTurnSpeed = 0.1;
+$pref::Input::JoystickEnabled = 0;
+
+// ----------------------------------------------------------------------------
+// Video Preferences
+// ----------------------------------------------------------------------------
+
+// Set directory paths for various data or default images.
+$pref::Video::ProfilePath = "core/rendering/scripts/gfxprofile";
+/*$pref::Video::missingTexturePath = "core/images/missingTexture.png";
+$pref::Video::unavailableTexturePath = "core/images/unavailable.png";
+$pref::Video::warningTexturePath = "core/images/warnMat.dds";*/
+
+$pref::Video::disableVerticalSync = 1;
+$pref::Video::mode = "800 600 false 32 60 4";
+$pref::Video::defaultFenceCount = 0;
+
+// This disables the hardware FSAA/MSAA so that we depend completely on the FXAA
+// post effect which works on all cards and in deferred mode. Note that the new
+// Intel Hybrid graphics on laptops will fail to initialize when hardware AA is
+// enabled... so you've been warned.
+$pref::Video::disableHardwareAA = true;
+
+$pref::Video::disableNormalmapping = false;
+$pref::Video::disablePixSpecular = false;
+$pref::Video::disableCubemapping = false;
+$pref::Video::disableParallaxMapping = false;
+
+// The number of mipmap levels to drop on loaded textures to reduce video memory
+// usage. It will skip any textures that have been defined as not allowing down
+// scaling.
+$pref::Video::textureReductionLevel = 0;
+
+$pref::Video::defaultAnisotropy = 1;
+//$pref::Video::Gamma = 1.0;
+
+/// AutoDetect graphics quality levels the next startup.
+$pref::Video::autoDetect = 1;
+
+// ----------------------------------------------------------------------------
+// Shader stuff
+// ----------------------------------------------------------------------------
+
+// This is the path used by ShaderGen to cache procedural shaders. If left
+// blank ShaderGen will only cache shaders to memory and not to disk.
+$shaderGen::cachePath = "data/shaderCache";
+
+// Uncomment to disable ShaderGen, useful when debugging
+//$ShaderGen::GenNewShaders = false;
+
+// Uncomment to dump disassembly for any shader that is compiled to disk. These
+// will appear as shadername_dis.txt in the same path as the shader file.
+//$gfx::disassembleAllShaders = true;
+
+// ----------------------------------------------------------------------------
+// Lighting and shadowing
+// ----------------------------------------------------------------------------
+
+// Uncomment to enable AdvancedLighting on the Mac (T3D 2009 Beta 3)
+//$pref::machax::enableAdvancedLighting = true;
+
+$sceneLighting::cacheSize = 20000;
+$sceneLighting::purgeMethod = "lastCreated";
+$sceneLighting::cacheLighting = 1;
+
+$pref::Shadows::textureScalar = 1.0;
+$pref::Shadows::disable = false;
+
+// Sets the shadow filtering mode.
+// None - Disables filtering.
+// SoftShadow - Does a simple soft shadow
+// SoftShadowHighQuality
+$pref::Shadows::filterMode = "SoftShadow";
diff --git a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs
new file mode 100644
index 000000000..8abe3e6e6
--- /dev/null
+++ b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs
@@ -0,0 +1,1158 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// Check if a script file exists, compiled or not.
+function isScriptFile(%path)
+{
+ if( isFile(%path @ ".dso") || isFile(%path) )
+ return true;
+
+ return false;
+}
+
+function loadMaterials()
+{
+ // Load any materials files for which we only have DSOs.
+
+ for( %file = findFirstFile( "*/materials.cs.dso" );
+ %file !$= "";
+ %file = findNextFile( "*/materials.cs.dso" ))
+ {
+ // Only execute, if we don't have the source file.
+ %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 );
+ if( !isFile( %csFileName ) )
+ exec( %csFileName );
+ }
+
+ // Load all source material files.
+
+ for( %file = findFirstFile( "*/materials.cs" );
+ %file !$= "";
+ %file = findNextFile( "*/materials.cs" ))
+ {
+ exec( %file );
+ }
+
+ // Load all materials created by the material editor if
+ // the folder exists
+ if( IsDirectory( "materialEditor" ) )
+ {
+ for( %file = findFirstFile( "materialEditor/*.cs.dso" );
+ %file !$= "";
+ %file = findNextFile( "materialEditor/*.cs.dso" ))
+ {
+ // Only execute, if we don't have the source file.
+ %csFileName = getSubStr( %file, 0, strlen( %file ) - 4 );
+ if( !isFile( %csFileName ) )
+ exec( %csFileName );
+ }
+
+ for( %file = findFirstFile( "materialEditor/*.cs" );
+ %file !$= "";
+ %file = findNextFile( "materialEditor/*.cs" ))
+ {
+ exec( %file );
+ }
+ }
+}
+
+function reloadMaterials()
+{
+ reloadTextures();
+ loadMaterials();
+ reInitMaterials();
+}
+
+function loadDatablockFiles( %datablockFiles, %recurse )
+{
+ if ( %recurse )
+ {
+ recursiveLoadDatablockFiles( %datablockFiles, 9999 );
+ return;
+ }
+
+ %count = %datablockFiles.count();
+ for ( %i=0; %i < %count; %i++ )
+ {
+ %file = %datablockFiles.getKey( %i );
+ if ( !isFile(%file @ ".dso") && !isFile(%file) )
+ continue;
+
+ exec( %file );
+ }
+
+ // Destroy the incoming list.
+ //%datablockFiles.delete();
+}
+
+function recursiveLoadDatablockFiles( %datablockFiles, %previousErrors )
+{
+ %reloadDatablockFiles = new ArrayObject();
+
+ // Keep track of the number of datablocks that
+ // failed during this pass.
+ %failedDatablocks = 0;
+
+ // Try re-executing the list of datablock files.
+ %count = %datablockFiles.count();
+ for ( %i=0; %i < %count; %i++ )
+ {
+ %file = %datablockFiles.getKey( %i );
+ if ( !isFile(%file @ ".dso") && !isFile(%file) )
+ continue;
+
+ // Start counting copy constructor creation errors.
+ $Con::objectCopyFailures = 0;
+
+ exec( %file );
+
+ // If errors occured then store this file for re-exec later.
+ if ( $Con::objectCopyFailures > 0 )
+ {
+ %reloadDatablockFiles.add( %file );
+ %failedDatablocks = %failedDatablocks + $Con::objectCopyFailures;
+ }
+ }
+
+ // Clear the object copy failure counter so that
+ // we get console error messages again.
+ $Con::objectCopyFailures = -1;
+
+ // Delete the old incoming list... we're done with it.
+ //%datablockFiles.delete();
+
+ // If we still have datablocks to retry.
+ %newCount = %reloadDatablockFiles.count();
+ if ( %newCount > 0 )
+ {
+ // If the datablock failures have not been reduced
+ // from the last pass then we must have a real syntax
+ // error and not just a bad dependancy.
+ if ( %previousErrors > %failedDatablocks )
+ recursiveLoadDatablockFiles( %reloadDatablockFiles, %failedDatablocks );
+
+ else
+ {
+ // Since we must have real syntax errors do one
+ // last normal exec to output error messages.
+ loadDatablockFiles( %reloadDatablockFiles, false );
+ }
+
+ return;
+ }
+
+ // Cleanup the empty reload list.
+ %reloadDatablockFiles.delete();
+}
+
+function getUserPath()
+{
+ %temp = getUserHomeDirectory();
+ echo(%temp);
+ if(!isDirectory(%temp))
+ {
+ %temp = getUserDataDirectory();
+ echo(%temp);
+ if(!isDirectory(%temp))
+ {
+ %userPath = "data";
+ }
+ else
+ {
+ //put it in appdata/roaming
+ %userPath = %temp @ "/" @ $appName;
+ }
+ }
+ else
+ {
+ //put it in user/documents
+ %userPath = %temp @ "/" @ $appName;
+ }
+ return %userPath;
+}
+
+function getPrefpath()
+{
+ $prefPath = getUserPath() @ "/preferences";
+ return $prefPath;
+}
+
+function updateTSShapeLoadProgress(%progress, %msg)
+{
+ // Check if the loading GUI is visible and use that instead of the
+ // separate import progress GUI if possible
+ /* if ( isObject(LoadingGui) && LoadingGui.isAwake() )
+ {
+ // Save/Restore load progress at the start/end of the import process
+ if ( %progress == 0 )
+ {
+ ColladaImportProgress.savedProgress = LoadingProgress.getValue();
+ ColladaImportProgress.savedText = LoadingProgressTxt.getValue();
+
+ ColladaImportProgress.msgPrefix = "Importing " @ %msg;
+ %msg = "Reading file into memory...";
+ }
+ else if ( %progress == 1.0 )
+ {
+ LoadingProgress.setValue( ColladaImportProgress.savedProgress );
+ LoadingProgressTxt.setValue( ColladaImportProgress.savedText );
+ }
+
+ %msg = ColladaImportProgress.msgPrefix @ ": " @ %msg;
+
+ %progressCtrl = LoadingProgress;
+ %textCtrl = LoadingProgressTxt;
+ }
+ else
+ {
+ //it's probably the editors using it
+ if(isFunction("updateToolTSShapeLoadProgress"))
+ {
+ updateToolTSShapeLoadProgress(%progress, %msg);
+ }
+ }
+
+ // Update progress indicators
+ if (%progress == 0)
+ {
+ %progressCtrl.setValue(0.001);
+ %textCtrl.setText(%msg);
+ }
+ else if (%progress != 1.0)
+ {
+ %progressCtrl.setValue(%progress);
+ %textCtrl.setText(%msg);
+ }
+
+ Canvas.repaint(33);*/
+}
+
+/// A helper function which will return the ghosted client object
+/// from a server object when connected to a local server.
+function serverToClientObject( %serverObject )
+{
+ assert( isObject( LocalClientConnection ), "serverToClientObject() - No local client connection found!" );
+ assert( isObject( ServerConnection ), "serverToClientObject() - No server connection found!" );
+
+ %ghostId = LocalClientConnection.getGhostId( %serverObject );
+ if ( %ghostId == -1 )
+ return 0;
+
+ return ServerConnection.resolveGhostID( %ghostId );
+}
+
+//----------------------------------------------------------------------------
+// Debug commands
+//----------------------------------------------------------------------------
+
+function netSimulateLag( %msDelay, %packetLossPercent )
+{
+ if ( %packetLossPercent $= "" )
+ %packetLossPercent = 0;
+
+ commandToServer( 'NetSimulateLag', %msDelay, %packetLossPercent );
+}
+
+//Various client functions
+
+function validateDatablockName(%name)
+{
+ // remove whitespaces at beginning and end
+ %name = trim( %name );
+
+ // remove numbers at the beginning
+ %numbers = "0123456789";
+ while( strlen(%name) > 0 )
+ {
+ // the first character
+ %firstChar = getSubStr( %name, 0, 1 );
+ // if the character is a number remove it
+ if( strpos( %numbers, %firstChar ) != -1 )
+ {
+ %name = getSubStr( %name, 1, strlen(%name) -1 );
+ %name = ltrim( %name );
+ }
+ else
+ break;
+ }
+
+ // replace whitespaces with underscores
+ %name = strreplace( %name, " ", "_" );
+
+ // remove any other invalid characters
+ %invalidCharacters = "-+*/%$&§=()[].?\"#,;!~<>|°^{}";
+ %name = stripChars( %name, %invalidCharacters );
+
+ if( %name $= "" )
+ %name = "Unnamed";
+
+ return %name;
+}
+
+//--------------------------------------------------------------------------
+// Finds location of %word in %text, starting at %start. Works just like strPos
+//--------------------------------------------------------------------------
+
+function wordPos(%text, %word, %start)
+{
+ if (%start $= "") %start = 0;
+
+ if (strpos(%text, %word, 0) == -1) return -1;
+ %count = getWordCount(%text);
+ if (%start >= %count) return -1;
+ for (%i = %start; %i < %count; %i++)
+ {
+ if (getWord( %text, %i) $= %word) return %i;
+ }
+ return -1;
+}
+
+//--------------------------------------------------------------------------
+// Finds location of %field in %text, starting at %start. Works just like strPos
+//--------------------------------------------------------------------------
+
+function fieldPos(%text, %field, %start)
+{
+ if (%start $= "") %start = 0;
+
+ if (strpos(%text, %field, 0) == -1) return -1;
+ %count = getFieldCount(%text);
+ if (%start >= %count) return -1;
+ for (%i = %start; %i < %count; %i++)
+ {
+ if (getField( %text, %i) $= %field) return %i;
+ }
+ return -1;
+}
+
+//--------------------------------------------------------------------------
+// returns the text in a file with "\n" at the end of each line
+//--------------------------------------------------------------------------
+
+function loadFileText( %file)
+{
+ %fo = new FileObject();
+ %fo.openForRead(%file);
+ %text = "";
+ while(!%fo.isEOF())
+ {
+ %text = %text @ %fo.readLine();
+ if (!%fo.isEOF()) %text = %text @ "\n";
+ }
+
+ %fo.delete();
+ return %text;
+}
+
+function setValueSafe(%dest, %val)
+{
+ %cmd = %dest.command;
+ %alt = %dest.altCommand;
+ %dest.command = "";
+ %dest.altCommand = "";
+
+ %dest.setValue(%val);
+
+ %dest.command = %cmd;
+ %dest.altCommand = %alt;
+}
+
+function shareValueSafe(%source, %dest)
+{
+ setValueSafe(%dest, %source.getValue());
+}
+
+function shareValueSafeDelay(%source, %dest, %delayMs)
+{
+ schedule(%delayMs, 0, shareValueSafe, %source, %dest);
+}
+
+
+//------------------------------------------------------------------------------
+// An Aggregate Control is a plain GuiControl that contains other controls,
+// which all share a single job or represent a single value.
+//------------------------------------------------------------------------------
+
+// AggregateControl.setValue( ) propagates the value to any control that has an
+// internal name.
+function AggregateControl::setValue(%this, %val, %child)
+{
+ for(%i = 0; %i < %this.getCount(); %i++)
+ {
+ %obj = %this.getObject(%i);
+ if( %obj == %child )
+ continue;
+
+ if(%obj.internalName !$= "")
+ setValueSafe(%obj, %val);
+ }
+}
+
+// AggregateControl.getValue() uses the value of the first control that has an
+// internal name, if it has not cached a value via .setValue
+function AggregateControl::getValue(%this)
+{
+ for(%i = 0; %i < %this.getCount(); %i++)
+ {
+ %obj = %this.getObject(%i);
+ if(%obj.internalName !$= "")
+ {
+ //error("obj = " @ %obj.getId() @ ", " @ %obj.getName() @ ", " @ %obj.internalName );
+ //error(" value = " @ %obj.getValue());
+ return %obj.getValue();
+ }
+ }
+}
+
+// AggregateControl.updateFromChild( ) is called by child controls to propagate
+// a new value, and to trigger the onAction() callback.
+function AggregateControl::updateFromChild(%this, %child)
+{
+ %val = %child.getValue();
+ if(%val == mCeil(%val)){
+ %val = mCeil(%val);
+ }else{
+ if ( %val <= -100){
+ %val = mCeil(%val);
+ }else if ( %val <= -10){
+ %val = mFloatLength(%val, 1);
+ }else if ( %val < 0){
+ %val = mFloatLength(%val, 2);
+ }else if ( %val >= 1000){
+ %val = mCeil(%val);
+ }else if ( %val >= 100){
+ %val = mFloatLength(%val, 1);
+ }else if ( %val >= 10){
+ %val = mFloatLength(%val, 2);
+ }else if ( %val > 0){
+ %val = mFloatLength(%val, 3);
+ }
+ }
+ %this.setValue(%val, %child);
+ %this.onAction();
+}
+
+// default onAction stub, here only to prevent console spam warnings.
+function AggregateControl::onAction(%this)
+{
+}
+
+// call a method on all children that have an internalName and that implement the method.
+function AggregateControl::callMethod(%this, %method, %args)
+{
+ for(%i = 0; %i < %this.getCount(); %i++)
+ {
+ %obj = %this.getObject(%i);
+ if(%obj.internalName !$= "" && %obj.isMethod(%method))
+ eval(%obj @ "." @ %method @ "( " @ %args @ " );");
+ }
+
+}
+
+//------------------------------------------------------------------------------
+// Altered Version of TGB's QuickEditDropDownTextEditCtrl
+//------------------------------------------------------------------------------
+function QuickEditDropDownTextEditCtrl::onRenameItem( %this )
+{
+}
+
+function QuickEditDropDownTextEditCtrl::updateFromChild( %this, %ctrl )
+{
+ if( %ctrl.internalName $= "PopUpMenu" )
+ {
+ %this->TextEdit.setText( %ctrl.getText() );
+ }
+ else if ( %ctrl.internalName $= "TextEdit" )
+ {
+ %popup = %this->PopupMenu;
+ %popup.changeTextById( %popup.getSelected(), %ctrl.getText() );
+ %this.onRenameItem();
+ }
+}
+
+// Writes out all script functions to a file.
+function writeOutFunctions()
+{
+ new ConsoleLogger(logger, "scriptFunctions.txt", false);
+ dumpConsoleFunctions();
+ logger.delete();
+}
+
+// Writes out all script classes to a file.
+function writeOutClasses()
+{
+ new ConsoleLogger(logger, "scriptClasses.txt", false);
+ dumpConsoleClasses();
+ logger.delete();
+}
+
+//
+function compileFiles(%pattern)
+{
+ %path = filePath(%pattern);
+
+ %saveDSO = $Scripts::OverrideDSOPath;
+ %saveIgnore = $Scripts::ignoreDSOs;
+
+ $Scripts::OverrideDSOPath = %path;
+ $Scripts::ignoreDSOs = false;
+ %mainCsFile = makeFullPath("main.cs");
+
+ for (%file = findFirstFileMultiExpr(%pattern); %file !$= ""; %file = findNextFileMultiExpr(%pattern))
+ {
+ // we don't want to try and compile the primary main.cs
+ if(%mainCsFile !$= %file)
+ compile(%file, true);
+ }
+
+ $Scripts::OverrideDSOPath = %saveDSO;
+ $Scripts::ignoreDSOs = %saveIgnore;
+
+}
+
+function displayHelp()
+{
+ // Notes on logmode: console logging is written to console.log.
+ // -log 0 disables console logging.
+ // -log 1 appends to existing logfile; it also closes the file
+ // (flushing the write buffer) after every write.
+ // -log 2 overwrites any existing logfile; it also only closes
+ // the logfile when the application shuts down. (default)
+
+ error(
+ "Torque Demo command line options:\n"@
+ " -log Logging behavior; see main.cs comments for details\n"@
+ " -game Reset list of mods to only contain \n"@
+ " Works like the -game argument\n"@
+ " -dir Add to list of directories\n"@
+ " -console Open a separate console\n"@
+ " -jSave Record a journal\n"@
+ " -jPlay Play back a journal\n"@
+ " -help Display this help message\n"
+ );
+}
+
+// Execute startup scripts for each mod, starting at base and working up
+function loadDir(%dir)
+{
+ pushback($userDirs, %dir, ";");
+
+ if (isScriptFile(%dir @ "/main.cs"))
+ exec(%dir @ "/main.cs");
+}
+
+function loadDirs(%dirPath)
+{
+ %dirPath = nextToken(%dirPath, token, ";");
+ if (%dirPath !$= "")
+ loadDirs(%dirPath);
+
+ if(exec(%token @ "/main.cs") != true)
+ {
+ error("Error: Unable to find specified directory: " @ %token );
+ $dirCount--;
+ }
+}
+
+//------------------------------------------------------------------------------
+// Utility remap functions:
+//------------------------------------------------------------------------------
+
+function ActionMap::copyBind( %this, %otherMap, %command )
+{
+ if ( !isObject( %otherMap ) )
+ {
+ error( "ActionMap::copyBind - \"" @ %otherMap @ "\" is not an object!" );
+ return;
+ }
+
+ %bind = %otherMap.getBinding( %command );
+ if ( %bind !$= "" )
+ {
+ %device = getField( %bind, 0 );
+ %action = getField( %bind, 1 );
+ %flags = %otherMap.isInverted( %device, %action ) ? "SDI" : "SD";
+ %deadZone = %otherMap.getDeadZone( %device, %action );
+ %scale = %otherMap.getScale( %device, %action );
+ %this.bind( %device, %action, %flags, %deadZone, %scale, %command );
+ }
+}
+
+//------------------------------------------------------------------------------
+function ActionMap::blockBind( %this, %otherMap, %command )
+{
+ if ( !isObject( %otherMap ) )
+ {
+ error( "ActionMap::blockBind - \"" @ %otherMap @ "\" is not an object!" );
+ return;
+ }
+
+ %bind = %otherMap.getBinding( %command );
+ if ( %bind !$= "" )
+ %this.bind( getField( %bind, 0 ), getField( %bind, 1 ), "" );
+}
+
+//Dev helpers
+/// Shortcut for typing dbgSetParameters with the default values torsion uses.
+function dbgTorsion()
+{
+ dbgSetParameters( 6060, "password", false );
+}
+
+/// Reset the input state to a default of all-keys-up.
+/// A helpful remedy for when Torque misses a button up event do to your breakpoints
+/// and can't stop shooting / jumping / strafing.
+function mvReset()
+{
+ for ( %i = 0; %i < 6; %i++ )
+ setVariable( "mvTriggerCount" @ %i, 0 );
+
+ $mvUpAction = 0;
+ $mvDownAction = 0;
+ $mvLeftAction = 0;
+ $mvRightAction = 0;
+
+ // There are others.
+}
+
+//Persistance Manager tests
+
+new PersistenceManager(TestPManager);
+
+function runPManTest(%test)
+{
+ if (!isObject(TestPManager))
+ return;
+
+ if (%test $= "")
+ %test = 100;
+
+ switch(%test)
+ {
+ case 0:
+ TestPManager.testFieldUpdates();
+ case 1:
+ TestPManager.testObjectRename();
+ case 2:
+ TestPManager.testNewObject();
+ case 3:
+ TestPManager.testNewGroup();
+ case 4:
+ TestPManager.testMoveObject();
+ case 5:
+ TestPManager.testObjectRemove();
+ case 100:
+ TestPManager.testFieldUpdates();
+ TestPManager.testObjectRename();
+ TestPManager.testNewObject();
+ TestPManager.testNewGroup();
+ TestPManager.testMoveObject();
+ TestPManager.testObjectRemove();
+ }
+}
+
+function TestPManager::testFieldUpdates(%doNotSave)
+{
+ // Set some objects as dirty
+ TestPManager.setDirty(AudioGui);
+ TestPManager.setDirty(AudioSim);
+ TestPManager.setDirty(AudioMessage);
+
+ // Alter some of the existing fields
+ AudioEffect.isLooping = true;
+ AudioMessage.isLooping = true;
+ AudioEffect.is3D = true;
+
+ // Test removing a field
+ TestPManager.removeField(AudioGui, "isLooping");
+
+ // Alter some of the persistent fields
+ AudioGui.referenceDistance = 0.8;
+ AudioMessage.referenceDistance = 0.8;
+
+ // Add some new dynamic fields
+ AudioGui.foo = "bar";
+ AudioEffect.foo = "bar";
+
+ // Remove an object from the dirty list
+ // It shouldn't get updated in the file
+ TestPManager.removeDirty(AudioEffect);
+
+ // Dirty an object in another file as well
+ TestPManager.setDirty(WarningMaterial);
+
+ // Update a field that doesn't exist
+ WarningMaterial.glow[0] = true;
+
+ // Drity another object to test for crashes
+ // when a dirty object is deleted
+ TestPManager.setDirty(SFXPausedSet);
+
+ // Delete the object
+ SFXPausedSet.delete();
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+}
+
+function TestPManager::testObjectRename(%doNotSave)
+{
+ // Flag an object as dirty
+ if (isObject(AudioGui))
+ TestPManager.setDirty(AudioGui);
+ else if (isObject(AudioGuiFoo))
+ TestPManager.setDirty(AudioGuiFoo);
+
+ // Rename it
+ if (isObject(AudioGui))
+ AudioGui.setName(AudioGuiFoo);
+ else if (isObject(AudioGuiFoo))
+ AudioGuiFoo.setName(AudioGui);
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+}
+
+function TestPManager::testNewObject(%doNotSave)
+{
+ // Test adding a new named object
+ new SFXDescription(AudioNew)
+ {
+ volume = 0.5;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 2;
+ };
+
+ // Flag it as dirty
+ TestPManager.setDirty(AudioNew, "core/scripts/client/audio.cs");
+
+ // Test adding a new unnamed object
+ %obj = new SFXDescription()
+ {
+ volume = 0.75;
+ isLooping = true;
+ bar = 3;
+ };
+
+ // Flag it as dirty
+ TestPManager.setDirty(%obj, "core/scripts/client/audio.cs");
+
+ // Test adding an "empty" object
+ new SFXDescription(AudioEmpty);
+
+ TestPManager.setDirty(AudioEmpty, "core/scripts/client/audio.cs");
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+}
+
+function TestPManager::testNewGroup(%doNotSave)
+{
+ // Test adding a new named SimGroup
+ new SimGroup(TestGroup)
+ {
+ foo = "bar";
+
+ new SFXDescription(TestObject)
+ {
+ volume = 0.5;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 1;
+ };
+ new SimGroup(SubGroup)
+ {
+ foo = 2;
+
+ new SFXDescription(SubObject)
+ {
+ volume = 0.5;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 3;
+ };
+ };
+ };
+
+ // Flag this as dirty
+ TestPManager.setDirty(TestGroup, "core/scripts/client/audio.cs");
+
+ // Test adding a new unnamed SimGroup
+ %group = new SimGroup()
+ {
+ foo = "bar";
+
+ new SFXDescription()
+ {
+ volume = 0.75;
+ channel = $GuiAudioType;
+ foo = 4;
+ };
+ new SimGroup()
+ {
+ foo = 5;
+
+ new SFXDescription()
+ {
+ volume = 0.75;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 6;
+ };
+ };
+ };
+
+ // Flag this as dirty
+ TestPManager.setDirty(%group, "core/scripts/client/audio.cs");
+
+ // Test adding a new unnamed SimSet
+ %set = new SimSet()
+ {
+ foo = "bar";
+
+ new SFXDescription()
+ {
+ volume = 0.75;
+ channel = $GuiAudioType;
+ foo = 7;
+ };
+ new SimGroup()
+ {
+ foo = 8;
+
+ new SFXDescription()
+ {
+ volume = 0.75;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 9;
+ };
+ };
+ };
+
+ // Flag this as dirty
+ TestPManager.setDirty(%set, "core/scripts/client/audio.cs");
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+}
+
+function TestPManager::testMoveObject(%doNotSave)
+{
+ // First add a couple of groups to the file
+ new SimGroup(MoveGroup1)
+ {
+ foo = "bar";
+
+ new SFXDescription(MoveObject1)
+ {
+ volume = 0.5;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 1;
+ };
+
+ new SimSet(SubGroup1)
+ {
+ new SFXDescription(SubObject1)
+ {
+ volume = 0.75;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 2;
+ };
+ };
+ };
+
+ // Flag this as dirty
+ TestPManager.setDirty(MoveGroup1, "core/scripts/client/audio.cs");
+
+ new SimGroup(MoveGroup2)
+ {
+ foo = "bar";
+
+ new SFXDescription(MoveObject2)
+ {
+ volume = 0.5;
+ isLooping = true;
+ channel = $GuiAudioType;
+ foo = 3;
+ };
+ };
+
+ // Flag this as dirty
+ TestPManager.setDirty(MoveGroup2, "core/scripts/client/audio.cs");
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+
+ // Set them as dirty again
+ TestPManager.setDirty(MoveGroup1);
+ TestPManager.setDirty(MoveGroup2);
+
+ // Give the subobject an new value
+ MoveObject1.foo = 4;
+
+ // Move it into the other group
+ MoveGroup1.add(MoveObject2);
+
+ // Switch the other subobject
+ MoveGroup2.add(MoveObject1);
+
+ // Also add a new unnamed object to one of the groups
+ %obj = new SFXDescription()
+ {
+ volume = 0.75;
+ isLooping = true;
+ bar = 5;
+ };
+
+ MoveGroup1.add(%obj);
+
+ // Unless %doNotSave is set (by a batch/combo test)
+ // then go ahead and save now
+ if (!%doNotSave)
+ TestPManager.saveDirty();
+}
+
+function TestPManager::testObjectRemove(%doNotSave)
+{
+ TestPManager.removeObjectFromFile(AudioSim);
+}
+
+//Game Object management
+function findGameObject(%name)
+{
+ //find all GameObjectAssets
+ %assetQuery = new AssetQuery();
+ if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset"))
+ return 0; //if we didn't find ANY, just exit
+
+ %count = %assetQuery.getCount();
+
+ for(%i=0; %i < %count; %i++)
+ {
+ %assetId = %assetQuery.getAsset(%i);
+
+ //%assetName = AssetDatabase.getAssetName(%assetId);
+
+ if(%assetId $= %name)
+ {
+ %gameObjectAsset = AssetDatabase.acquireAsset(%assetId);
+
+ %assetQuery.delete();
+ return %gameObjectAsset;
+ }
+ }
+
+ %assetQuery.delete();
+ return 0;
+}
+
+function spawnGameObject(%name, %addToMissionGroup)
+{
+ if(%addToMissionGroup $= "")
+ %addToMissionGroup = true;
+
+ //First, check if this already exists in our GameObjectPool
+ if(isObject(GameObjectPool))
+ {
+ %goCount = GameObjectPool.countKey(%name);
+
+ //if we have some already in the pool, pull it out and use that
+ if(%goCount != 0)
+ {
+ %goIdx = GameObjectPool.getIndexFromKey(%name);
+ %go = GameObjectPool.getValue(%goIdx);
+
+ %go.setHidden(false);
+ %go.setScopeAlways();
+
+ if(%addToMissionGroup == true) //save instance when saving level
+ MissionGroup.add(%go);
+ else // clear instance on level exit
+ MissionCleanup.add(%go);
+
+ //remove from the object pool's list
+ GameObjectPool.erase(%goIdx);
+
+ return %go;
+ }
+ }
+
+ //We have no existing pool, or no existing game objects of this type, so spawn a new one
+
+ %gameObjectAsset = findGameObject(%name);
+
+ if(isObject(%gameObjectAsset))
+ {
+ %newSGOObject = TamlRead(%gameObjectAsset.TAMLFilePath);
+
+ if(%addToMissionGroup == true) //save instance when saving level
+ MissionGroup.add(%newSGOObject);
+ else // clear instance on level exit
+ MissionCleanup.add(%newSGOObject);
+
+ return %newSGOObject;
+ }
+
+ return 0;
+}
+
+function saveGameObject(%name, %tamlPath, %scriptPath)
+{
+ %gameObjectAsset = findGameObject(%name);
+
+ //find if it already exists. If it does, we'll update it, if it does not, we'll make a new asset
+ if(isObject(%gameObjectAsset))
+ {
+ %assetID = %gameObjectAsset.getAssetId();
+
+ %gameObjectAsset.TAMLFilePath = %tamlPath;
+ %gameObjectAsset.scriptFilePath = %scriptPath;
+
+ TAMLWrite(%gameObjectAsset, AssetDatabase.getAssetFilePath(%assetID));
+ AssetDatabase.refreshAsset(%assetID);
+ }
+ else
+ {
+ //Doesn't exist, so make a new one
+ %gameObjectAsset = new GameObjectAsset()
+ {
+ assetName = %name @ "Asset";
+ gameObjectName = %name;
+ TAMLFilePath = %tamlPath;
+ scriptFilePath = %scriptPath;
+ };
+
+ //Save it alongside the taml file
+ %path = filePath(%tamlPath);
+
+ TAMLWrite(%gameObjectAsset, %path @ "/" @ %name @ ".asset.taml");
+ AssetDatabase.refreshAllAssets(true);
+ }
+}
+
+//Allocates a number of a game object into a pool to be pulled from as needed
+function allocateGameObjects(%name, %amount)
+{
+ //First, we need to make sure our pool exists
+ if(!isObject(GameObjectPool))
+ {
+ new ArrayObject(GameObjectPool);
+ }
+
+ //Next, we loop and generate our game objects, and add them to the pool
+ for(%i=0; %i < %amount; %i++)
+ {
+ %go = spawnGameObject(%name, false);
+
+ //When our object is in the pool, it's not "real", so we need to make sure
+ //that we don't ghost it to clients untill we actually spawn it.
+ %go.clearScopeAlways();
+
+ //We also hide it, so that we don't 'exist' in the scene until we spawn
+ %go.hidden = true;
+
+ //Lastly, add us to the pool, with the key being our game object type
+ GameObjectPool.add(%name, %go);
+ }
+}
+
+function Entity::delete(%this)
+{
+ //we want to intercept the delete call, and add it to our GameObjectPool
+ //if it's a game object
+ if(%this.gameObjectAsset !$= "")
+ {
+ %this.setHidden(true);
+ %this.clearScopeAlways();
+
+ if(!isObject(GameObjectPool))
+ {
+ new ArrayObject(GameObjectPool);
+ }
+
+ GameObjectPool.add(%this.gameObjectAsset, %this);
+
+ %missionSet = %this.getGroup();
+ %missionSet.remove(%this);
+ }
+ else
+ {
+ %this.superClass.delete();
+ }
+}
+
+function clearGameObjectPool()
+{
+ if(isObject(GameObjectPool))
+ {
+ %count = GameObjectPool.count();
+
+ for(%i=0; %i < %count; %i++)
+ {
+ %go = GameObjectPool.getValue(%i);
+
+ %go.superClass.delete();
+ }
+
+ GameObjectPool.empty();
+ }
+}
+
+//
+function switchCamera(%client, %newCamEntity)
+{
+ if(!isObject(%client) || !isObject(%newCamEntity))
+ return error("SwitchCamera: No client or target camera!");
+
+ %cam = %newCamEntity.getComponent(CameraComponent);
+
+ if(!isObject(%cam))
+ return error("SwitchCamera: Target camera doesn't have a camera behavior!");
+
+ //TODO: Cleanup clientOwner for previous camera!
+ if(%cam.clientOwner == 0 || %cam.clientOwner $= "")
+ %cam.clientOwner = 0;
+
+ %cam.scopeToClient(%client);
+ %cam.setDirty();
+
+ %client.setCameraObject(%newCamEntity);
+ %client.setControlCameraFov(%cam.FOV);
+
+ %client.camera = %newCamEntity;
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/utility/scripts/parseArgs.cs b/Templates/BaseGame/game/core/utility/scripts/parseArgs.cs
new file mode 100644
index 000000000..811cee00c
--- /dev/null
+++ b/Templates/BaseGame/game/core/utility/scripts/parseArgs.cs
@@ -0,0 +1,392 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// Support functions used to manage the directory list
+function pushFront(%list, %token, %delim)
+{
+ if (%list !$= "")
+ return %token @ %delim @ %list;
+ return %token;
+}
+
+function pushBack(%list, %token, %delim)
+{
+ if (%list !$= "")
+ return %list @ %delim @ %token;
+ return %token;
+}
+
+function popFront(%list, %delim)
+{
+ return nextToken(%list, unused, %delim);
+}
+
+function parseArgs()
+{
+ for ($i = 1; $i < $Game::argc ; $i++)
+ {
+ $arg = $Game::argv[$i];
+ $nextArg = $Game::argv[$i+1];
+ $hasNextArg = $Game::argc - $i > 1;
+ $logModeSpecified = false;
+
+ // Check for dedicated run
+ /*if( stricmp($arg,"-dedicated") == 0 )
+ {
+ $userDirs = $defaultGame;
+ $dirCount = 1;
+ $isDedicated = true;
+ }*/
+
+ switch$ ($arg)
+ {
+ //--------------------
+ case "-dedicated":
+ $userDirs = $defaultGame;
+ $dirCount = 1;
+ $isDedicated = true;
+ $Server::Dedicated = true;
+ enableWinConsole(true);
+ $argUsed[%i]++;
+
+ //--------------------
+ case "-mission":
+ $argUsed[%i]++;
+ if ($hasNextArg)
+ {
+ $missionArg = $nextArg;
+ $argUsed[%i+1]++;
+ %i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -mission ");
+
+ //--------------------
+ case "-connect":
+ $argUsed[%i]++;
+ if ($hasNextArg)
+ {
+ $JoinGameAddress = $nextArg;
+ $argUsed[%i+1]++;
+ %i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -connect ");
+
+
+ //--------------------
+ case "-log":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ // Turn on console logging
+ if ($nextArg != 0)
+ {
+ // Dump existing console to logfile first.
+ $nextArg += 4;
+ }
+ setLogMode($nextArg);
+ $logModeSpecified = true;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -log ");
+
+ //--------------------
+ case "-dir":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ // Append the mod to the end of the current list
+ $userDirs = strreplace($userDirs, $nextArg, "");
+ $userDirs = pushFront($userDirs, $nextArg, ";");
+ $argUsed[$i+1]++;
+ $i++;
+ $dirCount++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -dir ");
+
+ //--------------------
+ // changed the default behavior of this command line arg. It now
+ // defaults to ONLY loading the game, not tools
+ // default auto-run already loads in tools --SRZ 11/29/07
+ case "-game":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ // Set the selected dir --NOTE: we no longer allow tools with this argument
+ /*
+ if( $isDedicated )
+ {
+ $userDirs = $nextArg;
+ $dirCount = 1;
+ }
+ else
+ {
+ $userDirs = "tools;" @ $nextArg;
+ $dirCount = 2;
+ }
+ */
+ $userDirs = $nextArg;
+ $dirCount = 1;
+ $argUsed[$i+1]++;
+ $i++;
+ error($userDirs);
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -game ");
+
+ //--------------------
+ case "-console":
+ enableWinConsole(true);
+ $argUsed[$i]++;
+
+ //--------------------
+ case "-jSave":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ echo("Saving event log to journal: " @ $nextArg);
+ saveJournal($nextArg);
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -jSave ");
+
+ //--------------------
+ case "-jPlay":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ playJournal($nextArg);
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -jPlay ");
+
+ //--------------------
+ case "-jPlayToVideo":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $VideoCapture::journalName = $nextArg;
+ $VideoCapture::captureFromJournal = true;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -jPlayToVideo ");
+
+ //--------------------
+ case "-vidCapFile":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $VideoCapture::fileName = $nextArg;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -vidCapFile ");
+
+ //--------------------
+ case "-vidCapFPS":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $VideoCapture::fps = $nextArg;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -vidCapFPS ");
+
+ //--------------------
+ case "-vidCapEncoder":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $VideoCapture::encoder = $nextArg;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -vidCapEncoder ");
+
+ //--------------------
+ case "-vidCapWidth":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $videoCapture::width = $nextArg;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -vidCapWidth ");
+
+ //--------------------
+ case "-vidCapHeight":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ $videoCapture::height = $nextArg;
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -vidCapHeight ");
+
+ //--------------------
+ case "-level":
+ $argUsed[$i]++;
+ if ($hasNextArg)
+ {
+ %hasExt = strpos($nextArg, ".mis");
+ if(%hasExt == -1)
+ {
+ $levelToLoad = $nextArg @ " ";
+
+ for(%i = $i + 2; %i < $Game::argc; %i++)
+ {
+ $arg = $Game::argv[%i];
+ %hasExt = strpos($arg, ".mis");
+
+ if(%hasExt == -1)
+ {
+ $levelToLoad = $levelToLoad @ $arg @ " ";
+ } else
+ {
+ $levelToLoad = $levelToLoad @ $arg;
+ break;
+ }
+ }
+ }
+ else
+ {
+ $levelToLoad = $nextArg;
+ }
+
+ $argUsed[$i+1]++;
+ $i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -level ");
+
+ //-------------------
+ case "-worldeditor":
+ $startWorldEditor = true;
+ $argUsed[$i]++;
+
+ //-------------------
+ case "-guieditor":
+ $startGUIEditor = true;
+ $argUsed[$i]++;
+
+ //-------------------
+ case "-help":
+ $displayHelp = true;
+ $argUsed[$i]++;
+
+ //-------------------
+ case "-compileAll":
+ $compileAll = true;
+ $argUsed[$i]++;
+
+ //-------------------
+ case "-compileTools":
+ $compileTools = true;
+ $argUsed[$i]++;
+
+ //-------------------
+ case "-genScript":
+ $genScript = true;
+ $argUsed[$i]++;
+
+ case "-fullscreen":
+ $cliFullscreen = true;
+ $argUsed[%i]++;
+
+ case "-windowed":
+ $cliFullscreen = false;
+ $argUsed[%i]++;
+
+ case "-openGL":
+ $pref::Video::displayDevice = "OpenGL";
+ $argUsed[%i]++;
+
+ case "-directX":
+ $pref::Video::displayDevice = "D3D";
+ $argUsed[%i]++;
+
+ case "-autoVideo":
+ $pref::Video::displayDevice = "";
+ $argUsed[%i]++;
+
+ case "-prefs":
+ $argUsed[%i]++;
+ if ($hasNextArg) {
+ exec($nextArg, true, true);
+ $argUsed[%i+1]++;
+ %i++;
+ }
+ else
+ error("Error: Missing Command Line argument. Usage: -prefs ");
+
+
+ //-------------------
+ default:
+ $argUsed[$i]++;
+ if($userDirs $= "")
+ $userDirs = $arg;
+ }
+ }
+
+ //-----------------------------------------------
+ // Play journal to video file?
+ if ($VideoCapture::captureFromJournal && $VideoCapture::journalName !$= "")
+ {
+ if ($VideoCapture::fileName $= "")
+ $VideoCapture::fileName = $VideoCapture::journalName;
+
+ if ($VideoCapture::encoder $= "")
+ $VideoCapture::encoder = "THEORA";
+
+ if ($VideoCapture::fps $= "")
+ $VideoCapture::fps = 30;
+
+ if ($videoCapture::width $= "")
+ $videoCapture::width = 0;
+
+ if ($videoCapture::height $= "")
+ $videoCapture::height = 0;
+
+ playJournalToVideo( $VideoCapture::journalName, $VideoCapture::fileName,
+ $VideoCapture::encoder, $VideoCapture::fps,
+ $videoCapture::width SPC $videoCapture::height );
+ }
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/vr/Core_VR.cs b/Templates/BaseGame/game/core/vr/Core_VR.cs
new file mode 100644
index 000000000..42b2df7e0
--- /dev/null
+++ b/Templates/BaseGame/game/core/vr/Core_VR.cs
@@ -0,0 +1,9 @@
+
+function Core_VR::onCreate(%this)
+{
+ exec("./scripts/oculusVR.cs");
+}
+
+function Core_VR::onDestroy(%this)
+{
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/vr/Core_VR.module b/Templates/BaseGame/game/core/vr/Core_VR.module
new file mode 100644
index 000000000..960a5a85a
--- /dev/null
+++ b/Templates/BaseGame/game/core/vr/Core_VR.module
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/Templates/BaseGame/game/core/vr/guis/oculusVROverlay.gui b/Templates/BaseGame/game/core/vr/guis/oculusVROverlay.gui
new file mode 100644
index 000000000..62a9f719c
--- /dev/null
+++ b/Templates/BaseGame/game/core/vr/guis/oculusVROverlay.gui
@@ -0,0 +1,19 @@
+//--- OBJECT WRITE BEGIN ---
+%guiContent = singleton GuiControl(OculusVROverlay) {
+ canSaveDynamicFields = "0";
+ Enabled = "1";
+ isContainer = "1";
+ Profile = "GuiContentProfile";
+ HorizSizing = "width";
+ VertSizing = "height";
+ Position = "0 0";
+ Extent = "512 512";
+ MinExtent = "8 8";
+ canSave = "1";
+ Visible = "1";
+ tooltipprofile = "GuiToolTipProfile";
+ hovertime = "1000";
+ useVariable = "0";
+ tile = "0";
+};
+//--- OBJECT WRITE END ---
diff --git a/Templates/BaseGame/game/core/vr/scripts/oculusVR.cs b/Templates/BaseGame/game/core/vr/scripts/oculusVR.cs
new file mode 100644
index 000000000..fa9562c18
--- /dev/null
+++ b/Templates/BaseGame/game/core/vr/scripts/oculusVR.cs
@@ -0,0 +1,248 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+// Only load these functions if an Oculus VR device is present
+if(!isFunction(isOculusVRDeviceActive))
+ return;
+
+function setupOculusActionMaps()
+{
+ if (isObject(OculusWarningMap))
+ return;
+
+ new ActionMap(OculusWarningMap);
+ new ActionMap(OculusCanvasMap);
+
+ OculusWarningMap.bind(keyboard, space, dismissOculusVRWarnings);
+
+ OculusCanvasMap.bind( mouse, xaxis, oculusYaw );
+ OculusCanvasMap.bind( mouse, yaxis, oculusPitch );
+ OculusCanvasMap.bind( mouse, button0, oculusClick );
+}
+
+function oculusYaw(%val)
+{
+ OculusCanvas.cursorNudge(%val * 0.10, 0);
+}
+
+function oculusPitch(%val)
+{
+ OculusCanvas.cursorNudge(0, %val * 0.10);
+}
+
+function oculusClick(%active)
+{
+ OculusCanvas.cursorClick(0, %active);
+}
+
+function GuiOffscreenCanvas::checkCursor(%this)
+{
+ %count = %this.getCount();
+ for(%i = 0; %i < %count; %i++)
+ {
+ %control = %this.getObject(%i);
+ if ((%control.noCursor $= "") || !%control.noCursor)
+ {
+ %this.cursorOn();
+ return true;
+ }
+ }
+ // If we get here, every control requested a hidden cursor, so we oblige.
+
+ %this.cursorOff();
+ return false;
+}
+
+function GuiOffscreenCanvas::pushDialog(%this, %ctrl, %layer, %center)
+{
+ Parent::pushDialog(%this, %ctrl, %layer, %center);
+ %cursorVisible = %this.checkCursor();
+
+ if (%cursorVisible)
+ {
+ echo("OffscreenCanvas visible");
+ OculusCanvasMap.pop();
+ OculusCanvasMap.push();
+ }
+ else
+ {
+ echo("OffscreenCanvas not visible");
+ OculusCanvasMap.pop();
+ }
+}
+
+function GuiOffscreenCanvas::popDialog(%this, %ctrl)
+{
+ Parent::popDialog(%this, %ctrl);
+ %cursorVisible = %this.checkCursor();
+
+ if (%cursorVisible)
+ {
+ echo("OffscreenCanvas visible");
+ OculusCanvasMap.pop();
+ OculusCanvasMap.push();
+ }
+ else
+ {
+ echo("OffscreenCanvas not visible");
+ OculusCanvasMap.pop();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+
+function oculusSensorMetricsCallback()
+{
+ return ovrDumpMetrics(0);
+}
+
+
+//-----------------------------------------------------------------------------
+function onOculusStatusUpdate(%status)
+{
+ $LastOculusTrackingState = %status;
+}
+
+//-----------------------------------------------------------------------------
+
+// Call this function from createCanvas() to have the Canvas attach itself
+// to the Rift's display. The Canvas' window will still open on the primary
+// display if that is different from the Rift, but it will move to the Rift
+// when it goes full screen. If the Rift is not connected then nothing
+// will happen.
+function pointCanvasToOculusVRDisplay()
+{
+ $pref::Video::displayOutputDevice = getOVRHMDDisplayDeviceName(0);
+}
+
+//-----------------------------------------------------------------------------
+
+// Call this function from GameConnection::initialControlSet() just before
+// your "Canvas.setContent(PlayGui);" call, or at any time you wish to switch
+// to a side-by-side rendering and the appropriate barrel distortion. This
+// will turn on side-by-side rendering and tell the GameConnection to use the
+// Rift as its display device.
+// Parameters:
+// %gameConnection - The client GameConnection instance
+// %trueStereoRendering - If true will enable stereo rendering with an eye
+// offset for each viewport. This will render each frame twice. If false
+// then a pseudo stereo rendering is done with only a single render per frame.
+function enableOculusVRDisplay(%gameConnection, %trueStereoRendering)
+{
+ setOVRHMDAsGameConnectionDisplayDevice(%gameConnection);
+ PlayGui.renderStyle = "stereo side by side";
+ setOptimalOVRCanvasSize(Canvas);
+
+ if (!isObject(OculusCanvas))
+ {
+ new GuiOffscreenCanvas(OculusCanvas) {
+ targetSize = "512 512";
+ targetName = "oculusCanvas";
+ dynamicTarget = true;
+ };
+ }
+
+ if (!isObject(OculusVROverlay))
+ {
+ exec("core/vr/guis/oculusVROverlay.gui");
+ }
+
+ OculusCanvas.setContent(OculusVROverlay);
+ OculusCanvas.setCursor(DefaultCursor);
+ PlayGui.setStereoGui(OculusCanvas);
+ OculusCanvas.setCursorPos("128 128");
+ OculusCanvas.cursorOff();
+ $GameCanvas = OculusCanvas;
+
+ %ext = Canvas.getExtent();
+ $OculusMouseScaleX = 512.0 / 1920.0;
+ $OculusMouseScaleY = 512.0 / 1060.0;
+
+ //$gfx::wireframe = true;
+ // Reset all sensors
+ ovrResetAllSensors();
+}
+
+// Call this function when ever you wish to turn off the stereo rendering
+// and barrel distortion for the Rift.
+function disableOculusVRDisplay(%gameConnection)
+{
+ OculusCanvas.popDialog();
+ OculusWarningMap.pop();
+ $GameCanvas = Canvas;
+
+ if (isObject(gameConnection))
+ {
+ %gameConnection.clearDisplayDevice();
+ }
+ PlayGui.renderStyle = "standard";
+}
+
+// Helper function to set the standard Rift control scheme. You could place
+// this function in GameConnection::initialControlSet() at the same time
+// you call enableOculusVRDisplay().
+function setStandardOculusVRControlScheme(%gameConnection)
+{
+ if($OculusVR::SimulateInput)
+ {
+ // We are simulating a HMD so allow the mouse and gamepad to control
+ // both yaw and pitch.
+ %gameConnection.setControlSchemeParameters(true, true, true);
+ }
+ else
+ {
+ // A HMD is connected so have the mouse and gamepad only add to yaw
+ %gameConnection.setControlSchemeParameters(true, true, false);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+// Helper function to set the resolution for the Rift.
+// Parameters:
+// %fullscreen - If true then the display will be forced to full screen. If
+// pointCanvasToOculusVRDisplay() was called before the Canvas was created, then
+// the full screen display will appear on the Rift.
+function setVideoModeForOculusVRDisplay(%fullscreen)
+{
+ %res = getOVRHMDResolution(0);
+ Canvas.setVideoMode(%res.x, %res.y, %fullscreen, 32, 4);
+}
+
+//-----------------------------------------------------------------------------
+
+// Reset all Oculus Rift sensors. This will make the Rift's current heading
+// be considered the origin.
+function resetOculusVRSensors()
+{
+ ovrResetAllSensors();
+}
+
+function dismissOculusVRWarnings(%value)
+{
+ //if (%value)
+ //{
+ ovrDismissWarnings();
+ OculusWarningMap.pop();
+ //}
+}
\ No newline at end of file
diff --git a/Templates/BaseGame/game/tools/levels/BlankRoom.postfxpreset.cs b/Templates/BaseGame/game/tools/levels/BlankRoom.postfxpreset.cs
index 8b616a84a..23a6c3ced 100644
--- a/Templates/BaseGame/game/tools/levels/BlankRoom.postfxpreset.cs
+++ b/Templates/BaseGame/game/tools/levels/BlankRoom.postfxpreset.cs
@@ -1,4 +1,4 @@
-$PostFXManager::Settings::ColorCorrectionRamp = "core/images/null_color_ramp.png";
+$PostFXManager::Settings::ColorCorrectionRamp = "core/postFX/images/null_color_ramp.png";
$PostFXManager::Settings::DOF::BlurCurveFar = "";
$PostFXManager::Settings::DOF::BlurCurveNear = "";
$PostFXManager::Settings::DOF::BlurMax = "";