浏览代码

Implement computation of the view vector from the screen space coordinate

/main
Evgenii Golubev 7 年前
当前提交
69b2a277
共有 8 个文件被更改,包括 87 次插入26 次删除
  1. 1
      Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs
  2. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs
  3. 16
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader
  4. 5
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs
  5. 17
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader
  6. 56
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs
  7. 7
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs
  8. 4
      Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl

1
Assets/ScriptableRenderPipeline/HDRenderPipeline/HDShaderIDs.cs


internal static readonly int _Cubemap = Shader.PropertyToID("_Cubemap");
internal static readonly int _SkyParam = Shader.PropertyToID("_SkyParam");
internal static readonly int _PixelCoordToViewDirWS = Shader.PropertyToID("_PixelCoordToViewDirWS");
}
}

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/HDRISkyRenderer.cs


m_SkyHDRIMaterial.SetTexture(HDShaderIDs._Cubemap, m_HdriSkyParams.skyHDRI);
m_SkyHDRIMaterial.SetVector(HDShaderIDs._SkyParam, new Vector4(m_HdriSkyParams.exposure, m_HdriSkyParams.multiplier, m_HdriSkyParams.rotation, 0.0f));
builtinParams.commandBuffer.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_SkyHDRIMaterial, 0, renderForCubemap ? 0 : 1);
// This matrix needs to be updated at the draw call frequency.
MaterialPropertyBlock properties = new MaterialPropertyBlock();
Matrix4x4 transform = SkyManager.ComputePixelCoordToWorldSpaceViewDirectionMatrix(builtinParams.verticalFoV, builtinParams.screenSize, builtinParams.worldToViewMatrix, renderForCubemap);
properties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
Utilities.DrawFullScreen(builtinParams.commandBuffer, m_SkyHDRIMaterial, properties, renderForCubemap ? 0 : 1);
}
public override bool IsSkyValid()

16
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/HDRISky/Resources/SkyHDRI.shader


SAMPLERCUBE(sampler_Cubemap);
float4 _SkyParam; // x exposure, y multiplier, z rotation
float4x4 _PixelCoordToViewDirWS; // Actually just 3x3, but Unity can only set 4x4
float3 positionCS : POSITION;
float3 eyeVector : NORMAL;
uint vertexID : SV_VertexID;
float3 eyeVector : TEXCOORD0;
// TODO: implement SV_vertexID full screen quad
// Unity renders upside down, so the clip space coordinates have to be flipped.
output.positionCS = float4(input.positionCS.x, -input.positionCS.y, UNITY_RAW_FAR_CLIP_VALUE, 1.0);
output.eyeVector = input.eyeVector;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID, UNITY_RAW_FAR_CLIP_VALUE);
float3 dir = normalize(input.eyeVector);
// Points towards the camera
float3 viewDirWS = normalize(mul(float3(input.positionCS.xy, 1.0), (float3x3)_PixelCoordToViewDirWS));
// Reverse it to point into the scene
float3 dir = -viewDirWS;
// Rotate direction
float phi = DegToRad(_SkyParam.z);

5
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/ProceduralSkyRenderer.cs


// We do not render the height fog into the sky IBL cubemap.
properties.SetFloat("_HeightRayleighDensity", renderForCubemap ? -0.0f : -param.heightRayleighDensity / 100000f);
properties.SetFloat("_HeightMieDensity", renderForCubemap ? -0.0f : -param.heightMieDensity / 100000f);
Matrix4x4 transform = SkyManager.ComputePixelCoordToWorldSpaceViewDirectionMatrix(builtinParams.verticalFoV, builtinParams.screenSize, builtinParams.worldToViewMatrix, renderForCubemap);
properties.SetMatrix(HDShaderIDs._PixelCoordToViewDirWS, transform);
}
override public void RenderSky(BuiltinSkyParameters builtinParams, SkySettings skyParameters, bool renderForCubemap)

// Set shader constants.
SetUniforms(builtinParams, m_ProceduralSkySettings, renderForCubemap, ref properties);
builtinParams.commandBuffer.DrawMesh(builtinParams.skyMesh, Matrix4x4.identity, m_ProceduralSkyMaterial, 0, 0, properties);
Utilities.DrawFullScreen(builtinParams.commandBuffer, m_ProceduralSkyMaterial, properties);
}
}
}

