浏览代码

Make changes based on joachims feedback.

-Split Asset / created instance more cleanly.
-Asset provides an RenderLoop instance that can be used for rendering
-Remove data store (implicitly the loop instance now)
/main
Tim Cooper 8 年前
当前提交
5b39107f
共有 11 个文件被更改,包括 197 次插入233 次删除
  1. 99
      Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs
  2. 2
      Assets/Editor/Tests/RenderloopTests/CullResultsTest.cs
  3. 26
      Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs
  4. 2
      Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs
  5. 80
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  6. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs
  7. 76
      Assets/ScriptableRenderLoop/core/RenderPipeline.cs
  8. 80
      Assets/ScriptableRenderLoop/fptl/FptlLighting.cs
  9. 9
      Assets/ScriptableRenderLoop/common/CubeToSpherical.shader.meta
  10. 12
      Assets/ScriptableRenderLoop/core/RenderingDataStore.cs.meta
  11. 40
      Assets/ScriptableRenderLoop/core/RenderingDataStore.cs

99
Assets/BasicRenderLoopTutorial/BasicRenderLoop.cs


// - This loop also does not setup lightmaps, light probes, reflection probes or light cookies
[ExecuteInEditMode]
public class BasicRenderLoop : RenderPipeline
public class BasicRenderLoop : RenderPipelineAsset
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("Renderloop/Create BasicRenderLoop")]

}
#endif
protected override IRenderPipeline InternalCreatePipeline()
{
return new BasicRenderLoopInstance();
}
}
public class BasicRenderLoopInstance : RenderPipeline
{
protected override void InternalBuild()
{}
protected override void InternalCleanup()
{}
public override void Render(ScriptableRenderContext renderLoop, IScriptableRenderDataStore dataStore)
public override void Render(ScriptableRenderContext renderLoop)
base.Render(renderLoop, dataStore);
Render(renderLoop, m_CamerasToRender);
BasicRendering.Render(renderLoop, m_CamerasToRender);
}
public static class BasicRendering
{
public static void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras)
{
foreach (var camera in cameras)

if (!CullResults.GetCullingParameters (camera, out cullingParams))
if (!CullResults.GetCullingParameters(camera, out cullingParams))
CullResults cull = CullResults.Cull (ref cullingParams, context);
CullResults cull = CullResults.Cull(ref cullingParams, context);
context.SetupCameraProperties (camera);
context.SetupCameraProperties(camera);
// clear depth buffer
var cmd = new CommandBuffer();

// Setup global lighting shader variables
SetupLightShaderVariables (cull.visibleLights, context);
SetupLightShaderVariables(cull.visibleLights, context);
var settings = new DrawRendererSettings (cull, camera, new ShaderPassName("BasicPass"));
var settings = new DrawRendererSettings(cull, camera, new ShaderPassName("BasicPass"));
settings.inputFilter.SetQueuesOpaque ();
context.DrawRenderers (ref settings);
settings.inputFilter.SetQueuesOpaque();
context.DrawRenderers(ref settings);
context.DrawSkybox (camera);
context.DrawSkybox(camera);
settings.inputFilter.SetQueuesTransparent ();
context.DrawRenderers (ref settings);
settings.inputFilter.SetQueuesTransparent();
context.DrawRenderers(ref settings);
context.Submit ();
context.Submit();
static void SetupLightShaderVariables (VisibleLight[] lights, ScriptableRenderContext context)
private static void SetupLightShaderVariables(VisibleLight[] lights, ScriptableRenderContext context)
{
// We only support up to 8 visible lights here. More complex approaches would
// be doing some sort of per-object light setups, but here we go for simplest possible

// to the viewer, so that "most important" lights in the scene are picked, and not the 8
// that happened to be first.
int lightCount = Mathf.Min (lights.Length, kMaxLights);
int lightCount = Mathf.Min(lights.Length, kMaxLights);
// Prepare light data
Vector4[] lightColors = new Vector4[kMaxLights];

if (light.lightType == LightType.Directional)
{
// light position for directional lights is: (-direction, 0)
var dir = light.localToWorld.GetColumn (2);
lightPositions[i] = new Vector4 (-dir.x, -dir.y, -dir.z, 0);
var dir = light.localToWorld.GetColumn(2);
lightPositions[i] = new Vector4(-dir.x, -dir.y, -dir.z, 0);
var pos = light.localToWorld.GetColumn (3);
lightPositions[i] = new Vector4 (pos.x, pos.y, pos.z, 1);
var pos = light.localToWorld.GetColumn(3);
lightPositions[i] = new Vector4(pos.x, pos.y, pos.z, 1);
}
// attenuation set in a way where distance attenuation can be computed:
// float lengthSq = dot(toLight, toLight);

// spot direction & attenuation
if (light.lightType == LightType.Spot)
{
var dir = light.localToWorld.GetColumn (2);
lightSpotDirections[i] = new Vector4 (-dir.x, -dir.y, -dir.z, 0);
var dir = light.localToWorld.GetColumn(2);
lightSpotDirections[i] = new Vector4(-dir.x, -dir.y, -dir.z, 0);
float cosTheta = Mathf.Cos (radAngle * 0.25f);
float cosPhi = Mathf.Cos (radAngle * 0.5f);
float cosTheta = Mathf.Cos(radAngle * 0.25f);
float cosPhi = Mathf.Cos(radAngle * 0.5f);
lightAtten[i] = new Vector4 (cosPhi, (cosDiff != 0.0f) ? 1.0f / cosDiff : 1.0f, quadAtten, rangeSq);
lightAtten[i] = new Vector4(cosPhi, (cosDiff != 0.0f) ? 1.0f / cosDiff : 1.0f, quadAtten, rangeSq);
lightSpotDirections[i] = new Vector4 (0, 0, 1, 0);
lightAtten[i] = new Vector4 (-1, 1, quadAtten, rangeSq);
lightSpotDirections[i] = new Vector4(0, 0, 1, 0);
lightAtten[i] = new Vector4(-1, 1, quadAtten, rangeSq);
}
}
GetShaderConstantsFromNormalizedSH (ref ambientSH, shConstants);
GetShaderConstantsFromNormalizedSH(ref ambientSH, shConstants);
cmd.SetGlobalVectorArray ("globalLightColor", lightColors);
cmd.SetGlobalVectorArray ("globalLightPos", lightPositions);
cmd.SetGlobalVectorArray ("globalLightSpotDir", lightSpotDirections);
cmd.SetGlobalVectorArray ("globalLightAtten", lightAtten);
cmd.SetGlobalVector ("globalLightCount", new Vector4 (lightCount, 0, 0, 0));
cmd.SetGlobalVectorArray ("globalSH", shConstants);
context.ExecuteCommandBuffer (cmd);
cmd.Dispose ();
cmd.SetGlobalVectorArray("globalLightColor", lightColors);
cmd.SetGlobalVectorArray("globalLightPos", lightPositions);
cmd.SetGlobalVectorArray("globalLightSpotDir", lightSpotDirections);
cmd.SetGlobalVectorArray("globalLightAtten", lightAtten);
cmd.SetGlobalVector("globalLightCount", new Vector4(lightCount, 0, 0, 0));
cmd.SetGlobalVectorArray("globalSH", shConstants);
context.ExecuteCommandBuffer(cmd);
cmd.Dispose();
static void GetShaderConstantsFromNormalizedSH (ref SphericalHarmonicsL2 ambientProbe, Vector4[] outCoefficients)
private static void GetShaderConstantsFromNormalizedSH(ref SphericalHarmonicsL2 ambientProbe, Vector4[] outCoefficients)
{
for (int channelIdx = 0; channelIdx < 3; ++channelIdx)
{

outCoefficients[6].z = ambientProbe[2, 8];
outCoefficients[6].w = 1.0f;
}
}

2
Assets/Editor/Tests/RenderloopTests/CullResultsTest.cs


public void TestReflectionProbes()
{
UnityEditor.SceneManagement.EditorSceneManager.OpenScene("Assets/Editor/Tests/TestScene.unity");
RenderLoopTestFixture.Run(InspectCullResults);
RenderLoopTestFixtureInstance.Run(InspectCullResults);
}
}

