void UpdateRequestFinished(DSPNodeUpdateRequest <SpectrumUpdateKernel, SpectrumNode.Parameters, SpectrumNode.Providers, SpectrumNode> request) { _Waiting = false; if (_Initialized == false) { return; } _ScopeDataBuffer?.SetData(_Buffer); Compute.SetInt("BufferSize", _Buffer.Length); Compute.SetInt("SampleRate", AudioSettings.GetConfiguration().sampleRate); Compute.SetTexture(_GridKernelId, "Result", SpectrumRT); Compute.Dispatch(_GridKernelId, SpectrumRT.width, SpectrumRT.height, 1); Compute.SetBuffer(_SpectrumKernelId, "SpectrumData", _ScopeDataBuffer); Compute.SetTexture(_SpectrumKernelId, "Result", SpectrumRT); Compute.Dispatch(_SpectrumKernelId, SpectrumRT.width, 1, 1); }
void UpdateRequestFinished(DSPNodeUpdateRequest <ScopeUpdateKernel, ScopeNode.Parameters, ScopeNode.Providers, ScopeNode> request) { _Waiting = false; if (_Initialized == false) { return; } _ScopeDataBuffer?.SetData(_BufferX); Compute.SetInt("InputChannelsX", request.UpdateJob.InputChannelsX); Compute.SetInt("MaxChannels", ScopeNode.MAX_CHANNELS); Compute.SetInt("BufferSize", ScopeNode.BUFFER_SIZE); Compute.SetInt("BufferIdx", request.UpdateJob.BufferIdx); Compute.SetFloat("TriggerThreshold", request.UpdateJob.TriggerThreshold); Compute.SetFloat("ScopeXHeight", Height); Compute.SetFloat("ScopeXOffset", Offset); Compute.SetTexture(_GridKernelId, "Result", ScopeRT); Compute.Dispatch(_GridKernelId, ScopeRT.width, ScopeRT.height, 1); Compute.SetBuffer(_ScopeKernelId, "ScopeData", _ScopeDataBuffer); Compute.SetTexture(_ScopeKernelId, "Result", ScopeRT); Compute.Dispatch(_ScopeKernelId, ScopeNode.BUFFER_SIZE, 1, 1); }
// Start is called before the first frame update void Start() { //m_RTTarget = new RenderTexture(m_RTSize.x, m_RTSize.y, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.R8G8B8A8_SRGB); m_RTTarget = new RenderTexture(m_RTSize.x, m_RTSize.y, 0, UnityEngine.Experimental.Rendering.GraphicsFormat.R8G8B8A8_UNorm); m_RTTarget.enableRandomWrite = true; m_RTTarget.Create(); m_QuadMaterial.SetTexture("_MainTex", m_RTTarget); m_SimpleAccelerationStructureDataBuffer = new ComputeBuffer(512, System.Runtime.InteropServices.Marshal.SizeOf(typeof(SphereData))); SphereData Data = new SphereData(); Data.Center = new Vector3(0, -1000.0f, 0.0f); Data.Radius = 1000.0f; Data.MaterialType = (int)MaterialType.MAT_LAMBERTIAN; Data.MaterialAlbedo = new Vector3(0.5f, 0.5f, 0.5f); m_SphereArray[m_NumSpheres] = Data; m_SphereTimeOffset[m_NumSpheres] = UnityEngine.Random.Range(0, 100.0f); m_NumSpheres++; Data.Center = new Vector3(0, 1.0f, 0.0f); Data.Radius = 1.0f; Data.MaterialType = (int)MaterialType.MAT_DIELECTRIC; Data.MaterialAlbedo = new Vector3(0.1f, 0.2f, 0.5f); Data.MaterialData = new Vector4(1.5f, 0.0f, 0.0f, 0.0f); m_SphereArray[m_NumSpheres] = Data; m_SphereTimeOffset[m_NumSpheres] = UnityEngine.Random.Range(0, 100.0f); m_NumSpheres++; Data.Center = new Vector3(-4.0f, 1.0f, 0.0f); Data.Radius = 1.0f; Data.MaterialType = (int)MaterialType.MAT_LAMBERTIAN; Data.MaterialAlbedo = new Vector3(0.4f, 0.2f, 0.1f); Data.MaterialData = new Vector4(1.0f, 0.0f, 0.0f, 0.0f); m_SphereArray[m_NumSpheres] = Data; m_SphereTimeOffset[m_NumSpheres] = UnityEngine.Random.Range(0, 100.0f); m_NumSpheres++; Data.Center = new Vector3(4.0f, 1.0f, 0.0f); Data.Radius = 1.0f; Data.MaterialType = (int)MaterialType.MAT_METAL; Data.MaterialAlbedo = new Vector3(0.7f, 0.6f, 0.5f); Data.MaterialData = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); m_SphereArray[m_NumSpheres] = Data; m_SphereTimeOffset[m_NumSpheres] = UnityEngine.Random.Range(0, 100.0f); m_NumSpheres++; for (int a = -4; a < 5; a++) { for (int b = -4; b < 4; b++) { float Choose_Mat = UnityEngine.Random.Range(0, 1.0f); Vector3 Center = new Vector3(a * 1.5f + 1.5f * UnityEngine.Random.Range(0, 1.0f), 0.2f, b * 1.0f + 1.0f * UnityEngine.Random.Range(0, 1.0f)); Vector3 Dist = Center - new Vector3(4, 0.2f, 0); if (Dist.magnitude > 0.9f) { if (Choose_Mat < 0.5f) { // diffuse Vector3 Albedo = new Vector3(UnityEngine.Random.Range(0, 1.0f), UnityEngine.Random.Range(0, 1.0f), UnityEngine.Random.Range(0, 1.0f)); Data.Center = Center; Data.Radius = 0.2f; Data.MaterialType = (int)MaterialType.MAT_LAMBERTIAN; Data.MaterialAlbedo = Albedo; Data.MaterialData = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); } else if (Choose_Mat < 0.8f) { // metal Vector3 Albedo = new Vector3(UnityEngine.Random.Range(0, 1.0f), UnityEngine.Random.Range(0, 1.0f), UnityEngine.Random.Range(0, 1.0f)); float Fuzz = UnityEngine.Mathf.Min(UnityEngine.Random.Range(0, 1.0f), 0.5f); Data.Center = Center; Data.Radius = 0.2f; Data.MaterialType = (int)MaterialType.MAT_METAL; Data.MaterialAlbedo = Albedo; Data.MaterialData = new Vector4(Fuzz, 0.0f, 0.0f, 0.0f); } else { Data.Center = Center; Data.Radius = 0.2f; Data.MaterialType = (int)MaterialType.MAT_DIELECTRIC; Data.MaterialData = new Vector4(1.5f, 0.0f, 0.0f, 0.0f); } m_SphereArray[m_NumSpheres] = Data; m_SphereTimeOffset[m_NumSpheres] = UnityEngine.Random.Range(0, 100.0f); m_NumSpheres++; } } } m_SimpleAccelerationStructureDataBuffer.SetData(m_SphereArray); }
public void Erode() { if (numErosionIterations <= 0) { return; } int numThreads = Mathf.Max(1, numErosionIterations / 1024); // Create brush List <int> brushIndexOffsets = new List <int> (); List <float> brushWeights = new List <float> (); float weightSum = 0; for (int brushY = -erosionBrushRadius; brushY <= erosionBrushRadius; brushY++) { for (int brushX = -erosionBrushRadius; brushX <= erosionBrushRadius; brushX++) { float sqrDst = brushX * brushX + brushY * brushY; if (sqrDst < erosionBrushRadius * erosionBrushRadius) { brushIndexOffsets.Add(brushY * mapSize + brushX); float brushWeight = 1 - Mathf.Sqrt(sqrDst) / erosionBrushRadius; weightSum += brushWeight; brushWeights.Add(brushWeight); } } } for (int i = 0; i < brushWeights.Count; i++) { brushWeights[i] /= weightSum; } // Send brush data to compute shader ComputeBuffer brushIndexBuffer = new ComputeBuffer(brushIndexOffsets.Count, sizeof(int)); ComputeBuffer brushWeightBuffer = new ComputeBuffer(brushWeights.Count, sizeof(int)); brushIndexBuffer.SetData(brushIndexOffsets); brushWeightBuffer.SetData(brushWeights); erosion.SetBuffer(0, "brushIndices", brushIndexBuffer); erosion.SetBuffer(0, "brushWeights", brushWeightBuffer); // Generate random indices for droplet placement if (randomIndices == null || randomIndices.Length != numErosionIterations || mapSizeOld != mapSize) { mapSizeOld = mapSize; randomIndices = new int[numErosionIterations]; for (int i = 0; i < numErosionIterations; i++) { int randomX = Random.Range(erosionBrushRadius, mapSize + erosionBrushRadius); int randomY = Random.Range(erosionBrushRadius, mapSize + erosionBrushRadius); randomIndices[i] = randomY * mapSize + randomX; } } // Send random indices to compute shader ComputeBuffer randomIndexBuffer = new ComputeBuffer(randomIndices.Length, sizeof(int)); randomIndexBuffer.SetData(randomIndices); erosion.SetBuffer(0, "randomIndices", randomIndexBuffer); // Heightmap buffer if (heightmapUpdatedSinceErosion) { if (mapBuffer != null) { mapBuffer.Release(); } mapBuffer = new ComputeBuffer(map.Length, sizeof(float)); mapBuffer.SetData(map); erosion.SetBuffer(0, "map", mapBuffer); } // Settings erosion.SetInt("borderSize", erosionBrushRadius); erosion.SetInt("mapSize", mapSizeWithBorder); erosion.SetInt("brushLength", brushIndexOffsets.Count); erosion.SetInt("maxLifetime", maxLifetime); erosion.SetFloat("inertia", inertia); erosion.SetFloat("sedimentCapacityFactor", sedimentCapacityFactor); erosion.SetFloat("minSedimentCapacity", minSedimentCapacity); erosion.SetFloat("depositSpeed", depositSpeed); erosion.SetFloat("erodeSpeed", erodeSpeed); erosion.SetFloat("evaporateSpeed", evaporateSpeed); erosion.SetFloat("gravity", gravity); erosion.SetFloat("startSpeed", startSpeed); erosion.SetFloat("startWater", startWater); // Run compute shader erosion.Dispatch(0, numThreads, 1, 1); mapBuffer.GetData(map); // Release buffers //mapBuffer.Release (); randomIndexBuffer.Release(); brushIndexBuffer.Release(); brushWeightBuffer.Release(); if (!Application.isPlaying) { mapBuffer.Release(); } }
private void UpdateBrainDataAndBuffers() { // NEURON FEED DATA //if (neuronFeedDataCBuffer != null) // neuronFeedDataCBuffer.Release(); //neuronFeedDataCBuffer = new ComputeBuffer(numNeurons, sizeof(float) * 1); if (tempNeuronList == null) { return; } if (tempAxonList == null) { return; } NeuronFeedData[] neuronValuesArray = new NeuronFeedData[tempNeuronList.Count]; for (int i = 0; i < neuronValuesArray.Length; i++) { neuronValuesArray[i].curValue = Mathf.Sin(Time.fixedTime * 1.25f + tempNeuronList[i].currentValue[0]); } neuronFeedDataCBuffer.SetData(neuronValuesArray); // For some reason I have to setBuffer on all of these for it to WORK!!!!!!!! (even though they are all the same in the shader...) // For some reason I have to setBuffer on all of these for it to WORK!!!!!!!! // For some reason I have to setBuffer on all of these for it to WORK!!!!!!!! shaderComputeBrain.SetFloat("minAxonRadius", minAxonRadius); shaderComputeBrain.SetFloat("maxAxonRadius", maxAxonRadius); shaderComputeBrain.SetFloat("minNeuronRadius", minNeuronRadius); shaderComputeBrain.SetFloat("maxNeuronRadius", maxNeuronRadius); shaderComputeBrain.SetFloat("neuronAttractForce", neuronAttractForce); shaderComputeBrain.SetFloat("axonStraightenForce", axonStraightenForce); shaderComputeBrain.SetFloat("neuronRepelForce", neuronRepelForce); shaderComputeBrain.SetFloat("axonRepelForce", axonRepelForce); int simNeuronAttractKernelID = shaderComputeBrain.FindKernel("CSSimNeuronAttract"); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.Dispatch(simNeuronAttractKernelID, numAxons, 1, 1); // Simulate!! move neuron and axons around int simNeuronRepelKernelID = shaderComputeBrain.FindKernel("CSSimNeuronRepel"); shaderComputeBrain.SetBuffer(simNeuronRepelKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronRepelKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronRepelKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronRepelKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronRepelKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.Dispatch(simNeuronRepelKernelID, numNeurons, numNeurons, 1); // Simulate!! move neuron and axons around int simAxonRepelKernelID = shaderComputeBrain.FindKernel("CSSimAxonRepel"); shaderComputeBrain.SetBuffer(simAxonRepelKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(simAxonRepelKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(simAxonRepelKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(simAxonRepelKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(simAxonRepelKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.Dispatch(simAxonRepelKernelID, numAxons, numAxons, 1); // Simulate!! move neuron and axons around //shaderComputeBrain.Dispatch(simulateKernelID, tempAxonList.Count, 1, 1); // Simulate!! move neuron and axons around // Re-Generate TRIANGLES! // SET UP GEO BUFFER and REFS::::: if (appendTrianglesCBuffer != null) { appendTrianglesCBuffer.Release(); } //Debug.Log("Max Tris: " + (numNeurons * maxTrisPerNeuron + numAxons * maxTrisPerAxon).ToString()); appendTrianglesCBuffer = new ComputeBuffer(numNeurons * maxTrisPerNeuron + numAxons * maxTrisPerAxon, sizeof(float) * 27, ComputeBufferType.Append); // vector3 position * 3 verts appendTrianglesCBuffer.SetCounterValue(0); int neuronTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateNeuronTriangles"); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); //shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); //shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "appendTrianglesCBuffer", appendTrianglesCBuffer); int axonTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateAxonTriangles"); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "appendTrianglesCBuffer", appendTrianglesCBuffer); displayMaterial = new Material(shaderDisplayBrain); displayMaterial.SetPass(0); displayMaterial.SetBuffer("appendTrianglesBuffer", appendTrianglesCBuffer); //displayMaterial.SetPass(0); //displayMaterial.SetBuffer("appendTrianglesBuffer", appendTrianglesCBuffer); //int neuronTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateNeuronTriangles"); //int axonTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateAxonTriangles"); shaderComputeBrain.Dispatch(neuronTrianglesKernelID, tempNeuronList.Count, 1, 1); // create all triangles from Neurons shaderComputeBrain.Dispatch(axonTrianglesKernelID, tempAxonList.Count, 1, 1); // create all geometry for Axons args[0] = 0; // set later by counter;// 3; // 3 vertices to start args[1] = 1; // 1 instance/copy argsCBuffer.SetData(args); ComputeBuffer.CopyCount(appendTrianglesCBuffer, argsCBuffer, 0); argsCBuffer.GetData(args); //Debug.Log("triangle count " + args[0]); /*NeuronFeedData[] neuronValuesArray = new NeuronFeedData[refBrain.neuronList.Count]; * for (int i = 0; i < neuronValuesArray.Length; i++) { * neuronValuesArray[i].curValue = refBrain.neuronList[i].currentValue[0]; * } * neuronFeedDataCBuffer.SetData(neuronValuesArray);*/ }
void BuildLightData(CommandBuffer cmd, HDCamera hdCamera, HDRayTracingLights rayTracingLights, DebugDisplaySettings debugDisplaySettings) { // If no lights, exit if (rayTracingLights.lightCount == 0) { ResizeLightDataBuffer(1); return; } // Also we need to build the light list data if (m_LightDataGPUArray == null || m_LightDataGPUArray.count != rayTracingLights.lightCount) { ResizeLightDataBuffer(rayTracingLights.lightCount); } m_LightDataCPUArray.Clear(); // Grab the shadow settings var hdShadowSettings = hdCamera.volumeStack.GetComponent <HDShadowSettings>(); BoolScalableSetting contactShadowScalableSetting = HDAdditionalLightData.ScalableSettings.UseContactShadow(m_RenderPipeline.asset); // Build the data for every light for (int lightIdx = 0; lightIdx < rayTracingLights.hdLightArray.Count; ++lightIdx) { // Grab the additinal light data to process HDAdditionalLightData additionalLightData = rayTracingLights.hdLightArray[lightIdx]; LightData lightData = new LightData(); // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to add an invalid light for that frame if (additionalLightData == null) { m_LightDataCPUArray.Add(lightData); continue; } // Evaluate all the light type data that we need LightCategory lightCategory = LightCategory.Count; GPULightType gpuLightType = GPULightType.Point; LightVolumeType lightVolumeType = LightVolumeType.Count; HDLightType lightType = additionalLightData.type; HDRenderPipeline.EvaluateGPULightType(lightType, additionalLightData.spotLightShape, additionalLightData.areaLightShape, ref lightCategory, ref gpuLightType, ref lightVolumeType); // Fetch the light component for this light additionalLightData.gameObject.TryGetComponent(out lightComponent); // Build the processed light data that we need ProcessedLightData processedData = new ProcessedLightData(); processedData.additionalLightData = additionalLightData; processedData.lightType = additionalLightData.type; processedData.lightCategory = lightCategory; processedData.gpuLightType = gpuLightType; processedData.lightVolumeType = lightVolumeType; // Both of these positions are non-camera-relative. processedData.distanceToCamera = (additionalLightData.gameObject.transform.position - hdCamera.camera.transform.position).magnitude; processedData.lightDistanceFade = HDUtils.ComputeLinearDistanceFade(processedData.distanceToCamera, additionalLightData.fadeDistance); processedData.volumetricDistanceFade = HDUtils.ComputeLinearDistanceFade(processedData.distanceToCamera, additionalLightData.volumetricFadeDistance); processedData.isBakedShadowMask = HDRenderPipeline.IsBakedShadowMaskLight(lightComponent); // Build a visible light Color finalColor = lightComponent.color.linear * lightComponent.intensity; if (additionalLightData.useColorTemperature) { finalColor *= Mathf.CorrelatedColorTemperatureToRGB(lightComponent.colorTemperature); } visibleLight.finalColor = finalColor; visibleLight.range = lightComponent.range; // This should be done explicitely, localtoworld matrix doesn't work here localToWorldMatrix.SetColumn(3, lightComponent.gameObject.transform.position); localToWorldMatrix.SetColumn(2, lightComponent.transform.forward); localToWorldMatrix.SetColumn(1, lightComponent.transform.up); localToWorldMatrix.SetColumn(0, lightComponent.transform.right); visibleLight.localToWorldMatrix = localToWorldMatrix; visibleLight.spotAngle = lightComponent.spotAngle; int shadowIndex = additionalLightData.shadowIndex; int screenSpaceShadowIndex = -1; int screenSpaceChannelSlot = -1; Vector3 lightDimensions = new Vector3(0.0f, 0.0f, 0.0f); // Use the shared code to build the light data m_RenderPipeline.GetLightData(cmd, hdCamera, hdShadowSettings, visibleLight, lightComponent, in processedData, shadowIndex, contactShadowScalableSetting, isRasterization: false, ref lightDimensions, ref screenSpaceShadowIndex, ref screenSpaceChannelSlot, ref lightData); // We make the light position camera-relative as late as possible in order // to allow the preceding code to work with the absolute world space coordinates. Vector3 camPosWS = hdCamera.mainViewConstants.worldSpaceCameraPos; HDRenderPipeline.UpdateLightCameraRelativetData(ref lightData, camPosWS); // Set the data for this light m_LightDataCPUArray.Add(lightData); } // Push the data to the GPU m_LightDataGPUArray.SetData(m_LightDataCPUArray); }
public void Assign(SkinnedMeshRenderer smr) { Release(); if (smr == null) { return; } var mesh = smr.sharedMesh; if (mesh == null) { return; } { var b = smr.bones; if (b.Length > 0) { var matrices = new Matrix4x4[b.Length]; for (int bi = 0; bi < b.Length; ++bi) { if (b[bi] != null) { matrices[bi] = b[bi].localToWorldMatrix; } } bones = new ComputeBuffer(b.Length, 64); bones.SetData(matrices); } } var vertexCount = mesh.vertexCount; { var w = mesh.boneWeights; if (w.Length > 0) { // todo: support unlimited influence count on 2019.x weights = new ComputeBuffer(w.Length, 32); weights.SetData(w); } } { var p = mesh.vertices; srcPoints = new ComputeBuffer(p.Length, 12); srcPoints.SetData(p); dstPoints = new ComputeBuffer(p.Length, 12); } { var n = mesh.normals; if (n.Length == 0) { n = new Vector3[vertexCount]; } srcNormals = new ComputeBuffer(n.Length, 12); srcNormals.SetData(n); dstNormals = new ComputeBuffer(n.Length, 12); } { var t = mesh.tangents; if (t.Length == 0) { t = new Vector4[vertexCount]; } srcTangents = new ComputeBuffer(t.Length, 16); srcTangents.SetData(t); dstTangents = new ComputeBuffer(t.Length, 16); } }
public void BuildChunkMesh(RenderTexture volume, Mesh newMesh) { if (volume == null || newMesh == null) { Debug.LogWarning("Can't build mesh '" + newMesh + "' from '" + volume + "' volume"); return; } float startTime = Time.realtimeSinceStartup; Poly[] dataArray; dataArray = new Poly[_MaxSize]; ComputeBuffer cBuffer = new ComputeBuffer(_MaxSize, 72); //Set data to container cBuffer.SetData(dataArray); //Set container int id = _CShaderBuilder.FindKernel("CSMain"); _CShaderBuilder.SetTexture(id, "input_volume", volume); _CShaderBuilder.SetBuffer(id, "buffer", cBuffer); //Set parameters for building _CShaderBuilder.SetInt("_Trilinear", _Trilinear); _CShaderBuilder.SetInt("_Size", _ChunkSizeZ); _CShaderBuilder.SetInt("_MultiSampling", _MultiSampling); //Build! _CShaderBuilder.Dispatch(id, 1, 1, 1); //Recieve data from container cBuffer.GetData(dataArray); //Debug.Log("Building time: " + (1000.0f*(Time.realtimeSinceStartup-startTime)).ToString()+"ms"); //Construct mesh using received data int vindex = 0; int count = 0; //Count real data length for (count = 0; count < _MaxSize; count++) { if (dataArray[count].A1 == 0.0f && dataArray[count].B1 == 0.0f && dataArray[count].C1 == 0.0 && dataArray[count].A2 == 0.0f && dataArray[count].B2 == 0.0f && dataArray[count].C2 == 0.0 && dataArray[count].A3 == 0.0f && dataArray[count].B3 == 0.0f && dataArray[count].C3 == 0.0) { break; } } //Debug.Log(count+" triangles got"); Vector3[] vertices = new Vector3[count * 3]; int[] tris = new int[count * 3]; Vector2[] uvs = new Vector2[count * 3]; Vector3[] normals = new Vector3[count * 3]; Color[] colors = new Color[count * 3]; //Parse triangles for (int ix = 0; ix < count; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(-30, -30, -30); //A1,A2,A3 vPos = new Vector3(dataArray[ix].A1, dataArray[ix].A2, dataArray[ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(dataArray[ix].NA1, dataArray[ix].NA2, dataArray[ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x) * -_UVScale; // colors[vindex] = new Color(DataArray[ix].CA1, DataArray[ix].CA2, DataArray[ix].CA3); vindex++; //B1,B2,B3 vPos = new Vector3(dataArray[ix].B1, dataArray[ix].B2, dataArray[ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(dataArray[ix].NB1, dataArray[ix].NB2, dataArray[ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x) * -_UVScale; // colors[vindex] = new Color(DataArray[ix].CB1, DataArray[ix].CB2, DataArray[ix].CB3); vindex++; //C1,C2,C3 vPos = new Vector3(dataArray[ix].C1, dataArray[ix].C2, dataArray[ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(dataArray[ix].NC1, dataArray[ix].NC2, dataArray[ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x) * -_UVScale; // colors[vindex] = new Color(DataArray[ix].CC1, DataArray[ix].CC2, DataArray[ix].CC3); 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.colors = colors; ; cBuffer.Dispose(); }
// Use this for initialization void Start() { if (mesh == null && GetComponent <MeshFilter>() != null) { mesh = GetComponent <MeshFilter>().sharedMesh; } if (mesh == null && GetComponent <SkinnedMeshRenderer>() != null) { mesh = GetComponent <SkinnedMeshRenderer>().sharedMesh; } var rts = MeshInfoTexture.GeneratePositionNormalTexture(mesh, texSize, texSize); var positionTex = RenderTextureToTexture2D.Convert(rts[0]); var normalTex = RenderTextureToTexture2D.Convert(rts[1]); Texture colorTex = null; if (originColTex != null) { colorTex = MeshInfoTexture.ConvertTextureUV(originColTex, mesh, texSize, texSize); } var uvBuffer = new ComputeBuffer( texSize * texSize, SizeOf(typeof(Vector2)), ComputeBufferType.Append); var uvCounter = new ComputeBuffer( 1, SizeOf(typeof(int)), ComputeBufferType.IndirectArguments); uvBuffer.SetCounterValue(0); var kernel = sampler.FindKernel("sampleOpaqueTexel"); sampler.SetInt("TexSize", texSize); sampler.SetTexture(kernel, "Tex", positionTex); sampler.SetBuffer(kernel, "OpaqueUv", uvBuffer); sampler.Dispatch(kernel, texSize / 8, texSize / 8, 1); var count = new[] { 0 }; uvCounter.SetData(count); ComputeBuffer.CopyCount(uvBuffer, uvCounter, 0); uvCounter.GetData(count); var numUvs = count[0]; Debug.Log(numUvs); var width = texSize / 2; var height = Mathf.NextPowerOfTwo(numUvs / width); var rt = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat); rt.enableRandomWrite = true; rt.Create(); RenderTexture.active = rt; GL.Clear(true, true, Color.clear); kernel = sampler.FindKernel("buildUvTex"); sampler.SetInt("TexSize", width); sampler.SetInt("NumUvs", numUvs); sampler.SetBuffer(kernel, "UvPool", uvBuffer); sampler.SetTexture(kernel, "Output", rt); sampler.Dispatch(kernel, width / 8, height / 8, 1); uvBuffer.Release(); uvCounter.Release(); var uvTex = RenderTextureToTexture2D.Convert(rt); positionTex.filterMode = normalTex.filterMode = colorTex.filterMode = uvTex.filterMode = FilterMode.Point; positionTex.wrapMode = normalTex.wrapMode = colorTex.wrapMode = uvTex.wrapMode = TextureWrapMode.Clamp; rt.Release(); rts[0].Release(); rts[1].Release(); #if UNITY_EDITOR if (!AssetDatabase.IsValidFolder(assetFolderPath)) { AssetDatabase.CreateFolder("Assets", assetFolderName); } AssetDatabase.CreateAsset(positionTex, string.Format("{0}/{1}_pos.asset", assetFolderPath, mesh.name)); AssetDatabase.CreateAsset(normalTex, string.Format("{0}/{1}_norm.asset", assetFolderPath, mesh.name)); if (colorTex != null) { AssetDatabase.CreateAsset(colorTex, string.Format("{0}/{1}_col.asset", assetFolderPath, mesh.name)); } AssetDatabase.CreateAsset(uvTex, string.Format("{0}/{1}_uv.asset", assetFolderPath, mesh.name)); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); #endif }
private void RenderInstancedMesh() { //var boidArray = new BoidData[BoidsNum]; //_meshNo = (int) _boids._meshSetting.MeshNo; //_scale = _boids._meshSetting.Scale; if (m_useCircleMesh) // use 2D boids => creat the mesh in a script { _instanceMesh = _instanceMeshCircle; _instanceMaterial.SetVector("_Scale", new Vector3(m_scale, m_scale, m_scale)); } else { _instanceMesh = _instanceMeshSphere; _instanceMaterial.SetVector("_Scale", new Vector3(m_scale, m_scale, m_scale)); // _instanceMesh.RecalculateNormals(); // _instanceMesh.RecalculateBounds(); } // else { // Debug.LogError("useCircleMesh or useSphereMesh should be checked"); // //If we are running in a standalone build of the game // #if UNITY_STANDALONE // //Quit the application // Application.Quit(); //#endif // //If we are running in the editor // #if UNITY_EDITOR // //Stop playing the scene // // UnityEditor.EditorApplication.isPlaying = false; // //Setting isPlaying delays the result until after all script code has completed for this frame. // EditorApplication.Exit(0); // #endif // } //Debug.Log("number of indices="); //Debug.Log(_instanceMesh.GetIndexCount(0)); // Indirect numIndices = _instanceMesh ? _instanceMesh.GetIndexCount(0) : 0; //GetIndexCount(submesh = 0) // check if _boids.BoidBuffer is not null if (_boids.BoidBuffer == null) { return; // nothing to render; } // _instanceMaterial.SetBuffer("_BoidBuffer", _boids.BoidBuffer); // _boids.BoidBuffer.GetData(boidArray); // https://unity3d.com/kr/learn/tutorials/topics/graphics/gentle-introduction-shaders //Debug.Log("Current Num of Boids="); //Debug.Log(_boids.BoidsNum); _args[0] = numIndices; _args[1] = (uint)_boids.m_BoidsNum; _argsBuffer.SetData(_args); Graphics.DrawMeshInstancedIndirect( _instanceMesh, 0, _instanceMaterial, new Bounds(_boids.RoomCenter, _boids.RoomSize), _argsBuffer ); // reading from the buffer written by regular shaders //https://gamedev.stackexchange.com/questions/128976/writing-and-reading-computebuffer-in-a-shader // _boids.BoidBuffer.GetData(boidArray); }
internal void PushComputeData() { m_IndexOfIndicesBuffer.SetData(m_IndexOfIndicesData); m_NeedUpdateComputeBuffer = false; }
void TransferData() { var mapWidth = _positionMap.width; var mapHeight = _positionMap.height; var vcount = _positionList.Count; var vcount_x3 = vcount * 3; // Release the temporary objects when the size of them don't match // the input. if (_positionBuffer1 != null && _positionBuffer1.count != vcount_x3) { _positionBuffer1.Dispose(); _positionBuffer2.Dispose(); _normalBuffer.Dispose(); _positionBuffer1 = null; _positionBuffer2 = null; _normalBuffer = null; } if (_tempPositionMap != null && (_tempPositionMap.width != mapWidth || _tempPositionMap.height != mapHeight)) { Destroy(_tempPositionMap); Destroy(_tempVelocityMap); Destroy(_tempNormalMap); _tempPositionMap = null; _tempVelocityMap = null; _tempNormalMap = null; } // Lazy initialization of temporary objects if (_positionBuffer1 == null) { _positionBuffer1 = new ComputeBuffer(vcount_x3, sizeof(float)); _positionBuffer2 = new ComputeBuffer(vcount_x3, sizeof(float)); _normalBuffer = new ComputeBuffer(vcount_x3, sizeof(float)); } if (_tempPositionMap == null) { _tempPositionMap = Utility.CreateRenderTexture(_positionMap); _tempVelocityMap = Utility.CreateRenderTexture(_positionMap); _tempNormalMap = Utility.CreateRenderTexture(_positionMap); } // Set data and execute the transfer task. _compute.SetInt("VertexCount", vcount); _compute.SetMatrix("Transform", _source.transform.localToWorldMatrix); _compute.SetMatrix("OldTransform", _previousTransform); _compute.SetFloat("FrameRate", 1 / Time.deltaTime); _positionBuffer1.SetData(_positionList); _normalBuffer.SetData(_normalList); _compute.SetBuffer(0, "PositionBuffer", _positionBuffer1); _compute.SetBuffer(0, "OldPositionBuffer", _positionBuffer2); _compute.SetBuffer(0, "NormalBuffer", _normalBuffer); _compute.SetTexture(0, "PositionMap", _tempPositionMap); _compute.SetTexture(0, "VelocityMap", _tempVelocityMap); _compute.SetTexture(0, "NormalMap", _tempNormalMap); _compute.Dispatch(0, mapWidth / 8, mapHeight / 8, 1); Graphics.CopyTexture(_tempPositionMap, _positionMap); Graphics.CopyTexture(_tempVelocityMap, _velocityMap); Graphics.CopyTexture(_tempNormalMap, _normalMap); }
// Use this for initialization IEnumerator Start() { var animator = GetComponent <Animator>(); var clips = animator.runtimeAnimatorController.animationClips; var skin = GetComponentInChildren <SkinnedMeshRenderer>(); var vCount = skin.sharedMesh.vertexCount; var texWidth = Mathf.NextPowerOfTwo(vCount); var mesh = new Mesh(); animator.speed = 0; foreach (var c in clips) { var frames = Mathf.NextPowerOfTwo((int)(c.length / 0.05f)); var infoList = new List <VertInfo>(); var pRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf); pRt.name = string.Format("{0}.{1}.posTex", name, c.name); var nRt = new RenderTexture(texWidth, frames, 0, RenderTextureFormat.ARGBHalf); nRt.name = string.Format("{0}.{1}.normTex", name, c.name); foreach (var rt in new[] { pRt, nRt }) { rt.enableRandomWrite = true; rt.Create(); RenderTexture.active = rt; GL.Clear(true, true, Color.clear); } animator.Play(c.name); yield return(0); for (var i = 0; i < frames; i++) { animator.Play(c.name, 0, (float)i / frames); yield return(0); skin.BakeMesh(mesh); infoList.AddRange(Enumerable.Range(0, vCount) .Select(idx => new VertInfo() { position = mesh.vertices[idx], normal = mesh.normals[idx] }) ); } 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", vCount); infoTexGen.SetBuffer(kernel, "Info", buffer); infoTexGen.SetTexture(kernel, "OutPosition", pRt); infoTexGen.SetTexture(kernel, "OutNormal", nRt); infoTexGen.Dispatch(kernel, vCount / (int)x + 1, frames / (int)y + 1, 1); buffer.Release(); #if UNITY_EDITOR var folderName = "BakingSkinnedAnimationToTexture/BakedAnimationTex"; var folderPath = Path.Combine("Assets", folderName); if (!AssetDatabase.IsValidFolder(folderPath)) { AssetDatabase.CreateFolder("Assets", folderName); } var subFolder = name; var subFolderPath = Path.Combine(folderPath, subFolder); if (!AssetDatabase.IsValidFolder(subFolderPath)) { AssetDatabase.CreateFolder(folderPath, subFolder); } var posTex = RenderTextureToTexture2D.Convert(pRt); var normTex = RenderTextureToTexture2D.Convert(nRt); Graphics.CopyTexture(pRt, posTex); Graphics.CopyTexture(nRt, normTex); var mat = new Material(playShader); mat.SetTexture("_MainTex", skin.sharedMaterial.mainTexture); mat.SetTexture("_PosTex", posTex); mat.SetTexture("_NmlTex", normTex); mat.SetFloat("_Length", c.length); if (c.isLooping) { mat.SetFloat("_Loop", 1f); mat.EnableKeyword("ANIM_LOOP"); } var go = new GameObject(name + "." + c.name); go.AddComponent <MeshRenderer>().sharedMaterial = mat; go.AddComponent <MeshFilter>().sharedMesh = skin.sharedMesh; AssetDatabase.CreateAsset(posTex, Path.Combine(subFolderPath, pRt.name + ".asset")); AssetDatabase.CreateAsset(normTex, Path.Combine(subFolderPath, nRt.name + ".asset")); AssetDatabase.CreateAsset(mat, Path.Combine(subFolderPath, string.Format("{0}.{1}.animTex.asset", name, c.name))); PrefabUtility.CreatePrefab(Path.Combine(folderPath, go.name + ".prefab").Replace("\\", "/"), go); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); #endif } }
// inits the mesh and related data private void InitMesh() { // create mesh mesh = new Mesh { name = "SceneMesh-Sensor" + sensorIndex, indexFormat = UnityEngine.Rendering.IndexFormat.UInt32 }; MeshFilter meshFilter = GetComponent <MeshFilter>(); if (meshFilter != null) { meshFilter.mesh = mesh; } else { Debug.LogWarning("MeshFilter not found! You may not see the mesh on screen"); } // create point cloud color texture if (sensorData != null && sensorData.sensorInterface != null) { sensorInt = (DepthSensorBase)sensorData.sensorInterface; Vector2Int imageRes = Vector2Int.zero; if (sensorInt.pointCloudColorTexture == null) { sensorInt.pointCloudResolution = sourceImageResolution; imageRes = sensorInt.GetPointCloudTexResolution(sensorData); colorTexture = KinectInterop.CreateRenderTexture(colorTexture, imageRes.x, imageRes.y, RenderTextureFormat.ARGB32); sensorInt.pointCloudColorTexture = colorTexture; colorTextureCreated = true; } else { sourceImageResolution = sensorInt.pointCloudResolution; imageRes = sensorInt.GetPointCloudTexResolution(sensorData); colorTexture = sensorInt.pointCloudColorTexture; colorTextureCreated = false; } // create depth image buffer if (sourceImageResolution == DepthSensorBase.PointCloudResolution.DepthCameraResolution) { if (sensorData.depthImageBuffer == null) { int depthBufferLength = sensorData.depthImageWidth * sensorData.depthImageHeight / 2; sensorData.depthImageBuffer = KinectInterop.CreateComputeBuffer(sensorData.depthImageBuffer, depthBufferLength, sizeof(uint)); depthBufferCreated = true; } } else { if (sensorData.colorDepthBuffer == null && sensorData.colorImageWidth > 0 && sensorData.colorImageHeight > 0) { int bufferLength = sensorData.colorImageWidth * sensorData.colorImageHeight / 2; sensorData.colorDepthBuffer = new ComputeBuffer(bufferLength, sizeof(uint)); depthBufferCreated = true; } } // create space table spaceTable = sensorInt.pointCloudResolution == DepthSensorBase.PointCloudResolution.DepthCameraResolution ? sensorInt.GetDepthCameraSpaceTable(sensorData) : sensorInt.GetColorCameraSpaceTable(sensorData); int spaceBufferLength = imageRes.x * imageRes.y * 3; spaceTableBuffer = new ComputeBuffer(spaceBufferLength, sizeof(float)); spaceTableBuffer.SetData(spaceTable); spaceTable = null; // create copy texture colorTextureCopy = KinectInterop.CreateRenderTexture(colorTextureCopy, imageRes.x, imageRes.y, RenderTextureFormat.ARGB32); // set the color texture Renderer meshRenderer = GetComponent <Renderer>(); if (meshRenderer && meshRenderer.material /**&& meshRenderer.material.mainTexture == null*/) { meshShaderMat = meshRenderer.material; } // get reference to the transform trans = GetComponent <Transform>(); // image width & height imageWidth = imageRes.x; imageHeight = imageRes.y; // create mesh vertices & indices CreateMeshVertInd(); bMeshInited = true; } }
void SolveInteractions() { ComputeBuffer positionBuffer = new ComputeBuffer(Pedestrians.Length + 1, 8); ComputeBuffer velocityBuffer = new ComputeBuffer(Pedestrians.Length + 1, 8); int j = 0; for (j = 0; j < Pedestrians.Length; ++j) { Positions[j] = Pedestrians[j].GetComponent <PedestrianController>().position; Velocities[j] = Pedestrians[j].GetComponent <PedestrianController>().velocity; } Positions[j] = new Vector2(0, 0); Velocities[j] = new Vector2(0, 0); positionBuffer.SetData(Positions); AgentViewMaterial.SetBuffer("positionBuffer", positionBuffer); velocityBuffer.SetData(Velocities); AgentViewMaterial.SetBuffer("velocityBuffer", velocityBuffer); //1. First Render From Every Pedestrians PoV for (int i = 0; i < Pedestrians.Length; ++i) { Pedestrians[i].GetComponent <PedestrianController>().SolveInteraction(); } //2. Now Process the Resultant Texture if (RenderTargetTex && RenderTarget.IsCreated()) { RenderTexture.active = RenderTarget; RenderTargetTex.ReadPixels(new Rect(0, 0, RenderTarget.width, RenderTarget.height), 0, 0); RenderTargetTex.Apply(); // Launch CUDA Kernel uint textureSize = (uint)(RenderTargetTex.width * agentViewTexHeight); int threadsPerBlock = 1024; float threadsPerBlockInv = 1.0f / (float)threadsPerBlock; int blocksPerGrid = (int)((textureSize + threadsPerBlock - 1) * threadsPerBlockInv); /*******************************************************************/ /************************copyReductionKernel************************/ /*******************************************************************/ dim3 block = new dim3(threadsPerBlock, 1, 1); dim3 grid = new dim3(blocksPerGrid, 1, 1); uint shMemeSize = (uint)(block.x * 5 * sizeof(float)); // size of shared memory uint offset, currentNumData, currentNumBlocks; h_idata = RenderTargetTex.GetPixels(); for (int i = 0; i < h_idata.Length; i++) { h_idata_float4[i] = new float4(h_idata[i].r, h_idata[i].g, h_idata[i].b, h_idata[i].a); } d_idata.CopyToDevice(h_idata_float4); for (int i = pedStart; i < pedStop; i++) { offset = (uint)(i - pedStart) * (textureSize); currentNumData = textureSize; currentNumBlocks = (uint)blocksPerGrid; grid.x = currentNumBlocks; cudaKernel[0].BlockDimensions = block; cudaKernel[0].GridDimensions = grid; cudaKernel[0].DynamicSharedMemory = shMemeSize; cudaKernel[0].Run(d_idata.DevicePointer, d_odata.DevicePointer, 5, textureSize, offset); //Debug.Log("1: CUDA kernel launch with " + blocksPerGrid + " blocks of " + threadsPerBlock + " threads\n"); /*******************************************************************/ /**************************reductionKernel**************************/ /*******************************************************************/ currentNumData = currentNumBlocks; currentNumBlocks = (uint)((currentNumData + threadsPerBlock - 1) * threadsPerBlockInv); for (; currentNumData > 1;) { // perform reduction to get one pixel grid.x = currentNumBlocks; cudaKernel[1].BlockDimensions = block; cudaKernel[1].GridDimensions = grid; cudaKernel[1].DynamicSharedMemory = shMemeSize; cudaKernel[1].Run(d_odata.DevicePointer, 5, currentNumData); //Debug.Log("2: CUDA kernel launch with " + blocksPerGrid + " blocks of " + threadsPerBlock + " threads\n"); currentNumData = currentNumBlocks; currentNumBlocks = (uint)((currentNumData + threadsPerBlock - 1) * threadsPerBlockInv); } d_result_data.CopyToDevice(d_odata, 0, 5 * i * sizeof(float), 5 * sizeof(float)); } d_result_data.CopyToHost(h_result_data); RenderTexture.active = null; } //3. Now Calculate Agent Veclocity Based on Results from Step 2. for (int i = 0; i < Pedestrians.Length; ++i) { float thetaMax = 0; float thetaMin = 0; float ttcMin = 0; float dttcMin = 0; bool goFirstMin = true; bool goFirstMax = true; computeParams(i, ref thetaMax, ref thetaMin, ref ttcMin, ref dttcMin, ref goFirstMin, ref goFirstMax); // compute new velocity Pedestrians[i].GetComponent <PedestrianController>().updateVelocity(thetaMin, thetaMax, ttcMin, dttcMin, goFirstMin, goFirstMax); } }
private void GenerateWavesSpectrum() { // Slope variance due to all waves, by integrating over the full spectrum. // Used by the BRDF rendering model var theoreticSlopeVariance = 0.0f; var k = 5e-3f; while (k < 1e3f) { var nextK = k * 1.001f; theoreticSlopeVariance += k * k * Spectrum(k, 0, true) * (nextK - k); k = nextK; } var spectrum01 = new float[FourierGridSize * FourierGridSize * 4]; var spectrum23 = new float[FourierGridSize * FourierGridSize * 4]; int idx; float i; float j; float totalSlopeVariance = 0.0f; Vector2 sample12XY = Vector2.zero; Vector2 sample12ZW = Vector2.zero; Vector2 sample34XY = Vector2.zero; Vector2 sample34ZW = Vector2.zero; Random.InitState(0); for (int x = 0; x < FourierGridSize; x++) { for (int y = 0; y < FourierGridSize; y++) { idx = x + y * FourierGridSize; i = (x >= FourierGridSize / 2) ? (float)(x - FourierGridSize) : (float)x; j = (y >= FourierGridSize / 2) ? (float)(y - FourierGridSize) : (float)y; sample12XY = GetSpectrumSample(i, j, GridSizes.x, Mathf.PI / GridSizes.x); sample12ZW = GetSpectrumSample(i, j, GridSizes.y, Mathf.PI * FloatSize / GridSizes.x); sample34XY = GetSpectrumSample(i, j, GridSizes.z, Mathf.PI * FloatSize / GridSizes.y); sample34ZW = GetSpectrumSample(i, j, GridSizes.w, Mathf.PI * FloatSize / GridSizes.z); spectrum01[idx * 4 + 0] = sample12XY.x; spectrum01[idx * 4 + 1] = sample12XY.y; spectrum01[idx * 4 + 2] = sample12ZW.x; spectrum01[idx * 4 + 3] = sample12ZW.y; spectrum23[idx * 4 + 0] = sample34XY.x; spectrum23[idx * 4 + 1] = sample34XY.y; spectrum23[idx * 4 + 2] = sample34ZW.x; spectrum23[idx * 4 + 3] = sample34ZW.y; i *= 2.0f * Mathf.PI; j *= 2.0f * Mathf.PI; totalSlopeVariance += GetSlopeVariance(i / GridSizes.x, j / GridSizes.x, sample12XY); totalSlopeVariance += GetSlopeVariance(i / GridSizes.y, j / GridSizes.y, sample12ZW); totalSlopeVariance += GetSlopeVariance(i / GridSizes.z, j / GridSizes.z, sample34XY); totalSlopeVariance += GetSlopeVariance(i / GridSizes.w, j / GridSizes.w, sample34ZW); } } //Write floating point data into render texture ComputeBuffer buffer = new ComputeBuffer(FourierGridSize * FourierGridSize, sizeof(float) * 4); buffer.SetData(spectrum01); CBUtility.WriteIntoRenderTexture(Spectrum01, 4, buffer, GodManager.Instance.WriteData); buffer.SetData(spectrum23); CBUtility.WriteIntoRenderTexture(Spectrum23, 4, buffer, GodManager.Instance.WriteData); buffer.Release(); VarianceShader.SetFloat("_SlopeVarianceDelta", 0.5f * (theoreticSlopeVariance - totalSlopeVariance)); VarianceShader.SetFloat("_VarianceSize", (float)VarianceSize); VarianceShader.SetFloat("_Size", FloatSize); VarianceShader.SetVector("_GridSizes", GridSizes); VarianceShader.SetTexture(0, "_Spectrum01", Spectrum01); VarianceShader.SetTexture(0, "_Spectrum23", Spectrum23); VarianceShader.SetTexture(0, "des", Variance); VarianceShader.Dispatch(0, VarianceSize / 4, VarianceSize / 4, VarianceSize / 4); // Find the maximum value for slope variance buffer = new ComputeBuffer(VarianceSize * VarianceSize * VarianceSize, sizeof(float)); CBUtility.ReadFromRenderTexture(Variance, 1, buffer, GodManager.Instance.ReadData); var varianceData = new float[VarianceSize * VarianceSize * VarianceSize]; buffer.GetData(varianceData); MaxSlopeVariance = 0.0f; for (int v = 0; v < VarianceSize * VarianceSize * VarianceSize; v++) { MaxSlopeVariance = Mathf.Max(MaxSlopeVariance, varianceData[v]); } buffer.Release(); }
unsafe public void PrepareGPUShadowDatas(CullingResults cullResults, HDCamera camera) { if (m_MaxShadowRequests == 0) { return; } int shadowIndex = 0; m_ShadowDatas.Clear(); // Create all HDShadowDatas and update them with shadow request datas for (int i = 0; i < m_ShadowRequestCount; i++) { Debug.Assert(m_ShadowRequests[i] != null); HDShadowAtlas atlas = m_Atlas; if (m_ShadowRequests[i].isInCachedAtlas) { atlas = cachedShadowManager.punctualShadowAtlas; } if (m_ShadowRequests[i].shadowMapType == ShadowMapType.CascadedDirectional) { atlas = m_CascadeAtlas; } else if (m_ShadowRequests[i].shadowMapType == ShadowMapType.AreaLightAtlas) { atlas = m_AreaLightShadowAtlas; if (m_ShadowRequests[i].isInCachedAtlas) { atlas = cachedShadowManager.areaShadowAtlas; } } HDShadowData shadowData; if (m_ShadowRequests[i].shouldUseCachedShadowData) { shadowData = m_ShadowRequests[i].cachedShadowData; } else { shadowData = CreateShadowData(m_ShadowRequests[i], atlas); m_ShadowRequests[i].cachedShadowData = shadowData; } m_ShadowDatas.Add(shadowData); m_ShadowRequests[i].shadowIndex = shadowIndex++; } int first = k_DirectionalShadowCascadeCount, second = k_DirectionalShadowCascadeCount; fixed(float *sphereBuffer = m_DirectionalShadowData.sphereCascades) { Vector4 *sphere = (Vector4 *)sphereBuffer; for (int i = 0; i < k_DirectionalShadowCascadeCount; i++) { first = (first == k_DirectionalShadowCascadeCount && sphere[i].w > 0.0f) ? i : first; second = ((second == k_DirectionalShadowCascadeCount || second == first) && sphere[i].w > 0.0f) ? i : second; } } // Update directional datas: if (second != k_DirectionalShadowCascadeCount) { m_DirectionalShadowData.cascadeDirection = (GetCascadeSphereAtIndex(second) - GetCascadeSphereAtIndex(first)).normalized; } else { m_DirectionalShadowData.cascadeDirection = Vector4.zero; } m_DirectionalShadowData.cascadeDirection.w = camera.volumeStack.GetComponent <HDShadowSettings>().cascadeShadowSplitCount.value; if (m_ShadowRequestCount > 0) { // Upload the shadow buffers to GPU m_ShadowDataBuffer.SetData(m_ShadowDatas); m_CachedDirectionalShadowData[0] = m_DirectionalShadowData; m_DirectionalShadowDataBuffer.SetData(m_CachedDirectionalShadowData); } }
public void Init(IntTensorFactory _factory, int[] _shape, int[] _data = null, ComputeBuffer _dataBuffer = null, ComputeBuffer _shapeBuffer = null, ComputeBuffer _stridesBuffer = null, ComputeShader _shader = null, bool _copyData = true, bool _dataOnGpu = false, string _creation_op = null) { factory = _factory; dataOnGpu = _dataOnGpu; creation_op = _creation_op; // First: check that shape is valid. if (_shape == null || _shape.Length == 0) { throw new InvalidOperationException("Tensor shape can't be an empty array."); } // Second: since shape is valid, let's save it shape = (int[])_shape.Clone(); setStridesAndCheckShape(); // Third: let's see what kind of data we've got. We should either have // a GPU ComputeBuffer or a data[] object. if (_data != null && _shapeBuffer == null && _stridesBuffer == null && _dataBuffer == null) { InitCpu(_data: _data, _copyData: _copyData); } else if (_dataBuffer != null && _shapeBuffer != null && _stridesBuffer != null && SystemInfo.supportsComputeShaders && _data == null) { // looks like we have GPU data being passed in... initialize a GPU tensor. InitGpu(_shader, _dataBuffer, _shapeBuffer, _stridesBuffer, _copyData); } else { // no data seems to be passed in... or its got missing stuff // if CPU works... go with that if (_data != null) { InitCpu(_data, _copyData); } else if (_dataBuffer != null && _shader != null) { if (SystemInfo.supportsComputeShaders) { // seems i'm just missing a shape buffer - no biggie shapeBuffer = new ComputeBuffer(shape.Length, sizeof(int)); shapeBuffer.SetData(shape); InitGpu(_shader, _dataBuffer, _shapeBuffer, _stridesBuffer, _copyData); InitShaderKernels(); } else { throw new InvalidOperationException( "You seem to be trying to create a GPU tensor without having access to a GPU..."); } } else { // nothing else seems to work - i suppose i'm just supposed to initialize an empty tensor. long acc = 1; for (var i = shape.Length - 1; i >= 0; --i) { acc *= shape[i]; } if (_dataOnGpu) { _shapeBuffer = new ComputeBuffer(shape.Length, sizeof(int)); _shapeBuffer.SetData(shape); _stridesBuffer = new ComputeBuffer(shape.Length, sizeof(int)); _stridesBuffer.SetData(strides); _dataBuffer = new ComputeBuffer(size, sizeof(float)); InitGpu(_shader: _shader, _dataBuffer: _dataBuffer, _shapeBuffer: _shapeBuffer, _stridesBuffer: _stridesBuffer, _copyData: false); InitShaderKernels(); this.Zero_(); } else { _data = new int[acc]; InitCpu(_data, false); } } } // Lastly: let's set the ID of the tensor. // IDEs might show a warning, but ref and volatile seems to be working with Interlocked API. #pragma warning disable 420 id = System.Threading.Interlocked.Increment(ref nCreated); if (SystemInfo.supportsComputeShaders && shader == null) { shader = factory.GetShader(); InitShaderKernels(); } }
} // Awake() void Start() { //initialize others m_boids = this.gameObject.GetComponent <SimpleBoidsTreeOfVoice>(); //m_BoidBuffer = m_boids.m_BoidBuffer; if (m_boids == null) { Debug.LogError("SimpleBoidsTreeOfVoice component should be added to CommHub"); // Application.Quit(); #if UNITY_EDITOR // Application.Quit() does not work in the editor so // UnityEditor.EditorApplication.isPlaying = false; UnityEditor.EditorApplication.Exit(0); #else Application.Quit(); #endif } m_BoidLEDComputeShader.SetFloat("_CeilingInnerRadius", m_startingRadiusOfInnerChain); m_BoidLEDComputeShader.SetFloat("_MaxChainRadius", m_endingRadiusOfOuterChainThreeTurns); m_BoidLEDComputeShader.SetFloat("_Hemisphere", m_Hemisphere); m_BoidLEDComputeShader.SetFloat("_MaxDomainRadius", m_boids.m_MaxDomainRadius); // m_BoidLEDComputeShader.SetFloat("_MinDomainRadius", m_boids.m_MinDomainRadius); m_BoidLEDComputeShader.SetFloat("_CeilingInnerRadius", m_boids.m_CeilingInnerRadius); //m_BoidsNum = (int)m_boids.m_BoidsNum; m_BoidLEDComputeShader.SetInt("_BoidsNum", (int)m_boids.m_BoidsNum); m_BoidLEDComputeShader.SetBuffer(m_kernelIDLED, "_BoidBuffer", m_boids.m_BoidBuffer); m_BoidLEDComputeShader.SetInt("_ColorSamplingMethod", m_colorSamplingMethod); m_BoidLEDComputeShader.SetFloat("_SamplingRadius", m_samplingRadius); m_BoidLEDComputeShader.SetFloat("_NeighborRadius", m_neighborRadius); //define BoidLED Buffer m_BoidLEDBuffer = new ComputeBuffer(m_totalNumOfLEDs, Marshal.SizeOf(typeof(BoidLEDData))); m_BoidLEDArray = new BoidLEDData[m_totalNumOfLEDs]; //For each kernel we are setting the buffers that are used by the kernel, so it would read and write to those buffers // For the part of boidArray that is set by data are filled by null. // When the array boidArray is created each element is set by null. // create a m_BoidLEDArray to link to m_BoidLEDBuffer: SetBoidLEDArray(m_BoidLEDArray); // THe Boid LEDs array is defined without their colors m_BoidLEDBuffer.SetData(m_BoidLEDArray); // buffer is R or RW m_BoidLEDComputeShader.SetBuffer(m_kernelIDLED, "_BoidLEDBuffer", m_BoidLEDBuffer); }// void Start()
void Start() { transform.position = HivePosition; swarmKernel = swarmComputeShader.FindKernel("SwarmMain"); worldKernel = swarmComputeShader.FindKernel("WorldUpdateMain"); // Create rotation matrices CreateRotationMatrices(); // Create and init compute buffers worldTexture = CreateRenderTexture(); swarmBuffer = new ComputeBuffer(numSwarmers, 56); Swarmer[] swarmers = new Swarmer[numSwarmers]; for (int i = 0; i < swarmers.Length; i++) { swarmers[i].position = HivePosition + new Vector3(Random.Range(-spawnRange, spawnRange), Random.Range(-spawnRange, spawnRange), Random.Range(-spawnRange, spawnRange)); swarmers[i].previousPosition = swarmers[i].position; swarmers[i].direction = new Vector3(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f)).normalized; swarmers[i].life = Random.Range(0f, 3.0f); swarmers[i].startDelay = 0; swarmers[i].color = new Vector3(0, 0, 0); } swarmBuffer.SetData(swarmers); // Set swarm comput shader data swarmComputeShader.SetInt("width", worldSize.x); swarmComputeShader.SetInt("height", worldSize.y); swarmComputeShader.SetInt("depth", worldSize.z); swarmComputeShader.SetTexture(swarmKernel, "worldTex", worldTexture); swarmComputeShader.SetBuffer(swarmKernel, "swarmers", swarmBuffer); swarmComputeShader.SetFloats("hiveX", HivePosition.x); swarmComputeShader.SetFloats("hiveY", HivePosition.y); swarmComputeShader.SetFloats("hiveZ", HivePosition.z); swarmComputeShader.SetFloats("traceAdd", traceAdd); swarmComputeShader.SetFloats("traceDecay", traceDecay); swarmComputeShader.SetFloat("traceAttraction", traceAttraction); swarmComputeShader.SetFloat("swarmerSpeed", swarmerSpeed); swarmComputeShader.SetMatrix("rot1", rotMat1); swarmComputeShader.SetMatrix("rot2", rotMat2); swarmComputeShader.SetMatrix("rot3", rotMat3); swarmComputeShader.SetMatrix("rot4", rotMat4); swarmComputeShader.SetMatrix("rot5", rotMat5); swarmComputeShader.SetMatrix("rot6", rotMat6); swarmComputeShader.SetFloat("randomness", randomness); swarmComputeShader.SetTexture(worldKernel, "worldTex", worldTexture); Debug.Log($"Hiveposition: {HivePosition}"); // Set rendering materials data swarmerMaterial.SetBuffer("swarmers", swarmBuffer); // Debug debugWorldNodes = new WorldNode[NumWorldNodes]; }
void BuildGPULightVolumes(HDCamera hdCamera, HDRayTracingLights rayTracingLights) { int totalNumLights = rayTracingLights.lightCount; // Make sure the light volume buffer has the right size if (m_LightVolumesCPUArray == null || totalNumLights != m_LightVolumesCPUArray.Length) { ResizeVolumeBuffer(totalNumLights); } // Set Light volume data to the CPU buffer punctualLightCount = 0; areaLightCount = 0; envLightCount = 0; totalLightCount = 0; int realIndex = 0; for (int lightIdx = 0; lightIdx < rayTracingLights.hdLightArray.Count; ++lightIdx) { HDAdditionalLightData currentLight = rayTracingLights.hdLightArray[lightIdx]; // When the user deletes a light source in the editor, there is a single frame where the light is null before the collection of light in the scene is triggered // the workaround for this is simply to not add it if it is null for that invalid frame if (currentLight != null) { Light light = currentLight.gameObject.GetComponent <Light>(); if (light == null || !light.enabled) { continue; } // If the light is flagged as baked and has been effectively been baked, we need to skip it and not add it to the light cluster if (light.bakingOutput.lightmapBakeType == LightmapBakeType.Baked && light.bakingOutput.isBaked) { continue; } // If this light should not be included when ray tracing is active on the camera, skip it if (hdCamera.frameSettings.IsEnabled(FrameSettingsField.RayTracing) && !currentLight.includeForRayTracing) { continue; } // Reserve space in the cookie atlas m_RenderPipeline.ReserveCookieAtlasTexture(currentLight, light, currentLight.type); // Compute the camera relative position Vector3 lightPositionRWS = currentLight.gameObject.transform.position; if (ShaderConfig.s_CameraRelativeRendering != 0) { lightPositionRWS -= hdCamera.camera.transform.position; } // Grab the light range float lightRange = light.range; if (currentLight.type != HDLightType.Area) { m_LightVolumesCPUArray[realIndex].range = new Vector3(lightRange, lightRange, lightRange); m_LightVolumesCPUArray[realIndex].position = lightPositionRWS; m_LightVolumesCPUArray[realIndex].active = (currentLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[realIndex].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[realIndex].shape = 0; m_LightVolumesCPUArray[realIndex].lightType = 0; punctualLightCount++; } else { // let's compute the oobb of the light influence volume first Vector3 oobbDimensions = new Vector3(currentLight.shapeWidth + 2 * lightRange, currentLight.shapeHeight + 2 * lightRange, lightRange); // One-sided Vector3 extents = 0.5f * oobbDimensions; Vector3 oobbCenter = lightPositionRWS + extents.z * currentLight.gameObject.transform.forward; // Let's now compute an AABB that matches the previously defined OOBB OOBBToAABBBounds(oobbCenter, extents, currentLight.gameObject.transform.up, currentLight.gameObject.transform.right, currentLight.gameObject.transform.forward, ref bounds); // Fill the volume data m_LightVolumesCPUArray[realIndex].range = bounds.extents; m_LightVolumesCPUArray[realIndex].position = bounds.center; m_LightVolumesCPUArray[realIndex].active = (currentLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[realIndex].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[realIndex].shape = 1; m_LightVolumesCPUArray[realIndex].lightType = 1; areaLightCount++; } realIndex++; } } int indexOffset = realIndex; // Set Env Light volume data to the CPU buffer for (int lightIdx = 0; lightIdx < rayTracingLights.reflectionProbeArray.Count; ++lightIdx) { HDProbe currentEnvLight = rayTracingLights.reflectionProbeArray[lightIdx]; if (currentEnvLight != null) { // If the reflection probe is disabled, we should not be adding it if (!currentEnvLight.enabled) { continue; } // Compute the camera relative position Vector3 probePositionRWS = currentEnvLight.influenceToWorld.GetColumn(3); if (ShaderConfig.s_CameraRelativeRendering != 0) { probePositionRWS -= hdCamera.camera.transform.position; } if (currentEnvLight.influenceVolume.shape == InfluenceShape.Sphere) { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 0; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius, currentEnvLight.influenceVolume.sphereRadius); m_LightVolumesCPUArray[lightIdx + indexOffset].position = probePositionRWS; } else { m_LightVolumesCPUArray[lightIdx + indexOffset].shape = 1; m_LightVolumesCPUArray[lightIdx + indexOffset].range = new Vector3(currentEnvLight.influenceVolume.boxSize.x / 2.0f, currentEnvLight.influenceVolume.boxSize.y / 2.0f, currentEnvLight.influenceVolume.boxSize.z / 2.0f); m_LightVolumesCPUArray[lightIdx + indexOffset].position = probePositionRWS; } m_LightVolumesCPUArray[lightIdx + indexOffset].active = (currentEnvLight.gameObject.activeInHierarchy ? 1 : 0); m_LightVolumesCPUArray[lightIdx + indexOffset].lightIndex = (uint)lightIdx; m_LightVolumesCPUArray[lightIdx + indexOffset].lightType = 2; envLightCount++; } } totalLightCount = punctualLightCount + areaLightCount + envLightCount; // Push the light volumes to the GPU m_LightVolumeGPUArray.SetData(m_LightVolumesCPUArray); }
/// <summary> /// Generates the grid for the hexagons to spawn /// </summary> private void RegenerateGrid() { // Hexagon base number count on both axis float cx = _viewWidth / (_gridHexSize * magicNumber), cy = _viewHeight / (_gridHexSize * 3); // iy Rows of ix hexagons (half of the grid, centered) int ix = Mathf.CeilToInt(cx) - 1, iy = Mathf.CeilToInt(cy) - 1; // Corrections if (_gridHexSize * 2 < _viewHeight - iy * _gridHexSize * 3) { iy++; } if (.5f < cx - ix) { ix++; } // jy Rows of jx hexagons (other half of the grid, offset by half a hexagon on the X axis) int jx = ix + (cx > ix ? 1 : 0), jy = iy + (cy - iy > .25 ? 1 : 0); // The count of hexagons total needed for this grid _hexagonCount = (iy * 2 + 1) * (ix * 2 + 1) + jy * 2 * jx * 2; List <Vector3> vectors = new List <Vector3>(); // Don't generate if the hexagon spacing is too small if (_gridHexSize < .01) { return; } // First half of the grid for (int y = -iy; y <= iy; y++) { for (int x = -ix; x <= ix; x++) { vectors.Add(new Vector3(x * _gridHexSize * magicNumberHalf, y * _gridHexSize * 1.5f) + transform.position); } } // Second half of the grid (the offset ones) for (int y = -jy; y < jy; y++) { for (int x = -jx; x < jx; x++) { vectors.Add(new Vector3((x + .5f) * _gridHexSize * magicNumberHalf, (y + .5f) * _gridHexSize * 1.5f) + transform.position); } } // Clear the old buffer and set a new one _positionBuffer?.Release(); _positionBuffer = new ComputeBuffer(vectors.Count, sizeof(float) * 3); _positionBuffer.SetData(vectors.ToArray()); GC.SuppressFinalize(_positionBuffer); // Assing the buffer to the materials _materialIn.SetBuffer(_bufferID, _positionBuffer); _materialOut.SetBuffer(_bufferID, _positionBuffer); // Find the distance of the farthest hexagon from the center float mx = (jx > ix ? jx + .5f : ix) * _gridHexSize * magicNumberHalf; float my = (jy > iy ? jy + .5f : iy) * _gridHexSize * 1.5f; _maxSize = new Vector2(mx, my).magnitude; // Save the distance to materials _materialIn.SetFloat(_gridMaxID, _maxSize); _materialOut.SetFloat(_gridMaxID, _maxSize); }
public override void Setup(ScriptableRenderContext context, ref MyRenderingData renderingData) { if (needUpdate) { if (!computeShader || !material || !mesh) { return; } if (boidBuffer != null) { boidBuffer.Current.Release(); boidBuffer.Next.Release(); } if (argsBuffer != null) { argsBuffer.Release(); } boidBuffer = new DoubleBuffer <ComputeBuffer>((i) => new ComputeBuffer(count, EntityData.Size)); var data = new EntityData[count]; for (var i = 0; i < count; i++) { data[i] = new EntityData() { position = Random.insideUnitSphere * distributeRadius + spawnPoint.position, velocity = Random.insideUnitSphere, }; data[i].velocity = data[i].velocity.normalized * (data[i].velocity.magnitude * (maxSpeed - minSpeed) + minSpeed); var up = Random.onUnitSphere; var right = Vector3.Cross(data[i].velocity, up); if (Mathf.Approximately(right.magnitude, 0)) { var v = data[i].velocity; float x = Mathf.Abs(v.x); float y = Mathf.Abs(v.y); float z = Mathf.Abs(v.z); if (x < y && x < z) { right = Vector3.right; } else if (y < x && y < z) { right = Vector3.up; } else { right = Vector3.forward; } } up = Vector3.Cross(right, data[i].velocity); data[i].up = up.normalized; } boidBuffer.Current.SetData(data); boidBuffer.Next.SetData(data); //要绘制多少个实例的参数来自bufferWithArgs //Buffer with arguments, bufferWithArgs, has to have five integer numbers at given argsOffset offset: index count per instance, instance count, start index location, base vertex location, start instance location. //2是 ebo 3 是 vbo //带参数的bufferWithArgs,在给定的argsOffset偏移量处必须有五个整数:每个实例的索引计数、实例计数、起始索引位置、基顶点位置、开始实例的偏移。 args[0] = mesh.GetIndexCount(0); args[1] = (uint)count; args[2] = mesh.GetIndexStart(0); args[3] = mesh.GetBaseVertex(0); argsBuffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments); argsBuffer.SetData(args); needUpdate = false; } }
void SetupComputeShader() { if (r != null) { r.Release(); } if (r1 != null) { r1.Release(); } if (u != null) { u.Release(); } if (u1 != null) { u1.Release(); } int count = size.x * size.y * size.z; r = new ComputeBuffer(count, sizeof(float)); r1 = new ComputeBuffer(count, sizeof(float)); rData = new float[count]; for (int x = 0; x < size.x; x++) { for (int y = 0; y < size.y; y++) { for (int z = 0; z < size.z; z++) { rData[x + y * size.x + z * size.x * size.y] = 1; } } } r.SetData(rData); r1.SetData(rData); u = new ComputeBuffer(count, sizeof(float) * 3); u1 = new ComputeBuffer(count, sizeof(float) * 3); uData = new Vector3[count]; for (int i = 0; i < count; i++) { uData[i] = new Vector3(); } u.SetData(uData); u1.SetData(uData); renderTexture = new RenderTexture(renderTexture); renderTexture.enableRandomWrite = true; renderTexture.wrapMode = TextureWrapMode.Repeat; renderTexture.Create(); imageSize = new Vector2Int(renderTexture.width, renderTexture.height); shader.SetBuffer(R, "r", r); shader.SetBuffer(R, "r1", r1); shader.SetBuffer(R, "u", u); shader.SetBuffer(U, "r1", r1); shader.SetBuffer(U, "u", u); shader.SetBuffer(U, "u1", u1); shader.SetBuffer(Upd, "r", r); shader.SetBuffer(Upd, "r1", r1); shader.SetBuffer(Upd, "u", u); shader.SetBuffer(Upd, "u1", u1); shader.SetBuffer(Out, "r", r); shader.SetBuffer(Out, "u", u); shader.SetTexture(Out, "o", renderTexture); }
private void InitializeComputeBuffers() { // first-time setup for compute buffers (assume new brain) if (tempNeuronList == null || tempAxonList == null) { CreateDummyBrain(); } // NEURON INIT DATA if (neuronInitDataCBuffer != null) { neuronInitDataCBuffer.Release(); } neuronInitDataCBuffer = new ComputeBuffer(numNeurons, sizeof(float) * 3); NeuronInitData[] neuronInitDataArray = new NeuronInitData[numNeurons]; // for now only one seed data for (int x = 0; x < neuronInitDataArray.Length; x++) { NeuronInitData neuronData = new NeuronInitData(); //neuronData.pos = Vector3.zero; // refBrain.neuronList[x].pos; neuronData.radius = 1.6f; neuronData.type = (float)tempNeuronList[x].neuronType / 2.0f; neuronData.age = UnityEngine.Random.Range(0f, 1f); // refBrain.neuronList[x].age; neuronInitDataArray[x] = neuronData; } neuronInitDataCBuffer.SetData(neuronInitDataArray); // NEURON FEED DATA if (neuronFeedDataCBuffer != null) { neuronFeedDataCBuffer.Release(); } neuronFeedDataCBuffer = new ComputeBuffer(numNeurons, sizeof(float) * 1); NeuronFeedData[] neuronValuesArray = new NeuronFeedData[numNeurons]; Debug.Log(neuronValuesArray.Length.ToString() + ", numNeurons: " + numNeurons.ToString()); for (int i = 0; i < neuronValuesArray.Length; i++) { neuronValuesArray[i].curValue = tempNeuronList[i].currentValue[0]; } neuronFeedDataCBuffer.SetData(neuronValuesArray); // NEURON SIM DATA if (neuronSimDataCBuffer != null) { neuronSimDataCBuffer.Release(); } neuronSimDataCBuffer = new ComputeBuffer(numNeurons, sizeof(float) * 3); // One-time initialization of positions:::: NeuronSimData[] neuronSimDataArray = new NeuronSimData[numNeurons]; for (int i = 0; i < neuronSimDataArray.Length; i++) { neuronSimDataArray[i].pos = UnityEngine.Random.onUnitSphere * 12f; //refBrain.neuronList[i].pos; if (tempNeuronList[i].neuronType == NeuronGenome.NeuronType.In) { neuronSimDataArray[i].pos.x = -6.0f * Mathf.Abs(neuronSimDataArray[i].pos.x); } else { neuronSimDataArray[i].pos.x = 6.0f * Mathf.Abs(neuronSimDataArray[i].pos.x); } } neuronSimDataCBuffer.SetData(neuronSimDataArray); // AXON INIT DATA if (axonInitDataCBuffer != null) { axonInitDataCBuffer.Release(); } axonInitDataCBuffer = new ComputeBuffer(tempAxonList.Count, sizeof(float) * 1 + sizeof(int) * 2); AxonInitData[] axonInitDataArray = new AxonInitData[tempAxonList.Count]; // for now only one seed data for (int x = 0; x < axonInitDataArray.Length; x++) { AxonInitData axonData = new AxonInitData(); axonData.weight = tempAxonList[x].weight; axonData.fromID = tempAxonList[x].fromID; axonData.toID = tempAxonList[x].toID; axonInitDataArray[x] = axonData; } axonInitDataCBuffer.SetData(axonInitDataArray); // AXON SIM DATA if (axonSimDataCBuffer != null) { axonSimDataCBuffer.Release(); } axonSimDataCBuffer = new ComputeBuffer(tempAxonList.Count, sizeof(float) * 13); // TRIANGLE BUFFER: // SET UP GEO BUFFER and REFS::::: if (appendTrianglesCBuffer != null) { appendTrianglesCBuffer.Release(); } Debug.Log("Max Tris: " + (numNeurons * maxTrisPerNeuron + tempAxonList.Count * maxTrisPerAxon).ToString()); appendTrianglesCBuffer = new ComputeBuffer(numNeurons * maxTrisPerNeuron + tempAxonList.Count * maxTrisPerAxon, sizeof(float) * 27, ComputeBufferType.Append); // vector3 position * 3 verts appendTrianglesCBuffer.SetCounterValue(0); // Hook Buffers Up to Shaders!!! // populate initial data for neurons // populate initial data for axons // feed neuronValues data to shader (encapsulate in function since this is ongoing) // simulate movements / animation parameters // generate neuron triangles // generate axon triangles int initKernelID = shaderComputeBrain.FindKernel("CSInitializeAxonSimData"); shaderComputeBrain.SetBuffer(initKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(initKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(initKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(initKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(initKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.SetFloat("minAxonRadius", 0.02f); shaderComputeBrain.SetFloat("maxAxonRadius", 0.28f); shaderComputeBrain.SetFloat("minNeuronRadius", 0.8f); shaderComputeBrain.SetFloat("maxNeuronRadius", 1.5f); shaderComputeBrain.SetFloat("neuronAttractForce", 0.0001f); shaderComputeBrain.SetFloat("axonStraightenForce", .00001f); shaderComputeBrain.SetFloat("neuronRepelForce", 240.0f); shaderComputeBrain.SetFloat("axonRepelForce", 360f); int simNeuronAttractKernelID = shaderComputeBrain.FindKernel("CSSimNeuronAttract"); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(simNeuronAttractKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); int simNeuronRepelKernelID = shaderComputeBrain.FindKernel("CSSimNeuronRepel"); int simAxonRepelKernelID = shaderComputeBrain.FindKernel("CSSimAxonRepel"); int neuronTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateNeuronTriangles"); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); //shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); //shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.SetBuffer(neuronTrianglesKernelID, "appendTrianglesCBuffer", appendTrianglesCBuffer); int axonTrianglesKernelID = shaderComputeBrain.FindKernel("CSGenerateAxonTriangles"); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronInitDataCBuffer", neuronInitDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronFeedDataCBuffer", neuronFeedDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "neuronSimDataCBuffer", neuronSimDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "axonInitDataCBuffer", axonInitDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "axonSimDataCBuffer", axonSimDataCBuffer); shaderComputeBrain.SetBuffer(axonTrianglesKernelID, "appendTrianglesCBuffer", appendTrianglesCBuffer); displayMaterial = new Material(shaderDisplayBrain); displayMaterial.SetPass(0); displayMaterial.SetBuffer("appendTrianglesBuffer", appendTrianglesCBuffer); // link computeBuffer to both computeShader and displayShader so they share the same one!! shaderComputeBrain.Dispatch(initKernelID, numAxons, 1, 1); // initialize axon positions and attributes shaderComputeBrain.Dispatch(simNeuronAttractKernelID, numAxons, 1, 1); // Simulate!! move neuron and axons around shaderComputeBrain.Dispatch(simNeuronRepelKernelID, numNeurons, numNeurons, 1); // Simulate!! move neuron and axons around shaderComputeBrain.Dispatch(simAxonRepelKernelID, numAxons, numAxons, 1); // Simulate!! move neuron and axons around shaderComputeBrain.Dispatch(neuronTrianglesKernelID, numNeurons, 1, 1); // create all triangles from Neurons shaderComputeBrain.Dispatch(axonTrianglesKernelID, numAxons, 1, 1); // create all geometry for Axons args[0] = 0; // set later by counter;// 3; // 3 vertices to start args[1] = 1; // 1 instance/copy argsCBuffer.SetData(args); ComputeBuffer.CopyCount(appendTrianglesCBuffer, argsCBuffer, 0); argsCBuffer.GetData(args); Debug.Log("triangle count " + args[0]); }
void Start() { Application.targetFrameRate = 300; // Create initial positions total = x * y * z; m_matrices = new Matrix4x4[total]; positionArray = new Vector3[total]; quaternionArray = new Quaternion[total]; rigidBodyVelocitiesArray = new Vector3[total]; m_cubeScale = new Vector3(scale, scale, scale); m_deltaTimeShaderProperty = Shader.PropertyToID("deltaTime"); const int particlesPerBody = 8; int n_particles = particlesPerBody * total; int numGridCells = gridX * gridY * gridZ; particleForcesArray = new Vector3[n_particles]; for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { for (int k = 0; k < z; k++) { positionArray[IDX(i, j, k)] = new Vector3(i * scale, j * scale, k * scale) + new Vector3(0.5f * scale, 0.5f * scale, 0.5f * scale); quaternionArray[IDX(i, j, k)] = Quaternion.identity; rigidBodyVelocitiesArray[IDX(i, j, k)] = Vector3.zero; } } } // rigid body velocities positionArray[IDX(0, y - 1, 0)] = m_firstCubeLocation; rigidBodyVelocitiesArray[IDX(0, y - 1, 0)] = m_firstCubeVelocity; quaternionArray[IDX(0, y - 1, 0)] = Quaternion.Euler(m_firstCubeRotation); particleVelocities = new Vector3[n_particles]; particlePositions = new Vector3[n_particles]; particleRelativePositions = new Vector3[n_particles]; debugParticleIds = new int[debug_particle_id_count]; voxelGridArray = new int[numGridCells * 4]; particleVoxelPositionsArray = new int[n_particles * 3]; // Get Kernels m_kernel_generateParticleValues = m_computeShader.FindKernel("GenerateParticleValues"); m_kernel_clearGrid = m_computeShader.FindKernel("ClearGrid"); m_kernel_populateGrid = m_computeShader.FindKernel("PopulateGrid"); m_kernel_collisionDetection = m_computeShader.FindKernel("CollisionDetection"); m_kernel_computeMomenta = m_computeShader.FindKernel("ComputeMomenta"); m_kernel_computePositionAndRotation = m_computeShader.FindKernel("ComputePositionAndRotation"); m_kernelSavePreviousPositionAndRotation = m_computeShader.FindKernel("SavePreviousPositionAndRotation"); // Count Thread Groups m_threadGroupsPerRigidBody = Mathf.CeilToInt(total / 8.0f); m_threadGroupsPerParticle = Mathf.CeilToInt(n_particles / 8f); m_threadGroupsPerGridCell = Mathf.CeilToInt((gridX * gridY * gridZ) / 8f); // Create initial buffers const int floatThree = 3 * sizeof(float); const int floatFour = 4 * sizeof(float); const int intFour = 4 * sizeof(int); const int intThree = 3 * sizeof(int); m_rigidBodyPositions = new ComputeBuffer(total, floatThree); m_previousRigidBodyPositions = new ComputeBuffer(total, floatThree); m_rigidBodyQuaternions = new ComputeBuffer(total, floatFour); m_previousRigidBodyQuaternions = new ComputeBuffer(total, floatFour); m_rigidBodyAngularVelocities = new ComputeBuffer(total, floatThree); m_rigidBodyVelocities = new ComputeBuffer(total, floatThree); m_particleInitialRelativePositions = new ComputeBuffer(n_particles, floatThree); m_particlePositions = new ComputeBuffer(n_particles, floatThree); m_particleRelativePositions = new ComputeBuffer(n_particles, floatThree); m_particleVelocities = new ComputeBuffer(n_particles, floatThree); m_particleForces = new ComputeBuffer(n_particles, floatThree); m_voxelCollisionGrid = new ComputeBuffer(numGridCells, intFour); m_debugParticleVoxelPositions = new ComputeBuffer(n_particles, intThree); m_debugParticleIds = new ComputeBuffer(debug_particle_id_count, sizeof(int)); Debug.Log("nparticles: " + n_particles); // initialize constants int[] gridDimensions = new int[] { gridX, gridY, gridZ }; m_computeShader.SetInts("gridDimensions", gridDimensions); m_computeShader.SetInt("gridMax", numGridCells); m_computeShader.SetFloat("particleDiameter", scale * 0.5f); m_computeShader.SetFloat("springCoefficient", springCoefficient); m_computeShader.SetFloat("dampingCoefficient", dampingCoefficient); m_computeShader.SetFloat("frictionCoefficient", frictionCoefficient); m_computeShader.SetFloat("angularFrictionCoefficient", angularFrictionCoefficient); m_computeShader.SetFloat("gravityCoefficient", gravityCoefficient); m_computeShader.SetFloat("tangentialCoefficient", tangentialCoefficient); m_computeShader.SetFloat("angularForceScalar", angularForceScalar); m_computeShader.SetFloat("linearForceScalar", linearForceScalar); m_computeShader.SetFloat("particleMass", m_cubeMass / particlesPerBody); m_computeShader.SetFloats("gridStartPosition", new float[] { gridStartPosition.x, gridStartPosition.y, gridStartPosition.z }); // Inertial tensor of a cube formula taken from textbook: // "Essential Mathematics for Games and Interactive Applications" // by James Van Verth and Lars Bishop float twoDimSq = 2.0f * (scale * scale); float inertialTensorFactor = m_cubeMass * 1.0f / 12.0f * twoDimSq; float[] inertialTensor = { inertialTensorFactor, 0.0f, 0.0f, 0.0f, inertialTensorFactor, 0.0f, 0.0f, 0.0f, inertialTensorFactor }; float[] inverseInertialTensor; GPUPhysics.Invert(ref inertialTensor, out inverseInertialTensor); float[] quickInverseInertialTensor = { 1.0f / inertialTensorFactor, 0.0f, 0.0f, 0.0f, 1.0f / inertialTensorFactor, 0.0f, 0.0f, 0.0f, 1.0f / inertialTensorFactor }; m_computeShader.SetFloats("inertialTensor", inertialTensor); m_computeShader.SetFloats("inverseInertialTensor", inverseInertialTensor); // initialize buffers // initial relative positions // super dependent on 8/rigid body float quarterScale = scale * 0.25f; particleInitialRelativePositions = new Vector3[n_particles]; Vector3[] particleInitialsSmall = new Vector3[particlesPerBody]; particleInitialsSmall[0] = new Vector3(quarterScale, quarterScale, quarterScale); particleInitialsSmall[1] = new Vector3(-quarterScale, quarterScale, quarterScale); particleInitialsSmall[2] = new Vector3(quarterScale, quarterScale, -quarterScale); particleInitialsSmall[3] = new Vector3(-quarterScale, quarterScale, -quarterScale); particleInitialsSmall[4] = new Vector3(quarterScale, -quarterScale, quarterScale); particleInitialsSmall[5] = new Vector3(-quarterScale, -quarterScale, quarterScale); particleInitialsSmall[6] = new Vector3(quarterScale, -quarterScale, -quarterScale); particleInitialsSmall[7] = new Vector3(-quarterScale, -quarterScale, -quarterScale); for (int i = 0; i < particleInitialRelativePositions.Length; i++) { particleInitialRelativePositions[i] = particleInitialsSmall[i % 8]; } m_particleInitialRelativePositions.SetData(particleInitialRelativePositions); // rigid body positions m_rigidBodyPositions.SetData(positionArray); // rigid body quaternions m_rigidBodyQuaternions.SetData(quaternionArray); m_rigidBodyVelocities.SetData(rigidBodyVelocitiesArray); // Set matricies to initial positions SetMatrices(positionArray, quaternionArray); // Bind buffers // kernel 0 GenerateParticleValues m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyQuaternions", m_rigidBodyQuaternions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleInitialRelativePositions", m_particleInitialRelativePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particlePositions", m_particlePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleRelativePositions", m_particleRelativePositions); m_computeShader.SetBuffer(m_kernel_generateParticleValues, "particleVelocities", m_particleVelocities); //m_computeShader.SetBuffer(m_kernel_generateParticleValues, "debugParticleIds", m_debugParticleIds); // kernel 1 ClearGrid m_computeShader.SetBuffer(m_kernel_clearGrid, "voxelCollisionGrid", m_voxelCollisionGrid); // kernel 2 Populate Grid m_computeShader.SetBuffer(m_kernel_populateGrid, "debugParticleVoxelPositions", m_debugParticleVoxelPositions); m_computeShader.SetBuffer(m_kernel_populateGrid, "voxelCollisionGrid", m_voxelCollisionGrid); m_computeShader.SetBuffer(m_kernel_populateGrid, "particlePositions", m_particlePositions); //m_computeShader.SetBuffer(m_kernel_populateGrid, "debugParticleIds", m_debugParticleIds); // kernel 3 Collision Detection m_computeShader.SetBuffer(m_kernel_collisionDetection, "particlePositions", m_particlePositions); m_computeShader.SetBuffer(m_kernel_collisionDetection, "particleVelocities", m_particleVelocities); m_computeShader.SetBuffer(m_kernel_collisionDetection, "voxelCollisionGrid", m_voxelCollisionGrid); m_computeShader.SetBuffer(m_kernel_collisionDetection, "particleForces", m_particleForces); // kernel 4 Computation of Momenta m_computeShader.SetBuffer(m_kernel_computeMomenta, "particleForces", m_particleForces); m_computeShader.SetBuffer(m_kernel_computeMomenta, "particleRelativePositions", m_particleRelativePositions); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_computeMomenta, "debugParticleIds", m_debugParticleIds); m_computeShader.SetBuffer(m_kernel_computeMomenta, "rigidBodyQuaternions", m_rigidBodyQuaternions); // kernel 5 Compute Position and Rotation m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyVelocities", m_rigidBodyVelocities); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyAngularVelocities", m_rigidBodyAngularVelocities); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernel_computePositionAndRotation, "rigidBodyQuaternions", m_rigidBodyQuaternions); // kernel 6 Save Previous Position and Rotation m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "rigidBodyPositions", m_rigidBodyPositions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "rigidBodyQuaternions", m_rigidBodyQuaternions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "previousRigidBodyPositions", m_previousRigidBodyPositions); m_computeShader.SetBuffer(m_kernelSavePreviousPositionAndRotation, "previousRigidBodyQuaternions", m_previousRigidBodyQuaternions); // Setup Indirect Renderer uint[] sphereArgs = new uint[] { sphereMesh.GetIndexCount(0), (uint)n_particles, 0, 0, 0 }; m_bufferWithSphereArgs = new ComputeBuffer(1, sphereArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_bufferWithSphereArgs.SetData(sphereArgs); uint[] lineArgs = new uint[] { lineMesh.GetIndexCount(0), (uint)n_particles, 0, 0, 0 }; m_bufferWithLineArgs = new ComputeBuffer(1, lineArgs.Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_bufferWithLineArgs.SetData(lineArgs); cubeMaterial.SetBuffer("positions", m_rigidBodyPositions); cubeMaterial.SetBuffer("previousPositions", m_previousRigidBodyPositions); cubeMaterial.SetBuffer("quaternions", m_rigidBodyQuaternions); cubeMaterial.SetBuffer("previousQuaternions", m_previousRigidBodyQuaternions); sphereMaterial.SetBuffer("positions", m_particlePositions); sphereMaterial.SetVector("scale", new Vector4(0.25f, 0.25f, 0.25f, 1.0f)); lineMaterial.SetBuffer("positions", m_particlePositions); lineMaterial.SetBuffer("vectors", m_particleVelocities); // Setup Command Buffer m_commandBuffer = new CommandBuffer(); m_commandBuffer.BeginSample("GenerateParticleValues"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_generateParticleValues, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("GenerateParticleValues"); m_commandBuffer.BeginSample("ClearGrid"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_clearGrid, m_threadGroupsPerGridCell, 1, 1); m_commandBuffer.EndSample("ClearGrid"); m_commandBuffer.BeginSample("PopulateGrid"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_populateGrid, m_threadGroupsPerParticle, 1, 1); m_commandBuffer.EndSample("PopulateGrid"); m_commandBuffer.BeginSample("CollisionDetection"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_collisionDetection, m_threadGroupsPerParticle, 1, 1); m_commandBuffer.EndSample("CollisionDetection"); m_commandBuffer.BeginSample("ComputeMomenta"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_computeMomenta, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("ComputeMomenta"); m_commandBuffer.BeginSample("ComputePositions"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernel_computePositionAndRotation, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("ComputePositions"); m_commandBuffer.BeginSample("SavePreviousPositionAndRotation"); m_commandBuffer.DispatchCompute(m_computeShader, m_kernelSavePreviousPositionAndRotation, m_threadGroupsPerRigidBody, 1, 1); m_commandBuffer.EndSample("SavePreviousPositionAndRotation"); // rendering in command buffer - doesnt work for now seems like a unity bug #if !(UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) // Command Buffer DrawMeshInstancedIndirect doesnt work on my mac // rendering from command buffer via update isnt working so disabling this is necessary for delta time use // m_commandBuffer.BeginSample("DrawMeshInstancedIndirect"); // m_commandBuffer.DrawMeshInstancedIndirect(cubeMesh, 0, cubeMaterial, 0, m_bufferWithArgs); // m_commandBuffer.EndSample("DrawMeshInstancedIndirect"); #endif // Camera.main.AddCommandBuffer(CameraEvent.AfterSkybox, m_commandBuffer); }
/// <summary> /// Creates a series of textures that contain random noise. /// These texture tile together using the Wang Tiling method. /// Used by the UpSample shader to create fractal noise for the terrain elevations. /// </summary> private void CreateDemNoise() { var tileWidth = Cache.GetStorage(0).TileSize; NoiseTextures = new RenderTexture[6]; var layers = new int[] { 0, 1, 3, 5, 7, 15 }; var rand = 1234567; for (byte nl = 0; nl < 6; ++nl) { var noiseArray = new float[tileWidth * tileWidth]; var l = layers[nl]; var buffer = new ComputeBuffer(tileWidth * tileWidth, sizeof(float)); for (int j = 0; j < tileWidth; ++j) { for (int i = 0; i < tileWidth; ++i) { noiseArray[i + j * tileWidth] = Noise.Noise2D(i, j); } } // Corners for (int j = 0; j < tileWidth; ++j) { for (int i = 0; i < tileWidth; ++i) { noiseArray[i + j * tileWidth] = 0.0f; } } // Bottom border Random.InitState((l & 1) == 0 ? 7654321 : 5647381); for (int h = 5; h <= tileWidth / 2; ++h) { var N = RandomValue(); noiseArray[h + 2 * tileWidth] = N; noiseArray[(tileWidth - 1 - h) + 2 * tileWidth] = N; } for (int v = 3; v < 5; ++v) { for (int h = 5; h < tileWidth - 5; ++h) { var N = RandomValue(); noiseArray[h + v * tileWidth] = N; noiseArray[(tileWidth - 1 - h) + (4 - v) * tileWidth] = N; } } // Right border Random.InitState((l & 2) == 0 ? 7654321 : 5647381); for (int v = 5; v <= tileWidth / 2; ++v) { var N = RandomValue(); noiseArray[(tileWidth - 3) + v * tileWidth] = N; noiseArray[(tileWidth - 3) + (tileWidth - 1 - v) * tileWidth] = N; } for (int h = tileWidth - 4; h >= tileWidth - 5; --h) { for (int v = 5; v < tileWidth - 5; ++v) { var N = RandomValue(); noiseArray[h + v * tileWidth] = N; noiseArray[(2 * tileWidth - 6 - h) + (tileWidth - 1 - v) * tileWidth] = N; } } // Top border Random.InitState((l & 4) == 0 ? 7654321 : 5647381); for (int h = 5; h <= tileWidth / 2; ++h) { var N = RandomValue(); noiseArray[h + (tileWidth - 3) * tileWidth] = N; noiseArray[(tileWidth - 1 - h) + (tileWidth - 3) * tileWidth] = N; } for (int v = tileWidth - 2; v < tileWidth; ++v) { for (int h = 5; h < tileWidth - 5; ++h) { var N = RandomValue(); noiseArray[h + v * tileWidth] = N; noiseArray[(tileWidth - 1 - h) + (2 * tileWidth - 6 - v) * tileWidth] = N; } } // Left border Random.InitState((l & 8) == 0 ? 7654321 : 5647381); for (int v = 5; v <= tileWidth / 2; ++v) { var N = RandomValue(); noiseArray[2 + v * tileWidth] = N; noiseArray[2 + (tileWidth - 1 - v) * tileWidth] = N; } for (int h = 1; h >= 0; --h) { for (int v = 5; v < tileWidth - 5; ++v) { var N = RandomValue(); noiseArray[h + v * tileWidth] = N; noiseArray[(4 - h) + (tileWidth - 1 - v) * tileWidth] = N; } } // Center Random.InitState(rand); for (int v = 5; v < tileWidth - 5; ++v) { for (int h = 5; h < tileWidth - 5; ++h) { var N = RandomValue(); noiseArray[h + v * tileWidth] = N; } } // Randomize for next texture rand = (rand * 1103515245 + 12345) & 0x7FFFFFFF; NoiseTextures[nl] = RTExtensions.CreateRTexture(new Vector2(tileWidth, tileWidth), 0, RenderTextureFormat.RHalf, FilterMode.Point, TextureWrapMode.Repeat); // Write data into render texture buffer.SetData(noiseArray); CBUtility.WriteIntoRenderTexture(NoiseTextures[nl], 1, buffer, GodManager.Instance.WriteData); buffer.ReleaseAndDisposeBuffer(); } }
void Update() { if (m_bufferWithArgs == null || m_debugWireframe != m_lastDebugWireframe) { uint indexCountPerInstance = cubeMesh.GetIndexCount(0); uint instanceCount = (uint)total; uint startIndexLocation = 0; uint baseVertexLocation = 0; uint startInstanceLocation = 0; uint[] args = new uint[] { indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation }; m_bufferWithArgs = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments); m_bufferWithArgs.SetData(args); m_lastDebugWireframe = m_debugWireframe; } /* * //quaternionArray[IDX(0, y - 1, 0)] = Quaternion.Euler(m_firstCubeRotation); * //m_rigidBodyQuaternions.SetData(quaternionArray); * //positionArray[IDX(0, y -1, 0)] = m_firstCubeLocation; * //m_rigidBodyPositions.SetData(positionArray); * //positionArray[IDX(0,y-1,0)] = m_firstCubeLocation; * int idx = IDX(0,y-1,0); * m_rigidBodyQuaternions.GetData(quaternionArray); * m_rigidBodyPositions.GetData(positionArray); * m_particlePositions.GetData(particlePositions); */ /* * timestep adopted from the appreciated writings of Glenn Fiedler * https://gafferongames.com/post/fix_your_timestep/ * * accumulator += frameTime; * * while ( accumulator >= dt ) * { * previousState = currentState; * integrate( currentState, t, dt ); * t += dt; * accumulator -= dt; * } * * const double alpha = accumulator / dt; * * State state = currentState * alpha + * previousState * ( 1.0 - alpha ); */ ticker += Time.deltaTime; float _dt = 1.0f / tick_rate; while (ticker >= _dt) { ticker -= _dt; m_computeShader.SetFloat(m_deltaTimeShaderProperty, dt); Graphics.ExecuteCommandBuffer(m_commandBuffer); } float blendAlpha = ticker / _dt; cubeMaterial.SetFloat("blendAlpha", blendAlpha); // #if (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX) // Command Buffer DrawMeshInstancedIndirect doesnt work on my mac Graphics.DrawMeshInstancedIndirect(cubeMesh, 0, cubeMaterial, m_bounds, m_bufferWithArgs); if (m_debugWireframe) { m_computeShader.SetFloat("particleDiameter", scale * 0.5f); m_computeShader.SetFloat("springCoefficient", springCoefficient); m_computeShader.SetFloat("dampingCoefficient", dampingCoefficient); m_computeShader.SetFloat("frictionCoefficient", frictionCoefficient); m_computeShader.SetFloat("angularFrictionCoefficient", angularFrictionCoefficient); m_computeShader.SetFloat("gravityCoefficient", gravityCoefficient); m_computeShader.SetFloat("tangentialCoefficient", tangentialCoefficient); m_computeShader.SetFloat("angularForceScalar", angularForceScalar); m_computeShader.SetFloat("linearForceScalar", linearForceScalar); int particlesPerBody = 8; m_computeShader.SetFloat("particleMass", m_cubeMass / particlesPerBody); //Graphics.DrawMeshInstancedIndirect(sphereMesh, 0, sphereMaterial, m_bounds, m_bufferWithSphereArgs); //lineMaterial.SetBuffer("positions", m_particlePositions); //lineMaterial.SetBuffer("vectors", m_particleVelocities); lineMaterial.SetBuffer("positions", m_rigidBodyPositions); lineMaterial.SetBuffer("vectors", m_rigidBodyAngularVelocities); Graphics.DrawMeshInstancedIndirect(lineMesh, 0, lineMaterial, m_bounds, m_bufferWithLineArgs); m_rigidBodyQuaternions.GetData(quaternionArray); foreach (var r in comparisonCubes) { Debug.DrawLine(r.transform.position, r.transform.position + 10 * r.angularVelocity, Color.green, Time.deltaTime * 2); m_comparisonQuaternion = r.transform.rotation; } } // #endif /* * m_computeShader.Dispatch(m_kernel_generateParticleValues, m_threadGroupsPerRigidBody, 1, 1); * m_computeShader.Dispatch(m_kernel_clearGrid, m_threadGroupsPerGridCell, 1, 1); * m_computeShader.Dispatch(m_kernel_populateGrid, m_threadGroupsPerParticle,1, 1); * m_computeShader.Dispatch(m_kernel_collisionDetection, m_threadGroupsPerParticle, 1, 1); * m_computeShader.Dispatch(m_kernel_computeMomenta, m_threadGroupsPerRigidBody, 1, 1); * m_computeShader.Dispatch(m_kernel_computePositionAndRotation, m_threadGroupsPerRigidBody, 1, 1); */ // m_particleRelativePositions.GetData(particleRelativePositions); // m_particleVelocities.GetData(particleVelocities); // m_rigidBodyVelocities.GetData(rigidBodyVelocitiesArray); // m_particleForces.GetData(particleForcesArray); // m_particlePositions.GetData(particlePositions); // m_voxelCollisionGrid.GetData(voxelGridArray); // m_debugParticleVoxelPositions.GetData(particleVoxelPositionsArray); //m_rigidBodyPositions.GetData(positionArray); //m_rigidBodyQuaternions.GetData(quaternionArray); // m_debugParticleIds.GetData(debugParticleIds); //SetMatrices(positionArray, quaternionArray); //Graphics.DrawMeshInstanced(cubeMesh, 0, cubeMaterial, m_matrices, total, null, UnityEngine.Rendering.ShadowCastingMode.On, true, 0, Camera.main); //Graphics.ExecuteCommandBuffer(m_commandBuffer); }
public void SyncAnimBuffer() { animBuffer?.SetData(animPool); }
public void UpdateComputeBuffers() { buffer.SetData(brushingVisualisation.theVisualizationObject.viewList[0].BigMesh.getBigMeshVertices()); computeShader.SetBuffer(kernelHandleBrushTexture, "dataBuffer", buffer); }