Browse Source

Work on transparent rendering path
Also a few fixes:
- Issue with default shader data not being applied
- Issue with OpenGL not parsing int/uint sampled buffers
- Issue with shader flags not properly being sent to the core-thread counterpart object
- Issue with material data parameter syncing between sim and core threads
- Issue with DX11 not properly parsing non-structured buffer parameters in shaders

BearishSun 9 years ago
parent
commit
b2dd0ffa03
29 changed files with 445 additions and 155 deletions
  1. 4 3
      Data/Examples/Example.bsl
  2. BIN
      Data/Examples/Example.bsl.asset
  3. 8 4
      Data/Raw/Engine/DataList.json
  4. 23 19
      Data/Raw/Engine/Includes/BasePass.bslinc
  5. 4 13
      Data/Raw/Engine/Includes/LightingCommon.bslinc
  6. 8 6
      Data/Raw/Engine/Includes/NormalVertexInput.bslinc
  7. 8 6
      Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc
  8. 8 8
      Data/Raw/Engine/Includes/Surface.bslinc
  9. 1 1
      Data/Raw/Engine/Shaders/Default.bsl
  10. 3 3
      Data/Raw/Engine/Shaders/Diffuse.bsl
  11. 3 0
      Data/Raw/Engine/Shaders/LightGridLLCreation.bsl
  12. 10 8
      Data/Raw/Engine/Shaders/LightGridLLReduction.bsl
  13. 8 0
      Data/Raw/Engine/Shaders/TiledDeferredLighting.bsl
  14. 168 0
      Data/Raw/Engine/Shaders/Transparent.bsl
  15. 5 3
      Documentation/Manuals/Native/bslfx.md
  16. 3 3
      Source/BansheeCore/Source/BsMaterialParams.cpp
  17. 24 2
      Source/BansheeCore/Source/BsShader.cpp
  18. 13 2
      Source/BansheeD3D11RenderAPI/Source/BsD3D11HLSLParamParser.cpp
  19. 3 1
      Source/BansheeEngine/Include/BsBuiltinResources.h
  20. 5 1
      Source/BansheeEngine/Source/BsBuiltinResources.cpp
  21. 2 0
      Source/BansheeGLRenderAPI/Source/BsGLSLParamParser.cpp
  22. 4 1
      Source/MBansheeEditor/Inspectors/MaterialInspector.cs
  23. 2 1
      Source/MBansheeEngine/Utility/Builtin.cs
  24. 22 5
      Source/RenderBeast/Include/BsLightRendering.h
  25. 2 0
      Source/RenderBeast/Include/BsRenderBeast.h
  26. 6 0
      Source/RenderBeast/Include/BsRendererObject.h
  27. 47 42
      Source/RenderBeast/Source/BsLightRendering.cpp
  28. 11 0
      Source/RenderBeast/Source/BsObjectRendering.cpp
  29. 40 23
      Source/RenderBeast/Source/BsRenderBeast.cpp

+ 4 - 3
Data/Examples/Example.bsl

@@ -1,4 +1,4 @@
-#include "$ENGINE$\DeferredBasePass.bslinc"
+#include "$ENGINE$\BasePass.bslinc"
 
 Parameters = 
 {
@@ -44,8 +44,9 @@ Technique : base("Surface") =
 		Fragment =
 		{
 			layout(location = 0) in vec2 uv0;
-			layout(location = 1) in vec3 tangentToWorldZ;
-			layout(location = 2) in vec4 tangentToWorldX;			
+			layout(location = 1) in vec3 worldPosition;
+			layout(location = 2) in vec3 tangentToWorldZ;
+			layout(location = 3) in vec4 tangentToWorldX;			
 		
 			layout(binding = 4) uniform sampler2D tex;
 

BIN
Data/Examples/Example.bsl.asset


+ 8 - 4
Data/Raw/Engine/DataList.json

@@ -48,10 +48,6 @@
         }
     ],
     "Includes": [
-        {
-            "Path": "DeferredBasePass.bslinc",
-            "UUID": "d4078f9c-d7e9-4d63-b506-4d270c08b01e"
-        },
         {
             "Path": "GBuffer.bslinc",
             "UUID": "ef1a179a-4bf9-4dbd-b62a-e18524d959b6"
@@ -111,6 +107,10 @@
         {
             "Path": "SurfaceData.bslinc",
             "UUID": "3364cb35-9140-4571-8fae-d5648ae7386f"
+        },
+        {
+            "Path": "BasePass.bslinc",
+            "UUID": "ec1d3d37-5509-4bcb-9be2-93208d6ae224"
         }
     ],
     "Shaders": [
@@ -205,6 +205,10 @@
         {
             "Path": "LightGridLLReduction.bsl",
             "UUID": "d190e4e1-5ea9-4961-9ee3-b5df218cb5e6"
+        },
+        {
+            "Path": "Transparent.bsl",
+            "UUID": "10db2029-145c-424e-8399-2be48aa66680"
         }
     ],
     "Skin": [

+ 23 - 19
Data/Raw/Engine/Includes/DeferredBasePass.bslinc → Data/Raw/Engine/Includes/BasePass.bslinc

@@ -7,8 +7,9 @@
 #define USE_BLEND_SHAPES
 #include "$ENGINE$\SkinnedVertexInput.bslinc"
 #include "$ENGINE$\NormalVertexInput.bslinc"
+#undef USE_BLEND_SHAPES
 
-Technique : base("DeferredBasePassCommon") =
+Technique : base("BasePassCommon") =
 {
 	Language = "HLSL11";
 	
@@ -23,6 +24,7 @@ Technique : base("DeferredBasePassCommon") =
 				VertexIntermediate intermediate = getVertexIntermediate(input);
 				float4 worldPosition = getVertexWorldPosition(input, intermediate);
 				
+				output.worldPosition = worldPosition.xyz;
 				output.position = mul(gMatViewProj, worldPosition);
 				populateVertexOutput(input, intermediate, output);
 							
@@ -48,51 +50,51 @@ Technique : base("DeferredBasePassCommon") =
 };
 
 Technique
- : base("DeferredBasePass")
+ : base("BasePass")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("NormalVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 { 
 	Language = "HLSL11";
 };
 
 Technique
- : base("DeferredBasePassSkinned")
+ : base("BasePassSkinned")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("SkinnedVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "HLSL11";
 };
 
 Technique
- : base("DeferredBasePassMorph")
+ : base("BasePassMorph")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("MorphVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "HLSL11";
 };
 
 Technique
- : base("DeferredBasePassSkinnedMorph")
+ : base("BasePassSkinnedMorph")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("SkinnedMorphVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "HLSL11";
 };
 
 Technique 
-	: base("DeferredBasePassCommon") =
+	: base("BasePassCommon") =
 {
 	Language = "GLSL";
 	
@@ -107,8 +109,10 @@ Technique
 			
 				vec4 worldPos;
 				getVertexWorldPosition(intermediate, worldPos);
-			
+				
+				outWorldPosition = worldPos.xyz;
 				gl_Position = gMatViewProj * worldPos;
+				
 				populateVertexOutput(intermediate);
 			}
 		};
@@ -129,45 +133,45 @@ Technique
 };
 
 Technique