26
Assets/Editor/Tests/RenderloopTests/RenderloopTestFixture.cs


using UnityEngine.ScriptableRenderPipeline;
[ExecuteInEditMode]
public class RenderLoopTestFixture : RenderPipeline
public class RenderLoopTestFixture : RenderPipelineAsset
{
protected override IRenderPipeline InternalCreatePipeline()
{
return new BasicRenderLoopInstance();
}
}
public class RenderLoopTestFixtureInstance : RenderPipeline
protected override void InternalBuild()
{}
protected override void InternalCleanup()
{}
public override void Render(ScriptableRenderContext renderLoop, IScriptableRenderDataStore dataStore)
public override void Render(ScriptableRenderContext renderLoop)
{
cameraProvider.GetCamerasToRender(m_CamerasToRender);

continue;
CullingParameters cullingParams;
bool gotCullingParams = CullResults.GetCullingParameters(camera, out cullingParams);
Assert.IsTrue(gotCullingParams);

CleanCameras(m_CamerasToRender);
m_CamerasToRender.Clear();
}
public static void Run(TestDelegate renderCallback)
{
if (m_Instance == null)

2
Assets/ScriptableRenderLoop/HDRenderLoop/Editor/HDRenderLoopInspector.cs


EditorUtility.SetDirty(renderLoop); // Repaint
// SetAssetDirty will tell renderloop to rebuild
renderLoop.ClearCachedData();
renderLoop.DestroyCreatedInstances();
}
EditorGUI.BeginChangeCheck();

