float SampleEo(float _cosTheta, float _alpha) { return(Mathf.BiLerp(m_Eo, _cosTheta, _alpha)); // float X = Mathf.Saturate( _cosTheta ) * W; // int X0 = (int) Mathf.Floor( X ); // float x = X - X0; // X0 = Math.Min( W-1, X0 ); // int X1 = Math.Min( W-1, X0 + 1 ); // // float Y = Mathf.Saturate( _alpha ) * H; // int Y0 = (int) Mathf.Floor( Y ); // float y = Y - Y0; // Y0 = Math.Min( H-1, Y0 ); // int Y1 = Math.Min( H-1, Y0 + 1 ); // // float V00 = m_Eo[X0,Y0]; // float V10 = m_Eo[X1,Y0]; // float V01 = m_Eo[X0,Y1]; // float V11 = m_Eo[X1,Y1]; // float V0 = (1-x) * V00 + x * V10; // float V1 = (1-x) * V01 + x * V11; // float V = (1-y) * V0 + y * V1; // return V; }
void LoadMSBRDF(uint[] _sizes, FileInfo[] _irradianceTablesNames, FileInfo[] _albedoTablesNames, out Texture2D _irradianceTexture, out Texture2D _albedoTexture) { uint BRDFSCount = (uint)_sizes.Length; if (_irradianceTablesNames.Length != BRDFSCount || _albedoTablesNames.Length != BRDFSCount) { throw new Exception("Irradiance and albedo textures count must match the amount of BRDFs computed from the size of the _sizes array!"); } // Determine max texture size uint textureSize = 0; foreach (uint size in _sizes) { textureSize = Math.Max(textureSize, size); } // Create placeholders ImageUtility.ImagesMatrix texE = new ImageUtility.ImagesMatrix(); texE.InitTexture2DArray(textureSize, textureSize, BRDFSCount, 1); texE.AllocateImageFiles(ImageUtility.PIXEL_FORMAT.R32F, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.LINEAR)); ImageUtility.ImagesMatrix texEavg = new ImageUtility.ImagesMatrix(); texEavg.InitTexture2DArray(textureSize, BRDFSCount, 1, 1); texEavg.AllocateImageFiles(ImageUtility.PIXEL_FORMAT.R32F, new ImageUtility.ColorProfile(ImageUtility.ColorProfile.STANDARD_PROFILE.LINEAR)); float[][] albedoTables = new float[BRDFSCount][]; for (uint BRDFIndex = 0; BRDFIndex < BRDFSCount; BRDFIndex++) { uint size = _sizes[BRDFIndex]; // Read irradiance table float[,] irradianceTable = new float[size, size]; using (FileStream S = _irradianceTablesNames[BRDFIndex].OpenRead()) using (BinaryReader R = new BinaryReader(S)) { for (int Y = 0; Y < size; Y++) { for (int X = 0; X < size; X++) { irradianceTable[X, Y] = R.ReadSingle(); } } } // Write content if (size == textureSize) { // One-one correspondance texE[BRDFIndex][0][0].WritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = irradianceTable[_X, _Y]; }); } else { // Needs scaling texE[BRDFIndex][0][0].WritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = Mathf.BiLerp(irradianceTable, (float)_X / textureSize, (float)_Y / textureSize); }); } // Read albedo table float[] albedoTable = new float[size]; albedoTables[BRDFIndex] = albedoTable; using (FileStream S = _albedoTablesNames[BRDFIndex].OpenRead()) using (BinaryReader R = new BinaryReader(S)) { for (int Y = 0; Y < size; Y++) { albedoTable[Y] = R.ReadSingle(); } } } // Build the entire albedo tables texEavg[0][0][0].WritePixels((uint _X, uint _Y, ref float4 _color) => { _color.x = Mathf.Lerp(albedoTables[_Y], (float)_X / textureSize); }); // Create textures _irradianceTexture = new Texture2D(m_device, texE, ImageUtility.COMPONENT_FORMAT.AUTO); _albedoTexture = new Texture2D(m_device, texEavg, ImageUtility.COMPONENT_FORMAT.AUTO); }