浏览代码

HDRenderLoop: Add velocity buffer support (C# side)

/main
Sebastien Lagarde 8 年前
当前提交
b945ef44
共有 6 个文件被更改,包括 131 次插入53 次删除
  1. 75
      Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs
  2. 40
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs
  3. 18
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs
  4. 35
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl
  5. 4
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderConfig.cs
  6. 12
      Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassGBuffer.hlsl

75
Assets/ScriptableRenderLoop/HDRenderLoop/HDRenderLoop.cs


public bool displayOpaqueObjects = true;
public bool displayTransparentObjects = true;
public bool useForwardRenderingOnly = false;
public bool useForwardRenderingOnly = false; // TODO: Currently there is no way to strip the extra forward shaders generated by the shaders compiler, so we can switch dynamically.
public bool enableTonemap = true;
public float exposure = 0;

// TODO: Find a way to automatically create/iterate through these kind of class
Lit.RenderLoop m_LitRenderLoop;
Builtin.RenderLoop m_BuiltinRenderLoop;
// Debug
Material m_DebugViewMaterialGBuffer;

static private int s_CameraColorBuffer;
static private int s_CameraDepthBuffer;
static private int s_VelocityBuffer;
#if VELOCITY_IN_GBUFFER
private const bool m_velocityInGBuffer = true;
#else
private const bool m_velocityInGBuffer = false;
#endif
private bool m_requireVelocityBuffer = false;
static private ComputeBuffer s_punctualLightList;
static private ComputeBuffer s_envLightList;

// Init Lit material buffer - GBuffer and init
m_LitRenderLoop = new Lit.RenderLoop(); // Our object can be garbacge collected, so need to be allocate here
m_BuiltinRenderLoop = new Builtin.RenderLoop();
m_gbufferManager.gbufferCount = m_LitRenderLoop.GetGBufferCount();
for (int gbufferIndex = 0; gbufferIndex < m_gbufferManager.gbufferCount; ++gbufferIndex)

// In forward we still name the buffer as if they were gbuffer, it doesn't matter
int previousGbufferCount = m_gbufferManager.gbufferCount;
m_gbufferManager.gbufferCount += m_BuiltinRenderLoop.GetGBufferCount();
for (int gbufferIndex = previousGbufferCount; gbufferIndex < m_gbufferManager.gbufferCount; ++gbufferIndex)
{
m_gbufferManager.SetBufferDescription(gbufferIndex, "_CameraGBufferTexture" + gbufferIndex, m_BuiltinRenderLoop.RTFormat[gbufferIndex], m_BuiltinRenderLoop.RTReadWrite[gbufferIndex]);
}
s_VelocityBuffer = Shader.PropertyToID("_VelocityTexture");
if (m_velocityInGBuffer)
{
int gbufferIndex = m_gbufferManager.gbufferCount;
m_gbufferManager.gbufferCount++;
m_gbufferManager.SetBufferDescription(gbufferIndex, "_VelocityTexture", m_BuiltinRenderLoop.RTFormat[gbufferIndex], m_BuiltinRenderLoop.RTReadWrite[gbufferIndex]);
}
m_BuiltinRenderLoop.Rebuild();
}
void OnDisable()

