Autor Wątek: Woda, odbicia  (Przeczytany 1424 razy)

Offline Invincible

  • Użytkownik
    • Invincible

# Grudzień 01, 2012, 23:19:08
Cóż, nigdy nie byłem mistrzem w programowaniu grafiki, ale zachciało mi się ładnej wody. Siedzę nad tym drugi dzień i wciąż nie ogarniam ;) Może ktoś tutaj jakoś mnie poratuje.

Renderuje sobie do tekstury wszystko to co ma się odbijać, macierz mnożę przez vec4(1.0f ,-1.0f, 1.0f, 1.0f) coby było tak jak być powinno ;) Tutaj chyba wszystko mam dobrze.

Nakładam tą teksturę na wielki quad wody i tutaj mam problem którego nie potrafię obejść. Czego bym nie robił to nie potrafię tak manipulować texcoordami tej mapy odbić tak żeby na przykład odbicie drzewka trzymało się pod tym drzewkiem.


Wynik najbliższy zamierzonemu uzyskałem budując macierz tekstury, w Vertex Programie z nie robię texcoordy ( OUT.texCoord = mul( INposition, texMatrix ); ), a we Fragment Programie na ich podstawie liczę kolor wynikowy: color = tex2Dproj(reflectMap, INtexCoord);

Ale odbicia i tak rozłażą się z odbijanymi obiektami.


Macierz tekstury to po prostu macierz projekcji + macierz kamery, z zakresem przekształconym z [-1,1] do [0,1] w ten sposób:
mat_texMatrix=glm::scale( mat_texMatrix, glm::vec3(0.5f, 0.5f, 0.5f)  );
mat_texMatrix=glm::translate( mat_texMatrix, glm::vec3(0.5f, 0.5f, 0.5f)  );



Nie wiem czy od początku źle kombinuje, czy może źle wyznaczam macierz? A może po prostu ktoś przez to przebrną i ma lepsze rozwiązanie którym chętnie się podzieli ;) Jakby nie było byłbym bardzo wdzięczny za pomoc ;)

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Avaj

  • Użytkownik

# Grudzień 01, 2012, 23:28:21
Na pewno dobrą kolejność tych scale i translate masz? Może wysyłaj jako macierz identity na razie a te przekształcenie zrób już w samym shaderze?


Offline Invincible

  • Użytkownik
    • Invincible

# Grudzień 01, 2012, 23:33:43
Sprawdzałem i kolejność składania i przerzucanie tego do shadera.

Właściwie to od rana to co jakiś czas sprawdzam jak kończą mi się pomysły :D

Offline Dab

  • Redaktor
    • blog

# Grudzień 01, 2012, 23:41:17
Woda na wysokości y=0? Przy renderowaniu nie wystarczy zmienić kierunku, trzeba jeszcze przesunąć kamerę. Zrób sobie klawisz do przełączania między normalnym widokiem a odbitym, będziesz wiedział czy błąd jest w renderowaniu czy mapowaniu. Jak to nie pomoże to zapodaj screeny.

Offline Invincible

  • Użytkownik
    • Invincible

# Grudzień 02, 2012, 12:11:49
Yep, y=0.

Więc tak:

Odbite przez Vec3(1.0f ,-1.0f, 1.0f) i z kamerą przesuniętą przez y*=-1;




Odbite przez Vec3(1.0f ,-1.0f, 1.0f) i renderowane z pozycji zwykłej kamery:




Wszystko tak jak przy normalnym renderowaniu sceny:



 


Do tego w kwadraciku w lewym dolnym rogu macie to jak w każdym przypadku wygląda sama zrenderowana tekstura.

Próbuje rzutować ją tak jak napisałem:
OUT.texCoord = mul( IN.position, texMatrix );  w VS
float4 texture = tex2Dproj(tex1, texCoord); w PS

texMatrix to ta sama macierz przez którą lecą wierzchołki (projekcja * kamera * przesunięcie) z dodatkowo zmienionym zakresem z [-1; 1] do [0, 1].
« Ostatnia zmiana: Grudzień 02, 2012, 12:13:48 wysłana przez Invincible »

Offline .:NOXY:.

  • Użytkownik
    • Profil

# Grudzień 03, 2012, 20:51:11
Jak noxacz robil wode jak byl mlody i gupi:

