浏览代码

Merge pull request #326 from EvgeniiG/cam_rel_render

Implement camera-relative rendering
/RenderPassXR_Sandbox
GitHub 8 年前
当前提交
2909c501
共有 14 个文件被更改,包括 146 次插入53 次删除
  1. 21
      Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs
  2. 10
      Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs
  3. 2
      Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs
  4. 35
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs
  5. 41
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs
  6. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  7. 4
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl
  8. 6
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderConfig.cs
  9. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderConfig.cs.hlsl
  10. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassLightTransport.hlsl
  11. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl
  12. 3
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl
  13. 47
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl
  14. 22
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl

21
Assets/ScriptableRenderPipeline/Core/Shadow/Shadow.cs


Object.DestroyImmediate(m_DebugMaterial);
}
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
override public bool Reserve( FrameId frameId, Camera camera, bool cameraRelativeRendering, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
{
for( uint i = 0, cnt = sr.facecount; i < cnt; ++i )
{

return Reserve( frameId, ref shadowData, sr, m_TmpWidths, m_TmpHeights, ref entries, ref payload, lights );
return Reserve( frameId, camera, cameraRelativeRendering, ref shadowData, sr, m_TmpWidths, m_TmpHeights, ref entries, ref payload, lights );
override public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
override public bool Reserve( FrameId frameId, Camera camera, bool cameraRelativeRendering, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payload, List<VisibleLight> lights)
{
if( m_FrameId.frameCount != frameId.frameCount )
m_ActiveEntriesCount = 0;

}
else
vp = Matrix4x4.identity; // should never happen, though
if (cameraRelativeRendering)
{
Vector3 camPosWS = camera.transform.position;
Matrix4x4 translation = Matrix4x4.Translate(camPosWS);
ce.current.view *= translation;
vp *= translation;
}
// write :(
ce.current.shadowAlgo = shadowAlgo;
m_EntryCache[ceIdx] = ce;

cullingParams.shadowDistance = Mathf.Min( m_ShadowSettings.maxShadowDistance, cullingParams.shadowDistance );
}
public override void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices )
public override void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices )
{
shadowDataIndices = null;

ShadowDataVector shadowVector = m_ShadowCtxt.shadowDatas;
ShadowPayloadVector payloadVector = m_ShadowCtxt.payloads;
m_ShadowIndices.Reset( m_TmpRequests.Count() );
AllocateShadows( frameId, lights, totalGranted, ref m_TmpRequests, ref m_ShadowIndices, ref shadowVector, ref payloadVector );
AllocateShadows( frameId, camera, cameraRelativeRendering, lights, totalGranted, ref m_TmpRequests, ref m_ShadowIndices, ref shadowVector, ref payloadVector );
Debug.Assert( m_TmpRequests.Count() == m_ShadowIndices.Count() );
m_ShadowCtxt.shadowDatas = shadowVector;
m_ShadowCtxt.payloads = payloadVector;

m_TmpSortKeys.ExtractTo( ref shadowRequests, (long idx) => { return (int) idx; } );
}
protected override void AllocateShadows( FrameId frameId, List<VisibleLight> lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
protected override void AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref ShadowRequestVector grantedRequests, ref ShadowIndicesVector shadowIndices, ref ShadowDataVector shadowDatas, ref ShadowPayloadVector shadowmapPayload )
{
ShadowData sd = new ShadowData();
shadowDatas.Reserve( totalGranted );

int smidx = 0;
while( smidx < k_MaxShadowmapPerType )
{
if( m_ShadowmapsPerType[(int)shadowtype,smidx] != null && m_ShadowmapsPerType[(int)shadowtype,smidx].Reserve( frameId, ref sd, grantedRequests[i], (uint) asd.shadowResolution, (uint) asd.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights ) )
if( m_ShadowmapsPerType[(int)shadowtype,smidx] != null && m_ShadowmapsPerType[(int)shadowtype,smidx].Reserve( frameId, camera, cameraRelativeRendering, ref sd, grantedRequests[i], (uint) asd.shadowResolution, (uint) asd.shadowResolution, ref shadowDatas, ref shadowmapPayload, lights ) )
break;
smidx++;
}

10
Assets/ScriptableRenderPipeline/Core/Shadow/ShadowBase.cs


public ShadowSupport QueryShadowSupport() { return m_ShadowSupport; }
public uint GetMaxPayload() { return m_MaxPayloadCount; }
public void Assign( CullResults cullResults ) { m_CullResults = cullResults; } // TODO: Remove when m_CullResults is removed again
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public bool Reserve( FrameId frameId, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public bool Reserve( FrameId frameId, Camera camera, bool cameraRelativeRendering, ref ShadowData shadowData, ShadowRequest sr, uint width, uint height, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public bool Reserve( FrameId frameId, Camera camera, bool cameraRelativeRendering, ref ShadowData shadowData, ShadowRequest sr, uint[] widths, uint[] heights, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads, List<VisibleLight> lights);
abstract public bool ReserveFinalize( FrameId frameId, ref VectorArray<ShadowData> entries, ref VectorArray<ShadowPayload> payloads );
abstract public void Update( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights);
abstract public void ReserveSlots( ShadowContextStorage sc );

// shadowPayloads contains implementation specific data that is accessed from the shader by indexing into an Buffer<int> using ShadowData.ShadowmapData.payloadOffset.
// This is the equivalent of a void pointer in the shader and there needs to be loader code that knows how to interpret the data.
// If there are no valid shadow casters all output arrays will be null, otherwise they will contain valid data that can be passed to shaders.
void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
// Renders all shadows for lights the were deemed shadow casters after the last call to ProcessShadowRequests
void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights);
// Debug function to display a shadow at the screen coordinate

abstract public class ShadowManagerBase : ShadowRegistry, IShadowManager
{
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void ProcessShadowRequests( FrameId frameId, CullResults cullResults, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, ref uint shadowRequestsCount, int[] shadowRequests, out int[] shadowDataIndices );
public abstract void RenderShadows( FrameId frameId, ScriptableRenderContext renderContext, CommandBuffer cmd, CullResults cullResults, List<VisibleLight> lights);
public abstract void DisplayShadow(CommandBuffer cmd, int shadowIndex, uint faceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);
public abstract void DisplayShadowMap(CommandBuffer cmd, uint shadowMapIndex, uint sliceIndex, float screenX, float screenY, float screenSizeX, float screenSizeY, float minValue, float maxValue);

// prune the shadow requests - may modify shadowRequests and shadowsCountshadowRequestsCount
protected abstract void PruneShadowCasters( Camera camera, List<VisibleLight> lights, ref VectorArray<int> shadowRequests, ref VectorArray<ShadowmapBase.ShadowRequest> requestsGranted, out uint totalRequestCount );
// allocate the shadow requests in the shadow map, only is called if shadowsCount > 0 - may modify shadowRequests and shadowsCount
protected abstract void AllocateShadows( FrameId frameId, List<VisibleLight> lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
protected abstract void AllocateShadows( FrameId frameId, Camera camera, bool cameraRelativeRendering, List<VisibleLight> lights, uint totalGranted, ref VectorArray<ShadowmapBase.ShadowRequest> grantedRequests, ref VectorArray<int> shadowIndices, ref VectorArray<ShadowData> shadowmapDatas, ref VectorArray<ShadowPayload> shadowmapPayload );
public abstract uint GetShadowMapCount();
public abstract uint GetShadowMapSliceCount(uint shadowMapIndex);

2
Assets/ScriptableRenderPipeline/Fptl/FptlLighting.cs


uint shadowRequestCount = (uint)m_ShadowRequests.Count;
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, inputs.visibleLights,
m_ShadowMgr.ProcessShadowRequests(m_FrameId, inputs, camera, false, inputs.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information

35
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDRenderPipeline.cs


public Matrix4x4 viewMatrix;
public Matrix4x4 projMatrix;
public Vector4 screenSize;
public Vector4[] frustumPlaneEquations;
public Camera camera;
public Matrix4x4 viewProjMatrix

// avoid one-frame jumps/hiccups with temporal effects (motion blur, TAA...)
bool m_FirstFrame;
public HDCamera(Camera camera)
public HDCamera(Camera cam)
this.camera = camera;
camera = cam;
frustumPlaneEquations = new Vector4[6];
Reset();
}

// (different Z value ranges etc.)
var gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); // Had to change this from 'false'
var gpuVP = gpuProj * camera.worldToCameraMatrix;
Matrix4x4 gpuProj = GL.GetGPUProjectionMatrix(camera.projectionMatrix, true); // Had to change this from 'false'
Matrix4x4 gpuView = camera.worldToCameraMatrix;
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Zero out the translation component.
gpuView.SetColumn(3, new Vector4(0, 0, 0, 1));
}
Matrix4x4 gpuVP = gpuProj * gpuView;
// A camera could be rendered multiple time per frame, only updates the previous viewproj if needed
if (m_LastFrameActive != Time.frameCount)

m_FirstFrame = false;
}
viewMatrix = camera.worldToCameraMatrix;
viewMatrix = gpuView;
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(viewProjMatrix);
for (int i = 0; i < 6; i++)
{
frustumPlaneEquations[i] = new Vector4(planes[i].normal.x, planes[i].normal.y, planes[i].normal.z, -planes[i].distance);
}
m_LastFrameActive = Time.frameCount;
}