int w = camera.pixelWidth;
int h = camera.pixelHeight;
cmd.GetTemporaryRT(s_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default);
cmd.GetTemporaryRT(s_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_gbufferManager.InitGBuffers(w, h, cmd);
if (!debugParameters.useForwardRenderingOnly)
{
m_gbufferManager.InitGBuffers(w, h, cmd);
}
cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
cmd.ClearRenderTarget(true, false, new Color(0, 0, 0, 0));

// END TEMP
}
// TODO: Create an opaque and transparent list!
void RenderOpaqueRenderList(CullResults cull, Camera camera, RenderLoop renderLoop, string passName)
{
if (!debugParameters.displayOpaqueObjects)

var settings = new DrawRendererSettings(cull, camera, new ShaderPassName(passName))
{
rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes,
sorting = { sortOptions = SortOptions.SortByMaterialThenMesh }
rendererConfiguration = RendererConfiguration.PerObjectLightProbe | RendererConfiguration.PerObjectReflectionProbes | RendererConfiguration.PerObjectLightmaps | RendererConfiguration.PerObjectLightProbeProxyVolume,
sorting = { sortOptions = SortOptions.BackToFront }
};
settings.inputFilter.SetQueuesTransparent();
renderLoop.DrawRenderers(ref settings);

{
if (debugParameters.useForwardRenderingOnly)
{
return;
return ;
}
// Bind material data

RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
}
void RenderVelocity(CullResults cullResults, Camera camera, RenderLoop renderLoop)
{
int w = camera.pixelWidth;
int h = camera.pixelHeight;
var cmd = new CommandBuffer { name = "Velocity Pass" };
// If we are not using the velocity buffer inside GBuffer, allocate one
if (m_requireVelocityBuffer)
{
cmd.GetTemporaryRT(s_VelocityBuffer, w, h, 0, FilterMode.Point, m_BuiltinRenderLoop.GetVelocityBufferFormat(), m_BuiltinRenderLoop.GetVelocityBufferReadWrite());
}
cmd.SetRenderTarget(new RenderTargetIdentifier(s_VelocityBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
renderLoop.ExecuteCommandBuffer(cmd);
cmd.Dispose();
// If opaque haven't been render during gbuffer pass, render them now
if (m_requireVelocityBuffer)
{
RenderOpaqueRenderList(cullResults, camera, renderLoop, "MotionVectors");
}
RenderTransparentRenderList(cullResults, camera, renderLoop, "MotionVectors");
}
void FinalPass(RenderLoop renderLoop)
{
// Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that

m_LitRenderLoop.RenderInit(renderLoop);
}
// Allocate a velocity buffer if we are forward only or if we haven't set the velocity buffer to be part of GBuffer
m_requireVelocityBuffer = debugParameters.useForwardRenderingOnly || (!debugParameters.useForwardRenderingOnly && !m_velocityInGBuffer);
// Do anything we need to do upon a new frame.
NewFrame();

RenderForward(cullResults, camera, renderLoop);
RenderForwardUnlit(cullResults, camera, renderLoop);
// Render as late as possible to benefit from an up to date depth buffer (TODO: could use equal depth test ?)
RenderVelocity(cullResults, camera, renderLoop);
FinalPass(renderLoop);
}

// Post effects
}
#if UNITY_EDITOR
#if UNITY_EDITOR
public override UnityEditor.SupportedRenderingFeatures GetSupportedRenderingFeatures()
{
var features = new UnityEditor.SupportedRenderingFeatures

return features;
}
#endif
#endif
}
}

40
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Builtin/BuiltinData.cs


public Vector3 diffuseColor;
public Vector3 emissiveColor;
};
[GenerateHLSL(PackingRules.Exact)]
public enum GBufferBuiltin
{
Count = 1
};
public class RenderLoop : Object
{
// Note: Velocity buffer must be the last buffer of a GBuffer pass if applicable
public RenderTextureFormat GetVelocityBufferFormat()
{
return RenderTextureFormat.RGHalf;
}
public RenderTextureReadWrite GetVelocityBufferReadWrite()
{
return RenderTextureReadWrite.Linear;
}
//-----------------------------------------------------------------------------
// GBuffer management
//-----------------------------------------------------------------------------
public int GetGBufferCount() { return (int)GBufferBuiltin.Count; }
public RenderTextureFormat[] RTFormat =
{
RenderTextureFormat.RGB111110Float
};
public RenderTextureReadWrite[] RTReadWrite =
{
RenderTextureReadWrite.Linear
};
public void Rebuild()
{
}
}
}
}

18
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Lit/Lit.cs


// GBuffer management
//-----------------------------------------------------------------------------
#if (VELOCITY_IN_GBUFFER)
public const int s_GBufferCount = (int)GBufferMaterial.Count + 2; // +1 for emissive buffer
#else
public const int s_GBufferCount = (int)GBufferMaterial.Count + 1;
#endif
public int GetGBufferCount() { return s_GBufferCount; }
public int GetGBufferCount() { return (int)GBufferMaterial.Count; }
RenderTextureFormat.ARGB32,
#if (VELOCITY_IN_GBUFFER)
RenderTextureFormat.RGHalf,
#endif
RenderTextureFormat.RGB111110Float
RenderTextureFormat.ARGB32
};
public RenderTextureReadWrite[] RTReadWrite =