80
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class HDRenderLoopInstance : RenderPipeline
{
private readonly HDRenderLoop m_Owner;
public HDRenderLoopInstance(HDRenderLoop owner)
{
m_Owner = owner;
}
protected override void InternalBuild()
{
if (m_Owner != null)
m_Owner.Build();
}
protected override void InternalCleanup()
{
if (m_Owner != null)
m_Owner.Cleanup();
}
[NonSerialized]
readonly List<Camera> m_CamerasToRender = new List<Camera>();
public override void Render(ScriptableRenderContext renderContext)
{
cameraProvider.GetCamerasToRender(m_CamerasToRender);
m_Owner.Render(renderContext, m_CamerasToRender);
CleanCameras(m_CamerasToRender);
m_CamerasToRender.Clear();
}
}
public partial class HDRenderLoop : RenderPipeline
public class HDRenderLoop : RenderPipelineAsset
{
const string k_HDRenderLoopPath = "Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.asset";

}
}
#endif
private class HDLoopDataStore : RenderingDataStore
{
public HDLoopDataStore(BaseRenderPipeline owner) : base(owner)
{ }
protected override void InternalBuild()
{
base.InternalBuild();
HDRenderLoop theOwner = owner as HDRenderLoop;
if (theOwner != null)
theOwner.Build();
}
protected override void InternalCleanup()
{
base.InternalCleanup();
HDRenderLoop theOwner = owner as HDRenderLoop;
if (theOwner != null)
theOwner.Cleanup();
}
}
public override IScriptableRenderDataStore ConstructDataStore()
protected override IRenderPipeline InternalCreatePipeline()
return new HDLoopDataStore(this);
return new HDRenderLoopInstance(this);
SkyManager m_SkyManager = new SkyManager();
public SkyManager skyManager
{

m_ShadowSettings.maxShadowDistance = m_CommonSettings.shadowMaxDistance;
}
}
[NonSerialized]
readonly List<Camera> m_CamerasToRender = new List<Camera>();
public override void Render(ScriptableRenderContext renderLoop, IScriptableRenderDataStore dataStore)
public void Render(ScriptableRenderContext renderLoop, IEnumerable<Camera> cameras)
base.Render(renderLoop, dataStore);
cameraProvider.GetCamerasToRender(m_CamerasToRender);
if (!m_LitRenderLoop.isInit)
{
m_LitRenderLoop.RenderInit(renderLoop);

// Set Frame constant buffer
// TODO...
foreach (var camera in m_CamerasToRender)
foreach (var camera in cameras)
{
// Set camera constant buffer
// TODO...

renderLoop.Submit();
}
CleanCameras(m_CamerasToRender);
m_CamerasToRender.Clear();
// Post effects
}
}

4
Assets/ScriptableRenderLoop/HDRenderLoop/Utilities.cs


using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Experimental.Rendering;

76
Assets/ScriptableRenderLoop/core/RenderPipeline.cs


using System;
public abstract class RenderPipeline : BaseRenderPipeline
{
private readonly HashSet<IScriptableRenderDataStore> m_AssociatedDataStores = new HashSet<IScriptableRenderDataStore>();
private ICameraProvider m_CameraProvider;
public override ICameraProvider cameraProvider
{
get
{
if (m_CameraProvider == null)
m_CameraProvider = ConstructCameraProvider();
return m_CameraProvider;
}
set { m_CameraProvider = value; }
}
public override void Render(ScriptableRenderContext renderContext, IScriptableRenderDataStore dataStore)
{
if (dataStore == null)
throw new ArgumentException(string.Format("Null DataStore has been passed into pipe {0}", this));
if (dataStore.owner == null)
throw new ArgumentException(string.Format("DataStore owner is null. It needs o be owned by loop {0}", this));
public abstract class RenderPipeline : BaseRenderPipeline
{
private ICameraProvider m_CameraProvider;
if (dataStore.owner != null && !ReferenceEquals(dataStore.owner, this))
throw new ArgumentException(string.Format("DataStore {0} has been passed into pipe {1}, but is owned by {2}", dataStore, this, dataStore.owner));
m_AssociatedDataStores.Add(dataStore);
dataStore.Build();
}
public override void ClearCachedData()
{
foreach (var store in m_AssociatedDataStores)
store.Cleanup();
public override ICameraProvider cameraProvider
{
get
{
if (m_CameraProvider == null)
m_CameraProvider = ConstructCameraProvider();
m_AssociatedDataStores.Clear();
}
return m_CameraProvider;
}
set { m_CameraProvider = value; }
}
public override ICameraProvider ConstructCameraProvider()
{
return new DefaultCameraProvider();
}
public override ICameraProvider ConstructCameraProvider()
{
return new DefaultCameraProvider();
}
public override IScriptableRenderDataStore ConstructDataStore()
{
return new RenderingDataStore(this);
}
public static void CleanCameras(IEnumerable<Camera> cameras)
{
foreach (var camera in cameras)
camera.ClearIntermediateRenderers();
}
}
public static void CleanCameras(IEnumerable<Camera> cameras)
{
foreach (var camera in cameras)
camera.ClearIntermediateRenderers();
}
}
}

