diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f8360b..026d02a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Improved cone tracing direction selection. - Removed cone tracing bias. +- Removed redundant matrix multiplication in voxelization step. ### Fixed diff --git a/Resources/VXGI/Compute/VoxelShader.compute b/Resources/VXGI/Compute/VoxelShader.compute index 0017273..54faf1d 100644 --- a/Resources/VXGI/Compute/VoxelShader.compute +++ b/Resources/VXGI/Compute/VoxelShader.compute @@ -81,6 +81,8 @@ void CSRender(uint id : SV_DispatchThreadID) uint4 intColor = (uint4)round(color * RADIANCE_PRECISION); + position = min(position, Resolution - 1); + InterlockedAdd(RadianceRG[position], intColor.r | intColor.g << 16); InterlockedAdd(RadianceBA[position], intColor.b | intColor.a << 16); InterlockedAdd(RadianceCount[position], 1); diff --git a/Runtime/Stages/Voxelizer.cs b/Runtime/Stages/Voxelizer.cs index 75dc396..839efc2 100644 --- a/Runtime/Stages/Voxelizer.cs +++ b/Runtime/Stages/Voxelizer.cs @@ -4,12 +4,10 @@ public class Voxelizer : System.IDisposable { int _antiAliasing; int _resolution; - float _bound; Camera _camera; CommandBuffer _command; DrawingSettings _drawingSettings; FilteringSettings _filteringSettings; - Rect _rect; RenderTextureDescriptor _cameraDescriptor; ScriptableCullingParameters _cullingParameters; VXGI _vxgi; @@ -18,7 +16,6 @@ public Voxelizer(VXGI vxgi) { _vxgi = vxgi; _command = new CommandBuffer { name = "VXGI.Voxelizer" }; - _rect = new Rect(0f, 0f, 1f, 1f); CreateCamera(); CreateCameraDescriptor(); @@ -51,17 +48,14 @@ public void Voxelize(ScriptableRenderContext renderContext, VXGIRenderer rendere UpdateCamera(); - _camera.pixelRect = _rect; - _command.BeginSample(_command.name); _command.GetTemporaryRT(ShaderIDs.Dummy, _cameraDescriptor); _command.SetRenderTarget(ShaderIDs.Dummy, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.DontCare); _command.SetGlobalInt(ShaderIDs.Resolution, _resolution); - _command.SetGlobalMatrix(ShaderIDs.WorldToVoxel, _vxgi.worldToVoxel); - _command.SetGlobalMatrix(ShaderIDs.VoxelToProjection, GL.GetGPUProjectionMatrix(_camera.projectionMatrix, true) * _camera.worldToCameraMatrix * _vxgi.voxelToWorld); _command.SetRandomWriteTarget(1, _vxgi.voxelBuffer, false); + _command.SetViewProjectionMatrices(_camera.worldToCameraMatrix, _camera.projectionMatrix); _drawingSettings.perObjectData = renderer.RenderPipeline.PerObjectData; @@ -87,7 +81,7 @@ void CreateCamera() { _camera = gameObject.AddComponent(); _camera.allowMSAA = true; _camera.orthographic = true; - _camera.nearClipPlane = 0f; + _camera.pixelRect = new Rect(0f, 0f, 1f, 1f); } void CreateCameraDescriptor() { @@ -106,28 +100,20 @@ void CreateCameraSettings() { _filteringSettings = new FilteringSettings(RenderQueueRange.all); } - void ResizeCamera() { - _camera.farClipPlane = _bound; - _camera.orthographicSize = .5f * _camera.farClipPlane; - } - void UpdateCamera() { if (_antiAliasing != (int)_vxgi.antiAliasing) { _antiAliasing = (int)_vxgi.antiAliasing; _cameraDescriptor.msaaSamples = _antiAliasing; } - if (_bound != _vxgi.bound) { - _bound = _vxgi.bound; - ResizeCamera(); - } - if (_resolution != (int)_vxgi.resolution) { _resolution = (int)_vxgi.resolution; _cameraDescriptor.height = _cameraDescriptor.width = _resolution; } - _camera.transform.position = _vxgi.voxelSpaceCenter - Vector3.forward * _camera.orthographicSize; - _camera.transform.LookAt(_vxgi.voxelSpaceCenter, Vector3.up); + _camera.farClipPlane = .5f * _vxgi.bound; + _camera.orthographicSize = .5f * _vxgi.bound; + _camera.nearClipPlane = -.5f * _vxgi.bound; + _camera.transform.position = _vxgi.voxelSpaceCenter; } } diff --git a/Runtime/Utilities/ShaderIDs.cs b/Runtime/Utilities/ShaderIDs.cs index aaece8a..22c3e36 100644 --- a/Runtime/Utilities/ShaderIDs.cs +++ b/Runtime/Utilities/ShaderIDs.cs @@ -43,7 +43,6 @@ internal static class ShaderIDs { internal static readonly int Source = Shader.PropertyToID("Source"); internal static readonly int Target = Shader.PropertyToID("Target"); internal static readonly int VoxelBuffer = Shader.PropertyToID("VoxelBuffer"); - internal static readonly int VoxelToProjection = Shader.PropertyToID("VoxelToProjection"); internal static readonly int VoxelToWorld = Shader.PropertyToID("VoxelToWorld"); internal static readonly int WorldToVoxel = Shader.PropertyToID("WorldToVoxel"); } diff --git a/Runtime/VXGI.cs b/Runtime/VXGI.cs index 8cf44b9..28052f1 100644 --- a/Runtime/VXGI.cs +++ b/Runtime/VXGI.cs @@ -188,7 +188,7 @@ void SetupShader(ScriptableRenderContext renderContext) { #region Messages void OnDrawGizmosSelected() { - Gizmos.color = new Color(0, 0, 1, .2f); + Gizmos.color = Color.green; Gizmos.DrawWireCube(voxelSpaceCenter, Vector3.one * bound); } diff --git a/Shaders/Voxelization.shader b/Shaders/Voxelization.shader index 58da0cc..0ba7ae4 100644 --- a/Shaders/Voxelization.shader +++ b/Shaders/Voxelization.shader @@ -8,8 +8,8 @@ Shader "Hidden/VXGI/Voxelization" Tags { "LightMode"="Voxelization" } Cull Off - ZWrite Off ZTest Always + ZWrite Off HLSLPROGRAM #pragma require geometry @@ -18,6 +18,7 @@ Shader "Hidden/VXGI/Voxelization" #pragma geometry geom #pragma fragment frag #pragma shader_feature _EMISSION + #pragma shader_feature_local _METALLICGLOSSMAP #include "UnityCG.cginc" #include "Packages/com.looooong.srp.vxgi/ShaderLibrary/Variables.cginc" @@ -29,18 +30,14 @@ Shader "Hidden/VXGI/Voxelization" CBUFFER_START(UnityPerMaterial) half4 _Color; + half3 _EmissionColor; float4 _MainTex_ST; half _Metallic; - half3 _EmissionColor; CBUFFER_END + sampler2D _EmissionMap; sampler2D _MainTex; sampler2D _MetallicGlossMap; - sampler2D _EmissionMap; - - // Map depth [0, 1] to Z coordinate [0, Resolution) - static float DepthResolution = Resolution * 0.99999999; - float4x4 VoxelToProjection; AppendStructuredBuffer VoxelBuffer; @@ -62,9 +59,14 @@ Shader "Hidden/VXGI/Voxelization" v2g vert(appdata_base v) { v2g o; - o.vertex = mul(WorldToVoxel, mul(unity_ObjectToWorld, v.vertex)); + o.vertex = UnityObjectToClipPos(v.vertex); o.normal = UnityObjectToWorldNormal(v.normal); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); + +#ifdef UNITY_REVERSED_Z + o.vertex.z = mad(o.vertex.z, -2.0, 1.0); +#endif + return o; } @@ -107,11 +109,15 @@ Shader "Hidden/VXGI/Voxelization" for (int j = 0; j < 3; j++) { g2f o; - o.position = mul(VoxelToProjection, float4(SwizzleAxis(i[j].vertex, axis), 1.0)); + o.position = float4(SwizzleAxis(i[j].vertex, axis), 1.0); - #if defined(UNITY_REVERSED_Z) - o.position.z = 1.0 - o.position.z; - #endif +#ifdef UNITY_UV_STARTS_AT_TOP + o.position.y = -o.position.y; +#endif + +#ifdef UNITY_REVERSED_Z + o.position.z = mad(o.position.z, 0.5, 0.5); +#endif o.normal = i[j].normal; o.axis = axis; @@ -145,23 +151,25 @@ Shader "Hidden/VXGI/Voxelization" fixed frag(g2f i) : SV_TARGET { - #ifdef _METALLICGLOSSMAP - float metallic = tex2D(_MetallicGlossMap, i.uv).r; - #else - float metallic = _Metallic; - #endif +#ifdef _METALLICGLOSSMAP + float metallic = tex2D(_MetallicGlossMap, i.uv).r; +#else + float metallic = _Metallic; +#endif i.normal = normalize(i.normal); - #ifdef _EMISSION - float3 emission = _EmissionColor * tex2Dlod(_EmissionMap, float4(i.uv, 0.0, 0.0)); - #else - float3 emission = 0.0; - #endif +#ifdef _EMISSION + float3 emission = _EmissionColor * tex2Dlod(_EmissionMap, float4(i.uv, 0.0, 0.0)); +#else + float3 emission = 0.0; +#endif + + float3 voxelPosition = float3(i.position.xy, i.position.z * Resolution); VoxelData d; d.Initialize(); - d.SetPosition(RestoreAxis(float3(i.position.xy, i.position.z * DepthResolution), i.axis)); + d.SetPosition(RestoreAxis(voxelPosition, i.axis)); d.SetNormal(i.normal); d.SetColor(mad(-0.5, metallic, 1.0) * _Color * tex2Dlod(_MainTex, float4(i.uv, 0.0, 0.0))); d.SetEmission(emission + ShadeSH9(float4(i.normal, 1.0)));