void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. // Used by the BRDF rendering model float theoreticSlopeVariance = 0.0f; float k = 5e-3f; while (k < 1e3f) { float nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4]; float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4]; int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY; Vector2 sample12ZW; Vector2 sample34XY; Vector2 sample34ZW; UnityEngine.Random.seed = 0; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { idx = x + y * m_fourierGridSize; i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float)x; j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float)y; sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x); sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x); sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y); sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z); spectrum01[idx * 4 + 0] = sample12XY.x; spectrum01[idx * 4 + 1] = sample12XY.y; spectrum01[idx * 4 + 2] = sample12ZW.x; spectrum01[idx * 4 + 3] = sample12ZW.y; spectrum23[idx * 4 + 0] = sample34XY.x; spectrum23[idx * 4 + 1] = sample34XY.y; spectrum23[idx * 4 + 2] = sample34ZW.x; spectrum23[idx * 4 + 3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW); } } //Write floating point data into render texture m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01); m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23); if (!SystemInfo.supportsComputeShaders) { // Compute variance for the BRDF // copied from the dx9 project float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance); // m_varianceMax = new Vector2(float.NegativeInfinity, float.NegativeInfinity); Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize]; Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize]; // for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { variance32bit [x, y, z] = ComputeVariance(slopeVarianceDelta, spectrum01, spectrum23, x, y, z); //problematic line if (variance32bit [x, y, z].x > m_varianceMax.x) { m_varianceMax.x = variance32bit [x, y, z].x; } if (variance32bit [x, y, z].y > m_varianceMax.y) { m_varianceMax.y = variance32bit [x, y, z].y; } } } } for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize; variance8bit [idx] = new Color(variance32bit [x, y, z].x / m_varianceMax.x, variance32bit [x, y, z].y / m_varianceMax.y, 0.0f, 1.0f); } } } m_varianceTexture.SetPixels(variance8bit); m_varianceTexture.Apply(); m_maxSlopeVariance = 0.0f; for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit [v].r * m_varianceMax.x); m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit [v].g * m_varianceMax.y); } } else { m_varianceShader = ShaderReplacer.Instance.LoadedComputeShaders["SlopeVariance"]; m_varianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance)); m_varianceShader.SetFloat("_VarianceSize", (float)m_varianceSize); m_varianceShader.SetFloat("_Size", m_fsize); m_varianceShader.SetVector("_GridSizes", m_gridSizes); m_varianceShader.SetTexture(0, "_Spectrum01", m_spectrum01); m_varianceShader.SetTexture(0, "_Spectrum23", m_spectrum23); m_varianceShader.SetTexture(0, "des", m_varianceRenderTexture); m_varianceShader.Dispatch(0, m_varianceSize / 4, m_varianceSize / 4, m_varianceSize / 4); //Find the maximum value for slope variance ComputeBuffer buffer = new ComputeBuffer(m_varianceSize * m_varianceSize * m_varianceSize, sizeof(float)); CBUtility.ReadFromRenderTexture(m_varianceRenderTexture, 1, buffer, ShaderReplacer.Instance.LoadedComputeShaders["ReadData"]); float[] varianceData = new float[m_varianceSize * m_varianceSize * m_varianceSize]; buffer.GetData(varianceData); m_maxSlopeVariance = 0.0f; for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, varianceData[v]); } buffer.Release(); } }
void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. // Used by the BRDF rendering model float theoreticSlopeVariance = 0.0f; float k = 5e-3f; while (k < 1e3f) { float nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } float[] spectrum01 = new float[m_fourierGridSize * m_fourierGridSize * 4]; float[] spectrum23 = new float[m_fourierGridSize * m_fourierGridSize * 4]; int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY; Vector2 sample12ZW; Vector2 sample34XY; Vector2 sample34ZW; UnityEngine.Random.seed = 0; for (int x = 0; x < m_fourierGridSize; x++) { for (int y = 0; y < m_fourierGridSize; y++) { idx = x + y * m_fourierGridSize; i = (x >= m_fourierGridSize / 2) ? (float)(x - m_fourierGridSize) : (float)x; j = (y >= m_fourierGridSize / 2) ? (float)(y - m_fourierGridSize) : (float)y; sample12XY = GetSpectrumSample(i, j, m_gridSizes.x, Mathf.PI / m_gridSizes.x); sample12ZW = GetSpectrumSample(i, j, m_gridSizes.y, Mathf.PI * m_fsize / m_gridSizes.x); sample34XY = GetSpectrumSample(i, j, m_gridSizes.z, Mathf.PI * m_fsize / m_gridSizes.y); sample34ZW = GetSpectrumSample(i, j, m_gridSizes.w, Mathf.PI * m_fsize / m_gridSizes.z); spectrum01[idx * 4 + 0] = sample12XY.x; spectrum01[idx * 4 + 1] = sample12XY.y; spectrum01[idx * 4 + 2] = sample12ZW.x; spectrum01[idx * 4 + 3] = sample12ZW.y; spectrum23[idx * 4 + 0] = sample34XY.x; spectrum23[idx * 4 + 1] = sample34XY.y; spectrum23[idx * 4 + 2] = sample34ZW.x; spectrum23[idx * 4 + 3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.x, j / m_gridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.y, j / m_gridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.z, j / m_gridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / m_gridSizes.w, j / m_gridSizes.w, sample34ZW); } } //Write floating point data into render texture m_writeFloat.WriteIntoRenderTexture(m_spectrum01, 4, spectrum01); m_writeFloat.WriteIntoRenderTexture(m_spectrum23, 4, spectrum23); // Compute variance for the BRDF // copied from the dx9 project float slopeVarianceDelta = 0.5f * (theoreticSlopeVariance - totalSlopeVariance); // m_varianceMax = new Vector2(float.NegativeInfinity, float.NegativeInfinity); Vector2[, , ] variance32bit = new Vector2[m_varianceSize, m_varianceSize, m_varianceSize]; Color[] variance8bit = new Color[m_varianceSize * m_varianceSize * m_varianceSize]; // for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { variance32bit[x, y, z] = ComputeVariance(slopeVarianceDelta, spectrum01, spectrum23, x, y, z); //problematic line if (variance32bit[x, y, z].x > m_varianceMax.x) { m_varianceMax.x = variance32bit[x, y, z].x; } if (variance32bit[x, y, z].y > m_varianceMax.y) { m_varianceMax.y = variance32bit[x, y, z].y; } } } } for (int x = 0; x < m_varianceSize; x++) { for (int y = 0; y < m_varianceSize; y++) { for (int z = 0; z < m_varianceSize; z++) { idx = x + y * m_varianceSize + z * m_varianceSize * m_varianceSize; variance8bit[idx] = new Color(variance32bit[x, y, z].x / m_varianceMax.x, variance32bit[x, y, z].y / m_varianceMax.y, 0.0f, 1.0f); } } } m_variance.SetPixels(variance8bit); m_variance.Apply(); m_maxSlopeVariance = 0.0f; for (int v = 0; v < m_varianceSize * m_varianceSize * m_varianceSize; v++) { m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].r * m_varianceMax.x); m_maxSlopeVariance = Mathf.Max(m_maxSlopeVariance, variance8bit[v].g * m_varianceMax.y); } }