protected override void OnLoad(EventArgs e) { base.OnLoad(e); try { m_Device.Init(viewportPanelResult.Handle, false, true); // Create our compute shaders #if DEBUG m_CS_BilateralFilter = new RendererManaged.ComputeShader(m_Device, new RendererManaged.ShaderFile(new System.IO.FileInfo("./Shaders/BilateralFiltering.hlsl")), "CS", null); m_CS_GenerateSSBumpMap = new RendererManaged.ComputeShader(m_Device, new RendererManaged.ShaderFile(new System.IO.FileInfo("./Shaders/GenerateAOMap.hlsl")), "CS", null); #else m_CS_BilateralFilter = RendererManaged.ComputeShader.CreateFromBinaryBlob(m_Device, new System.IO.FileInfo("./Shaders/Binary/BilateralFiltering.fxbin"), "CS"); m_CS_GenerateSSBumpMap = RendererManaged.ComputeShader.CreateFromBinaryBlob(m_Device, new System.IO.FileInfo("./Shaders/Binary/GenerateAOMap.fxbin"), "CS"); #endif // Create our constant buffers m_CB_Input = new RendererManaged.ConstantBuffer <CBInput>(m_Device, 0); m_CB_Filter = new RendererManaged.ConstantBuffer <CBFilter>(m_Device, 0); // Create our structured buffer containing the rays m_SB_Rays = new RendererManaged.StructuredBuffer <RendererManaged.float3>(m_Device, MAX_THREADS, true); integerTrackbarControlRaysCount_SliderDragStop(integerTrackbarControlRaysCount, 0); // Create the default, planar normal map buttonClearNormalMap_Click(null, EventArgs.Empty); } catch (Exception _e) { MessageBox("Failed to create DX11 device and default shaders:\r\n", _e); Close(); } }
private void GenerateRays(int _RaysCount, RendererManaged.StructuredBuffer <RendererManaged.float3> _Target) { _RaysCount = Math.Min(MAX_THREADS, _RaysCount); // Half-Life 2 basis RendererManaged.float3[] HL2Basis = new RendererManaged.float3[] { new RendererManaged.float3((float)Math.Sqrt(2.0 / 3.0), 0.0f, (float)Math.Sqrt(1.0 / 3.0)), new RendererManaged.float3(-(float)Math.Sqrt(1.0 / 6.0), (float)Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0)), new RendererManaged.float3(-(float)Math.Sqrt(1.0 / 6.0), -(float)Math.Sqrt(1.0 / 2.0), (float)Math.Sqrt(1.0 / 3.0)) }; float CenterTheta = (float)Math.Acos(HL2Basis[0].z); float[] CenterPhi = new float[] { (float)Math.Atan2(HL2Basis[0].y, HL2Basis[0].x), (float)Math.Atan2(HL2Basis[1].y, HL2Basis[1].x), (float)Math.Atan2(HL2Basis[2].y, HL2Basis[2].x), }; for (int RayIndex = 0; RayIndex < _RaysCount; RayIndex++) { double Phi = (Math.PI / 3.0) * (2.0 * WMath.SimpleRNG.GetUniform() - 1.0); // Stratified version double Theta = (Math.Acos(Math.Sqrt((RayIndex + WMath.SimpleRNG.GetUniform()) / _RaysCount))); // // Don't give a shit version (a.k.a. melonhead version) // // double Theta = Math.Acos( Math.Sqrt(WMath.SimpleRNG.GetUniform() ) ); // double Theta = 0.5 * Math.PI * WMath.SimpleRNG.GetUniform(); Theta = Math.Min(0.499f * Math.PI, Theta); double CosTheta = Math.Cos(Theta); double SinTheta = Math.Sin(Theta); double LengthFactor = 1.0 / SinTheta; // The ray is scaled so we ensure we always walk at least a texel in the texture CosTheta *= LengthFactor; SinTheta *= LengthFactor; // Yeah, yields 1... :) _Target.m[0 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[0] + Phi) * SinTheta), (float)(Math.Sin(CenterPhi[0] + Phi) * SinTheta), (float)CosTheta); _Target.m[1 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[1] + Phi) * SinTheta), (float)(Math.Sin(CenterPhi[1] + Phi) * SinTheta), (float)CosTheta); _Target.m[2 * MAX_THREADS + RayIndex].Set((float)(Math.Cos(CenterPhi[2] + Phi) * SinTheta), (float)(Math.Sin(CenterPhi[2] + Phi) * SinTheta), (float)CosTheta); } _Target.Write(); }
private void GenerateRays(int _RaysCount, float _MaxConeAngle, RendererManaged.StructuredBuffer <RendererManaged.float3> _Target) { _RaysCount = Math.Min(MAX_THREADS, _RaysCount); WMath.Hammersley hammersley = new WMath.Hammersley(); double[,] sequence = hammersley.BuildSequence(_RaysCount, 2); WMath.Vector[] rays = hammersley.MapSequenceToSphere(sequence, 0.5f * _MaxConeAngle); for (int RayIndex = 0; RayIndex < _RaysCount; RayIndex++) { WMath.Vector ray = rays[RayIndex]; // // Scale the ray so we ensure to always walk at least a texel in the texture // float SinTheta = (float) Math.Sqrt( 1.0 - ray.y * ray.y ); // float LengthFactor = 1.0f / SinTheta; // ray *= LengthFactor; _Target.m[RayIndex].Set(ray.x, -ray.z, ray.y); } _Target.Write(); }