浏览代码

Cleanup, Integrations with Shadows.hlsl

/main
John 7 年前
当前提交
5fcbd9af
共有 2 个文件被更改,包括 69 次插入103 次删除
  1. 10
      ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs
  2. 162
      ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader

10
ScriptableRenderPipeline/LightweightPipeline/LWRP/LightweightPipeline.cs


context.DrawRenderers(m_CullResults.visibleRenderers, ref opaqueDrawSettings, opaqueFilterSettings);
}
//TODO: Offline
//TODO: Find place to live.
//http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/
float farH = 2.0f * Mathf.Tan(m_CurrCamera.fieldOfView * 0.5f * Mathf.Deg2Rad) * m_CurrCamera.farClipPlane;
float farW = farH * m_CurrCamera.aspect;

private void CollectShadowPass(ref ScriptableRenderContext context)
{
CommandBuffer cmd = CommandBufferPool.Get("Collect Shadows");
//NOTE: Renderscale?
cmd.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32);
cmd.GetTemporaryRT(m_ScreenSpaceShadowMapRTID, m_CurrCamera.pixelWidth, m_CurrCamera.pixelHeight, 0, FilterMode.Bilinear, RenderTextureFormat.R8);
cmd.SetGlobalTexture("_Depth", m_DepthRT);
cmd.SetGlobalTexture("_ShadowCascades", m_ShadowMapRT);
cmd.Blit(null, m_ScreenSpaceShadowMapRT, m_ScreenSpaceShadowsMaterial); //TODO: PCF passes
cmd.Blit(null, m_ScreenSpaceShadowMapRT, m_ScreenSpaceShadowsMaterial);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);

162
ScriptableRenderPipeline/LightweightPipeline/LWRP/Shaders/LightweightScreenSpaceShadows.shader


