void BitonicSort_fastest(ComputeBuffer gpu_data) { int n = gpu_data.count; //引数をセット shader.SetBuffer(kernel_ParallelBitonic_B16, "data", gpu_data); shader.SetBuffer(kernel_ParallelBitonic_B8, "data", gpu_data); shader.SetBuffer(kernel_ParallelBitonic_B4, "data", gpu_data); shader.SetBuffer(kernel_ParallelBitonic_B2, "data", gpu_data); shader.SetBuffer(kernel_ParallelBitonic_C4, "data", gpu_data); shader.SetBuffer(kernel_ParallelBitonic_C2, "data", gpu_data); int nlog = (int)(Mathf.Log(n, 2)); int B_indx, inc; int kernel_id; for (int i = 0; i < nlog; i++) { inc = 1 << i; for (int j = 0; j < i + 1; j++) { if (inc <= 128) { break; //あとはshared memory内におさまるので } if (inc >= 2048) { B_indx = 16; kernel_id = kernel_ParallelBitonic_B16; } else if (inc >= 1024) { B_indx = 8; kernel_id = kernel_ParallelBitonic_B8; } else if (inc >= 512) { B_indx = 4; kernel_id = kernel_ParallelBitonic_B4; } else { B_indx = 2; kernel_id = kernel_ParallelBitonic_B2; } shader.SetInt("inc", inc * 2 / B_indx); shader.SetInt("dir", 2 << i); shader.Dispatch(kernel_id, n / B_indx / THREADNUM_X, 1, 1); inc /= B_indx; } //これ以降はshared memoryに収まりそうなサイズなので shader.SetInt("inc0", inc); shader.SetInt("dir", 2 << i); if ((inc == 8) | (inc == 32) | (inc == 128)) { shader.Dispatch(kernel_ParallelBitonic_C4, n / 4 / 64, 1, 1); } else { shader.Dispatch(kernel_ParallelBitonic_C2, n / 2 / 128, 1, 1); } }//ループの終わり }
/*void LoadSkyMaps() * { * skybox_material = new Material(skybox_shader); * m_cam = gameObject.GetComponent<Camera>(); * m_cam.depthTextureMode = DepthTextureMode.DepthNormals; * * //Transmittance is responsible for the change in the sun color as it moves * //The raw file is a 2D array of 32 bit floats with a range of 0 to 1 * string path = Application.dataPath + m_filePath + "/transmittance.raw"; * * rt_transmittanceT = new RenderTexture(TRANSMITTANCE_W, TRANSMITTANCE_H, 0, RenderTextureFormat.ARGBFloat); * rt_transmittanceT.wrapMode = TextureWrapMode.Clamp; * rt_transmittanceT.filterMode = FilterMode.Bilinear; * rt_transmittanceT.enableRandomWrite = true; * rt_transmittanceT.Create(); * * ComputeBuffer buffer = new ComputeBuffer(TRANSMITTANCE_W*TRANSMITTANCE_H, sizeof(float)*3); * CBUtility.WriteIntoRenderTexture(rt_transmittanceT, 3, path, buffer, m_writeData); * buffer.Release(); * * //Iirradiance is responsible for the change in the sky color as the sun moves * //The raw file is a 2D array of 32 bit floats with a range of 0 to 1 * path = Application.dataPath + m_filePath + "/irradiance.raw"; * * rt_irradianceT[READ] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat); * rt_irradianceT[READ].wrapMode = TextureWrapMode.Clamp; * rt_irradianceT[READ].filterMode = FilterMode.Bilinear; * rt_irradianceT[READ].enableRandomWrite = true; * rt_irradianceT[READ].Create(); * * buffer = new ComputeBuffer(SKY_W*SKY_H, sizeof(float)*3); * CBUtility.WriteIntoRenderTexture(rt_irradianceT[READ], 3, path, buffer, m_writeData); * buffer.Release(); * * //Inscatter is responsible for the change in the sky color as the sun moves * //The raw file is a 4D array of 32 bit floats with a range of 0 to 1.589844 * //As there is not such thing as a 4D texture the data is packed into a 3D texture * //and the shader manually performs the sample for the 4th dimension * path = Application.dataPath + m_filePath + "/inscatter.raw"; * * rt_inscatterT[READ] = new RenderTexture(RES_MU_S * RES_NU, RES_MU, 0, RenderTextureFormat.ARGBFloat); * rt_inscatterT[READ].volumeDepth = RES_R; * rt_inscatterT[READ].wrapMode = TextureWrapMode.Clamp; * rt_inscatterT[READ].filterMode = FilterMode.Bilinear; * rt_inscatterT[READ].isVolume = true; * rt_inscatterT[READ].enableRandomWrite = true; * rt_inscatterT[READ].Create(); * * buffer = new ComputeBuffer(RES_MU_S*RES_NU*RES_MU*RES_R, sizeof(float)*4); * CBUtility.WriteIntoRenderTexture(rt_inscatterT[READ], 4, path, buffer, m_writeData); * buffer.Release(); * * InitUniforms(skybox_material); * } */ void Preprocess() { if (m_step == 0) { // computes transmittance texture T (line 1 in algorithm 4.1) m_transmittance.SetTexture(0, "transmittanceWrite", rt_transmittanceT); m_transmittance.Dispatch(0, TRANSMITTANCE_W / NUM_THREADS, TRANSMITTANCE_H / NUM_THREADS, 1); } else if (m_step == 1) { // computes irradiance texture deltaE (line 2 in algorithm 4.1) m_irradiance1.SetTexture(0, "transmittanceRead", rt_transmittanceT); m_irradiance1.SetTexture(0, "deltaEWrite", rt_deltaET); m_irradiance1.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1); //if(WRITE_DEBUG_TEX) // SaveAs8bit(SKY_W, SKY_H, 4, "/deltaE_debug", rt_deltaET); } else if (m_step == 2) { // computes single scattering texture deltaS (line 3 in algorithm 4.1) // Rayleigh and Mie separated in deltaSR + deltaSM m_inscatter1.SetTexture(0, "transmittanceRead", rt_transmittanceT); m_inscatter1.SetTexture(0, "deltaSRWrite", rt_deltaSRT); m_inscatter1.SetTexture(0, "deltaSMWrite", rt_deltaSMT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < RES_R; i++) { m_inscatter1.SetInt("layer", i); m_inscatter1.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1); } /*if(WRITE_DEBUG_TEX) * SaveAs8bit(RES_MU_S*RES_NU, RES_MU*RES_R, 4, "/deltaSR_debug", rt_deltaSRT); * * if(WRITE_DEBUG_TEX) * SaveAs8bit(RES_MU_S*RES_NU, RES_MU*RES_R, 4, "/deltaSM_debug", rt_deltaSMT); */ } else if (m_step == 3) { // copies deltaE into irradiance texture E (line 4 in algorithm 4.1) m_copyIrradiance.SetFloat("k", 0.0f); m_copyIrradiance.SetTexture(0, "deltaERead", rt_deltaET); m_copyIrradiance.SetTexture(0, "irradianceRead", rt_irradianceT[READ]); m_copyIrradiance.SetTexture(0, "irradianceWrite", rt_irradianceT[WRITE]); m_copyIrradiance.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1); //RTUtility.Swap(rt_irradianceT); } else if (m_step == 4) { // copies deltaS into inscatter texture S (line 5 in algorithm 4.1) m_copyInscatter1.SetTexture(0, "deltaSRRead", rt_deltaSRT); m_copyInscatter1.SetTexture(0, "deltaSMRead", rt_deltaSMT); m_copyInscatter1.SetTexture(0, "inscatterWrite", rt_inscatterT[WRITE]); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < RES_R; i++) { m_copyInscatter1.SetInt("layer", i); m_copyInscatter1.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1); } RTUtility.Swap(rt_inscatterT); } else if (m_step == 5) { // computes deltaJ (line 7 in algorithm 4.1) m_inscatterS.SetInt("first", (m_order == 2) ? 1 : 0); m_inscatterS.SetTexture(0, "transmittanceRead", rt_transmittanceT); m_inscatterS.SetTexture(0, "deltaERead", rt_deltaET); m_inscatterS.SetTexture(0, "deltaSRRead", rt_deltaSRT); m_inscatterS.SetTexture(0, "deltaSMRead", rt_deltaSMT); m_inscatterS.SetTexture(0, "deltaJWrite", rt_deltaJT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < RES_R; i++) { m_inscatterS.SetInt("layer", i); m_inscatterS.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1); } } else if (m_step == 6) { // computes deltaE (line 8 in algorithm 4.1) m_irradianceN.SetInt("first", (m_order == 2) ? 1 : 0); m_irradianceN.SetTexture(0, "deltaSRRead", rt_deltaSRT); m_irradianceN.SetTexture(0, "deltaSMRead", rt_deltaSMT); m_irradianceN.SetTexture(0, "deltaEWrite", rt_deltaET); m_irradianceN.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1); } else if (m_step == 7) { // computes deltaS (line 9 in algorithm 4.1) m_inscatterN.SetTexture(0, "transmittanceRead", rt_transmittanceT); m_inscatterN.SetTexture(0, "deltaJRead", rt_deltaJT); m_inscatterN.SetTexture(0, "deltaSRWrite", rt_deltaSRT); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < RES_R; i++) { m_inscatterN.SetInt("layer", i); m_inscatterN.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1); } } else if (m_step == 8) { // adds deltaE into irradiance texture E (line 10 in algorithm 4.1) m_copyIrradiance.SetFloat("k", 1.0f); m_copyIrradiance.SetTexture(0, "deltaERead", rt_deltaET); m_copyIrradiance.SetTexture(0, "irradianceRead", rt_irradianceT[READ]); m_copyIrradiance.SetTexture(0, "irradianceWrite", rt_irradianceT[WRITE]); m_copyIrradiance.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1); //RTUtility.Swap(rt_irradianceT); } else if (m_step == 9) { // adds deltaS into inscatter texture S (line 11 in algorithm 4.1) m_copyInscatterN.SetTexture(0, "deltaSRead", rt_deltaSRT); m_copyInscatterN.SetTexture(0, "inscatterRead", rt_inscatterT[READ]); m_copyInscatterN.SetTexture(0, "inscatterWrite", rt_inscatterT[WRITE]); //The inscatter calc's can be quite demanding for some cards so process //the calc's in layers instead of the whole 3D data set. for (int i = 0; i < RES_R; i++) { m_copyInscatterN.SetInt("layer", i); m_copyInscatterN.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1); } RTUtility.Swap(rt_inscatterT); if (m_order < 4) { m_step = 4; m_order += 1; } } else if (m_step == 10) { ReleaseRT(); m_finished = true; } m_step += 1; }
// Use this for initialization void Start () { ComputeBuffer uniform01Data = new ComputeBuffer(512*512,16); float[] uniform01Array=new float[512*512*4]; for (int i = 0; i < 512*512 * 4; ++i) { uniform01Array[i] = Random.Range(0.00001f, 1.0f); } uniform01Data.SetData(uniform01Array); ComputeBuffer uniform01Data2 = new ComputeBuffer(512 * 512, 16); float[] uniform01Array2 = new float[512 * 512 * 4]; for (int i = 0; i < 512 * 512 * 4; ++i) { uniform01Array2[i] = Random.Range(0.00001f, 1.0f); } uniform01Data2.SetData(uniform01Array2); heightTex0=new RenderTexture(512,512,0,RenderTextureFormat.ARGBFloat); heightTex0.enableRandomWrite = true; heightTex0.filterMode = FilterMode.Bilinear; heightTex0.Create(); pingpong01 = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); pingpong01.enableRandomWrite = true; pingpong01.filterMode = FilterMode.Bilinear; pingpong01.Create(); pingpong02 = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); pingpong02.enableRandomWrite = true; pingpong02.filterMode = FilterMode.Bilinear; pingpong02.Create(); pingpong[0] = pingpong01; pingpong[1] = pingpong02; pingpong01CP = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); pingpong01CP.enableRandomWrite = true; pingpong01CP.filterMode = FilterMode.Bilinear; pingpong01CP.Create(); pingpong02CP = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); pingpong02CP.enableRandomWrite = true; pingpong02CP.filterMode = FilterMode.Bilinear; pingpong02CP.Create(); pingpongCP[0] = pingpong01CP; pingpongCP[1] = pingpong02CP; butterfly = new RenderTexture(9, 512, 0, RenderTextureFormat.ARGBFloat); butterfly.enableRandomWrite = true; butterfly.filterMode = FilterMode.Bilinear; butterfly.Create(); finalPassOutput = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); finalPassOutput.enableRandomWrite = true; finalPassOutput.filterMode = FilterMode.Bilinear; finalPassOutput.wrapMode = TextureWrapMode.Repeat; finalPassOutput.Create(); normalMap = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat); normalMap.enableRandomWrite = true; normalMap.filterMode = FilterMode.Bilinear; normalMap.wrapMode = TextureWrapMode.Repeat; normalMap.Create(); int[] revIndices = new int[512]; for (int i = 0; i < 512; ++i) { revIndices[i] = i; } int[] test= RadixSortByBits(revIndices,9); Debug.Log(string.Join(", ", value: test.Select(e=>e.ToString()).ToArray())); ComputeBuffer reserveBit = new ComputeBuffer(512,4); reserveBit.SetData(test); int k = OceanComputeShader.FindKernel("Height0"); OceanComputeShader.SetTexture(k, "Height0Tex", heightTex0); OceanComputeShader.SetFloat("unit",100); OceanComputeShader.SetInt("N",512); OceanComputeShader.SetVector("windDirection",new Vector4(1,1,0,0)); OceanComputeShader.SetFloat("windSpeed",10); OceanComputeShader.SetFloat("A", 2f); OceanComputeShader.SetFloat("gravity",9.81f); OceanComputeShader.SetBuffer(k, "uniform01Data", uniform01Data); OceanComputeShader.SetBuffer(k, "uniform01Data2", uniform01Data2); OceanComputeShader.Dispatch(k,512/8,512/8,1); int k3 = OceanComputeShader.FindKernel("Butterfly"); OceanComputeShader.SetBuffer(k3, "reserveBit", reserveBit); OceanComputeShader.SetTexture(k3, "ButterflyTex", butterfly); OceanComputeShader.Dispatch(k3, 9, 512 / 8, 1); // Mat.SetTexture("_MainTex", butterfly); uniform01Data.Release(); uniform01Data2.Release(); reserveBit.Release(); }
public List <PackedUniformVolume> Reduce(PackedUniformVolume packedUniformVolume) { // Calculate the size of the array containing all the voxel data for all layers var bitCount = 0; for (var i = 0; i <= packedUniformVolume.Depth; i++) { bitCount += PackedUniformVolume.GetVolumeBitCount(i); } var dataCount = (int)math.ceil(bitCount / 32.0); // Setup an buffer that will contain all the reduction layers and fill it with the finest layer values // To start the reduction process var packedVolumes = new ComputeBuffer(dataCount, sizeof(uint)); packedVolumes.SetData(packedUniformVolume.Voxels); _reduceComputeShader.SetBuffer(_reduceKernelId, "packed_volumes", packedVolumes); // Setup an buffer that will contain all the hashed reduction layers var hashedVolumes = new ComputeBuffer(bitCount, sizeof(uint)); _reduceComputeShader.SetBuffer(_reduceKernelId, "hashed_volumes", hashedVolumes); // Bit offsets to use when reading from src layer or writing to the dst layer var dstPackedVolumeStartOffsetBitIndex = 0; var dstHashedVolumeStartOffsetIndex = 0; for (var i = packedUniformVolume.Depth; i > 0; i--) { // Set the src packed volume to the dst packed volume for next iteration var srcPackedVolumeStartOffsetBitIndex = dstPackedVolumeStartOffsetBitIndex; var srcHashedVolumeStartOffsetIndex = dstHashedVolumeStartOffsetIndex; // Assign the dimensions of the source volume var srcPackedVolumeBitDimensions = PackedUniformVolume.GetVolumeBitDimensions(i); _reduceComputeShader.SetInts("src_packed_volume_bit_dimensions", srcPackedVolumeBitDimensions.x, srcPackedVolumeBitDimensions.y, srcPackedVolumeBitDimensions.z); // Assign the offset to use when reading bits from the src layer _reduceComputeShader.SetInt("src_packed_volume_start_offset_bit_index", srcPackedVolumeStartOffsetBitIndex); // Assign dimensions of the destination volume var dstPackedVolumeBitDimensions = srcPackedVolumeBitDimensions / 2; _reduceComputeShader.SetInts("dst_packed_volume_bit_dimensions", dstPackedVolumeBitDimensions.x, dstPackedVolumeBitDimensions.y, dstPackedVolumeBitDimensions.z); // Increment destination offset so we write to the area reserved for the next layer dstPackedVolumeStartOffsetBitIndex += PackedUniformVolume.GetVolumeBitCount(i); _reduceComputeShader.SetInt("dst_packed_volume_start_offset_bit_index", dstPackedVolumeStartOffsetBitIndex); _reduceComputeShader.SetInts("src_hashed_volume_dimensions", srcPackedVolumeBitDimensions.x, srcPackedVolumeBitDimensions.y, srcPackedVolumeBitDimensions.z); _reduceComputeShader.SetInt("src_hashed_volume_start_offset_index", srcHashedVolumeStartOffsetIndex); _reduceComputeShader.SetInts("dst_hashed_volume_dimensions", dstPackedVolumeBitDimensions.x, dstPackedVolumeBitDimensions.y, dstPackedVolumeBitDimensions.z); // Increment destination offset so we write to the area reserved for the next layer dstHashedVolumeStartOffsetIndex += PackedUniformVolume.GetVolumeBitCount(i); _reduceComputeShader.SetInt("dst_hashed_volume_start_offset_index", dstHashedVolumeStartOffsetIndex); // Dispatch to the GPU. /8 is used for better utilization of the GPU var dispatchVolumeDimensions = math.max(new int3(1), dstPackedVolumeBitDimensions / 8); _reduceComputeShader.Dispatch( _reduceKernelId, dispatchVolumeDimensions.x, dispatchVolumeDimensions.y, dispatchVolumeDimensions.z ); } //Collect all the reduction data from the gpu var reducedPackedVolumes = new uint[dataCount]; packedVolumes.GetData(reducedPackedVolumes); var reducedHashedVolumes = new uint[bitCount]; hashedVolumes.GetData(reducedHashedVolumes); var packedVolumeList = new List <PackedUniformVolume>(); var voxelWorldScaleInMeters = packedUniformVolume.VoxelWorldScaleInMeters; var bitOffset = 0; for (var i = packedUniformVolume.Depth; i > 0; i--) { bitCount = PackedUniformVolume.GetVolumeBitCount(i); var intCount = (int)math.ceil(bitCount / 32.0); var intOffset = (int)math.ceil(bitOffset / 32.0); packedVolumeList.Add(new PackedUniformVolume(voxelWorldScaleInMeters, i) { Voxels = reducedPackedVolumes.Skip(intOffset).Take(intCount).ToArray(), Hashes = reducedHashedVolumes.Skip(bitOffset).Take(bitCount).ToArray() }); bitOffset += bitCount; voxelWorldScaleInMeters *= 2; } packedVolumes.Dispose(); DEBUG = packedVolumeList; return(packedVolumeList); }
void RenderAsSolid() { CreateSolidMaterial(); // TODO: camera var camera = Camera.main; int width = camera.pixelWidth; int height = camera.pixelHeight; int size = Math.Max(Mathf.NextPowerOfTwo(width), Mathf.NextPowerOfTwo(height)); if (rt == null || rt.width != camera.pixelWidth || rt.height != camera.pixelHeight) { rt?.Release(); rt = new RenderTexture(width, height, 24, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rt.enableRandomWrite = true; rt.autoGenerateMips = false; rt.useMipMap = false; rt.Create(); rtPos?.Release(); rtPos = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear); rtPos.enableRandomWrite = true; rtPos.autoGenerateMips = false; rtPos.useMipMap = false; rtPos.Create(); rtMask?.Release(); rtMask = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear); rtMask.enableRandomWrite = true; rtMask.autoGenerateMips = false; rtMask.useMipMap = false; rtMask.Create(); rtPosition?.Release(); rtPosition = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rtPosition.enableRandomWrite = true; rtPosition.autoGenerateMips = false; rtPosition.useMipMap = true; rtPosition.Create(); rtColor?.Release(); rtColor = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); rtColor.enableRandomWrite = true; rtColor.autoGenerateMips = false; rtColor.useMipMap = true; rtColor.Create(); rtDepth?.Release(); rtDepth = new RenderTexture(size, size, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear); rtDepth.enableRandomWrite = true; rtDepth.autoGenerateMips = false; rtDepth.useMipMap = true; rtDepth.Create(); } int maxLevel = 0; while ((size >> maxLevel) > 8) { maxLevel++; } Graphics.SetRenderTarget(new[] { rt.colorBuffer, rtPos.colorBuffer }, rt.depthBuffer); GL.Clear(true, true, Color.clear); SolidRenderMaterial.SetInt("_Colorize", (int)Colorize); SolidRenderMaterial.SetFloat("_MinHeight", Data.Bounds.min.y); SolidRenderMaterial.SetFloat("_MaxHeight", Data.Bounds.max.y); SolidRenderMaterial.SetMatrix("_Transform", camera.worldToCameraMatrix * transform.localToWorldMatrix); SolidRenderMaterial.SetMatrix("_ViewToClip", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false)); SolidRenderMaterial.SetPass(0); Graphics.DrawProceduralNow(MeshTopology.Points, Buffer.count); var setupClear = SolidComputeShader.FindKernel("SetupClear"); SolidComputeShader.SetTexture(setupClear, "_SetupClearPosition", rtPosition, 0); SolidComputeShader.SetTexture(setupClear, "_SetupClearColor", rtColor, 0); SolidComputeShader.SetTexture(setupClear, "_SetupClearDepth", rtDepth, 0); SolidComputeShader.Dispatch(setupClear, size / 8, size / 8, 1); var setupCopy = SolidComputeShader.FindKernel("SetupCopy"); SolidComputeShader.SetTexture(setupCopy, "_SetupCopyInput", rt, 0); SolidComputeShader.SetTexture(setupCopy, "_SetupCopyInputPos", rtPos, 0); SolidComputeShader.SetTexture(setupCopy, "_SetupCopyPosition", rtPosition, 0); SolidComputeShader.SetTexture(setupCopy, "_SetupCopyColor", rtColor, 0); SolidComputeShader.SetTexture(setupCopy, "_SetupCopyDepth", rtDepth, 0); SolidComputeShader.SetFloat("_SetupCopyMaxDepth", camera.farClipPlane); SolidComputeShader.SetMatrix("_SetupCopyProj", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false)); SolidComputeShader.SetMatrix("_SetupCopyInverseProj", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false).inverse); SolidComputeShader.Dispatch(setupCopy, size / 8, size / 8, 1); if (SolidRemoveHidden) { var posMax = new[] { width - 1, height - 1 }; var downsample = SolidComputeShader.FindKernel("Downsample"); for (int i = 1; i <= maxLevel + 3; i++) { SolidComputeShader.SetInts("_DownsamplePosMax", posMax); posMax[0] = (posMax[0] + 1) / 2 - 1; posMax[1] = (posMax[1] + 1) / 2 - 1; SolidComputeShader.SetTexture(downsample, "_DownsampleInput", rtPosition, i - 1); SolidComputeShader.SetTexture(downsample, "_DownsampleOutput", rtPosition, i); SolidComputeShader.SetTexture(downsample, "_DownsampleDepthInput", rtDepth, i - 1); SolidComputeShader.SetTexture(downsample, "_DownsampleDepthOutput", rtDepth, i); SolidComputeShader.Dispatch(downsample, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1); } float metric = DebugSolidMetric / 100f; float removeHiddenMagic = 10 * metric * camera.pixelHeight * 0.5f / Mathf.Tan(0.5f * camera.fieldOfView * Mathf.Deg2Rad); DebugSolidFixedLevel = Math.Min(Math.Max(DebugSolidFixedLevel, 0), maxLevel); var removeHidden = SolidComputeShader.FindKernel("RemoveHidden"); SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenMask", rtMask); SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenPosition", rtPosition); SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenColor", rtColor, 0); SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenDepth", rtDepth); SolidComputeShader.SetFloat("_RemoveHiddenMagic", removeHiddenMagic); SolidComputeShader.SetInt("_RemoveHiddenLevel", DebugSolidFixedLevel); SolidComputeShader.Dispatch(removeHidden, size / 8, size / 8, 1); } if (DebugSolidPullPush) { var pullKernel = SolidComputeShader.FindKernel("PullKernel"); for (int i = 1; i <= maxLevel; i++) { SolidComputeShader.SetTexture(pullKernel, "_PullInput", rtColor, i - 1); SolidComputeShader.SetTexture(pullKernel, "_PullOutput", rtColor, i); SolidComputeShader.Dispatch(pullKernel, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1); } var pushKernel = SolidComputeShader.FindKernel("PushKernel"); SolidComputeShader.SetTexture(pushKernel, "_PushMaskTex", rtMask); SolidComputeShader.SetTexture(pushKernel, "_PushPosition", rtPosition); SolidComputeShader.SetFloat("_PushAlwaysFillDistance", DebugSolidAlwaysFillDistance); for (int i = maxLevel; i > 0; i--) { SolidComputeShader.SetInt("_PushOutputLevel", i - 1); SolidComputeShader.SetTexture(pushKernel, "_PushInput", rtColor, i); SolidComputeShader.SetTexture(pushKernel, "_PushOutput", rtColor, i - 1); SolidComputeShader.Dispatch(pushKernel, Math.Max(1, (size >> (i - 1)) / 8), Math.Max(1, (size >> (i - 1)) / 8), 1); } } DebugSolidBlitLevel = Math.Min(Math.Max(DebugSolidBlitLevel, 0), maxLevel); SolitBlitMaterial.SetTexture("_ColorTex", rtColor); SolitBlitMaterial.SetTexture("_MaskTex", rtMask); SolitBlitMaterial.SetInt("_DebugLevel", DebugSolidBlitLevel); Graphics.DrawProcedural(SolitBlitMaterial, GetWorldBounds(), MeshTopology.Triangles, 3, camera: camera, layer: 1); }
/// <summary> /// This function determines where and whether fluid will be filled in the cellular automaton. /// </summary> /// <param name="fill">An array of size 4. The first three values determine the position, where fluid will be filled in (a coordinate outside the borders will stop filling).</param> /// <param name="element">The type of element, that is filled in.</param> /// <param name="radius">The radius.</param> public void Fill(float[] fill, int element, int radius) { cellularAutomaton.SetInt("radius", radius); cellularAutomaton.SetInts("fill", new int[] { (int)(fill[0] * dimensions.x * 16.0), (int)(fill[1] * dimensions.y * 16.0), (int)(fill[2] * dimensions.z * 16.0), element }); }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys Debug.Log("cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString()); _MaxBufferSize = numPolys[0]; Poly[] polyArray = new Poly[_MaxBufferSize]; ComputeBuffer cBuffer = new ComputeBuffer(_MaxBufferSize, 72); // 18 floats x 4 bytes/float = 72 cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU //Construct mesh using received data Mesh newMesh = new Mesh(); int vindex = 0; //int count = 0; //Count real data length --- Looks like there might be wasted data??? -- investigate how to Optimize /*for (count = 0; count < _MaxBufferSize; count++) { * if (polyArray[count].A1 == 0.0f && polyArray[count].B1 == 0.0f && polyArray[count].C1 == 0.0 && * polyArray[count].A2 == 0.0f && polyArray[count].B2 == 0.0f && polyArray[count].C2 == 0.0 && * polyArray[count].A3 == 0.0f && polyArray[count].B3 == 0.0f && polyArray[count].C3 == 0.0) { * * break; * } * }*/ //Debug.Log(count+" triangles got"); // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[_MaxBufferSize * 3]; int[] tris = new int[_MaxBufferSize * 3]; Vector2[] uvs = new Vector2[_MaxBufferSize * 3]; Vector3[] normals = new Vector3[_MaxBufferSize * 3]; //Parse triangles for (int ix = 0; ix < _MaxBufferSize; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(polyArray[ix].A1, polyArray[ix].A2, polyArray[ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NA1, polyArray[ix].NA2, polyArray[ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //B1,B2,B3 vPos = new Vector3(polyArray[ix].B1, polyArray[ix].B2, polyArray[ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NB1, polyArray[ix].NB2, polyArray[ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //C1,C2,C3 vPos = new Vector3(polyArray[ix].C1, polyArray[ix].C2, polyArray[ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NC1, polyArray[ix].NC2, polyArray[ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; } //We have got all data and are ready to setup a new mesh! //newMesh.Clear(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.RecalculateNormals(); newMesh.Optimize(); cBuffer.Dispose(); cBufferNumPoly.Dispose(); //cBuffer.Release(); this.GetComponent <MeshFilter>().sharedMesh = newMesh; }
private void CalculateVisibleInstances() { // Global data m_camPosition = mainCamera.transform.position; //Matrix4x4 m = mainCamera.transform.localToWorldMatrix; Matrix4x4 v = mainCamera.worldToCameraMatrix; Matrix4x4 p = mainCamera.projectionMatrix; m_MVP = p * v;//*m; m_bounds.center = m_camPosition; m_bounds.extents = Vector3.one * 10000; ////////////////////////////////////////////////////// // Reset the arguments buffer ////////////////////////////////////////////////////// Profiler.BeginSample("Resetting args buffer"); { m_argsBuffer.SetData(m_args); } Profiler.EndSample(); ////////////////////////////////////////////////////// // Sort the position buffer based on distance from camera ////////////////////////////////////////////////////// Profiler.BeginSample("01 LOD Sorting"); { RunGpuSorting(ref m_camPosition); } Profiler.EndSample(); ////////////////////////////////////////////////////// // Set up compute shader to perform the occlusion culling ////////////////////////////////////////////////////// Profiler.BeginSample("02 Occlusion"); { // Input occlusionCS.SetInt("_ShouldFrustumCull", enableFrustumCulling ? 1 : 0); occlusionCS.SetInt("_ShouldOcclusionCull", enableOcclusionCulling ? 1 : 0); occlusionCS.SetInt("_ShouldDetailCull", enableDetailCulling ? 1 : 0); occlusionCS.SetInt("_ShouldLOD", enableLOD ? 1 : 0); occlusionCS.SetInt("_Cascades", QualitySettings.shadowCascades); occlusionCS.SetFloat("_DetailCullingScreenPercentage", detailCullingScreenPercentage); occlusionCS.SetMatrix("_UNITY_MATRIX_MVP", m_MVP); occlusionCS.SetVector("_HiZTextureSize", hiZBuffer.TextureSize); occlusionCS.SetVector("_CamPosition", m_camPosition); occlusionCS.SetBuffer(m_occlusionKernelID, "_InstanceDataBuffer", m_instanceDataBuffer); occlusionCS.SetTexture(m_occlusionKernelID, "_Unity_WorldToShadow", GetWorldToShadowMatrixTexture()); occlusionCS.SetTexture(m_occlusionKernelID, "_HiZMap", hiZBuffer.HiZDepthTexture); // Output occlusionCS.SetBuffer(m_occlusionKernelID, "_ArgsBuffer", m_argsBuffer); occlusionCS.SetBuffer(m_occlusionKernelID, "_IsVisibleBuffer", m_isVisibleBuffer); // Dispatch int groupX = Mathf.Max(m_numberOfInstances / 64, 1); occlusionCS.Dispatch(m_occlusionKernelID, groupX, 1, 1); } Profiler.EndSample(); ////////////////////////////////////////////////////// // Perform scan of instance predicates ////////////////////////////////////////////////////// Profiler.BeginSample("03 Scan Instances"); { int groupX = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE); // Input scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_InstancePredicatesIn", m_isVisibleBuffer); // Output scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_GroupSumArray", m_groupSumArray); scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_ScannedInstancePredicates", m_scannedInstancePredicates); // Dispatch scanInstancesCS.Dispatch(m_scanInstancesKernelID, groupX, 1, 1); } Profiler.EndSample(); ////////////////////////////////////////////////////// // Perform scan of group sums ////////////////////////////////////////////////////// Profiler.BeginSample("04 Scan Thread Groups"); { // Input int numOfGroups = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE); scanGroupSumsCS.SetInt("_NumOfGroups", numOfGroups); scanGroupSumsCS.SetBuffer(m_scanGroupSumsKernelID, "_GroupSumArrayIn", m_groupSumArray); // Output scanGroupSumsCS.SetBuffer(m_scanGroupSumsKernelID, "_GroupSumArrayOut", m_scannedGroupSumBuffer); // Dispatch scanGroupSumsCS.Dispatch(m_scanGroupSumsKernelID, 1, 1, 1); } Profiler.EndSample(); ////////////////////////////////////////////////////// // Perform stream compaction // Calculate instance offsets and store in drawcall arguments buffer ////////////////////////////////////////////////////// Profiler.BeginSample("05 Copy Instance Data"); { int groupX = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE); // Input copyInstanceDataCS.SetInt("_NumberOfInstanceTypes", m_numberOfInstanceTypes * NUMBER_OF_DRAW_CALLS); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceData", m_instanceDataBuffer); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceDrawData", m_instanceDrawDataBuffer); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstancePredicatesIn", m_isVisibleBuffer); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_GroupSumArray", m_scannedGroupSumBuffer); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_ScannedInstancePredicates", m_scannedInstancePredicates); // Output copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_DrawcallDataOut", m_argsBuffer); copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceDataOut", m_culledInstanceBuffer); // Dispatch copyInstanceDataCS.Dispatch(m_copyInstanceDataKernelID, groupX, 1, 1); } Profiler.EndSample(); LogStats(); }
void Update() { Vector2 mousePos = new Vector2 { x = Input.mousePosition.x / (float)Screen.width, y = Input.mousePosition.y / (float)Screen.height }; Vector2 resolution = new Vector2 { x = _doubleBuffer.width, y = _doubleBuffer.height }; Shader.SetGlobalVector("_Resolution", new Vector4 { x = resolution.x, y = resolution.y, z = 1f / resolution.x, w = 1f / resolution.y }); Shader.SetGlobalVector("_Mouse", mousePos); Shader.SetGlobalFloat("_Time", Time.time); Shader.SetGlobalFloat("_DeltaTime", Time.deltaTime); if (Input.GetMouseButton(0)) { particleShader.SetInt("_MaxParticles", maxParticles); particleShader.SetBuffer(particleSeedKernel, "_CounterBuf", indirectArgsBuf); particleShader.SetBuffer(particleSeedKernel, "_WriteParticles", pBufA); particleShader.Dispatch(particleSeedKernel, 1, 1, 1); } ComputeBuffer.CopyCount(pBufA, indirectArgsBuf, 0); indirectArgsShader.SetBuffer(0, "_IndirectArgsBuf", indirectArgsBuf); indirectArgsShader.Dispatch(0, 1, 1, 1); particleShader.SetBuffer(particleSimKernel, "_CounterBuf", indirectArgsBuf); particleShader.SetBuffer(particleSimKernel, "_ReadParticles", pBufA); particleShader.SetBuffer(particleSimKernel, "_WriteParticles", pBufB); particleShader.SetTexture(particleSimKernel, "_ReadTexture", _doubleBuffer.read); particleShader.SetTexture(particleSimKernel, "_WriteTexture", _doubleBuffer.write); uniforms.Bind(particleShader); particleShader.DispatchIndirect(particleSimKernel, indirectArgsBuf, sizeof(int)); ComputeBuffer.CopyCount(pBufB, indirectArgsBuf, 0); // flip buffers var tmp = pBufA; pBufA = pBufB; pBufB = tmp; _doubleBuffer.Flip(); { colorDiffuseShader.SetFloat("_DecayRate", decayRate); colorDiffuseShader.SetTexture(0, "_ReadTexture", _doubleBuffer.read); colorDiffuseShader.SetTexture(0, "_WriteTexture", _doubleBuffer.write); colorDiffuseShader.GetKernelThreadGroupSizes(0, out var threadsX, out var threadsY, out var threadsZ); var threadGroupsX = _doubleBuffer.width / (int)threadsX; var threadGroupsY = _doubleBuffer.height / (int)threadsY; colorDiffuseShader.Dispatch(0, threadGroupsX, threadGroupsY, 1); } renderer.material.SetTexture("_MainTex", _doubleBuffer.write); }
private void OnPreRender() { primitives.SetData(linesData); for (int i = 0; i < verts.Length; i++) { verts[i] += Vector2.left * (Input.GetKey(KeyCode.LeftArrow)?Time.deltaTime * 0.1f:0); verts[i] += Vector2.right * (Input.GetKey(KeyCode.RightArrow) ? Time.deltaTime * 0.1f : 0); verts[i] += Vector2.up * (Input.GetKey(KeyCode.UpArrow) ? Time.deltaTime * 0.1f : 0); verts[i] += Vector2.down * (Input.GetKey(KeyCode.DownArrow) ? Time.deltaTime * 0.1f : 0); } vertices.SetData(verts); ComputeBuffer filterCounts = new ComputeBuffer(1, 4); int[] fdat = { numLines }; filterCounts.SetData(fdat); ComputeBuffer primIds = index; int filterTilesX = 1; int filterTilesY = 1; for (int i = 0; i < 2; i++) { int kernel = kernels[i]; shader.SetBuffer(kernel, "filterCounts", filterCounts); shader.SetBuffer(kernel, "buffer", primitives); shader.SetBuffer(kernel, "vertices", vertices); shader.SetBuffer(kernel, "lines", primIds); shader.SetBuffer(kernel, "counts", counts[i]); shader.SetInt("filterXtiles", filterTilesX); shader.SetInt("filterYtiles", filterTilesY); shader.SetInt("xtiles", (Screen.width / tileSize[i])); shader.SetInt("ytiles", (Screen.height / tileSize[i])); shader.SetInt("tileLines", tileLines[i]); shader.SetFloat("distCheck", Mathf.Sqrt(2) * tileSize[i] / Screen.width); shader.SetBuffer(kernel, "tiles", tiles[i]); uint x, y, z; shader.GetKernelThreadGroupSizes(kernel, out x, out y, out z); shader.Dispatch(kernel, Screen.width / (int)x / tileSize[i], Screen.height / (int)y / tileSize[i], 1); if (i == 0) { filterCounts.Release(); } filterCounts = counts[i]; filterTilesX = Screen.width / tileSize[i]; filterTilesY = Screen.height / tileSize[i]; primIds = tiles[i]; } }
void OnPreRender() { //Force reinitialization to make sure that everything is working properly if one of the cameras was unexpectedly destroyed if (!voxelCamera || !shadowCam) { initChecker = null; } InitCheck(); if (notReadyToRender) { return; } if (!updateGI) { return; } //Cache the previous active render texture to avoid issues with other Unity rendering going on RenderTexture previousActive = RenderTexture.active; Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0); //Main voxelization work if (renderState == RenderState.Voxelize) { activeVolume = voxelFlipFlop == 0 ? volumeTextures[0] : volumeTextureB; //Flip-flopping volume textures to avoid simultaneous read and write errors in shaders previousActiveVolume = voxelFlipFlop == 0 ? volumeTextureB : volumeTextures[0]; //float voxelTexel = (1.0f * voxelSpaceSize) / (int)voxelResolution * 0.5f; //Calculate the size of a voxel texel in world-space units //Setup the voxel volume origin position float interval = voxelSpaceSize / 8.0f; //The interval at which the voxel volume will be "locked" in world-space Vector3 origin; if (followTransform) { origin = followTransform.position; } else { //GI is still flickering a bit when the scene view and the game view are opened at the same time origin = transform.position + transform.forward * voxelSpaceSize / 4.0f; } //Lock the voxel volume origin based on the interval voxelSpaceOrigin = new Vector3(Mathf.Round(origin.x / interval) * interval, Mathf.Round(origin.y / interval) * interval, Mathf.Round(origin.z / interval) * interval); //Calculate how much the voxel origin has moved since last voxelization pass. Used for scrolling voxel data in shaders to avoid ghosting when the voxel volume moves in the world voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin; Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize); previousVoxelSpaceOrigin = voxelSpaceOrigin; //Set the voxel camera (proxy camera used to render the scene for voxelization) parameters voxelCamera.enabled = false; voxelCamera.orthographic = true; voxelCamera.orthographicSize = voxelSpaceSize * 0.5f; voxelCamera.nearClipPlane = 0.0f; voxelCamera.farClipPlane = voxelSpaceSize; voxelCamera.depth = -2; voxelCamera.renderingPath = RenderingPath.Forward; voxelCamera.clearFlags = CameraClearFlags.Color; voxelCamera.backgroundColor = Color.black; voxelCamera.cullingMask = giCullingMask; //Move the voxel camera game object and other related objects to the above calculated voxel space origin voxelCameraGO.transform.position = voxelSpaceOrigin - Vector3.forward * voxelSpaceSize * 0.5f; voxelCameraGO.transform.rotation = rotationFront; leftViewPoint.transform.position = voxelSpaceOrigin + Vector3.left * voxelSpaceSize * 0.5f; leftViewPoint.transform.rotation = rotationLeft; topViewPoint.transform.position = voxelSpaceOrigin + Vector3.up * voxelSpaceSize * 0.5f; topViewPoint.transform.rotation = rotationTop; //Set matrices needed for voxelization Shader.SetGlobalMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix); Shader.SetGlobalMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix)); Shader.SetGlobalMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix)); Shader.SetGlobalMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix)); Shader.SetGlobalMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix); Shader.SetGlobalMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix); Shader.SetGlobalMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse); Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution); Matrix4x4 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix); Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection); Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up); //Set paramteters Shader.SetGlobalColor("GISunColor", sun == null ? Color.black : new Color(Mathf.Pow(sun.color.r, 2.2f), Mathf.Pow(sun.color.g, 2.2f), Mathf.Pow(sun.color.b, 2.2f), Mathf.Pow(sun.intensity, 2.2f))); Shader.SetGlobalColor("SEGISkyColor", new Color(Mathf.Pow(skyColor.r * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.g * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.b * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.a, 2.2f))); Shader.SetGlobalFloat("GIGain", giGain); Shader.SetGlobalFloat("SEGISecondaryBounceGain", infiniteBounces ? secondaryBounceGain : 0.0f); Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight); Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0); Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers); //Render the depth texture from the sun's perspective in order to inject sunlight with shadows during voxelization if (sun != null) { shadowCam.cullingMask = giCullingMask; Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio; shadowCamTransform.position = shadowCamPosition; shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up); shadowCam.renderingPath = RenderingPath.Forward; shadowCam.depthTextureMode |= DepthTextureMode.None; shadowCam.orthographicSize = shadowSpaceSize; shadowCam.farClipPlane = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio; Graphics.SetRenderTarget(sunDepthTexture); shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer); shadowCam.RenderWithShader(sunDepthShader, ""); Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture); } //Clear the volume texture that is immediately written to in the voxelization scene shader clearCompute.SetTexture(0, "RG0", integerVolume); clearCompute.SetInt("Res", (int)voxelResolution); clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1); //Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture Graphics.SetRandomWriteTarget(1, integerVolume); voxelCamera.targetTexture = dummyVoxelTextureAAScaled; voxelCamera.RenderWithShader(voxelizationShader, ""); Graphics.ClearRandomWriteTargets(); //Transfer the data from the volume integer texture to the main volume texture used for GI tracing. transferIntsCompute.SetTexture(0, "Result", activeVolume); transferIntsCompute.SetTexture(0, "PrevResult", previousActiveVolume); transferIntsCompute.SetTexture(0, "RG0", integerVolume); transferIntsCompute.SetInt("VoxelAA", voxelAA ? 1 : 0); transferIntsCompute.SetInt("Resolution", (int)voxelResolution); transferIntsCompute.SetVector("VoxelOriginDelta", (voxelSpaceOriginDelta / voxelSpaceSize) * (int)voxelResolution); transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1); Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume); //Manually filter/render mip maps for (int i = 0; i < numMipLevels - 1; i++) { RenderTexture source = volumeTextures[i]; if (i == 0) { source = activeVolume; } int destinationRes = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i + 1.0f)); mipFilterCompute.SetInt("destinationRes", destinationRes); mipFilterCompute.SetTexture(mipFilterKernel, "Source", source); mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]); mipFilterCompute.Dispatch(mipFilterKernel, destinationRes / 8, destinationRes / 8, 1); Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]); } //Advance the voxel flip flop counter voxelFlipFlop += 1; voxelFlipFlop = voxelFlipFlop % 2; if (infiniteBounces) { renderState = RenderState.Bounce; } } else if (renderState == RenderState.Bounce) { //Clear the volume texture that is immediately written to in the voxelization scene shader clearCompute.SetTexture(0, "RG0", integerVolume); clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1); //Set secondary tracing parameters Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones); Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength); //Render the scene from the voxel camera object with the voxel tracing shader to render a bounce of GI into the irradiance volume Graphics.SetRandomWriteTarget(1, integerVolume); voxelCamera.targetTexture = dummyVoxelTextureFixed; voxelCamera.RenderWithShader(voxelTracingShader, ""); Graphics.ClearRandomWriteTargets(); //Transfer the data from the volume integer texture to the irradiance volume texture. This result is added to the next main voxelization pass to create a feedback loop for infinite bounces transferIntsCompute.SetTexture(1, "Result", secondaryIrradianceVolume); transferIntsCompute.SetTexture(1, "RG0", integerVolume); transferIntsCompute.SetInt("Resolution", (int)voxelResolution); transferIntsCompute.Dispatch(1, (int)voxelResolution / 16, (int)voxelResolution / 16, 1); Shader.SetGlobalTexture("SEGIVolumeTexture1", secondaryIrradianceVolume); renderState = RenderState.Voxelize; } RenderTexture.active = previousActive; }
public override bool Calculate() { Texture texL = texLKnob.GetValue <Texture>(); if (!texLKnob.connected() || texL == null) { outputTexKnob.ResetValue(); outputSize = Vector2Int.zero; if (outputTex != null) { outputTex.Release(); } return(true); } Texture texR = texRKnob.GetValue <Texture>(); if (!texRKnob.connected() || texR == null) { outputTexKnob.ResetValue(); outputSize = Vector2Int.zero; if (outputTex != null) { outputTex.Release(); } return(true); } var inputSize = new Vector2Int(texL.width, texL.height); if (inputSize != outputSize) { outputSize = inputSize; InitializeRenderTexture(); } patternShader.SetInt("width", outputSize.x); patternShader.SetInt("height", outputSize.y); int kernel = 0; switch (mergeModeSelection.Selected) { case "Simple": crossfader = crossfaderKnob.connected() ? crossfaderKnob.GetValue <float>() : crossfader; patternShader.SetFloat("crossfader", crossfader); kernel = fadeKernel; break; case "Layers": kernel = layerKernel; break; } patternShader.SetTexture(kernel, "texL", texL); patternShader.SetTexture(kernel, "texR", texR); patternShader.SetTexture(kernel, "outputTex", outputTex); uint tx, ty, tz; patternShader.GetKernelThreadGroupSizes(kernel, out tx, out ty, out tz); var threadGroupX = Mathf.CeilToInt(((float)outputSize.x) / tx); var threadGroupY = Mathf.CeilToInt(((float)outputSize.y) / ty); patternShader.Dispatch(kernel, threadGroupX, threadGroupY, 1); outputTexKnob.SetValue(outputTex); return(true); }
// Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) { InitBuffer(); } if (Input.GetKey(KeyCode.RightArrow)) { m_ElementCount += 10; } if (Input.GetKey(KeyCode.LeftArrow)) { m_ElementCount -= 10; } m_ElementCount = Mathf.Clamp(m_ElementCount, 0, kCount); if (Input.GetKeyDown(KeyCode.UpArrow)) { ++m_MaxPassCount; } if (Input.GetKeyDown(KeyCode.DownArrow)) { --m_MaxPassCount; } m_MaxPassCount = Mathf.Clamp(m_MaxPassCount, 0, Log2(kGroupCount)); // sort Profiler.BeginSample("Sort"); sortShader.SetInt("elementCount", m_ElementCount); sortShader.SetBuffer(sortKernelBitonic, "inputSequence", inputBuffer); sortShader.SetBuffer(sortKernelBitonic, "sortedSequence", scratchBuffer[0]); sortShader.SetBuffer(sortKernelBitonic, "deadElementCount", deadElementCount); sortShader.Dispatch(sortKernelBitonic, kGroupCount, 1, 1); sortedBuffer = scratchBuffer[0]; int arraySize = kElementCount; for (int i = 0; i < m_MaxPassCount; ++i) { sortShader.SetInt("subArraySize", arraySize); sortShader.SetBuffer(mergeKernel, "inputSequence", scratchBuffer[0]); sortShader.SetBuffer(mergeKernel, "sortedSequence", scratchBuffer[1]); sortShader.SetBuffer(mergeKernel, "deadElementCount", deadElementCount); sortShader.Dispatch(mergeKernel, (kElementCount * kGroupCount) / 64, 1, 1); sortedBuffer = scratchBuffer[1]; // swap ComputeBuffer tmp = scratchBuffer[0]; scratchBuffer[0] = scratchBuffer[1]; scratchBuffer[1] = tmp; arraySize <<= 1; } Profiler.EndSample(); sortedMat1.SetBuffer("buffer", sortedBuffer); sortedMat1.SetInt("totalCount", m_ElementCount); sortedMat1.SetInt("elementCount", kElementCount); sortedMat1.SetInt("groupCount", kGroupCount); inputMat.SetBuffer("buffer", inputBuffer); inputMat.SetInt("totalCount", m_ElementCount); inputMat.SetInt("elementCount", kElementCount); inputMat.SetInt("groupCount", kGroupCount); /*sortShader.SetBuffer(sortKernelMerge, "inputSequence", inputBuffer); * sortShader.SetBuffer(sortKernelMerge, "sortedSequence", sortedBuffer1); * sortShader.Dispatch(sortKernelMerge, kGroupCount, 1, 1);*/ }
void UpdateHistogram(RenderTexture source, Rect rect, HistogramMode mode) { if (m_HistogramMaterial == null) { m_HistogramMaterial = ImageEffectHelper.CheckShaderAndCreateMaterial(concreteTarget.histogramShader); } if (m_HistogramBuffer == null) { m_HistogramBuffer = new ComputeBuffer(256, sizeof(uint) << 2); } m_HistogramBuffer.SetData(k_EmptyBuffer); ComputeShader cs = concreteTarget.histogramComputeShader; int kernel = cs.FindKernel("KHistogramGather"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetTexture(kernel, "_Source", source); int[] channels = null; switch (mode) { case HistogramMode.Luminance: channels = new[] { 0, 0, 0, 1 }; break; case HistogramMode.RGB: channels = new[] { 1, 1, 1, 0 }; break; case HistogramMode.Red: channels = new[] { 1, 0, 0, 0 }; break; case HistogramMode.Green: channels = new[] { 0, 1, 0, 0 }; break; case HistogramMode.Blue: channels = new[] { 0, 0, 1, 0 }; break; } cs.SetInts("_Channels", channels); cs.SetInt("_IsLinear", concreteTarget.isGammaColorSpace ? 0 : 1); cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1); kernel = cs.FindKernel("KHistogramScale"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetFloat("_Height", rect.height); cs.Dispatch(kernel, 1, 1, 1); if (m_HistogramTexture == null) { DestroyImmediate(m_HistogramTexture); m_HistogramTexture = new RenderTexture((int)rect.width, (int)rect.height, 0, RenderTextureFormat.ARGB32); m_HistogramTexture.hideFlags = HideFlags.HideAndDontSave; } m_HistogramMaterial.SetBuffer("_Histogram", m_HistogramBuffer); m_HistogramMaterial.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height)); m_HistogramMaterial.SetColor("_ColorR", redCurveColor); m_HistogramMaterial.SetColor("_ColorG", greenCurveColor); m_HistogramMaterial.SetColor("_ColorB", blueCurveColor); m_HistogramMaterial.SetColor("_ColorL", masterCurveColor); m_HistogramMaterial.SetInt("_Channel", (int)mode); Graphics.Blit(m_HistogramTexture, m_HistogramTexture, m_HistogramMaterial, (mode == HistogramMode.RGB) ? 1 : 0); }
public void ComputePressureWithRGGS() { // red-black gauss-sebel UploadGlobalParameters(mComputePressure); int formPoissonKernel = mComputePressure.FindKernel("FormPoisson"); // 1. compute poisson mComputePressure.SetTexture(formPoissonKernel, "gPoisson0", mPoisson0.Source); mComputePressure.SetTexture(formPoissonKernel, "gPoisson1", mPoisson1.Source); mComputePressure.SetTexture(formPoissonKernel, "gPoisson2", mPoisson2.Source); mComputePressure.SetTexture(formPoissonKernel, "gGridMarker", mGridMarker.Source); mComputePressure.SetTexture(formPoissonKernel, "gLevelSet", mLevelSet[READ].Source); mComputePressure.Dispatch(formPoissonKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1); // 2. red-black gaus sebel int RBGSKernel = mComputePressure.FindKernel("RBGS"); for (int i = 0; i < 200; i++) { mComputePressure.SetInt("_redOrBlack", 0); mComputePressure.SetTexture(RBGSKernel, "gGridMarker", mGridMarker.Source); mComputePressure.SetTexture(RBGSKernel, "gPressure", mPressure.Source); mComputePressure.SetTexture(RBGSKernel, "gVelocityDivergence", mDivergence.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson0", mPoisson0.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson1", mPoisson1.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson2", mPoisson2.Source); mComputePressure.Dispatch(RBGSKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1); mComputePressure.SetInt("_redOrBlack", 1); mComputePressure.SetTexture(RBGSKernel, "gGridMarker", mGridMarker.Source); mComputePressure.SetTexture(RBGSKernel, "gPressure", mPressure.Source); mComputePressure.SetTexture(RBGSKernel, "gVelocityDivergence", mDivergence.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson0", mPoisson0.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson1", mPoisson1.Source); mComputePressure.SetTexture(RBGSKernel, "gPoisson2", mPoisson2.Source); mComputePressure.Dispatch(RBGSKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1); } // 3. projection (subtract divergence of pressure) bool notUseSimpleSubtract = true; if (notUseSimpleSubtract) { // TODO: Exist some bug... int subtractPressureGradientXKernel = mComputePressure.FindKernel("SubtractPressureGradientX"); mComputePressure.SetTexture(subtractPressureGradientXKernel, "gPressure", mPressure.Source); mComputePressure.SetTexture(subtractPressureGradientXKernel, "gVelocityU", mVelocityU[READ].Source); mComputePressure.SetTexture(subtractPressureGradientXKernel, "gGridMarker", mGridMarker.Source); mComputePressure.SetTexture(subtractPressureGradientXKernel, "gLevelSet", mLevelSet[READ].Source); mComputePressure.Dispatch(subtractPressureGradientXKernel, Mathf.CeilToInt((mWidth + 1) * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1); int subtractPressureGradientYKernel = mComputePressure.FindKernel("SubtractPressureGradientY"); mComputePressure.SetTexture(subtractPressureGradientYKernel, "gPressure", mPressure.Source); mComputePressure.SetTexture(subtractPressureGradientYKernel, "gVelocityV", mVelocityV[READ].Source); mComputePressure.SetTexture(subtractPressureGradientYKernel, "gGridMarker", mGridMarker.Source); mComputePressure.SetTexture(subtractPressureGradientYKernel, "gLevelSet", mLevelSet[READ].Source); mComputePressure.Dispatch(subtractPressureGradientYKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt((mHeight + 1) * 1.0f / mGroupThreadSizeX), 1); } else { int applyPressureKernel = mComputePressure.FindKernel("ApplyPressure"); mComputePressure.SetTexture(applyPressureKernel, "gPressure", mPressure.Source); mComputePressure.SetTexture(applyPressureKernel, "gVelocityU", mVelocityU[READ].Source); mComputePressure.SetTexture(applyPressureKernel, "gVelocityV", mVelocityV[READ].Source); mComputePressure.Dispatch(applyPressureKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1); } }
private void InitShaderData() { //Force field compute shader init shaderForceFieldCompute.SetInt("_N", N); _forceFieldBufferData = new Vector2[(N + 2) * (N + 2)]; _forceFieldBuffer = new ComputeBuffer(_forceFieldBufferData.Length, 2 * 4); _forceFieldBuffer.SetData(_forceFieldBufferData); shaderForceFieldCompute.SetBuffer(kernelForceFieldCompute, "Result", _forceFieldBuffer); _sourcesBuffer = new ComputeBuffer(maxSource, 2 * 4 + 4); shaderForceFieldCompute.SetBuffer(kernelForceFieldCompute, "_sources", _sourcesBuffer); //Force field apply shader init shaderForceFieldApply.SetInt("_N", N); shaderForceFieldApply.SetFloat("_speedLim", speedLim); _ufBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_u", _ufBuffer); _vfBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_v", _vfBuffer); _fBuffer = new ComputeBuffer((N + 2) * (N + 2), 2 * 4); shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_f", _fBuffer); _dfBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_d", _dfBuffer); //Diffusion shader init shaderDiffusion.SetInt("_N", N); _x0Buffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderDiffusion.SetBuffer(kernelDiffusion, "_x0", _x0Buffer); _xBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderDiffusion.SetBuffer(kernelDiffusion, "Result", _xBuffer); //Advection shader init shaderAdvection.SetInt("_N", N); _dBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderAdvection.SetBuffer(kernelAdvection, "_d", _dBuffer); _d0Buffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderAdvection.SetBuffer(kernelAdvection, "_d0", _d0Buffer); _uaBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderAdvection.SetBuffer(kernelAdvection, "_u", _uaBuffer); _vaBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderAdvection.SetBuffer(kernelAdvection, "_v", _vaBuffer); //ProjectionCompute shader init shaderProjectionCompute.SetInt("_N", N); _uInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_u", _uInBuffer); _vInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_v", _vInBuffer); _pOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_p", _pOutBuffer); //ProjectionApply shader init shaderProjectionApply.SetInt("_N", N); _uOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionApply.SetBuffer(kernelProjectionApply, "_u", _uOutBuffer); _vOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionApply.SetBuffer(kernelProjectionApply, "_v", _vOutBuffer); _pInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderProjectionApply.SetBuffer(kernelProjectionApply, "_p", _pInBuffer); //FillFluidRenderTex shader init shaderFillFluidRTex.SetInt("_N", N); _urInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_u", _urInBuffer); _vrInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_v", _vrInBuffer); _drInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4); shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_d", _drInBuffer); fluidRenderTexture = new RenderTexture(N, N, 1); fluidRenderTexture.enableRandomWrite = true; fluidRenderTexture.Create(); shaderFillFluidRTex.SetTexture(kernelFillFluidRTex, "Result", fluidRenderTexture); }
// updates the floor parameters async private IEnumerator UpdateFloorAsync() { while (isRoutineRunning) { // wait for imu vector & depth frame while (/**!isImuVectorSet ||*/ !isDepthFrameSet) { yield return(null); } //isImuVectorSet = false; isDepthFrameSet = false; KinectInterop.SetComputeShaderInt2(floorDetOffsetEstShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight); //KinectInterop.SetComputeShaderFloat2(floorDetOffsetEstShader, "SpaceScale", sensorData.sensorSpaceScale.x, sensorData.sensorSpaceScale.y); KinectInterop.SetComputeShaderFloat3(floorDetOffsetEstShader, "ImuUpVector", imuUpVector); floorDetOffsetEstShader.SetInt("MinDepth", minDepthDistance); floorDetOffsetEstShader.SetInt("MaxDepth", maxDepthDistance); floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "SpaceTable", pointCloudSpaceBuffer); floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "DepthMap", pointCloudDepthBuffer); floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudPos", pointCloudPosBuffer); floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudOfs", pointCloudOfsBuffer); floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudMask", pointCloudMaskBuffer); floorDetOffsetEstShader.Dispatch(floorDetOffsetEstKernel, sensorData.depthImageWidth / 8, sensorData.depthImageHeight / 8, 1); // FloorDetectionOffsetMinMaxShader KinectInterop.SetComputeShaderInt2(floorDetOffsetMinMaxShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight); floorDetOffsetMinMaxShader.SetInt("OfsHistBinLength", histBufferLength); floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "PointCloudOfs", pointCloudOfsBuffer); floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "PointCloudMask", pointCloudMaskBuffer); floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "OfsMinMax", ofsHistMinMaxBuffer); floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "OfsHistBinCount", ofsHistBinCountBuffer); floorDetOffsetMinMaxShader.Dispatch(floorDetOffsetMinMaxKernel, 1, 1, 1); //ofsHistMinMaxBuffer.GetData(histMinMax); //Debug.Log("Hist min: " + histMinMax[0] + ", max: " + histMinMax[1]); // FloorDetectionOffsetHistShader KinectInterop.SetComputeShaderInt2(floorDetOffsetHistShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight); //floorDetOffsetHistShader.SetInt("PointCloudOfsLength", sensorData.depthImageWidth * sensorData.depthImageHeight); floorDetOffsetHistShader.SetInt("OfsHistBinLength", histBufferLength); floorDetOffsetHistShader.SetFloat("BinSize", histBinSize); floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "PointCloudOfs", pointCloudOfsBuffer); floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "PointCloudMask", pointCloudMaskBuffer); floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsMinMax", ofsHistMinMaxBuffer); floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsHistBinCount", ofsHistBinCountBuffer); //floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsHistBinLeft", ofsHistBinLeftBuffer); floorDetOffsetHistShader.Dispatch(floorDetOffsetHistKernel, sensorData.depthImageWidth / 1, sensorData.depthImageHeight / 1, 1); //floorDetOffsetHistShader.Dispatch(floorDetOffsetHistKernel, 1, 1, 1); // FloorDetectionPlanePointsShader floorDetPlaneEstShader.SetInt("OfsHistBinLength", histBufferLength); floorDetPlaneEstShader.SetInt("PointCloudOfsLength", sensorData.depthImageWidth * sensorData.depthImageHeight); floorDetPlaneEstShader.SetFloat("BinSize", histBinSize); floorDetPlaneEstShader.SetInt("BinAggregation", binAggregation); floorDetPlaneEstShader.SetInt("MinimumFloorPointCount", minFloorPointCount / 4); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsHistBinCount", ofsHistBinCountBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudPos", pointCloudPosBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudOfs", pointCloudOfsBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudMask", pointCloudMaskBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsMinMax", ofsHistMinMaxBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsHistBinLeft", ofsHistBinLeftBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "HistCumulativeCount", histCumulativeCountBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "InlierIndices", planeIndicesBuffer); floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PlanePosNorm", planePosNormBuffer); floorDetPlaneEstShader.Dispatch(floorDetPlaneEstKernel, 1, 1, 1); // wait some frames before GetData() for (int i = 0; i < WAIT_FRAMES_BEFORE_GPUGET; i++) { yield return(null); } //uint[] histCumCount = new uint[histBufferLength]; //histCumulativeCountBuffer.GetData(histCumCount); //uint maxDiffCount = 0; //System.Text.StringBuilder sbCumCount = new System.Text.StringBuilder(); //for(int i = 1; (i + binAggregation) < histCumCount.Length; i++) // i += binAggregation //{ // uint diffCount = histCumCount[i + binAggregation - 1] - histCumCount[i - 1]; // if (maxDiffCount < diffCount) // maxDiffCount = diffCount; // if (diffCount > 0) // sbCumCount.Append(i).Append('-').Append(diffCount).Append(" "); //} //Debug.Log("histCumCount(" + maxDiffCount + "): " + sbCumCount); planePosNormBuffer.GetData(planePosNorm); vPlanePos = new Vector3(planePosNorm[0], planePosNorm[1], planePosNorm[2]); vPlaneNorm = new Vector3(planePosNorm[3], planePosNorm[4], planePosNorm[5]); //Vector3 vPlaneOfs = new Vector3(planePosNorm[6], planePosNorm[7], planePosNorm[8]); //Vector3 vPlaneOfs2 = new Vector3(planePosNorm[9], planePosNorm[10], planePosNorm[11]); bPlaneValid = (vPlaneNorm != Vector3.zero); if (bPlaneValid) { //Debug.Log("Plane pos: " + vPlanePos + ", norm: " + vPlaneNorm.normalized + ", rot: " + qSensorRot.eulerAngles + ", ofs: " + vPlaneOfs + ", ofs2: " + vPlaneOfs2); vPlaneNorm = vPlaneNorm.normalized; if (Vector3.Dot(vPlaneNorm, imuUpVector) < 0f) { vPlaneNorm = -vPlaneNorm; //Debug.Log("Inverted plane normal: " + vPlaneNorm); } float floorTiltInDeg = Mathf.Acos(Vector3.Dot(vPlaneNorm, imuUpVector)) * Mathf.Rad2Deg; if (floorTiltInDeg < planeMaxTiltInDeg) { // For reduced jitter, use gravity for floor normal. vPlaneNorm = imuUpVector; //Debug.Log("Used gravity for normal: " + vPlaneNorm + ", tiltAngle: " + floorTiltInDeg); } // get results float fCurTimeSecs = Time.time; bool bSmoothResult = (fCurTimeSecs - fLastTimeSecs) < SMOOTH_TIME_THRESHOLD; //Debug.Log("SmoothResult: " + bSmoothResult); fLastTimeSecs = fCurTimeSecs; vPlanePos = new Vector3(vPlanePos.x * spaceScale.x, vPlanePos.y * spaceScale.y, vPlanePos.z * spaceScale.z); vPlaneNorm = new Vector3(vPlaneNorm.x * spaceScale.x, vPlaneNorm.y * spaceScale.y, vPlaneNorm.z * spaceScale.z); Quaternion curSensorRot = Quaternion.FromToRotation(vPlaneNorm, Vector3.up); qSensorRot = bSmoothResult ? Quaternion.Slerp(qSensorRot, curSensorRot, smoothFactor * Time.deltaTime) : curSensorRot; floorPlane = new Plane(vPlaneNorm, vPlanePos); float curSensorHeight = floorPlane.GetDistanceToPoint(Vector3.zero); fSensorHeight = bSmoothResult ? Mathf.Lerp(fSensorHeight, curSensorHeight, smoothFactor * Time.deltaTime) : curSensorHeight; //Debug.Log("Floor pos: " + vPlanePos + ", norm: " + vPlaneNorm + ", rot: " + qSensorRot.eulerAngles + ", height: " + curSensorHeight + ", smoothed: " + fSensorHeight); } } }
private void Bake(AnimationClip[] clips) { if (!infoTexGen) { infoTexGen = (ComputeShader)Resources.Load("AnimationBaker/Shaders/MeshInfoTextureGen", typeof(ComputeShader)); } if (!playShader) { playShader = (Shader)Resources.Load("AnimationBaker/Shaders/LitBakedStatePlayer", typeof(Shader)); } AssetDatabase.SaveAssets(); var instance = Instantiate(graph.Prefab, Vector3.zero, Quaternion.identity); var instanceTransform = instance.transform; var skinRenderer = FindSkinnedMeshRenderer(instanceTransform); for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++) { var mat = skinRenderer.sharedMaterials[i]; var materialPath = outputPath + "/" + mat.name + ".mat"; if (File.Exists(materialPath)) { File.Delete(materialPath); } } var dataPathLength = Application.dataPath.Length - 6; var meshPath = outputPath + "/" + cleanName + "Mesh.asset"; if (File.Exists(meshPath)) { File.Delete(meshPath); } meshPath = meshPath.Substring(dataPathLength); var positionTexturePath = StringUtils.Combine(outputPath, "Positions.asset"); if (File.Exists(positionTexturePath)) { File.Delete(positionTexturePath); } positionTexturePath = positionTexturePath.Substring(dataPathLength); var normalTexturePath = StringUtils.Combine(outputPath, "Normals.asset"); if (File.Exists(normalTexturePath)) { File.Delete(normalTexturePath); } normalTexturePath = normalTexturePath.Substring(dataPathLength); var prefabPath = StringUtils.Combine(outputPath, cleanName + ".prefab"); if (File.Exists(prefabPath)) { File.Delete(prefabPath); } prefabPath = prefabPath.Substring(dataPathLength); AssetDatabase.Refresh(); var newAnimation = FindAnimation(instanceTransform); var boneMeshes = new List <MeshFilter>(); FindMeshInBones(boneMeshes, instanceTransform); var skinTransform = skinRenderer.transform; var oldMesh = skinRenderer.sharedMesh; Mesh newMesh = new Mesh(); var offset = PopulateMesh(newMesh, oldMesh, boneMeshes, skinRenderer.transform); var verticesCount = newMesh.vertexCount; // Save mesh AssetDatabase.CreateAsset(newMesh, meshPath); graph.rendererData.Mesh = newMesh; graph.rendererData.SubMeshCount = newMesh.subMeshCount; var scale = Vector3.one; scale.x = 1 / rootBone.localScale.x; scale.y = 1 / rootBone.localScale.y; scale.z = 1 / rootBone.localScale.z; var totalClips = 0; var frames = new List <int>(); var frameDeltas = new List <float>(); var totalFrames = 0; var finalClips = new List <AnimationClip>(); for (int i = 0; i < clips.Length; i++) { var clip = clips[i]; var delta = clip.frameRate * 0.001f; var frame = Mathf.CeilToInt(clip.length / delta); frames.Add(frame); frameDeltas.Add(delta); totalFrames += frame; totalClips++; finalClips.Add(clip); } // to store metadata totalFrames += 1; var texHeight = Mathf.NextPowerOfTwo(totalFrames); var texWidth = Mathf.NextPowerOfTwo(verticesCount); // store first cell: // total clips // second cell and beyond: // x: frame count // y: 1 / framerate // z: offset // w: wrap mode: // 0 play once the revert to default // 1 play once the revert to default // 2 loop // 4 not implemented // 8 play once then hold var infoList = new List <VertInfo>(); int texOffset = 1; // infoList.Add(new VertInfo { position = new Vector3(totalClips, 0, 0), normal = Vector3.zero }); for (int i = 0; i < frames.Count; i++) { infoList.Add(new VertInfo { position = new Vector3(frames[i], finalClips[i].length, texOffset), normal = Vector3.zero, extra = (int)finalClips[i].wrapMode }); texOffset += (int)frames[i]; } for (int i = totalClips; i < verticesCount; i++) { infoList.Add(new VertInfo { position = Vector3.zero, normal = Vector3.zero }); } var boneOffset = Vector3.zero; var boneScale = 0f; var animMesh = new Mesh(); for (int i = 0; i < finalClips.Count; i++) { var clip = finalClips[i]; var dt = 0f; var len = 0; while (dt < clip.length) { clip.SampleAnimation(instance, Mathf.Clamp(dt, 0, clip.length)); skinRenderer.BakeMesh(animMesh); if (boneScale == 0) { var bounds = new Bounds(); for (int j = 0; j < animMesh.vertexCount; j++) { var point = skinTransform.TransformPoint(animMesh.vertices[j]); if (j == 0) { bounds.center = point; } bounds.Encapsulate(point); } foreach (var filter in boneMeshes) { var boneMesh = filter.sharedMesh; for (int j = 0; j < boneMesh.vertexCount; j++) { var point = filter.transform.TransformPoint(boneMesh.vertices[j]); bounds.Encapsulate(point); } } boneScale = newMesh.bounds.size.y / bounds.size.y; boneOffset.y = 0 - bounds.min.y; } for (int j = 0; j < animMesh.vertexCount; j++) { var vert = (skinTransform.TransformPoint(animMesh.vertices[j]) + boneOffset) * boneScale; infoList.Add(new VertInfo { position = vert, normal = animMesh.normals[j], extra = 1 }); } foreach (var filter in boneMeshes) { var mesh = filter.sharedMesh; for (int k = 0; k < mesh.vertexCount; k++) { var vert = (filter.transform.TransformPoint(mesh.vertices[k]) + boneOffset) * boneScale; infoList.Add(new VertInfo { position = vert, normal = mesh.normals[k], extra = 1 }); } } len++; dt += frameDeltas[i]; } } var positionsRenderTexture = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf); var normalRenderTexture = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf); var positionTexture = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false); positionTexture.wrapMode = TextureWrapMode.Clamp; positionTexture.filterMode = FilterMode.Point; var normalTexture = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false); normalTexture.wrapMode = TextureWrapMode.Clamp; normalTexture.filterMode = FilterMode.Point; foreach (var rt in new [] { positionsRenderTexture, normalRenderTexture }) { rt.enableRandomWrite = true; rt.Create(); RenderTexture.active = rt; GL.Clear(true, true, Color.clear); } var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo))); buffer.SetData(infoList.ToArray()); var kernel = infoTexGen.FindKernel("CSMain"); uint x, y, z; infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z); infoTexGen.SetInt("VertCount", verticesCount); infoTexGen.SetBuffer(kernel, "Info", buffer); infoTexGen.SetTexture(kernel, "OutPosition", positionsRenderTexture); infoTexGen.SetTexture(kernel, "OutNormal", normalRenderTexture); infoTexGen.Dispatch(kernel, verticesCount / (int)x + 1, texHeight / (int)y + 1, 1); var posTex = RenderTextureToTexture2D.Convert(positionsRenderTexture); var normTex = RenderTextureToTexture2D.Convert(normalRenderTexture); Graphics.CopyTexture(posTex, positionTexture); Graphics.CopyTexture(normTex, normalTexture); positionsRenderTexture.Release(); normalRenderTexture.Release(); buffer.Release(); AssetDatabase.CreateAsset(positionTexture, positionTexturePath); AssetDatabase.CreateAsset(normalTexture, normalTexturePath); // var pngData = positionTexture.EncodeToPNG(); // System.IO.File.WriteAllBytes(Utils.Combine(outputPath, "DebugPositions.png"), pngData); AssetDatabase.Refresh(); var materials = new Material[skinRenderer.sharedMaterials.Length]; graph.rendererData.Materials = new Material[skinRenderer.sharedMaterials.Length]; graph.rendererData.ShadowCastingMode = skinRenderer.shadowCastingMode; graph.rendererData.ReceivesShadows = skinRenderer.receiveShadows; for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++) { var mat = new Material(playShader); mat.name = string.Format("{0}.{1}.Material", cleanName, i); mat.SetTexture("_MainTex", skinRenderer.sharedMaterials[i].mainTexture); mat.SetColor("_Color", skinRenderer.sharedMaterials[i].color); mat.SetTexture("_PosTex", positionTexture); mat.SetTexture("_NmlTex", normalTexture); mat.enableInstancing = true; var materialPath = outputPath + "/" + mat.name + ".mat"; materialPath = materialPath.Substring(dataPathLength); AssetDatabase.CreateAsset(mat, materialPath); materials[i] = mat; graph.rendererData.Materials[i] = mat; } var go = new GameObject(cleanName); go.AddComponent <MeshFilter>().sharedMesh = newMesh; AssetDatabase.Refresh(); var assembly = Assembly.GetAssembly(typeof(StateGraph)); var componentType = assembly.GetType("AnimationBaker.Baked." + cleanName + "Component"); go.AddComponent(componentType); var mr = go.AddComponent <MeshRenderer>(); mr.sharedMaterials = materials; mr.material = materials[0]; PrefabUtility.CreatePrefab(prefabPath, go); DestroyImmediate(go); DestroyImmediate(instance); EditorUtility.SetDirty(graph.rendererData); }
void Update() { if (_pointSource == null || _template == null || _material == null || _gradient == null) { return; } // Lazy initialization. if (_drawArgsBuffer == null) { // Initialize the indirect draw args buffer. _drawArgsBuffer = new ComputeBuffer( 1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments ); _drawArgsBuffer.SetData(new uint[5] { _template.GetIndexCount(0), (uint)InstanceCount, 0, 0, 0 }); // Allocate compute buffers. _positionBuffer = _pointSource.CreatePositionBuffer(); _normalBuffer = _pointSource.CreateNormalBuffer(); _tangentBuffer = _pointSource.CreateTangentBuffer(); _transformBuffer = new ComputeBuffer(TotalThreadCount * 3, 4 * 4); } // Use a cloned material to avoid issue 914787 ("Only one shadow is // cast when using Graphics.DrawMeshInstancedIndirect more than one // time per frame"). // FIXME: remove this when issue 914787 gets fixed. if (_tempMaterial == null) { _tempMaterial = new Material(_material); } else { _tempMaterial.CopyPropertiesFromMaterial(_material); } // Calculate the time-based parameters. var noiseOffset = Vector2.one * _randomSeed + _noiseSpeed * _time; var pulseTime = _pulseSpeed * _time + _randomSeed * 443; // Invoke the update compute kernel. var kernel = _compute.FindKernel("ClonerUpdate"); _compute.SetInt("InstanceCount", InstanceCount); _compute.SetInt("BufferStride", TotalThreadCount); _compute.SetFloat("PositionNoise", _displacementByNoise); _compute.SetFloat("NormalNoise", _rotationByNoise); _compute.SetFloat("BaseScale", _templateScale); _compute.SetFloat("ScaleNoise", _scaleByNoise); _compute.SetFloat("ScalePulse", _scaleByPulse); _compute.SetFloat("NoiseFrequency", _noiseFrequency); _compute.SetVector("NoiseOffset", noiseOffset); _compute.SetFloat("PulseProbability", _pulseProbability); _compute.SetFloat("PulseTime", pulseTime); _compute.SetBuffer(kernel, "PositionBuffer", _positionBuffer); _compute.SetBuffer(kernel, "NormalBuffer", _normalBuffer); _compute.SetBuffer(kernel, "TangentBuffer", _tangentBuffer); _compute.SetBuffer(kernel, "TransformBuffer", _transformBuffer); _compute.Dispatch(kernel, ThreadGroupCount, 1, 1); // Draw the template mesh with instancing. if (_props == null) { _props = new MaterialPropertyBlock(); } _props.SetVector("_GradientA", _gradient.coeffsA); _props.SetVector("_GradientB", _gradient.coeffsB); _props.SetVector("_GradientC", _gradient.coeffsC2); _props.SetVector("_GradientD", _gradient.coeffsD2); _props.SetMatrix("_LocalToWorld", transform.localToWorldMatrix); _props.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix); _props.SetBuffer("_TransformBuffer", _transformBuffer); _props.SetFloat("_BufferStride", TotalThreadCount); Graphics.DrawMeshInstancedIndirect( _template, 0, _tempMaterial, TransformedBounds, _drawArgsBuffer, 0, _props ); // Advance the time. if (!_timeControlled && Application.isPlaying) { _time += Time.deltaTime; } }
public IEnumerator InitModel() { RenTexture = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat) { enableRandomWrite = true, volumeDepth = N, dimension = UnityEngine.Rendering.TextureDimension.Tex3D, filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp }; RenTexture.Create(); Buffer = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat) { enableRandomWrite = true, volumeDepth = N, dimension = UnityEngine.Rendering.TextureDimension.Tex3D, filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp }; Buffer.Create(); Display = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat) { enableRandomWrite = true, volumeDepth = N, dimension = UnityEngine.Rendering.TextureDimension.Tex3D, filterMode = FilterMode, wrapMode = TextureWrapMode.Clamp }; Display.Create(); yield return(new WaitForSeconds(1)); PlaneMaterial.SetTexture("_MainTex", Display); PlaneMaterial.SetFloat("_MaxValue", StartPotential); var initKernelId = Init.FindKernel("CSMain"); Init.SetTexture(initKernelId, "_Result", RenTexture); Init.SetFloat("_InitialValue", StartPotential); Init.SetFloat("_NodesCount", N); mFigures = mTree.GetComponentsInChildren <Figure>(); mFiguresCount = mFigures.Length; //Init.SetInt("_MaxStep", mMaxSteps); //Init.SetFloat("_MaxDist", MaxDistance); Init.SetInt("_FiguresCount", mFiguresCount); mBuffer = new ComputeBuffer(mFiguresCount, 132); var data = mFigures.Select((x) => new ShaderFigure { Type = (int)x.Type, Matr = x.transform.worldToLocalMatrix, Params = x.Params }).ToArray(); mBuffer.SetData(data); Init.SetBuffer(initKernelId, "_Figures", mBuffer); var n4 = N / 4; Init.Dispatch(initKernelId, n4, n4, n4); //buffer.Dispose(); yield return(new WaitForSeconds(1)); mIterationKernelId = Iteraition.FindKernel("CSMain"); Iteraition.SetTexture(mIterationKernelId, "_Source", RenTexture); Iteraition.SetTexture(mIterationKernelId, "_Result", Buffer); mIterationHardKernelId = IterationHard.FindKernel("CSMain"); IterationHard.SetTexture(mIterationKernelId, "_Source", RenTexture); IterationHard.SetTexture(mIterationKernelId, "_Result", Buffer); IterationHard.SetFloat("_InitialValue", StartPotential); IterationHard.SetFloat("_NodesCount", N); IterationHard.SetInt("_MaxStep", MaxSteps); IterationHard.SetFloat("_Dist", 1f / (N - 1)); //IterationHard.SetFloat("_MaxDist", MaxDistance); IterationHard.SetInt("_FiguresCount", mFiguresCount); IterationHard.SetBuffer(mIterationHardKernelId, "_Figures", mBuffer); mCopyKernelId = Copy.FindKernel("CSMain"); Copy.SetTexture(mCopyKernelId, "_Source", Buffer); Copy.SetTexture(mCopyKernelId, "_Result", RenTexture); Copy.SetTexture(mCopyKernelId, "_ResultAbs", Display); yield return(new WaitForSeconds(1)); mCutFigure = Instantiate(mCutPrefab, mTree); mCutFigure.SetActive(Cut); mCutFigure.GetComponent <Synch>().From = mCutAnchor; mPlane.CanShow = true; mStart = true; yield break; }
public void BuildMesh(ref TrainerCritterBrushstrokeManager trainerCritterBrushstrokeManagerRef) { float startTime = Time.realtimeSinceStartup; // NOISE VOLUME! RenderTexture DensityVolume = new RenderTexture(16, 16, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.sRGB); DensityVolume.volumeDepth = 16; DensityVolume.isVolume = true; DensityVolume.enableRandomWrite = true; DensityVolume.filterMode = FilterMode.Bilinear; DensityVolume.wrapMode = TextureWrapMode.Repeat; DensityVolume.Create(); int mgen_id = CShaderSimplex.FindKernel("FillEmpty"); // uses renderTexture rather than StructuredBuffer? CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); // Links RenderTexture to the "Result" RWTexture in the compute shader? CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // run computeShader "FillEmpty" with 1 x 1 x 31 threadGroups? mgen_id = CShaderSimplex.FindKernel("Simplex3d"); CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // Fill shared RenderTexture with GPU simplex Noise ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4)); cBufferSegmentTransform.SetData(critterSegmentTransforms); int kernelID = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform); CShaderBuildMC.SetTexture(kernelID, "noise_volume", DensityVolume); // Noise 3D texture // Figure out how many chunks are needed: int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x / (cellResolution * 8f)); int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y / (cellResolution * 8f)); int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z / (cellResolution * 8f)); //Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")"); int totalNumChunks = numChunksX * numChunksY * numChunksZ; Poly[][] PolyArrayArray = new Poly[totalNumChunks][]; // This will hold the mesh data from the chunks calculated on the GPU int[] numPolysArray = new int[totalNumChunks]; int totalNumPolys = 0; // Get each chunk! int chunkIndex = 0; for (int x = 0; x < numChunksX; x++) { for (int y = 0; y < numChunksY; y++) { for (int z = 0; z < numChunksZ; z++) { // Figure out chunk offset amount: Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z) + GlobalBoundingBoxOffset - (GlobalBoundingBoxDimensions / 2f); int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x); CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y); CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z); CShaderBuildMC.SetFloat("_CellSize", cellResolution); CShaderBuildMC.SetVector("_ColorPrimary", colorPrimary); CShaderBuildMC.SetVector("_ColorSecondary", colorSecondary); CShaderBuildMC.SetFloat("_ColorNoiseScale", colorNoiseScale); CShaderBuildMC.SetFloat("_ColorSmlAmplitude", colorSmlAmplitude); CShaderBuildMC.SetFloat("_ColorMedAmplitude", colorMedAmplitude); CShaderBuildMC.SetFloat("_ColorLrgAmplitude", colorLrgAmplitude); CShaderBuildMC.SetFloat("_ColorContrast", colorContrast); CShaderBuildMC.SetFloat("_ColorThreshold", colorThreshold); CShaderBuildMC.SetVector("_SkinNoiseScale", skinNoiseScale); CShaderBuildMC.SetFloat("_SkinNoiseAmplitude", skinNoiseAmplitude); CShaderBuildMC.SetVector("_SkinLocalTaper", skinLocalTaper); CShaderBuildMC.SetVector("_SkinLocalSinFreq", skinLocalSinFreq); CShaderBuildMC.SetVector("_SkinLocalSinAmp", skinLocalSinAmp); // Local Segment-space modifications, sin, taper, etc. CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys //Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkOffset: " + chunkOffset.ToString()); totalNumPolys += numPolys[0]; numPolysArray[chunkIndex] = numPolys[0]; if (numPolys[0] > 0) // only do this if there was at least 1 triangle in the test pass { Poly[] polyArray = new Poly[numPolys[0]]; int cBufferStride = sizeof(float) * (18 + 9 + 6) + sizeof(int) * (6); ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], cBufferStride); // 18 floats x 4 bytes/float = 72 + COLORS! 9 x 4 = 36 = 108 + BONES! 6x4 = 24 + 6 xint... cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU PolyArrayArray[chunkIndex] = polyArray; cBuffer.Dispose(); } cBufferNumPoly.Dispose(); chunkIndex++; } } } // OLD: // CritterDecorationsTest.decorationStruct[] points = new CritterDecorationsTest.decorationStruct[totalNumPolys]; critterPointsDataArray = new TrainerRenderManager.strokeStruct[totalNumPolys]; // first try brushstrokes //Construct mesh using received data int vindex = 0; int decindex = 0; // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[totalNumPolys * 3]; Color[] colors = new Color[totalNumPolys * 3]; int[] tris = new int[totalNumPolys * 3]; Vector2[] uvs = new Vector2[totalNumPolys * 3]; Vector3[] normals = new Vector3[totalNumPolys * 3]; BoneWeight[] weights = new BoneWeight[totalNumPolys * 3]; //Parse triangles for (int i = 0; i < PolyArrayArray.Length; i++) { if (numPolysArray[i] > 0) // only do this if there was at least 1 triangle in the test pass { for (int ix = 0; ix < numPolysArray[i]; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CAR, PolyArrayArray[i][ix].CAG, PolyArrayArray[i][ix].CAB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexA0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexA1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightA0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightA1; critterPointsDataArray[decindex].pos = vPos; critterPointsDataArray[decindex].col = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b); critterPointsDataArray[decindex].normal = normals[vindex]; //critterPointsDataArray[decindex].tangent = ; // Tangent is calculated during initial Skinning (when determining weights) critterPointsDataArray[decindex].prevPos = vPos; critterPointsDataArray[decindex].dimensions = new Vector2(1f, 1f); critterPointsDataArray[decindex].brushType = 0; // default // OLD: //points[decindex].pos = vPos; //points[decindex].normal = normals[vindex]; //points[decindex].color = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b); decindex++; vindex++; //B1,B2,B3 vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CBR, PolyArrayArray[i][ix].CBG, PolyArrayArray[i][ix].CBB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexB0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexB1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightB0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightB1; vindex++; //C1,C2,C3 vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CCR, PolyArrayArray[i][ix].CCG, PolyArrayArray[i][ix].CCB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexC0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexC1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightC0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightC1; vindex++; } } } //We have got all data and are ready to setup a new mesh! if (critterMesh == null) { critterMesh = new Mesh(); } else { critterMesh.Clear(); } //Mesh newMesh = new Mesh(); critterMesh.vertices = vertices; critterMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); critterMesh.triangles = tris; critterMesh.normals = normals; //NewMesh.RecalculateNormals(); critterMesh.colors = colors; critterMesh.Optimize(); // Set up SKINNING!!!: Transform[] bones = new Transform[critter.critterSegmentList.Count]; Matrix4x4[] bindPoses = new Matrix4x4[critter.critterSegmentList.Count]; // Try just using existing critter's GameObjects/Transforms: for (int seg = 0; seg < critter.critterSegmentList.Count; seg++) { bones[seg] = critter.critterSegmentList[seg].transform; bindPoses[seg] = bones[seg].worldToLocalMatrix * transform.localToWorldMatrix; // ????????????????? // the bind pose is the inverse of inverse transformation matrix of the bone, when the bone is in the bind pose .... unhelpful .... } critterMesh.boneWeights = weights; critterMesh.bindposes = bindPoses; SkinnedMeshRenderer skinnedMeshRenderer = this.GetComponent <SkinnedMeshRenderer>(); skinnedMeshRenderer.bones = bones; skinnedMeshRenderer.sharedMesh = critterMesh; skinnedMeshRenderer.enabled = true; skinnedMeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly; cBufferSegmentTransform.Release(); trainerCritterBrushstrokeManagerRef.TurnOn(critterPointsDataArray); // Initializes Buffers for Brushstroke //critterPointsBuffer = new ComputeBuffer(critterPointsDataArray.Length, sizeof(float) * 3); //critterPointsBuffer.SetData(critterPointsDataArray); //Debug.Log("BuildMesh count: " + critterPointsDataArray.Length.ToString() + ", 0: " + critterPointsDataArray[0].pos.ToString() + ", 500: " + critterPointsDataArray[500].pos.ToString()); // OLD: //critterDecorationsTest.TurnOn(points); float calcTime = Time.realtimeSinceStartup - startTime; //Debug.Log("MeshCreated! " + calcTime.ToString()); HideSegmentCubes(); }
public void SetParameters(ComputeShader cs, AtmosphereParameters AP) { if (cs == null) { return; } cs.SetFloat("Rg", AP.bRg); cs.SetFloat("Rt", AP.bRt); cs.SetFloat("RL", AP.bRl); cs.SetInt("TRANSMITTANCE_W", AtmosphereConstants.TRANSMITTANCE_W); cs.SetInt("TRANSMITTANCE_H", AtmosphereConstants.TRANSMITTANCE_H); cs.SetInt("SKY_W", AtmosphereConstants.SKY_W); cs.SetInt("SKY_H", AtmosphereConstants.SKY_H); cs.SetInt("RES_R", AtmosphereConstants.RES_R); cs.SetInt("RES_MU", AtmosphereConstants.RES_MU); cs.SetInt("RES_MU_S", AtmosphereConstants.RES_MU_S); cs.SetInt("RES_NU", AtmosphereConstants.RES_NU); cs.SetFloat("AVERAGE_GROUND_REFLECTANCE", AP.AVERAGE_GROUND_REFLECTANCE); cs.SetFloat("HR", AP.HR); cs.SetFloat("HM", AP.HM); cs.SetInt("TRANSMITTANCE_INTEGRAL_SAMPLES", AtmosphereConstants.TRANSMITTANCE_INTEGRAL_SAMPLES); cs.SetInt("INSCATTER_INTEGRAL_SAMPLES", AtmosphereConstants.INSCATTER_INTEGRAL_SAMPLES); cs.SetInt("IRRADIANCE_INTEGRAL_SAMPLES", AtmosphereConstants.IRRADIANCE_INTEGRAL_SAMPLES); cs.SetInt("IRRADIANCE_INTEGRAL_SAMPLES_HALF", AtmosphereConstants.IRRADIANCE_INTEGRAL_SAMPLES_HALF); cs.SetInt("INSCATTER_SPHERICAL_INTEGRAL_SAMPLES", AtmosphereConstants.INSCATTER_SPHERICAL_INTEGRAL_SAMPLES); cs.SetVector("betaR", AP.BETA_R); cs.SetVector("betaMSca", AP.BETA_MSca); cs.SetVector("betaMEx", AP.BETA_MEx); cs.SetFloat("mieG", Mathf.Clamp(AP.MIE_G, 0.0f, 0.99f)); }
void FixedUpdate() { //output.Release(); //output.Create(); ComputeVoxels.SetTexture(0, "_Result", output); ComputeVoxels.Dispatch(0, GridSize / ThreadCount, GridSize / ThreadCount, GridSize / ThreadCount); Collider[] cols = Physics.OverlapBox(transform.position, transform.lossyScale * 0.5f, transform.rotation); foreach (Collider c in cols) { Mesh m = c.GetComponent <MeshFilter>().mesh; if (m == null) { return; } /* Vector3 scale = new Vector3(transform.localScale.x / GridSize, transform.localScale.y / GridSize, transform.localScale.z / GridSize); * Matrix4x4 sim2world = Matrix4x4.TRS(transform.position + new Vector3(-.5f * GridSize * scale.x, -.5f * GridSize * scale.y, -.5f * GridSize * scale.z), Quaternion.identity, scale); * Matrix4x4 world2sim = sim2world.inverse; * * Vector3 min = world2sim.MultiplyPoint(c.bounds.min); * Vector3 max = world2sim.MultiplyPoint(c.bounds.max); * * Vector3Int offset; * Vector3Int ilength; * * offset = new Vector3Int(Mathf.FloorToInt(Mathf.Clamp(min.x, 0, GridSize)), Mathf.FloorToInt(Mathf.Clamp(min.y, 0, GridSize)), Mathf.FloorToInt(Mathf.Clamp(min.z, 0, GridSize))); * * ilength = new Vector3Int(Mathf.CeilToInt(max.x - min.x), Mathf.CeilToInt(max.y - min.y), Mathf.CeilToInt(max.z - min.z)); * ilength.x = Mathf.Max(GetNearPow2(ilength.x), ThreadCount); * ilength.y = Mathf.Max(GetNearPow2(ilength.y), ThreadCount); * ilength.z = Mathf.Max(GetNearPow2(ilength.z), ThreadCount); * * Vector3[] vertices = m.vertices; * int[] triangles = m.triangles; * * Rigidbody rb = c.GetComponent<Rigidbody>(); * Vector3 vel = rb != null ? rb.velocity : Vector3.zero; * * ComputeBuffer input_verts = new ComputeBuffer(vertices.Length, sizeof(float) * 3); * ComputeBuffer input_tris = new ComputeBuffer(triangles.Length, sizeof(int)); * * input_verts.SetData(vertices); * input_tris.SetData(triangles); * * ComputeVoxels.SetInt("_NumTriangles", triangles.Length); * ComputeVoxels.SetVector("_Offset", new Vector3(offset.x, offset.y, offset.z)); * * ComputeVoxels.SetMatrix("_Sim2WorldMat", sim2world); * ComputeVoxels.SetMatrix("_Obj2WorldMat", c.transform.localToWorldMatrix); * * ComputeVoxels.SetBuffer(0, "_Vertices", input_verts); * ComputeVoxels.SetBuffer(0, "_Triangles", input_tris); * ComputeVoxels.SetTexture(0, "_Result", output); * * ComputeVoxels.Dispatch(0, ilength.x / ThreadCount, ilength.y / ThreadCount, ilength.z / ThreadCount); * * DebugMaterial.SetTexture("_Voxels", output); * * input_verts.Release(); * input_tris.Release();*/ Vector3 scale = new Vector3(transform.localScale.x / GridSize, transform.localScale.y / GridSize, transform.localScale.z / GridSize); Matrix4x4 sim2world = Matrix4x4.TRS(transform.position + new Vector3(-.5f * GridSize * scale.x, -.5f * GridSize * scale.y, -.5f * GridSize * scale.z), Quaternion.identity, scale); Matrix4x4 world2sim = sim2world.inverse; int num_triangles = m.triangles.Length / 3; Vector3[] vertices = m.vertices; int[] triangles = m.triangles; ComputeBuffer input_verts = new ComputeBuffer(vertices.Length, sizeof(float) * 3); ComputeBuffer input_tris = new ComputeBuffer(triangles.Length, sizeof(int)); input_verts.SetData(vertices); input_tris.SetData(triangles); ComputeVoxels.SetInt("_NumTriangles", num_triangles); ComputeVoxels.SetMatrix("_Sim2WorldMat", world2sim); ComputeVoxels.SetMatrix("_Obj2WorldMat", c.transform.localToWorldMatrix); ComputeVoxels.SetBuffer(1, "_Vertices", input_verts); ComputeVoxels.SetBuffer(1, "_Triangles", input_tris); ComputeVoxels.SetTexture(1, "_Result", output); ComputeVoxels.Dispatch(1, num_triangles / 8 + 1, 1, 1); DebugMaterial.SetTexture("_Voxels", output); input_verts.Release(); input_tris.Release(); } }
void Start() { // Grab phosphor manager phosphorManager = FindObjectOfType <PhosphorManager>(); // Grab chat chat = FindObjectOfType <Chat>(); // Create Kernels and Material KernelMain = computeShader.FindKernel("KMain"); KInit = computeShader.FindKernel("KInit"); KSpawn = computeShader.FindKernel("KSpawn"); KInstantiate = computeShader.FindKernel("KInstantiate"); KPhosphorFeed = computeShader.FindKernel("KPhosphorFeed"); KReturn = computeShader.FindKernel("KReturn"); triMaterial = new Material(triShader); /// // Create Buffers // Agent Buffers agentBuffer0 = new ComputeBuffer(maxAgents, AgentData.size); agentBuffer1 = new ComputeBuffer(maxAgents, AgentData.size); // Spawn Buffer spawnBuffer = new ComputeBuffer(BLOCK_SIZE * spawnerBlockCount, AgentData.size); spawningAgents = new List <AgentData>(BLOCK_SIZE * spawnerBlockCount); // Free Buffer freeBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append); freeBuffer.ClearAppendBuffer(); // Triangle Instance Buffer agentInstanceBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append); agentInstanceBuffer.ClearAppendBuffer(); // Args Buffer agentCountArgBuffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.DrawIndirect); int[] dArgs = new int[] { 0, 1, 0, 0 }; agentCountArgBuffer.SetData(dArgs); // Targets Buffer targetsBuffer = new ComputeBuffer(phosphorManager.phosphorsToSpawn + 1, sizeof(float) * 4); targetsArray = new Vector4[phosphorManager.phosphorsToSpawn + 1]; // Set home target end of array to zero targetsArray[phosphorManager.phosphorsToSpawn] = Vector4.zero; // Return Buffer... awful way to do this? returnBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append); returnIds = new int[maxAgents]; returnBuffer.ClearAppendBuffer(); // Run init shader on initial buffer computeShader.SetBuffer(KInit, "appendFreeBuffer", freeBuffer); computeShader.SetBuffer(KInit, "agentBufferOut", agentBuffer0); computeShader.Dispatch(KInit, maxAgents / BLOCK_SIZE, 1, 1); // Init constant uniforms computeShader.SetInt("maxAgents", maxAgents); computeShader.SetInt("maxPhosphors", phosphorManager.phosphorsToSpawn); }
public ColumnResult Generate(int Y_Min, int Y_Max, int xStart, int zStart) { Stopwatch watch_overall = new Stopwatch(); watch_overall.Start(); Stopwatch watch = new Stopwatch(); watch.Start(); Sampler.ComputeNoiseGrid(Y_Min, Y_Max, xStart, zStart); watch.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): ComputeNoiseGrid: {0}", watch.Elapsed); int y_height = (Y_Max - Y_Min) + 2; watch.Restart(); int[] args = new int[] { 0, 1, 0, 0 }; ComputeBuffer argBuffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments); argBuffer.SetData(args); Data = new ComputeBuffer(Sampler.iso_type_buffer.count, sizeof(int), ComputeBufferType.Append); Data_DEBUG = new ComputeBuffer(Sampler.iso_type_buffer.count, sizeof(float) * 2, ComputeBufferType.Append); Data.SetCounterValue(0); Data_DEBUG.SetCounterValue(0); shader.SetBuffer(CS_Generate, "HeightMap", Sampler.height_buffer); shader.SetBuffer(CS_Generate, "ISO_Type_Map", Sampler.iso_type_buffer); shader.SetBuffer(CS_Generate, "Data", Data); shader.SetBuffer(CS_Generate, "Data_DEBUG", Data_DEBUG); watch.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Init buffers: {0}", watch.Elapsed); watch.Restart(); shader.SetInt("Y_Min", Y_Min); shader.SetInt("Y_Max", Y_Max); shader.SetInt("xStart", xStart); shader.SetInt("zStart", zStart); shader.SetInt("y_height", y_height); watch.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Init shader globals: {0}", watch.Elapsed); watch.Restart(); //Debug.LogFormat("GPU Generate: {0} x {1} x {2}", ChunkSizeX, y_height, ChunkSizeZ); shader.Dispatch(CS_Generate, ChunkSizeX / 6, y_height - 1, ChunkSizeZ / 6); watch.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Dispatch: {0}", watch.Elapsed); watch.Restart(); ComputeBuffer.CopyCount(Data, argBuffer, 0); argBuffer.GetData(args); Result.surfaceBlocksCount = args[0]; Result.surfaceBlocks = new uint[Result.surfaceBlocksCount]; Data.GetData(Result.surfaceBlocks); watch.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Get surfaceBlocks: {0}", watch.Elapsed); watch.Restart(); Debug_Data_Res[] debug_data = new Debug_Data_Res[0]; if (true) { debug_data = new Debug_Data_Res[Result.surfaceBlocksCount]; Data_DEBUG.GetData(debug_data); } watch.Stop(); watch_overall.Stop(); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Get debug_data: {0}", watch.Elapsed); UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Overall: {0}", watch_overall.Elapsed); Data.Dispose(); Data_DEBUG.Dispose(); Sampler.Dispose_ISO_Types(); for (int i = 0; i < debug_data.Length; i++) { Vector3Int p1 = debug_data[i].p1; Vector3Int p2 = debug_data[i].p2; Vector3 orig = new Vector3(p2.x, p2.y, p2.z); Vector3 other = new Vector3(p1.x, p1.y, p1.z); UnityEngine.Debug.DrawLine(orig, other, UnityEngine.Color.red, 50000); } return(Result); }
void PrintCubemap() { float3[][] forwd = new float3[6][]; for (int i = 0; i < 6; ++i) { forwd[i] = new float3[4]; } //Forward forwd[4][0] = normalize(float3(-1, 1, 1)); forwd[4][1] = normalize(float3(1, 1, 1)); forwd[4][2] = normalize(float3(-1, -1, 1)); forwd[4][3] = normalize(float3(1, -1, 1)); //Left forwd[1][0] = normalize(float3(-1, 1, -1)); forwd[1][1] = normalize(float3(-1, 1, 1)); forwd[1][2] = normalize(float3(-1, -1, -1)); forwd[1][3] = normalize(float3(-1, -1, 1)); //Back forwd[5][0] = normalize(float3(1, 1, -1)); forwd[5][1] = normalize(float3(-1, 1, -1)); forwd[5][2] = normalize(float3(1, -1, -1)); forwd[5][3] = normalize(float3(-1, -1, -1)); //Right forwd[0][0] = normalize(float3(1, 1, 1)); forwd[0][1] = normalize(float3(1, 1, -1)); forwd[0][2] = normalize(float3(1, -1, 1)); forwd[0][3] = normalize(float3(1, -1, -1)); //up forwd[2][0] = normalize(float3(-1, 1, -1)); forwd[2][1] = normalize(float3(1, 1, -1)); forwd[2][2] = normalize(float3(-1, 1, 1)); forwd[2][3] = normalize(float3(1, 1, 1)); //down forwd[3][0] = normalize(float3(-1, -1, 1)); forwd[3][1] = normalize(float3(1, -1, 1)); forwd[3][2] = normalize(float3(-1, -1, -1)); forwd[3][3] = normalize(float3(1, -1, -1)); uint2 size = uint2(max((uint)texture.width, 1024), max((uint)texture.height, 1024)); ComputeBuffer cb = new ComputeBuffer((int)size.x * (int)size.y, sizeof(float4), ComputeBufferType.Default); int mipCount = useMipMap ? (int)(log2(size.x / 16) + 0.1) : 1; TextureData data = new TextureData { depth = 6, width = size.x, height = size.y, mipCount = (uint)mipCount, format = TextureData.LoadFormat.LoadFormat_RGBAFloat16, textureType = TextureType.Cubemap }; readCS.SetTexture(0, "_MainTex", texture); readCS.SetBuffer(0, "_ResultBuffer", cb); float4[] readbackValues = new float4[size.x * size.y]; NativeList <byte> lst = new NativeList <byte>((int)(size.x * size.y * 1.4), Unity.Collections.Allocator.Temp); byte * headerPtr = (byte *)data.Ptr(); for (int i = 0; i < sizeof(TextureData); ++i) { lst.Add(headerPtr[i]); } Vector4[] setterArray = new Vector4[4]; for (int face = 0; face < 6; ++face) { size = uint2(max((uint)texture.width, 1024), max((uint)texture.height, 1024)); for (int i = 0; i < mipCount; ++i) { readCS.SetInt("_TargetMipLevel", i); readCS.SetInt("_Count", (int)size.x); for (int j = 0; j < 4; ++j) { setterArray[j] = (Vector3)forwd[face][j]; } readCS.SetVectorArray("_Directions", setterArray); readCS.Dispatch(0, max(1, Mathf.CeilToInt(size.x / 8f)), max(1, Mathf.CeilToInt(size.y / 8f)), 1); int cum = (int)(size.x * size.y); cb.GetData(readbackValues, 0, 0, cum); int pixelSize = 0; if (isCubemapCompress) { pixelSize = 1; NativeArray <byte> compressedData = new NativeArray <byte>(cum, Allocator.Temp, NativeArrayOptions.UninitializedMemory); BC6UHCompressJob job; job.dest = (uint4 *)compressedData.GetUnsafePtr(); job.source = readbackValues.Ptr(); job.width = (int)size.x; JobHandle handle = job.Schedule((cum / 16), max((cum / 16) / 20, 1)); handle.Complete(); for (int a = 0; a < compressedData.Length; ++a) { lst.Add(compressedData[a]); } } else { pixelSize = sizeof(half4); for (int j = 0; j < cum; ++j) { half4 hlfResult = (half4)readbackValues[j]; byte *b = (byte *)hlfResult.Ptr(); for (int z = 0; z < sizeof(half4); ++z) { lst.Add(b[z]); } } } for (int j = cum * pixelSize; j < 512; ++j) { lst.Add(0); } size /= 2; size = max(size, 1); } } byte[] finalArray = new byte[lst.Length]; UnsafeUtility.MemCpy(finalArray.Ptr(), lst.unsafePtr, lst.Length); using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write)) { fs.Write(finalArray, 0, lst.Length); } }
private static bool CaptureViews( Transform root, BillboardImposter imposter, Snapshots[] snapshots, Transform lightingRoot, Shader albedoBake, Shader normalBake, ComputeShader processCompute) { Vector3 originalScale = root.localScale; root.localScale = Vector3.one; var prevRt = RenderTexture.active; var baseAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); baseAtlas.enableRandomWrite = true; baseAtlas.Create(); var packAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); packAtlas.enableRandomWrite = true; packAtlas.Create(); var tempAtlas = RenderTexture.GetTemporary(baseAtlas.descriptor); tempAtlas.Create(); var frameReso = _atlasResolution / imposter.Frames; var frame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); frame.enableRandomWrite = true; frame.Create(); var packFrame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); packFrame.Create(); var tempFrame = RenderTexture.GetTemporary(frame.descriptor); tempFrame.Create(); var frameResUpscale = frameReso * 4; var superSizedFrame = RenderTexture.GetTemporary(frameResUpscale, frameResUpscale, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); superSizedFrame.enableRandomWrite = true; superSizedFrame.Create(); var superSizedFrameTemp = RenderTexture.GetTemporary(superSizedFrame.descriptor); var superSizedAlphaMask = RenderTexture.GetTemporary(superSizedFrame.descriptor); superSizedAlphaMask.Create(); imposter.BaseTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true); imposter.PackTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true); ComputeBuffer minDistancesBuffer = new ComputeBuffer(frame.width * frame.height, sizeof(float)); ComputeBuffer maxDistanceBuffer = new ComputeBuffer(1, sizeof(float)); const int layer = 30; var clearColor = Color.clear; var camera = new GameObject().AddComponent <Camera>(); camera.gameObject.hideFlags = HideFlags.DontSave; camera.cullingMask = 1 << layer; camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = clearColor; camera.orthographic = true; camera.nearClipPlane = 0f; camera.farClipPlane = imposter.Radius * 2f; camera.orthographicSize = imposter.Radius; camera.allowMSAA = false; camera.enabled = false; var frameCount = imposter.Frames * imposter.Frames; var originalLayers = new Dictionary <GameObject, int>(); StoreLayers(root, layer, ref originalLayers); var originalLights = new Dictionary <Light, bool>(); var customLit = lightingRoot != null; if (customLit) { var lights = FindObjectsOfType <Light>(); for (var i = 0; i < lights.Length; i++) { if (!lights[i].transform.IsChildOf(lightingRoot)) { if (originalLights.ContainsKey(lights[i])) { continue; } originalLights.Add(lights[i], lights[i].enabled); lights[i].enabled = false; } else { lights[i].enabled = true; if (!originalLights.ContainsKey(lights[i])) { originalLights.Add(lights[i], false); } } } } var tempMinMaxRT = RenderTexture.GetTemporary(frame.width, frame.height, 0, RenderTextureFormat.ARGB32); tempMinMaxRT.Create(); Graphics.SetRenderTarget(tempMinMaxRT); GL.Clear(true, true, Color.clear); camera.clearFlags = CameraClearFlags.Nothing; camera.backgroundColor = clearColor; camera.targetTexture = tempMinMaxRT; var min = Vector2.one * frame.width; var max = Vector2.zero; for (var i = 0; i < frameCount; i++) { if (i > snapshots.Length - 1) { Debug.LogError("[Imposter] snapshot data length less than frame count! this shouldn't happen!"); continue; } //position camera with the current snapshot info var snap = snapshots[i]; camera.transform.position = snap.Position; camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up); //render alpha only Shader.SetGlobalFloat("_ImposterRenderAlpha", 1f); camera.RenderWithShader(albedoBake, ""); camera.ResetReplacementShader(); //render without clearing (accumulating filled pixels) camera.Render(); //supply the root position taken into camera space //this is for the min max, in the case root is further from opaque pixels var viewPos = camera.WorldToViewportPoint(root.position); var texPos = new Vector2(viewPos.x, viewPos.y) * frame.width; texPos.x = Mathf.Clamp(texPos.x, 0f, frame.width); texPos.y = Mathf.Clamp(texPos.y, 0f, frame.width); min.x = Mathf.Min(min.x, texPos.x); min.y = Mathf.Min(min.y, texPos.y); max.x = Mathf.Max(max.x, texPos.x); max.y = Mathf.Max(max.y, texPos.y); } camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = clearColor; camera.targetTexture = null; //now read render texture var tempMinMaxTex = new Texture2D(tempMinMaxRT.width, tempMinMaxRT.height, TextureFormat.ARGB32, false); RenderTexture.active = tempMinMaxRT; tempMinMaxTex.ReadPixels(new Rect(0f, 0f, tempMinMaxRT.width, tempMinMaxRT.height), 0, 0); tempMinMaxTex.Apply(); var tempTexC = tempMinMaxTex.GetPixels32(); //loop pixels get min max for (var c = 0; c < tempTexC.Length; c++) { if (tempTexC[c].r != 0x00) { var texPos = Get2DIndex(c, tempMinMaxRT.width); min.x = Mathf.Min(min.x, texPos.x); min.y = Mathf.Min(min.y, texPos.y); max.x = Mathf.Max(max.x, texPos.x); max.y = Mathf.Max(max.y, texPos.y); } } DestroyImmediate(tempMinMaxTex, true); RenderTexture.ReleaseTemporary(tempMinMaxRT); //rescale radius var len = new Vector2(max.x - min.x, max.y - min.y); var maxR = Mathf.Max(len.x, len.y); var ratio = maxR / frame.width; imposter.Radius = imposter.Radius * ratio; camera.farClipPlane = imposter.Radius * 2f; camera.orthographicSize = imposter.Radius; Vector3 scaleFactor = new Vector3(root.localScale.x / originalScale.x, root.localScale.y / originalScale.y, root.localScale.z / originalScale.z); imposter.Offset = Vector3.Scale(imposter.Offset, scaleFactor); snapshots = UpdateSnapshots(imposter.Frames, imposter.Radius, root.position + imposter.Offset, imposter.IsHalf); for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { if (frameIndex > snapshots.Length - 1) { Debug.LogError("[Imposter] snapshot data length less than frame count! this shouldn't happen!"); continue; } var snap = snapshots[frameIndex]; camera.transform.position = snap.Position; camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up); clearColor = Color.clear; //target and clear base frame Graphics.SetRenderTarget(superSizedFrame); GL.Clear(true, true, clearColor); Graphics.SetRenderTarget(superSizedFrameTemp); GL.Clear(true, true, clearColor); camera.targetTexture = superSizedFrameTemp; camera.backgroundColor = clearColor; if (!customLit) { Shader.SetGlobalFloat("_ImposterRenderAlpha", 0f); camera.RenderWithShader(albedoBake, ""); camera.ResetReplacementShader(); } else { camera.Render(); } camera.targetTexture = superSizedAlphaMask; camera.backgroundColor = clearColor; camera.Render(); Graphics.Blit(superSizedAlphaMask, superSizedFrame, _processingMat, 3); Graphics.Blit(superSizedFrame, superSizedAlphaMask); _processingMat.SetTexture("_MainTex", superSizedFrameTemp); _processingMat.SetTexture("_MainTex2", superSizedAlphaMask); _processingMat.SetFloat("_Step", 1f); Graphics.Blit(superSizedFrameTemp, superSizedFrame, _processingMat, 1); Graphics.SetRenderTarget(frame); GL.Clear(true, true, clearColor); Graphics.Blit(superSizedFrame, frame); Graphics.SetRenderTarget(superSizedFrameTemp); GL.Clear(true, true, clearColor); Graphics.SetRenderTarget(superSizedFrame); GL.Clear(true, true, clearColor); clearColor = new Color(0.0f, 0.0f, 0.0f, 0.5f); camera.targetTexture = superSizedFrame; camera.backgroundColor = clearColor; camera.RenderWithShader(normalBake, ""); camera.ResetReplacementShader(); Graphics.SetRenderTarget(packFrame); GL.Clear(true, true, clearColor); Graphics.Blit(superSizedFrame, packFrame); Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); int threadsX, threadsY, threadsZ; CalcWorkSize(packFrame.width * packFrame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(0, "Source", packFrame); processCompute.SetTexture(0, "SourceMask", frame); processCompute.SetTexture(0, "Result", tempFrame); processCompute.SetBool("AllChannels", true); processCompute.SetBool("NormalsDepth", true); processCompute.Dispatch(0, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, packFrame); Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(0, "Source", frame); processCompute.SetTexture(0, "SourceMask", frame); processCompute.SetTexture(0, "Result", tempFrame); processCompute.SetBool("AllChannels", false); processCompute.SetBool("NormalsDepth", false); processCompute.Dispatch(0, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, frame); Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(1, "Source", frame); processCompute.SetTexture(1, "SourceMask", frame); processCompute.SetBuffer(1, "MinDistances", minDistancesBuffer); processCompute.Dispatch(1, threadsX, threadsY, threadsZ); processCompute.SetInt("MinDistancesLength", minDistancesBuffer.count); processCompute.SetBuffer(2, "MaxOfMinDistances", maxDistanceBuffer); processCompute.SetBuffer(2, "MinDistances", minDistancesBuffer); processCompute.Dispatch(2, 1, 1, 1); CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(3, "Source", frame); processCompute.SetTexture(3, "SourceMask", frame); processCompute.SetTexture(3, "Result", tempFrame); processCompute.SetBuffer(3, "MinDistances", minDistancesBuffer); processCompute.SetBuffer(3, "MaxOfMinDistances", maxDistanceBuffer); processCompute.Dispatch(3, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, frame); int x; int y; XYFromIndex(frameIndex, imposter.Frames, out x, out y); x *= frame.width; y *= frame.height; Graphics.CopyTexture(frame, 0, 0, 0, 0, frame.width, frame.height, baseAtlas, 0, 0, x, y); Graphics.CopyTexture(packFrame, 0, 0, 0, 0, packFrame.width, packFrame.height, packAtlas, 0, 0, x, y); } Graphics.SetRenderTarget(packAtlas); imposter.PackTexture.ReadPixels(new Rect(0f, 0f, packAtlas.width, packAtlas.height), 0, 0); Graphics.SetRenderTarget(baseAtlas); imposter.BaseTexture.ReadPixels(new Rect(0f, 0f, baseAtlas.width, baseAtlas.height), 0, 0); RenderTexture.active = prevRt; baseAtlas.Release(); frame.Release(); packAtlas.Release(); packFrame.Release(); RenderTexture.ReleaseTemporary(baseAtlas); RenderTexture.ReleaseTemporary(packAtlas); RenderTexture.ReleaseTemporary(tempAtlas); RenderTexture.ReleaseTemporary(frame); RenderTexture.ReleaseTemporary(packFrame); RenderTexture.ReleaseTemporary(tempFrame); RenderTexture.ReleaseTemporary(superSizedFrame); RenderTexture.ReleaseTemporary(superSizedAlphaMask); RenderTexture.ReleaseTemporary(superSizedFrameTemp); minDistancesBuffer.Dispose(); maxDistanceBuffer.Dispose(); DestroyImmediate(camera.gameObject, true); //restore layers RestoreLayers(originalLayers); //restore lights var enumerator2 = originalLights.Keys.GetEnumerator(); while (enumerator2.MoveNext()) { var light = enumerator2.Current; if (light != null) { light.enabled = originalLights[light]; } } enumerator2.Dispose(); originalLights.Clear(); var savePath = ""; var file = ""; var filePrefab = ""; if (imposter.AssetReference != null) { savePath = AssetDatabase.GetAssetPath(imposter.AssetReference); var lastSlash = savePath.LastIndexOf("/", StringComparison.Ordinal); var folder = savePath.Substring(0, lastSlash); file = savePath.Substring(lastSlash + 1, savePath.LastIndexOf(".", StringComparison.Ordinal) - lastSlash - 1); filePrefab = file; savePath = folder + "/" + file + "_Imposter" + ".asset"; } else //no prefab, ask where to save { file = root.name; savePath = EditorUtility.SaveFilePanelInProject("Save Billboard Imposter", file + "_Imposter", "asset", "Select save location"); } imposter.PrefabSuffix = _suffix; imposter.name = file; AssetDatabase.CreateAsset(imposter, savePath); imposter.Save(savePath, file, _createUnityBillboard); //spawn var spawned = imposter.Spawn(root.position, true, filePrefab); spawned.transform.position = root.position + new Vector3(2f, 0f, 2f); spawned.transform.rotation = root.rotation; spawned.transform.localScale = originalScale; root.localScale = originalScale; return(true); }
// Update is called once per frame void Update() { //Vector3 offset = target.position - transform.position; //offset = new Vector3(Mathf.Round(offset.x * simulationWidth) / simulationWidth, 0.0f, Mathf.Round(offset.z * simulationHeight)/simulationHeight); //transform.position = new Vector3(transform.position.x + offset.x, transform.position.y, transform.position.z + offset.z); //transform.position = new Vector3(target.position.x, transform.position.y, target.position.z ); float simW = (float)simulationWidth; float simH = (float)simulationHeight; Vector3 offset = target.position - transform.position; float scale = transform.lossyScale.x; float offX = Mathf.Ceil(offset.x * simW / scale); float offY = Mathf.Ceil(offset.z * simH / scale); float wOffX = offX * scale / simW; float wOffY = offY * scale / simW; offset = new Vector3(offX, 0.0f, offY); Vector3 offsetWorld = new Vector3(wOffX, 0.0f, wOffY); Vector3 newWorldPos = new Vector3(transform.position.x + offsetWorld.x, transform.position.y, transform.position.z + offsetWorld.z); // Debug.Log(offset + "sinW : " + simW + "scale : " + scale + "world :" + offsetWorld); m_orthoCam.Render(); if (currentArray) { simulateWater.SetBuffer(0, "readBuffer", waterBuffer1); simulateWater.SetBuffer(0, "writeBuffer", waterBuffer2); renderWater.SetBuffer(0, "simulationBuffer", waterBuffer2); } else { simulateWater.SetBuffer(0, "readBuffer", waterBuffer2); simulateWater.SetBuffer(0, "writeBuffer", waterBuffer1); renderWater.SetBuffer(0, "simulationBuffer", waterBuffer1); } currentArray = !currentArray; // Debug.Log("dT" + Time.deltaTime); simulateWater.SetFloat("deltaTime", Time.deltaTime); simulateWater.SetFloat("time", Time.time); simulateWater.SetInt("simulationWidth", simulationWidth); simulateWater.SetInt("simulationHeight", simulationHeight); simulateWater.SetFloat("springStrength", springStrength); simulateWater.SetFloat("viscosity", viscosity); simulateWater.SetFloat("neighbourSpeedAveraging", neighbourSpeedAveraging); simulateWater.SetFloat("neighbourHeightAveraging", neighbourHeightAveraging); simulateWater.SetFloat("speedDifferenceToFoam", speedDifferenceToFoam); simulateWater.SetFloat("waveHeight", waveHeight[0]); simulateWater.SetFloat("waveHeight2", waveHeight[1]); simulateWater.SetFloat("waveHeight3", waveHeight[2]); simulateWater.SetFloat("waveHeight4", waveHeight[3]); simulateWater.SetFloat("waveRadius", waveRadius[0]); simulateWater.SetFloat("waveRadius2", waveRadius[1]); simulateWater.SetFloat("waveRadius3", waveRadius[2]); simulateWater.SetFloat("waveRadius4", waveRadius[3]); simulateWater.SetFloat("borderMaskSize", borderMaskSize); simulateWater.SetVector("wavePosition", wavePosition[0]); simulateWater.SetVector("wavePosition2", wavePosition[1]); simulateWater.SetVector("wavePosition3", wavePosition[2]); simulateWater.SetVector("wavePosition4", wavePosition[3]); simulateWater.SetVector("waterPosition", new Vector4(transform.position.x, transform.position.y, transform.position.z, transform.lossyScale.x)); simulateWater.SetTextureFromGlobal(0, "_OrthoCollisionsTex", "_OrthoCollisionsTex"); simulateWater.SetVector("offset", offset); simulateWater.SetVector("oldWaterPosition", oldWaterPosition); simulateWater.Dispatch(0, simulationWidth * simulationHeight / 32, 1, 1); renderWater.SetInt("simulationWidth", simulationWidth); renderWater.SetInt("simulationHeight", simulationHeight); renderWater.SetTexture(0, "albedo", albedoWater); renderWater.SetTexture(0, "normal", normalWater); renderWater.Dispatch(0, width / 8, height / 8, 1); transform.position = newWorldPos; m_orthoCam.transform.SetPositionAndRotation(transform.position - Vector3.up * (waveAverageAmplitude + collisionRenderNearClipBias), Quaternion.LookRotation(Vector3.up, Vector3.forward)); oldWaterPosition = transform.position; }
// Start is called before the first frame update void Init() { shader.SetInt("size", size); shader.SetInt("iterations", iterations); shader.SetFloat("viscosity", viscosity); shader.SetFloat("dt", Time.deltaTime); //Lin solve diffuse linsolve = shader.FindKernel("LinearSolve"); shader.SetBuffer(linsolve, "v", velocities); shader.SetBuffer(linsolve, "v0", velocities0); float a = Time.deltaTime * viscosity * (size - 2) * (size - 2); shader.SetFloat("a", a); shader.SetFloat("c", 1 + 4 * a); // // Set bounds V0 true setboundsv0 = shader.FindKernel("Setboundsv0"); shader.SetBuffer(setboundsv0, "v0", velocities0); // //// Project // start projectStart = shader.FindKernel("ProjectStart"); shader.SetBuffer(projectStart, "v", velocities); shader.SetBuffer(projectStart, "v0", velocities0); //Lin solve 2 linsolve2 = shader.FindKernel("LinearSolve2"); shader.SetBuffer(linsolve2, "v", velocities); //end projectEnd = shader.FindKernel("ProjectEnd"); shader.SetBuffer(projectEnd, "v", velocities); shader.SetBuffer(projectEnd, "v0", velocities0); //// // Advect advect = shader.FindKernel("Advect"); shader.SetBuffer(advect, "v", velocities); shader.SetBuffer(advect, "v0", velocities0); shader.SetFloat("dtx", Time.deltaTime * (size - 2)); shader.SetFloat("dty", Time.deltaTime * (size - 2)); shader.SetFloat("sizefloat", size); // //// Project 2 // start2 projectStart2 = shader.FindKernel("ProjectStart2"); shader.SetBuffer(projectStart2, "v", velocities); shader.SetBuffer(projectStart2, "v0", velocities0); //Lin solve 22 linsolve22 = shader.FindKernel("LinearSolve22"); shader.SetBuffer(linsolve22, "v0", velocities0); //end2 projectEnd2 = shader.FindKernel("ProjectEnd2"); shader.SetBuffer(projectEnd2, "v", velocities); shader.SetBuffer(projectEnd2, "v0", velocities0); //// render = shader.FindKernel("Render"); shader.SetBuffer(render, "v", velocities); shader.SetTexture(render, "Result", result); addVelocity = shader.FindKernel("AddVelocity"); shader.SetBuffer(addVelocity, "v", velocities); shader.SetFloats("velToAdd", d); int[] i = new int[2]; i[0] = 50; i[1] = 50; shader.SetInts("position", i); FluidUpdate(); }
void InitShaders() { // Link kernels with shader fwdTransfKernel = shader.FindKernel("MultiplyWToL"); bckTransfKernel = shader.FindKernel("MultiplyLToW"); dispKernel = shader.FindKernel("movePoints"); FDEUKernel = shader.FindKernel("executeFDEUB"); fwdTransfNormalKern = shader.FindKernel("MultiplyWToLNorm"); bckTransfNormalKern = shader.FindKernel("MultiplyLToWNorm"); fwdTransfObsKern = shader.FindKernel("MultiplyWToLObs"); bckTransfObsKern = shader.FindKernel("MultiplyLToWObs"); fwdTransPlanKern = shader.FindKernel("MultiplyWToLPla"); bckTransPlanKern = shader.FindKernel("MultiplyLToWPla"); // Link buffer with RWTextures in shader myLineBuffer = new ComputeBuffer(lineTab.Length, 3 * sizeof(float)); myLineBuffer.SetData(lineTab); myDisplacementBuffer = new ComputeBuffer(lineTab.Length, 3 * sizeof(float)); normSrcVecBuffer = new ComputeBuffer(beginLineNormal.Length, 3 * sizeof(float)); normSrcVecBuffer.SetData(beginLineNormal); normDestVecBuffer = new ComputeBuffer(endLineNormal.Length, 3 * sizeof(float)); normDestVecBuffer.SetData(endLineNormal); if (pointsToAvoid.Length > 0) { myAvoidPointBuffer = new ComputeBuffer(pointsToAvoid.Length, 3 * sizeof(float)); myAvoidPointBuffer.SetData(pointsToAvoid); } else { myAvoidPointBuffer = new ComputeBuffer(1, 3 * sizeof(float)); Vector3[] dummyPoint = new Vector3[1]; dummyPoint[0] = new Vector3(0, 0, 0); myAvoidPointBuffer.SetData(dummyPoint); } myBundleIdBuffer = new ComputeBuffer(bundleId.Length, sizeof(int)); myBundleIdBuffer.SetData(bundleId); int nbPlane = (int)(planeCoord.Length / 4.0); //Debug.Log("Nb Plane: "+nbPlane); if (nbPlane > 0) { myAttractivePlane = new ComputeBuffer(planeCoord.Length, 3 * sizeof(float)); myAttractivePlane.SetData(planeCoord); } else { myAttractivePlane = new ComputeBuffer(1, 3 * sizeof(float)); Vector3[] dummyPoint = new Vector3[1]; dummyPoint[0] = new Vector3(0, 0, 0); myAttractivePlane.SetData(dummyPoint); } // Coord Transform Buffers shader.SetBuffer(fwdTransfKernel, "pos", myLineBuffer); shader.SetBuffer(bckTransfKernel, "pos", myLineBuffer); shader.SetBuffer(bckTransfKernel, "dispVec", myDisplacementBuffer); //Normal coordinate change shader.SetBuffer(fwdTransfNormalKern, "normSrcVec", normSrcVecBuffer); shader.SetBuffer(fwdTransfNormalKern, "normDestVec", normDestVecBuffer); shader.SetBuffer(bckTransfNormalKern, "normSrcVec", normSrcVecBuffer); shader.SetBuffer(bckTransfNormalKern, "normDestVec", normDestVecBuffer); // Obstacle coordinate change if (pointsToAvoid.Length > 0) { shader.SetBuffer(fwdTransfObsKern, "avoidPoints", myAvoidPointBuffer); shader.SetBuffer(bckTransfObsKern, "avoidPoints", myAvoidPointBuffer); } //Plane Attraction Coordinate change if (planeCoord.Length > 0) { shader.SetBuffer(fwdTransPlanKern, "attracPlane", myAttractivePlane); shader.SetBuffer(bckTransPlanKern, "attracPlane", myAttractivePlane); } // FD Kernel Buffers shader.SetBuffer(FDEUKernel, "pos", myLineBuffer); shader.SetBuffer(FDEUKernel, "dispVec", myDisplacementBuffer); shader.SetBuffer(FDEUKernel, "normSrcVec", normSrcVecBuffer); shader.SetBuffer(FDEUKernel, "normDestVec", normDestVecBuffer); //if (pointsToAvoid.Length > 0) //{ shader.SetBuffer(FDEUKernel, "avoidPoints", myAvoidPointBuffer); //} //if(planeCoord.Length > 0) //if(nbPlane > 0) //{ //Debug.Log("Set AttractPlane property..."); shader.SetBuffer(FDEUKernel, "attracPlane", myAttractivePlane); //} shader.SetBuffer(FDEUKernel, "bundleId", myBundleIdBuffer); // Displacement kernel Buffers shader.SetBuffer(dispKernel, "pos", myLineBuffer); shader.SetBuffer(dispKernel, "dispVec", myDisplacementBuffer); // Link shader uniforms shader.SetInt("lineNb", lineNb); shader.SetInt("obsNb", pointsToAvoid.Length); shader.SetFloat("k", springConstant); shader.SetFloat("kr", repulsionConstant); shader.SetFloat("ka", attractionConstant); shader.SetFloat("kor", obstacleRepulsionConstant); shader.SetFloat("dmin", obstacleDMin); shader.SetFloat("dmax", distanceMaxNormal); shader.SetFloat("fmax", forceMaxNormal); shader.SetInt("nbPlane", planeCoord.Length); shader.SetFloat("dmaxP", distancePlane); shader.SetFloat("fmaxP", forcePlane); }