12-08-2024, 09:55 AM
(12-08-2024, 07:44 AM)josemendez Wrote: Hi!
There's quite a few problems with this code:
- Your compute shader does not declare any kernels. As a result, it won't do anything. You must add this line at the top:
Code:#pragma kernel CSMain
- You're not checking whether the current thread can do any work. As a result your compute shader will access memory outside of the structured buffer and yield undefined behavior, including the chance of your game crashing. You must pass the total amount of particles to your shader and add this code at the beginning of your kernel:
Code:if(id.x >= particleCount)
return;
- You're using Time.deltaTime to set the velocity, which is expressed in m/s. As a result, the velocity will randomly change every frame. As usual when dealing with physics, you should only multiply by the time delta if adding an acceleration and in that case you should use the time delta passed to you as an argument to the solver's callback, not the frame's delta time.
- Math.CeilToInt does nothing, as you're already passing an int as argument.
Also note this code only does something if using the Compute backend, it won't work when using the Burst backend for obvious reasons (compute shaders run on the GPU, not the CPU).
kind regards,
Thanks for your quick reply!
I tried another test
1. Setting the velocity to zero in the compute shader
2. Copying data from the buffer to the array at both the beginning and the end of the process
As a result, It seems that the velocity buffer was successfully rewritten, but everything resets in the next tick
Not sure what happened.
I know setting velocity to zero doesn't make sense, just for the test purpose
Code:
#pragma kernel CSMain
RWStructuredBuffer<float4> ObiVelocityBuffer;
int ParticleCount;
[numthreads(128,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
if (id.x >= ParticleCount)
return;
ObiVelocityBuffer[id.x] = float4(0, 0, 0, 0);
}
Code:
using Obi;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class VFXFluidParticle_Obi : MonoBehaviour
{
public ObiSolver m_solver;
public ComputeShader m_computeShader;
public Vector4[] m_veclocityArray;
void Start()
{
m_solver.OnSimulationEnd += ColorFromVelocity_OnInterpolate;
}
private void ColorFromVelocity_OnInterpolate(ObiSolver solver, float simulatedTime, float substepTime)
{
if(m_veclocityArray == null || m_veclocityArray.Length != solver.positions.computeBuffer.count)
{
m_veclocityArray = new Vector4[solver.positions.computeBuffer.count];
}
if (solver.backendType == ObiSolver.BackendType.Compute)
{
solver.velocities.computeBuffer.GetData(m_veclocityArray);
Debug.Log(m_veclocityArray[100]);
m_computeShader.SetInt("ParticleCount", solver.positions.computeBuffer.count);
m_computeShader.SetBuffer(0, "ObiVelocityBuffer", solver.velocities.computeBuffer);
int threadGroups = ComputeMath.ThreadGroupCount(solver.allocParticleCount, 128);
m_computeShader.Dispatch(0, threadGroups, 1, 1);
solver.velocities.computeBuffer.GetData(m_veclocityArray);
Debug.Log(m_veclocityArray[100]);
}
}
}