{
Tags {}
Pass
{
ZTest Always ZWrite Off
HLSLINCLUDE
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment Fragment
//Keeping the compiler quiet about Shadows.hlsl.
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "CoreRP/ShaderLibrary/EntityLighting.hlsl"
#include "CoreRP/ShaderLibrary/ImageBasedLighting.hlsl"
#include "LWRP/ShaderLibrary/Core.hlsl"
#include "LWRP/ShaderLibrary/Shadows.hlsl"
#include "LWRP/ShaderLibrary/Core.hlsl"
#define MAX_SHADOW_CASCADES 4
CBUFFER_START(_ShadowBuffer)
// Last cascade is initialized with a no-op matrix. It always transforms
// shadow coord to half(0, 0, NEAR_PLANE). We use this trick to avoid
// branching since ComputeCascadeIndex can return cascade index = MAX_SHADOW_CASCADES
float4x4 _WorldToShadow[MAX_SHADOW_CASCADES + 1];
float4 _DirShadowSplitSpheres[MAX_SHADOW_CASCADES];
float4 _DirShadowSplitSphereRadii;
half4 _ShadowOffset0;
half4 _ShadowOffset1;
half4 _ShadowOffset2;
half4 _ShadowOffset3;
half4 _ShadowData; // (x: shadowStrength)
CBUFFER_END
//Scene Depth
TEXTURE2D(_Depth);
SAMPLER(sampler_Depth);
//Scene Depth
TEXTURE2D(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
//Far plane corners in view space
float4 _FrustumCorners[4];
//Shadow Cascades
TEXTURE2D_SHADOW(_ShadowCascades);
SAMPLER_CMP(sampler_ShadowCascades);
//Far plane corners in view space
float4 _FrustumCorners[4];
struct VertexInput
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
uint id : SV_VertexID;
};
struct VertexOutput
{
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
float3 ray : TEXCOORD1;
};
VertexOutput Vertex(VertexInput i)
{
VertexOutput o;
o.pos = TransformObjectToHClip(i.vertex.xyz);
o.uv = i.uv;
o.ray = _FrustumCorners[i.id];
return o;
}
float4 GetCascadeWeights(float3 wpos)
{
float3 fromCenter0 = wpos.xyz - _DirShadowSplitSpheres[0].xyz;
float3 fromCenter1 = wpos.xyz - _DirShadowSplitSpheres[1].xyz;
float3 fromCenter2 = wpos.xyz - _DirShadowSplitSpheres[2].xyz;
float3 fromCenter3 = wpos.xyz - _DirShadowSplitSpheres[3].xyz;
float4 distances2 = float4(dot(fromCenter0, fromCenter0), dot(fromCenter1, fromCenter1), dot(fromCenter2, fromCenter2), dot(fromCenter3, fromCenter3));
half4 weights = half4(distances2 < _DirShadowSplitSphereRadii);
weights.yzw = saturate(weights.yzw - weights.xyz);
struct VertexInput
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
uint id : SV_VertexID;
};
return weights;
}
struct Interpolators
{
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
float3 ray : TEXCOORD1;
};
float4 GetShadowCoordinates (float4 wpos, float4 cascadeWeights)
{
float3 sc0 = mul (_WorldToShadow[0], wpos).xyz;
float3 sc1 = mul (_WorldToShadow[1], wpos).xyz;
float3 sc2 = mul (_WorldToShadow[2], wpos).xyz;
float3 sc3 = mul (_WorldToShadow[3], wpos).xyz;
float4 shadowMapCoordinate = float4(sc0 * cascadeWeights[0] + sc1 * cascadeWeights[1] + sc2 * cascadeWeights[2] + sc3 * cascadeWeights[3], 1);
//NOTE: Core library reconstructs via inv projection.
float3 ComputeViewSpacePositionGeometric(Interpolators i)
{
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, i.uv);
return i.ray * Linear01Depth(depth, _ZBufferParams);
}
return shadowMapCoordinate;
}
Interpolators Vertex(VertexInput i)
{
Interpolators o;
o.pos = TransformObjectToHClip(i.vertex.xyz);
o.uv = i.uv;
o.ray = _FrustumCorners[i.id].xyz;
return o;
}
//TODO: Handle orthographic.
//NOTE: This function exists in Core library via inv projection.
float3 ComputeViewSpacePosition(VertexOutput i)
{
float depth = SAMPLE_DEPTH_TEXTURE(_Depth, sampler_Depth, i.uv);
depth = Linear01Depth(depth, _ZBufferParams);
half Fragment(Interpolators i) : SV_Target
{
//Reconstruct the world position.
//TODO: More/less optimal to do unprojection method?
float3 vpos = ComputeViewSpacePositionGeometric(i);
float3 wpos = mul(unity_CameraToWorld, float4(vpos, 1)).xyz;
//Calculate the shadow coordinates.
half cascade = ComputeCascadeIndex(wpos);
float4 coords = ComputeShadowCoord(wpos, cascade);
return i.ray * depth;
}
return SampleShadowmap(coords);
}
half4 Fragment(VertexOutput i) : SV_Target
{
float3 vpos = ComputeViewSpacePosition(i);
float4 wpos = mul(unity_CameraToWorld, float4(vpos, 1));
float4 cascadeWeights = GetCascadeWeights(wpos);
float4 coords = GetShadowCoordinates(wpos, cascadeWeights);
ENDHLSL
half shadow = SAMPLE_TEXTURE2D_SHADOW(_ShadowCascades, sampler_ShadowCascades, coords);
Pass
{
ZTest Always ZWrite Off
return half4(shadow, shadow, shadow, 1);
}
HLSLPROGRAM
// -------------------------------------
// Lightweight Pipeline keywords
// We have no good approach exposed to skip shader variants, e.g, ideally we would like to skip _CASCADE for all puctual lights
// Lightweight combines light classification and shadows keywords to reduce shader variants.
// Lightweight shader library declares defines based on these keywords to avoid having to check them in the shaders
// Core.hlsl defines _MAIN_LIGHT_DIRECTIONAL and _MAIN_LIGHT_SPOT (point lights can't be main light)
// Shadow.hlsl defines _SHADOWS_ENABLED, _SHADOWS_SOFT, _SHADOWS_CASCADE, _SHADOWS_PERSPECTIVE
#pragma multi_compile _ _MAIN_LIGHT_DIRECTIONAL_SHADOW _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE _MAIN_LIGHT_DIRECTIONAL_SHADOW_SOFT _MAIN_LIGHT_DIRECTIONAL_SHADOW_CASCADE_SOFT _MAIN_LIGHT_SPOT_SHADOW _MAIN_LIGHT_SPOT_SHADOW_SOFT
#pragma vertex Vertex
#pragma fragment Fragment
ENDHLSL
}
}
正在加载...
取消
保存