Jelajahi Sumber

Shader default values (untested)

Marko Pintera 10 tahun lalu
induk
melakukan
d0793ab046

+ 3 - 1
BansheeCore/Include/BsCommonTypes.h

@@ -220,7 +220,9 @@ namespace BansheeEngine
 	enum GpuParamType
 	{
 		GPT_DATA,
-		GPT_OBJECT
+		GPT_TEXTURE,
+		GPT_BUFFER,
+		GPT_SAMPLER
 	};
 
 	/**

+ 11 - 0
BansheeCore/Include/BsGpuParam.h

@@ -6,6 +6,7 @@
 #include "BsVector4.h"
 #include "BsMatrix3.h"
 #include "BsMatrix4.h"
+#include "BsMatrixNxM.h"
 #include "BsColor.h"
 
 namespace BansheeEngine
@@ -82,6 +83,16 @@ namespace BansheeEngine
 			static bool transposeEnabled(bool enabled) { return enabled; }
 		};
 
+		/**
+		 * @brief	Transpose policy for NxM matrix.
+		 */
+		template<int N, int M>
+		struct TransposePolicy<MatrixNxM<N, M>>
+		{
+			static MatrixNxM<N, M> transpose(const MatrixNxM<N, M>& value) { return value.transpose(); }
+			static bool transposeEnabled(bool enabled) { return enabled; }
+		};
+
 	public:
 		TGpuDataParam();
 		TGpuDataParam(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);

+ 14 - 0
BansheeCore/Include/BsMaterial.h

@@ -549,12 +549,26 @@ namespace BansheeEngine
 		template <typename T>
 		void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
 
+		/**
+		 * @brief	Assigns a value from a raw buffer to the parameter with the specified name.
+		 *			Buffer must be of sizeof(T) * numElements size and initialized.
+		 *
+		 * @note	Provided parameter must exist, no checking is done.
+		 */
+		template <typename T>
+		void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
+
 		/**
 		 * @brief	Initializes the material by using the best technique from the currently set shader. Shader
 		 * 			must contain the technique that matches the current renderer and render system.
 		 */
 		void initBestTechnique();
 
+		/**
+		 * @brief	Assigns all the default parameters specified in the shader to the material.
+		 */
+		void initDefaultParameters();
+
 		/**
 		 * @brief	Throw an exception if no shader is set, or no acceptable
 		 * 			technique was found.

+ 171 - 49
BansheeCore/Include/BsShader.h

@@ -19,6 +19,7 @@ namespace BansheeEngine
 		StringID rendererSemantic;
 		UINT32 arraySize;
 		UINT32 elementSize;
+		UINT32 defaultValueIdx;
 	};
 
 	/**
@@ -32,6 +33,7 @@ namespace BansheeEngine
 		Vector<String> gpuVariableNames;
 		StringID rendererSemantic;
 		GpuParamObjectType type;
+		UINT32 defaultValueIdx;
 	};
 
 	/**
@@ -48,9 +50,21 @@ namespace BansheeEngine
 	/**
 	 * @brief Structure used for initializing a shader.
 	 */
-	struct BS_CORE_EXPORT SHADER_DESC
+	template<bool Core>
+	struct BS_CORE_EXPORT TSHADER_DESC
 	{
-		SHADER_DESC();
+		template<bool Core> struct TTextureType {};
+		template<> struct TTextureType < false > { typedef HTexture Type; };
+		template<> struct TTextureType < true > { typedef SPtr<TextureCore> Type; };
+
+		template<bool Core> struct TSamplerStateType {};
+		template<> struct TSamplerStateType < false > { typedef SamplerStatePtr Type; };
+		template<> struct TSamplerStateType < true > { typedef SPtr<SamplerStateCore> Type; };
+
+		typedef typename TTextureType<Core>::Type TextureType;
+		typedef typename TSamplerStateType<Core>::Type SamplerStateType;
+
+		TSHADER_DESC();
 
 		/**
 		 * @brief	Registers a new data (int, Vector2, etc.) parameter you that you may then use 
@@ -67,9 +81,14 @@ namespace BansheeEngine
 		 * @param	arraySize	   	 (optional) If the parameter is an array, the number of elements in the array. Size of 1 means its not an array.
 		 * @param	elementSize	   	 (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
 		 * 							 length parameters, like structs.
+		 * @param	defaultValue	 (optional) Pointer to the buffer containing the default value for this parameter (initial value that will be set
+		 *							 when a material is initialized with this shader). The provided buffer must be of the correct size (depending on the
+		 *							 element type and array size).
+		 *
+		 * @note	If multiple parameters are given with the same name but different types behavior is undefined.
 		 */
 		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, StringID rendererSemantic = StringID::NONE,
-			UINT32 arraySize = 1, UINT32 elementSize = 0);
+			UINT32 arraySize = 1, UINT32 elementSize = 0, UINT8* defaultValue = nullptr);
 
 		/**
 		 * @brief	Registers a new object (texture, sampler state, etc.) parameter you that you may then use 
@@ -85,11 +104,34 @@ namespace BansheeEngine
 		 *							 by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
 		 *							 with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
 		 *
-		 * @note	Mapping multiple GPU variables to a single parameter is useful when you are defining a shader that supports techniques across different render
-		 *			systems where GPU variable names for the same parameters might differ.
+		 * @note	If multiple parameters are given with the same name but different types behavior is undefined.
+		 *			You are allowed to call this method multiple times in order to map multiple GPU variable names to a single parameter, 
+		 *			but the default value (if any) will only be recognized on the first call. Mapping multiple GPU variables to a single parameter 
+		 *			is useful when you are defining a shader that supports techniques across different render systems where GPU variable names for 
+		 *			the same parameters might differ.
 		 */
 		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic = StringID::NONE);
 
+		/**
+		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	Specialized version of addParameter that accepts a default sampler value that will be used for
+		 *			initializing the object parameter upon Material creation. Default sampler value is only valid
+		 *			if the object type is one of the sampler types.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
+			const SamplerStateType& defaultValue, StringID rendererSemantic = StringID::NONE);
+
+		/**
+		 * @see	SHADER_DESC::addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	Specialized version of addParameter that accepts a default texture value that will be used for
+		 *			initializing the object parameter upon Material creation. Default texture value is only valid
+		 *			if the object type is one of the texture types.
+		 */
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, 
+			const TextureType& defaultValue, StringID rendererSemantic = StringID::NONE);
+
 		/**
 		 * @brief	Changes parameters of a parameter block with the specified name.
 		 *
@@ -140,23 +182,65 @@ namespace BansheeEngine
 		bool separablePasses;
 
 		Map<String, SHADER_DATA_PARAM_DESC> dataParams;
-		Map<String, SHADER_OBJECT_PARAM_DESC> objectParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> textureParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> bufferParams;
+		Map<String, SHADER_OBJECT_PARAM_DESC> samplerParams;
 		Map<String, SHADER_PARAM_BLOCK_DESC> paramBlocks;
+
+		Vector<UINT8> dataDefaultValues;
+		Vector<SamplerStateType> samplerDefaultValues;
+		Vector<TextureType> textureDefaultValues;
+
+	private:
+		/**
+		 * @copydoc	addParameter(const String&, const String&, GpuParamObjectType, StringID)
+		 *
+		 * @note	Common method shared by different addParameter overloads.
+		 */
+		void addParameterInternal(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic, UINT32 defaultValueIdx);
 	};
 
+	typedef TSHADER_DESC<true> SHADER_DESC_CORE;
+	typedef TSHADER_DESC<false> SHADER_DESC;
+
 	/**
 	 * @brief	Shader represents a collection of techniques. They are used in Materials,
 	 * 			which can be considered as instances of a Shader. Multiple materials
 	 * 			may share the same shader but provide different parameters to it.
-	 * 			
+	 *
 	 *			Shader will always choose the first supported technique based on the current render
 	 *			system, render manager and other properties. So make sure to add most important techniques
 	 *			first so you make sure they are used if they are supported.
+	 *
+	 * @note	Templated version of Shader used for implementing both 
+	 *			sim and core thread variants.
 	 */