RenderTextureReadWrite.Linear,
#if (VELOCITY_IN_GBUFFER)
RenderTextureReadWrite.Linear,
#endif
RenderTextureReadWrite.Linear
};

35
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/Material/Material.hlsl


#define ENCODE_INTO_GBUFFER(SURFACE_DATA, NAME) EncodeIntoGBuffer(SURFACE_DATA, MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2))
#define DECODE_FROM_GBUFFER(NAME) DecodeFromGBuffer(MERGE_NAME(NAME,0), MERGE_NAME(NAME,1), MERGE_NAME(NAME,2))
#ifdef VELOCITY_IN_GBUFFER
#define GBUFFER_VELOCITY_NAME(NAME) MERGE_NAME(NAME, 3)
#define GBUFFER_VELOCITY_TARGET(TARGET) MERGE_NAME(TARGET, 3)
#define GBUFFER_BAKE_LIGHTING_NAME(NAME) MERGE_NAME(NAME, 4)
#define GBUFFER_BAKE_LIGHTING_TARGET(TARGET) MERGE_NAME(TARGET, 4)
#else
#ifdef VELOCITY_IN_GBUFFER
#define GBUFFER_VELOCITY_NAME(NAME) MERGE_NAME(NAME, 4)
#define GBUFFER_VELOCITY_TARGET(TARGET) MERGE_NAME(TARGET, 4)
#endif
#elif GBUFFERMATERIAL_COUNT == 4

#define ENCODE_INTO_GBUFFER(SURFACE_DATA, NAME) EncodeIntoGBuffer(SURFACE_DATA, MERGE_NAME(NAME, 0), MERGE_NAME(NAME, 1), MERGE_NAME(NAME, 2), MERGE_NAME(NAME, 3))
#define DECODE_FROM_GBUFFER(NAME) DecodeFromGBuffer(MERGE_NAME(NAME, 0), MERGE_NAME(NAME, 1), MERGE_NAME(NAME, 2), MERGE_NAME(NAME, 3))
#define GBUFFER_BAKE_LIGHTING_NAME(NAME) MERGE_NAME(NAME, 4)
#define GBUFFER_BAKE_LIGHTING_TARGET(TARGET) MERGE_NAME(TARGET, 4)
#define GBUFFER_VELOCITY_NAME(NAME) MERGE_NAME(NAME, 4)
#define GBUFFER_VELOCITY_TARGET(TARGET) MERGE_NAME(TARGET, 4)
#else
#define GBUFFER_BAKE_LIGHTING_NAME(NAME) MERGE_NAME(NAME, 4)
#define GBUFFER_BAKE_LIGHTING_TARGET(TARGET) MERGE_NAME(TARGET, 4)
#endif
#elif GBUFFERMATERIAL_COUNT == 5