static float depth = -4;

WaterFBO->Begin();
                {

                    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                    glMatrixMode(GL_PROJECTION);
                    glLoadIdentity();
                    gluPerspective(MConfig.FOV, (float)MConfig.S_WIDTH/MConfig.S_HEIGHT, MConfig.NEARPLANE, MConfig.FARPLANE);
                    glMatrixMode(GL_MODELVIEW);
                    glLoadIdentity();

glScalef(-1.0f, 1.0f, 1.0f);

                    FreeCam(true, depth);

NxVec3  verts[4] = { NxVec3(1,depth,0), NxVec3(0,depth,1), NxVec3(-1,depth,0), NxVec3(0,depth,-1) };
GLdouble eq[4]={0.0,1.0,0.0,0.0};

get_plane_equation(verts[1], verts[0], verts[2], &eq[0]);
glClipPlane(GL_CLIP_PLANE0, eq);

//DRAW MESH


                }
WaterFBO->End();

glLoadIdentity();

gdzie poszczegolne funkcje to:

void FreeCam(bool reflectmap, float depth)
{
static NxVec3 gViewY = NxVec3(0.0);

float add = 0.2f;

if(MConfig.MAINCAMMODE == CAM_FREE){
if(glfwGetKey( GLFW_KEY_LSHIFT  ) == GLFW_PRESS) add = 5.0f;
if(glfwGetKey( GLFW_KEY_LCTRL  ) == GLFW_PRESS) add = 0.05f;

//if(glfwGetMouseButton(1)) add = 5.0f;

if(glfwGetKey( 'W' ) == GLFW_PRESS) gEye += gDir*add;
if(glfwGetKey( 'S' ) == GLFW_PRESS) gEye -= gDir*add;
if(glfwGetKey( 'A' ) == GLFW_PRESS) gEye -= gViewY*add;
if(glfwGetKey( 'D' ) == GLFW_PRESS) gEye += gViewY*add;


static int  tx = 0,
ty = 0;
int dx,dy;

//glfwGetMousePos(&tx,&ty);

if((tx != MouseX) || (ty != MouseY))
{
dx = tx - MouseX;
dy = ty - MouseY;

if(glfwGetMouseButton(0))
{
gDir.normalize();
gViewY.cross(gDir, NxVec3(0,1,0));

NxQuat qx(NxPiF32 * dx * 20/ 180.0f, NxVec3(0,1,0));
qx.rotate(gDir);
NxQuat qy(NxPiF32 * dy * 20/ 180.0f, gViewY);
qy.rotate(gDir);
}

tx = MouseX;
ty = MouseY;
}

}

if(reflectmap)
{
gluLookAt(gEye.x, 2.0f*depth - gEye.y, gEye.z,
  gEye.x + gDir.x, 2.0f*depth - (gEye.y + gDir.y), gEye.z + gDir.z,
  -gUp.x, -gUp.y, -gUp.z);

}
else
{
gluLookAt(gEye.x, gEye.y, gEye.z,
gEye.x + gDir.x, gEye.y + gDir.y, gEye.z + gDir.z,
gUp.x, gUp.y, gUp.z);
}
}

bool get_plane_equation(NxVec3 p0, NxVec3 p1, NxVec3 p2, double* eq)
{
NxVec3 v0(p0 - p1),
    v1(p1 - p2),
n;
n = v0.cross(v1);
//if(n.length() <= MU_PREC) return false;
double &A = eq[0], &B = eq[1], &C = eq[2], &D = eq[3];
A = n.x; B = n.y; C = n.z;
D = - (A*p0.x + B*p0.y + C*p0.z);

return true;
}


No i na koniec szejdery:

VERTEX:
void main(void)
{
gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;
        gl_Position = ftransform();
}

FRAGMENT:

uniform sampler2D texWaterReflection;
uniform int win_width;
uniform int win_height

void main(){
vec2 uvReflection = vec2(gl_FragCoord.x/win_width, gl_FragCoord.y/win_height);
vec4 outcolor = texture2D(texWaterReflection, uvReflection);
        gl_FragColor = outcolor;
}


Przeruchaj sobie to wacpan na 3.2 czy tam 3.3 i bedzie git :)