浏览代码

Shadow slice resolution being computed automatically for best fit in the shadow atlas.

Moved all non-serialized settings from pipeline asset to pipeline instance.
/vr_sandbox
Felipe Lira 8 年前
当前提交
c9e863e4
共有 5 个文件被更改,包括 89 次插入104 次删除
  1. 9
      Assets/LowEndRenderLoop/LowEndPipeline.asset
  2. 20
      Assets/LowEndRenderLoop/LowEndRenderLoopScene.unity
  3. 19
      Assets/LowEndRenderLoop/LowEndRenderLoopShader.shader
  4. 115
      Assets/LowEndRenderLoop/LowEndRenderPipeline.cs
  5. 30
      Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs

9
Assets/LowEndRenderLoop/LowEndPipeline.asset


m_Name: LowEndPipeline
m_EditorClassIdentifier:
m_SupportsVertexLight: 1
m_ShadowSettings:
enabled: 1
shadowAtlasWidth: 4096
shadowAtlasHeight: 4096
maxShadowDistance: 1000
directionalLightCascadeCount: 4
directionalLightCascades: {x: 0.05, y: 0.2, z: 0.3}
m_ShadowAtlasWidth: 2048
m_ShadowAtlasHeight: 2048

20
Assets/LowEndRenderLoop/LowEndRenderLoopScene.unity


m_Component:
- component: {fileID: 1111054117}
- component: {fileID: 1111054118}
- component: {fileID: 1111054119}
m_Layer: 0
m_Name: Directional light
m_TagString: Untagged

m_CCT: 6500
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!114 &1111054119
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 1111054116}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 7a68c43fe1f2a47cfa234b5eeaa98012, type: 3}
m_Name:
m_EditorClassIdentifier:
shadowResolution: 512
shadowDimmer: 1
affectDiffuse: 1
affectSpecular: 1
archetype: 0
isDoubleSided: 0
areaLightLength: 0
areaLightWidth: 0
--- !u!1 &1177504217
GameObject:
m_ObjectHideFlags: 0

19
Assets/LowEndRenderLoop/LowEndRenderLoopShader.shader


ZWrite[_ZWrite]
CGPROGRAM
#pragma enable_d3d11_debug_symbols
#pragma target 2.0
#pragma vertex vert
#pragma fragment frag

#include "UnityStandardUtils.cginc"
#define DEBUG_CASCADES 0
#define MAX_SHADOW_CASCADES 4
#define MAX_LIGHTS 8

{
int cascadeIndex = ComputeCascadeIndex(posWorld.w);
float3 shadowCoord = mul(_WorldToShadow[cascadeIndex], float4(posWorld.xyz, 1.0));
shadowCoord.z = saturate(shadowCoord.z);
// TODO: Apply proper bias considering NdotL
half bias = 0.001;

#else
shadowAttenuation = step(shadowCoord.z - bias, shadowDepth);
#endif
#if DEBUG_CASCADES
half4 cascadeColors[MAX_SHADOW_CASCADES] = { half4(1.0, 0.0, 0.0, 1.0), half4(0.0, 1.0, 0.0, 1.0), half4(0.0, 0.0, 1.0, 1.0), half4(1.0, 0.0, 1.0, 1.0) };
return cascadeColors[cascadeIndex] * diffuseColor * max(shadowAttenuation, 0.5);
#else
#endif
}
struct VertexInput

half3 color = i.color * diffuseAlbedo.rgb;
#if DEBUG_CASCADES
LightInput lightInput;
lightInput.pos = globalLightPos[0];
lightInput.color = globalLightColor[0];
lightInput.atten = globalLightAtten[0];
lightInput.spotDir = globalLightSpotDir[0];
color = EvaluateOneLightAndShadow(lightInput, diffuse, specColor, i.normalWS, i.posWSEyeZ, viewDir);
#else
for (int lightIndex = 0; lightIndex < globalLightCount.x; ++lightIndex)
{
LightInput lightInput;

else
color += EvaluateOneLight(lightInput, diffuse, specColor, i.normalWS, posWorld, viewDir);
}
#endif
return half4(color, diffuseAlbedo.a);
}
ENDCG

