我的glsl程序遇到了一些问题,尝试在后期渲染中渲染对象。为了它的工作,我需要将一个2D数组的结构传递给我的片段着色器,我在我的顶点着色器中使用其他数组。我正在使用Libgdx。我如何欺骗glsl使它工作?
我试图给阵列一个固定的大小,但它对于glsl来说太大了,对我来说太小了......
//顶点着色器
#version 150
#extension GL_ARB_arrays_of_arrays: require
struct Info{
bool joints[8];
vec2 jpos[8];
vec4 col;
vec2 uv;
vec2 pos;
float flooded;
bool exists;
};
in vec4 a_position;
in vec4 a_color;
in vec2 a_texCoord0;
uniform mat4 u_projTrans;
uniform vec2 u_pos;
uniform vec2 u_size;
uniform float u_zoom;
uniform ivec2 sSize;
uniform float exists[];
uniform vec2 positions[];
uniform float flooded[];
uniform float colors[];
uniform vec2 uvs[];
uniform float hozj[];
uniform float verj[];
uniform float nej[];
uniform float nwj[];
uniform int Mode;
out vec2 vTexCoord0;
out vec2 vWldCoord0;
out Info infos[][];
float getverj(in int x, in int y){
if (x>=0 && y>=0 && x<sSize.x&&y<sSize.y-1){
return verj[x+y*(sSize.x)];
}else{
return 0.;
}
}
float gethozj(in int x, in int y){
if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y){
return verj[x+y*(sSize.x-1)];
}else{
return 0.;
}
}
float getnej(in int x, in int y){
if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y-1){
return verj[x+y*(sSize.x-1)];
}else{
return 0.;
}
}
float getnwj(in int x, in int y){
if (x>=0 && y>=0 && x<sSize.x-1&&y<sSize.y-1){
return verj[x+y*(sSize.x-1)];
}else{
return 0.;
}
}
float getSJ(in int i,in int x,in int y){
if (i == 0){
return getverj(x,y);
}else if (i == 1){
return getnej(x,y);
}else if (i == 2){
return gethozj(x,y);
}else if (i == 3){
return getnwj(x,y-1);
}else if (i == 4){
return getverj(x,y-1);
}else if (i == 5){
return getnej(x-1,y-1);
}else if (i == 6){
return gethozj(x-1,y);
}else if (i == 7){
return getnwj(x-1,y+1);
}else{
return -1.;
}
}
ivec2 getRP(in int i,in ivec2 pos){
if (i == 0){
return pos+ivec2(0,1);
}else if (i == 1){
return pos+ivec2(1,1);
}else if (i == 2){
return pos+ivec2(1,0);
}else if (i == 3){
return pos+ivec2(1,-1);
}else if (i == 4){
return pos+ivec2(0,-1);
}else if (i == 5){
return pos+ivec2(-1,-1);
}else if (i == 6){
return pos+ivec2(-1,0);
}else if (i == 7){
return pos+ivec2(-1,1);
}else{
return ivec2(-1);
}
}
bool isInScreen(in vec2 pos){
bool inside = true;
vec2 size = u_size*u_zoom;
vec2 bigger = u_pos+size/2.;
vec2 smaller = u_pos-size/2.;
if (bigger.x<pos.x||bigger.y<pos.y||smaller.x>pos.x||smaller.y>pos.y){
inside = false;
}
return inside;
}
vec4 pack_depth(const in float depth)
{
const vec4 bit_shift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
const vec4 bit_mask = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
vec4 res = fract(depth * bit_shift);
res -= res.xxyz * bit_mask;
return res;
}
void ProcessArrays(void){
int i = 0;
for (int x = 0; x<sSize.x; x++){
for (int y = 0; y<sSize.y; y++){
float e = exists[x+y*sSize.x];
if (e == 1. && !isInScreen(positions[i])){
e = 0.;
}
if (e == 0.){
infos[x][y].exists = false;
}else{
infos[x][y].exists = true;
infos[x][y].col = pack_depth(colors[i]);
infos[x][y].pos = positions[i];
infos[x][y].uv = uvs[i];
infos[x][y].flooded = flooded[i];
i++;
}
}
}
for (int x = 0; x<sSize.x; x++){
for (int y = 0; y<sSize.y; y++){
if (infos[x][y].exists){
for (int i = 0;i<8;i++){
if (getSJ(i,x,y) == 1.){
ivec2 pos = getRP(i,ivec2(x,y));
infos[x][y].joints[i] = true;
infos[x][y].jpos[i] = pos;
}else{
infos[x][y].joints[i] = false;
}
}
}
}
}
}
void main() {
vTexCoord0 = a_texCoord0;
vWldCoord0 = (a_position.xy-(u_size*0.5))*u_zoom-u_pos;
gl_Position = u_projTrans * a_position;
ProcessArrays();
}
//片段着色器
#version 150
#extension GL_ARB_arrays_of_arrays: require
struct Info{
bool joints[8];
vec2 jpos[8];
vec4 col;
vec2 uv;
vec2 pos;
float flooded;
bool exists;
};
in vec2 vTexCoord0;
in vec2 vWldCoord0;
uniform sampler2D u_texture;
uniform vec2 u_pos;
uniform vec2 u_size;
uniform float u_zoom;
uniform ivec2 sSize;
uniform int Mode;
in Info infos[][];
float minimum_distance( in vec2 a, in vec2 b, in vec2 p ){
vec2 pa = p - a, ba = b - a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h );
}
float DrawLine(in vec2 a, in vec2 b, in float t, in vec2 co){
float dst = minimum_distance(a,b,co);
return 1.0-smoothstep( t, t+1.0, dst );
}
vec3 toBari(in vec2 a,in vec2 b,in vec2 c,in vec2 p){
vec3 coord = vec3(0);
float det = (b.y-c.y)*(a.x-c.x)+(c.x-b.x)*(a.y-c.y);
coord.x = ((b.y-c.y)*(p.x-c.x)+(c.x-b.x)*(p.y-c.y))/det;
coord.y = ((c.y-a.y)*(p.x-c.x)+(a.x-c.x)*(p.y-c.y))/det;
coord.z = 1.-coord.x-coord.y;
return coord;
}
vec2 toCartesian(in vec2 a,in vec2 b,in vec2 c,in vec3 p){
return a*p.x+b*p.y+c*p.z;
}
float DrawQuad(in vec2 a, in vec2 b,in vec2 c,in vec2 d,in float t,in vec2 co){
float f = 0.;
f= max(f,DrawLine(a,b,t,co));
f= max(f,DrawLine(a,c,t,co));
f= max(f,DrawLine(a,d,t,co));
f= max(f,DrawLine(b,c,t,co));
f= max(f,DrawLine(b,d,t,co));
f= max(f,DrawLine(c,d,t,co));
return f;
}
vec4 Iterate(){
float mask = 0.;
vec4 col = vec4(0);
float sdst = 16000.;
for (int x = 0; x<sSize.x; x++){
for (int y = 0; y<sSize.y; y++){
if (infos[x][y].exists == true){
bool bound;
for (int i = 0;i<8;i++){
if (infos[x][y].joints[i] == true){
bound = true;
mask = max(mask,DrawLine(infos[x][y].pos,infos[x][y].jpos[i],u_zoom,vWldCoord0));
}
}
if (bound == false){
mask = max(mask,DrawLine(infos[x][y].pos,infos[x][y].pos,u_zoom,vWldCoord0));
}
float f = distance(infos[x][y].pos,vWldCoord0);
if (f < sdst){
sdst = f;
col = infos[x][y].col;
}
}
}
}
return col*mask;
}
void main(void) {
gl_FragColor = Iterate();
}
我想指出,如果我给阵列一个固定的大小,我的计算机使用50%的CPU,程序没有响应。否则它会出错并制作一个黑屏...它会产生编译错误,需要固定的数组大小。在之前的情况下,它什么也没做,似乎没有编译。