80
Assets/ScriptableRenderLoop/fptl/FptlLighting.cs


namespace UnityEngine.Experimental.ScriptableRenderLoop
{
public class FptlLightingInstance : RenderPipeline
{
private readonly FptlLighting m_Owner;
public FptlLightingInstance(FptlLighting owner)
{
m_Owner = owner;
}
protected override void InternalBuild()
{
if (m_Owner != null)
m_Owner.Build();
}
protected override void InternalCleanup()
{
if (m_Owner != null)
m_Owner.Cleanup();
}
[NonSerialized]
readonly List<Camera> m_CamerasToRender = new List<Camera>();
public override void Render(ScriptableRenderContext renderContext)
{
cameraProvider.GetCamerasToRender(m_CamerasToRender);
m_Owner.Render(renderContext, m_CamerasToRender);
CleanCameras(m_CamerasToRender);
m_CamerasToRender.Clear();
}
}
public class FptlLighting : RenderPipeline
public class FptlLighting : RenderPipelineAsset
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("Renderloop/CreateRenderLoopFPTL")]

//AssetDatabase.CreateAsset(instance, "Assets/ScriptableRenderLoop/fptl/renderloopfptl.asset");
}
#endif
private class FptlLightingDataStore : RenderingDataStore
protected override IRenderPipeline InternalCreatePipeline()
public FptlLightingDataStore(BaseRenderPipeline owner) : base(owner)
{}
protected override void InternalBuild()
{
base.InternalBuild();
FptlLighting theOwner = owner as FptlLighting;
if (theOwner != null)
theOwner.Build();
}
protected override void InternalCleanup()
{
base.InternalCleanup();
FptlLighting theOwner = owner as FptlLighting;
if (theOwner != null)
theOwner.Cleanup();
}
return new FptlLightingInstance(this);
}
[SerializeField]

m_shadowBufferID = Shader.PropertyToID("g_tShadowBuffer");
}
public override IScriptableRenderDataStore ConstructDataStore()
{
return new FptlLightingDataStore(this);
}
static void SetupGBuffer(int width, int height, CommandBuffer cmd)
{
var format10 = RenderTextureFormat.ARGB32;

return numLightsOut + numProbesOut;
}
[NonSerialized]
readonly List<Camera> m_CamerasToRender = new List<Camera>();
public override void Render(ScriptableRenderContext renderLoop, IScriptableRenderDataStore dataStore)
public void Render(ScriptableRenderContext renderLoop, IEnumerable<Camera> cameras)
base.Render(renderLoop, dataStore);
cameraProvider.GetCamerasToRender(m_CamerasToRender);
foreach (var camera in m_CamerasToRender)
foreach (var camera in cameras)
{
CullingParameters cullingParams;
if (!CullResults.GetCullingParameters(camera, out cullingParams))

}
renderLoop.Submit();
CleanCameras(m_CamerasToRender);
m_CamerasToRender.Clear();
}
void FinalPass(ScriptableRenderContext loop)

9
Assets/ScriptableRenderLoop/common/CubeToSpherical.shader.meta


fileFormatVersion: 2
guid: 595434cc3b6405246b6cd3086d0b6f7d
timeCreated: 1482845902
licenseType: Pro
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

12
Assets/ScriptableRenderLoop/core/RenderingDataStore.cs.meta


fileFormatVersion: 2
guid: bd20f7d7bf8c34548b33677973016a96
timeCreated: 1483005411
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

40
Assets/ScriptableRenderLoop/core/RenderingDataStore.cs


using UnityEngine.Experimental.Rendering;
namespace UnityEngine.ScriptableRenderPipeline
{
public class RenderingDataStore : IScriptableRenderDataStore
{
private bool m_NeedsBuild = true;
public RenderingDataStore(IRenderPipeline owner)
{
this.owner = owner;
}
public void Build()
{
if (m_NeedsBuild)
{
InternalBuild();
m_NeedsBuild = false;
}
}
protected virtual void InternalBuild()
{}
public void Cleanup()
{
if (!m_NeedsBuild)
{
InternalCleanup();
m_NeedsBuild = true;
}
}
protected virtual void InternalCleanup()
{}
public IRenderPipeline owner { get; private set; }
}
}
正在加载...
取消
保存