Jump to content
Unity Insider Forum

ComputeShader.SetFloats() in float3-Array


Mr 3d

Recommended Posts

Hi,

 

ich spiele gerade mal wieder etwas mit ComputeShadern und bin auf ein mir nicht erklärbares Verhalten gestoßen...

 

Ich habe ein float-Array mit 9 Elementen.

In meinem ComputeShader habe ich ein ein Array aus drei float3`s

( da es anscheinend keinen direkten Weg gibt eine 3x3 Matrix zu übertragen .. )

Wenn ich jetzt per "SetFloats();" versuche mein Array an den ComputeShader zu übergeben, kommt im ComputeShader dann das an:

 

(x1, y1, z1 )

(y2, z2, x3 )

(z3, 0 , 0 )

 

anstatt:

 

(x1,y1,z1)

(x2,y2,z2)

(x3,y3,z3)

 

Also so, wie wenn immer alle drei Elemente ein Element übersprungen wird.

 

Nur warum? ^.^

 

Wenn ich mein Array statt 9 Elementen 12 Elemente gebe und dafür nach jedem 3. Element ( das ja ahnscheinend übersprungen wird ) ein Element "leer" lasse, dann kommen im ComputeShader die "richtigen" Werte an.

 

Aber ich finde es nicht so schön jeden Frame 12 "unnötige" bytes zu versenden.. also weiß jemand was ich falsch mache? :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

okay ^ .. ich bin wirklich noch ziemlich neu auf dem Gebiet ;)

 

also, im Grunde der Code auf C# Seite ist:

 

void Update(){
myComputeShader.SetFloats("rotation", generateRotationMatrix(transform.rotation));
}
//Quaternion to Matrix
private float[] generateRotationMatrix(Quaternion rot)
{
float[] matrix = new float[9];
matrix[0] = 1 - 2 * rot.y * rot.y - 2 * rot.z * rot.z;
matrix[1] = 2 * rot.x * rot.y - 2 * rot.z * rot.w;
matrix[2] = 2 * rot.x * rot.z + 2 * rot.y * rot.w;
matrix[3] = 2 * rot.x * rot.y + 2 * rot.z * rot.w;
matrix[4] = 1 - 2 * rot.x * rot.x - 2 * rot.z * rot.z;
matrix[5] = 2 * rot.y * rot.z - 2 * rot.x * rot.w;
matrix[6] = 2 * rot.x * rot.z - 2 * rot.y * rot.w;
matrix[7] = 2 * rot.y * rot.w + 2 * rot.x * rot.w;
matrix[8] = 1 - 2 * rot.x * rot.x - 2 * rot.y * rot.y;
return matrix;
}

 

und auf Shader Seite gibt es einfach:

 

float3 rotation[3];

 

Ansonsten hat bisher auch alles ohne Probleme geklappt also sämmtliche ComputeBuffer oder Vectoren zu übertragen..

nur eben mit SetFloats scheint es Probleme zu haben..

 

Welchen Buffertyp benutzt du im Shader?

 

Ehrlich gesagt hab ich keine Ahnung ^^ ich hab nur gesehen dass man bei ComputeBuffern einen ComputeBufferTyp angeben kann aber nicht bei SetFloats()..

 

Oder soll ich vtl doch einfach einen ComputeBuffer dafür benutzen? das mit SetFloats kam mir einfach irgendwie schöner vor..

 

btw..

ich schiebe im Megabyte-Bereich Daten in meine Shader.

 

Ich habe gehört man soll so wenig traffic zwischen vram und ram erzeugen wie möglich.. sind Megabyte noch ok oder ist das dann schon zu viel?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ah gut - ich habe einfach einen ComputeBuffer und benutze SetData.

Nur so am Rand: Auf meinem Arbeitsrechner geht das mit den vielen Daten in gut unter einer Millisekunde.

 

Warum das mit SetFloats jetzt nicht geht, kann ich leider nicht sagen. Auf beiden Seiten hast du 9 32bit-Floats, sieht also gut aus.

 

Da ich auch nicht über Vor- und Nachteile von float-Arrays und ComputeBuffern Bescheid weiß, würde ich sagen: Probier's einfach mal mit einem ComputeBuffer aus.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok danke^

 

also gerade läuft es ganz gut indem ich, wie oben schon beschrieben, einfach drei float4 versende und die w-Koordinate ignoriere..

Wenn das Probleme macht, oder ich noch Lust und Zeit hab, stell ichs eben auf ComputeBuffer um. Dürfte ja theoretisch kein Problem sein ( theoretisch ^ )

 

 

Aber vtl kannst Du ( oder natürlich auch wer anders ;) ) mir noch eine Frage beantworten die mir gerade noch gekommen ist..

Wenn man einen ComputeBuffer setzt, dann muss man eine art "Zielkernel" angeben.

Und von anderen Kerneln lässt sich dann auf diesen Buffer nicht direkt zugreifen, wie ich festgestellt habe,

außer man schreibt ".SetBuffer" auch nochmal für den anderen Kernel.

Nur wird dann jedes mal wieder der Buffer von Ram in vRam kopiert, oder wird dann nur ein Pointer an den neuen Kernel übergeben, der zeigt wo der Buffer im vRam schon liegt?

 

( ich bin mir nicht 100% sicher ob das so richtig formuliert ist.. )

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...