cmd.SetGlobalVector("_InvProjParam", invProjParam);
cmd.SetGlobalVector("_ScreenSize", screenSize);
cmd.SetGlobalMatrix("_PrevViewProjMatrix", prevViewProjMatrix);
cmd.SetGlobalVectorArray("_FrustumPlanes", frustumPlaneEquations);
}
// Does not modify global settings. Used for shadows, low res. rendering, etc.

material.SetVector("_InvProjParam", invProjParam);
material.SetVector("_ScreenSize", screenSize);
material.SetMatrix("_PrevViewProjMatrix", prevViewProjMatrix);
material.SetVectorArray("_FrustumPlanes", frustumPlaneEquations);
}
public void SetupComputeShader(ComputeShader cs, CommandBuffer cmd)

cmd.SetComputeVectorParam(cs, "_InvProjParam", invProjParam);
cmd.SetComputeVectorParam(cs, "_ScreenSize", screenSize);
cmd.SetComputeMatrixParam(cs, "_PrevViewProjMatrix", prevViewProjMatrix);
cmd.SetComputeVectorArrayParam(cs, "_FrustumPlanes", frustumPlaneEquations);
}
}

renderContext.SetupCameraProperties(camera);
var hdCamera = HDCamera.Get(camera);
HDCamera hdCamera = HDCamera.Get(camera);
PushGlobalParams(hdCamera, cmd, m_Asset.sssSettings);
// TODO: Find a correct place to bind these material textures
// We have to bind the material specific global parameters in this mode

}
InitAndClearBuffer(camera, cmd);
PushGlobalParams(hdCamera, cmd, m_Asset.sssSettings);
RenderDepthPrepass(m_CullResults, camera, renderContext, cmd);