#define ENCODE_INTO_GBUFFER(SURFACE_DATA, NAME) EncodeIntoGBuffer(SURFACE_DATA, MERGE_NAME(NAME, 0), MERGE_NAME(NAME, 1), MERGE_NAME(NAME, 2), MERGE_NAME(NAME, 3), MERGE_NAME(NAME, 4))
#define DECODE_FROM_GBUFFER(NAME) DecodeFromGBuffer(MERGE_NAME(NAME, 0), MERGE_NAME(NAME, 1), MERGE_NAME(NAME, 2), MERGE_NAME(NAME, 3), MERGE_NAME(NAME, 4))
#define GBUFFER_BAKE_LIGHTING_NAME(NAME) MERGE_NAME(NAME, 5)
#define GBUFFER_BAKE_LIGHTING_TARGET(TARGET) MERGE_NAME(TARGET, 5)
#define GBUFFER_VELOCITY_NAME(NAME) MERGE_NAME(NAME, 5)
#define GBUFFER_VELOCITY_TARGET(TARGET) MERGE_NAME(TARGET, 5)
#else
#define GBUFFER_BAKE_LIGHTING_NAME(NAME) MERGE_NAME(NAME, 5)
#define GBUFFER_BAKE_LIGHTING_TARGET(TARGET) MERGE_NAME(TARGET, 5)
#define OUTPUT_GBUFFER_BAKE_LIGHTING(NAME) out float4 GBUFFER_BAKE_LIGHTING_NAME(NAME) : GBUFFER_BAKE_LIGHTING_TARGET(SV_Target)
#define DECLARE_GBUFFER_BAKE_LIGHTING(NAME) TEXTURE2D(GBUFFER_BAKE_LIGHTING_NAME(NAME));
#define ENCODE_BAKE_LIGHTING_INTO_GBUFFER(BAKE_DIFFUSE_LIGHTING, NAME) EncodeBakedDiffuseLigthingIntoGBuffer(BAKE_DIFFUSE_LIGHTING, GBUFFER_BAKE_LIGHTING_NAME(NAME))
#define FETCH_BAKE_LIGHTING_GBUFFER(NAME, TEX, UV) float4 GBUFFER_BAKE_LIGHTING_NAME(NAME) = LOAD_TEXTURE2D(GBUFFER_BAKE_LIGHTING_NAME(TEX), uint3(UV, 0));
#define DECODE_BAKE_LIGHTING_FROM_GBUFFER(NAME) DecodeBakedDiffuseLigthingFromGBuffer(GBUFFER_BAKE_LIGHTING_NAME(NAME))
#define OUTPUT_GBUFFER_BAKE_LIGHTING(NAME) out float4 GBUFFER_BAKE_LIGHTING_NAME(NAME) : GBUFFER_BAKE_LIGHTING_TARGET(SV_Target)
#define DECLARE_GBUFFER_BAKE_LIGHTING(NAME) TEXTURE2D(GBUFFER_BAKE_LIGHTING_NAME(NAME));
#define ENCODE_BAKE_LIGHTING_INTO_GBUFFER(BAKE_DIFFUSE_LIGHTING, NAME) EncodeBakedDiffuseLigthingIntoGBuffer(BAKE_DIFFUSE_LIGHTING, GBUFFER_BAKE_LIGHTING_NAME(NAME))
#define FETCH_BAKE_LIGHTING_GBUFFER(NAME, TEX, UV) float4 GBUFFER_BAKE_LIGHTING_NAME(NAME) = GBUFFER_BAKE_LIGHTING_NAME(TEX).Load(uint3(UV, 0));
#define DECODE_BAKE_LIGHTING_FROM_GBUFFER(NAME) DecodeBakedDiffuseLigthingFromGBuffer(GBUFFER_BAKE_LIGHTING_NAME(NAME))
#endif // #ifdef GBUFFERMATERIAL_COUNT

4
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderConfig.cs


// #define DIFFUSE_LAMBERT_BRDF
// #define USE_BSDF_PRE_LAMBDAV
// #define VELOCITY_IN_GBUFFER
// Caution: If you change one of the define below you need to regenerate the hlsl code (Push Generate Shader Includes)
//#define VELOCITY_IN_GBUFFER

12
Assets/ScriptableRenderLoop/HDRenderLoop/Shaders/ShaderPass/ShaderPassGBuffer.hlsl


#endif
void Frag( PackedVaryings packedInput,
OUTPUT_GBUFFER(outGBuffer)
#ifdef VELOCITY_IN_GBUFFER
, OUTPUT_GBUFFER_VELOCITY(outGBuffer)
#endif
, OUTPUT_GBUFFER_BAKE_LIGHTING(outGBuffer)
OUTPUT_GBUFFER(outGBuffer),
OUTPUT_GBUFFER_BAKE_LIGHTING(outGBuffer)
#ifdef VELOCITY_IN_GBUFFER
, OUTPUT_GBUFFER_VELOCITY(outGBuffer)
#endif
)
{
FragInput input = UnpackVaryings(packedInput);

PreLightData preLightData = GetPreLightData(V, positionWS, coord, bsdfData);
ENCODE_INTO_GBUFFER(surfaceData, outGBuffer);
ENCODE_BAKE_LIGHTING_INTO_GBUFFER(GetBakedDiffuseLigthing(preLightData, surfaceData, builtinData, bsdfData), outGBuffer);
ENCODE_BAKE_LIGHTING_INTO_GBUFFER(GetBakedDiffuseLigthing(preLightData, surfaceData, builtinData, bsdfData), outGBuffer);
}
正在加载...
取消
保存