17
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/ProceduralSky/Resources/SkyProcedural.shader


// x exposure, y multiplier, z rotation
float4 _SkyParam;
float4x4 _PixelCoordToViewDirWS; // Actually just 3x3, but Unity can only set 4x4
// x = width, y = height, z = 1.0/width, w = 1.0/height
float4 _ScreenSize;

#define IS_RENDERING_SKY
#include "AtmosphericScattering.hlsl"
float3 positionCS : POSITION;
float3 eyeVector : NORMAL;
uint vertexID : SV_VertexID;
float3 eyeVector : TEXCOORD0;
// TODO: implement SV_vertexID full screen quad
// Unity renders upside down, so the clip space coordinates have to be flipped.
output.positionCS = float4(input.positionCS.x, -input.positionCS.y, UNITY_RAW_FAR_CLIP_VALUE, 1.0);
output.eyeVector = input.eyeVector;
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID, UNITY_RAW_FAR_CLIP_VALUE);
float3 dir = normalize(input.eyeVector);
// Points towards the camera
float3 viewDirWS = normalize(mul(float3(input.positionCS.xy, 1.0), (float3x3)_PixelCoordToViewDirWS));
// Reverse it to point into the scene
float3 dir = -viewDirWS;
// Rotate direction
float phi = DegToRad(_SkyParam.z);

56
Assets/ScriptableRenderPipeline/HDRenderPipeline/Sky/SkyManager.cs