41
Assets/ScriptableRenderPipeline/HDRenderPipeline/Lighting/TilePass/TilePass.cs


// Then Culling side
var range = light.range;
var lightToWorld = light.localToWorld;
Vector3 lightPos = lightToWorld.GetColumn(3);
Vector3 lightPos = lightData.positionWS;
// Fill bounds
var bound = new SFiniteLightBound();

{
m_lightList.Clear();
Vector3 camPosWS = camera.transform.position;
if (cullResults.visibleLights.Count != 0 || cullResults.visibleReflectionProbes.Count != 0)
{
// 0. deal with shadows

//TODO: Do not call ToArray here to avoid GC, refactor API
int[] shadowRequests = m_ShadowRequests.ToArray();
int[] shadowDataIndices;
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, cullResults.visibleLights,
m_ShadowMgr.ProcessShadowRequests(m_FrameId, cullResults, camera, ShaderConfig.s_CameraRelativeRendering != 0, cullResults.visibleLights,
ref shadowRequestCount, shadowRequests, out shadowDataIndices);
// update the visibleLights with the shadow information

if (gpuLightType == GPULightType.Directional)
{
if (GetDirectionalLightData(shadowSettings, gpuLightType, light, additionalLightData, additionalShadowData, lightIndex))
{
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'DirectionalLightData.positionWS' is camera-relative after this point.
int n = m_lightList.directionalLights.Count;
DirectionalLightData lightData = m_lightList.directionalLights[n - 1];
lightData.positionWS -= camPosWS;
m_lightList.directionalLights[n - 1] = lightData;
}
}
continue;
}
// Punctual, area, projector lights - the rendering side.

// Then culling side. Must be call in this order as we pass the created Light data to the function
GetLightVolumeDataAndBound(lightCategory, gpuLightType, lightVolumeType, light, m_lightList.lights[m_lightList.lights.Count - 1], worldToView);
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'LightData.positionWS' is camera-relative after this point.
int n = m_lightList.lights.Count;
LightData lightData = m_lightList.lights[n - 1];
lightData.positionWS -= camPosWS;
m_lightList.lights[n - 1] = lightData;
}
}
}

