Skip to content

Commit 2cb0992

Browse files
Joachim AnteJoachim Ante
authored andcommitted
Initial ScriptableRenderLoop
0 parents  commit 2cb0992

52 files changed

Lines changed: 7383 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
Library/*
3+
Temp/*

Assets/ScriptableRenderLoop.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System;
2+
3+
namespace UnityEngine.ScriptableRenderLoop
4+
{
5+
//@TODO: We should continously move these values
6+
// into the engine when we can see them being generally useful
7+
[RequireComponent(typeof(Light))]
8+
public class AdditionalLightData : MonoBehaviour
9+
{
10+
public const int defaultShadowResolution = 512;
11+
12+
public int shadowResolution = defaultShadowResolution;
13+
14+
[RangeAttribute(0.0F, 100.0F)]
15+
public float innerSpotPercent = 0.0F;
16+
17+
public static float GetInnerSpotPercent01(AdditionalLightData lightData)
18+
{
19+
if (lightData != null)
20+
return Mathf.Clamp( lightData.innerSpotPercent, 0.0f, 100.0f ) / 100.0f;
21+
else
22+
return 0.0F;
23+
}
24+
25+
public static int GetShadowResolution(AdditionalLightData lightData)
26+
{
27+
if (lightData != null)
28+
return lightData.shadowResolution;
29+
else
30+
return defaultShadowResolution;
31+
}
32+
}
33+
}
34+
35+

Assets/ScriptableRenderLoop/AdditionalLightData.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/ScriptableRenderLoop/ForwardRenderLoop.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
%YAML 1.1
2+
%TAG !u! tag:unity3d.com,2011:
3+
--- !u!114 &11400000
4+
MonoBehaviour:
5+
m_ObjectHideFlags: 0
6+
m_PrefabParentObject: {fileID: 0}
7+
m_PrefabInternal: {fileID: 0}
8+
m_GameObject: {fileID: 0}
9+
m_Enabled: 1
10+
m_EditorHideFlags: 0
11+
m_Script: {fileID: 11500000, guid: 98fe12104b04e43dd9a963f3f7b26e8e, type: 3}
12+
m_Name: ForwardRenderLoop
13+
m_EditorClassIdentifier:
14+
m_ShadowSettings:
15+
enabled: 1
16+
shadowAtlasWidth: 4096
17+
shadowAtlasHeight: 4096
18+
maxShadowDistance: 500
19+
directionalLightCascadeCount: 4
20+
directionalLightCascades: {x: 0.02, y: 0.1, z: 0.6}

Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.asset.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
using UnityEngine;
2+
using System.Collections;
3+
using UnityEngine.Rendering;
4+
using System.Collections.Generic;
5+
using System;
6+
7+
using UnityEditor;
8+
9+
namespace UnityEngine.ScriptableRenderLoop
10+
{
11+
public class ForwardRenderLoop : ScriptableRenderLoop
12+
{
13+
[MenuItem("Renderloop/CreateForwardRenderLoop")]
14+
static void CreateForwardRenderLoop()
15+
{
16+
var instance = ScriptableObject.CreateInstance<ForwardRenderLoop>();
17+
AssetDatabase.CreateAsset(instance, "Assets/forwardrenderloop.asset");
18+
}
19+
20+
[SerializeField]
21+
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
22+
ShadowRenderPass m_ShadowPass;
23+
24+
25+
const int MAX_LIGHTS = 10;
26+
const int MAX_SHADOWMAP_PER_LIGHTS = 6;
27+
const int MAX_DIRECTIONAL_SPLIT = 4;
28+
// Directional lights become spotlights at a far distance. This is the distance we pull back to set the spotlight origin.
29+
const float DIRECTIONAL_LIGHT_PULLBACK_DISTANCE = 10000.0f;
30+
31+
[NonSerialized] private int m_nWarnedTooManyLights = 0;
32+
33+
34+
void OnEnable()
35+
{
36+
Rebuild ();
37+
}
38+
39+
void OnValidate()
40+
{
41+
Rebuild ();
42+
}
43+
44+
void Rebuild()
45+
{
46+
m_ShadowPass = new ShadowRenderPass (m_ShadowSettings);
47+
}
48+
49+
//---------------------------------------------------------------------------------------------------------------------------------------------------
50+
void UpdateLightConstants(ActiveLight[] activeLights, ref ShadowOutput shadow)
51+
{
52+
int nNumLightsIncludingTooMany = 0;
53+
54+
int g_nNumLights = 0;
55+
56+
Vector4[] g_vLightColor = new Vector4[ MAX_LIGHTS ];
57+
Vector4[] g_vLightPosition_flInvRadius = new Vector4[ MAX_LIGHTS ];
58+
Vector4[] g_vLightDirection = new Vector4[ MAX_LIGHTS ];
59+
Vector4[] g_vLightShadowIndex_vLightParams = new Vector4[ MAX_LIGHTS ];
60+
Vector4[] g_vLightFalloffParams = new Vector4[ MAX_LIGHTS ];
61+
Vector4[] g_vSpotLightInnerOuterConeCosines = new Vector4[ MAX_LIGHTS ];
62+
Matrix4x4[] g_matWorldToShadow = new Matrix4x4[ MAX_LIGHTS * MAX_SHADOWMAP_PER_LIGHTS ];
63+
Vector4[] g_vDirShadowSplitSpheres = new Vector4[ MAX_DIRECTIONAL_SPLIT ];
64+
65+
for ( int nLight = 0; nLight < activeLights.Length; nLight++ )
66+
{
67+
68+
nNumLightsIncludingTooMany++;
69+
if ( nNumLightsIncludingTooMany > MAX_LIGHTS )
70+
continue;
71+
72+
ActiveLight light = activeLights [nLight];
73+
LightType lightType = light.lightType;
74+
Vector3 position = light.light.transform.position;
75+
Vector3 lightDir = light.light.transform.forward.normalized;
76+
AdditionalLightData additionalLightData = light.light.GetComponent<AdditionalLightData> ();
77+
78+
// Setup shadow data arrays
79+
bool hasShadows = shadow.GetShadowSliceCountLightIndex (nLight) != 0;
80+
81+
if ( lightType == LightType.Directional )
82+
{
83+
g_vLightColor[ g_nNumLights ] = light.finalColor;
84+
g_vLightPosition_flInvRadius[ g_nNumLights ] = new Vector4(
85+
position.x - ( lightDir.x * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE ),
86+
position.y - ( lightDir.y * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE ),
87+
position.z - ( lightDir.z * DIRECTIONAL_LIGHT_PULLBACK_DISTANCE ),
88+
-1.0f );
89+
g_vLightDirection[ g_nNumLights ] = new Vector4( lightDir.x, lightDir.y, lightDir.z );
90+
g_vLightShadowIndex_vLightParams[ g_nNumLights ] = new Vector4( 0, 0, 1, 1 );
91+
g_vLightFalloffParams[ g_nNumLights ] = new Vector4( 0.0f, 0.0f, float.MaxValue, (float)lightType );
92+
g_vSpotLightInnerOuterConeCosines[ g_nNumLights ] = new Vector4( 0.0f, -1.0f, 1.0f );
93+
94+
if (hasShadows)
95+
{
96+
for (int s = 0; s < MAX_DIRECTIONAL_SPLIT; ++s)
97+
{
98+
g_vDirShadowSplitSpheres[s] = shadow.directionalShadowSplitSphereSqr[s];
99+
}
100+
}
101+
}
102+
else if ( lightType == LightType.Point )
103+
{
104+
g_vLightColor[ g_nNumLights ] = light.finalColor;
105+
106+
g_vLightPosition_flInvRadius[ g_nNumLights ] = new Vector4( position.x, position.y, position.z, 1.0f / light.range );
107+
g_vLightDirection[ g_nNumLights ] = new Vector4( 0.0f, 0.0f, 0.0f );
108+
g_vLightShadowIndex_vLightParams[ g_nNumLights ] = new Vector4( 0, 0, 1, 1 );
109+
g_vLightFalloffParams[ g_nNumLights ] = new Vector4( 1.0f, 0.0f, light.range * light.range, (float)lightType );
110+
g_vSpotLightInnerOuterConeCosines[ g_nNumLights ] = new Vector4( 0.0f, -1.0f, 1.0f );
111+
}
112+
else if ( lightType == LightType.Spot )
113+
{
114+
g_vLightColor[ g_nNumLights ] = light.finalColor;
115+
g_vLightPosition_flInvRadius[ g_nNumLights ] = new Vector4( position.x, position.y, position.z, 1.0f / light.range );
116+
g_vLightDirection[ g_nNumLights ] = new Vector4( lightDir.x, lightDir.y, lightDir.z );
117+
g_vLightShadowIndex_vLightParams[ g_nNumLights ] = new Vector4( 0, 0, 1, 1 );
118+
g_vLightFalloffParams[ g_nNumLights ] = new Vector4( 1.0f, 0.0f, light.range * light.range, (float)lightType );
119+
120+
float flInnerConePercent = AdditionalLightData.GetInnerSpotPercent01(additionalLightData);
121+
float spotAngle = light.light.spotAngle;
122+
float flPhiDot = Mathf.Clamp( Mathf.Cos( spotAngle * 0.5f * Mathf.Deg2Rad ), 0.0f, 1.0f ); // outer cone
123+
float flThetaDot = Mathf.Clamp( Mathf.Cos( spotAngle * 0.5f * flInnerConePercent * Mathf.Deg2Rad ), 0.0f, 1.0f ); // inner cone
124+
g_vSpotLightInnerOuterConeCosines[ g_nNumLights ] = new Vector4( flThetaDot, flPhiDot, 1.0f / Mathf.Max( 0.01f, flThetaDot - flPhiDot ) );
125+
126+
}
127+
128+
if ( hasShadows )
129+
{
130+
// Enable shadows
131+
g_vLightShadowIndex_vLightParams[ g_nNumLights ].x = 1;
132+
for(int s=0; s < shadow.GetShadowSliceCountLightIndex (nLight); ++s)
133+
{
134+
int shadowSliceIndex = shadow.GetShadowSliceIndex (nLight, s);
135+
g_matWorldToShadow [g_nNumLights * MAX_SHADOWMAP_PER_LIGHTS + s] = shadow.shadowSlices[shadowSliceIndex].shadowTransform.transpose;
136+
}
137+
}
138+
139+
g_nNumLights++;
140+
}
141+
142+
// Warn if too many lights found
143+
if ( nNumLightsIncludingTooMany > MAX_LIGHTS )
144+
{
145+
if ( nNumLightsIncludingTooMany > m_nWarnedTooManyLights )
146+
{
147+
Debug.LogError( "ERROR! Found " + nNumLightsIncludingTooMany + " runtime lights! Valve renderer supports up to " + MAX_LIGHTS +
148+
" active runtime lights at a time!\nDisabling " + ( nNumLightsIncludingTooMany - MAX_LIGHTS ) + " runtime light" +
149+
( ( nNumLightsIncludingTooMany - MAX_LIGHTS ) > 1 ? "s" : "" ) + "!\n" );
150+
}
151+
m_nWarnedTooManyLights = nNumLightsIncludingTooMany;
152+
}
153+
else
154+
{
155+
if ( m_nWarnedTooManyLights > 0 )
156+
{
157+
m_nWarnedTooManyLights = 0;
158+
Debug.Log( "SUCCESS! Found " + nNumLightsIncludingTooMany + " runtime lights which is within the supported number of lights, " + MAX_LIGHTS + ".\n\n" );
159+
}
160+
}
161+
162+
// Send constants to shaders
163+
Shader.SetGlobalInt( "g_nNumLights", g_nNumLights );
164+
165+
// New method for Unity 5.4 to set arrays of constants
166+
Shader.SetGlobalVectorArray( "g_vLightPosition_flInvRadius", g_vLightPosition_flInvRadius );
167+
Shader.SetGlobalVectorArray( "g_vLightColor", g_vLightColor );
168+
Shader.SetGlobalVectorArray( "g_vLightDirection", g_vLightDirection );
169+
Shader.SetGlobalVectorArray( "g_vLightShadowIndex_vLightParams", g_vLightShadowIndex_vLightParams );
170+
Shader.SetGlobalVectorArray( "g_vLightFalloffParams", g_vLightFalloffParams );
171+
Shader.SetGlobalVectorArray( "g_vSpotLightInnerOuterConeCosines", g_vSpotLightInnerOuterConeCosines );
172+
Shader.SetGlobalMatrixArray( "g_matWorldToShadow", g_matWorldToShadow );
173+
Shader.SetGlobalVectorArray( "g_vDirShadowSplitSpheres", g_vDirShadowSplitSpheres );
174+
175+
// Time
176+
#if ( UNITY_EDITOR )
177+
{
178+
Shader.SetGlobalFloat( "g_flTime", Time.realtimeSinceStartup );
179+
//Debug.Log( "Time " + Time.realtimeSinceStartup );
180+
}
181+
#else
182+
{
183+
Shader.SetGlobalFloat( "g_flTime", Time.timeSinceLevelLoad );
184+
//Debug.Log( "Time " + Time.timeSinceLevelLoad );
185+
}
186+
#endif
187+
188+
// PCF 3x3 Shadows
189+
float flTexelEpsilonX = 1.0f / m_ShadowSettings.shadowAtlasWidth;
190+
float flTexelEpsilonY = 1.0f / m_ShadowSettings.shadowAtlasHeight;
191+
Vector4 g_vShadow3x3PCFTerms0 = new Vector4( 20.0f / 267.0f, 33.0f / 267.0f, 55.0f / 267.0f, 0.0f );
192+
Vector4 g_vShadow3x3PCFTerms1 = new Vector4( flTexelEpsilonX, flTexelEpsilonY, -flTexelEpsilonX, -flTexelEpsilonY );
193+
Vector4 g_vShadow3x3PCFTerms2 = new Vector4( flTexelEpsilonX, flTexelEpsilonY, 0.0f, 0.0f );
194+
Vector4 g_vShadow3x3PCFTerms3 = new Vector4( -flTexelEpsilonX, -flTexelEpsilonY, 0.0f, 0.0f );
195+
196+
Shader.SetGlobalVector( "g_vShadow3x3PCFTerms0", g_vShadow3x3PCFTerms0 );
197+
Shader.SetGlobalVector( "g_vShadow3x3PCFTerms1", g_vShadow3x3PCFTerms1 );
198+
Shader.SetGlobalVector( "g_vShadow3x3PCFTerms2", g_vShadow3x3PCFTerms2 );
199+
Shader.SetGlobalVector( "g_vShadow3x3PCFTerms3", g_vShadow3x3PCFTerms3 );
200+
}
201+
202+
public override void Render(Camera[] cameras, RenderLoop renderLoop)
203+
{
204+
foreach (var camera in cameras)
205+
{
206+
CullResults cullResults;
207+
CullingParameters cullingParams;
208+
if (!CullResults.GetCullingParameters (camera, out cullingParams))
209+
continue;
210+
211+
m_ShadowPass.UpdateCullingParameters (ref cullingParams);
212+
213+
cullResults = CullResults.Cull (ref cullingParams, renderLoop);
214+
215+
ShadowOutput shadows;
216+
m_ShadowPass.Render (renderLoop, cullResults, out shadows);
217+
218+
renderLoop.SetupCameraProperties (camera);
219+
220+
UpdateLightConstants(cullResults.culledLights, ref shadows);
221+
222+
DrawRendererSettings settings = new DrawRendererSettings (cullResults, camera, new ShaderPassName("ForwardBase"));
223+
settings.rendererConfiguration = RendererConfiguration.ConfigureOneLightProbePerRenderer | RendererConfiguration.ConfigureReflectionProbesProbePerRenderer;
224+
settings.sorting.sortOptions = SortOptions.SortByMaterialThenMesh;
225+
226+
renderLoop.DrawRenderers (ref settings);
227+
renderLoop.Submit ();
228+
}
229+
230+
// Post effects
231+
}
232+
}
233+
}

Assets/ScriptableRenderLoop/ForwardRenderLoop/ForwardRenderLoop.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Assets/ScriptableRenderLoop/ForwardRenderLoop/Shaders.meta

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)