public class BuiltinSkyParameters
{
public Matrix4x4 invViewProjMatrix;
public Matrix4x4 worldToViewMatrix;
public float verticalFoV;
public Mesh skyMesh;
public CommandBuffer commandBuffer;
public Light sunLight;

IBLFilterGGX m_iblFilterGgx = null;
Vector4 m_CubemapScreenSize;
Matrix4x4[] m_faceWorldToViewMatrices = new Matrix4x4[6];
Matrix4x4[] m_faceCameraViewProjectionMatrix = new Matrix4x4[6];
Matrix4x4[] m_faceCameraInvViewProjectionMatrix = new Matrix4x4[6];
Mesh[] m_CubemapFaceMesh = new Mesh[6];

{
Matrix4x4 cubeProj = Matrix4x4.Perspective(90.0f, 1.0f, nearPlane, farPlane);
// Ref: https://msdn.microsoft.com/en-us/library/windows/desktop/bb204881(v=vs.85).aspx
Vector3[] lookAtList =
{
new Vector3(1.0f, 0.0f, 0.0f),

new Vector3(0.0f, 0.0f, -1.0f),
};
Vector3[] UpVectorList =
Vector3[] upVectorList =
{
new Vector3(0.0f, 1.0f, 0.0f),
new Vector3(0.0f, 1.0f, 0.0f),

for (int i = 0; i < 6; ++i)
{
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], UpVectorList[i]);
Matrix4x4 lookAt = Matrix4x4.LookAt(Vector3.zero, lookAtList[i], upVectorList[i]);
m_faceWorldToViewMatrices[i] = lookAt * Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); // Need to scale -1.0 on Z to match what is being done in the camera.wolrdToCameraMatrix API. ...
m_faceCameraViewProjectionMatrix[i] = Utilities.GetViewProjectionMatrix(lookAt, cubeProj);
m_faceCameraInvViewProjectionMatrix[i] = m_faceCameraViewProjectionMatrix[i].inverse;

}
public static Matrix4x4 ComputePixelCoordToWorldSpaceViewDirectionMatrix(float verticalFoV, Vector4 screenSize, Matrix4x4 worldToViewMatrix, bool renderToCubemap)
{
// Compose the view space version first.
// V = -(X, Y, Z), s.t. Z = 1,
// X = (2x / resX - 1) * tan(vFoV / 2) * ar = x * [(2 / resX) * tan(vFoV / 2) * ar] + [-tan(vFoV / 2) * ar] = x * [-m00] + [-m20]
// Y = (2y / resY - 1) * tan(vFoV / 2) = y * [(2 / resY) * tan(vFoV / 2)] + [-tan(vFoV / 2)] = y * [-m11] + [-m21]
float tanHalfVertFoV = Mathf.Tan(0.5f * verticalFoV);
float aspectRatio = screenSize.x * screenSize.w;
// Compose the matrix.
float m21 = tanHalfVertFoV;
float m20 = tanHalfVertFoV * aspectRatio;
float m00 = -2.0f * screenSize.z * m20;
float m11 = -2.0f * screenSize.w * m21;
float m33 = -1.0f;
if (renderToCubemap)
{
// Flip Y.
m11 = -m11;
m21 = -m21;
}
Matrix4x4 viewSpaceRasterTransform = new Matrix4x4(new Vector4( m00, 0.0f, 0.0f, 0.0f),
new Vector4(0.0f, m11, 0.0f, 0.0f),
new Vector4( m20, m21, m33, 0.0f),
new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
// Remove the translation component.
Vector4 homogeniousZero = new Vector4(0, 0, 0, 1);
worldToViewMatrix.SetColumn(3, homogeniousZero);
// Flip the Z to make the coordinate system left-handed.
worldToViewMatrix.SetRow(2, -worldToViewMatrix.GetRow(2));
// Transpose for HLSL.
return Matrix4x4.Transpose(worldToViewMatrix.transpose * viewSpaceRasterTransform);
}
// Sets the global MIP-mapped cubemap '_SkyTexture' in the shader.
// The texture being set is the sky (environment) map pre-convolved with GGX.
public void SetGlobalSkyTexture()

{
for (int i = 0; i < 6; ++i)
{
builtinParams.worldToViewMatrix = m_faceWorldToViewMatrices[i];
builtinParams.screenSize = m_CubemapScreenSize;
builtinParams.skyMesh = m_CubemapFaceMesh[i];
builtinParams.colorBuffer = target;
builtinParams.depthBuffer = BuiltinSkyParameters.nullRT;

m_BuiltinParameters.commandBuffer = cmd;
m_BuiltinParameters.sunLight = sunLight;
m_BuiltinParameters.screenSize = m_CubemapScreenSize;
m_BuiltinParameters.verticalFoV = 0.5f * Mathf.PI;
m_BuiltinParameters.cameraPosWS = camera.camera.transform.position;
if (
m_UpdatedFramesRequired > 0 ||

{
m_BuiltinParameters.commandBuffer = cmd;
m_BuiltinParameters.sunLight = sunLight;
m_BuiltinParameters.worldToViewMatrix = camera.viewMatrix;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.verticalFoV = camera.camera.fieldOfView * Mathf.Deg2Rad;
m_BuiltinParameters.screenSize = camera.screenSize;
m_BuiltinParameters.skyMesh = BuildSkyMesh(camera.camera.GetComponent<Transform>().position, m_BuiltinParameters.invViewProjMatrix);
m_BuiltinParameters.colorBuffer = colorBuffer;
m_BuiltinParameters.depthBuffer = depthBuffer;

7
Assets/ScriptableRenderPipeline/HDRenderPipeline/Utilities.cs


// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{
commandBuffer.DrawProcedural(Matrix4x4.identity, material, shaderPassID, MeshTopology.Triangles, 3, 1, properties);
}
// Draws a full screen triangle as a faster alternative to drawing a full screen quad.
public static void DrawFullScreen(CommandBuffer commandBuffer, Material material,
RenderTargetIdentifier colorBuffer,
MaterialPropertyBlock properties = null, int shaderPassID = 0)
{

4
Assets/ScriptableRenderPipeline/ShaderLibrary/Common.hlsl


#endif
}
float4 GetFullScreenTriangleVertexPosition(uint vertexID)
float4 GetFullScreenTriangleVertexPosition(uint vertexID, float z = UNITY_NEAR_CLIP_VALUE)
return float4(uv * 2.0 - 1.0, 1.0, 1.0);
return float4(uv * 2.0 - 1.0, z, 1.0);
}
// LOD dithering transition helper

正在加载...
取消
保存