I have an array that is 60 by 60 by 60 filled with Vector3 wind data. What I am trying to do is visualize how the wind is flowing with arrows that move around the scene. Right now there is too much processing going on and the game freezes.
Currenty I am working with a smaller array that way the game can load. I am wondering what actions I can I take to optimize this process. I was told to try and use a compute shader because every object is doing the exact same task, but the documentation on compute shaders seems pretty slim. I also don't know, can the GPU access an array of data to get wind information? Please share any tips that might help and just note how much difference you think it would make. I don't have much experience with Unity or shaders at all, but I have Google!
Thank you!
What the game does:
First 216,000 (60*60*60) objects are created and there positions are set to the index values of our wind array. ex: (1,1,1) (1,1,2) ... (60,60,60)
Every frame their positions are transformed by taking there current position + the value from the wind data array. Lets say a partial is at (5.3,2.0,6.9) the new position will be (5.3,2.0,6.9) + windData[5,2,6]
The rotation of the objects are also set to the windData to make sure the arrow is pointing the correct way.
If an object is out of the 60 by 60 by 60 cube then its position is set to its starting location
↧
Indexing an array thousands of times per frame
↧
confusing compute shader results
I have a compute shader that generates only positions for my geom shader to build cubes. The compute shader has 4 by 4 by 4 threadGroups and a group size of 1 by 1 by 1. So there are 4*4*4 positions 'calculated', but even if i set the position for all the buffer elements to (1, 0, 0) i see more than one cube (thats been rendered on each position) on the screen, means that there are strangely come in different positions?! If i hardcode a fix position in the geom (or vert) shader the problem is gone so it has to be in the buffer/compute shader.
I simplified all of the code but can't find the problem causing this odd behaviour.
Anybody got a same behaviour or can tell what's happening?
↧
↧
Strange behaviour on compute shader
I've written a small compute shader that spit out positions for my geom shader. The threadGroup size is 4by4by4 and the group size just 1. So I get 4*4*4=64 positions where my geom shader have to generate a simple cube. But I get some strange behaviours... Even if I set all the buffer elements (my positions) to (1.0, 0.0, 0.0) I see more than one cube on the screen :( if I set the position directly in the geom(vert) shader to this value I have only my single cube, so it has to be something in the compute shader right?!
Is there someone having a similar problem or someone that can give me a hint of what causes this strange behaviour?
↧
RWTexture2D in Compute Shader on Android?
**I am trying to use [this asset][1] to test out a compute shader on android**, that allows texture modification. I'm new to shaders, I could have misunderstood or not realizing some kind of limitation on mobile. I had assumed since the editor (while under android platform) worked that it would just work on android. I have tested this in the editor, on android platform, with opengl 3.1 as min graphics API, disabled the graphics emulation, and the asset works as expected. Player settings like this:
![alt text][2]
When testing it on android, the asset caused a force close on Unity 5.4, and on 5.5, it would complain about "*Kernel at index 0 is invalid*" when I ran the code the same as in the editor. If I modify the shader code by commenting out a section where it assigns to a RWTexture2D, then the error goes away, but obviously nothing is drawn to the screen.
This is a snippet of code to describe the problem area (cannot share complete code, its asset from asset store):
#pragma kernel pixelCalc
RWTexture2D textureOut;
[numthreads(32,32,1)]
void pixelCalc (uint3 id : SV_DispatchThreadID){
// some stuff happens here...
while (itn < 255 && d < 4){
// calculations and stuff...
itn++;
}
if (itn == 256) // if this line and 3 below it are commented out, runs on android!
textureOut[id.xy] = float4(0, 0, 0, 1);
else
textureOut[id.xy] = colors[itn];
}
**Hope somebody can confirm that RWTexture2D on a compute shader should work or not on android?** Has anybody had this error and found a way to make it work on android?
[1]: https://www.assetstore.unity3d.com/en/#!/content/72649
[2]: /storage/temp/83658-b8b256d68784a6cdb751453836cd2dee.png
↧
Computeshader array output
Hi Everyone,
is it possible to output for example 8 vertices in output buffer using array in C#, but not using unsafe or fixed struct?
for example, look at this code:
struct outData
{
public float sdf;
float v0, v1, v2, v3, v4, v5, v6;
float v7, v8, v9, v10, v11, v12, v13;
float v14, v15, v16, v17, v18, v19, v20;
float v21, v22, v23; };
this is not nice code, is it only solution?
Thanks, bye
↧
↧
Use of compute shader in coroutine freeze the rendering threads
I'm currently working on a learning AI based on the Double DQN algorithm.
As the code is huge and I couldn't find which part of the code is bugged, I'll first described the system. I'm working on a smaller example project to share, but I prefer present my problem first.
I developed a compute shader to manipulate a neural network on the GPU. The learning algorithm run on the CPU side, in a coroutine.
The main loop is used to managed the interface with some button and slider for visual feedback.
Everything is fine when I try the framework on small test project.
My problem appears when I work on my real project. The coroutine seems to run perfectly, I can follow the full loop on the debugger. But, despite the yield method, the interface loop never resume, and the editor freeze.
So, waiting for an example project, is there a known reason for the main loop to not resume after a "yield return null;" statement in a coroutine.
[ps: I'm not fluent in english, sorry for the possible speaking error.]
↧
Use compute shader to go RGBA to RGB
Is it possible to write a compute shader that can convert an RGBA image to a RGB image? I am new to HLSL and I cannot find a type of byte or uchar to make a structured buffer like
RWStructuredBuffer< uchar > WouldntThisBeNice;
Many functions in OpenCV work on RGB images but not RGBA. I am already successful in flipping my RGBA images up/down before sending them to OpenCV and figured it would nice to avoid an OpenCV call to convert the image on the CPU.
↧
Compute Shader compile error from Texture3D.Sample()
I'm trying to sample a 3D noise texture that I generate elsewhere and pass to my ComputeShader. However, when compiling the following, all I get is "Shader error in 'DensityGenerator.compute': cannot map expression to cs_5_0 instruction set at DensityGenerator.compute(14) (on d3d11)".
I really haven't got a clue where to start with this. It [looks right][1] and the only way to get it to compile is to comment out line 14 (noiseVol.Sample(), specifically).
What obvious bug have I missed?
#pragma kernel Density
Texture3D noiseVol;
SamplerState samplerNoiseVol;
RWStructuredBuffer voxels;
[numthreads(32,32,1)]
void Density (uint3 threadId : SV_DispatchThreadID, uint3 groupId : SV_GroupID)
{
int size = 32;
int3 voxPos = threadId; // Just rename this for the sake of clarity
float density = 0;//-voxPos.y;
density += noiseVol.Sample(samplerNoiseVol, voxPos, 0).z;
voxels[voxPos.x + voxPos.y*size + voxPos.z*size*size] = density;
}
[1]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509695(v=vs.85).aspx
↧
Compute shader FindKernel() fails with unity exception
So the shader code is here: http://pastebin.com/Tbgu7UvH
And the script is here: http://pastebin.com/r19BV1Rh
If I try to find the only kernel that I have, I get this:
Kernel 'CSMain' not found
UnityEngine.ComputeShader:FindKernel(String)
Controller:Start() (at Assets/Controller.cs:10)
and
UnityException: FindKernel failed
Controller.Start () (at Assets/Controller.cs:10)
If I try to Dispatch directly by index such as this:
shader.Dispatch(0, 1, 1, 1);
Then I receive this error:
Kernel index (0) out of range
UnityEngine.ComputeShader:Dispatch(Int32, Int32, Int32, Int32)
↧
↧
How (Or Why) to use Consume Buffers safely on arbitrary data lengths
Hey guys, I wanted to use compute shaders to write object position into a texture, then manipulate the texture and sometimes read a value back from the texture.
To avoid too much stalling, I wanted to write positions into the texture every 100ms (for example).
So every update write position into a list, then send that list as a consume buffer on that 100ms tick.
But I do not know how many samples I will be sending per time, which is why I thought consume buffers were the solution, but now I learned they are rather "dumb".
But if I consume more elements than it contains, I start getting into trouble.
So how do I do this? Do I have to have a 1x1x1 sized thread group and just dispatch only enough groups for the list length? Or is there a smarter way?
Or maybe I should use a different approach altogether?
↧
Calling Graphics.DrawProcedural multiple times for chunked procedural terrain
In my project, I'm creating chunks of 3D procedural terrain (voxels) using a series of compute shaders and then passing the vertex data of each chunk from a ComputeBuffer to the Graphics.DrawProcedural method to be rendered in a surface shader.
void OnPostRender()
{
foreach(GPUMeshData gMeshData in gpuMeshData) {
m_drawBuffer.SetBuffer("_Buffer", gMeshData._Vert);
m_drawBuffer.SetBuffer("_ColorBuffer", gMeshData._Color);
m_drawBuffer.SetPass(0);
Graphics.DrawProcedural(MeshTopology.Triangles, SIZE);
}
}
...
...
public struct GPUMeshData {
public int meshNum;
public ComputeBuffer _Vert;
public ComputeBuffer _Color;
public GPUMeshData(int meshNumber, ComputeBuffer vert, ComputeBuffer color) {
meshNum = meshNumber;
_Vert = vert;
_Color = color;
}
}
It works OK, but the problem is that it appears the buffer data seems to get jumbled up intermittently. Newer buffer vertex data is somehow getting merged with older vertex data that was in previous frames but should no longer be present in my GPUMeshData list. As a result, old meshes at different LODs are overlapping my newly rendered chunks. It starts to get ugly quick.
![alt text][1]
Through debugging, I know for certain that I'm not making calls to re-render the "bad" chunks/buffers after I remove them, yet somehow the old data gets mixed into one of my new buffers. When I remove objects from the GPUMeshData list, I am doing a Release() on the ComputeBuffers as well:
public void removeChunkGPU(int meshNum) {
if(gpuMeshData.Exists(x => x.meshNum == meshNum)) {
GPUMeshData gMeshData = gpuMeshData.Find(x => x.meshNum == meshNum);
if(gMeshData._Vert != null) gMeshData._Vert.Release();
if(gMeshData._Color != null) gMeshData._Color.Release();
gpuMeshData.RemoveAll(x => x.meshNum == meshNum);
}
}
I'm just trying to find out... am I doing a big "no-no" here by making multiple DrawProcedural calls for different buffers per frame? I can't understand how the older data is getting "stuck" in the Graphics pipeline. I also found a very similar question asked here:
https://forum.unity3d.com/threads/compute-shaders-and-drawprocedural-drawproceduralindirect.413196/
In my case though, I only need to render a maximum of ~350 chunks in the worst case. But as that poster mentioned, merging all chunks into a single buffer just seems counter-intuitive to me.
Any thoughts are appreciated!
**EDIT: ** So I discovered something that seems to fix the issue, but I'm not sure why exactly. Essentially if I pre-initialize all the values in my mesh ComputeBuffers using a **SetData()** call before generating data in them, the problem no longer occurs.
public void generateChunkGPU(OctreeNode node) {
...
...
gpuMeshData.Add(new GPUMeshData(meshNum,
new ComputeBuffer(SIZE, sizeof(float)*7),
new ComputeBuffer(SIZE, sizeof(float)*4)));
GPUMeshData gMeshData = gpuMeshData[gpuMeshData.Count-1];
// Initialize all verts to -1
float[] val = new float[SIZE*7];
for(int k = 0; k < SIZE*7; k++)
val[k] = -1.0f;
gMeshData._Vert.SetData(val);
...
perlinNoise.SetFloat("_ChunkWidth", chunkWidth);
...
perlinNoise.SetBuffer(0, "_Result", noiseBuffer);
perlinNoise.Dispatch(0, 4, 4, 4);
marchingCubes.SetFloat("_ChunkWidth", chunkWidth);
...
marchingCubes.SetBuffer(0, "_Voxels", noiseBuffer);
marchingCubes.SetBuffer(0, "_Buffer", gMeshData._Vert);
marchingCubes.Dispatch(0, 4, 4, 4);
}
![alt text][2]
Obviously though **SetData()** is very expensive and stalls on the CPU, so I'd like to avoid using it. But this seems to suggest that whenever I create a new ComputeBuffer, there is some "left over" data sitting in memory where it's allocating to create the new buffer.
I also tried writing another ComputeShader to just "clear" the buffer in my remove function:
public void removeChunkGPU(int meshNum) {
if(gpuMeshData.Exists(x => x.meshNum == meshNum)) {
GPUMeshData gMeshData = gpuMeshData.Find(x => x.meshNum == meshNum);
// Clear buffer before releasing
initializeMeshBuffer.SetInt("SIZE", SIZE);
initializeMeshBuffer.SetBuffer(0, "_Buffer", gMeshData._Vert);
initializeMeshBuffer.Dispatch(0, 0, 0, 1);
if(gMeshData._Vert != null) gMeshData._Vert.Release();
if(gMeshData._Color != null) gMeshData._Color.Release();
gpuMeshData.RemoveAll(x => x.meshNum == meshNum);
}
}
But that didn't seem to help at all.. Here's the shader code for it anyway:
#pragma kernel CSMain
struct Vert
{
float4 position;
float3 normal;
};
int SIZE;
RWStructuredBuffer _Buffer;
[numthreads(1,1,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
Vert vert;
vert.position = float4(-1.0, -1.0, -1.0, -1.0);
vert.normal = float3(-1.0, -1.0, -1.0);
for(int i = 0; i < SIZE; i++)
_Buffer[i] = vert;
}
Anybody have any thoughts on how I can avoid using **SetData()** and truly get a clear ComputeBuffer each time I create a new one?
[1]: /storage/temp/93386-overlapping-meshes-issue.jpg
[2]: /storage/temp/93958-overlapping-meshes-no-issue.jpg
↧
Compute shader on UWP
Hi everyone,
I have some difficulties on running a very simple test compute shader on UWP.
As a base I have a very simple shader and script running just fine on a Quad in my Unity editor (5.6.0f3).
But it simply doesn't do anything when the application is built for UWP, even with the compute shader support confirmed in the application or a continuous dispatch in the Update function.
Here's the shader. #pragma kernel CSMain //Result texture. RWTexture2D result;
[numthreads(10,10,1)]
void CSMain( uint3 id : SV_DispatchThreadID ){
//Color a 1440x900 texture with the pixel coordinates.
float R = (float)id.x / 1440.0;
float G = (float)id.y / 900.0;
result[id.xy] = float4( R, G, 1.0, 1.0 );
}
And the following script handling the shader.
public class ComputeShaderInstance : MonoBehaviour {
protected ComputeShader computeShader;
protected int kernelHandle;
protected Renderer renderer;
protected RenderTexture renderTexture;
public int pixelByteSize = 16;
public int textureWidth = 1440;
public int textureHeight = 900;
// Use this for initialization
void Start () {
if( SystemInfo.supportsComputeShaders ) {
//Initializing object holding the compute shader.
renderTexture = new RenderTexture(textureWidth, textureHeight, pixelByteSize);
renderTexture.enableRandomWrite = true;
renderTexture.Create();
renderer = GetComponent();
//Recovering shader and kernel entry point.
computeShader = (ComputeShader)Resources.Load("Shaders/ComputeShader");
kernelHandle = computeShader.FindKernel("CSMain");
//Configuring compute shader.
computeShader.SetTexture(kernelHandle, "result", renderTexture);
//Launching compute shader.
computeShader.Dispatch(kernelHandle, textureWidth / 10, textureHeight / 10, 1);
//Put texture back to the renderer.
renderer.material.SetTexture("_MainTex", renderTexture);
}
}
// Update is called once per frame
void Update () { }
}
Am I missing some windows specificities ?
Thanks in advance :)
As a base I have a very simple shader and script running just fine on a Quad in my Unity editor (5.6.0f3).
But it simply doesn't do anything when the application is built for UWP, even with the compute shader support confirmed in the application or a continuous dispatch in the Update function.
Here's the shader. #pragma kernel CSMain //Result texture. RWTexture2D
Thanks in advance :)
↧
How to build for Mac to make compute shaders work?
The problem is that even though 5.6 supposed to compile compute shaders for Metal, it didn't work for me.
I created a simple project: compute shader is used to render a fractal. Then I just made Mac OS build.
And Mac users report the project runs, but the fractal is not being built. Looks like compute shader doesn't work. What could be wrong? Are there some special configuration things I Must take care of to make it work? Or maybe it's because I build on Windows editor, and that is the problem? Any tips would be appreciated.
If anyone's curious, here's the build: https://drive.google.com/open?id=0B22OLebalqvJQzBCUVFkLUtmYjA
If it works, it should look like this: http://i.imgur.com/YqwA1Lz.png
↧
↧
Implementation of GPU Flocking?
Hi,
I'm new to Unity and Compute Shaders. I'm trying to implement GPU Flocking using compute shaders in Unity to show that GPU Computing is faster than the CPU . I've managed to write a script and implement the flocking effect in both CPU and GPU. However, the GPU Flocking FPS tends to be slower than the CPU Flocking's FPS. The method I've used is to perform all calculations for each prefab in a Compute Shader and return the value. I've implemented "Ping Pong" effect but the CPU still seems to be faster? Is there any other method I can use to show the GPU is faster?
Thanks in Advance
↧
SystemInfo.supportsComputeShaders always false on Android
Hello,
I'm trying to get compute shaders to work on Android but SystemInfo.supportsComputeShaders always return false when my target platform is Android. When I select Windows as my target platform, it works well. To be more precise, I'm testing in unity editor with the Android selected at my current platform, not on an actual android device.
Here are the settings I'm currently using. I've also tried other settings based on information I've seen online.
I am currently using Unity 5.6.0 and the android API target is 5.0.
![alt text][1]
Is there a setting I'm missing that could cause this ?
Thank you.
[1]: /storage/temp/97071-computeshadersettings.png
↧
Upload list of textures to the GPU to be used with compute shaders ?
Hi,
i need to collect ( have no problem with this ) and upload all the textures used in a scene to the GPU memory.
ComputeShader.SetTexture() can set a single texture only.
Is there any way of loading multiple textures, may be using a buffer ?
↧
How does one do compute shaders(with particles)?
So, this is my first attempt at compute shaders and I'm quite lost... ANY help or referral is higly appreciated.
----------
My goal is to achieve an effect that I've only been able to identify as "plexus" or "plexus particles".
They look like this;
![alt text][1]
... Or this;
![alt text][2]
But nevermind all that, my approach is to get the positions of all the particles in the particle system, then I'll pass that array to my compute shader that can compute the distance between them, and then check which particles are close enough together to create a line between them.
Most important is probably to improve my understanding of compute shader syntax and workflow. Any example code would be nice.
-----
From here on out it's more of a "nice to have" deal.
I'd like to define a threshold for how many lines or connections any particles can have as well. If possible I'd like it to output a position and scale for a billboard particle to function as the line between two particles.
By the way, i know there are easier and probably better ways to do this, but I'd like to at least use compute shaders, as learning them is the goal of the project.
Again, thanks for any type of help!
[1]: https://i.ytimg.com/vi/G7HksQNa9a0/maxresdefault.jpg
[2]: http://aescripts.com/images/news/plexus3/noise.jpg
↧
↧
Compute shaders not working in editor but working on device
I have started learning compute shaders. And I found a really good project on github (https://github.com/antoinefournier/XParticle) that would help me learn and experiment with compute shaders. As I opened the project it worked just fine, but when switching platforms to android I just got a bunch of errors saying compute shaders aren't supported on this platform. Then I proceeded to check the player settings and setting the correct graphics api. (http://imgur.com/a/5ZSET). I also set the minimum api level to 5.0 (not sure if that's required, but did that just to make sure). Even after doing all of that the same error was shown when playing the project. So I almost gave up and said to myself why not try to run it on a device? So I built the project with those settings and ran it on a lg g4 running lineage os 14.1 and it works as expected. It even runs well without many slowdowns.
So what am I missing here?
also: I am running unity 2017.1.0f3
↧
How to write to a RenderTexture as a cubemap
So after a lot of digging I found RenderTexture.isCubeMap. Then I found that it was obsolete.
Then I found RenderTexture.dimension and, by extension, UnityEngine.Rendering.TextureDimension.Cube which seems to be what I want.
But I'm not sure how this is used. How are the six faces represented internally when the rendertexture is created this way? I'm currently writing a compute shader that writes to a render texture, and I'm not sure how I should be writing my output that writes to the cubemap.
So what do I do with this in the compute shader...
RWTexture2D o_result;
//...
o_result[tex.xy] = float4(outputColor.x, outputColor.y, outputColor.z, 1);
As you can see, this is for a 2d texture, is there anything special I need to do to get it working with a cubemap? My first instinct is something like:
RWTexture3D o_result;
//...
// Where tex.xyz flies on the outside of the cube? How do I address each side's pixels...
o_result[tex.xyz] = float4(outputColor.x, outputColor.y, outputColor.z, 1);
If someone has visibility on cubemap rendertextures but not compute shaders, that's fine. I'm just very unsure as to how this all lays out in addressable memory and using RenderTexture.dimension isn't very well documented.
↧
How to disable Warnings in Compute Shaders ?
Hi,
We are using Compute Shaders in our project and doing quite a lot of math operations. A warning is always generated :
***"Shader warning in 'VertexGenerator.compute': integer divides may be much slower, try using uints if possible"***
We need to use integers and not uints. Is there a way to disable these kind of warnings ? (we have 74 of them each time we change the shader so it's a bit annoying).
Have a nice day!
↧