115
Assets/LowEndRenderLoop/LowEndRenderPipeline.cs


using System;
using UnityEngine;
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
private readonly LowEndRenderPipeline m_Owner;
public LowEndRenderPipelineInstance(LowEndRenderPipeline owner)
{
m_Owner = owner;
if (m_Owner != null)
m_Owner.Build();
}
public override void Dispose()
{
base.Dispose();
if (m_Owner != null)
m_Owner.Cleanup();
}
public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
{
base.Render(renderContext, cameras);
if (m_Owner != null)
m_Owner.Render(renderContext, cameras);
}
}
#endregion
private readonly LowEndRenderPipeline m_Asset;
public class LowEndRenderPipeline : RenderPipelineAsset
{
#region AssetAndPipelineCreation
#if UNITY_EDITOR
[UnityEditor.MenuItem("Renderloop/Create Low End Pipeline")]
static void CreateLowEndPipeline()
{
var instance = ScriptableObject.CreateInstance<LowEndRenderPipeline>();
AssetDatabase.CreateAsset(instance, "Assets/LowEndRenderLoop/LowEndPipeline.asset");
}
#endif
ShadowRenderPass m_ShadowPass;
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
protected override IRenderPipeline InternalCreatePipeline()
public LowEndRenderPipelineInstance(LowEndRenderPipeline asset)
return new LowEndRenderPipelineInstance(this);
}
#endregion
#region Storage
public bool m_SupportsVertexLight = true;
m_Asset = asset;
[SerializeField]
ShadowSettings m_ShadowSettings = ShadowSettings.Default;
ShadowRenderPass m_ShadowPass;
#endregion
#region RenderPipelineAssetImplementation
public void Build()
{
public void Cleanup()
public override void Render(ScriptableRenderContext context, Camera[] cameras)
}
base.Render(context, cameras);
public void Render(ScriptableRenderContext context, IEnumerable<Camera> cameras)
{
foreach (Camera camera in cameras)
{
CullingParameters cullingParameters;

context.Submit();
}
#endregion
#region HelperMethods
m_ShadowSettings.directionalLightCascadeCount = QualitySettings.shadowCascades; ;
m_ShadowSettings.shadowAtlasWidth = 1024;
m_ShadowSettings.shadowAtlasHeight = 1024;
m_ShadowSettings.directionalLightCascadeCount = QualitySettings.shadowCascades;
m_ShadowSettings.shadowAtlasWidth = m_Asset.ShadowAtlasWidth;
m_ShadowSettings.shadowAtlasHeight = m_Asset.ShadowAtlasHeight;
m_ShadowSettings.maxShadowDistance = QualitySettings.shadowDistance;
m_ShadowSettings.maxShadowLightsSupported = 1;
m_ShadowSettings.shadowType = ShadowSettings.ShadowType.LIGHTSPACE;

}
}
#region HelperMethods
private void SetupLightShaderVariables(VisibleLight[] lights, ScriptableRenderContext context)
{
if (lights.Length <= 0)

// TODO: Sort Lighting Importance
int pixelLightCount = Mathf.Min(lights.Length, QualitySettings.pixelLightCount);
int vertexLightCount = Mathf.Min(lights.Length - pixelLightCount, kMaxLights);
int vertexLightCount = (m_Asset.SupportsVertexLight) ? Mathf.Min(lights.Length - pixelLightCount, kMaxLights) : 0;
int totalLightCount = pixelLightCount + vertexLightCount;
for (int i = 0; i < totalLightCount; ++i)

cmd.Dispose();
}
private void RenderShadowPass(CullResults results, ScriptableRenderContext context, out ShadowOutput shadow)
{
m_ShadowPass.Render(context, results, out shadow);
}
void SetupShadowShaderVariables(ShadowOutput shadowOutput, ScriptableRenderContext context, float shadowNear, float shadowFar)
{
// PSSM distance settings

outCoefficients[6].z = ambientProbe[2, 8];
outCoefficients[6].w = 1.0f;
}
#endregion
}
#endregion
public class LowEndRenderPipeline : RenderPipelineAsset
{
#region AssetAndPipelineCreation
#if UNITY_EDITOR
[UnityEditor.MenuItem("Renderloop/Create Low End Pipeline")]
static void CreateLowEndPipeline()
{
var instance = ScriptableObject.CreateInstance<LowEndRenderPipeline>();
UnityEditor.AssetDatabase.CreateAsset(instance, "Assets/LowEndRenderLoop/LowEndPipeline.asset");
}
#endif
protected override IRenderPipeline InternalCreatePipeline()
{
return new LowEndRenderPipelineInstance(this);
}
#endregion
#region PipelineAssetSettings
public bool m_SupportsVertexLight = true;
public int m_ShadowAtlasWidth = 1024;
public int m_ShadowAtlasHeight = 1024;
public bool SupportsVertexLight { get { return m_SupportsVertexLight;} private set { m_SupportsVertexLight = value; } }
public int ShadowAtlasWidth { get { return m_ShadowAtlasWidth; } private set { m_ShadowAtlasWidth = value; } }
public int ShadowAtlasHeight { get { return m_ShadowAtlasHeight; } private set { m_ShadowAtlasHeight = value; } }
#endregion
}