- : base("DeferredBasePass")
+ : base("BasePass")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("NormalVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 { 
 	Language = "GLSL";
 };
 
 Technique
- : base("DeferredBasePassSkinned")
+ : base("BasePassSkinned")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("SkinnedVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "GLSL";
 };
 
 Technique
- : base("DeferredBasePassMorph")
+ : base("BasePassMorph")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("MorphVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "GLSL";
 };
 
 Technique
- : base("DeferredBasePassSkinnedMorph")
+ : base("BasePassSkinnedMorph")
  : inherits("GBuffer")
  : inherits("PerCameraData")
  : inherits("PerObjectData")
  : inherits("SkinnedMorphVertexInput")
- : inherits("DeferredBasePassCommon") =
+ : inherits("BasePassCommon") =
 {
 	Language = "GLSL";
 };

+ 4 - 13
Data/Raw/Engine/Includes/LightingCommon.bslinc

@@ -1,19 +1,11 @@
-#include "$ENGINE$\PerCameraData.bslinc"
-
-Blocks =
-{
-	Block PerCamera : auto("PerCamera");
-};
-
 Technique
- : base("LightingCommon")
- : inherits("PerCameraData") =
+ : base("LightingCommon") =
 {
 	Language = "HLSL11";
 	
 	Pass =
 	{
-		Compute = 
+		Common = 
 		{
 			#define PI 3.1415926
 			#define HALF_PI 1.5707963
@@ -88,14 +80,13 @@ Technique
 };
 
 Technique
- : base("LightingCommon")
- : inherits("PerCameraData") =
+ : base("LightingCommon") =
 {
 	Language = "GLSL";
 	
 	Pass =
 	{
-		Compute = 
+		Common = 
 		{
 			#define PI 3.1415926
 			#define HALF_PI 1.5707963

+ 8 - 6
Data/Raw/Engine/Includes/NormalVertexInput.bslinc

@@ -15,6 +15,7 @@ Technique
 			{
 				float4 position : SV_Position;
 				float2 uv0 : TEXCOORD0;
+				float3 worldPosition : TEXCOORD1;
 				
 				float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
 				float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
@@ -124,9 +125,10 @@ Technique
 				layout(location = 5) in vec4 bs_normal1;
 			#endif
 		
-			layout(location = 0) out vec2 uv0;
-			layout(location = 1) out vec3 tangentToWorldZ;
-			layout(location = 2) out vec4 tangentToWorldX;	
+			layout(location = 0) out vec2 outUV0;
+			layout(location = 1) out vec3 outWorldPosition;
+			layout(location = 2) out vec3 outTangentToWorldZ;
+			layout(location = 3) out vec4 outTangentToWorldX;	
 		
 			out gl_PerVertex
 			{
@@ -182,10 +184,10 @@ Technique
 			
 			void populateVertexOutput(VertexIntermediate intermediate)
 			{
-				uv0 = bs_texcoord0;
+				outUV0 = bs_texcoord0;
 				
-				tangentToWorldZ = intermediate.worldNormal;
-				tangentToWorldX = intermediate.worldTangent;
+				outTangentToWorldZ = intermediate.worldNormal;
+				outTangentToWorldX = intermediate.worldTangent;
 			}
 		};
 	};

+ 8 - 6
Data/Raw/Engine/Includes/SkinnedVertexInput.bslinc

@@ -20,6 +20,7 @@ Technique
 			{
 				float4 position : SV_Position;
 				float2 uv0 : TEXCOORD0;
+				float3 worldPosition : TEXCOORD1;
 				
 				float3 tangentToWorldZ : NORMAL; // Note: Half-precision could be used
 				float4 tangentToWorldX : TANGENT; // Note: Half-precision could be used
@@ -162,9 +163,10 @@ Technique
 				layout(location = 7) in vec4 bs_normal1;
 			#endif
 			
-			layout(location = 0) out vec2 uv0;
-			layout(location = 1) out vec3 tangentToWorldZ;
-			layout(location = 2) out vec4 tangentToWorldX;	
+			layout(location = 0) out vec2 outUV0;
+			layout(location = 1) out vec3 outWorldPosition;
+			layout(location = 2) out vec3 outTangentToWorldZ;
+			layout(location = 3) out vec4 outTangentToWorldX;	
 			
 			layout(binding = 3) uniform samplerBuffer boneMatrices;
 		
@@ -260,10 +262,10 @@ Technique
 			
 			void populateVertexOutput(VertexIntermediate intermediate)
 			{
-				uv0 = bs_texcoord0;
+				outUV0 = bs_texcoord0;
 				
-				tangentToWorldZ = intermediate.worldNormal;
-				tangentToWorldX = intermediate.worldTangent;
+				outTangentToWorldZ = intermediate.worldNormal;
+				outTangentToWorldX = intermediate.worldTangent;
 			}
 		};
 	};

+ 8 - 8
Data/Raw/Engine/Includes/Surface.bslinc

@@ -1,12 +1,12 @@
 Technique 
- : inherits("DeferredBasePass")
+ : inherits("BasePass")
  : inherits("Surface") =
 {
 	Language = "HLSL11";
 };
 
 Technique 
- : inherits("DeferredBasePassSkinned")
+ : inherits("BasePassSkinned")
  : inherits("Surface") =
 {
 	Language = "HLSL11";
@@ -14,7 +14,7 @@ Technique
 };
 
 Technique 
- : inherits("DeferredBasePassMorph")
+ : inherits("BasePassMorph")
  : inherits("Surface") =
 {
 	Language = "HLSL11";
@@ -22,7 +22,7 @@ Technique
 };
 
 Technique 
- : inherits("DeferredBasePassSkinnedMorph")
+ : inherits("BasePassSkinnedMorph")
  : inherits("Surface") =
 {
 	Language = "HLSL11";
@@ -30,14 +30,14 @@ Technique
 };
 
 Technique 
- : inherits("DeferredBasePass")
+ : inherits("BasePass")
  : inherits("Surface") =
 {
 	Language = "GLSL";
 };
 
 Technique 
- : inherits("DeferredBasePassSkinned")
+ : inherits("BasePassSkinned")
  : inherits("Surface") =
 {
 	Language = "GLSL";
@@ -45,7 +45,7 @@ Technique
 };
 
 Technique 
- : inherits("DeferredBasePassMorph")
+ : inherits("BasePassMorph")
  : inherits("Surface") =
 {
 	Language = "GLSL";
@@ -53,7 +53,7 @@ Technique
 };
 
 Technique 
- : inherits("DeferredBasePassSkinnedMorph")
+ : inherits("BasePassSkinnedMorph")
  : inherits("Surface") =
 {
 	Language = "GLSL";

+ 1 - 1
Data/Raw/Engine/Shaders/Default.bsl

@@ -1,4 +1,4 @@
-#include "$ENGINE$\DeferredBasePass.bslinc"
+#include "$ENGINE$\BasePass.bslinc"
 
 Technique : base("Surface") =
 {

+ 3 - 3
Data/Raw/Engine/Shaders/Diffuse.bsl

@@ -1,4 +1,4 @@
-#include "$ENGINE$\DeferredBasePass.bslinc"
+#include "$ENGINE$\BasePass.bslinc"
 
 Parameters =
 {
@@ -53,8 +53,8 @@ Technique : base("Surface") =
 		Fragment =
 		{
 			layout(location = 0) in vec2 uv0;
-			layout(location = 1) in vec3 tangentToWorldZ;
-			layout(location = 2) in vec4 tangentToWorldX;			
+			layout(location = 2) in vec3 tangentToWorldZ;
+			layout(location = 3) in vec4 tangentToWorldX;			
 		
 			layout(binding = 4) uniform sampler2D gAlbedoTex;
 			layout(binding = 5) uniform sampler2D gNormalTex;

+ 3 - 0
Data/Raw/Engine/Shaders/LightGridLLCreation.bsl

@@ -1,4 +1,5 @@
 #include "$ENGINE$\GBuffer.bslinc"
+#include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\LightingCommon.bslinc"
 
 Blocks =
@@ -8,6 +9,7 @@ Blocks =
 
 Technique
  : inherits("GBuffer")
+ : inherits("PerCameraData")
  : inherits("LightingCommon") =
 {
 	Language = "HLSL11";
@@ -133,6 +135,7 @@ Technique
 
 Technique
  : inherits("GBuffer")
+ : inherits("PerCameraData")
  : inherits("LightingCommon") =
 {
 	Language = "GLSL";

+ 10 - 8
Data/Raw/Engine/Shaders/LightGridLLReduction.bsl

@@ -1,4 +1,6 @@
-Technique
+#include "$ENGINE$\PerCameraData.bslinc"
+
+Technique : inherits("PerCameraData") = 
 {
 	Language = "HLSL11";
 	
@@ -71,7 +73,7 @@ Technique
 	};
 };
 
-Technique
+Technique : inherits("PerCameraData") = 
 {
 	Language = "GLSL";
 	
@@ -108,15 +110,15 @@ Technique
 					return;
 					
 				uint maxNumLinks = gNumCells * gMaxNumLightsPerCell;	
-				uint cellIdx = (gl_GlobalInvocationID.z * gGridSize.y + gl_GlobalInvocationID.y) * gGridSize.x + gl_GlobalInvocationID.x;
+				int cellIdx = int((gl_GlobalInvocationID.z * gGridSize.y + gl_GlobalInvocationID.y) * gGridSize.x + gl_GlobalInvocationID.x);
 				
 				// First count total number of lights affecting the tile
-				uint currentIdx = texelFetch(gLinkedListHeads, cellIdx).x;
+				int currentIdx = int(texelFetch(gLinkedListHeads, cellIdx).x);
 				uint numLights = 0;
 				while(currentIdx != 0xFFFFFFFF)
 				{
 					numLights++;
-					currentIdx = texelFetch(gLinkedList, currentIdx).y;
+					currentIdx = int(texelFetch(gLinkedList, currentIdx).y);
 				}
 				
 				// Allocate enough room and remember the offset to indices
@@ -125,15 +127,15 @@ Technique
 
 				// Actually write light indices
 				// Note: Values are written in the reverse order than they were found in
-				currentIdx = texelFetch(gLinkedListHeads, cellIdx).x;
+				currentIdx = int(texelFetch(gLinkedListHeads, cellIdx).x);
 				uint lightIdx = 0;
 				while(currentIdx != 0xFFFFFFFF)
 				{
 					uvec2 entry = texelFetch(gLinkedList, currentIdx).xy;
 				
-					imageStore(gGridLightIndices, indicesStart + lightIdx, uvec4(entry.x, 0, 0, 0));
+					imageStore(gGridLightIndices, int(indicesStart + lightIdx), uvec4(entry.x, 0, 0, 0));
 					
-					currentIdx = entry.y;
+					currentIdx = int(entry.y);
 					lightIdx++;
 				}
 			}

+ 8 - 0
Data/Raw/Engine/Shaders/TiledDeferredLighting.bsl

@@ -1,4 +1,5 @@
 #include "$ENGINE$\GBuffer.bslinc"
+#include "$ENGINE$\PerCameraData.bslinc"
 #include "$ENGINE$\LightingCommon.bslinc"
 
 Parameters =
@@ -12,8 +13,14 @@ Parameters =
 	Texture2D 	gDepthBufferTex : auto("GBufferDepth");
 };
 
+Blocks =
+{
+	Block PerCamera : auto("PerCamera");
+};
+
 Technique 
   : inherits("GBuffer")
+  : inherits("PerCameraData")
   : inherits("LightingCommon") =
 {
 	Language = "HLSL11";
@@ -273,6 +280,7 @@ Technique
 
 Technique 
   : inherits("GBuffer")
+  : inherits("PerCameraData")
   : inherits("LightingCommon") =
 {
 	Language = "GLSL";

+ 168 - 0
Data/Raw/Engine/Shaders/Transparent.bsl

@@ -0,0 +1,168 @@
+#include "$ENGINE$\BasePass.bslinc"
+#include "$ENGINE$\LightingCommon.bslinc"
+
+Parameters =
+{
+	Sampler2D 	gAlbedoSamp : alias("gAlbedoTex");
+	Sampler2D 	gNormalSamp : alias("gNormalTex");
+	
+	Texture2D 	gAlbedoTex;
+	Texture2D	gNormalTex = "normal";
+	
+	float		gOpacity   = 1.0f;
+};
+
+Blocks =
+{
+	Block MaterialParams;
+};
+
+Transparent = true;
+
+Technique 
+ : inherits("LightingCommon")
+ : base("Surface") =
+{
+	Language = "HLSL11";
+	
+	Pass =
+	{
+		DepthWrite = false;
+	
+		Target = 
+		{
+			Blend = true;
+			Color = { SRCA, SRCIA, ADD };
+		};	
+	
+		Fragment =
+		{
+			SamplerState gAlbedoSamp : register(s0);
+			SamplerState gNormalSamp : register(s1);
+			
+			Texture2D gAlbedoTex : register(t0);
+			Texture2D gNormalTex : register(t1);
+			
+			StructuredBuffer<LightData> gLights : register(t2);
+		
+			cbuffer LightParams : register(b4)
+			{
+				// Offsets at which specific light types begin in gLights buffer
+				// Assumed directional lights start at 0
+				// x - offset to point lights, y - offset to spot lights, z - total number of lights
+				uint3 gLightOffsets;
+			}
+			
+			cbuffer MaterialParams : register(b5)
+			{
+				float gOpacity;
+			}
+			
+			float4 main(in VStoFS input) : SV_Target0
+			{
+				float3 normal = normalize(gNormalTex.Sample(gNormalSamp, input.uv0) * 2.0f - float3(1, 1, 1));
+				float3 worldNormal = calcWorldNormal(input, normal);
+			
+				SurfaceData surfaceData;
+				surfaceData.albedo = gAlbedoTex.Sample(gAlbedoSamp, input.uv0);
+				surfaceData.worldNormal.xyz = worldNormal;
+				
+				float3 lightAccumulator = 0;
+				for(uint i = 0; i < gLightOffsets[0]; ++i)
+					lightAccumulator += getDirLightContibution(surfaceData, gLights[i]);
+				
+				for (uint i = gLightOffsets[0]; i < gLightOffsets[1]; ++i)
+					lightAccumulator += getPointLightContribution(input.worldPosition, surfaceData, gLights[i]);
+
+				for(uint i = gLightOffsets[1]; i < gLightOffsets[2]; ++i)
+					lightAccumulator += getSpotLightContribution(input.worldPosition, surfaceData, gLights[i]);
+				
+				float3 diffuse = surfaceData.albedo.xyz / PI;
+				return float4(diffuse * lightAccumulator, gOpacity); // TODO - Add better lighting model later
+			}	
+		};
+	};
+};
+
+Technique 
+ : inherits("LightingCommon")
+ : base("Surface") =
+{
+	Language = "GLSL";
+	
+	Pass =
+	{
+		DepthWrite = false;
+		
+		Target = 
+		{
+			Blend = true;
+			Color = { SRCA, SRCIA, ADD };
+		};
+	
+		Fragment =
+		{
+			layout(location = 0) in vec2 uv0;
+			layout(location = 1) in vec3 worldPosition;
+			layout(location = 2) in vec3 tangentToWorldZ;
+			layout(location = 3) in vec4 tangentToWorldX;			
+		
+			layout(binding = 4) uniform sampler2D gAlbedoTex;
+			layout(binding = 5) uniform sampler2D gNormalTex;
+
+			layout(std430, binding = 6) buffer gLights
+			{
+				LightData[] gLightsData;
+			};
+						
+			layout(binding = 7, std140) uniform LightParams
+			{
+				// Offsets at which specific light types begin in gLights buffer
+				// Assumed directional lights start at 0
+				// x - offset to point lights, y - offset to spot lights, z - total number of lights
+				uvec3 gLightOffsets;
+			};
+			
+			layout(binding = 8, std140) uniform MaterialParams
+			{
+				float gOpacity;
+			};
+			
+			layout(location = 0) out vec4 fragColor;
+			
+			void main()
+			{
+				vec3 normal = normalize(texture(gNormalTex, uv0).xyz * 2.0f - vec3(1, 1, 1));
+				vec3 worldNormal = calcWorldNormal(tangentToWorldZ, tangentToWorldX, normal);
+			
+				SurfaceData surfaceData;
+				surfaceData.albedo = texture(gAlbedoTex, uv0);
+				surfaceData.worldNormal.xyz = worldNormal;
+				
+				vec3 lightAccumulator = vec3(0, 0, 0);
+				for(uint i = 0; i < gLightOffsets[0]; ++i)
+				{
+					LightData lightData = gLightsData[i];
+					lightAccumulator += getDirLightContibution(surfaceData, lightData);
+				}
+				
+				for (uint i = gLightOffsets[0]; i < gLightOffsets[1]; ++i)
+				{
+					LightData lightData = gLightsData[i];
+					lightAccumulator += getPointLightContribution(worldPosition, surfaceData, lightData);
+				}
+
+				for(uint i = gLightOffsets[1]; i < gLightOffsets[2]; ++i)
+				{
+					LightData lightData = gLightsData[i];
+					lightAccumulator += getSpotLightContribution(worldPosition, surfaceData, lightData);
+				}
+				
+				vec3 diffuse = surfaceData.albedo.xyz / PI; // TODO - Add better lighting model later
+				fragColor = vec4(diffuse * lightAccumulator, gOpacity); 
+			}	
+		};
+	};
+};
+
+#include "$ENGINE$\Surface.bslinc"

+ 5 - 3
Documentation/Manuals/Native/bslfx.md

@@ -186,7 +186,7 @@ Technique block should therefore always contain a "Language" property. This will
 	Language = "HLSL"
 ~~~~~~~~~~~~~~
 
-Supported values are "HLSL" (DirectX 11 HLSL), "HLSL9" (DirectX 9 HLSL), and "GLSL".
+Supported values are "HLSL" and "GLSL".
 
 In case you are using a non-standard render, you can also specify a renderer using the "Renderer" property. This will ensure the propert technique is used as you switch between renderers.
 ~~~~~~~~~~~~~~
@@ -201,9 +201,11 @@ And finally you may specify an optional set of tags that serve as hints to the r
 ~~~~~~~~~~~~~~
 
 Currently recognized tags by the default renderer are:
- - Animated - When renderer detects it is rendering a mesh that supports skeletal or blend shape animation, it will prefer to pick a technique with this tag, rather than one without it.
+ - Skinned - Technique capable of rendering a skin animated mesh
+ - Morph -  Technique capable of rendering a blend shape animated mesh
+ - SkinnedMorph -  Technique capable of rendering a skin and blend shape animated mesh
 
-Unrecognized tags will just be ignored. Renderer can be extended so it supports custom tags.
+When renderer detects an object is using skinned or morph animation (or both), it will prefer to pick a technique with the relevant tag. Unrecognized tags will just be ignored. Renderer can be extended so it supports custom tags.
  
 Once the base properties are defined you can start defining code blocks and states.
 

+ 3 - 3
Source/BansheeCore/Source/BsMaterialParams.cpp

@@ -575,7 +575,7 @@ namespace bs
 				numDirtyDataParams++;
 
 				UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
-				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.type];
+				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.dataType];
 				UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
 
 				dataParamSize += arraySize * paramSize;
@@ -638,7 +638,7 @@ namespace bs
 			case ParamType::Data:
 			{
 				UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
-				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.type];
+				const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[(int)param.dataType];
 				UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
 
 				UINT32 dataSize = arraySize * paramSize;
@@ -791,7 +791,7 @@ namespace bs
 			param.version = mParamVersion;
 
 			UINT32 arraySize = param.arraySize > 1 ? param.arraySize : 1;
-			const GpuParamDataTypeInfo& typeInfo = bs::GpuParams::PARAM_SIZES.lookup[(int)param.type];
+			const GpuParamDataTypeInfo& typeInfo = bs::GpuParams::PARAM_SIZES.lookup[(int)param.dataType];
 			UINT32 paramSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
 
 			UINT32 dataParamSize = arraySize * paramSize;

+ 24 - 2
Source/BansheeCore/Source/BsShader.cpp

@@ -10,6 +10,7 @@
 #include "BsFrameAlloc.h"
 #include "BsPass.h"
 #include "BsSamplerState.h"
+#include "BsTexture.h"
 
 namespace bs
 {
@@ -35,8 +36,6 @@ namespace bs
 		desc.rendererSemantic = rendererSemantic;
 		desc.elementSize = elementSize;
 
-		dataParams[name] = desc;
-
 		if (defaultValue != nullptr)
 		{
 			desc.defaultValueIdx = (UINT32)dataDefaultValues.size();
@@ -47,6 +46,8 @@ namespace bs
 		}
 		else
 			desc.defaultValueIdx = (UINT32)-1;
+
+		dataParams[name] = desc;
 	}
 
 	template<bool Core>
@@ -358,9 +359,30 @@ namespace bs
 		output.bufferParams = desc.bufferParams;
 		output.paramBlocks = desc.paramBlocks;
 
+		output.dataDefaultValues = desc.dataDefaultValues;
+
+		output.samplerDefaultValues.resize(desc.samplerDefaultValues.size());
+		for (UINT32 i = 0; i < (UINT32)desc.samplerDefaultValues.size(); i++)
+		{
+			if (desc.samplerDefaultValues[i] != nullptr)
+				output.samplerDefaultValues.push_back(desc.samplerDefaultValues[i]->getCore());
+			else
+				output.samplerDefaultValues.push_back(nullptr);
+		}
+
+		output.textureDefaultValues.resize(desc.textureDefaultValues.size());
+		for (UINT32 i = 0; i < (UINT32)desc.textureDefaultValues.size(); i++)
+		{
+			if (desc.textureDefaultValues[i].isLoaded())
+				output.textureDefaultValues.push_back(desc.textureDefaultValues[i]->getCore());
+			else
+				output.textureDefaultValues.push_back(nullptr);
+		}
+
 		output.queuePriority = desc.queuePriority;
 		output.queueSortType = desc.queueSortType;
 		output.separablePasses = desc.separablePasses;
+		output.flags = desc.flags;
 		
 		// Ignoring default values as they are not needed for syncing since
 		// they're initialized through the material.

+ 13 - 2
Source/BansheeD3D11RenderAPI/Source/BsD3D11HLSLParamParser.cpp

@@ -113,7 +113,9 @@ namespace bs { namespace ct
 					desc.samplers.insert(std::make_pair(memberDesc.name, memberDesc));
 					break;
 				case D3D_SIT_TEXTURE:
-					switch(resourceDesc.Dimension)
+				{
+					bool isTexture = true;
+					switch (resourceDesc.Dimension)
 					{
 					case D3D_SRV_DIMENSION_TEXTURE1D:
 					case D3D_SRV_DIMENSION_TEXTURE1DARRAY:
@@ -134,6 +136,10 @@ namespace bs { namespace ct
 					case D3D_SRV_DIMENSION_TEXTURE2DMSARRAY:
 						memberDesc.type = GPOT_TEXTURE2DMS;
 						break;
+					case D3D_SRV_DIMENSION_BUFFER:
+						memberDesc.type = GPOT_BYTE_BUFFER;
+						isTexture = false;
+						break;
 					default:
 						LOGWRN("Skipping texture because it has unsupported dimension: " + toString(resourceDesc.Dimension));
 					}
@@ -141,8 +147,13 @@ namespace bs { namespace ct
 					if (memberDesc.type != GPOT_UNKNOWN)
 					{
 						memberDesc.set = mapParameterToSet(type, ParamType::Texture);
-						desc.textures.insert(std::make_pair(memberDesc.name, memberDesc));
+
+						if (isTexture)
+							desc.textures.insert(std::make_pair(memberDesc.name, memberDesc));
+						else
+							desc.buffers.insert(std::make_pair(memberDesc.name, memberDesc));
 					}
+				}
 					break;
 				case D3D_SIT_STRUCTURED:
 					memberDesc.type = GPOT_STRUCTURED_BUFFER;

+ 3 - 1
Source/BansheeEngine/Include/BsBuiltinResources.h

@@ -29,7 +29,7 @@ namespace bs
 	/** Types of builtin shaders that are always available. */
 	enum class BuiltinShader
 	{
-		Standard, Custom
+		Custom, Standard, Transparent
 	};
 
 	/**	Holds references to built-in resources used by the core engine. */
@@ -180,6 +180,7 @@ namespace bs
 		HShader mShaderSpriteNonAlphaImage;
 		HShader mShaderSpriteLine;
 		HShader mShaderDiffuse;
+		HShader mShaderTransparent;
 
 		SPtr<ResourceManifest> mResourceManifest;
 
@@ -322,6 +323,7 @@ namespace bs
 		static const WString ShaderSpriteImageNoAlphaFile;
 		static const WString ShaderSpriteLineFile;
 		static const WString ShaderDiffuseFile;
+		static const WString ShaderTransparentFile;
 
 		static const WString MeshSphereFile;
 		static const WString MeshBoxFile;

+ 5 - 1
Source/BansheeEngine/Source/BsBuiltinResources.cpp

@@ -185,6 +185,7 @@ namespace bs
 	const WString BuiltinResources::ShaderSpriteImageNoAlphaFile = L"SpriteImageNoAlpha.bsl";
 	const WString BuiltinResources::ShaderSpriteLineFile = L"SpriteLine.bsl";
 	const WString BuiltinResources::ShaderDiffuseFile = L"Diffuse.bsl";
+	const WString BuiltinResources::ShaderTransparentFile = L"Transparent.bsl";
 
 	/************************************************************************/
 	/* 								MESHES							  		*/
@@ -278,6 +279,7 @@ namespace bs
 		mShaderSpriteNonAlphaImage = getShader(ShaderSpriteImageNoAlphaFile);
 		mShaderSpriteLine = getShader(ShaderSpriteLineFile);
 		mShaderDiffuse = getShader(ShaderDiffuseFile);
+		mShaderTransparent = getShader(ShaderTransparentFile);
 
 		SPtr<PixelData> dummyPixelData = PixelData::create(2, 2, 1, PF_R8G8B8A8);
 
@@ -1311,7 +1313,9 @@ namespace bs
 		switch(type)
 		{
 		case BuiltinShader::Standard:
-				return mShaderDiffuse;
+			return mShaderDiffuse;
+		case BuiltinShader::Transparent:
+			return mShaderTransparent;
 		}
 
 		return HShader();

+ 2 - 0
Source/BansheeGLRenderAPI/Source/BsGLSLParamParser.cpp

@@ -397,6 +397,8 @@ namespace bs { namespace ct
 				isImage = true;
 				break;
 			case GL_SAMPLER_BUFFER:
+			case GL_UNSIGNED_INT_SAMPLER_BUFFER:
+			case GL_INT_SAMPLER_BUFFER:
 			case GL_IMAGE_BUFFER:
 			case GL_UNSIGNED_INT_IMAGE_BUFFER:
 			case GL_INT_IMAGE_BUFFER:

+ 4 - 1
Source/MBansheeEditor/Inspectors/MaterialInspector.cs

@@ -112,8 +112,11 @@ namespace BansheeEditor
         {
             // Note: Need a better way to detect the builtin shader perhaps (store it in Material?)
             Shader standardShader = Builtin.GetShader(BuiltinShader.Standard);
-            if(standardShader == shader)
+            Shader transparentShader = Builtin.GetShader(BuiltinShader.Transparent);
+;            if(standardShader == shader)
                 return BuiltinShader.Standard;
+            else if(transparentShader == shader)
+                return BuiltinShader.Transparent;
             
             return BuiltinShader.Custom;
         }

+ 2 - 1
Source/MBansheeEngine/Utility/Builtin.cs

@@ -14,8 +14,9 @@ namespace BansheeEngine
     /// </summary>
     public enum BuiltinShader // Note: Must match C++ BuiltinShader enum
     {
+        Custom,
         Standard,
-        Custom
+        Transparent
     }
 
     /// <summary>

+ 22 - 5
Source/RenderBeast/Include/BsLightRendering.h

@@ -40,6 +40,27 @@ namespace bs { namespace ct
 		Light* mInternal;
 	};
 
+	/** Contains GPU buffers used by the renderer to manipulate lights. */
+	class GPULightData
+	{
+	public:
+		GPULightData();
+
+		/** Updates the internal buffers with a new set of lights. */
+		void setLights(const Vector<LightData>& lightData, UINT32 numDirLights, UINT32 numRadialLights,
+					   UINT32 numSpotLights);
+
+		/** Returns a GPU bindable buffer containing information about every light. */
+		SPtr<GpuBuffer> getLightBuffer() const { return mLightBuffer; }
+
+		/** Returns a GPU bindable param buffer containing meta-data about light in the ligth buffer. */
+		SPtr<GpuParamBlockBuffer> getParamBuffer() const { return mParamBuffer; }
+
+	private:
+		SPtr<GpuParamBlockBuffer> mParamBuffer;
+		SPtr<GpuBuffer> mLightBuffer;
+	};
+
 	BS_PARAM_BLOCK_BEGIN(TiledLightingParamDef)
 		BS_PARAM_BLOCK_ENTRY(Vector3I, gLightOffsets)
 	BS_PARAM_BLOCK_END
@@ -58,8 +79,7 @@ namespace bs { namespace ct
 		void execute(const SPtr<RenderTargets>& gbuffer, const SPtr<GpuParamBlockBuffer>& perCamera);
 
 		/** Binds all the active lights. */
-		void setLights(const Vector<LightData>& lightData, UINT32 numDirLights, UINT32 numRadialLights, 
-					   UINT32 numSpotLights);
+		void setLights(const GPULightData& lightData);
 	private:
 		GpuParamTexture mGBufferA;
 		GpuParamTexture mGBufferB;
@@ -68,9 +88,6 @@ namespace bs { namespace ct
 		GpuParamBuffer mLightBufferParam;
 		GpuParamLoadStoreTexture mOutputParam;
 
-		SPtr<GpuParamBlockBuffer> mParamBuffer;
-		SPtr<GpuBuffer> mLightBuffer;
-
 		static const UINT32 TILE_SIZE;
 	};
 

+ 2 - 0
Source/RenderBeast/Include/BsRenderBeast.h

@@ -219,6 +219,8 @@ namespace bs
 		TiledDeferredLightingMat* mTiledDeferredLightingMat;
 		SkyboxMat* mSkyboxMat;
 
+		GPULightData* mGPULightData;
+
 		ObjectRenderer* mObjectRenderer;
 
 		// Sim thread only fields

+ 6 - 0
Source/RenderBeast/Include/BsRendererObject.h

@@ -64,6 +64,12 @@ namespace bs { namespace ct
 		/** Index to which should the per-camera param block buffer be bound to. */
 		UINT32 perCameraBindingIdx;
 
+		/** Index to which should the lights param block buffer be bound to. */
+		UINT32 lightParamsBindingIdx;
+
+		/** Parameter to which to bind light buffer used for forward rendering. */
+		GpuParamBuffer lightsBufferParam;
+
 		/** GPU buffer containing element's bone matrices, if it requires any. */
 		SPtr<GpuBuffer> boneMatrixBuffer;
 

+ 47 - 42
Source/RenderBeast/Source/BsLightRendering.cpp

@@ -38,6 +38,50 @@ namespace bs { namespace ct
 		output.color = Vector3(color.r, color.g, color.b);
 	}
 
+	GPULightData::GPULightData()
+	{
+		mParamBuffer = gTiledLightingParamDef.createBuffer();
+	}
+
+	void GPULightData::setLights(const Vector<LightData>& lightData, UINT32 numDirLights, UINT32 numRadialLights,
+				   UINT32 numSpotLights)
+	{
+		Vector3I lightOffsets;
+		lightOffsets[0] = numDirLights;
+		lightOffsets[1] = lightOffsets[0] + numRadialLights;
+		lightOffsets[2] = lightOffsets[1] + numSpotLights;
+
+		UINT32 totalNumLights = (UINT32)lightOffsets[2];
+
+		UINT32 size = totalNumLights * sizeof(LightData);
+		UINT32 curBufferSize;
+
+		if (mLightBuffer != nullptr)
+			curBufferSize = mLightBuffer->getSize();
+		else
+			curBufferSize = 0;
+
+		if (size > curBufferSize || curBufferSize == 0)
+		{
+			// Allocate at least one block even if no lights, to avoid issues with null buffers
+			UINT32 bufferSize = std::max(1, Math::ceilToInt(size / (float)BUFFER_INCREMENT)) * BUFFER_INCREMENT;
+
+			GPU_BUFFER_DESC bufferDesc;
+			bufferDesc.type = GBT_STRUCTURED;
+			bufferDesc.elementCount = bufferSize / sizeof(LightData);
+			bufferDesc.elementSize = sizeof(LightData);
+			bufferDesc.format = BF_UNKNOWN;
+
+			mLightBuffer = GpuBuffer::create(bufferDesc);
+		}
+
+		if (size > 0)
+			mLightBuffer->writeData(0, size, lightData.data(), BWT_DISCARD);
+
+		gTiledLightingParamDef.gLightOffsets.set(mParamBuffer, lightOffsets);
+		mParamBuffer->flushToGPU();
+	}
+
 	const UINT32 TiledDeferredLightingMat::TILE_SIZE = 16;
 
 	TiledDeferredLightingMat::TiledDeferredLightingMat()
@@ -57,9 +101,6 @@ namespace bs { namespace ct
 
 		params->getBufferParam(GPT_COMPUTE_PROGRAM, "gLights", mLightBufferParam);
 		params->getLoadStoreTextureParam(GPT_COMPUTE_PROGRAM, "gOutput", mOutputParam);
-
-		mParamBuffer = gTiledLightingParamDef.createBuffer();
-		mParamsSet->setParamBlockBuffer("Params", mParamBuffer, true);
 	}
 
 	void TiledDeferredLightingMat::_initDefines(ShaderDefines& defines)
@@ -90,45 +131,9 @@ namespace bs { namespace ct
 		RenderAPI::instance().dispatchCompute(numTilesX, numTilesY);
 	}
 
-	void TiledDeferredLightingMat::setLights(const Vector<LightData>& lightData, UINT32 numDirLights, 
-											 UINT32 numRadialLights, UINT32 numSpotLights)
+	void TiledDeferredLightingMat::setLights(const GPULightData& lightData)
 	{
-		Vector3I lightOffsets;
-		lightOffsets[0] = numDirLights;
-		lightOffsets[1] = lightOffsets[0] + numRadialLights;
-		lightOffsets[2] = lightOffsets[1] + numSpotLights;
-
-		UINT32 totalNumLights = (UINT32)lightOffsets[2];
-
-		UINT32 size = totalNumLights * sizeof(LightData);
-		UINT32 curBufferSize;
-
-		if (mLightBuffer != nullptr)
-			curBufferSize = mLightBuffer->getSize();
-		else
-			curBufferSize = 0;
-
-		if (size > curBufferSize || curBufferSize == 0)
-		{
-			// Allocate at least one block even if no lights, to avoid issues with null buffers
-			UINT32 bufferSize = std::max(1, Math::ceilToInt(size / (float)BUFFER_INCREMENT)) * BUFFER_INCREMENT;
-
-			GPU_BUFFER_DESC bufferDesc;
-			bufferDesc.type = GBT_STRUCTURED;
-			bufferDesc.elementCount = bufferSize / sizeof(LightData);
-			bufferDesc.elementSize = sizeof(LightData);
-			bufferDesc.format = BF_UNKNOWN;
-
-			mLightBuffer = GpuBuffer::create(bufferDesc);
-		}
-
-		if (size > 0)
-			mLightBuffer->writeData(0, size, lightData.data(), BWT_DISCARD);
-
-		mLightBufferParam.set(mLightBuffer);
-
-		gTiledLightingParamDef.gLightOffsets.set(mParamBuffer, lightOffsets);
-
-		mParamBuffer->flushToGPU();
+		mLightBufferParam.set(lightData.getLightBuffer());
+		mParamsSet->setParamBlockBuffer("Params", lightData.getParamBuffer(), true);
 	}
 }}

+ 11 - 0
Source/RenderBeast/Source/BsObjectRendering.cpp

@@ -27,6 +27,7 @@ namespace bs { namespace ct
 		if (shader == nullptr)
 		{
 			element.perCameraBindingIdx = -1;
+			element.lightParamsBindingIdx = -1;
 
 			LOGWRN("Missing shader on material.");
 			return;
@@ -50,8 +51,18 @@ namespace bs { namespace ct
 				element.params->setParamBlockBuffer(paramBlockDesc.second.name,
 													owner.perCallParamBuffer, true);
 			}
+			else if(paramBlockDesc.second.rendererSemantic == RBS_PerCamera)
+			{
+				element.perCameraBindingIdx = element.params->getParamBlockBufferIndex(paramBlockDesc.second.name);
+			}
 		}
 
+		element.lightParamsBindingIdx = element.params->getParamBlockBufferIndex("LightParams");
+
+		SPtr<GpuParams> gpuParams = element.params->getGpuParams();
+		if(gpuParams->hasBuffer(GPT_FRAGMENT_PROGRAM, "gLights"))
+			gpuParams->getBufferParam(GPT_FRAGMENT_PROGRAM, "gLights", element.lightsBufferParam);
+
 		const Map<String, SHADER_OBJECT_PARAM_DESC>& bufferDescs = shader->getBufferParams();
 		String boneMatricesParamName;
 

+ 40 - 23
Source/RenderBeast/Source/BsRenderBeast.cpp

@@ -39,9 +39,8 @@ using namespace std::placeholders;
 namespace bs { namespace ct
 {
 	RenderBeast::RenderBeast()
-		: mDefaultMaterial(nullptr), mTiledDeferredLightingMat(nullptr)
-		, mSkyboxMat(nullptr), mObjectRenderer(nullptr), mOptions(bs_shared_ptr_new<RenderBeastOptions>())
-		, mOptionsDirty(true)
+		: mDefaultMaterial(nullptr), mTiledDeferredLightingMat(nullptr), mSkyboxMat(nullptr), mGPULightData(nullptr)
+		, mObjectRenderer(nullptr), mOptions(bs_shared_ptr_new<RenderBeastOptions>()), mOptionsDirty(true)
 	{ }
 
 	const StringID& RenderBeast::getName() const
@@ -76,6 +75,8 @@ namespace bs { namespace ct
 		mTiledDeferredLightingMat = bs_new<TiledDeferredLightingMat>();
 		mSkyboxMat = bs_new<SkyboxMat>();
 
+		mGPULightData = bs_new<GPULightData>();
+
 		RenderTexturePool::startUp();
 		PostProcessing::startUp();
 	}
@@ -102,6 +103,7 @@ namespace bs { namespace ct
 		bs_delete(mDefaultMaterial);
 		bs_delete(mTiledDeferredLightingMat);
 		bs_delete(mSkyboxMat);
+		bs_delete(mGPULightData);
 
 		RendererUtility::shutDown();
 
@@ -698,24 +700,6 @@ namespace bs { namespace ct
 		for(UINT32 i = 0; i < numViews; i++)
 			views[i]->determineVisible(mRenderables, mRenderableCullInfos, &mRenderableVisibility);
 
-		// Update per-object, bone matrix and morph shape GPU buffers
-		UINT32 numRenderables = (UINT32)mRenderables.size();
-		for (UINT32 i = 0; i < numRenderables; i++)
-		{
-			if (!mRenderableVisibility[i])
-				continue;
-
-			// Note: Before uploading bone matrices perhaps check if they has actually been changed since last frame
-			mRenderables[i]->renderable->updateAnimationBuffers(frameInfo.animData);
-
-			// Note: Could this step be moved in notifyRenderableUpdated, so it only triggers when material actually gets
-			// changed? Although it shouldn't matter much because if the internal versions keeping track of dirty params.
-			for (auto& element : mRenderables[i]->elements)
-				element.material->updateParamsSet(element.params);
-
-			mRenderables[i]->perObjectParamBuffer->flushToGPU();
-		}
-
 		// Generate a list of lights and their GPU buffers
 		UINT32 numDirLights = (UINT32)mDirectionalLights.size();
 		for (UINT32 i = 0; i < numDirLights; i++)
@@ -752,11 +736,39 @@ namespace bs { namespace ct
 			mSpotLights[i].getParameters(mLightDataTemp.back());
 		}
 
-		mTiledDeferredLightingMat->setLights(mLightDataTemp, numDirLights, numRadialLights, numSpotLights);
+		mGPULightData->setLights(mLightDataTemp, numDirLights, numRadialLights, numSpotLights);
 
 		mLightDataTemp.clear();
 		mLightVisibilityTemp.clear();
 
+		mTiledDeferredLightingMat->setLights(*mGPULightData);
+
+		// Update various buffers required by each renderable
+		UINT32 numRenderables = (UINT32)mRenderables.size();
+		for (UINT32 i = 0; i < numRenderables; i++)
+		{
+			if (!mRenderableVisibility[i])
+				continue;
+
+			// Note: Before uploading bone matrices perhaps check if they has actually been changed since last frame
+			mRenderables[i]->renderable->updateAnimationBuffers(frameInfo.animData);
+
+			// Note: Could this step be moved in notifyRenderableUpdated, so it only triggers when material actually gets
+			// changed? Although it shouldn't matter much because if the internal versions keeping track of dirty params.
+			for (auto& element : mRenderables[i]->elements)
+			{
+				bool isTransparent = (element.material->getShader()->getFlags() & (UINT32)ShaderFlags::Transparent) != 0;
+				if(isTransparent)
+				{
+					
+				}
+
+				element.material->updateParamsSet(element.params);
+			}
+
+			mRenderables[i]->perObjectParamBuffer->flushToGPU();
+		}
+
 		for (UINT32 i = 0; i < numViews; i++)
 		{
 			if (views[i]->isOverlay())
@@ -792,6 +804,11 @@ namespace bs { namespace ct
 			{
 				if (element.perCameraBindingIdx != -1)
 					element.params->setParamBlockBuffer(element.perCameraBindingIdx, perCameraBuffer, true);
+
+				if (element.lightParamsBindingIdx != -1)
+					element.params->setParamBlockBuffer(element.lightParamsBindingIdx, mGPULightData->getParamBuffer(), true);
+
+				element.lightsBufferParam.set(mGPULightData->getLightBuffer());
 			}
 		}
 
@@ -861,7 +878,7 @@ namespace bs { namespace ct
 
 		renderTargets->bindSceneColor(false);
 
-		// Render transparent objects (TODO - No lighting yet)
+		// Render transparent objects
 		const Vector<RenderQueueElement>& transparentElements = viewInfo->getTransparentQueue()->getSortedElements();
 		for (auto iter = transparentElements.begin(); iter != transparentElements.end(); ++iter)
 		{