2016-06-20 6 views
0

Я в OpenGL 4.5 (OpenGL.net в C#, но код очень похож на обычный OpenGL-код), и я пытаюсь использовать вычислительный шейдер. Вот то, что я до сих пор:Почему мой вычислительный шейдер ничего не делает?

// (Compile and link stuff, this part I know works) 

// Use the compute shader 
Gl.UseProgram(program); 

// Create the texture the compute shader will output to 
int textureWidth = 512, textureHeight = 512; 
uint[] texturesMaking = new uint[1]; 
Gl.GenTextures(texturesMaking); 
uint texture = texturesMaking[0]; 
Gl.ActiveTexture(Gl.TEXTURE0); 
Gl.BindTexture(TextureTarget.Texture2d, texture); 
Gl.TextureParameter(Gl.TEXTURE_2D, Gl.TEXTURE_MAG_FILTER, Gl.NEAREST); 
Gl.TextureParameter(Gl.TEXTURE_2D, Gl.TEXTURE_MIN_FILTER, Gl.NEAREST); 
Gl.TexImage2D(TextureTarget.Texture2d, 0, Gl.RGBA32F, textureWidth, textureHeight, 0, PixelFormat.Rgba, PixelType.Float, IntPtr.Zero); 

// Get the shader output variable and set it 
int location = Gl.GetUniformLocation(program, "destTex"); 
Gl.Uniform1(location, texture); 
Gl.BindImageTexture(0, texture, 0, false, 0, Gl.READ_WRITE, Gl.RGBA32F); 

// Send off the compute shader to do work, with one group per pixel 
// (I know this is far less than optimal, it was just a debugging thing) 
Gl.DispatchCompute((uint)textureWidth, (uint)textureHeight, 1); 

// Wait for compute shader to finish 
Gl.MemoryBarrier(Gl.SHADER_IMAGE_ACCESS_BARRIER_BIT); 

// Looking at the texture, it is black 

А вот мой Compute Shader:

#version 450 
layout(local_size_x = 1, local_size_y = 1) in; 
layout(rgba32f) uniform image2D destTex; 

void main() { 
    imageStore (destTex, ivec2(gl_GlobalInvocationID.xy), vec4(1.0, 0.0, 1.0, 1.0)); 
} 

Если я понимаю правильно, моя текстура должна быть фиолетовый/розовый цвет после прогонов шейдера, но вместо того, чтобы он просто черный, и распечатка нескольких цветов пикселей показывает, что все значения равны нулю. Что я делаю не так?

+0

Как вы смотрите на текстуру? У вас есть барьер памяти, который соответствует типу «поиска», который вы делаете? –

+0

А, это может быть проблемой. Я использую 'Gl.GetTexImage (TextureTarget.Texture2d, 0, PixelFormat.Rgba, PixelType.Float, pixelArrayPointer);' (для указателя на 'float []' размера 'textureWidth * textureHeight * 4'). Затем, когда у меня есть данные с плавающей точкой, я сохраняю его на изображении, а затем открываю это изображение, чтобы увидеть содержимое. – Phylliida

+0

Для тех, кого это интересует, я поместил свой полученный код [здесь] (http://answers.unity3d.com/answers/1205676/view.html) – Phylliida

ответ

3

Проблема заключается в том, как вы говорите шейдеру, какую текстуру использовать. Значение, установленное

int location = Gl.GetUniformLocation(program, "destTex"); 
Gl.Uniform1(location, texture); 

должен быть текстура изображения блока (первый параметр команды Gl.BindImageTexture), а не сама текстурой. Поскольку вы используете блок текстуры изображения 0, вам также необходимо передать 0 в форму:

GLuint unit = 0; 
int location = Gl.GetUniformLocation(program, "destTex"); 
Gl.Uniform1(location, unit); 
Gl.BindImageTexture(unit, texture, 0, false, 0, Gl.READ_WRITE, Gl.RGBA32F); 
+1

Альтернативно, просто установите равномерное местоположение из шейдера. Он использует CS, поэтому у него должен быть GL 4.30, поэтому он может это сделать. –

+0

* Она. И благодарю вас!! Это работает! – Phylliida