GetEnvLightData(probe);
GetEnvLightVolumeDataAndBound(probe, lightVolumeType, worldToView);
// We make the light position camera-relative as late as possible in order
// to allow the preceding code to work with the absolute world space coordinates.
if (ShaderConfig.s_CameraRelativeRendering != 0)
{
// Caution: 'EnvLightData.positionWS' is camera-relative after this point.
int n = m_lightList.envLights.Count;
EnvLightData envLightData = m_lightList.envLights[n - 1];
envLightData.positionWS -= camPosWS;
m_lightList.envLights[n - 1] = envLightData;
}
}
// Sanity check

3
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


float2 uvXZ;
float2 uvXY;
float2 uvZY;
GetTriplanarCoordinate(positionWS * worldScale, uvXZ, uvXY, uvZY);
GetTriplanarCoordinate(GetAbsolutePositionWS(positionWS) * worldScale, uvXZ, uvXY, uvZY);
// Planar is just XZ of triplanar
if (mappingType == UV_MAPPING_PLANAR)

4
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitTessellation.hlsl


{
float maxDisplacement = GetMaxDisplacement();
bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])unity_CameraWorldClipPlanes);
bool frustumCulled = WorldViewFrustumCull(p0, p1, p2, maxDisplacement, (float4[4])_FrustumPlanes);
bool faceCull = false;

float3 camPosWS = _WorldSpaceCameraPos;
float3 camPosWS = GetPrimaryCameraPosition();
#ifndef _DOUBLESIDED_ON
// TODO: Handle inverse culling (for mirror)!

6
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderConfig.cs


// All this could be fix we a new Mesh API not ready yet. Note that this feature only affect animated mesh (vertex or skin) as others use depth reprojection.
VelocityInGBuffer = 0, // Change to 1 to enable the feature, then regenerate hlsl headers.
// TODO: not working yet, waiting for UINT16 RT format support
PackGBufferInU16 = 0
PackGBufferInU16 = 0,
CameraRelativeRendering = 0 // Rendering sets the origin of the world to the position of the primary (scene view) camera
};
// Note: #define can't be use in include file in C# so we chose this way to configure both C# and hlsl

public const int k_PackgbufferInU16 = (int)ShaderOptions.PackGBufferInU16;
public static int s_PackgbufferInU16 = (int)ShaderOptions.PackGBufferInU16;
public const int k_CameraRelativeRendering = (int)ShaderOptions.CameraRelativeRendering;
public static int s_CameraRelativeRendering = (int)ShaderOptions.CameraRelativeRendering;
}
}

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderConfig.cs.hlsl


//
#define SHADEROPTIONS_VELOCITY_IN_GBUFFER (0)
#define SHADEROPTIONS_PACK_GBUFFER_IN_U16 (0)
#define SHADEROPTIONS_CAMERA_RELATIVE_RENDERING (0)
#endif

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/ShaderPassLightTransport.hlsl


// position, so also take this opportunity to create a dependence on it.
inputMesh.positionOS.z = inputMesh.positionOS.z > 0 ? 1.0e-4 : 0.0;
float3 positionWS = TransformObjectToWorld(inputMesh.positionOS);
float3 positionWS = GetCameraRelativePositionWS(TransformObjectToWorld(inputMesh.positionOS));
output.vmesh.positionCS = TransformWorldToHClip(positionWS);
output.vmesh.texCoord0 = inputMesh.uv0;
output.vmesh.texCoord1 = inputMesh.uv1;

2
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VertMesh.hlsl


ApplyWind(positionWS, normalWS, rootWP, _Stiffness, _Drag, _ShiverDrag, _ShiverDirectionality, _InitialBend, vertexColor.a, _Time);
#endif
positionWS = GetCameraRelativePositionWS(positionWS);
#ifdef TESSELLATION_ON
output.positionWS = positionWS;
#ifdef _TESSELLATION_OBJECT_SCALE