-	class BS_CORE_EXPORT ShaderBase
+	template<bool Core>
+	class BS_CORE_EXPORT TShader
 	{
 	public:
-		virtual ~ShaderBase() { }
+		template<bool Core> struct TTechniqueType {};
+		template<> struct TTechniqueType < false > { typedef Technique Type; };
+		template<> struct TTechniqueType < true > { typedef TechniqueCore Type; };
+
+		typedef typename TTechniqueType<Core>::Type TechniqueType;
+		typedef typename TSHADER_DESC<Core>::TextureType TextureType;
+		typedef typename TSHADER_DESC<Core>::SamplerStateType SamplerStateType;
+
+		TShader() { }
+		TShader(const String& name, const TSHADER_DESC<Core>& desc, const Vector<SPtr<TechniqueType>>& techniques);
+		virtual ~TShader();
+	
+		/**
+		 * @brief	Returns the total number of techniques in this shader.
+		 */
+		UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
+
+		/**
+		 * @brief	Gets the best supported technique based on current render and other systems.
+		 * 			Returns null if not a single technique is supported.
+		 */
+		SPtr<TechniqueType> getBestTechnique() const;
 
 		/**
 		 * @brief	Returns currently active queue sort type.
@@ -192,10 +276,22 @@ namespace BansheeEngine
 		const SHADER_DATA_PARAM_DESC& getDataParamDesc(const String& name) const;
 
 		/**
-		 * @brief	Returns description for an object parameter with the specified name. Throws exception if
+		 * @brief	Returns description for a texture parameter with the specified name. Throws exception if
 		 *			the parameter doesn't exist.
 		 */
-		const SHADER_OBJECT_PARAM_DESC& getObjectParamDesc(const String& name) const;
+		const SHADER_OBJECT_PARAM_DESC& getTextureParamDesc(const String& name) const;
+
+		/**
+		 * @brief	Returns description for a sampler parameter with the specified name. Throws exception if
+		 *			the parameter doesn't exist.
+		 */
+		const SHADER_OBJECT_PARAM_DESC& getSamplerParamDesc(const String& name) const;
+
+		/**
+		 * @brief	Returns description for a buffer parameter with the specified name. Throws exception if
+		 *			the parameter doesn't exist.
+		 */
+		const SHADER_OBJECT_PARAM_DESC& getBufferParamDesc(const String& name) const;
 
 		/** 
 		 * @brief	Checks if the parameter with the specified name exists, and is a data parameter.
@@ -203,9 +299,19 @@ namespace BansheeEngine
 		bool hasDataParam(const String& name) const;
 
 		/** 
-		 * @brief	Checks if the parameter with the specified name exists, and is an object parameter.
+		 * @brief	Checks if the parameter with the specified name exists, and is a texture parameter.
+		 */
+		bool hasTextureParam(const String& name) const;
+
+		/** 
+		 * @brief	Checks if the parameter with the specified name exists, and is a sampler parameter.
 		 */
-		bool hasObjectParam(const String& name) const;
+		bool hasSamplerParam(const String& name) const;
+
+		/** 
+		 * @brief	Checks if the parameter with the specified name exists, and is a buffer parameter.
+		 */
+		bool hasBufferParam(const String& name) const;
 
 		/** 
 		 * @brief	Returns a map of all data parameters in the shader.
@@ -213,55 +319,47 @@ namespace BansheeEngine
 		const Map<String, SHADER_DATA_PARAM_DESC>& getDataParams() const { return mDesc.dataParams; }
 
 		/** 
-		 * @brief	Returns a map of all object parameters in the shader. 
+		 * @brief	Returns a map of all texture parameters in the shader. 
+		 */
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getTextureParams() const { return mDesc.textureParams; }
+
+		/**
+		 * @brief	Returns a map of all buffer parameters in the shader.
+		 */
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getBufferParams() const { return mDesc.bufferParams; }
+
+		/**
+		 * @brief	Returns a map of all sampler parameters in the shader.
 		 */
-		const Map<String, SHADER_OBJECT_PARAM_DESC>& getObjectParams() const { return mDesc.objectParams; }
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& getSamplerParams() const { return mDesc.samplerParams; }
 
 		/** 
 		 * @brief	Returns a map of all parameter blocks.
 		 */
 		const Map<String, SHADER_PARAM_BLOCK_DESC>& getParamBlocks() const { return mDesc.paramBlocks; }
 
-	protected:
-		ShaderBase() { }
-		ShaderBase(const String& name, const SHADER_DESC& desc);
-
-		String mName;
-		SHADER_DESC mDesc;
-	};
-
-	/**
-	 * @copydoc	ShaderBase
-	 *
-	 * @note	Templated version of Shader used for implementing both 
-	 *			sim and core thread variants.
-	 */
-	template<bool Core>
-	class BS_CORE_EXPORT TShader : public ShaderBase
-	{
-	public:
-		template<bool Core> struct TTechniqueType {};
-		template<> struct TTechniqueType < false > { typedef Technique Type; };
-		template<> struct TTechniqueType < true > { typedef TechniqueCore Type; };
-
-		typedef typename TTechniqueType<Core>::Type TechniqueType;
+		/**
+		 * @brief	Returns a default texture for a parameter that has the specified
+		 *			default value index (retrieved from the parameters descriptor).
+		 */
+		TextureType getDefaultTexture(UINT32 index) const;
 
-		TShader() { }
-		TShader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueType>>& techniques);
-		virtual ~TShader();
-	
 		/**
-		 * @brief	Returns the total number of techniques in this shader.
+		 * @brief	Returns a default sampler state for a parameter that has the specified
+		 *			default value index (retrieved from the parameters descriptor).
 		 */
-		UINT32 getNumTechniques() const { return (UINT32)mTechniques.size(); }
+		SamplerStateType getDefaultSampler(UINT32 index) const;
 
 		/**
-		 * @brief	Gets the best supported technique based on current render and other systems.
-		 * 			Returns null if not a single technique is supported.
+		 * @brief	Returns a pointer to the internal buffer containing the default 
+		 *			value for a data parameter that has the specified default value index 
+		 *			(retrieved from the parameters descriptor).
 		 */
-		SPtr<TechniqueType> getBestTechnique() const;
+		UINT8* getDefaultValue(UINT32 index) const;
 
 	protected:
+		String mName;
+		TSHADER_DESC<Core> mDesc;
 		Vector<SPtr<TechniqueType>> mTechniques;
 	};
 
@@ -274,12 +372,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	Shader::create
 		 */
-		static SPtr<ShaderCore> create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques);
+		static SPtr<ShaderCore> create(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques);
 
 	protected:
 		friend class Shader;
 
-		ShaderCore(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques);
+		ShaderCore(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques);
 	};
 
 	/**
@@ -294,10 +392,28 @@ namespace BansheeEngine
 		 */
 		SPtr<ShaderCore> getCore() const;
 
+		/**
+		 * @brief	Checks is the provided object type a sampler.
+		 */
 		static bool isSampler(GpuParamObjectType type);
+
+		/**
+		 * @brief	Checks is the provided object type a texture.
+		 */
 		static bool isTexture(GpuParamObjectType type);
+
+		/**
+		 * @brief	Checks is the provided object type a buffer.
+		 */
 		static bool isBuffer(GpuParamObjectType type);
 
+		/**
+		 * @brief	Returns the size in bytes for a specific data type.
+		 *
+		 * @note	Returns 0 for variable size types like structures.
+		 */
+		static UINT32 getDataParamSize(GpuParamDataType type);
+
 		/**
 		 * @brief	Creates a new shader resource using the provided descriptor and techniques.
 		 */
@@ -328,6 +444,12 @@ namespace BansheeEngine
 		 */
 		SPtr<CoreObjectCore> createCore() const;
 
+		/**
+		 * @brief	Converts a sim thread version of the shader descriptor to
+		 *			a core thread version.
+		 */
+		SHADER_DESC_CORE convertDesc(const SHADER_DESC& desc) const;
+
 	private:
 		/************************************************************************/
 		/* 								RTTI		                     		*/

+ 61 - 15
BansheeCore/Include/BsShaderRTTI.h

@@ -178,24 +178,48 @@ namespace BansheeEngine
 		UINT32 getDataParamsArraySize(Shader* obj) { return (UINT32)obj->mDesc.dataParams.size(); }
 		void setDataParamsArraySize(Shader* obj, UINT32 size) {  } // Do nothing
 
-		SHADER_OBJECT_PARAM_DESC& getObjectParam(Shader* obj, UINT32 idx) 
+		SHADER_OBJECT_PARAM_DESC& getTextureParam(Shader* obj, UINT32 idx) 
 		{ 
-			auto iter = obj->mDesc.objectParams.begin();
+			auto iter = obj->mDesc.textureParams.begin();
 			for(UINT32 i = 0; i < idx; i++) ++iter;
 
 			return iter->second; 
 		}
 
-		void setObjectParam(Shader* obj, UINT32 idx, SHADER_OBJECT_PARAM_DESC& val) { obj->mDesc.objectParams[val.name] = val; }
-		UINT32 getObjectParamsArraySize(Shader* obj) { return (UINT32)obj->mDesc.objectParams.size(); }
-		void setObjectParamsArraySize(Shader* obj, UINT32 size) {  } // Do nothing
+		void setTextureParam(Shader* obj, UINT32 idx, SHADER_OBJECT_PARAM_DESC& val) { obj->mDesc.textureParams[val.name] = val; }
+		UINT32 getTextureParamsArraySize(Shader* obj) { return (UINT32)obj->mDesc.textureParams.size(); }
+		void setTextureParamsArraySize(Shader* obj, UINT32 size) {  } // Do nothing
 
