private void PrepareComputeBuffer(int count) { if (outputBuffer is not null && outputBuffer.count >= count) { return; } outputBuffer?.Release(); outputBuffer = new ComputeBuffer(math.max(count * 2, 1024), sizeof(int)); computeShader?.SetBuffer(mainKernel.index, ShaderPropertyIds.OutputBuffer, outputBuffer); }
public static void ReadSingleFromRenderTexture(RenderTexture tex, float x, float y, float z, ComputeBuffer buffer, ComputeShader readData, bool useBilinear) { if (tex == null) { Debug.Log("CBUtility: ReadSingleFromRenderTexture - RenderTexture is null!"); return; } if (buffer == null) { Debug.Log("CBUtility: ReadSingleFromRenderTexture - buffer is null!"); return; } if (readData == null) { Debug.Log("CBUtility: ReadSingleFromRenderTexture - Computer shader is null!"); return; } if (!tex.IsCreated()) { Debug.Log("CBUtility: ReadSingleFromRenderTexture - tex has not been created (Call Create() on tex)!"); return; } int kernel = -1; int depth = 1; string D = "2D"; string B = (useBilinear) ? "Bilinear" : ""; if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D) { depth = tex.volumeDepth; D = "3D"; } kernel = readData.FindKernel("readSingle" + B + D); if (kernel == -1) { Debug.LogFormat("CBUtility::ReadSingleFromRenderTexture - could not find kernel readSingle{0}", B + D); return; } int width = tex.width; int height = tex.height; //set the compute shader uniforms readData.SetTexture(kernel, "_Tex" + D, tex); readData.SetBuffer(kernel, "_BufferSingle" + D, buffer); //used for point sampling readData.SetInt("_IdxX", (int)x); readData.SetInt("_IdxY", (int)y); readData.SetInt("_IdxZ", (int)z); //used for bilinear sampling readData.SetVector("_UV", new Vector4(x / (float)(width - 1), y / (float)(height - 1), z / (float)(depth - 1), 0.0f)); readData.Dispatch(kernel, 1, 1, 1); }
void Start() { transform.position = HivePosition; hiveTransform.localScale = new Vector3(hiveRadius, hiveRadius, hiveRadius); swarmKernel = swarmComputeShader.FindKernel("TargetSwarmMain"); worldKernel = swarmComputeShader.FindKernel("TargetWorldUpdateMain"); // Create rotation matrices CreateRotationMatrices(); // Create the worldtexture worldTexture = CreateRenderTexture(); // Create and init swarmer compute buffers swarmBuffer = new ComputeBuffer(numSwarmers, 56); Swarmer[] swarmers = new Swarmer[numSwarmers]; for (int i = 0; i < swarmers.Length; i++) { swarmers[i].color = new Vector3(0.20f, 1f, 0f); 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].scent = 0; swarmers[i].pheromoneScent = 0; } swarmBuffer.SetData(swarmers); // Create and init swarm targets compute buffer swarmTargetBuffer = new ComputeBuffer(targets.Length, 16); SwarmTarget[] swarmTargets = new SwarmTarget[targets.Length]; for (int i = 0; i < swarmTargets.Length; i++) { swarmTargets[i].position = HivePosition + targets[i].localPosition; swarmTargets[i].hp = 1; } swarmTargetBuffer.SetData(swarmTargets); // 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.SetBuffer(swarmKernel, "targets", swarmTargetBuffer); swarmComputeShader.SetInt("numTargets", swarmTargets.Length); 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.SetFloat("hiveRadius", hiveRadius); swarmComputeShader.SetTexture(worldKernel, "worldTex", worldTexture); Debug.Log($"Hiveposition: {HivePosition}"); // Set rendering materials data swarmerMaterial.SetBuffer("swarmers", swarmBuffer); // Debug debugWorldNodes = new WorldNode[NumWorldNodes]; }
protected override void OnPreRenderImage(ComputeShader compute, RenderTexture src, RenderTexture dst) { var sdfShapes = RayMarchedShape.GetShapes(); int numShapes = sdfShapes.Count; if (m_shapes == null || m_shapes.count != numShapes) { if (m_shapes != null) { m_shapes.Dispose(); } m_shapes = new ComputeBuffer(Mathf.Max(1, numShapes), SdfShape.Stride); } if (m_heatMap == null || m_heatMap.width != src.width || m_heatMap.height != src.height) { if (m_heatMap != null) { DestroyImmediate(m_heatMap); m_heatMap = null; } m_heatMap = new RenderTexture(src.width, src.height, 0, RenderTextureFormat.RFloat); m_heatMap.enableRandomWrite = true; m_heatMap.Create(); } m_shapes.SetData(sdfShapes); var camera = GetComponent <Camera>(); if (m_const.Kernels == null) { InitShaderConstants(); } foreach (int kernel in m_const.Kernels) { compute.SetTexture(kernel, m_const.Src, src); compute.SetTexture(kernel, m_const.Dst, dst); compute.SetTexture(kernel, m_const.HeatMap, m_heatMap); compute.SetBuffer(kernel, m_const.SdfShapes, m_shapes); } compute.SetMatrix(m_const.CameraInverseProjection, camera.projectionMatrix.inverse); compute.SetMatrix(m_const.CameraToWorld, camera.cameraToWorldMatrix); compute.SetVector(m_const.CameraPosition, camera.transform.position); compute.SetInts(m_const.ScreenSize, new int[] { camera.pixelWidth, camera.pixelHeight }); compute.SetInt(m_const.NumSdfShapes, numShapes); compute.SetVector(m_const.RayMarchParams, new Vector4(MaxRaySteps, RayHitThreshold, MaxRayDistance, Time.time)); compute.SetFloat(m_const.BlendDistance, BlendDistance); compute.SetVector(m_const.BackgroundColor, new Vector4(BackgroundColor.r, BackgroundColor.g, BackgroundColor.b, BackgroundColor.a)); compute.SetVector(m_const.MissColor, new Vector4(MissColor.r, MissColor.g, MissColor.b, MissColor.a)); compute.SetVector(m_const.HeatColorCool, new Vector4(HeatColorCool.r, HeatColorCool.g, HeatColorCool.b, HeatColorCool.a)); compute.SetVector(m_const.HeatColorMedium, new Vector4(HeatColorMedium.r, HeatColorMedium.g, HeatColorMedium.b, HeatColorMedium.a)); compute.SetVector(m_const.HeatColorHot, new Vector4(HeatColorHot.r, HeatColorHot.g, HeatColorHot.b, HeatColorHot.a)); compute.SetFloat(m_const.HeatAlpha, HeatAlpha); }
static public void WriteIntoRenderTexture(RenderTexture tex, int channels, string path, ComputeBuffer buffer, ComputeShader writeData) { if (tex == null) { Debug.Log("CBUtility::WriteIntoRenderTexture - RenderTexture is null"); return; } if (buffer == null) { Debug.Log("CBUtility::WriteIntoRenderTexture - buffer is null"); return; } if (writeData == null) { Debug.Log("CBUtility::WriteIntoRenderTexture - Computer shader is null"); return; } if (channels < 1 || channels > 4) { Debug.Log("CBUtility::WriteIntoRenderTexture - Channels must be 1, 2, 3, or 4"); return; } if (!tex.enableRandomWrite) { Debug.Log("CBUtility::WriteIntoRenderTexture - you must enable random write on render texture"); return; } if (!tex.IsCreated()) { Debug.Log("CBUtility::WriteIntoRenderTexture - tex has not been created (Call Create() on tex)"); return; } int kernel = -1; int depth = 1; string D = "2D"; string C = "C" + channels.ToString(); if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D) { depth = tex.volumeDepth; D = "3D"; } kernel = writeData.FindKernel("write" + D + C); if (kernel == -1) { Debug.Log("CBUtility::WriteIntoRenderTexture - could not find kernel " + "write" + D + C); return; } int width = tex.width; int height = tex.height; int size = width * height * depth * channels; float[] map = new float[size]; if (!LoadRawFile(path, map, size)) { return; } buffer.SetData(map); //set the compute shader uniforms writeData.SetTexture(kernel, "_Des" + D + C, tex); writeData.SetInt("_Width", width); writeData.SetInt("_Height", height); writeData.SetInt("_Depth", depth); writeData.SetBuffer(kernel, "_Buffer" + D + C, buffer); //run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need //some extra threadBlocks. This will result in some unneeded threads running int padX = (width % 8 == 0) ? 0 : 1; int padY = (height % 8 == 0) ? 0 : 1; int padZ = (depth % 8 == 0) ? 0 : 1; writeData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ)); }
void DoSpawning() { //Sets the buffers of the spawn function cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "CdeadList", DeadBuffer); cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertPos", PosBuffer[READ]); cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertVel", VelBuffer[READ]); cShade.SetBuffer(cShade.FindKernel(_SpawnKernelName), "WvertDat", IdAgeBuffer[READ]); spawnCount += Mathf.Abs(psystem.particlesToSpawnPerFrame) * this.simSpeed; int intspawnCount = Mathf.FloorToInt(spawnCount); int toSpawnThisFrame = (int)Mathf.Min(intspawnCount, (int)(this.deadParticles / 64)); if (toSpawnThisFrame * 64 > this.deadParticles) { //Debug.Log("NOSPAWN>> ded:" + this.deadParticles + " liv:" + this.liveParticles + " tot:" + (this.liveParticles + this.deadParticles)); toSpawnThisFrame = 0; //(int)Mathf.Max(this.particlesLeftInBank - psystem.particlesToSpawnPerFrame*2,0); } else { spawnCount -= intspawnCount; } if (this.deadParticles + this.liveParticles != this.count && Time.frameCount > 2) { Debug.LogError("ERROR!!! PARTICLE COUNT OFFSET!!! ded:" + this.deadParticles + " liv:"+ this.liveParticles + " tot:"+ (this.liveParticles + this.deadParticles)); } if (toSpawnThisFrame > 0) { //Debug.Log("Testey>> ded:" + this.deadParticles + " \t liv:" + this.liveParticles + " \t tot:" + (this.liveParticles + this.deadParticles)); cShade.Dispatch(cShade.FindKernel(_SpawnKernelName), toSpawnThisFrame, 1, 1); } DisplayFrameSpawns(toSpawnThisFrame); }
private void OnEnable() { // If initialized, call on disable to clean things up if (initialized) { OnDisable(); } initialized = true; // Grab data from the source mesh Vector3[] positions = sourceMesh.vertices; Vector2[] uvs = sourceMesh.uv; int[] tris = sourceMesh.triangles; // Create the data to upload to the source vert buffer SourceVertex[] vertices = new SourceVertex[positions.Length]; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new SourceVertex() { position = positions[i], uv = uvs[i], }; } int numTriangles = tris.Length / 3; // The number of triangles in the source mesh is the index array / 3 // Create compute buffers // The stride is the size, in bytes, each object in the buffer takes up sourceVertBuffer = new ComputeBuffer(vertices.Length, SOURCE_VERT_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable); sourceVertBuffer.SetData(vertices); sourceTriBuffer = new ComputeBuffer(tris.Length, SOURCE_TRI_STRIDE, ComputeBufferType.Structured, ComputeBufferMode.Immutable); sourceTriBuffer.SetData(tris); // We split each triangle into three new ones drawBuffer = new ComputeBuffer(numTriangles * 3, DRAW_STRIDE, ComputeBufferType.Append); drawBuffer.SetCounterValue(0); // Set the count to zero argsBuffer = new ComputeBuffer(1, ARGS_STRIDE, ComputeBufferType.IndirectArguments); // The data in the args buffer corresponds to: // 0: vertex count per draw instance. We will only use one instance // 1: instance count. One // 2: start vertex location if using a Graphics Buffer // 3: and start instance location if using a Graphics Buffer argsBuffer.SetData(new int[] { 0, 1, 0, 0 }); // Cache the kernel IDs we will be dispatching idPyramidKernel = pyramidComputeShader.FindKernel("Main"); idTriToVertKernel = triToVertComputeShader.FindKernel("Main"); // Set data on the shaders pyramidComputeShader.SetBuffer(idPyramidKernel, "_SourceVertices", sourceVertBuffer); pyramidComputeShader.SetBuffer(idPyramidKernel, "_SourceTriangles", sourceTriBuffer); pyramidComputeShader.SetBuffer(idPyramidKernel, "_DrawTriangles", drawBuffer); pyramidComputeShader.SetInt("_NumSourceTriangles", numTriangles); triToVertComputeShader.SetBuffer(idTriToVertKernel, "_IndirectArgsBuffer", argsBuffer); material.SetBuffer("_DrawTriangles", drawBuffer); // Calculate the number of threads to use. Get the thread size from the kernel // Then, divide the number of triangles by that size pyramidComputeShader.GetKernelThreadGroupSizes(idPyramidKernel, out uint threadGroupSize, out _, out _); dispatchSize = Mathf.CeilToInt((float)numTriangles / threadGroupSize); // Get the bounds of the source mesh and then expand by the pyramid height localBounds = sourceMesh.bounds; localBounds.Expand(pyramidHeight); }
Vector4[] GenerateComputedDistances(int bufferSize) { //create the buffers //fill position buffers Vector4[] positionsArray = new Vector4[bufferSize]; Vector4 newVector; for (int i = 0; i < bufferSize; ++i) { if (i < population.Count) { //valid cell operations newVector = population[i].transform.position; newVector.w = 0f; if (population[i] is BasicGuy) { newVector.w = 1f; } if (population[i] is SpecialGuy) { newVector.w = 2f; } //positions. = population[i].transform.position; positionsArray[i] = newVector; } else { //empty space to make the buffer fit evenly newVector = Vector4.zero; newVector.w = -1f; positionsArray[i] = newVector; } } int float4Stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Vector4)); ComputeBuffer positionsBuffer = new ComputeBuffer(bufferSize, float4Stride, ComputeBufferType.Default); positionsBuffer.SetData(positionsArray); //fill the buffer with data from the array //Create output directional buffer ComputeBuffer directionalsBuffer = new ComputeBuffer(bufferSize, float4Stride, ComputeBufferType.Default); //attach buffers to compuet shader int kernelIndex = computeShader.FindKernel("CSMain"); computeShader.SetBuffer(kernelIndex, "Positions", positionsBuffer); computeShader.SetInt("resolution", bufferSize); //debug render texture output /* * RenderTexture renderTetxure; * * renderTetxure = new RenderTexture(bufferSize, bufferSize, 1); * renderTetxure.enableRandomWrite = true; * renderTetxure.useMipMap = false; * renderTetxure.Create(); * * computeShaderOutputMaterial.SetTexture("_MainTex", renderTetxure); * * computeShader.SetTexture(kernelIndex,"ResultTexture",renderTetxure); * */ //run the compute shader computeShader.Dispatch(kernelIndex, 16, 16, 1); computeShader.SetBuffer(kernelIndex, "Result", directionalsBuffer); //get the processed data Vector4[] finalDirectionals = new Vector4[bufferSize * bufferSize]; //directionalsBuffer.GetData(finalDirectionals); return(finalDirectionals); }
void Start() { if (followTarget) { groupAnchor = target.position; } else { GeneratePath(); groupAnchor = targetPositions[0]; } drawArgsBuffer = new ComputeBuffer(1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments); drawArgsBuffer.SetData(new uint[5] { fishMesh.GetIndexCount(0), (uint)fishesCount, 0, 0, 0 }); // This property block is used only for avoiding an instancing bug. props = new MaterialPropertyBlock(); props.SetFloat("_UniqueID", Random.value); fishesData = new FishBehaviourGPU[fishesCount]; kernelHandle = computeShader.FindKernel("CSMain"); for (int i = 0; i < fishesCount; i++) { fishesData[i] = CreateBehaviour(); fishesData[i].speed_offset = Random.value * 1000.0f; } fishBuffer = new ComputeBuffer(fishesCount, sizeof(float) * 9); fishBuffer.SetData(fishesData); if (boxColliders.Length <= 0) { collisionData = new CollisionArea[1] { new CollisionArea() } } ; collisionBuffer = new ComputeBuffer(collisionData.Length, sizeof(float) * 6); collisionBuffer.SetData(collisionData); collisionDataLength = boxColliders.Length <= 0 ? 0 : collisionData.Length; } FishBehaviourGPU CreateBehaviour() { FishBehaviourGPU behaviour = new FishBehaviourGPU(); Vector3 pos = groupAnchor + Random.insideUnitSphere * spawnRadius; Quaternion rot = Quaternion.Slerp(transform.rotation, Random.rotation, 0.3f); switch (movementAxis) { case MovementAxis.XY: pos.z = rot.z = 0.0f; break; case MovementAxis.XZ: pos.y = rot.y = 0.0f; break; } behaviour.position = pos; behaviour.velocity = rot.eulerAngles; behaviour.speed = Random.Range(minSpeed, maxSpeed); behaviour.rot_speed = Random.Range(minRotationSpeed, maxRotationSpeed); return(behaviour); } void Update() { UpdateGroupAnchor(); switch (movementAxis) { case MovementAxis.XY: computeShader.SetInt("movementMode", 1); break; case MovementAxis.XZ: computeShader.SetInt("movementMode", 2); break; default: computeShader.SetInt("movementMode", 0); break; } computeShader.SetFloat("deltaTime", Time.deltaTime); computeShader.SetVector("target", groupAnchor); computeShader.SetFloat("neighbourDistance", neighbourDistance); computeShader.SetInt("fishesCount", fishesCount); computeShader.SetFloat("collisionForce", force); computeShader.SetInt("collisionCount", collisionDataLength); computeShader.SetFloat("speedVariation", speedVariation); computeShader.SetBuffer(this.kernelHandle, "fishBuffer", fishBuffer); computeShader.SetBuffer(kernelHandle, "collisionBuffer", collisionBuffer); fishInstancedMaterial.SetVector("offsetPosition", myTransform.position); computeShader.Dispatch(this.kernelHandle, this.fishesCount / GROUP_SIZE + 1, 1, 1); fishInstancedMaterial.SetBuffer("fishBuffer", fishBuffer); instancingBounds.center = myTransform.position; Graphics.DrawMeshInstancedIndirect( fishMesh, 0, fishInstancedMaterial, instancingBounds, drawArgsBuffer, 0, props ); } void OnDestroy() { if (collisionBuffer != null) { collisionBuffer.Release(); } if (fishBuffer != null) { fishBuffer.Release(); } if (drawArgsBuffer != null) { drawArgsBuffer.Release(); } } void UpdateGroupAnchor() { float minX = myTransform.position.x - (swimmingAreaWidth / 2) + (groupAreaWidth / 2); float maxX = myTransform.position.x + (swimmingAreaWidth / 2) - (groupAreaWidth / 2); float minY = myTransform.position.y - (swimmingAreaHeight / 2) + (groupAreaHeight / 2); float maxY = myTransform.position.y + (swimmingAreaHeight / 2) - (groupAreaHeight / 2); float minZ = myTransform.position.z - (swimmingAreaDepth / 2) + (groupAreaDepth / 2); float maxZ = myTransform.position.z + (swimmingAreaDepth / 2) - (groupAreaDepth / 2); Vector3 futurePosition = myTransform.position; if (!followTarget && targetPositions.Length > 0) { if ((groupAnchor - targetPositions[currentTargetPosIndex]).magnitude < 1) { currentTargetPosIndex++; if (currentTargetPosIndex >= targetPositions.Length) { if (recalculatePoints) { GeneratePath(); } else { currentTargetPosIndex = targetPositions.Length - 1; } } } Vector3 vel = (targetPositions[currentTargetPosIndex] - groupAnchor); futurePosition = groupAnchor + vel * Time.deltaTime * groupAreaSpeed; } else if (followTarget) { if (target != null) { Vector3 vel = (target.position - groupAnchor); futurePosition = groupAnchor + vel * Time.deltaTime * groupAreaSpeed; } } futurePosition.x = Mathf.Clamp(futurePosition.x, minX, maxX); futurePosition.y = Mathf.Clamp(futurePosition.y, minY, maxY); futurePosition.z = Mathf.Clamp(futurePosition.z, minZ, maxZ); groupAnchor = futurePosition; } void GeneratePath() { float minX = myTransform.position.x - (swimmingAreaWidth / 2) + (groupAreaWidth / 2); float maxX = myTransform.position.x + (swimmingAreaWidth / 2) - (groupAreaWidth / 2); float minY = myTransform.position.y - (swimmingAreaHeight / 2) + (groupAreaHeight / 2); float maxY = myTransform.position.y + (swimmingAreaHeight / 2) - (groupAreaHeight / 2); float minZ = myTransform.position.z - (swimmingAreaDepth / 2) + (groupAreaDepth / 2); float maxZ = myTransform.position.z + (swimmingAreaDepth / 2) - (groupAreaDepth / 2); targetPositions = new Vector3[Random.Range(minTargetPoints, maxTargetPoints)]; Vector3 tempPos; for (int i = 0; i < targetPositions.Length; i++) { tempPos.x = Random.Range(minX, maxX); tempPos.y = Random.Range(minY, maxY); tempPos.z = Random.Range(minZ, maxZ); targetPositions[i] = tempPos; } currentTargetPosIndex = 0; } Vector3 volumeSize;
protected void InitCells(Kernel ker) { compute.SetBuffer(ker.Index, "_Cells", cellsBufferRead); compute.SetBuffer(ker.Index, "_CellPoolAppend", cellsPoolBuffer); compute.SetInt("_CellsCount", cellsCount); compute.Dispatch(ker.Index, Mathf.FloorToInt(cellsCount / (int)ker.ThreadX) + 1, 1, 1); }
public override void Inject(Vapor vapor, ComputeShader compute, Matrix4x4 viewProj) { if (HasShadow) { if (GetShadowMapResolution() != m_shadowMap.width) { DestroyImmediate(m_shadowMap); CreateShadowTex(); } } //TODO: This doesn't really need to run every frame UpdateCommandBuffer(); //Setup basic params Vector4 posRange = transform.position; posRange.w = 1.0f / (m_light.range * m_light.range); compute.SetVector("_LightPosRange", posRange); Vector4 lightStrength = m_light.color * m_light.intensity * FogScatterIntensity; lightStrength *= 10; compute.SetVector("_LightColor", lightStrength); //Per light type things switch (LightType) { case LightType.Directional: int dirKernel; if (HasShadow) { if (QualitySettings.shadowCascades > 1) { dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.Cascaded); } else { dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.Shadowed); } } else { dirKernel = vapor.LightDirKernel.GetKernel(VaporKernel.ShadowMode.None); } compute.SetVector("_LightPosRange", m_light.transform.forward); if (HasShadow) { compute.SetBuffer(dirKernel, "_MatrixBuf", MatrixBuffer); compute.SetTexture(dirKernel, "_ShadowMapTexture", m_shadowMap); } else { compute.SetTexture(dirKernel, "_ShadowMapTexture", Texture2D.whiteTexture); } vapor.SetLightAccum(dirKernel, false); Profiler.BeginSample("Dir Light pass"); var tex = vapor.GetDensityTex(); compute.DispatchScaled(dirKernel, tex.width, tex.height, tex.volumeDepth); Profiler.EndSample(); break; case LightType.Point: vapor.SetLightAccum(vapor.LightPointKernel, false); vapor.InjectObject(viewProj, vapor.LightPointKernel, this); break; case LightType.Spot: int spotKernel = vapor.LightSpotKernel.GetKernel(HasShadow ? VaporKernel.ShadowMode.Shadowed : VaporKernel.ShadowMode.None); if (HasShadow) { Matrix4x4 v = transform.worldToLocalMatrix; Matrix4x4 p = GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(m_light.spotAngle, 1.0f, m_light.shadowNearPlane, m_light.range), true); //For some reason z is flipped :( p *= Matrix4x4.Scale(new Vector3(1.0f, 1.0f, -1.0f)); compute.SetMatrix("_SpotShadowMatrix", p * v); compute.SetTexture(spotKernel, "_SpotShadow", m_shadowMap); } var lightProjMatrix = Matrix4x4.identity; float d = Mathf.Deg2Rad * m_light.spotAngle * 0.5f; d = Mathf.Cos(d) / Mathf.Sin(d); lightProjMatrix[3, 2] = 2f / d; lightProjMatrix[3, 3] = SpotBaseSize; var mat = lightProjMatrix * transform.worldToLocalMatrix; compute.SetMatrix("_SpotMatrix", mat); if (m_light.cookie != null) { compute.SetTexture(spotKernel, "_SpotCookie", m_light.cookie); } else { compute.SetTexture(spotKernel, "_SpotCookie", vapor.SpotCookie); } vapor.SetLightAccum(spotKernel, false); vapor.InjectObject(viewProj, spotKernel, this); break; } }
public void SetBuffer(ComputeShader shader, string kernelName) { int kernelHandle = shader.FindKernel(kernelName); shader.SetBuffer(kernelHandle, bufferName, buffer); }
unsafe public void nuStart() { float initTime = Time.realtimeSinceStartup; Debug.Log(Time.realtimeSinceStartup); d_particles = new ComputeBuffer(n, sizeof(particle_t)); // For GPU particles = new particle_t[n]; // Local stuff int sx = (int)Mathf.Ceil(Mathf.Sqrt((float)n)); int sy = (n + sx - 1) / sx; int[] shuffle = new int[n]; for (int i = 0; i < n; i++) { shuffle[i] = i; } for (int i = 0; i < n; i++) { // // make sure particles are not spatially sorted // int j = UnityEngine.Random.Range(0, 2147483640) % (n - i); Debug.Log(j); int k = shuffle[j]; shuffle[j] = shuffle[n - i - 1]; // // distribute particles evenly to ensure proper spacing // particles[i].x = size * (1.0f + (k % sx)) / (1 + sx); particles[i].y = size * (1.0f + (k / sx)) / (1 + sy); // // assign random velocities within a bound // particles[i].vx = UnityEngine.Random.Range(0.0f, 1.0f) * 2 - 1; particles[i].vy = UnityEngine.Random.Range(0.0f, 1.0f) * 2 - 1; } d_particles.SetData(particles); int particle_blks = (n + NUM_THREADS - 1) / NUM_THREADS; double bin_size = 2 * cutoff; double area_size = Mathf.Sqrt((float)density * n); int nbin_1d = (int)Mathf.Ceil(1.0f * (float)area_size / (float)bin_size); Vector2 bin_threads = new Vector2(Mathf.Sqrt(NUM_THREADS), Mathf.Sqrt(NUM_THREADS)); int bin_blk = (int)Mathf.Ceil((float)(1.0 * nbin_1d / Mathf.Sqrt(NUM_THREADS))); Vector2 bin_blks = new Vector2(bin_blk, bin_blk); d_particle_chain = new ComputeBuffer(n, sizeof(int)); d_bin = new ComputeBuffer(nbin_1d * nbin_1d, sizeof(int)); d_bin_debug = new ComputeBuffer(n, sizeof(float)); // Debugging NBodyCUDA.SetInt("nbin_1d", nbin_1d); // // Declare Constants for Compute Shaders // NBodyCUDA.SetFloat("density", density); NBodyCUDA.SetFloat("mass", mass); NBodyCUDA.SetFloat("cutoff", cutoff); NBodyCUDA.SetFloat("min_r", min_r); NBodyCUDA.SetFloat("dt", dt); NBodyCUDA.SetFloat("bin_size", 2 * cutoff); NBodyCUDA.SetFloat("size", size); NBodyCUDA.SetInt("count", 11); // // simulate a number of time steps // for (int step = 0; step < NSTEPS; step++) { int kID_clear_bin_gpu = NBodyCUDA.FindKernel("clear_bin_gpu"); NBodyCUDA.SetInt("nbin_1d", nbin_1d); NBodyCUDA.SetBuffer(kID_clear_bin_gpu, "d_bin", d_bin); NBodyCUDA.Dispatch(kID_clear_bin_gpu, (int)bin_blks.x, (int)bin_blks.y, 1); int kID_assign_particle_gpu = NBodyCUDA.FindKernel("assign_particle_gpu"); NBodyCUDA.SetInt("n", n); NBodyCUDA.SetBuffer(kID_assign_particle_gpu, "d_bin", d_bin); Shader.SetGlobalBuffer(Shader.PropertyToID("d_particles"), d_particles); Shader.SetGlobalBuffer(Shader.PropertyToID("d_particle_chain"), d_particle_chain); NBodyCUDA.Dispatch(kID_assign_particle_gpu, particle_blks, 1, 1); // // compute forces // int kID_compute_forces_gpu = NBodyCUDA.FindKernel("compute_forces_gpu"); NBodyCUDA.SetBuffer(kID_compute_forces_gpu, "d_bin", d_bin); Shader.SetGlobalBuffer(Shader.PropertyToID("d_bin_debug"), d_bin_debug); // NBodyCUDA.SetBuffer(kID_compute_forces_gpu, "d_bin_debug", d_bin_debug); NBodyCUDA.Dispatch(kID_compute_forces_gpu, particle_blks, 1, 1); // // move particles // int kID_move_gpu = NBodyCUDA.FindKernel("move_gpu"); NBodyCUDA.Dispatch(kID_move_gpu, particle_blks, 1, 1); } Debug.Log("Simulation over"); float final = (Time.realtimeSinceStartup - initTime); test.text = final.ToString(); Debug.Log(size); d_particles.Release(); d_particle_chain.Release(); d_bin.Release(); d_bin_debug.Release(); }
// float time = 0; void BufferSort() { var _cp = Camera.main.transform.position; var cp = new Vector4(_cp.x, _cp.y, _cp.z, 1); float[] vMatrix = new float[16]; var _v = Camera.main.worldToCameraMatrix; //set world2camera matrix to vMatrix vMatrix [0] = _v.m00; vMatrix [1] = _v.m01; vMatrix [2] = _v.m02; vMatrix [3] = _v.m03; vMatrix [4] = _v.m10; vMatrix [5] = _v.m11; vMatrix [6] = _v.m12; vMatrix [7] = _v.m13; vMatrix [8] = _v.m20; vMatrix [9] = _v.m21; vMatrix [10] = _v.m22; vMatrix [11] = _v.m23; vMatrix [12] = _v.m30; vMatrix [13] = _v.m31; vMatrix [14] = _v.m32; vMatrix [15] = _v.m33; kernel = updater.FindKernel("BitonicSort"); // time += Time.deltaTime; // if (time < 0.1f) // return; for (int i = 0; i < max; i++) { step = Count; int rank = 0; for (rank = 0; rank < step; rank++) { step -= rank + 1; } //2,4,8,16,32,64,128... stepno = 1 << (rank + 1); // Debug.Log ("stepno = " + stepno); //1, 2,1, 4,2,1, 8,4,2,1, 16,8... offset = 1 << (rank - step); // Debug.Log ("offset = " + offset); //2, 4,2, 8,4,2, 16,8,4,2, 32,16... stage = 2 * offset; // Debug.Log ("stage = " + stage); updater.SetBuffer(kernel, "ParticlesBuffer", particlesBuffer); updater.SetInt("stepno", stepno); updater.SetInt("offset", offset); updater.SetInt("stage", stage); //updater.SetVector ("CameraPos", cp); //updater.SetFloats ("vMatrix", vMatrix); updater.Dispatch(kernel, (int)Mathf.Sqrt(particleCount) / 8, (int)Mathf.Sqrt(particleCount) / 8, 1); if (Count < max) { Count += 1; } } Count = 0; step = 0; stepno = 0; offset = 0; stage = 0; }
private void SetComputeBuffers() { CurrentDensityShader.SetBuffer(0, "pts", PointsBuffer); marchCompute.SetBuffer(0, "pts", PointsBuffer); marchCompute.SetBuffer(0, "Result", TrianglesBuffer); }
//----------------------------------------------------------------- private void OnEnable() { // Init data structures m_DyeSources = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_ForceSources = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_Density = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_Density0 = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_V = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_V0 = new RenderTexture(c_Size, c_Size, 0, RenderTextureFormat.ARGBFloat) { enableRandomWrite = true }; m_VisTex = new RenderTexture(c_Size, c_Size, 0) { enableRandomWrite = true }; m_DyeSources.Create(); m_ForceSources.Create(); m_Density.Create(); m_Density0.Create(); m_V.Create(); m_V0.Create(); m_VisTex.Create(); // Setup visualization of dye m_VisImage.texture = m_VisTex; // Prepare compute shader data int kernelID = m_ModifyFieldCS.FindKernel("ModifyField"); Vector4[] pixels = new Vector4[c_Size * c_Size]; var computeBuf = new ComputeBuffer(pixels.Length, stride: 4 * 4); // Clear dye texture computeBuf.SetData(pixels); m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf); m_ModifyFieldCS.SetTexture(kernelID, "field", m_Density); m_ModifyFieldCS.SetInt("size", c_Size); m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1); // Init external source of dye pixels[c_Size / 2 + (c_Size / 3) * c_Size] = new Vector3(50.0f, 0.0f, 50.0f); pixels[c_Size / 3 + (c_Size / 2) * c_Size] = new Vector3(0.0f, 40.0f, 40.0f); computeBuf.SetData(pixels); m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf); m_ModifyFieldCS.SetTexture(kernelID, "field", m_DyeSources); m_ModifyFieldCS.SetInt("size", c_Size); m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1); // Init external source of velocity pixels[c_Size / 2 + (c_Size / 3) * c_Size] = new Vector3(22.0f, 22.0f, 0.0f); pixels[c_Size / 3 + (c_Size / 2) * c_Size] = new Vector3(18.0f, 18.0f, 0.0f); computeBuf.SetData(pixels); m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf); m_ModifyFieldCS.SetTexture(kernelID, "field", m_ForceSources); m_ModifyFieldCS.SetInt("size", c_Size); m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1); // Randomize velocities for each cell for (int i = 0; i < pixels.Length; i++) { pixels[i] = new Vector3(x: Random.Range(-1.0f, 1.0f), y: Random.Range(-1.0f, 1.0f), z: 0); } computeBuf.SetData(pixels); m_ModifyFieldCS.SetBuffer(kernelID, "sources", computeBuf); m_ModifyFieldCS.SetTexture(kernelID, "field", m_V); m_ModifyFieldCS.SetInt("size", c_Size); m_ModifyFieldCS.Dispatch(kernelID, c_Size / 8, c_Size / 8, 1); // Cleanup computeBuf.Dispose(); }
public Texture Prepare(RenderTexture source, Material uberMaterial) { var settings = model.settings; // Setup compute if (m_EyeCompute == null) { m_EyeCompute = Resources.Load <ComputeShader>("Shaders/EyeHistogram"); } var material = context.materialFactory.Get("Hidden/Post FX/Eye Adaptation"); material.shaderKeywords = null; if (m_HistogramBuffer == null) { m_HistogramBuffer = new ComputeBuffer(k_HistogramBins, sizeof(uint)); } if (s_EmptyHistogramBuffer == null) { s_EmptyHistogramBuffer = new uint[k_HistogramBins]; } // Downscale the framebuffer, we don't need an absolute precision for auto exposure and it // helps making it more stable var scaleOffsetRes = GetHistogramScaleOffsetRes(); var rt = context.renderTextureFactory.Get((int)scaleOffsetRes.z, (int)scaleOffsetRes.w, 0, source.format); Graphics.Blit(source, rt); if (m_AutoExposurePool[0] == null || !m_AutoExposurePool[0].IsCreated()) { m_AutoExposurePool[0] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat); } if (m_AutoExposurePool[1] == null || !m_AutoExposurePool[1].IsCreated()) { m_AutoExposurePool[1] = new RenderTexture(1, 1, 0, RenderTextureFormat.RFloat); } // Clears the buffer on every frame as we use it to accumulate luminance values on each frame m_HistogramBuffer.SetData(s_EmptyHistogramBuffer); // Gets a log histogram int kernel = m_EyeCompute.FindKernel("KEyeHistogram"); m_EyeCompute.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); m_EyeCompute.SetTexture(kernel, "_Source", rt); m_EyeCompute.SetVector("_ScaleOffsetRes", scaleOffsetRes); m_EyeCompute.Dispatch(kernel, Mathf.CeilToInt(rt.width / (float)k_HistogramThreadX), Mathf.CeilToInt(rt.height / (float)k_HistogramThreadY), 1); // Cleanup context.renderTextureFactory.Release(rt); // Make sure filtering values are correct to avoid apocalyptic consequences const float minDelta = 1e-2f; settings.highPercent = Mathf.Clamp(settings.highPercent, 1f + minDelta, 99f); settings.lowPercent = Mathf.Clamp(settings.lowPercent, 1f, settings.highPercent - minDelta); // Compute auto exposure material.SetBuffer("_Histogram", m_HistogramBuffer); // No (int, buffer) overload for SetBuffer ? material.SetVector(Uniforms._Params, new Vector4(settings.lowPercent * 0.01f, settings.highPercent * 0.01f, Mathf.Exp(settings.minLuminance * 0.69314718055994530941723212145818f), Mathf.Exp(settings.maxLuminance * 0.69314718055994530941723212145818f))); material.SetVector(Uniforms._Speed, new Vector2(settings.speedDown, settings.speedUp)); material.SetVector(Uniforms._ScaleOffsetRes, scaleOffsetRes); material.SetFloat(Uniforms._ExposureCompensation, settings.keyValue); if (settings.dynamicKeyValue) { material.EnableKeyword("AUTO_KEY_VALUE"); } if (m_FrameCount < 2 || !Application.isPlaying) { // We don't want eye adaptation when not in play mode because the GameView isn't // animated, thus making it harder to tweak. Just use the final audo exposure value. m_CurrentAutoExposure = m_AutoExposurePool[0]; Graphics.Blit(null, m_CurrentAutoExposure, material, (int)EyeAdaptationModel.EyeAdaptationType.Fixed); // Copy current exposure to the other pingpong target to avoid adapting from black Graphics.Blit(m_AutoExposurePool[0], m_AutoExposurePool[1]); } else { int pp = m_AutoExposurePingPing; var src = m_AutoExposurePool[++pp % 2]; var dst = m_AutoExposurePool[++pp % 2]; Graphics.Blit(src, dst, material, (int)settings.adaptationType); m_AutoExposurePingPing = ++pp % 2; m_CurrentAutoExposure = dst; } // Generate debug histogram if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.EyeAdaptation)) { if (m_DebugHistogram == null || !m_DebugHistogram.IsCreated()) { m_DebugHistogram = new RenderTexture(256, 128, 0, RenderTextureFormat.ARGB32) { filterMode = FilterMode.Point, wrapMode = TextureWrapMode.Clamp }; } material.SetFloat(Uniforms._DebugWidth, m_DebugHistogram.width); Graphics.Blit(null, m_DebugHistogram, material, 2); } m_FrameCount++; return(m_CurrentAutoExposure); }
void Start() { if (baseMesh == null) { baseMesh = GetComponent <MeshFilter>().sharedMesh; } #if UNITY_EDITOR var cam = Camera.current; if (cam == null || Application.isPlaying) { cam = Camera.main; } #else var cam = Camera.main; #endif var draft = new MeshDraft(); var rand = new System.Random(0); // expend the number normalBufferof triangles var triangles = baseMesh.Triangles(); var dist = Vector3.Distance(cam.transform.position, transform.position); var lod = (1f - ((Mathf.Clamp(dist, minDist, maxDist)) - minDist) / (maxDist - minDist)); var numSplits = lod * maxSplits; var height = lod * maxHeight; #if DEBUG Debug.Log(dist + " : " + numSplits); var startTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; #endif // Kernel One var eye = cam.transform.forward; for (int i = 0; i < numSplits; i++) { var tmpTriangles = new ConcurrentStack <(Vector3 a, Vector3 b, Vector3 c)>(); Parallel.ForEach(triangles, tri => { if (Vector3.Dot(tri.Normal(), eye) < 0) { var(middle, oposite, first, second) = tri.MiddleLargestSide(); tmpTriangles.Push((oposite, first, middle)); tmpTriangles.Push((oposite, middle, second)); } }); triangles = tmpTriangles.ToArray(); } #if DEBUG var endTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; Debug.Log("Kernel One (CPU) : " + (endTime - startTime)); startTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; #endif // Kernel Two buffer = new ComputeBuffer(triangles.Length, 36); buffer.SetData(ToGPUTriangle(triangles)); outputBuffer = new ComputeBuffer(triangles.Length * 3, 12); normalBuffer = new ComputeBuffer(triangles.Length * 3, 12); int kernel = shader.FindKernel("CSMain"); shader.SetVector("position", transform.position); shader.SetFloat("randWidth", randWidth); shader.SetFloat("randHeight", randHeight); shader.SetFloat("randLeanDist", randLeanDist); shader.SetFloat("maxWidth", maxWidth); shader.SetFloat("maxHeight", maxHeight); shader.SetFloat("leanDist", leanDist); shader.SetBuffer(kernel, "dataBuffer", buffer); shader.SetBuffer(kernel, "outputBuffer", outputBuffer); shader.SetBuffer(kernel, "normalBuffer", normalBuffer); shader.Dispatch(kernel, triangles.Length, 1, 1); #if DEBUG endTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; Debug.Log("Kernel Two (GPU) : " + (endTime - startTime)); #endif //var array = new Vector3[triangles.Length * 3]; //outputBuffer.GetData(array); //Debug.Log(string.Join(",", array)); //Debug.Log(string.Join(",", triangles)); //Grass = draft.ToMesh(); }
private void OnGUI() { if (!drawShader) { drawShader = Resources.Load <ComputeShader>("ShaderBlend"); } targetShowMat = EditorGUILayout.ObjectField("Target Material: ", targetShowMat, typeof(Material), true) as Material; //TODO rtSize = EditorGUILayout.Vector2IntField("Texture Size: ", rtSize); rtSize.x = max(1, rtSize.x); rtSize.y = max(1, rtSize.y); format = (RenderTextureFormat)EditorGUILayout.EnumPopup("Texture Format: ", format); //Set RT if (!rt) { rt = new RenderTexture(new RenderTextureDescriptor { colorFormat = format, depthBufferBits = 0, enableRandomWrite = true, height = rtSize.y, width = rtSize.x, volumeDepth = 1, msaaSamples = 1, sRGB = false, dimension = TextureDimension.Tex2D }); rt.Create(); } else if (rt.format != format || rt.width != rtSize.x || rt.height != rtSize.y) { rt.Release(); rt.width = rtSize.x; rt.height = rtSize.y; rt.format = format; rt.Create(); } if (targetShowMat) { targetShowMat.SetTexture(ShaderIDs._MainTex, rt); } drawShader.SetTexture(1, ShaderIDs._MainTex, rt); drawShader.SetVector("_MainTex_TexelSize", float4(1f / rtSize.x, 1f / rtSize.y, rtSize.x - 0.1f, rtSize.y - 0.1f)); initColor = EditorGUILayout.ColorField("Initial Color: ", initColor); drawShader.SetVector("_InitialColor", new Vector4(initColor.r, initColor.g, initColor.b, initColor.a)); drawShader.Dispatch(1, Mathf.CeilToInt(rtSize.x / 8f), Mathf.CeilToInt(rtSize.y / 8f), 1); for (int i = 0; i < allTextures.Count; ++i) { var e = allTextures[i]; EditorGUILayout.BeginHorizontal(); e.isOpen = EditorGUILayout.Foldout(e.isOpen, "Texture Layer " + i); bool remove = GUILayout.Button("Remove", GUILayout.MaxWidth(100)); EditorGUILayout.EndHorizontal(); if (remove) { allTextures.RemoveAt(i); i--; } else { if (e.isOpen) { EditorGUI.indentLevel++; e.targetTexture = EditorGUILayout.ObjectField("Texture: ", e.targetTexture, typeof(Texture), true) as Texture; e.voronoiSample = EditorGUILayout.Toggle("Voronoi Sample: ", e.voronoiSample); e.size = saturate(EditorGUILayout.Vector2Field("Blend Size", saturate(e.size))); e.blendAlpha = EditorGUILayout.Slider("Blend Alpha: ", e.blendAlpha, 0, 1); e.scale = EditorGUILayout.Vector2Field("Tiling Scale: ", e.scale); e.offset = EditorGUILayout.Vector2Field("Tiling Offset: ", e.offset); //Start Blending EditorGUI.indentLevel--; } allTextures[i] = e; } } foreach (var e in allTextures) { if (e.targetTexture) { int2 blendSize = (int2)(e.size * float2(rtSize.x, rtSize.y)); if (blendSize.x > 0 && blendSize.y > 0) { float4 blendTexelSize = float4(1f / (float2)blendSize, (float2)blendSize.xy - 0.1f); float4 offsetScale = float4(floor(e.offset * float2(rtSize.x, rtSize.y) + 0.1f), e.scale); int pass = e.voronoiSample ? 3 : 0; drawShader.SetTexture(pass, ShaderIDs._MainTex, rt); drawShader.SetTexture(pass, "_BlendTex", e.targetTexture); drawShader.SetVector("_OffsetScale", offsetScale); drawShader.SetVector("_BlendTex_TexelSize", blendTexelSize); drawShader.SetFloat("_BlendAlpha", e.blendAlpha); drawShader.Dispatch(pass, Mathf.CeilToInt(blendSize.x / 8f), Mathf.CeilToInt(blendSize.y / 8f), 1); } } } if (GUILayout.Button("Add New Texture")) { allTextures.Add(new TextureSettings { blendAlpha = 1f, voronoiSample = false, isOpen = false, offset = 0, size = 1, scale = 1, targetTexture = null }); } saveIsOpen = EditorGUILayout.Foldout(saveIsOpen, "Save Mode: "); if (saveIsOpen) { EditorGUI.indentLevel++; path = EditorGUILayout.TextField("Save Path: ", path); saveFormat = (TextureFormat)EditorGUILayout.EnumPopup("Save Format: ", saveFormat); if (GUILayout.Button("Save To PNG")) { Texture2D tex = new Texture2D(rtSize.x, rtSize.y, saveFormat, false, true); ComputeBuffer dataBuffer = new ComputeBuffer(rtSize.x * rtSize.y, sizeof(float4)); drawShader.SetTexture(2, ShaderIDs._MainTex, rt); drawShader.SetBuffer(2, "_ColorBuffer", dataBuffer); drawShader.Dispatch(2, Mathf.CeilToInt(rtSize.x / 8f), Mathf.CeilToInt(rtSize.y / 8f), 1); Color[] colors = new Color[rtSize.x * rtSize.y]; dataBuffer.GetData(colors); tex.SetPixels(colors); System.IO.File.WriteAllBytes(path, tex.EncodeToPNG()); } EditorGUI.indentLevel--; } }
private static bool CaptureViews(Transform root, BillboardImposter imposter, Snapshots[] snapshots, Transform lightingRoot, Shader albedoBake, Shader normalBake, ComputeShader processCompute) { Vector3 originalScale = root.localScale; //reset root local scale root.localScale = Vector3.one; var prevRt = RenderTexture.active; ///////////////// create the atlas for base and pack //base target var baseAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); baseAtlas.enableRandomWrite = true; baseAtlas.Create(); //world normal target var packAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); packAtlas.enableRandomWrite = true; packAtlas.Create(); //temp var tempAtlas = RenderTexture.GetTemporary(baseAtlas.descriptor); tempAtlas.Create(); ////////////// create the single frame RT for base and pack var frameReso = _atlasResolution / imposter.Frames; //base frame (multiple frames make up target) var frame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); frame.enableRandomWrite = true; frame.Create(); //world normal frame var packFrame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); packFrame.Create(); //temp var tempFrame = RenderTexture.GetTemporary(frame.descriptor); tempFrame.Create(); //high-res frame, intended for super sampling //TODO proper super sampling //upscale 4 times var frameResUpscale = frameReso * 4; var superSizedFrame = RenderTexture.GetTemporary(frameResUpscale, frameResUpscale, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); superSizedFrame.enableRandomWrite = true; superSizedFrame.Create(); //temp var superSizedFrameTemp = RenderTexture.GetTemporary(superSizedFrame.descriptor); var superSizedAlphaMask = RenderTexture.GetTemporary(superSizedFrame.descriptor); superSizedAlphaMask.Create(); //////////// create the Texture2D used for writing final image imposter.BaseTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true); imposter.PackTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true); //compute buffer for distance alpha ComputeBuffer minDistancesBuffer = new ComputeBuffer(frame.width * frame.height, sizeof(float)); ComputeBuffer maxDistanceBuffer = new ComputeBuffer(1, sizeof(float)); const int layer = 30; var clearColor = Color.clear; //create camera var camera = new GameObject().AddComponent <Camera>(); camera.gameObject.hideFlags = HideFlags.DontSave; camera.cullingMask = 1 << layer; camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = clearColor; camera.orthographic = true; camera.nearClipPlane = 0f; camera.farClipPlane = imposter.Radius * 2f; camera.orthographicSize = imposter.Radius; camera.allowMSAA = false; camera.enabled = false; var frameCount = imposter.Frames * imposter.Frames; //set and store original layer to restore afterwards var originalLayers = new Dictionary <GameObject, int>(); StoreLayers(root, layer, ref originalLayers); var originalLights = new Dictionary <Light, bool>(); var customLit = lightingRoot != null; //custom lit renders with lighting into base RGB if (customLit) { //toggle all lights off except for lighting rig var lights = FindObjectsOfType <Light>(); for (var i = 0; i < lights.Length; i++) { //not part of lighting rig if (!lights[i].transform.IsChildOf(lightingRoot)) { if (originalLights.ContainsKey(lights[i])) { continue; } //store original state originalLights.Add(lights[i], lights[i].enabled); //toggle it off lights[i].enabled = false; } else { //is part of lighting rig lights[i].enabled = true; //store state as off if (!originalLights.ContainsKey(lights[i])) { originalLights.Add(lights[i], false); } } } } //first render solid color replacement, checking for filled pixels //this decides if the camera can be cropped in closer to maximize atlas usage var tempMinMaxRT = RenderTexture.GetTemporary(frame.width, frame.height, 0, RenderTextureFormat.ARGB32); tempMinMaxRT.Create(); Graphics.SetRenderTarget(tempMinMaxRT); GL.Clear(true, true, Color.clear); camera.clearFlags = CameraClearFlags.Nothing; camera.backgroundColor = clearColor; camera.targetTexture = tempMinMaxRT; var min = Vector2.one * frame.width; var max = Vector2.zero; for (var i = 0; i < frameCount; i++) { if (i > snapshots.Length - 1) { Debug.LogError("[IMP] snapshot data length less than frame count! this shouldn't happen!"); continue; } //position camera with the current snapshot info var snap = snapshots[i]; camera.transform.position = snap.Position; camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up); //render alpha only Shader.SetGlobalFloat("_ImposterRenderAlpha", 1f); camera.RenderWithShader(albedoBake, ""); camera.ResetReplacementShader(); //render without clearing (accumulating filled pixels) camera.Render(); //supply the root position taken into camera space //this is for the min max, in the case root is further from opaque pixels var viewPos = camera.WorldToViewportPoint(root.position); var texPos = new Vector2(viewPos.x, viewPos.y) * frame.width; texPos.x = Mathf.Clamp(texPos.x, 0f, frame.width); texPos.y = Mathf.Clamp(texPos.y, 0f, frame.width); min.x = Mathf.Min(min.x, texPos.x); min.y = Mathf.Min(min.y, texPos.y); max.x = Mathf.Max(max.x, texPos.x); max.y = Mathf.Max(max.y, texPos.y); } camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = clearColor; camera.targetTexture = null; //now read render texture var tempMinMaxTex = new Texture2D(tempMinMaxRT.width, tempMinMaxRT.height, TextureFormat.ARGB32, false); RenderTexture.active = tempMinMaxRT; tempMinMaxTex.ReadPixels(new Rect(0f, 0f, tempMinMaxRT.width, tempMinMaxRT.height), 0, 0); tempMinMaxTex.Apply(); var tempTexC = tempMinMaxTex.GetPixels32(); //loop pixels get min max for (var c = 0; c < tempTexC.Length; c++) { if (tempTexC[c].r != 0x00) { var texPos = Get2DIndex(c, tempMinMaxRT.width); min.x = Mathf.Min(min.x, texPos.x); min.y = Mathf.Min(min.y, texPos.y); max.x = Mathf.Max(max.x, texPos.x); max.y = Mathf.Max(max.y, texPos.y); } } DestroyImmediate(tempMinMaxTex, true); RenderTexture.ReleaseTemporary(tempMinMaxRT); //rescale radius var len = new Vector2(max.x - min.x, max.y - min.y); ////add 2 pixels to x and y //len.x += 2f; //len.y += 2f; var maxR = Mathf.Max(len.x, len.y); var ratio = maxR / frame.width; //assume square //adjust ratio (if clipping is too tight) //ratio = Mathf.Lerp(1f, ratio, _pixelCrop); imposter.Radius = imposter.Radius * ratio; //adjust the camera size and far clip camera.farClipPlane = imposter.Radius * 2f; camera.orthographicSize = imposter.Radius; //use a scale factor to make sure the offset is in the correct location //this is related to scaling the asset to 1,1,1 while baking, to ensure imposter matches all types of asset scaling Vector3 scaleFactor = new Vector3(root.localScale.x / originalScale.x, root.localScale.y / originalScale.y, root.localScale.z / originalScale.z); imposter.Offset = Vector3.Scale(imposter.Offset, scaleFactor); //recalculate snapshots snapshots = UpdateSnapshots(imposter.Frames, imposter.Radius, root.position + imposter.Offset, imposter.IsHalf); ///////////////////// rendering the actual frames int kernelCSDilate = processCompute.FindKernel("CSDilate"); int kernelCSDistanceAlpha = processCompute.FindKernel("CSDistanceAlpha"); int kernelCSDistanceAlphaGetMax = processCompute.FindKernel("CSDistanceAlphaGetMax"); int kernelCSDistanceAlphaFinalize = processCompute.FindKernel("CSDistanceAlphaFinalize"); for (var frameIndex = 0; frameIndex < frameCount; frameIndex++) { if (frameIndex > snapshots.Length - 1) { Debug.LogError("[IMP] snapshot data length less than frame count! this shouldn't happen!"); continue; } var snap = snapshots[frameIndex]; camera.transform.position = snap.Position; camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up); clearColor = Color.clear; //target and clear base frame Graphics.SetRenderTarget(superSizedFrame); GL.Clear(true, true, clearColor); Graphics.SetRenderTarget(superSizedFrameTemp); GL.Clear(true, true, clearColor); //render into temp camera.targetTexture = superSizedFrameTemp; camera.backgroundColor = clearColor; if (!customLit) { Shader.SetGlobalFloat("_ImposterRenderAlpha", 0f); camera.RenderWithShader(albedoBake, ""); camera.ResetReplacementShader(); } else { //render without replacement camera.Render(); } camera.targetTexture = superSizedAlphaMask; camera.backgroundColor = clearColor; camera.Render(); //solidify alpha (uses step) //TODO probably dont need this anymore Graphics.Blit(superSizedAlphaMask, superSizedFrame, _processingMat, 3); Graphics.Blit(superSizedFrame, superSizedAlphaMask); //combine RGB and ALPHA _processingMat.SetTexture("_MainTex", superSizedFrameTemp); _processingMat.SetTexture("_MainTex2", superSizedAlphaMask); _processingMat.SetFloat("_Step", 1f); //result in frameUp Graphics.Blit(superSizedFrameTemp, superSizedFrame, _processingMat, 1); //target frame and clear, TODO proper sampling Graphics.SetRenderTarget(frame); GL.Clear(true, true, clearColor); Graphics.Blit(superSizedFrame, frame); //clear superSized frames for use with normals + depth Graphics.SetRenderTarget(superSizedFrameTemp); GL.Clear(true, true, clearColor); Graphics.SetRenderTarget(superSizedFrame); GL.Clear(true, true, clearColor); //render normals & depth //camera background half gray (helps with height displacement) clearColor = new Color(0.0f, 0.0f, 0.0f, 0.5f); camera.targetTexture = superSizedFrame; camera.backgroundColor = clearColor; camera.RenderWithShader(normalBake, ""); camera.ResetReplacementShader(); //clear the pack frame and write TODO proper sampling Graphics.SetRenderTarget(packFrame); GL.Clear(true, true, clearColor); Graphics.Blit(superSizedFrame, packFrame); //////////// perform processing on frames //pack frame is done first so alpha of base frame can be used as a mask (before distance alpha process) Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); //padding / dilate TODO can be improved? int threadsX, threadsY, threadsZ; CalcWorkSize(packFrame.width * packFrame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(kernelCSDilate, "Source", packFrame); processCompute.SetTexture(kernelCSDilate, "SourceMask", frame); processCompute.SetTexture(kernelCSDilate, "Result", tempFrame); processCompute.SetBool("AllChannels", true); processCompute.SetBool("NormalsDepth", true); processCompute.Dispatch(kernelCSDilate, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, packFrame); //Perform processing on base atlas, Albedo + alpha (alpha is modified) Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); //padding / dilate CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(kernelCSDilate, "Source", frame); processCompute.SetTexture(kernelCSDilate, "SourceMask", frame); processCompute.SetTexture(kernelCSDilate, "Result", tempFrame); processCompute.SetBool("AllChannels", false); processCompute.SetBool("NormalsDepth", false); processCompute.Dispatch(kernelCSDilate, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, frame); Graphics.SetRenderTarget(tempFrame); GL.Clear(true, true, Color.clear); //distance field alpha //step 1 store min distance to unfilled alpha CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(kernelCSDistanceAlpha, "Source", frame); processCompute.SetTexture(kernelCSDistanceAlpha, "SourceMask", frame); processCompute.SetBuffer(kernelCSDistanceAlpha, "MinDistances", minDistancesBuffer); processCompute.Dispatch(kernelCSDistanceAlpha, threadsX, threadsY, threadsZ); //step 2 write maximum of the min distances to MaxDistanceBuffer[0] //also reset the min distances to 0 during this kernel processCompute.SetInt("MinDistancesLength", minDistancesBuffer.count); processCompute.SetBuffer(kernelCSDistanceAlphaGetMax, "MaxOfMinDistances", maxDistanceBuffer); processCompute.SetBuffer(kernelCSDistanceAlphaGetMax, "MinDistances", minDistancesBuffer); processCompute.Dispatch(kernelCSDistanceAlphaGetMax, 1, 1, 1); //step 3 write min distance / max of min to temp frame CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ); processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "Source", frame); processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "SourceMask", frame); processCompute.SetTexture(kernelCSDistanceAlphaFinalize, "Result", tempFrame); processCompute.SetBuffer(kernelCSDistanceAlphaFinalize, "MinDistances", minDistancesBuffer); processCompute.SetBuffer(kernelCSDistanceAlphaFinalize, "MaxOfMinDistances", maxDistanceBuffer); processCompute.Dispatch(kernelCSDistanceAlphaFinalize, threadsX, threadsY, threadsZ); Graphics.Blit(tempFrame, frame); //convert 1D index to flattened octahedra coordinate int x; int y; //this is 0-(frames-1) ex, 0-(12-1) 0-11 (for 12 x 12 frames) XYFromIndex(frameIndex, imposter.Frames, out x, out y); //X Y position to write frame into atlas //this would be frame index * frame width, ex 2048/12 = 170.6 = 170 //so 12 * 170 = 2040, loses 8 pixels on the right side of atlas and top of atlas x *= frame.width; y *= frame.height; //copy base frame into base render target Graphics.CopyTexture(frame, 0, 0, 0, 0, frame.width, frame.height, baseAtlas, 0, 0, x, y); //copy normals frame into normals render target Graphics.CopyTexture(packFrame, 0, 0, 0, 0, packFrame.width, packFrame.height, packAtlas, 0, 0, x, y); } //read render target pixels Graphics.SetRenderTarget(packAtlas); imposter.PackTexture.ReadPixels(new Rect(0f, 0f, packAtlas.width, packAtlas.height), 0, 0); Graphics.SetRenderTarget(baseAtlas); imposter.BaseTexture.ReadPixels(new Rect(0f, 0f, baseAtlas.width, baseAtlas.height), 0, 0); //restore previous render target RenderTexture.active = prevRt; baseAtlas.Release(); frame.Release(); packAtlas.Release(); packFrame.Release(); RenderTexture.ReleaseTemporary(baseAtlas); RenderTexture.ReleaseTemporary(packAtlas); RenderTexture.ReleaseTemporary(tempAtlas); RenderTexture.ReleaseTemporary(frame); RenderTexture.ReleaseTemporary(packFrame); RenderTexture.ReleaseTemporary(tempFrame); RenderTexture.ReleaseTemporary(superSizedFrame); RenderTexture.ReleaseTemporary(superSizedAlphaMask); RenderTexture.ReleaseTemporary(superSizedFrameTemp); minDistancesBuffer.Dispose(); maxDistanceBuffer.Dispose(); DestroyImmediate(camera.gameObject, true); //restore layers RestoreLayers(originalLayers); //restore lights var enumerator2 = originalLights.Keys.GetEnumerator(); while (enumerator2.MoveNext()) { var light = enumerator2.Current; if (light != null) { light.enabled = originalLights[light]; } } enumerator2.Dispose(); originalLights.Clear(); var savePath = ""; var file = ""; var filePrefab = ""; if (imposter.AssetReference != null) { savePath = AssetDatabase.GetAssetPath(imposter.AssetReference); var lastSlash = savePath.LastIndexOf("/", StringComparison.Ordinal); var folder = savePath.Substring(0, lastSlash); file = savePath.Substring(lastSlash + 1, savePath.LastIndexOf(".", StringComparison.Ordinal) - lastSlash - 1); filePrefab = file; savePath = folder + "/" + file + "_Imposter" + ".asset"; } else //no prefab, ask where to save { file = root.name; savePath = EditorUtility.SaveFilePanelInProject("Save Billboard Imposter", file + "_Imposter", "asset", "Select save location"); } imposter.PrefabSuffix = _suffix; imposter.name = file; AssetDatabase.CreateAsset(imposter, savePath); imposter.Save(savePath, file, _createUnityBillboard); //spawn var spawned = imposter.Spawn(root.position, true, filePrefab); spawned.transform.position = root.position + new Vector3(2f, 0f, 2f); spawned.transform.rotation = root.rotation; spawned.transform.localScale = originalScale; root.localScale = originalScale; return(true); }
// Function which voxelizes the scene and stores the grid in the voxel buffer private void Voxelize() { // Kernel index for the entry point in compute shader int kernelHandle = filteredVoxelizationShader.FindKernel("FilteredVoxelizationMain"); int currentVoxelVolumeDimension = 1; filteredVoxelizationShader.SetBuffer(kernelHandle, "_VoxelVolumeBuffer", voxelVolumeBufferSpecular); filteredVoxelizationShader.SetInt("_VoxelVolumeDimension", voxelVolumeDimensionSpecular); currentVoxelVolumeDimension = voxelVolumeDimensionSpecular; // 1st pass // Render the color and position textures for the camera frontCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", frontCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", frontCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); // 2nd pass // Render the color and position textures for the camera backCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", backCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", backCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); // 3rd pass // Render the color and position textures for the camera leftCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", leftCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", leftCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); // 4th pass // Render the color and position textures for the camera rightCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", rightCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", rightCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); // 5th pass // Render the color and position textures for the camera topCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", topCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", topCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); // 6th pass // Render the color and position textures for the camera bottomCamera.GetComponent <WorldPositionSecondary>().RenderTextures(); filteredVoxelizationShader.SetTexture(kernelHandle, "_DirectLightingColorTexture", bottomCamera.GetComponent <WorldPositionSecondary>().GetDirectTexture()); filteredVoxelizationShader.SetTexture(kernelHandle, "_PositionTexture", bottomCamera.GetComponent <WorldPositionSecondary>().GetPositionTexture()); filteredVoxelizationShader.Dispatch(kernelHandle, currentVoxelVolumeDimension, currentVoxelVolumeDimension, 1); }
protected void InitParticlesKernel() { var kernel = compute.FindKernel("InitParticles"); compute.SetBuffer(kernel, "_Particles", particleBuffer.Read); // Set object pool buffer as AppendStructuredBuffer compute.SetBuffer(kernel, "_ParticlePoolAppend", poolBuffer); Dispatch1D(kernel, count); }
/// <summary> /// Computes the volumetric data /// </summary> public void ComputeData() { if (!_hasInitializedBuffers) { CreateBuffers(settings.resolution); } settings.ComputeFlags(); #region Variables _farClip = Mathf.Min(Aura.CameraComponent.farClipPlane, Mathf.Max(Aura.CameraComponent.nearClipPlane, settings.farClipPlaneDistance)); _cameraRanges = new Vector4(Aura.CameraComponent.nearClipPlane, _farClip); Shader.SetGlobalVector("Aura_FrustumRange", _cameraRanges); _zParameters = new Vector4(-1.0f + Aura.CameraComponent.farClipPlane / Aura.CameraComponent.nearClipPlane, 1.0f); _zParameters.z = _zParameters.x / Aura.CameraComponent.farClipPlane; _zParameters.w = _zParameters.y / Aura.CameraComponent.farClipPlane; _volumeDepth = _farClip - Aura.CameraComponent.nearClipPlane; _layerDepth = _volumeDepth / _resolutionVector.z; _inverseLayerDepth = 1.0f / _layerDepth; #endregion #region Occlusion culling if (settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling)) { Profiler.BeginSample("Aura : Compute occlusion culling data"); _computeMaximumDepthComputeShader.SetTextureFromGlobal((int)settings.occlusionCullingAccuracy, "depthTexture", "_CameraDepthTexture"); // TODO : USE EVENT TO SET TEXTURES _computeMaximumDepthComputeShader.SetVector("cameraRanges", _cameraRanges); _computeMaximumDepthComputeShader.SetVector("zParameters", _zParameters); _computeMaximumDepthComputeShader.SetTexture((int)settings.occlusionCullingAccuracy, "occlusionTexture", _buffers.OcclusionTexture.WriteBuffer); _computeMaximumDepthComputeShader.Dispatch((int)settings.occlusionCullingAccuracy, settings.resolution.x, settings.resolution.y, 1); //Par blocks puis repasser en resolution _buffers.OcclusionTexture.Swap(); if (_processOcclusionMapMaterial == null) { _processOcclusionMapMaterial = new Material(_processOcclusionMapShader); } _processOcclusionMapMaterial.SetVector("bufferResolution", _resolutionVector); Graphics.Blit(_buffers.OcclusionTexture.ReadBuffer, _buffers.OcclusionTexture.WriteBuffer, _processOcclusionMapMaterial); _buffers.OcclusionTexture.Swap(); _computeDataComputeShader.SetTexture(settings.GetId(), "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "occlusionTexture", _buffers.OcclusionTexture.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.FogVolumeTexture.Clear(Color.black); Profiler.EndSample(); } #endregion #region Compute contributions Profiler.BeginSample("Aura : Compute volumetric lighting and density"); _buffers.LightingVolumeTextures.Swap(); Shader.SetGlobalTexture("Aura_VolumetricDataTexture", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _buffers.LightingVolumeTextures.WriteBuffer.Clear(new Color(0, 0, 0, -10)); _computeDataComputeShader.SetTexture(settings.GetId(), "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "previousFrameLightingVolumeTexture", _buffers.LightingVolumeTextures.ReadBuffer); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetFloat("time", Aura.Time); _computeDataComputeShader.SetVector("cameraPosition", Aura.CameraComponent.transform.position); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetFloat("layerDepth", _layerDepth); _computeDataComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeDataComputeShader.SetFloats("frustumCornersWorldPositionArray", Aura.CameraComponent.GetFrustumCornersWorldPosition(Aura.CameraComponent.nearClipPlane, _farClip).AsFloatArray()); _computeDataComputeShader.SetFloat("baseDensity", settings.density); _computeDataComputeShader.SetFloat("baseAnisotropy", settings.anisotropy); _computeDataComputeShader.SetVector("baseColor", settings.color * settings.colorStrength); #region Temporal Reprojection if (settings.HasFlags(FrustumParametersEnum.EnableTemporalReprojection)) { _computeDataComputeShader.SetFloat("temporalReprojectionFactor", settings.temporalReprojectionFactor); _computeDataComputeShader.SetVector("cameraRanges", _cameraRanges); _computeDataComputeShader.SetInt("_frameID", Aura.FrameId); } #endregion #region Volumes Injection if (settings.HasFlags(FrustumParametersEnum.EnableVolumes)) { _computeDataComputeShader.SetInt("volumeCount", Aura.VolumesManager.Buffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "volumeDataBuffer", Aura.VolumesManager.Buffer); if (settings.HasFlags(FrustumParametersEnum.EnableVolumesTextureMask)) { _computeDataComputeShader.SetTexture(settings.GetId(), "volumeMaskTexture", Aura.VolumesManager.VolumeTexture); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Directional lights if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLights)) { _computeDataComputeShader.SetInt("directionalLightCount", Aura.LightsManager.DirectionalLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "directionalLightDataBuffer", Aura.LightsManager.DirectionalLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableDirectionalLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowMapsArray", Aura.LightsManager.DirectionalLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES _computeDataComputeShader.SetTexture(settings.GetId(), "directionalShadowDataArray", Aura.LightsManager.DirectionalLightsManager.ShadowDataArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.DirectionalLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "directionalCookieMapsArray", Aura.LightsManager.DirectionalLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Spot lights if (settings.HasFlags(FrustumParametersEnum.EnableSpotLights)) { _computeDataComputeShader.SetInt("spotLightCount", Aura.LightsManager.SpotLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "spotLightDataBuffer", Aura.LightsManager.SpotLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnableSpotLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotShadowMapsArray", Aura.LightsManager.SpotLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.SpotLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "spotCookieMapsArray", Aura.LightsManager.SpotLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Point lights if (settings.HasFlags(FrustumParametersEnum.EnablePointLights)) { _computeDataComputeShader.SetInt("pointLightCount", Aura.LightsManager.PointLightsManager.DataBuffer.count); _computeDataComputeShader.SetBuffer(settings.GetId(), "pointLightDataBuffer", Aura.LightsManager.PointLightsManager.DataBuffer); if (settings.HasFlags(FrustumParametersEnum.EnablePointLightsShadows)) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointShadowMapsArray", Aura.LightsManager.PointLightsManager.ShadowMapsArray); // TODO : USE EVENT TO SET TEXTURES } if (settings.HasFlags(FrustumParametersEnum.EnableLightsCookies) && Aura.LightsManager.PointLightsManager.HasCookieCasters) { _computeDataComputeShader.SetTexture(settings.GetId(), "pointCookieMapsArray", Aura.LightsManager.PointLightsManager.CookieMapsArray); // TODO : USE EVENT TO SET TEXTURES } } #endregion #region Compute _computeDataComputeShader.Dispatch(settings.GetId(), _computeDataComputeShaderDispatchSizeX, _computeDataComputeShaderDispatchSizeY, _computeDataComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion #endregion #region Accumulate fog texture Profiler.BeginSample("Aura : Compute accumulated contributions"); _computeAccumulationComputeShader.SetFloat("layerDepth", _layerDepth); _computeAccumulationComputeShader.SetFloat("invLayerDepth", _inverseLayerDepth); _computeAccumulationComputeShader.SetTexture(0, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetTexture(1, "textureBuffer", _buffers.LightingVolumeTextures.WriteBuffer); // TODO : USE EVENT TO SET TEXTURES _computeAccumulationComputeShader.SetFloat("normalizationCoefficient", -(_farClip - Aura.CameraComponent.nearClipPlane) / 256.0f); // simplified from : (farClip - Aura.cameraComponent.nearClipPlane) / resolution.z) [->layerDepth] * (bufferResolution.z / 256.0f) [->buffer resolution normalization (256.0f is an abritrary scale factor)] * -1 [->needed for exponential function] _computeAccumulationComputeShader.Dispatch(settings.HasFlags(FrustumParametersEnum.EnableOcclusionCulling) ? 1 : 0, _computeAccumulationComputeShaderDispatchSizeX, _computeAccumulationComputeShaderDispatchSizeY, _computeAccumulationComputeShaderDispatchSizeZ); Profiler.EndSample(); #endregion _computeDataComputeShader.SetFloats("previousFrameWorldToClipMatrix", FrustumCorners.GetWorldToClipMatrix(Aura.CameraComponent, _farClip).ToFloatArray()); }
public void BuildPipeline() { if (IsInitialized) { return; } if (m_PathTracingShader == null) { return; } if (m_Camera == null) { return; } m_KernelIndex = m_PathTracingShader.FindKernel(m_KernelName); if (m_KernelIndex < 0) { return; } if (m_EnableNEE) { m_PathTracingShader.EnableKeyword("ENABLE_NEXT_EVENT_ESTIMATION"); } else { m_PathTracingShader.DisableKeyword("ENABLE_NEXT_EVENT_ESTIMATION"); } if (m_EnableThinLens) { m_PathTracingShader.EnableKeyword("ENABLE_THIN_LENS"); } else { m_PathTracingShader.DisableKeyword("ENABLE_THIN_LENS"); } if (m_EnableSampleTexture) { m_PathTracingShader.EnableKeyword("ENABLE_SAMPLE_TEXTURE"); } else { m_PathTracingShader.DisableKeyword("ENABLE_SAMPLE_TEXTURE"); } if (m_EnableTangentSpace) { m_PathTracingShader.EnableKeyword("ENABLE_TANGENT_SPACE"); } else { m_PathTracingShader.DisableKeyword("ENABLE_TANGENT_SPACE"); } m_RenderTexture = new RenderTexture(Screen.width, Screen.height, 0, RenderTextureFormat.ARGBFloat); m_RenderTexture.enableRandomWrite = true; m_RenderTexture.Create(); m_DispatchThreadGroupsX = Mathf.CeilToInt((float)m_RenderTexture.width / kTileSize); m_DispatchThreadGroupsY = Mathf.CeilToInt((float)m_RenderTexture.height / kTileSize); List <PTMaterial> materials; List <Primitive> primitives; List <Texture2D> baseColorTextures = null; List <Texture2D> mroTextures = null; List <Texture2D> normalTextures = null; if (m_EnableSampleTexture) { baseColorTextures = new List <Texture2D>(); } if (m_EnableTangentSpace) { mroTextures = new List <Texture2D>(); normalTextures = new List <Texture2D>(); } CollectPrimitives(out materials, out primitives, ref baseColorTextures, ref mroTextures, ref normalTextures); BVH bvhTree = new BVH(); bvhTree.Build(primitives); List <Sphere> spheres; List <Quad> quads; List <Cube> cubes; List <Triangle> triangles; List <LBVHNode> bvh; int bvhRoot = BuildLBVH(bvhTree, out bvh, out spheres, out quads, out cubes, out triangles); if (m_EnableSampleTexture) { m_baseColorTextureArray = CreateTextureArray(baseColorTextures); m_PathTracingShader.SetTexture(m_KernelIndex, "_Textures", m_baseColorTextureArray); } if (m_EnableTangentSpace) { m_mroTextureArray = CreateTextureArray(mroTextures); m_normalTextureArray = CreateTextureArray(normalTextures); m_PathTracingShader.SetTexture(m_KernelIndex, "_MROTextures", m_mroTextureArray); m_PathTracingShader.SetTexture(m_KernelIndex, "_NormalTextures", m_normalTextureArray); } m_NodesBuffer = CreateComputeBuffer <LBVHNode>(bvh); m_SpheresBuffer = CreateComputeBuffer <Sphere>(spheres); m_QuadsBuffer = CreateComputeBuffer <Quad>(quads); m_CubeBuffer = CreateComputeBuffer <Cube>(cubes); m_TrianglesBuffer = CreateComputeBuffer <Triangle>(triangles); m_MaterialsBuffer = CreateComputeBuffer <PTMaterial>(materials); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Spheres", m_SpheresBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Quads", m_QuadsBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Cubes", m_CubeBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Triangles", m_TrianglesBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_BVHTree", m_NodesBuffer); m_PathTracingShader.SetBuffer(m_KernelIndex, "_Materials", m_MaterialsBuffer); m_PathTracingShader.SetInt("_BVHRootNodeIndex", bvhRoot); m_PathTracingShader.SetInt("_BVHNodeCount", bvh.Count); IsInitialized = true; m_PathTracingShader.SetTexture(m_KernelIndex, "_Result", m_RenderTexture); m_PathTracingShader.SetInt("_ScreenWidth", m_RenderTexture.width); m_PathTracingShader.SetInt("_ScreenHeight", m_RenderTexture.height); Debug.Log($"BVH Root:{bvhRoot}, BVH Childs:{bvh.Count}"); }
static public void ReadFromRenderTexture(RenderTexture tex, int channels, ComputeBuffer buffer, ComputeShader readData) { if (tex == null) { Debug.Log("CBUtility::ReadFromRenderTexture - RenderTexture is null"); return; } if (buffer == null) { Debug.Log("CBUtility::ReadFromRenderTexture - buffer is null"); return; } if (readData == null) { Debug.Log("CBUtility::ReadFromRenderTexture - Computer shader is null"); return; } if (channels < 1 || channels > 4) { Debug.Log("CBUtility::ReadFromRenderTexture - Channels must be 1, 2, 3, or 4"); return; } if (!tex.IsCreated()) { Debug.Log("CBUtility::ReadFromRenderTexture - tex has not been created (Call Create() on tex)"); return; } int kernel = -1; int depth = 1; string D = "2D"; string C = "C" + channels.ToString(); if (tex.dimension == UnityEngine.Rendering.TextureDimension.Tex3D) { depth = tex.volumeDepth; D = "3D"; } kernel = readData.FindKernel("read" + D + C); if (kernel == -1) { Debug.Log("CBUtility::ReadFromRenderTexture - could not find kernel " + "read" + D + C); return; } int width = tex.width; int height = tex.height; //set the compute shader uniforms readData.SetTexture(kernel, "_Tex" + D, tex); readData.SetInt("_Width", width); readData.SetInt("_Height", height); readData.SetInt("_Depth", depth); readData.SetBuffer(kernel, "_Buffer" + D + C, buffer); //run the compute shader. Runs in threads of 8 so non divisable by 8 numbers will need //some extra threadBlocks. This will result in some unneeded threads running int padX = (width % 8 == 0) ? 0 : 1; int padY = (height % 8 == 0) ? 0 : 1; int padZ = (depth % 8 == 0) ? 0 : 1; readData.Dispatch(kernel, Mathf.Max(1, width / 8 + padX), Mathf.Max(1, height / 8 + padY), Mathf.Max(1, depth / 8 + padZ)); }
public void SetBuffer(ComputeShader compute, int kernel) { compute.SetInt(ShaderConst.PROP_WALL_COUNT, _colliders.Count); compute.SetBuffer(kernel, ShaderConst.BUF_WALL, Walls); }
private bool CreateCoordMapperShader(KinectInterop.SensorData sensorData, bool bColor2Depth) { if (_depthCameraIntrinsics == null || _colorCameraIntrinsics == null || _coordinateMapper == null) { return(false); } _coordMapperShader = Resources.Load("CoordMapper") as ComputeShader; if (_coordMapperShader) { _depth2colorKernel = _coordMapperShader.FindKernel("MapDepthFrame2ColorFrame"); _color2depthKernel = _coordMapperShader.FindKernel("MapColorSpace2DepthFrame"); float[] depthFocalLength = new float[] { _depthCameraIntrinsics.FocalLengthX, _depthCameraIntrinsics.FocalLengthY }; float[] depthPrincipalPoint = new float[] { _depthCameraIntrinsics.PrincipalPointX, _depthCameraIntrinsics.PrincipalPointY }; float[] depthRadialDistortion = new float[] { _depthCameraIntrinsics.RadialDistortionSecondOrder, _depthCameraIntrinsics.RadialDistortionFourthOrder, _depthCameraIntrinsics.RadialDistortionSixthOrder }; _coordMapperShader.SetFloats("depthFocalLength", depthFocalLength); _coordMapperShader.SetFloats("depthPrincipalPoint", depthPrincipalPoint); _coordMapperShader.SetFloats("depthRadialDistortion", depthRadialDistortion); float[] colorFocalLength = new float[] { _colorCameraIntrinsics.FocalLengthX, _colorCameraIntrinsics.FocalLengthY }; float[] colorPrincipalPoint = new float[] { _colorCameraIntrinsics.PrincipalPointX, _colorCameraIntrinsics.PrincipalPointY }; float[] colorRadialDistortion = new float[] { _colorCameraIntrinsics.RadialDistortionSecondOrder, _colorCameraIntrinsics.RadialDistortionFourthOrder, _colorCameraIntrinsics.RadialDistortionSixthOrder }; _coordMapperShader.SetFloats("colorFocalLength", colorFocalLength); _coordMapperShader.SetFloats("colorPrincipalPoint", colorPrincipalPoint); _coordMapperShader.SetFloats("colorRadialDistortion", colorRadialDistortion); System.Numerics.Matrix4x4?matrix = !bColor2Depth ? _coordinateMapper.DepthToColorMatrix : _coordinateMapper.ColorToDepthMatrix; float[] space2spaceMat = new float[] { matrix.Value.M11, matrix.Value.M12, matrix.Value.M13, matrix.Value.M14, matrix.Value.M21, matrix.Value.M22, matrix.Value.M23, matrix.Value.M24, matrix.Value.M31, matrix.Value.M32, matrix.Value.M33, matrix.Value.M34, matrix.Value.M41, matrix.Value.M42, matrix.Value.M43, matrix.Value.M44 }; if (!bColor2Depth) { _coordMapperShader.SetFloats("depth2colorMat", space2spaceMat); } else { _coordMapperShader.SetFloats("color2depthMat", space2spaceMat); } // compute buffers int depthImageLength = sensorData.depthImageWidth * sensorData.depthImageHeight; _depthDepthValuesBuf = new ComputeBuffer(depthImageLength, sizeof(int)); _coordMapperShader.SetBuffer(_depth2colorKernel, "depthDepthValues", _depthDepthValuesBuf); if (!bColor2Depth) { _depthPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float)); _colorPlaneCoordsBuf = new ComputeBuffer(depthImageLength, 2 * sizeof(float)); // set plane coords Vector2[] depthPlaneCoords = new Vector2[depthImageLength]; for (int dy = 0, di = 0; dy < sensorData.depthImageHeight; dy++) { for (int dx = 0; dx < sensorData.depthImageWidth; dx++) { depthPlaneCoords[di] = new Vector2(dx, dy); di++; } } _depthPlaneCoordsBuf.SetData(depthPlaneCoords); _coordMapperShader.SetBuffer(_depth2colorKernel, "depthPlaneCoords", _depthPlaneCoordsBuf); _coordMapperShader.SetBuffer(_depth2colorKernel, "colorPlaneCoords", _colorPlaneCoordsBuf); } else { int colorImageLength = sensorData.colorImageWidth * sensorData.colorImageHeight; _colorSpaceCoordsBuf = new ComputeBuffer(colorImageLength, 3 * sizeof(float)); _colorDepthCoordsBuf = new ComputeBuffer(colorImageLength, 2 * sizeof(float)); _coordMapperShader.SetBuffer(_color2depthKernel, "colorSpaceCoords", _colorSpaceCoordsBuf); _coordMapperShader.SetBuffer(_color2depthKernel, "colorDepthCoords", _colorDepthCoordsBuf); } } return(_coordMapperShader != null); }
void UpdateHistogram(RenderTexture source, Rect rect, HistogramMode mode) { if (m_HistogramMaterial == null) { m_HistogramMaterial = ImageEffectHelper.CheckShaderAndCreateMaterial(concreteTarget.histogramShader); } if (m_HistogramBuffer == null) { m_HistogramBuffer = new ComputeBuffer(256, sizeof(uint) << 2); } m_HistogramBuffer.SetData(k_EmptyBuffer); ComputeShader cs = concreteTarget.histogramComputeShader; int kernel = cs.FindKernel("KHistogramGather"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetTexture(kernel, "_Source", source); int[] channels = null; switch (mode) { case HistogramMode.Luminance: channels = new[] { 0, 0, 0, 1 }; break; case HistogramMode.RGB: channels = new[] { 1, 1, 1, 0 }; break; case HistogramMode.Red: channels = new[] { 1, 0, 0, 0 }; break; case HistogramMode.Green: channels = new[] { 0, 1, 0, 0 }; break; case HistogramMode.Blue: channels = new[] { 0, 0, 1, 0 }; break; } cs.SetInts("_Channels", channels); cs.SetInt("_IsLinear", concreteTarget.isGammaColorSpace ? 0 : 1); cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1); kernel = cs.FindKernel("KHistogramScale"); cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer); cs.SetFloat("_Height", rect.height); cs.Dispatch(kernel, 1, 1, 1); if (m_HistogramTexture == null) { DestroyImmediate(m_HistogramTexture); m_HistogramTexture = new RenderTexture((int)rect.width, (int)rect.height, 0, RenderTextureFormat.ARGB32); m_HistogramTexture.hideFlags = HideFlags.HideAndDontSave; } m_HistogramMaterial.SetBuffer("_Histogram", m_HistogramBuffer); m_HistogramMaterial.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height)); m_HistogramMaterial.SetColor("_ColorR", redCurveColor); m_HistogramMaterial.SetColor("_ColorG", greenCurveColor); m_HistogramMaterial.SetColor("_ColorB", blueCurveColor); m_HistogramMaterial.SetColor("_ColorL", masterCurveColor); m_HistogramMaterial.SetInt("_Channel", (int)mode); Graphics.Blit(m_HistogramTexture, m_HistogramTexture, m_HistogramMaterial, (mode == HistogramMode.RGB) ? 1 : 0); }
protected void Setup(Vector3[] points) { var kernel = compute.FindKernel("Setup"); compute.SetBuffer(kernel, "_NodesPoolAppend", nodePoolBuffer); compute.SetBuffer(kernel, "_Nodes", nodeBuffer); GPUHelper.Dispatch1D(compute, kernel, count); using (ComputeBuffer seeds = new ComputeBuffer(points.Length, Marshal.SizeOf(typeof(Vector3)))) { seeds.SetData(points); kernel = compute.FindKernel("Start"); compute.SetFloat("_MassMin", massMin); compute.SetFloat("_MassMax", massMax); compute.SetBuffer(kernel, "_Start", seeds); compute.SetBuffer(kernel, "_Attractions", attractionBuffer); compute.SetBuffer(kernel, "_NodesPoolConsume", nodePoolBuffer); compute.SetBuffer(kernel, "_Nodes", nodeBuffer); GPUHelper.Dispatch1D(compute, kernel, seeds.count); } nodesCount = nodePoolBuffer.count; edgesCount = 0; }
private void UpdateShaderParameters(RenderTexture t, ComputeBuffer d, List <ComputeBuffer> d0, ComputeBuffer m) { uint zf, zd, zw; if (t == null) { t = _outputRT; } _kernelsLoaded = _shader.HasKernel("WriteDepth") && _shader.HasKernel("DisplaceAlbedo") && _shader.HasKernel("Clear"); if (!_kernelsLoaded) { Debug.LogError("Shader Kernel compilation error"); return; } _materialToShareTexture.SetTexture(_textureName, t); _clearKernel = _shader.FindKernel("Clear"); _writeDepthKernel = _shader.FindKernel("WriteDepth"); _displaceKernel = _shader.FindKernel("DisplaceAlbedo"); _shader.SetBuffer(_clearKernel, "Depth", d); _shader.SetBuffer(_clearKernel, "Depth0[0]", d0[0]); _shader.SetBuffer(_clearKernel, "Depth0[1]", d0[1]); _shader.SetBuffer(_clearKernel, "Depth0[2]", d0[2]); _shader.SetBuffer(_clearKernel, "Depth0[3]", d0[3]); _shader.SetBuffer(_clearKernel, "MutexBuffer", m); _shader.SetTexture(_clearKernel, "Result", t); _shader.SetBuffer(_writeDepthKernel, "Depth", d); _shader.SetBuffer(_writeDepthKernel, "Depth0[0]", d0[0]); _shader.SetBuffer(_writeDepthKernel, "Depth0[1]", d0[1]); _shader.SetBuffer(_writeDepthKernel, "Depth0[2]", d0[2]); _shader.SetBuffer(_writeDepthKernel, "Depth0[3]", d0[3]); _shader.SetBuffer(_writeDepthKernel, "MutexBuffer", m); _shader.SetTexture(_writeDepthKernel, "Result", t); _shader.SetTexture(_writeDepthKernel, "DepthTexture", depth); _shader.SetTexture(_writeDepthKernel, "AlbedoTexture", albedo); _shader.SetBuffer(_displaceKernel, "Depth", d); _shader.SetBuffer(_displaceKernel, "Depth0[0]", d0[0]); _shader.SetBuffer(_displaceKernel, "Depth0[1]", d0[1]); _shader.SetBuffer(_displaceKernel, "Depth0[2]", d0[2]); _shader.SetBuffer(_displaceKernel, "Depth0[3]", d0[3]); _shader.SetBuffer(_displaceKernel, "MutexBuffer", m); _shader.SetTexture(_displaceKernel, "Result", t); _shader.SetTexture(_displaceKernel, "DepthTexture", depth); _shader.SetTexture(_displaceKernel, "AlbedoTexture", albedo); _shader.GetKernelThreadGroupSizes(_clearKernel, out _xf, out _yf, out zf); _shader.GetKernelThreadGroupSizes(_writeDepthKernel, out _xw, out _yw, out zw); _shader.GetKernelThreadGroupSizes(_displaceKernel, out _xd, out _yd, out zd); }