3
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariables.hlsl


float4x4 _InvViewMatrix;
float4x4 _InvProjMatrix;
float4 _InvProjParam;
float4 _ScreenSize;
float4 _ScreenSize; // (w, h, 1/w, 1/h)
float4 _FrustumPlanes[6]; // (N, -dot(N, P))
CBUFFER_END
#ifdef USE_LEGACY_UNITY_MATRIX_VARIABLES

47
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderVariablesFunctions.hlsl


return mul(GetWorldToHClipMatrix(), float4(positionWS, 1.0));
}
float3 GetCurrentCameraPosition()
float3 GetAbsolutePositionWS(float3 cameraRelativePositionWS)
{
float3 pos = cameraRelativePositionWS;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
pos += _WorldSpaceCameraPos;
#endif
return pos;
}
float3 GetCameraRelativePositionWS(float3 absolutePositionWS)
{
float3 pos = absolutePositionWS;
#if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0)
pos -= _WorldSpaceCameraPos;
#endif
return pos;
}
// Note: '_WorldSpaceCameraPos' is set by the legacy Unity code.
float3 GetPrimaryCameraPosition()
{
return GetCameraRelativePositionWS(_WorldSpaceCameraPos);
}
// Could be e.g. the position of a primary camera or a shadow-casting light.
float3 GetCurrentViewPosition()
return _WorldSpaceCameraPos;
return GetPrimaryCameraPosition();
#else
// TEMP: this is rather expensive. Then again, we need '_WorldSpaceCameraPos'
// to represent the position of the primary (scene view) camera in order to

float3 rotCamPos = trViewMat[3].xyz;
return mul((float3x3)trViewMat, -rotCamPos);
return mul((float3x3)trViewMat, -rotCamPos);
// Returns the forward direction of the current camera in the world space.
float3 GetCameraForwardDir()
// Returns the forward (central) direction of the current view in the world space.
float3 GetViewForwardDir()
// Returns 'true' if the current camera performs a perspective projection.
bool IsPerspectiveCamera()
// Returns 'true' if the current view performs a perspective projection.
bool IsPerspectiveProjection()
{
#if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS)
return (unity_OrthoParams.w == 0);

#endif
}
// Computes the world space view direction (pointing towards the camera).
// Computes the world space view direction (pointing towards the viewer).
if (IsPerspectiveCamera())
if (IsPerspectiveProjection())
float3 V = GetCurrentCameraPosition() - positionWS;
float3 V = GetCurrentViewPosition() - positionWS;
return -GetCameraForwardDir();
return -GetViewForwardDir();
}
}

22
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


return positionSS;
}
float3 ComputeViewSpacePosition(float2 positionSS, float depthRaw, float4x4 invProjMatrix)
{
float4 positionCS = ComputeClipSpacePosition(positionSS, depthRaw);
float4 positionVS = mul(invProjMatrix, positionCS);
// The view space uses a right-handed coordinate system.
positionVS.z = -positionVS.z;
return positionVS.xyz / positionVS.w;
}
// It may be necessary to flip the Y axis as the origin of the screen-space coordinate system
// of Direct3D is at the top left corner of the screen, with the Y axis pointing downwards.
void UpdatePositionInput(float depthRaw, float4x4 invViewProjMatrix, float4x4 viewProjMatrix, inout PositionInputs posInput)
{
posInput.depthRaw = depthRaw;

// The compiler should optimize this (less expensive than reconstruct depth VS from depth buffer)
posInput.depthVS = mul(viewProjMatrix, float4(posInput.positionWS, 1.0)).w;
}
// It may be necessary to flip the Y axis as the origin of the screen-space coordinate system
// of Direct3D is at the top left corner of the screen, with the Y axis pointing downwards.
float3 ComputeViewSpacePosition(float2 positionSS, float depthRaw, float4x4 invProjMatrix)
{
float4 positionCS = ComputeClipSpacePosition(positionSS, depthRaw);
float4 positionVS = mul(invProjMatrix, positionCS);
// The view space uses a right-handed coordinate system.
positionVS.z = -positionVS.z;
return positionVS.xyz / positionVS.w;
}
// The view direction 'V' points towards the camera.

正在加载...
取消
保存