30
Assets/ScriptableRenderLoop/RenderPasses/ShadowRenderPass.cs


ShadowSettings settings = new ShadowSettings();
settings.enabled = true;
settings.shadowAtlasHeight = settings.shadowAtlasWidth = 4096;
settings.directionalLightCascadeCount = 1;
settings.directionalLightCascades = new Vector3(0.05F, 0.2F, 0.3F);
settings.directionalLightCascadeCount = 4;
settings.maxShadowDistance = 1000.0F;

return requestedPages.Count != 0;
}
static List<InputShadowLightData> GetInputShadowLightData(CullResults cullResults)
static List<InputShadowLightData> GetInputShadowLightData(CullResults cullResults, ShadowSettings settings)
{
var shadowCasters = new List<InputShadowLightData>();
var lights = cullResults.visibleLights;

}
AdditionalLightData additionalLight = lights[i].light.GetComponent<AdditionalLightData>();
int shadowResolution;
if (additionalLight != null)
shadowResolution = AdditionalLightData.GetShadowResolution(additionalLight);
else
shadowResolution = GetMaxTileResolutionInAtlas(settings.shadowAtlasWidth, settings.shadowAtlasHeight, settings.directionalLightCascadeCount);
light.shadowResolution = AdditionalLightData.GetShadowResolution(additionalLight);
light.shadowResolution = shadowResolution;
shadowCasters.Add(light);
}

static int GetMaxTileResolutionInAtlas(int atlasWidth, int atlasHeight, int tileCount)
{
int resolution = Mathf.Min(atlasWidth, atlasHeight);
if (tileCount > Mathf.Log(resolution))
{
Debug.LogError(String.Format("Cannot fit {0} tiles into current shadowmap atlas of size ({1}, {2}). ShadowMap Resolution set to zero.", tileCount, atlasWidth, atlasHeight));
return 0;
}
int currentTileCount = atlasWidth / resolution + atlasHeight / resolution;
while (currentTileCount < tileCount)
{
resolution = resolution >> 1;
currentTileCount = atlasWidth / resolution + atlasHeight / resolution;
}
return resolution;
}
public void UpdateCullingParameters(ref CullingParameters parameters)
{
parameters.shadowDistance = Mathf.Min(m_Settings.maxShadowDistance, parameters.shadowDistance);

}
// Pack all shadow quads into the texture
if (!AutoPackLightsIntoShadowTexture(GetInputShadowLightData(cullResults), cullResults.visibleLights, out packedShadows))
if (!AutoPackLightsIntoShadowTexture(GetInputShadowLightData(cullResults, m_Settings), cullResults.visibleLights, out packedShadows))
{
// No shadowing lights found, so skip all rendering
return;

正在加载...
取消
保存