-		SHADER_PARAM_BLOCK_DESC& getParamBlock(Shader* obj, UINT32 idx) 
-		{ 
+		SHADER_OBJECT_PARAM_DESC& getSamplerParam(Shader* obj, UINT32 idx)
+		{
+			auto iter = obj->mDesc.samplerParams.begin();
+			for (UINT32 i = 0; i < idx; i++) ++iter;
+
+			return iter->second;
+		}
+
+		void setSamplerParam(Shader* obj, UINT32 idx, SHADER_OBJECT_PARAM_DESC& val) { obj->mDesc.samplerParams[val.name] = val; }
+		UINT32 getSamplerParamsArraySize(Shader* obj) { return (UINT32)obj->mDesc.samplerParams.size(); }
+		void setSamplerParamsArraySize(Shader* obj, UINT32 size) {  } // Do nothing
+
+		SHADER_OBJECT_PARAM_DESC& getBufferParam(Shader* obj, UINT32 idx)
+		{
+			auto iter = obj->mDesc.bufferParams.begin();
+			for (UINT32 i = 0; i < idx; i++) ++iter;
+
+			return iter->second;
+		}
+
+		void setBufferParam(Shader* obj, UINT32 idx, SHADER_OBJECT_PARAM_DESC& val) { obj->mDesc.bufferParams[val.name] = val; }
+		UINT32 getBufferParamsArraySize(Shader* obj) { return (UINT32)obj->mDesc.bufferParams.size(); }
+		void setBufferParamsArraySize(Shader* obj, UINT32 size) {  } // Do nothing
+
+		SHADER_PARAM_BLOCK_DESC& getParamBlock(Shader* obj, UINT32 idx)
+		{
 			auto iter = obj->mDesc.paramBlocks.begin();
-			for(UINT32 i = 0; i < idx; i++) ++iter;
+			for (UINT32 i = 0; i < idx; i++) ++iter;
 
-			return iter->second; 
+			return iter->second;
 		}
 
 		void setParamBlock(Shader* obj, UINT32 idx, SHADER_PARAM_BLOCK_DESC& val) { obj->mDesc.paramBlocks[val.name] = val; }
@@ -211,6 +235,18 @@ namespace BansheeEngine
 		bool& getAllowSeparablePasses(Shader* obj) { return obj->mDesc.separablePasses; }
 		void setAllowSeparablePasses(Shader* obj, bool& value) { obj->mDesc.separablePasses = value; }
 
+		Vector<UINT8>& getDataDefaultValues(Shader* obj) { return obj->mDesc.dataDefaultValues; }
+		void setDataDefaultValues(Shader* obj, Vector<UINT8>& value) { obj->mDesc.dataDefaultValues = value; }
+
+		HTexture& getDefaultTexture(Shader* obj, UINT32 idx) { return obj->mDesc.textureDefaultValues[idx]; }
+		void setDefaultTexture(Shader* obj, UINT32 idx, HTexture& val) { obj->mDesc.textureDefaultValues[idx] = val; }
+		UINT32 getDefaultTextureArraySize(Shader* obj) { return (UINT32)obj->mDesc.textureDefaultValues.size(); }
+		void setDefaultTextureArraySize(Shader* obj, UINT32 size) { obj->mDesc.textureDefaultValues.resize(size); }
+
+		SamplerStatePtr getDefaultSampler(Shader* obj, UINT32 idx) { return obj->mDesc.samplerDefaultValues[idx]; }
+		void setDefaultSampler(Shader* obj, UINT32 idx, SamplerStatePtr val) { obj->mDesc.samplerDefaultValues[idx] = val; }
+		UINT32 getDefaultSamplerArraySize(Shader* obj) { return (UINT32)obj->mDesc.samplerDefaultValues.size(); }
+		void setDefaultSamplerArraySize(Shader* obj, UINT32 size) { obj->mDesc.samplerDefaultValues.resize(size); }
 
 	public:
 		ShaderRTTI()
@@ -221,14 +257,24 @@ namespace BansheeEngine
 
 			addPlainArrayField("mDataParams", 2, &ShaderRTTI::getDataParam, &ShaderRTTI::getDataParamsArraySize, 
 				&ShaderRTTI::setDataParam, &ShaderRTTI::setDataParamsArraySize);
-			addPlainArrayField("mObjectParams", 3, &ShaderRTTI::getObjectParam, &ShaderRTTI::getObjectParamsArraySize, 
-				&ShaderRTTI::setObjectParam, &ShaderRTTI::setObjectParamsArraySize);
-			addPlainArrayField("mParamBlocks", 4, &ShaderRTTI::getParamBlock, &ShaderRTTI::getParamBlocksArraySize, 
+			addPlainArrayField("mTextureParams", 3, &ShaderRTTI::getTextureParam, &ShaderRTTI::getTextureParamsArraySize,
+				&ShaderRTTI::setTextureParam, &ShaderRTTI::setTextureParamsArraySize);
+			addPlainArrayField("mSamplerParams", 4, &ShaderRTTI::getSamplerParam, &ShaderRTTI::getSamplerParamsArraySize,
+				&ShaderRTTI::setSamplerParam, &ShaderRTTI::setSamplerParamsArraySize);
+			addPlainArrayField("mBufferParams", 5, &ShaderRTTI::getBufferParam, &ShaderRTTI::getBufferParamsArraySize,
+				&ShaderRTTI::setBufferParam, &ShaderRTTI::setBufferParamsArraySize);
+			addPlainArrayField("mParamBlocks", 6, &ShaderRTTI::getParamBlock, &ShaderRTTI::getParamBlocksArraySize, 
 				&ShaderRTTI::setParamBlock, &ShaderRTTI::setParamBlocksArraySize);
 
-			addPlainField("mQueueSortType", 5, &ShaderRTTI::getQueueSortType, &ShaderRTTI::setQueueSortType);
-			addPlainField("mQueuePriority", 6, &ShaderRTTI::getQueuePriority, &ShaderRTTI::setQueuePriority);
-			addPlainField("mSeparablePasses", 7, &ShaderRTTI::getAllowSeparablePasses, &ShaderRTTI::setAllowSeparablePasses);
+			addPlainField("mQueueSortType", 7, &ShaderRTTI::getQueueSortType, &ShaderRTTI::setQueueSortType);
+			addPlainField("mQueuePriority", 8, &ShaderRTTI::getQueuePriority, &ShaderRTTI::setQueuePriority);
+			addPlainField("mSeparablePasses", 9, &ShaderRTTI::getAllowSeparablePasses, &ShaderRTTI::setAllowSeparablePasses);
+
+			addPlainField("mDataDefaultValues", 10, &ShaderRTTI::getDataDefaultValues, &ShaderRTTI::setDataDefaultValues);
+			addReflectableArrayField("mTextureDefaultValues", 11, &ShaderRTTI::getDefaultTexture, &ShaderRTTI::getDefaultTextureArraySize,
+				&ShaderRTTI::setDefaultTexture, &ShaderRTTI::setDefaultTextureArraySize);
+			addReflectablePtrArrayField("mSamplerDefaultValues", 12, &ShaderRTTI::getDefaultSampler, &ShaderRTTI::getDefaultSamplerArraySize,
+				&ShaderRTTI::setDefaultSampler, &ShaderRTTI::setDefaultSamplerArraySize);
 		}
 
 		virtual void onDeserializationEnded(IReflectable* obj)

+ 24 - 0
BansheeCore/Source/BsGpuParam.cpp

@@ -4,6 +4,8 @@
 #include "BsGpuParamDesc.h"
 #include "BsDebug.h"
 #include "BsException.h"
+#include "BsVectorNI.h"
+#include "BsVector2I.h"
 
 namespace BansheeEngine
 {
@@ -272,20 +274,42 @@ namespace BansheeEngine
 	}
 
 	template class TGpuDataParam < float, false > ;
+	template class TGpuDataParam < int, false >;
 	template class TGpuDataParam < Color, false > ;
 	template class TGpuDataParam < Vector2, false > ;
 	template class TGpuDataParam < Vector3, false > ;
 	template class TGpuDataParam < Vector4, false > ;
+	template class TGpuDataParam < Vector2I, false > ;
+	template class TGpuDataParam < Vector3I, false > ;
+	template class TGpuDataParam < Vector4I, false > ;
+	template class TGpuDataParam < Matrix2, false >;
+	template class TGpuDataParam < Matrix2x3, false >;
+	template class TGpuDataParam < Matrix2x4, false >;
 	template class TGpuDataParam < Matrix3, false > ;
+	template class TGpuDataParam < Matrix3x2, false > ;
+	template class TGpuDataParam < Matrix3x4, false > ;
 	template class TGpuDataParam < Matrix4, false > ;
+	template class TGpuDataParam < Matrix4x2, false >;
+	template class TGpuDataParam < Matrix4x3, false >;
 
 	template class TGpuDataParam < float, true > ;
+	template class TGpuDataParam < int, true >;
 	template class TGpuDataParam < Color, true > ;
 	template class TGpuDataParam < Vector2, true > ;
 	template class TGpuDataParam < Vector3, true > ;
 	template class TGpuDataParam < Vector4, true > ;
+	template class TGpuDataParam < Vector2I, true > ;
+	template class TGpuDataParam < Vector3I, true > ;
+	template class TGpuDataParam < Vector4I, true > ;
+	template class TGpuDataParam < Matrix2, true >;
+	template class TGpuDataParam < Matrix2x3, true >;
+	template class TGpuDataParam < Matrix2x4, true >;
 	template class TGpuDataParam < Matrix3, true > ;
+	template class TGpuDataParam < Matrix3x2, true >;
+	template class TGpuDataParam < Matrix3x4, true >;
 	template class TGpuDataParam < Matrix4, true > ;
+	template class TGpuDataParam < Matrix4x2, true >;
+	template class TGpuDataParam < Matrix4x3, true >;
 
 	template class TGpuParamStruct < false > ;
 	template class TGpuParamStruct < true > ;

+ 24 - 0
BansheeCore/Source/BsGpuParams.cpp

@@ -7,6 +7,8 @@
 #include "BsFrameAlloc.h"
 #include "BsDebug.h"
 #include "BsException.h"
+#include "BsVectorNI.h"
+#include "BsMatrixNxM.h"
 
 namespace BansheeEngine
 {
@@ -332,20 +334,42 @@ UINT32 GpuParamsBase::getDataParamSize(const String& name) const
 	template class TGpuParams < true > ;
 
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<float>(const String&, TGpuDataParam<float, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<int>(const String&, TGpuDataParam<int, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Color>(const String&, TGpuDataParam<Color, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2>(const String&, TGpuDataParam<Vector2, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3>(const String&, TGpuDataParam<Vector3, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4>(const String&, TGpuDataParam<Vector4, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector2I>(const String&, TGpuDataParam<Vector2I, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector3I>(const String&, TGpuDataParam<Vector3I, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Vector4I>(const String&, TGpuDataParam<Vector4I, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2>(const String&, TGpuDataParam<Matrix2, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x3>(const String&, TGpuDataParam<Matrix2x3, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix2x4>(const String&, TGpuDataParam<Matrix2x4, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3>(const String&, TGpuDataParam<Matrix3, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x2>(const String&, TGpuDataParam<Matrix3x2, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix3x4>(const String&, TGpuDataParam<Matrix3x4, false>&) const;
 	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4>(const String&, TGpuDataParam<Matrix4, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x2>(const String&, TGpuDataParam<Matrix4x2, false>&) const;
+	template BS_CORE_EXPORT void TGpuParams<false>::getParam<Matrix4x3>(const String&, TGpuDataParam<Matrix4x3, false>&) const;
 
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<float>(const String&, TGpuDataParam<float, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<int>(const String&, TGpuDataParam<int, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Color>(const String&, TGpuDataParam<Color, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2>(const String&, TGpuDataParam<Vector2, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3>(const String&, TGpuDataParam<Vector3, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4>(const String&, TGpuDataParam<Vector4, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector2I>(const String&, TGpuDataParam<Vector2I, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector3I>(const String&, TGpuDataParam<Vector3I, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Vector4I>(const String&, TGpuDataParam<Vector4I, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2>(const String&, TGpuDataParam<Matrix2, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x3>(const String&, TGpuDataParam<Matrix2x3, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix2x4>(const String&, TGpuDataParam<Matrix2x4, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3>(const String&, TGpuDataParam<Matrix3, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x2>(const String&, TGpuDataParam<Matrix3x2, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix3x4>(const String&, TGpuDataParam<Matrix3x4, true>&) const;
 	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4>(const String&, TGpuDataParam<Matrix4, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x2>(const String&, TGpuDataParam<Matrix4x2, true>&) const;
+	template BS_CORE_EXPORT void TGpuParams<true>::getParam<Matrix4x3>(const String&, TGpuDataParam<Matrix4x3, true>&) const;
 
 	GpuParamsCore::GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices)
 		: TGpuParams(paramDesc, transposeMatrices)

+ 195 - 13
BansheeCore/Source/BsMaterial.cpp

@@ -13,6 +13,8 @@
 #include "BsDebug.h"
 #include "BsResources.h"
 #include "BsFrameAlloc.h"
+#include "BsMatrixNxM.h"
+#include "BsVectorNI.h"
 
 namespace BansheeEngine
 {
@@ -253,8 +255,11 @@ namespace BansheeEngine
 		return paramToParamBlock;
 	}
 
-	Map<String, String> determineParamMappings(const Vector<GpuParamDescPtr>& paramDescs, const Map<String, SHADER_DATA_PARAM_DESC>& dataParams,
-		const Map<String, SHADER_OBJECT_PARAM_DESC>& objectParam)
+	Map<String, String> determineParamMappings(const Vector<GpuParamDescPtr>& paramDescs, 
+		const Map<String, SHADER_DATA_PARAM_DESC>& dataParams,
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams,
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferParams,
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& samplerParams)
 	{
 		Map<String, String> validParams;
 
@@ -295,21 +300,28 @@ namespace BansheeEngine
 		}
 
 		// Create object param mappings
-		for (auto iter = objectParam.begin(); iter != objectParam.end(); ++iter)
+		auto determineObjectMappings = [&](const Map<String, SHADER_OBJECT_PARAM_DESC>& params)
 		{
-			const Vector<String>& gpuVariableNames = iter->second.gpuVariableNames;
-			for (auto iter2 = gpuVariableNames.begin(); iter2 != gpuVariableNames.end(); ++iter2)
+			for (auto iter = params.begin(); iter != params.end(); ++iter)
 			{
-				for (auto iter3 = validObjectParameters.begin(); iter3 != validObjectParameters.end(); ++iter3)
+				const Vector<String>& gpuVariableNames = iter->second.gpuVariableNames;
+				for (auto iter2 = gpuVariableNames.begin(); iter2 != gpuVariableNames.end(); ++iter2)
 				{
-					if ((*iter3)->name == (*iter2) && (*iter3)->type == iter->second.type)
+					for (auto iter3 = validObjectParameters.begin(); iter3 != validObjectParameters.end(); ++iter3)
 					{
-						validParams[iter->first] = *iter2;
-						break;
+						if ((*iter3)->name == (*iter2) && (*iter3)->type == iter->second.type)
+						{
+							validParams[iter->first] = *iter2;
+							break;
+						}
 					}
 				}
 			}
-		}
+		};
+
+		determineObjectMappings(textureParams);
+		determineObjectMappings(samplerParams);
+		determineObjectMappings(bufferParams);
 
 		return validParams;
 	}
@@ -644,7 +656,8 @@ namespace BansheeEngine
 			mValidShareableParamBlocks.clear();
 			Vector<GpuParamDescPtr> allParamDescs = getAllParamDescs(mBestTechnique);
 
-			mValidParams = determineParamMappings(allParamDescs, mShader->getDataParams(), mShader->getObjectParams());
+			mValidParams = determineParamMappings(allParamDescs, mShader->getDataParams(), mShader->getTextureParams(),
+				mShader->getBufferParams(), mShader->getSamplerParams());
 
 			// Fill out various helper structures
 			Set<String> validShareableParamBlocks = determineValidShareableParamBlocks(allParamDescs);
@@ -733,6 +746,139 @@ namespace BansheeEngine
 					}
 				}
 			}
+
+			// Assign default parameters
+			initDefaultParameters();
+		}
+	}
+
+	template <bool Core>
+	template <typename T>
+	void TMaterial<Core>::setParamValue(const String& name, UINT8* buffer, UINT32 numElements)
+	{
+		TMaterialDataParam<T, Core> param;
+		getParam(name, param);
+
+		T* ptr = (T*)buffer;
+		for (UINT32 i = 0; i < numElements; i++)
+			param.set(ptr[i], i);
+	}
+
+	template <bool Core>
+	void TMaterial<Core>::initDefaultParameters()
+	{
+		const Map<String, SHADER_DATA_PARAM_DESC>& dataParams = mShader->getDataParams();
+		for (auto& paramData : dataParams)
+		{
+			if (paramData.second.defaultValueIdx == (UINT32)-1)
+				continue;
+
+			auto iterFind = mValidParams.find(paramData.first);
+			if (iterFind == mValidParams.end())
+				continue;
+			
+			UINT8* buffer = (UINT8*)mShader->getDefaultValue(paramData.second.defaultValueIdx);
+			if (buffer == nullptr)
+				continue;
+
+			switch (paramData.second.type)
+			{
+			case GPDT_FLOAT1: 
+				setParamValue<float>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_FLOAT2:
+				setParamValue<Vector2>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_FLOAT3:
+				setParamValue<Vector3>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_FLOAT4:
+				setParamValue<Vector4>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_2X2:
+				setParamValue<Matrix2>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_2X3:
+				setParamValue<Matrix2x3>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_2X4:
+				setParamValue<Matrix2x4>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_3X2:
+				setParamValue<Matrix3x2>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_3X3:
+				setParamValue<Matrix3>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_3X4:
+				setParamValue<Matrix3x4>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_4X2:
+				setParamValue<Matrix4x2>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_4X3:
+				setParamValue<Matrix4x3>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_MATRIX_4X4:
+				setParamValue<Matrix4>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_INT1:
+				setParamValue<int>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_INT2:
+				setParamValue<Vector2I>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_INT3:
+				setParamValue<Vector3I>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_INT4:
+				setParamValue<Vector4I>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_BOOL:
+				setParamValue<int>(iterFind->first, buffer, paramData.second.arraySize);
+				break;
+			case GPDT_STRUCT:
+			{
+				TMaterialParamStruct<Core> param = getParamStruct(paramData.first);
+
+				UINT32 elementSizeBytes = paramData.second.elementSize * sizeof(UINT32);
+				UINT8* ptr = buffer;
+				for (UINT32 i = 0; i < paramData.second.arraySize; i++)
+				{
+					param.set(ptr, elementSizeBytes, i);
+					ptr += elementSizeBytes;
+				}
+			}
+			break;
+			}
+		}
+
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = mShader->getTextureParams();
+		for (auto& param : textureParams)
+		{
+			if (param.second.defaultValueIdx == (UINT32)-1)
+				continue;
+
+			auto iterFind = mValidParams.find(param.first);
+			if (iterFind == mValidParams.end())
+				continue;
+
+			TextureType defaultTex = mShader->getDefaultTexture(param.second.defaultValueIdx);
+			getParamTexture(param.first).set(defaultTex);
+		}
+
+		const Map<String, SHADER_OBJECT_PARAM_DESC>& samplerParams = mShader->getSamplerParams();
+		for (auto& param : samplerParams)
+		{
+			if (param.second.defaultValueIdx == (UINT32)-1)
+				continue;
+
+			auto iterFind = mValidParams.find(param.first);
+			if (iterFind == mValidParams.end())
+				continue;
+
+			SamplerStateType defaultSampler = mShader->getDefaultSampler(param.second.defaultValueIdx);
+			getParamSamplerState(param.first).set(defaultSampler);
 		}
 	}
 
@@ -791,20 +937,42 @@ namespace BansheeEngine
 	template class TMaterial < true > ;
 
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<float, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<int, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Color, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector2, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector3, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector4, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector2I, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector3I, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Vector4I, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2x3, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix2x4, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3x2, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix3x4, false>&) const;
 	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4x2, false>&) const;
+	template BS_CORE_EXPORT void TMaterial<false>::getParam(const String&, TMaterialDataParam<Matrix4x3, false>&) const;
 
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<float, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<int, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Color, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector2, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector3, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector4, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector2I, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector3I, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Vector4I, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2x3, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix2x4, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3x2, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix3x4, true>&) const;
 	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4x2, true>&) const;
+	template BS_CORE_EXPORT void TMaterial<true>::getParam(const String&, TMaterialDataParam<Matrix4x3, true>&) const;
 
 	MaterialCore::MaterialCore(const SPtr<ShaderCore>& shader)
 	{
@@ -1008,14 +1176,28 @@ namespace BansheeEngine
 
 	void Material::getListenerResources(Vector<HResource>& resources)
 	{
-		if (mShader != nullptr)
-			resources.push_back(mShader);
+		getResourceDependencies(resources);
 	}
 
 	void Material::getResourceDependencies(Vector<HResource>& dependencies) const
 	{
 		if (mShader != nullptr)
 			dependencies.push_back(mShader);
+
+		if (mShader.isLoaded())
+		{
+			const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = mShader->getTextureParams();
+
+			for (auto& param : textureParams)
+			{
+				if (param.second.defaultValueIdx != (UINT32)-1)
+				{
+					HTexture defaultTex = mShader->getDefaultTexture(param.second.defaultValueIdx);
+					if (defaultTex != nullptr)
+						dependencies.push_back(defaultTex);
+				}
+			}
+		}
 	}
 
 	void Material::initializeIfLoaded()

+ 24 - 0
BansheeCore/Source/BsMaterialParam.cpp

@@ -1,4 +1,6 @@
 #include "BsMaterialParam.h"
+#include "BsVector2I.h"
+#include "BsVectorNI.h"
 
 namespace BansheeEngine
 {
@@ -120,20 +122,42 @@ namespace BansheeEngine
 	}
 
 	template class TMaterialDataParam<float, false>;
+	template class TMaterialDataParam<int, false>;
 	template class TMaterialDataParam<Color, false>;
 	template class TMaterialDataParam<Vector2, false>;
 	template class TMaterialDataParam<Vector3, false>;
 	template class TMaterialDataParam<Vector4, false>;
+	template class TMaterialDataParam<Vector2I, false>;
+	template class TMaterialDataParam<Vector3I, false>;
+	template class TMaterialDataParam<Vector4I, false>;
+	template class TMaterialDataParam<Matrix2, false>;
+	template class TMaterialDataParam<Matrix2x3, false>;
+	template class TMaterialDataParam<Matrix2x4, false>;
 	template class TMaterialDataParam<Matrix3, false>;
+	template class TMaterialDataParam<Matrix3x2, false>;
+	template class TMaterialDataParam<Matrix3x4, false>;
 	template class TMaterialDataParam<Matrix4, false>;
+	template class TMaterialDataParam<Matrix4x2, false>;
+	template class TMaterialDataParam<Matrix4x3, false>;
 
 	template class TMaterialDataParam<float, true>;
+	template class TMaterialDataParam<int, true>;
 	template class TMaterialDataParam<Color, true>;
 	template class TMaterialDataParam<Vector2, true>;
 	template class TMaterialDataParam<Vector3, true>;
 	template class TMaterialDataParam<Vector4, true>;
+	template class TMaterialDataParam<Vector2I, true>;
+	template class TMaterialDataParam<Vector3I, true>;
+	template class TMaterialDataParam<Vector4I, true>;
+	template class TMaterialDataParam<Matrix2, true>;
+	template class TMaterialDataParam<Matrix2x3, true>;
+	template class TMaterialDataParam<Matrix2x4, true>;
 	template class TMaterialDataParam<Matrix3, true>;
+	template class TMaterialDataParam<Matrix3x2, true>;
+	template class TMaterialDataParam<Matrix3x4, true>;
 	template class TMaterialDataParam<Matrix4, true>;
+	template class TMaterialDataParam<Matrix4x2, true>;
+	template class TMaterialDataParam<Matrix4x3, true>;
 
 	template class TMaterialParamStruct<false>;
 	template class TMaterialParamStruct<true>;

+ 23 - 36
BansheeCore/Source/BsMaterialRTTI.cpp

@@ -150,34 +150,29 @@ namespace BansheeEngine
 						BS_EXCEPT(InternalErrorException, "Cannot serialize this paramater type: " + toString(paramDesc.type));
 					}
 				}
-				else if(type == GPT_OBJECT)
+				else if(type == GPT_TEXTURE)
 				{
-					const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->first);
+					const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getTextureParamDesc(iter->first);
 
-					if(Shader::isSampler(paramDesc.type))
-					{
-						MaterialSamplerStateParam param;
-						param.name = iter->first;
-						param.value = material->getSamplerState(iter->first);
+					MaterialTextureParam param;
+					param.name = iter->first;
+					param.value = material->getTexture(iter->first);
 
-						params->samplerStateParams.push_back(param);
-					}
-					else if(Shader::isTexture(paramDesc.type))
-					{
-						MaterialTextureParam param;
-						param.name = iter->first;
-						param.value = material->getTexture(iter->first);
+					params->textureParams.push_back(param);
+				}
+				else if (type == GPT_SAMPLER)
+				{
+					const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getSamplerParamDesc(iter->first);
 
-						params->textureParams.push_back(param);
-					}
-					else if(Shader::isBuffer(paramDesc.type))
-					{
-						BS_EXCEPT(NotImplementedException, "Buffers can't be serialized yet."); // TODO
-					}
-					else
-					{
-						BS_EXCEPT(InternalErrorException, "Cannot serialize this paramater type: " + toString(paramDesc.type));
-					}
+					MaterialSamplerStateParam param;
+					param.name = iter->first;
+					param.value = material->getSamplerState(iter->first);
+
+					params->samplerStateParams.push_back(param);
+				}
+				else if (type == GPT_BUFFER)
+				{
+					BS_EXCEPT(NotImplementedException, "Buffers can't be serialized yet.");
 				}
 				else
 					BS_EXCEPT(InternalErrorException, "Invalid parameter type.");
@@ -308,27 +303,19 @@ namespace BansheeEngine
 
 			for(auto iter = params->samplerStateParams.begin(); iter != params->samplerStateParams.end(); ++iter)
 			{
-				if(!shader->hasObjectParam(iter->name))
-					continue;
-
-				const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->name);
-
-				if(!Shader::isSampler(paramDesc.type))
+				if(!shader->hasSamplerParam(iter->name))
 					continue;
 
+				const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getSamplerParamDesc(iter->name);
 				material->setSamplerState(iter->name, iter->value);
 			}
 
 			for(auto iter = params->textureParams.begin(); iter != params->textureParams.end(); ++iter)
 			{
-				if(!shader->hasObjectParam(iter->name))
-					continue;
-
-				const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getObjectParamDesc(iter->name);
-
-				if(!Shader::isTexture(paramDesc.type))
+				if(!shader->hasTextureParam(iter->name))
 					continue;
 
+				const SHADER_OBJECT_PARAM_DESC& paramDesc = shader->getTextureParamDesc(iter->name);
 				material->setTexture(iter->name, iter->value);
 			}
 		}

+ 229 - 36
BansheeCore/Source/BsShader.cpp

@@ -6,17 +6,20 @@
 #include "BsResources.h"
 #include "BsFrameAlloc.h"
 #include "BsPass.h"
+#include "BsSamplerState.h"
 
 namespace BansheeEngine
 {
-	SHADER_DESC::SHADER_DESC()
+	template<bool Core>
+	TSHADER_DESC<Core>::TSHADER_DESC()
 		:queuePriority(0), queueSortType(QueueSortType::None), separablePasses(false)
 	{
 
 	}
 
-	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, 
-		StringID rendererSemantic, UINT32 arraySize, UINT32 elementSize)
+	template<bool Core>
+	void TSHADER_DESC<Core>::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type,
+		StringID rendererSemantic, UINT32 arraySize, UINT32 elementSize, UINT8* defaultValue)
 	{
 		if(type == GPDT_STRUCT && elementSize <= 0)
 			BS_EXCEPT(InvalidParametersException, "You need to provide a non-zero element size for a struct parameter.")
@@ -30,29 +33,84 @@ namespace BansheeEngine
 		desc.elementSize = elementSize;
 
 		dataParams[name] = desc;
-		objectParams.erase(name);
+
+		if (defaultValue != nullptr)
+		{
+			desc.defaultValueIdx = (UINT32)dataDefaultValues.size();
+			UINT32 defaultValueSize = Shader::getDataParamSize(type);
+
+			dataDefaultValues.resize(desc.defaultValueIdx + defaultValueSize);
+			memcpy(&dataDefaultValues[desc.defaultValueIdx], defaultValue, defaultValueSize);
+		}
+		else
+			desc.defaultValueIdx = (UINT32)-1;
 	}
 
-	void SHADER_DESC::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic)
+	template<bool Core>
+	void TSHADER_DESC<Core>::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic)
+	{
+		UINT32 defaultValueIdx = (UINT32)-1;
+
+		addParameterInternal(name, gpuVariableName, type, rendererSemantic, defaultValueIdx);
+	}
+
+	template<bool Core>
+	void TSHADER_DESC<Core>::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, const SamplerStateType& defaultValue, StringID rendererSemantic)
 	{
-		auto iterFind = objectParams.find(name);
+		UINT32 defaultValueIdx = (UINT32)-1;
+		if (Shader::isSampler(type) && defaultValue != nullptr)
+		{
+			defaultValueIdx = (UINT32)samplerDefaultValues.size();
+			samplerDefaultValues.push_back(defaultValue);
+		}
+
+		addParameterInternal(name, gpuVariableName, type, rendererSemantic, defaultValueIdx);
+	}
 
-		if (iterFind == objectParams.end())
+	template<bool Core>
+	void TSHADER_DESC<Core>::addParameter(const String& name, const String& gpuVariableName, GpuParamObjectType type, const TextureType& defaultValue, StringID rendererSemantic)
+	{
+		UINT32 defaultValueIdx = (UINT32)-1;
+		if (Shader::isTexture(type) && defaultValue != nullptr)
+		{
+			defaultValueIdx = (UINT32)textureDefaultValues.size();
+			textureDefaultValues.push_back(defaultValue);
+		}
+
+		addParameterInternal(name, gpuVariableName, type, rendererSemantic, defaultValueIdx);
+	}
+
+	template<bool Core>
+	void TSHADER_DESC<Core>::addParameterInternal(const String& name, const String& gpuVariableName, GpuParamObjectType type, StringID rendererSemantic, UINT32 defaultValueIdx)
+	{
+		Map<String, SHADER_OBJECT_PARAM_DESC>* DEST_LOOKUP[] = { &textureParams, &bufferParams, &samplerParams };
+		UINT32 destIdx = 0;
+		if (Shader::isBuffer(type))
+			destIdx = 1;
+		else if (Shader::isSampler(type))
+			destIdx = 2;
+
+		Map<String, SHADER_OBJECT_PARAM_DESC>& paramsMap = *DEST_LOOKUP[destIdx];
+
+		auto iterFind = paramsMap.find(name);
+		if (iterFind == paramsMap.end())
 		{
 			SHADER_OBJECT_PARAM_DESC desc;
 			desc.name = name;
 			desc.type = type;
 			desc.rendererSemantic = rendererSemantic;
 			desc.gpuVariableNames.push_back(gpuVariableName);
+			desc.defaultValueIdx = defaultValueIdx;
 
-			objectParams[name] = desc;
+			paramsMap[name] = desc;
 		}
 		else
 		{
 			SHADER_OBJECT_PARAM_DESC& desc = iterFind->second;
 
+			// If same name but different properties, we ignore this param
 			if (desc.type != type || desc.rendererSemantic != rendererSemantic)
-				BS_EXCEPT(InvalidParametersException, "Shader parameter with the name \"" + name + "\" already exists with different properties.");
+				return;
 
 			Vector<String>& gpuVariableNames = desc.gpuVariableNames;
 			bool found = false;
@@ -68,11 +126,10 @@ namespace BansheeEngine
 			if (!found)
 				gpuVariableNames.push_back(gpuVariableName);
 		}
-
-		dataParams.erase(name);
 	}
 
-	void SHADER_DESC::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic)
+	template<bool Core>
+	void TSHADER_DESC<Core>::setParamBlockAttribs(const String& name, bool shared, GpuParamBlockUsage usage, StringID rendererSemantic)
 	{
 		SHADER_PARAM_BLOCK_DESC desc;
 		desc.name = name;
@@ -83,26 +140,42 @@ namespace BansheeEngine
 		paramBlocks[name] = desc;
 	}
 
-	ShaderBase::ShaderBase(const String& name, const SHADER_DESC& desc)
-		:mName(name), mDesc(desc)
-	{
+	template struct TSHADER_DESC<false>;
+	template struct TSHADER_DESC<true>;
 
-	}
+	template<bool Core>
+	TShader<Core>::TShader(const String& name, const TSHADER_DESC<Core>& desc, const Vector<SPtr<TechniqueType>>& techniques)
+		:mName(name), mDesc(desc), mTechniques(techniques)
+	{ }
+
+	template<bool Core>
+	TShader<Core>::~TShader() 
+	{ }
 
-	GpuParamType ShaderBase::getParamType(const String& name) const
+	template<bool Core>
+	GpuParamType TShader<Core>::getParamType(const String& name) const
 	{
 		auto findIterData = mDesc.dataParams.find(name);
 		if (findIterData != mDesc.dataParams.end())
 			return GPT_DATA;
 
-		auto findIterObject = mDesc.objectParams.find(name);
-		if (findIterObject != mDesc.objectParams.end())
-			return GPT_OBJECT;
+		auto findIterTexture = mDesc.textureParams.find(name);
+		if (findIterTexture != mDesc.textureParams.end())
+			return GPT_TEXTURE;
+
+		auto findIterBuffer = mDesc.bufferParams.find(name);
+		if (findIterBuffer != mDesc.bufferParams.end())
+			return GPT_BUFFER;
+
+		auto findIterSampler = mDesc.samplerParams.find(name);
+		if (findIterSampler != mDesc.samplerParams.end())
+			return GPT_SAMPLER;
 
 		BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
 	}
 
-	const SHADER_DATA_PARAM_DESC& ShaderBase::getDataParamDesc(const String& name) const
+	template<bool Core>
+	const SHADER_DATA_PARAM_DESC& TShader<Core>::getDataParamDesc(const String& name) const
 	{
 		auto findIterData = mDesc.dataParams.find(name);
 		if (findIterData != mDesc.dataParams.end())
@@ -111,16 +184,38 @@ namespace BansheeEngine
 		BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
 	}
 
-	const SHADER_OBJECT_PARAM_DESC& ShaderBase::getObjectParamDesc(const String& name) const
+	template<bool Core>
+	const SHADER_OBJECT_PARAM_DESC& TShader<Core>::getTextureParamDesc(const String& name) const
+	{
+		auto findIterObject = mDesc.textureParams.find(name);
+		if (findIterObject != mDesc.textureParams.end())
+			return findIterObject->second;
+
+		BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
+	}
+
+	template<bool Core>
+	const SHADER_OBJECT_PARAM_DESC& TShader<Core>::getSamplerParamDesc(const String& name) const
 	{
-		auto findIterObject = mDesc.objectParams.find(name);
-		if (findIterObject != mDesc.objectParams.end())
+		auto findIterObject = mDesc.samplerParams.find(name);
+		if (findIterObject != mDesc.samplerParams.end())
 			return findIterObject->second;
 
 		BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
 	}
 
-	bool ShaderBase::hasDataParam(const String& name) const
+	template<bool Core>
+	const SHADER_OBJECT_PARAM_DESC& TShader<Core>::getBufferParamDesc(const String& name) const
+	{
+		auto findIterObject = mDesc.bufferParams.find(name);
+		if (findIterObject != mDesc.bufferParams.end())
+			return findIterObject->second;
+
+		BS_EXCEPT(InternalErrorException, "Cannot find the parameter with the name: " + name);
+	}
+
+	template<bool Core>
+	bool TShader<Core>::hasDataParam(const String& name) const
 	{
 		auto findIterData = mDesc.dataParams.find(name);
 		if (findIterData != mDesc.dataParams.end())
@@ -129,23 +224,62 @@ namespace BansheeEngine
 		return false;
 	}
 
-	bool ShaderBase::hasObjectParam(const String& name) const
+	template<bool Core>
+	bool TShader<Core>::hasTextureParam(const String& name) const
 	{
-		auto findIterObject = mDesc.objectParams.find(name);
-		if (findIterObject != mDesc.objectParams.end())
+		auto findIterObject = mDesc.textureParams.find(name);
+		if (findIterObject != mDesc.textureParams.end())
 			return true;
 
 		return false;
 	}
 
 	template<bool Core>
-	TShader<Core>::TShader(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueType>>& techniques)
-		:ShaderBase(name, desc), mTechniques(techniques)
-	{ }
+	bool TShader<Core>::hasSamplerParam(const String& name) const
+	{
+		auto findIterObject = mDesc.samplerParams.find(name);
+		if (findIterObject != mDesc.samplerParams.end())
+			return true;
+
+		return false;
+	}
 
 	template<bool Core>
-	TShader<Core>::~TShader() 
-	{ }
+	bool TShader<Core>::hasBufferParam(const String& name) const
+	{
+		auto findIterObject = mDesc.bufferParams.find(name);
+		if (findIterObject != mDesc.bufferParams.end())
+			return true;
+
+		return false;
+	}
+
+	template<bool Core>
+	typename TShader<Core>::TextureType TShader<Core>::getDefaultTexture(UINT32 index) const
+	{
+		if (index < (UINT32)mDesc.textureDefaultValues.size())
+			return mDesc.textureDefaultValues[index];
+
+		return TextureType();
+	}
+
+	template<bool Core>
+	typename TShader<Core>::SamplerStateType TShader<Core>::getDefaultSampler(UINT32 index) const
+	{
+		if (index < (UINT32)mDesc.samplerDefaultValues.size())
+			return mDesc.samplerDefaultValues[index];
+
+		return SamplerStateType();
+	}
+
+	template<bool Core>
+	UINT8* TShader<Core>::getDefaultValue(UINT32 index) const
+	{
+		if (index < (UINT32)mDesc.dataDefaultValues.size())
+			return (UINT8*)&mDesc.dataDefaultValues[index];
+
+		return nullptr;
+	}
 
 	template<bool Core>
 	SPtr<typename TShader<Core>::TechniqueType> TShader<Core>::getBestTechnique() const
@@ -166,13 +300,13 @@ namespace BansheeEngine
 	template class TShader < false > ;
 	template class TShader < true >;
 
-	ShaderCore::ShaderCore(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques)
+	ShaderCore::ShaderCore(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques)
 		:TShader(name, desc, techniques)
 	{
 
 	}
 
-	SPtr<ShaderCore> ShaderCore::create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<TechniqueCore>>& techniques)
+	SPtr<ShaderCore> ShaderCore::create(const String& name, const SHADER_DESC_CORE& desc, const Vector<SPtr<TechniqueCore>>& techniques)
 	{
 		ShaderCore* shaderCore = new (bs_alloc<ShaderCore>()) ShaderCore(name, desc, techniques);
 		SPtr<ShaderCore> shaderCorePtr = bs_shared_ptr<ShaderCore, GenAlloc>(shaderCore);
@@ -199,13 +333,31 @@ namespace BansheeEngine
 		for (auto& technique : mTechniques)
 			techniques.push_back(technique->getCore());
 
-		ShaderCore* shaderCore = new (bs_alloc<ShaderCore>()) ShaderCore(mName, mDesc, techniques);
+		ShaderCore* shaderCore = new (bs_alloc<ShaderCore>()) ShaderCore(mName, convertDesc(mDesc), techniques);
 		SPtr<ShaderCore> shaderCorePtr = bs_shared_ptr<ShaderCore, GenAlloc>(shaderCore);
 		shaderCorePtr->_setThisPtr(shaderCorePtr);
 
 		return shaderCorePtr;
 	}
 
+	SHADER_DESC_CORE Shader::convertDesc(const SHADER_DESC& desc) const
+	{
+		SHADER_DESC_CORE output;
+		output.dataParams = desc.dataParams;
+		output.textureParams = desc.textureParams;
+		output.samplerParams = desc.samplerParams;
+		output.bufferParams = desc.bufferParams;
+		output.paramBlocks = desc.paramBlocks;
+
+		output.queuePriority = desc.queuePriority;
+		output.queueSortType = desc.queueSortType;
+		output.separablePasses = desc.separablePasses;
+		
+		// Ignoring default values as they are not needed for syncing since
+		// they're initialized through the material.
+		return output;
+	}
+
 	void Shader::getCoreDependencies(Vector<SPtr<CoreObject>>& dependencies)
 	{
 		for (auto& technique : mTechniques)
@@ -260,6 +412,47 @@ namespace BansheeEngine
 		return false;
 	}
 
+	struct ShaderDataParamsSizes
+	{
+		ShaderDataParamsSizes()
+		{
+			memset(LOOKUP, 0, sizeof(LOOKUP));
+
+			LOOKUP[(UINT32)GPDT_FLOAT1] = 4;
+			LOOKUP[(UINT32)GPDT_FLOAT2] = 8;
+			LOOKUP[(UINT32)GPDT_FLOAT3] = 12;
+			LOOKUP[(UINT32)GPDT_FLOAT4] = 16;
+			LOOKUP[(UINT32)GPDT_MATRIX_2X2] = 16;
+			LOOKUP[(UINT32)GPDT_MATRIX_2X3] = 24;
+			LOOKUP[(UINT32)GPDT_MATRIX_2X4] = 32;
+			LOOKUP[(UINT32)GPDT_MATRIX_3X2] = 24;
+			LOOKUP[(UINT32)GPDT_MATRIX_3X3] = 36;
+			LOOKUP[(UINT32)GPDT_MATRIX_3X4] = 52;
+			LOOKUP[(UINT32)GPDT_MATRIX_4X2] = 32;
+			LOOKUP[(UINT32)GPDT_MATRIX_4X3 ] = 52;
+			LOOKUP[(UINT32)GPDT_MATRIX_4X4] = 64;
+			LOOKUP[(UINT32)GPDT_INT1] = 4;
+			LOOKUP[(UINT32)GPDT_INT2] = 8;
+			LOOKUP[(UINT32)GPDT_INT3] = 12;
+			LOOKUP[(UINT32)GPDT_INT4] = 16;
+			LOOKUP[(UINT32)GPDT_BOOL] = 1;
+		}
+
+		static const UINT32 NUM_DATA_PARAMS = 25;
+		UINT32 LOOKUP[NUM_DATA_PARAMS];
+	};
+
+	UINT32 Shader::getDataParamSize(GpuParamDataType type)
+	{
+		static const ShaderDataParamsSizes PARAM_SIZES;
+
+		UINT32 idx = (UINT32)type;
+		if (idx < sizeof(PARAM_SIZES.LOOKUP))
+			return PARAM_SIZES.LOOKUP[idx];
+
+		return 0;
+	}
+
 	HShader Shader::create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques)
 	{
 		ShaderPtr newShader = _createPtr(name, desc, techniques);

+ 2 - 2
BansheeEditor/Source/BsScenePicking.cpp

@@ -132,8 +132,8 @@ namespace BansheeEngine
 						HTexture mainTexture;
 						if (useAlphaShader)
 						{
-							const Map<String, SHADER_OBJECT_PARAM_DESC>& objectParams = originalMat->getShader()->getObjectParams();
-							for (auto& objectParam : objectParams)
+							const Map<String, SHADER_OBJECT_PARAM_DESC>& textureParams = originalMat->getShader()->getTextureParams();
+							for (auto& objectParam : textureParams)
 							{
 								if (objectParam.second.rendererSemantic == RPS_Diffuse)
 								{

+ 1 - 1
BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -384,7 +384,7 @@ namespace BansheeEngine
 		SPtr<PassCore> newPass = PassCore::create(passDesc);
 		SPtr<TechniqueCore> newTechnique = TechniqueCore::create(rsName, RendererDefault, { newPass });
 
-		SHADER_DESC shaderDesc;
+		SHADER_DESC_CORE shaderDesc;
 		shaderDesc.setParamBlockAttribs("Static", true, GPBU_DYNAMIC, RBS_Static);
 		shaderDesc.setParamBlockAttribs("PerFrame", true, GPBU_DYNAMIC, RBS_PerFrame);
 		shaderDesc.setParamBlockAttribs("PerObject", true, GPBU_DYNAMIC, RBS_PerObject);

+ 1 - 1
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -468,7 +468,7 @@ namespace BansheeEngine
 		SPtr<PassCore> newPass = PassCore::create(passDesc);
 		SPtr<TechniqueCore> newTechnique = TechniqueCore::create(rsName, RendererDefault, { newPass });
 
-		SHADER_DESC shaderDesc;
+		SHADER_DESC_CORE shaderDesc;
 		shaderDesc.setParamBlockAttribs("PerObject", true, GPBU_DYNAMIC, RBS_PerObject);
 		shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4, RPS_WorldViewProjTfrm);
 

+ 25 - 12
BansheeSL/Source/BsSLFXCompiler.cpp

@@ -1356,7 +1356,6 @@ namespace BansheeEngine
 	{
 		if (parametersNode == nullptr || parametersNode->type != NT_Parameters)
 			return;
-
 		for (int i = 0; i < parametersNode->options->count; i++)
 		{
 			NodeOption* option = &parametersNode->options->entries[i];
@@ -1370,9 +1369,11 @@ namespace BansheeEngine
 			String alias;
 
 			float defaultValue[16];
+			bool hasDefaultValue = false;
 			UINT32 typeId = 0;
 			bool isObjType = false;
 			StringID semantic;
+			SamplerStatePtr samplerState = nullptr;
 
 			for (int j = 0; j < parameter->options->count; j++)
 			{
@@ -1388,6 +1389,7 @@ namespace BansheeEngine
 					break;
 				case OT_ParamValue:
 					memcpy(defaultValue, paramOption->value.matrixValue, sizeof(defaultValue));
+					hasDefaultValue = true;
 					break;
 				case OT_ParamType:
 					parseParamType((ParamType)paramOption->value.intValue, isObjType, typeId);
@@ -1396,8 +1398,7 @@ namespace BansheeEngine
 					semantic = removeQuotes(paramOption->value.strValue);
 					break;
 				case OT_SamplerState:
-					SamplerStatePtr samplerState = parseSamplerState(paramOption->value.nodePtr);
-					// TODO - How to deal with sampler-state default value?
+					samplerState = parseSamplerState(paramOption->value.nodePtr);
 					break;
 				}
 			}
@@ -1405,18 +1406,30 @@ namespace BansheeEngine
 			if (name.empty())
 				continue;
 
-			if (isObjType)
-				desc.addParameter(name, name, (GpuParamObjectType)typeId, semantic);
-			else
-				desc.addParameter(name, name, (GpuParamDataType)typeId, semantic); // TODO - Add default value
-
-			if (!alias.empty())
+			auto addParameter = [&](const String& paramName, const String& gpuVarName)
 			{
 				if (isObjType)
-					desc.addParameter(name, alias, (GpuParamObjectType)typeId, semantic);
+				{
+					GpuParamObjectType objType = (GpuParamObjectType)typeId;
+
+					if (Shader::isSampler(objType) && hasDefaultValue)
+						desc.addParameter(paramName, gpuVarName, objType, samplerState, semantic);
+					else
+						desc.addParameter(paramName, gpuVarName, objType, semantic);
+				}
 				else
-					desc.addParameter(name, alias, (GpuParamDataType)typeId, semantic); // TODO - Add default value
-			}
+				{
+					if (hasDefaultValue)
+						desc.addParameter(paramName, gpuVarName, (GpuParamDataType)typeId, semantic, 1, 0, (UINT8*)defaultValue);
+					else
+						desc.addParameter(paramName, gpuVarName, (GpuParamDataType)typeId, semantic);
+				}
+			};
+
+			addParameter(name, name);
+
+			if (!alias.empty())
+				addParameter(name, alias);
 		}
 	}
 

+ 2 - 0
BansheeUtility/BansheeUtility.vcxproj

@@ -291,6 +291,7 @@
     <ClInclude Include="Include\BsConvexVolume.h" />
     <ClInclude Include="Include\BsEvent.h" />
     <ClInclude Include="Include\BsLineSegment3.h" />
+    <ClInclude Include="Include\BsMatrixNxM.h" />
     <ClInclude Include="Include\BsMessageHandler.h" />
     <ClInclude Include="Include\BsMessageHandlerFwd.h" />
     <ClInclude Include="Include\BsRect3.h" />
@@ -367,6 +368,7 @@
     <ClCompile Include="Source\BsRTTIType.cpp" />
     <ClInclude Include="Include\BsTexAtlasGenerator.h" />
     <ClCompile Include="Source\BsHString.cpp" />
+    <ClInclude Include="Include\BsVectorNI.h" />
     <ClInclude Include="Include\ThirdParty\md5.h" />
   </ItemGroup>
   <ItemGroup>

+ 6 - 0
BansheeUtility/BansheeUtility.vcxproj.filters

@@ -284,6 +284,12 @@
     <ClInclude Include="Include\BsStringID.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsMatrixNxM.h">
+      <Filter>Header Files\Math</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVectorNI.h">
+      <Filter>Header Files\Math</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsThreadPool.cpp">

+ 86 - 0
BansheeUtility/Include/BsMatrixNxM.h

@@ -0,0 +1,86 @@
+#pragma once
+
+#include "BsPrerequisitesUtil.h"
+#include "BsVector3.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Class representing a NxM matrix.
+	 *
+	 * @note	If you need to use matrices for more than just data storage then
+	 *			it is suggested you use specialized Matrix3 or Matrix4 classes
+	 *			as they provide a wide range of functionality.
+	 */
+	template<int N, int M>
+	class MatrixNxM
+	{
+	public:
+		MatrixNxM() {}
+
+		MatrixNxM(float data[N*M])
+		{
+			memcpy(m, data, N*M * sizeof(float));
+		}
+
+		/**
+		 * @brief	Returns a transpose of the matrix (switched columns and rows).
+		 */
+		MatrixNxM<N, M> transpose() const
+		{
+			MatrixNxM<N, M> matTranspose;
+			for (UINT32 row = 0; row < N; row++)
+			{
+				for (UINT32 col = 0; col < M; col++)
+					matTranspose[row][col] = m[col][row];
+			}
+
+			return matTranspose;
+		}
+
+		/**
+         * @brief	Returns a row of the matrix.
+         */
+        inline float* operator[] (UINT32 row) const
+		{
+			assert(row < N);
+
+			return (float*)m[row];
+		}
+
+		MatrixNxM<N, M>& operator= (const MatrixNxM<N, M>& rhs)
+		{
+			memcpy(m, rhs.m, (N*M)*sizeof(float));
+			return *this;
+		}
+
+		bool operator== (const MatrixNxM<N, M>& rhs) const
+		{
+			for (UINT32 row = 0; row < N; row++)
+			{
+				for (UINT32 col = 0; col < M; col++)
+				{
+					if (m[row][col] != rhs.m[row][col])
+						return false;
+				}
+			}
+
+			return true;
+		}
+
+		bool operator!= (const MatrixNxM<N, M>& rhs) const
+		{
+			return !operator==(rhs);
+		}
+
+		float m[N][M];
+	};
+
+	typedef MatrixNxM<2, 2> Matrix2;
+	typedef MatrixNxM<2, 3> Matrix2x3;
+	typedef MatrixNxM<2, 4> Matrix2x4;
+	typedef MatrixNxM<3, 2> Matrix3x2;
+	typedef MatrixNxM<3, 4> Matrix3x4;
+	typedef MatrixNxM<4, 2> Matrix4x2;
+	typedef MatrixNxM<4, 3> Matrix4x3;
+}

+ 1 - 1
BansheeUtility/Include/BsVector2I.h

@@ -5,7 +5,7 @@
 namespace BansheeEngine
 {
 	/**
-	 * @brief	A two dimensional vector with integer
+	 * @brief	A N dimensional vector with integer
 	 *			coordinates.
 	 */
 	struct BS_UTILITY_EXPORT Vector2I

+ 66 - 0
BansheeUtility/Include/BsVectorNI.h

@@ -0,0 +1,66 @@
+#pragma once
+
+#include "BsPrerequisitesUtil.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	A N dimensional vector with integer
+	 *			coordinates.
+	 */
+	template<int N>
+	struct VectorNI
+	{
+		INT32 v[N];
+
+		VectorNI()
+		{ 
+			memset(v, 0, sizeof(v));
+		}
+
+		VectorNI(INT32 val[N])
+		{ 
+			memcpy(v, val, sizeof(v));
+		}
+
+		INT32 operator[] (size_t i) const
+		{
+			assert(i < N);
+
+			return v[i];
+		}
+
+		INT32& operator[] (size_t i)
+		{
+			assert(i < N);
+
+			return v[i];
+		}
+
+		VectorNI& operator= (const VectorNI& rhs)
+		{
+			memcpy(v, rhs.v, sizeof(v));
+
+			return *this;
+		}
+
+		bool operator== (const Vector2I& rhs) const
+		{
+			for (UINT32 i = 0; i < N; i++)
+			{
+				if (v[i] != rhs.v[i])
+					return false;
+			}
+
+			return true;
+		}
+
+		bool operator!= (const Vector2I& rhs) const
+		{
+			return !operator==(*this, rhs);
+		}
+	};
+
+	typedef VectorNI<3> Vector3I;
+	typedef VectorNI<4> Vector4I;
+}

+ 13 - 11
TODO.txt

@@ -96,20 +96,21 @@ Later:
 ----------------------------------------------------------------------
 Include files:
 
-Modify all engine/editor shaders so they use includes
-Add support for shader automatic recompilation if includes change
- - This duty falls on ProjectLibrary. It needs to track shader dependencies, and track
-   include file move/rename/delete/reimport.
+Shader dependencies:
+ - Store include dependencies in Shader itself
+   - Store by the source path, not referencing the asset
+   - Update shader RTTI so it's properly serialized
+ - Add project library template method:
+  - getImportDependencies<Type>(obj)
+    - shader would return a list of include paths, and other types can include other objects
+  - project library keeps a list of all such dependencies
+   - it detects when the dependencies change (i.e. are moved, renamed, deleted or reimported) and also triggers a reimport of the dependentee
+    - TODO - what if multiple dependencies are reimported at once? do I want to reimport the dependntee 
+       for each one or should there be some kind of a delay?
 
 Test:
- - Test include merging and ensure new techniques/passes are created if matching ones cannot be found
- - If errors are reported properly from FX compiler and GPU program compilers
  - Try preprocessing using one RenderAPi and then load the shaders using another and see if they're created normally
-
-----
-
-Add support for registering default parameters (add a set of addParameter methods to SHADER_DESC). Keep sampler states and textures in a dynamic array, and all other data in a dynamic byte array.
- - Make sure initializing the material properly sets up default parameters
+ - Test if default values work
 
 ----------------------------------------------------------------------
 Scene View
@@ -127,6 +128,7 @@ Other
 
 Got a crash on shutdown that was caused by locking a mutex in an Event destructor. Event was Platform::onMouseCaptureChanged. 
 Issue happened when I closed the app via the X button (if that's relevant). It doesn't seem to happen always.
+ - This is likely due to some other error. When VS finds an exception it triggers a dialog box which triggers the msg loop in-engine and causes another exception.
 
 Create a stack allocatable custom vector implementation and make getResourceDependencies and getCoreDependencies use it.
  - These methods are called often and cause allocations whenever they are.