├── .gitattributes ├── .gitignore ├── Assets ├── Demo.meta ├── Demo │ ├── Animations.meta │ ├── Animations │ │ ├── cubeAC.controller │ │ ├── cubeAC.controller.meta │ │ ├── cubeAnimation.anim │ │ └── cubeAnimation.anim.meta │ ├── Materials.meta │ ├── Materials │ │ ├── cube.mat │ │ ├── cube.mat.meta │ │ ├── plane.mat │ │ └── plane.mat.meta │ ├── Scenes.meta │ ├── Scenes │ │ ├── Scene1.unity │ │ └── Scene1.unity.meta │ ├── Scripts.meta │ ├── Scripts │ │ ├── FPSCamera.cs │ │ ├── FPSCamera.cs.meta │ │ ├── RandomLights.cs │ │ └── RandomLights.cs.meta │ ├── Shaders.meta │ ├── Shaders │ │ ├── TestDiffuse.shader │ │ └── TestDiffuse.shader.meta │ ├── Textures.meta │ └── Textures │ │ ├── grid.png │ │ ├── grid.png.meta │ │ ├── heatmap.png │ │ └── heatmap.png.meta ├── ForwardPlus.meta └── ForwardPlus │ ├── Scripts.meta │ ├── Scripts │ ├── ForwardPlusManager.cs │ └── ForwardPlusManager.cs.meta │ ├── Shaders.meta │ └── Shaders │ ├── Common.cginc │ ├── Common.cginc.meta │ ├── CopyDepth.shader │ ├── CopyDepth.shader.meta │ ├── LightCulling.compute │ ├── LightCulling.compute.meta │ ├── debug_showGrid.shader │ ├── debug_showGrid.shader.meta │ ├── precomputeFrustums.compute │ └── precomputeFrustums.compute.meta ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset └── docs ├── LICENSE.md ├── README.md ├── banner.png ├── component.png └── heatmap.png /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | /.hg/ 8 | 9 | # Visual Studio 2015 cache directory 10 | /.vs/ 11 | 12 | # Autogenerated VS/MD/Consulo solution and project files 13 | ExportedObj/ 14 | .consulo/ 15 | *.csproj 16 | *.unityproj 17 | *.sln 18 | *.suo 19 | *.tmp 20 | *.user 21 | *.userprefs 22 | *.pidb 23 | *.booproj 24 | *.svd 25 | *.pdb 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | 30 | # Unity3D Generated File On Crash Reports 31 | sysinfo.txt 32 | 33 | # Builds 34 | *.apk 35 | *.unitypackage 36 | .hgignore 37 | -------------------------------------------------------------------------------- /Assets/Demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 113eeac369b939f4e8d82eb33d47592c 3 | folderAsset: yes 4 | timeCreated: 1520285468 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Animations.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b8d63d0692798044ae10392571c3f21 3 | folderAsset: yes 4 | timeCreated: 1520685441 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Animations/cubeAC.controller: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Animations/cubeAC.controller -------------------------------------------------------------------------------- /Assets/Demo/Animations/cubeAC.controller.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 813288260b2d9ef428b6e2c3d7d29bf5 3 | timeCreated: 1520685450 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 9100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Animations/cubeAnimation.anim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Animations/cubeAnimation.anim -------------------------------------------------------------------------------- /Assets/Demo/Animations/cubeAnimation.anim.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b0e053bde277aeb43b0b0a2b13347ea2 3 | timeCreated: 1520685463 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 7400000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b341dd43321bdb34696fa0dd244e0c31 3 | folderAsset: yes 4 | timeCreated: 1504560765 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Materials/cube.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Materials/cube.mat -------------------------------------------------------------------------------- /Assets/Demo/Materials/cube.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 886e373ee556b90409768dace2646ea7 3 | timeCreated: 1504560772 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Materials/plane.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Materials/plane.mat -------------------------------------------------------------------------------- /Assets/Demo/Materials/plane.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 28c9651ebda830d489bc0921fe7e6442 3 | timeCreated: 1504560772 4 | licenseType: Free 5 | NativeFormatImporter: 6 | mainObjectFileID: 2100000 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3bac9ba7767dbd4bb7c920ebd55a299 3 | folderAsset: yes 4 | timeCreated: 1497386419 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Scenes/Scene1.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Scenes/Scene1.unity -------------------------------------------------------------------------------- /Assets/Demo/Scenes/Scene1.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c7e84f9e429d66245bacc71db9eb0afa 3 | timeCreated: 1497386426 4 | licenseType: Free 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Demo/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e47ef624ddea57f49ba06a4dda8088c0 3 | folderAsset: yes 4 | timeCreated: 1520289325 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Scripts/FPSCamera.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class FPSCamera : MonoBehaviour 6 | { 7 | //PUBLIC FIELDS 8 | public float RotateSensitivity = 0.4f; 9 | public float MoveSensitivity = 0.5f; 10 | 11 | //PRIVATE FIELDS 12 | private Vector3 rot; 13 | private bool rotating = false; 14 | private Vector3 lastMousePos; 15 | private float rotationY = 0; 16 | 17 | private void Update() 18 | { 19 | float dx = Input.GetAxis("Horizontal") * MoveSensitivity; 20 | float dy = Input.GetAxis("Vertical") * MoveSensitivity; 21 | 22 | if (Input.GetMouseButtonDown(1)) 23 | { 24 | lastMousePos = Input.mousePosition; 25 | rotating = true; 26 | } 27 | if (Input.GetMouseButtonUp(1)) 28 | { 29 | rotating = false; 30 | } 31 | 32 | //rotate 33 | if (rotating) 34 | { 35 | float deltaX = Input.mousePosition.x - lastMousePos.x; 36 | float deltaY = Input.mousePosition.y - lastMousePos.y; 37 | 38 | float rotationX = transform.localEulerAngles.y + deltaX * RotateSensitivity; 39 | 40 | rotationY += deltaY * RotateSensitivity; 41 | 42 | transform.localEulerAngles = new Vector3(-rotationY, rotationX, 0); 43 | 44 | lastMousePos = Input.mousePosition; 45 | } 46 | 47 | //move 48 | Vector3 p = transform.position; 49 | p += transform.right * dx + transform.forward * dy; 50 | transform.position = p; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Assets/Demo/Scripts/FPSCamera.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 579932240d5390d49a40a7ad36551268 3 | timeCreated: 1503005064 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Demo/Scripts/RandomLights.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class RandomLights : MonoBehaviour 6 | { 7 | private void Awake() 8 | { 9 | //create random lights 10 | 11 | for (int i = 0; i < 100; ++i) 12 | { 13 | GameObject ob = new GameObject("light" + i.ToString()); 14 | Vector3 p = Random.insideUnitSphere * 15; 15 | p.z *= 0.3f; 16 | p.z += 10; 17 | ob.transform.position = p; 18 | 19 | Light l = ob.AddComponent(); 20 | l.type = LightType.Point; 21 | l.range = Random.Range(2, 10); 22 | l.color = Random.ColorHSV(); 23 | l.intensity = Random.Range(0.1f, 8.0f); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Assets/Demo/Scripts/RandomLights.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fb6520d1a44f4a245a90d0cc8adb429d 3 | timeCreated: 1520289422 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/Demo/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 77fea49e64616f54b9d4680d31754556 3 | folderAsset: yes 4 | timeCreated: 1520289358 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Shaders/TestDiffuse.shader: -------------------------------------------------------------------------------- 1 | Shader "ForwardPlus/TestDiffuse" 2 | { 3 | Properties 4 | { 5 | } 6 | SubShader 7 | { 8 | Tags { "RenderType"="Opaque" } 9 | LOD 100 10 | 11 | Pass 12 | { 13 | CGPROGRAM 14 | #pragma vertex vert 15 | #pragma fragment frag 16 | 17 | #pragma target 5.0 18 | 19 | #include "UnityCG.cginc" 20 | #include "Assets/ForwardPlus/Shaders/Common.cginc" 21 | 22 | Texture2D g_lightsGrid; 23 | Buffer g_lightsIndexBuffer; 24 | StructuredBuffer g_lights; 25 | 26 | struct appdata 27 | { 28 | float4 vertex : POSITION; 29 | float2 uv : TEXCOORD0; 30 | float3 normal : NORMAL; 31 | }; 32 | 33 | struct v2f 34 | { 35 | float4 vertex : SV_POSITION; 36 | float2 uv : TEXCOORD0; 37 | float4 clipPosition : TEXCOORD1; 38 | float4 worldPosition : TEXCOORD2; 39 | float3 normal : TEXCOORD3; 40 | }; 41 | 42 | v2f vert (appdata v) 43 | { 44 | v2f o; 45 | o.vertex = UnityObjectToClipPos(v.vertex); 46 | o.worldPosition = mul(unity_ObjectToWorld, v.vertex); 47 | o.normal = mul(unity_ObjectToWorld, float4(v.normal, 0)); 48 | o.clipPosition = o.vertex; 49 | o.uv = v.uv; 50 | return o; 51 | } 52 | 53 | fixed4 frag (v2f i) : SV_Target 54 | { 55 | float3 worldPosition = i.worldPosition; 56 | 57 | float3 N = normalize(i.normal); 58 | 59 | float2 texcoord = i.clipPosition.xy / i.clipPosition.w * 0.5 + 0.5; 60 | uint2 grid = g_lightsGrid[(uint2)(texcoord * _ScreenParams.xy / 16.0)]; 61 | 62 | uint n = min(64, grid.y); 63 | 64 | float vv = grid.x; 65 | 66 | float3 lit = float3(0, 0, 0); 67 | 68 | for (int i = 0; i < n; ++i) 69 | { 70 | uint index = g_lightsIndexBuffer[grid.x + i]; 71 | Light l = g_lights[index]; 72 | float3 dist = l.PositionWorldSpace - worldPosition; 73 | float3 E = l.Color * (1.0 / (dot(dist, dist) * 100 / l.range / l.range) - 0.01); 74 | 75 | lit += max(0, E); 76 | } 77 | 78 | return float4(lit, 1); 79 | } 80 | ENDCG 81 | } 82 | } 83 | 84 | Fallback "Diffuse" 85 | } 86 | -------------------------------------------------------------------------------- /Assets/Demo/Shaders/TestDiffuse.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4361b3352b4b984408b4a87e31295324 3 | timeCreated: 1504560725 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: df6e1eb57bd6f5c4cbb136a33b19b65c 3 | folderAsset: yes 4 | timeCreated: 1502919625 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Demo/Textures/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Textures/grid.png -------------------------------------------------------------------------------- /Assets/Demo/Textures/grid.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0d50476d5bcf10944870e7ee756bb7ee 3 | timeCreated: 1520682491 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 4 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapsPreserveCoverage: 0 16 | alphaTestReferenceValue: 0.5 17 | mipMapFadeDistanceStart: 1 18 | mipMapFadeDistanceEnd: 3 19 | bumpmap: 20 | convertToNormalMap: 0 21 | externalNormalMap: 0 22 | heightScale: 0.25 23 | normalMapFilter: 0 24 | isReadable: 0 25 | grayScaleToAlpha: 0 26 | generateCubemap: 6 27 | cubemapConvolution: 0 28 | seamlessCubemap: 0 29 | textureFormat: 1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | serializedVersion: 2 33 | filterMode: -1 34 | aniso: -1 35 | mipBias: -1 36 | wrapU: -1 37 | wrapV: -1 38 | wrapW: -1 39 | nPOTScale: 1 40 | lightmap: 0 41 | compressionQuality: 50 42 | spriteMode: 0 43 | spriteExtrude: 1 44 | spriteMeshType: 1 45 | alignment: 0 46 | spritePivot: {x: 0.5, y: 0.5} 47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 48 | spritePixelsToUnits: 100 49 | alphaUsage: 1 50 | alphaIsTransparency: 0 51 | spriteTessellationDetail: -1 52 | textureType: 0 53 | textureShape: 1 54 | maxTextureSizeSet: 0 55 | compressionQualitySet: 0 56 | textureFormatSet: 0 57 | platformSettings: 58 | - buildTarget: DefaultTexturePlatform 59 | maxTextureSize: 2048 60 | textureFormat: -1 61 | textureCompression: 1 62 | compressionQuality: 50 63 | crunchedCompression: 0 64 | allowsAlphaSplitting: 0 65 | overridden: 0 66 | spriteSheet: 67 | serializedVersion: 2 68 | sprites: [] 69 | outline: [] 70 | physicsShape: [] 71 | spritePackingTag: 72 | userData: 73 | assetBundleName: 74 | assetBundleVariant: 75 | -------------------------------------------------------------------------------- /Assets/Demo/Textures/heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/Assets/Demo/Textures/heatmap.png -------------------------------------------------------------------------------- /Assets/Demo/Textures/heatmap.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed836b9cfa611c140b73ceead7456a7e 3 | timeCreated: 1502919625 4 | licenseType: Free 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 4 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | sRGBTexture: 1 12 | linearTexture: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapsPreserveCoverage: 0 16 | alphaTestReferenceValue: 0.5 17 | mipMapFadeDistanceStart: 1 18 | mipMapFadeDistanceEnd: 3 19 | bumpmap: 20 | convertToNormalMap: 0 21 | externalNormalMap: 0 22 | heightScale: 0.25 23 | normalMapFilter: 0 24 | isReadable: 0 25 | grayScaleToAlpha: 0 26 | generateCubemap: 6 27 | cubemapConvolution: 0 28 | seamlessCubemap: 0 29 | textureFormat: 1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | serializedVersion: 2 33 | filterMode: 0 34 | aniso: -1 35 | mipBias: -1 36 | wrapU: 1 37 | wrapV: 1 38 | wrapW: 1 39 | nPOTScale: 1 40 | lightmap: 0 41 | compressionQuality: 50 42 | spriteMode: 0 43 | spriteExtrude: 1 44 | spriteMeshType: 1 45 | alignment: 0 46 | spritePivot: {x: 0.5, y: 0.5} 47 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 48 | spritePixelsToUnits: 100 49 | alphaUsage: 1 50 | alphaIsTransparency: 0 51 | spriteTessellationDetail: -1 52 | textureType: 0 53 | textureShape: 1 54 | maxTextureSizeSet: 0 55 | compressionQualitySet: 0 56 | textureFormatSet: 0 57 | platformSettings: 58 | - buildTarget: DefaultTexturePlatform 59 | maxTextureSize: 2048 60 | textureFormat: -1 61 | textureCompression: 1 62 | compressionQuality: 50 63 | crunchedCompression: 0 64 | allowsAlphaSplitting: 0 65 | overridden: 0 66 | - buildTarget: Standalone 67 | maxTextureSize: 2048 68 | textureFormat: -1 69 | textureCompression: 1 70 | compressionQuality: 50 71 | crunchedCompression: 0 72 | allowsAlphaSplitting: 0 73 | overridden: 0 74 | spriteSheet: 75 | serializedVersion: 2 76 | sprites: [] 77 | outline: [] 78 | physicsShape: [] 79 | spritePackingTag: 80 | userData: 81 | assetBundleName: 82 | assetBundleVariant: 83 | -------------------------------------------------------------------------------- /Assets/ForwardPlus.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a2c565467115abe4c951b7dd9f9b8737 3 | folderAsset: yes 4 | timeCreated: 1520289376 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 70370486e037ba94fbc505c4b746244b 3 | folderAsset: yes 4 | timeCreated: 1497302059 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Scripts/ForwardPlusManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | 6 | public class Plane 7 | { 8 | public Vector3 normal; 9 | public float d; 10 | } 11 | 12 | public class Frustum 13 | { 14 | public Plane[] planes = new Plane[4]; 15 | } 16 | 17 | //only point lights at the moment 18 | public struct LightData 19 | { 20 | public Vector3 worldSpacePosition; 21 | public float enabled; 22 | public Vector3 color; 23 | public float range; 24 | 25 | public LightData(Vector3 WorldSpacePosition, float Enabled, Vector3 Col, float Range) 26 | { 27 | worldSpacePosition = WorldSpacePosition; 28 | enabled = Enabled; 29 | color = Col; 30 | range = Range; 31 | } 32 | } 33 | 34 | public class ForwardPlusManager : MonoBehaviour 35 | { 36 | //PUBLIC FIELDS 37 | public ComputeShader precomputeFrustums; 38 | public ComputeShader lightCulling; 39 | 40 | public bool Debug_ShowGrid; 41 | public Texture2D heatmap; 42 | 43 | //PRIVATE FIELDS 44 | private readonly int LIGHTS_PER_TILE = 64; 45 | 46 | private ComputeBuffer frustumBuffer; 47 | private ComputeBuffer lightListBuffer; 48 | private ComputeBuffer currentLightIndexBuffer; 49 | private ComputeBuffer lightIndexBuffer; 50 | 51 | private RenderTexture depthTexture; 52 | private RenderTexture lightsGrid; 53 | private CommandBuffer commandBuffer; 54 | 55 | private Camera cam; 56 | 57 | private Material debug_showGridMat; 58 | private Material copyDepthMat; 59 | 60 | //PRIVATE METHODS 61 | private void Start() 62 | { 63 | cam = GetComponent (); 64 | cam.depthTextureMode = DepthTextureMode.Depth; 65 | 66 | //compute the number of frustums 67 | int num_frustums_x = (int)System.Math.Ceiling(Screen.width / 16.0f); 68 | int num_frustums_y = (int)System.Math.Ceiling (Screen.height / 16.0f); 69 | int total_frustums = num_frustums_x * num_frustums_y; 70 | 71 | //initialize buffers 72 | frustumBuffer = new ComputeBuffer (total_frustums, 64, ComputeBufferType.Default); 73 | lightListBuffer = new ComputeBuffer (256, 32, ComputeBufferType.Default); 74 | currentLightIndexBuffer = new ComputeBuffer (1, 4, ComputeBufferType.Default); 75 | lightIndexBuffer = new ComputeBuffer (LIGHTS_PER_TILE * total_frustums, 4, ComputeBufferType.Default); 76 | 77 | depthTexture = new RenderTexture (Screen.width, Screen.height, 24, RenderTextureFormat.RFloat); 78 | depthTexture.filterMode = FilterMode.Point; 79 | depthTexture.name = "DepthTexture"; 80 | 81 | lightsGrid = new RenderTexture (num_frustums_x, num_frustums_y, 0, RenderTextureFormat.RGInt, RenderTextureReadWrite.Linear); 82 | lightsGrid.name = "LightsGrid"; 83 | lightsGrid.filterMode = FilterMode.Point; 84 | lightsGrid.enableRandomWrite = true; 85 | lightsGrid.Create(); 86 | 87 | //populate the buffer with le list of lights 88 | LightData[] lightsData = new LightData[256]; 89 | int index = 0; 90 | Light[] lights = GameObject.FindObjectsOfType(); 91 | foreach (Light l in lights) 92 | { 93 | if (l.type == LightType.Point) 94 | { 95 | Vector3 col = new Vector3(l.color.r, l.color.g, l.color.b) * l.intensity; 96 | LightData d = new LightData (l.transform.position, 1, col, l.range); //world space position 97 | 98 | lightsData [index++] = d; 99 | 100 | if (index >= 256) 101 | break; 102 | } 103 | } 104 | 105 | //zero-initialize the remaining elements 106 | for (int i = index; i < 256; ++i) 107 | { 108 | lightsData [i] = new LightData (Vector3.zero, 0, Vector3.zero, 0); 109 | } 110 | 111 | lightListBuffer.SetData (lightsData); 112 | 113 | //precompute frustums 114 | 115 | Vector4 data = new Vector4(1.0f / (float)Screen.width, 1.0f / (float)Screen.height, num_frustums_x, num_frustums_y); 116 | Matrix4x4 matrix = GL.GetGPUProjectionMatrix (Camera.main.projectionMatrix, false); 117 | matrix = matrix.inverse; 118 | 119 | float[] matrixFloats = new float[] 120 | { 121 | matrix[0,0], matrix[1, 0], matrix[2, 0], matrix[3, 0], 122 | matrix[0,1], matrix[1, 1], matrix[2, 1], matrix[3, 1], 123 | matrix[0,2], matrix[1, 2], matrix[2, 2], matrix[3, 2], 124 | matrix[0,3], matrix[1, 3], matrix[2, 3], matrix[3, 3] 125 | }; 126 | 127 | precomputeFrustums.SetVector ("data", data); 128 | precomputeFrustums.SetFloats ("InverseProjection", matrixFloats); 129 | precomputeFrustums.SetBuffer (0, "frustums", frustumBuffer); 130 | 131 | int dispacth_x = (int)System.Math.Ceiling (num_frustums_x / 16.0f); 132 | int dispacth_y = (int)System.Math.Ceiling (num_frustums_y / 16.0f); 133 | 134 | precomputeFrustums.Dispatch (0, dispacth_x, dispacth_y, 1); 135 | 136 | //materials 137 | copyDepthMat = new Material(Shader.Find("ForwardPlus/CopyDepth")); 138 | 139 | debug_showGridMat = new Material(Shader.Find("ForwardPlus/debug_showGrid")); 140 | debug_showGridMat.SetTexture ("lightsGrid", lightsGrid); 141 | debug_showGridMat.SetFloat("screenWidth", Screen.width); 142 | debug_showGridMat.SetFloat("screenHeight", Screen.height); 143 | debug_showGridMat.SetTexture("heatmap", heatmap); 144 | 145 | lightCulling.SetTexture(0, "lightsGrid", lightsGrid); 146 | lightCulling.SetTexture(0, "depthBuffer", depthTexture); 147 | lightCulling.SetBuffer(0, "lights", lightListBuffer); 148 | 149 | //set the lights list globally 150 | Shader.SetGlobalTexture("g_lightsGrid", lightsGrid); 151 | Shader.SetGlobalBuffer("g_lightsIndexBuffer", lightIndexBuffer); 152 | Shader.SetGlobalBuffer("g_lights", lightListBuffer); 153 | 154 | commandBuffer = new CommandBuffer(); 155 | 156 | //first get the depth texture 157 | commandBuffer.name = "ForwardPlus"; 158 | commandBuffer.Blit(null, depthTexture, copyDepthMat); 159 | 160 | //then light culling phase 161 | commandBuffer.SetComputeBufferParam(lightCulling, 0, "frustums", frustumBuffer); 162 | commandBuffer.SetComputeBufferParam (lightCulling, 0, "currentIndex", currentLightIndexBuffer); 163 | commandBuffer.SetComputeBufferParam (lightCulling, 0, "lightsIndexBuffer", lightIndexBuffer); 164 | commandBuffer.SetComputeVectorParam (lightCulling, "data", data); 165 | commandBuffer.SetComputeFloatParams (lightCulling, "InverseProjection", matrixFloats); 166 | 167 | commandBuffer.DispatchCompute(lightCulling, 0, num_frustums_x, num_frustums_y, 1); 168 | 169 | cam.AddCommandBuffer (CameraEvent.AfterDepthTexture, commandBuffer); 170 | } 171 | 172 | private void OnPreRender() 173 | { 174 | Matrix4x4 matrix = cam.worldToCameraMatrix; 175 | float[] matrixFloats = new float[] 176 | { 177 | matrix[0,0], matrix[1, 0], matrix[2, 0], matrix[3, 0], 178 | matrix[0,1], matrix[1, 1], matrix[2, 1], matrix[3, 1], 179 | matrix[0,2], matrix[1, 2], matrix[2, 2], matrix[3, 2], 180 | matrix[0,3], matrix[1, 3], matrix[2, 3], matrix[3, 3] 181 | }; 182 | lightCulling.SetFloats("WorldToViewMatrix", matrixFloats); 183 | 184 | uint[] zero = new uint[1]; 185 | zero[0] = 0; 186 | currentLightIndexBuffer.SetData(zero); 187 | } 188 | 189 | private void OnRenderImage(RenderTexture src, RenderTexture dest) 190 | { 191 | if (Debug_ShowGrid) 192 | { 193 | Graphics.Blit(src, dest, debug_showGridMat); 194 | } 195 | else 196 | { 197 | Graphics.Blit(src, dest); 198 | } 199 | } 200 | 201 | } 202 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Scripts/ForwardPlusManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5f9a414df4f15bc42aa3e78d222d002c 3 | timeCreated: 1497386371 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a6b19b90448d2544db658443790f1f39 3 | folderAsset: yes 4 | timeCreated: 1497470855 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/Common.cginc: -------------------------------------------------------------------------------- 1 | #define POINT_LIGHT 0 2 | #define SPOT_LIGHT 1 3 | #define DIRECTIONAL_LIGHT 2 4 | 5 | struct Plane 6 | { 7 | float3 normal; 8 | float d; //distance from origin 9 | }; 10 | 11 | Plane ComputePlane(float3 p0, float3 p1, float3 p2) 12 | { 13 | Plane plane; 14 | 15 | float3 v0 = p1 - p0; 16 | float3 v2 = p2 - p0; 17 | 18 | plane.normal = normalize(cross(v0, v2)); 19 | plane.d = dot(p0, plane.normal); 20 | 21 | return plane; 22 | } 23 | 24 | struct Frustum 25 | { 26 | Plane planes[4]; 27 | }; 28 | 29 | float4 NDCtoViewSpace(float4 p, float4x4 InverseProjection) 30 | { 31 | float4 t = mul(InverseProjection, p); 32 | return t / t.w; 33 | } 34 | 35 | struct Sphere 36 | { 37 | float3 center; 38 | float radius; 39 | }; 40 | 41 | struct Light 42 | { 43 | float3 PositionWorldSpace; 44 | bool Enabled; 45 | float3 Color; 46 | float range; 47 | }; 48 | 49 | bool SphereInsidePlane(Sphere sphere, Plane plane) 50 | { 51 | return (dot(plane.normal, sphere.center) - plane.d < -sphere.radius); 52 | } 53 | 54 | bool SphereInsideFrustum(Sphere sphere, Frustum frustum, float near, float far) 55 | { 56 | bool ris = true; 57 | 58 | if (sphere.center.z - sphere.radius > near || sphere.center.z + sphere.radius < far) 59 | ris = false; 60 | 61 | for (int i = 0; i < 4; ++i) 62 | { 63 | if (SphereInsidePlane(sphere, frustum.planes[i])) 64 | { 65 | ris = false; 66 | } 67 | } 68 | 69 | return ris; 70 | } -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/Common.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7bd7b841b3736bc42af885ae1abe0d30 3 | timeCreated: 1497471221 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/CopyDepth.shader: -------------------------------------------------------------------------------- 1 | Shader "ForwardPlus/CopyDepth" 2 | { 3 | SubShader 4 | { 5 | Tags { "RenderType"="Opaque" } 6 | LOD 100 7 | 8 | Pass 9 | { 10 | CGPROGRAM 11 | #pragma vertex vert 12 | #pragma fragment frag 13 | #include "UnityCG.cginc" 14 | 15 | struct appdata 16 | { 17 | float4 vertex : POSITION; 18 | float2 uv : TEXCOORD0; 19 | }; 20 | 21 | struct v2f 22 | { 23 | float2 uv : TEXCOORD0; 24 | float4 vertex : SV_POSITION; 25 | }; 26 | 27 | v2f vert (appdata v) 28 | { 29 | v2f o; 30 | o.vertex = UnityObjectToClipPos(v.vertex); 31 | o.uv = v.uv; 32 | return o; 33 | } 34 | 35 | sampler2D _CameraDepthTexture; 36 | 37 | fixed4 frag (v2f i) : SV_Target 38 | { 39 | return tex2D(_CameraDepthTexture, i.uv); 40 | } 41 | ENDCG 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/CopyDepth.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 721696086a5749940ba59f88db1f594f 3 | timeCreated: 1499631382 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/LightCulling.compute: -------------------------------------------------------------------------------- 1 | #pragma kernel CSMain 2 | #pragma enable_d3d11_debug_symbols 3 | 4 | #define BLOCK_SIZE 16 5 | 6 | #include "Common.cginc" 7 | 8 | struct CS_INPUT 9 | { 10 | uint3 Gid : SV_GroupID; 11 | uint3 GTid : SV_GroupThreadID; 12 | uint3 DTid : SV_DispatchThreadID; 13 | uint GI : SV_GroupIndex; 14 | }; 15 | 16 | float4 data; 17 | float4x4 InverseProjection; 18 | float4x4 WorldToViewMatrix; 19 | 20 | StructuredBuffer frustums; 21 | Texture2D depthBuffer; 22 | StructuredBuffer lights; //array with all lights and their properties 23 | RWBuffer currentIndex; 24 | RWBuffer lightsIndexBuffer; 25 | 26 | RWTexture2D lightsGrid; 27 | 28 | groupshared uint maxDepth; 29 | groupshared uint minDepth; 30 | groupshared uint lightsCount; 31 | groupshared uint startIndexOffset; 32 | groupshared uint indices[64]; 33 | groupshared Frustum groupFrustum; 34 | 35 | void AppendLight(uint lightIndex) 36 | { 37 | uint index; 38 | InterlockedAdd(lightsCount, 1, index); //add 1 to the number of group lights 39 | if (index < 64) 40 | { 41 | indices[index] = lightIndex; //indices is the local indices list 42 | } 43 | } 44 | 45 | [numthreads(BLOCK_SIZE, BLOCK_SIZE,1)] 46 | void CSMain (CS_INPUT input) 47 | { 48 | uint2 texcoord = input.DTid.xy; //screen coordinates 49 | texcoord.y = 1.0 / data.y - texcoord.y; 50 | float depth = 1.0 - depthBuffer.Load(int3(texcoord, 0)).r; //read the depth and invert 51 | uint intDepth = asuint(depth); //convert to int for atomic operations 52 | 53 | if (input.GI == 0) //primo group thread 54 | { 55 | minDepth = 0xffffffff; 56 | maxDepth = 0; 57 | lightsCount = 0; 58 | groupFrustum = frustums[input.Gid.x + input.Gid.y * data.z]; 59 | } 60 | 61 | GroupMemoryBarrierWithGroupSync(); 62 | 63 | InterlockedMin(minDepth, intDepth); //atomic operations 64 | InterlockedMax(maxDepth, intDepth); 65 | 66 | GroupMemoryBarrierWithGroupSync(); 67 | 68 | float fMin = asfloat(minDepth); //convert to float 69 | float fMax = asfloat(maxDepth); 70 | 71 | float minInViewSpace = NDCtoViewSpace(float4(0, 0, 1 - fMin, 1), InverseProjection).z; //also here the z is inverted 72 | float maxInViewSpace = NDCtoViewSpace(float4(0, 0, 1 - fMax, 1), InverseProjection).z; 73 | 74 | //the number of thread in the group is 256, as the number of light to process, so every thread processes its own light 75 | 76 | Light light = lights[input.GI]; 77 | if (light.Enabled) 78 | { 79 | float3 lightViewSpacePosition = mul(WorldToViewMatrix, float4(light.PositionWorldSpace, 1)); 80 | 81 | Sphere sphere = { lightViewSpacePosition , light.range }; 82 | 83 | if (SphereInsideFrustum(sphere, groupFrustum, minInViewSpace, maxInViewSpace)) 84 | { 85 | AppendLight(input.GI); 86 | } 87 | } 88 | 89 | GroupMemoryBarrierWithGroupSync(); 90 | 91 | if (input.GI == 0) 92 | { 93 | InterlockedAdd(currentIndex[0], lightsCount, startIndexOffset); 94 | lightsGrid[input.Gid.xy] = uint2(startIndexOffset, lightsCount); 95 | } 96 | 97 | GroupMemoryBarrierWithGroupSync(); 98 | 99 | for (int i = input.GI; i < lightsCount; i += BLOCK_SIZE * BLOCK_SIZE) 100 | { 101 | lightsIndexBuffer[startIndexOffset + i] = indices[i]; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/LightCulling.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aaa3c0ad428f8f5429e50656fb013007 3 | timeCreated: 1499981110 4 | licenseType: Free 5 | ComputeShaderImporter: 6 | currentAPIMask: 4 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/debug_showGrid.shader: -------------------------------------------------------------------------------- 1 | Shader "ForwardPlus/debug_showGrid" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _GridColor("GridColor", Color) = (0, 0, 0, 1) 7 | _Show("Show", Range(0, 1)) = 0.8 8 | } 9 | SubShader 10 | { 11 | Cull Off ZWrite Off ZTest Always 12 | 13 | Pass 14 | { 15 | CGPROGRAM 16 | #pragma vertex vert_img 17 | #pragma fragment frag 18 | 19 | #include "UnityCG.cginc" 20 | 21 | sampler2D _MainTex; 22 | sampler2D heatmap; 23 | 24 | //REVERTARE 25 | Texture2D lightsGrid; 26 | 27 | float4 _GridColor; 28 | float _Show; 29 | 30 | fixed4 frag (v2f_img i) : SV_Target 31 | { 32 | float2 uv = i.uv.xy; 33 | uv.y = 1 - uv.y; 34 | uv *= _ScreenParams.xy / 16.0; 35 | 36 | float2 xy = abs(frac(uv) * 2 - 1); 37 | float VAL = 8; 38 | float reticolo = 1.0 - step(pow(pow(xy.x, VAL) + pow(xy.y, VAL), 1.0 / VAL), 0.93); 39 | reticolo *= 0.25; 40 | 41 | fixed4 col = tex2D(_MainTex, i.uv); 42 | 43 | uint2 grid = lightsGrid[(uint2)uv]; 44 | 45 | float heat_uv_x = grid.y * 0.015625; 46 | 47 | float4 heat = tex2D(heatmap, float2(heat_uv_x, 0.5f)); 48 | 49 | fixed4 ris = heat * (1.0 - reticolo) + _GridColor * reticolo; 50 | 51 | ris = col * (1 - _Show) + ris * _Show; 52 | 53 | ris.a = 1; 54 | 55 | return ris; 56 | } 57 | ENDCG 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/debug_showGrid.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04d3c2f5f12055a47bc1d6d8ebf8ee9e 3 | timeCreated: 1500491074 4 | licenseType: Free 5 | ShaderImporter: 6 | defaultTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/precomputeFrustums.compute: -------------------------------------------------------------------------------- 1 | #pragma kernel CSMain 2 | #pragma enable_d3d11_debug_symbols 3 | 4 | #define BLOCK_SIZE 16 5 | 6 | #include "Common.cginc" 7 | 8 | RWStructuredBuffer frustums; 9 | 10 | struct CS_INPUT 11 | { 12 | uint3 Gid : SV_GroupID; 13 | uint3 GTid : SV_GroupThreadID; 14 | uint3 DTid : SV_DispatchThreadID; 15 | uint GI : SV_GroupIndex; 16 | }; 17 | 18 | float4 data; //inverse of the resolution and number of groups 19 | float4x4 InverseProjection; 20 | 21 | [numthreads(BLOCK_SIZE, BLOCK_SIZE,1)] 22 | void CSMain (CS_INPUT input) 23 | { 24 | float2 points[4]; 25 | points[0] = input.DTid.xy * BLOCK_SIZE * data.xy * float2(2, -2) - float2(1, -1); 26 | points[1] = (input.DTid.xy + float2(1, 0)) * BLOCK_SIZE * data.xy * float2(2, -2) - float2(1, -1); 27 | points[2] = (input.DTid.xy + float2(0, 1)) * BLOCK_SIZE * data.xy * float2(2, -2) - float2(1, -1); 28 | points[3] = (input.DTid.xy + float2(1, 1)) * BLOCK_SIZE * data.xy * float2(2, -2) - float2(1, -1); 29 | 30 | float4 viewSpacePoints[4]; 31 | for (int i = 0; i < 4; ++i) 32 | viewSpacePoints[i] = NDCtoViewSpace(float4(points[i], 0, 1), InverseProjection); //z from 1 to 0 33 | 34 | float3 origin = float3(0, 0, 0); 35 | 36 | Frustum frustum; 37 | 38 | frustum.planes[0] = ComputePlane(origin, viewSpacePoints[2], viewSpacePoints[0]); 39 | frustum.planes[1] = ComputePlane(origin, viewSpacePoints[0], viewSpacePoints[1]); 40 | frustum.planes[2] = ComputePlane(origin, viewSpacePoints[1], viewSpacePoints[3]); 41 | frustum.planes[3] = ComputePlane(origin, viewSpacePoints[3], viewSpacePoints[2]); 42 | 43 | if (input.DTid.x < data.z && input.DTid.y < data.w) 44 | { 45 | uint index = input.DTid.y * data.z + input.DTid.x; 46 | frustums[index] = frustum; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Assets/ForwardPlus/Shaders/precomputeFrustums.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5b3ef852122f28449a3ee40a18c6314b 3 | timeCreated: 1497470871 4 | licenseType: Free 5 | ComputeShaderImporter: 6 | currentAPIMask: 4 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.1.1f1 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /docs/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Accardi Piero 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Unity Forward+ System 2 |

