SOM
- 2. DATA STRUCT
/*Neuro -----------------------------------*/
GLuint GTEX_image3D_neuro;
GLuint SHA_AP_uniform_image3D_neuro;
/*Neuro distance result -------------------*/
GLuint SSBO_vec2_neuro_distance;
/*Neuro weight update ---------------------*/
GLuint SHA_AP_uniform_float_learn;
GLuint SHA_AP_uniform_float_range;
GLuint SHA_AP_uniform_vec2_win;
GLuint SHA_AP_uniform_vec4_td0;
GLuint SHA_AP_uniform_vec4_td1;
float range = 8.0;
float learn = 1;
float win[2];
float td0[4];
float td1[4];
/*Noise -----------------------------------*/
GLuint TEX_sampler2D_noise;
GLuint SHA_AP_uniform_sampler2D_noise;
float noise[0x400000];
/*Dummy vrt -------------------------------*/
GLuint SHA_VBO_vrt;
GLuint SHA_AP_VERT_in_vec2_vrt;
float vrt[12];
/*subroutine ------------------------------*/
GLint SHA_SUB_ImageOperation;
GLuint SHA_SUB_IND_stage1;
GLuint SHA_SUB_IND_stage2;
GLuint SHA_SUB_IND_stage3;
- 3. KEY SOURCE CODE
// FUNCTION DECLARATION ===========================================================================
// Self -------------------------------------------------------------------------------------------
void
Neuro_intoShader()
{
glUniform1f(SHA_AP_uniform_float_learn, learn);
glUniform1f(SHA_AP_uniform_float_range, range);
glUniform2f(SHA_AP_uniform_vec2_win, win[0], win[1]);
glUniform4f(SHA_AP_uniform_vec4_td0, td0[0], td0[1], td0[2], td0[3]);
glUniform4f(SHA_AP_uniform_vec4_td1, td1[0], td1[1], td1[2], td1[3]);
/*Noise -----------------------------------*/
glUniform1i(SHA_AP_uniform_sampler2D_noise, 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, TEX_sampler2D_noise);
/*Dummy vrt -------------------------------*/
glBindBuffer(GL_ARRAY_BUFFER, SHA_VBO_vrt);
glVertexAttribPointer(SHA_AP_VERT_in_vec2_vrt, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(SHA_AP_VERT_in_vec2_vrt);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
//-------------------------------------------------------------------------------------------------
void
Neuro_decrease()
{
learn = learn*0.999;
range += 0.001;
}
// CoreEntry --------------------------------------------------------------------------------------
void
Neuro_create()
{
/*Neuro Init ------------------------------*/
glGenTextures(1, >EX_image3D_neuro);
glBindTexture(GL_TEXTURE_3D, GTEX_image3D_neuro);
glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA32F, 1024, 1024, 2);
glBindTexture(GL_TEXTURE_3D, 0);
glBindImageTexture(1, GTEX_image3D_neuro, 0, GL_FALSE, 1, GL_READ_WRITE, GL_RGBA32F);
/*Dummy vrt -------------------------------*/
glGenBuffers(1, &SHA_VBO_vrt);
vrt[0] = 0; vrt[1] = 0;
vrt[2] = 1024; vrt[3] = 0;
vrt[4] = 1024; vrt[5] = 1024;
vrt[6] = 0; vrt[7] = 0;
vrt[8] = 1024; vrt[9] = 1024;
vrt[10] = 0; vrt[11] = 1024;
glBindBuffer(GL_ARRAY_BUFFER, SHA_VBO_vrt);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 12, vrt, GL_STATIC_DRAW);
/*Noise -----------------------------------*/
srand(time(NULL));
for (int i = 0; i < 0x400000; ++i){
noise[i] = float(rand() % 1000) / 1000;
}
- 4. glGenTextures(1, &TEX_sampler2D_noise);
glBindTexture(GL_TEXTURE_2D, TEX_sampler2D_noise);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 1024, 1024, 0, GL_RGBA, GL_FLOAT, noise);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
/*Neuro distance result -------------------*/
glGenBuffers(1, &SSBO_vec2_neuro_distance);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO_vec2_neuro_distance);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GL_FLOAT) * 0x989680 * 2, NULL, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, SSBO_vec2_neuro_distance);
}
//-------------------------------------------------------------------------------------------------
void
Neuro_AP_assigned()
{
/*uniform AP Init -------------------------*/
SHA_AP_uniform_image3D_neuro =
glGetUniformLocation(Shader_main_program(), "neuro");
SHA_AP_uniform_sampler2D_noise =
glGetUniformLocation(Shader_main_program(), "noise");
SHA_AP_uniform_float_learn =
glGetUniformLocation(Shader_main_program(), "learn");
SHA_AP_uniform_float_range =
glGetUniformLocation(Shader_main_program(), "range");
SHA_AP_uniform_vec2_win =
glGetUniformLocation(Shader_main_program(), "win");
SHA_AP_uniform_vec4_td0 =
glGetUniformLocation(Shader_main_program(), "td0");
SHA_AP_uniform_vec4_td1 =
glGetUniformLocation(Shader_main_program(), "td1");
/*Attrib AP Init --------------------------*/
SHA_AP_VERT_in_vec2_vrt =
glGetAttribLocation(Shader_main_program(), "vrt");
/*subroutine Init -------------------------*/
SHA_SUB_ImageOperation =
glGetSubroutineUniformLocation(Shader_main_program(), GL_FRAGMENT_SHADER, "ImageOperationShader");
SHA_SUB_IND_stage1 =
glGetSubroutineIndex(Shader_main_program(), GL_FRAGMENT_SHADER, "stage1");
SHA_SUB_IND_stage2 =
glGetSubroutineIndex(Shader_main_program(), GL_FRAGMENT_SHADER, "stage2");
SHA_SUB_IND_stage3 =
glGetSubroutineIndex(Shader_main_program(), GL_FRAGMENT_SHADER, "stage3");
}
//-------------------------------------------------------------------------------------------------
void
Neuro_stage1()
{
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &SHA_SUB_IND_stage1);
Neuro_intoShader();
}
//-------------------------------------------------------------------------------------------------
void
Neuro_stage2()
{
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO_vec2_neuro_distance);
void * data = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
- 5. memset(data, -1, sizeof(GL_FLOAT) * 0x989680 * 2);
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &SHA_SUB_IND_stage2);
Neuro_intoShader();
}
//-------------------------------------------------------------------------------------------------
void
Neuro_stage3()
{
glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO_vec2_neuro_distance);
float *data = (float*)glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY);
for (int i = 0; i < 0x989680; ++i){
if (data[i * 2 + 0] > 0.0001 && data[i * 2 + 1] > 0.0001){
win[0] = data[i * 2 + 0];
win[1] = data[i * 2 + 1];
break;
}
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &SHA_SUB_IND_stage3);
Neuro_intoShader();
Neuro_decrease();
}
//-------------------------------------------------------------------------------------------------
void
Neuro_delete()
{
}
// MainEntry --------------------------------------------------------------------------------------
void
Neuro_tdInput(vmath::vec4 _td0, vmath::vec4 _td1)
{
td0[0] = _td0[0]; td0[1] = _td0[1]; td0[2] = _td0[2]; td0[3] = _td0[3];
td1[0] = _td1[0]; td1[1] = _td1[1]; td1[2] = _td1[2]; td1[3] = _td1[3];
}
// Texture Neuro ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- 6. GLSL SHADER
VERT
#version 430 core
// uniform ========================================================================================
uniform mat4 ViewMat;
uniform mat4 ProjectionMat;
// IO =============================================================================================
in vec2 vrt;
out vec2 loc;
// MAIN ===========================================================================================
void main()
{
gl_Position = ProjectionMat * (ViewMat * vec4(vrt.x, vrt.y, 0, 1));
loc = vrt.xy;
}
FRAG
#version 430 core
// uniform ========================================================================================
uniform sampler2D noise;
uniform float learn;
uniform float range;
uniform vec2 win;
uniform vec4 td0;
uniform vec4 td1;
// memory =========================================================================================
layout (binding = 1, rgba32f) uniform image3D neuro;
layout (std430, binding = 2) buffer neuro_distance{ float _dist[]; };
// IO =============================================================================================
in vec2 loc;
out vec4 farg_Color;
// subroutine =====================================================================================
subroutine void ImageOperation();
//-------------------------------------------------------------------------------------------------
subroutine (ImageOperation) void stage1()
{
imageStore(neuro, ivec3(loc.x, loc.y, 1), texture(noise, vec2(loc.x/1024, loc.y/1024)));
imageStore(neuro, ivec3(loc.x, loc.y, 0), texture(noise, vec2((1024-loc.x)/1024, (1024-loc.y)/1024)));
discard;
}
//-------------------------------------------------------------------------------------------------
subroutine (ImageOperation) void stage2()
{
vec4 neuro_res0 = imageLoad(neuro, ivec3(loc.xy, 0));
vec4 neuro_res1 = imageLoad(neuro, ivec3(loc.xy, 1));
int index = int(
1249999*distance(neuro_res0.x , td0.x) +
1249999*distance(neuro_res0.y , td0.y) +
1249999*distance(neuro_res0.z , td0.z) +
1249999*distance(neuro_res0.w , td0.w) +
1249999*distance(neuro_res1.x , td1.x) +
1249999*distance(neuro_res1.y , td1.y) +
1249999*distance(neuro_res1.z , td1.z) +
1249999*distance(neuro_res1.w , td1.w));
_dist[index*2 + 0] = loc.x;
_dist[index*2 + 1] = loc.y;
- 7. discard;
}
//-------------------------------------------------------------------------------------------------
subroutine (ImageOperation) void stage3()
{
vec2 gxy= vec2((loc.x - win.x) * (range/1024), (loc.y - win.y) * (range/1024));
float gres = exp(-(((gxy.x*gxy.x)/2)+((gxy.y*gxy.y)/2)));
vec4 gres4 = vec4(gres,gres,gres,gres);
vec4 neuro_res0 = imageLoad(neuro, ivec3(loc.xy, 0));
vec4 neuro_res1 = imageLoad(neuro, ivec3(loc.xy, 1));
vec4 res0 = neuro_res0 + gres4 * vec4(learn, learn, learn, learn) * (td0 - neuro_res0);
vec4 res1 = neuro_res1 + gres4 * vec4(learn, learn, learn, learn) * (td1 - neuro_res1);
imageStore(neuro, ivec3(loc.xy, 0), res0);
imageStore(neuro, ivec3(loc.xy, 1), res1);
}
//-------------------------------------------------------------------------------------------------
subroutine uniform ImageOperation ImageOperationShader;
// MAIN ===========================================================================================
void main()
{
ImageOperationShader();
vec4 img0 = imageLoad(neuro, ivec3(loc.x, loc.y, 0));
vec4 img1 = imageLoad(neuro, ivec3(loc.x, loc.y, 1));
vec4 SrcColor = vec4(
img0.r*img0.a*img1.a,
img0.g*img0.a*img1.a,
img0.b*img0.a*img1.a,
img0.a);
vec4 DstColor = vec4(
img1.r*(1-img0.a*img1.a),
img1.g*(1-img0.a*img1.a),
img1.b*(1-img0.a*img1.a),
img1.a);
farg_Color = SrcColor + DstColor;
}