3 | 4 |

5 | 6 | # Overview 7 | Implementation of a **Forward+** (tiled forward) system for Unity, based on this article: https://www.3dgep.com/forward-plus/ 8 | 9 | # Usage 10 |

11 | 12 |

13 | 14 | - Add the component **Forward Plus Manager** to the camera 15 | - Fill the fields **Precompute Frustums** and **Light Culling** with their corrisponding compute shaders from the folder `Assets/ForwardPlus/Shaders/` 16 | - Add a texture in the **Heatmap** field, try with `Assets/Demo/Textures/heatmap.png` 17 | - The field **Debug_ShowGrid** is a toggle to enable the visualization of the lights grid with an heatmap for the most populated tiles 18 | 19 |

20 | 21 |

22 | 23 | To write a shader you need: 24 | - Declare this resources: 25 | - `Texture2D g_lightsGrid` 26 | - `Buffer g_lightsIndexBuffer` 27 | - `StructuredBuffer g_lights ` 28 | - In the fragment shader compute the tile coordinate, and use it to read from the `g_lightsGrid`. The x component is the number is the start offset in the buffer `g_lightsIndexBuffer` and the y component is the number of lights for the tile. 29 | - Cycle for the number of lights and read first the index from `g_lightsIndexBuffer` and use it to get the light data from the buffer `g_lights` 30 | 31 | There is an example diffuse shader in the folder `Assets/Demo/Shaders/` 32 | 33 | ## Further Development 34 | - Right now only point lights are supported, next i'll implement directional and spot 35 | - Allow dynamically movable lights 36 | - Make the system working also in the editor and not only in play mode 37 | 38 | ## License 39 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) 40 | -------------------------------------------------------------------------------- /docs/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/docs/banner.png -------------------------------------------------------------------------------- /docs/component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/docs/component.png -------------------------------------------------------------------------------- /docs/heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pieroaccardi/Unity_ForwardPlus/b239f85bf3d72b5401afd7c7370be34f07d33e5b/docs/heatmap.png --------------------------------------------------------------------------------