[3d/c++] lighting probleem, continued...

Pagina: 1
Acties:

  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Na jullie geweldige hulp in mijn vorige topic vrees ik dat ik jullie hulp weer nodig heb. Het gaat weer om dezelfde renderer met een lighting probleempje:

Afbeeldingslocatie: http://dev.trag.nl/meuk/3d-prob..gif

Volgens mij is dit niet goed :? Als ik ga ronddraaien dan klopt er ook een hoop niet (voor de geinteresseerden is hier het proggeltje te downen, slepen=ronddraaien rechtsklikken+slepen=inzoomen).

Ik vind het nogal vreemd waarom die lichtjes niet kloppen. Ik heb grote stukken van de code al vaak doorgekeken (het is een port van deze engine, code checken is dus makkelijk :Y)) maar heb nog niet kunnen ontdekken waar het aan licht ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

uhm ja, je kan niet echt van ons verwachten dat wij die hele code door gaan nemen om te zien wat er fout aan is

heb je je al 'ns verdiept in belichtingstechnieken? Hoe doe je het nu? Of heb je het gewoon maar geport op hoop van goede zegen? ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

Je hebt reflecties aanstaan op het object, en daar gaat duidelijk iets mis mee. Wat precies weet ik niet. Ergens zal je de blending(?) of reflecties anders moeten instellen denk ik.

[edit] Misschien kan je even de code posten die zorgt vr de reflecties (van de omgeving?) op dit object?

[ Voor 52% gewijzigd door Verwijderd op 21-03-2003 21:31 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Verwijderd schreef op 21 maart 2003 @ 21:30:
Je hebt reflecties aanstaan op het object, en daar gaat duidelijk iets mis mee. Wat precies weet ik niet. Ergens zal je de blending(?) of reflecties anders moeten instellen denk ik.

[edit] Misschien kan je even de code posten die zorgt vr de reflecties (van de omgeving?) op dit object?
Reflecties uit de omgeving bestaan in deze engine niet ;) Dat zou te traag worden. Op dit moment werkt de lighting zo:

- Eerst worden twee lightmaps opgebouwd (specular en diffuse). Dit gaat op de volgende manier:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
void CLightmap::RebuildLightmap() {
    CVector l;
    float fnx, fny, phongfact, sheen, spread;
    CColor diffuse, specular;
    int cos, dr, dg, db, sr, sg, sb, pos;

    for(int ny=-128;ny<128;ny++) {
        fny = (float)ny/128;
        for(int nx=-128;nx<128;nx++) {
            pos = nx+128+((ny+128)<<8);
            fnx = (float)nx/128;
            sr = 0;
            sg = 0;
            sb = 0;
            dr = 0;
            dg = 0;
            db = 0;
        
            _scene->_lights.Restart();
            while(_scene->_lights.HasNext()) {
                CLight* li = _scene->_lights.NextStack();
                l = li->v;
                specular = li->specular;
                diffuse = li->diffuse;
                sheen = (float)li->highlightSheen/255.0f;
                spread = (float)li->highlightSpread/4096;
                spread = (spread<0.01f)?0.01f:spread;

                //cos=(int)(255*idx3d_Vector.angle(light[i].v,new idx3d_Vector(fnx,fny,sphere[pos])));
                cos = (int)(255*CVector::Angle(li->v,CVector(fnx, fny, sphere[pos])));
                cos = (cos>0)?cos:0;

                dr += (diffuse._red*cos)>>8; // >>8
                dg += (diffuse._green*cos)>>8; //>>8;
                db += (diffuse._blue*cos)>>8; //>>8;

                phongfact = sheen*(float)pow((float)cos/255.0f,1/spread);

                sr += (int)((float)specular._red*phongfact);
                sg += (int)((float)specular._green*phongfact);
                sb += (int)((float)specular._blue*phongfact);

                sr = sr>255?255:sr;
                sg = sg>255?255:sg;
                sb = sb>255?255:sb;

                dr = dr>255?255:dr;
                dg = dg>255?255:dg;
                db = db>255?255:db;             
            }

            this->diffuse[pos] = CColor(dr, dg, db);
            this->specular[pos] = CColor(sr, sg, sb);
        }
    }
}



Vervolgens wordt er natuurlijk ieder frame de normal-x en y uitgerekend:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void CVertex::Project(CMatrix vertexProjection,CMatrix normalProjection,CCamera* camera) {
    pos2 = pos.Transform(vertexProjection);
    n2 = n.Transform(normalProjection);

    fact = camera->screenscale/camera->fovfact/((pos2._z>0.1)?pos2._z:0.1f);
    _x = (int)(pos2._x*fact+(camera->screenwidth>>1)); 
    _y = (int)(-pos2._y*fact+(camera->screenheight>>1)); 
    _z = 65536.0f*pos2._z; // 65536.0f


    nx = (int)(n2._x*127+127);
    ny = (int)(n2._y*127+127);
    
    //if (parent->_material==null) return;
    //if (parent->_material.texture==null) return;
    
    tx = (int)(_u*_parent->_material.texture._width);
    ty = (int)(_v*_parent->_material.texture._height);
    
    /*if(_parent->_parent!=0) {
        tx=(int)((float)_parent->_parent->_material.texture._width*_u);
        ty=(int)((float)_parent->_parent->_material.texture._height*_v);
    }*/
    

    /*
    if(_parent!=0) {
        tx=(int)((float)_parent->_parent->_material.texture._width*_u);
        ty=(int)((float)_parent->_parent->_material.texture._height*_v);
    }*/
}


Daarna gaat de rasterizer aan de slag:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void CRasterizer::RenderLineP() {
    assert(_lightmap!=0);
    float gz;

    for(x=xL;x<xR;x++) {
        pos = x+offset;
        
        gz = _zbuffer->Get(x,y);

        if(_zbufferNegative) {
            gz = -gz;
        }
        
        if(z<gz||gz<0) {
            lutID=((nx>>16)&255)+(((ny>>16)&255)<<8);
            _canvas->At(x,y,&bkgrd);
            c = CColor::Multiply(color,_lightmap->diffuse[lutID]);
            s = _lightmap->specular[lutID];
            s = CColor::Scale(s,reflectivity);
            CColor::Transparency(bkgrd,c,c);
            c = CColor::Add(c,s);
                                        
            _canvas->DrawTexel(x,y,c);
            _zbuffer->Put(x,y,_zbufferNegative?-z:z);
        }

        z+=dz;
        nx+=dnx;
        ny+=dny;
    }   
}



Dit zijn denk ik de meest relevante stukken (en ik heb ze gechecked). De vraag is niet of jullie in de code willen gaan wroeten, de vraag is of iemand een idee heeft over hoe dit zou kunnen worden veroorzaakt :)

edit: je vroeg om de reflectie- en blendingfuncties?
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
        static int Add(int ca, int cb) {
            int pixel=(ca&MASK7Bit)+(cb&MASK7Bit);
            int overflow=pixel&0x1010100;
            overflow=overflow-(overflow>>8);
            return ALPHA|overflow|pixel;
        }


static CColor Multiply(CColor& a, CColor& b) {
            if(a._red+a._blue+a._green==0) {
                return CColor(0,0,0);
            }

            if(b._red+b._blue+b._green==0) {
                return CColor(0,0,0);
            }
            
        
            int r = (a._red*b._red)/255;
            int g = (a._green*b._green)/255;
            int bl = (a._blue*b._blue)/255;
            int al = (a._alpha*b._alpha)/255;

            return CColor(r,g,bl,al);
        }

    static CColor Scale(CColor& a, int factor) {
            if (factor==0) return CColor(0,0,0);
            if (factor==255) return a;
            
            int r = (a._red*factor)/255;
            int g = (a._green*factor)/255;
            int b = (a._blue*factor)/255;

            return CColor(r,g,b,a._alpha);
        }

[ Voor 20% gewijzigd door MisterData op 21-03-2003 21:45 ]


Verwijderd

Ik vraag me af wat die rasterizer eigenlijk doet?
Visueel vormt er zich een soort raster van reflecties op het object, ipv 1 'normale' reflect over het hele object. Dit zou kunnen komen omdat de lightmapping verkeerd gaat.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Verwijderd schreef op 21 maart 2003 @ 21:57:
Ik vraag me af wat die rasterizer eigenlijk doet?
Visueel vormt er zich een soort raster van reflecties op het object, ipv 1 'normale' reflect over het hele object. Dit zou kunnen komen omdat de lightmapping verkeerd gaat.
Ja dat dacht ik ook ja, heb je meer code van de rasterizer nodig? Er zit ergens een rekenfoutje ofzo vrees ik, maarja ik heb em nog niet ontdekt :(

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
// ---------------------------------------------------------------------------------------------------------------------------------------------------
// Method implementations for the CRasterizer class.
// ---------------------------------------------------------------------------------------------------------------------------------------------------
#include "../include/cactus.h"

void CRasterizer::Render(CTriangle* tri) {
    RebuildReferences();

    // Draw a wireframe
    if (_mode==WIREFRAME) {
        DrawWireframe(tri);
        return;
    }


    _zbufferNegative = _renderer->_zbufferNegative;

    CVertex* p1=tri->_a;
    CVertex* p2=tri->_b;
    CVertex* p3=tri->_c;
    CVertex* tempVertex;
        
    if (p1->_y>p2->_y) {
        tempVertex=p1;
        p1=p2;
        p2=tempVertex;
    }

    if (p2->_y>p3->_y) {
        tempVertex=p2;
        p2=p3;
        p3=tempVertex; 
    }
    if (p1->_y>p2->_y) {
        tempVertex=p1;
        p1=p2;
        p2=tempVertex;
    }
    
    if (p1->_y>=_height) {
        return;
    }
    if (p3->_y<0) {
        return;
    }
    if (p1->_y==p3->_y) {
        return;
    }
    
    if (_mode==FLAT) {
        lutID = (int) (tri->n2._x*127+127)+((int)(tri->n2._y*127+127)<<8); // +127
        if(lutID>=65536) {
            lutID = 65535;
        }
        else if(lutID<0) {
            lutID = 0;
        }
        c = CColor::Multiply(color,_lightmap->diffuse[lutID]);
        s = CColor::Scale(_lightmap->specular[lutID],reflectivity);
        currentColor = CColor::Add(c,s);
    }

    
    x1=p1->_x<<8;
    x2=p2->_x<<8;
    x3=p3->_x<<8;
    y1=p1->_y;
    y2=p2->_y;
    y3=p3->_y;
    
    x4=x1+(x3-x1)*(y2-y1)/(y3-y1);
    x1<<=8; x2<<=8; x3<<=8; x4<<=8;

    z1 = p1->_z;
    z2 = p2->_z;
    z3 = p3->_z;
    nx1=p1->nx<<16;
    nx2=p2->nx<<16;
    nx3=p3->nx<<16;
    ny1=p1->ny<<16;
    ny2=p2->ny<<16;
    ny3=p3->ny<<16;

    tx1=p1->tx<<16;
    tx2=p2->tx<<16;
    tx3=p3->tx<<16;
    ty1=p1->ty<<16;
    ty2=p2->ty<<16;
    ty3=p3->ty<<16;
    
    dx=(x4-x2)>>16;
    if (dx==0) return;
    
    temp=256*(y2-y1)/(y3-y1);
    
    z4=z1+((z3-z1)/(float)pow(2,8))*temp; //    z4=z1+((z3-z1)>>8)*temp;
    nx4=nx1+((nx3-nx1)>>8)*temp;
    ny4=ny1+((ny3-ny1)>>8)*temp;
    tx4=tx1+((tx3-tx1)>>8)*temp;
    ty4=ty1+((ty3-ty1)>>8)*temp;

    dz=(z4-z2)/dx;
    dnx=(nx4-nx2)/dx;
    dny=(ny4-ny2)/dx;
    dtx=(tx4-tx2)/dx;
    dty=(ty4-ty2)/dx;


    if (dx<0)
    { 
        temp=x2; x2=x4; x4=temp; 
        z2=z4;
        tx2=tx4;
        ty2=ty4;
        nx2=nx4;
        ny2=ny4;
    }
    if (y2>=0)
    {
        dy=y2-y1;
        if (dy!=0)
        {
            dxL=(x2-x1)/dy;
            dxR=(x4-x1)/dy;
            dzBase=(z2-z1)/dy;
            dnxBase=(nx2-nx1)/dy;
            dnyBase=(ny2-ny1)/dy;
            dtxBase=(tx2-tx1)/dy;
            dtyBase=(ty2-ty1)/dy;
        }
                    
        xBase=x1;
        xMax=x1;
        zBase=z1;
        nxBase=nx1;
        nyBase=ny1;
        txBase=tx1;
        tyBase=ty1;
        
        if (y1<0)
        {
            xBase-=y1*dxL;
            xMax-=y1*dxR;
            zBase-=y1*dzBase;
            nxBase-=y1*dnxBase;
            nyBase-=y1*dnyBase;
            txBase-=y1*dtxBase;
            tyBase-=y1*dtyBase;
            y1=0;
        }
        
        y2=(y2<_height)?y2:_height;
        offset=y1*_width;
        for (y=y1;y<y2;y++) RenderLine();
    }
    
    if (y2<_height)
    {
        dy=y3-y2;
        if (dy!=0)
        {
            dxL=(x3-x2)/dy;
            dxR=(x3-x4)/dy;
            dzBase=(z3-z2)/dy;
            dnxBase=(nx3-nx2)/dy;
            dnyBase=(ny3-ny2)/dy;
            dtxBase=(tx3-tx2)/dy;
            dtyBase=(ty3-ty2)/dy;   
        }
                        
        xBase=x2;
        xMax=x4;
        zBase=z2;
        nxBase=nx2;
        nyBase=ny2;
        txBase=tx2;
        tyBase=ty2;
        
        if (y2<0)
        {
            xBase-=y2*dxL;
            xMax-=y2*dxR;
            zBase-=y2*dzBase;
            nxBase-=y2*dnxBase;
            nyBase-=y2*dnyBase;
            txBase-=y2*dtxBase;
            tyBase-=y2*dtyBase;
            y2=0;
        }
        
        y3=(y3<_height)?y3:_height;
        offset=y2*_width;
        

        for (y=y2;y<y3;y++) RenderLine();
    }
}

void CRasterizer::DrawWireframe(CTriangle* tri) {
    CColor wcolor(255,255,255);
    DrawLine(tri->_a,tri->_b,wcolor);
    DrawLine(tri->_b,tri->_c,wcolor);
    DrawLine(tri->_c,tri->_a,wcolor);
}

void CRasterizer::RenderLine() {
    xL=xBase>>16;
    xR=xMax>>16;
    z=zBase;
    nx=nxBase;
    ny=nyBase;
    tx=txBase;
    ty=tyBase;
    

    if (xL<0) {
        z-=xL*dz;
        nx-=xL*dnx;
        ny-=xL*dny;
        tx-=xL*dtx;
        ty-=xL*dty;
        xL=0;
    }

    xR = (xR<_width)?xR:_width;
    
    if (_mode==FLAT) RenderLineF();
    else if (_mode==TEXTURED) RenderLineT();
    else if (_mode==PHONG) RenderLineP();
    else if (_mode==(PHONG|TEXTURED)) RenderLinePT();

    //else if (_mode==PHONG) RenderLineP();
    //else if ((_mode&SHADED)==E) renderLineE();
    //else if ((_mode&SHADED)==(P|E)) renderLinePE();
    //else if ((_mode&SHADED)==(P|T)) renderLinePT();
    //else if ((_mode&SHADED)==(P|E|T)) renderLinePET();
    
    offset+=_width;
    xBase+=dxL;
    xMax+=dxR;
    zBase+=dzBase;
    nxBase+=dnxBase;
    nyBase+=dnyBase;
    txBase+=dtxBase;
    tyBase+=dtyBase;    
}

void CRasterizer::RenderLinePT() {
    float gz = 0;

    for (x=xL;x<xR;x++) {
        pos=x+offset;
        gz = _zbuffer->Get(x,y);

        if(_zbufferNegative) {
            gz = -gz;
        }

        if(z<gz||gz<0) {
            lutID=((nx>>16)&255)+(((ny>>16)&255)<<8);
            
            bkgrd._red = _canvas->_buffer[(y*_width*3)+(x*3)];
            bkgrd._blue = _canvas->_buffer[(y*_width*3)+(x*3)+1];
            bkgrd._green = _canvas->_buffer[(y*_width*3)+(x*3)+2];

            //c = texture->_pixel[((tx>>16)&tw)+(((ty>>16)&th)<<tbitW)];
            int index = ((tx>>16)&tw) + (((ty>>16)&th) << tbitW);
            c = texture->_pixel[index];
            c = CColor::Multiply(c,CColor(_lightmap->diffuse[lutID]));
            s = _lightmap->specular[lutID];
            s = CColor::Scale(s,reflectivity);
            //CColor::Transparency(bkgrd,c,c);
            c = CColor::Add(c,s);
                                
            _canvas->_buffer[(y*_width*3)+(x*3)] = c._red;
            _canvas->_buffer[(y*_width*3)+(x*3)+1] = c._green;
            _canvas->_buffer[(y*_width*3)+(x*3)+2] = c._blue;
            
            _zbuffer->Put(x,y,_zbufferNegative?-z:z);
        }
        z+=dz;
        nx+=dnx;
        ny+=dny;
        tx+=dtx;
        ty+=dty;
    }
}


void CRasterizer::LoadMaterial(CMaterial* material) {
    texture = &material->texture;
    color = material->color;
    transparency = material->transparency;
    reflectivity = material->reflectivity;
    
    tw=texture->_width-1;
    th=texture->_height-1;
    tbitW=texture->_bitWidth;
    tbitH=texture->_bitHeight;

    _mode = material->mode;
}

void CRasterizer::LoadLightmap(CLightmap* lightmap) {
    _lightmap = lightmap;
}

void CRasterizer::RenderLineP() {
    assert(_lightmap!=0);
    float gz;

    for(x=xL;x<xR;x++) {
        pos = x+offset;
        
        gz = _zbuffer->Get(x,y);

        if(_zbufferNegative) {
            gz = -gz;
        }
        
        if(z<gz||gz<0) {
            lutID=((nx>>16)&255)+(((ny>>16)&255)<<8);
            _canvas->At(x,y,&bkgrd);
            c = CColor::Multiply(color,_lightmap->diffuse[lutID]);
            s = _lightmap->specular[lutID];
            s = CColor::Scale(s,reflectivity);
            CColor::Transparency(bkgrd,c,c);
            c = CColor::Add(c,s);
                                        
            _canvas->DrawTexel(x,y,c);
            _zbuffer->Put(x,y,_zbufferNegative?-z:z);
        }

        z+=dz;
        nx+=dnx;
        ny+=dny;
    }   
}

[ Voor 88% gewijzigd door MisterData op 21-03-2003 22:03 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
En de headerfile (react ging zeuren over een te lang bericht :()

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class CACTUS_API CRasterizer {
    friend class CRenderer;
    public:
        CRasterizer(CRenderer* rend);
        CRasterizer();
        virtual ~CRasterizer();
        void RebuildReferences();
        void LoadMaterial(CMaterial* material);
        void LoadLightmap(CLightmap* lightmap);
        void DrawLine(CVertex* a, CVertex* b, CColor& c);
        inline void RenderLine();
        inline void RenderLineF();
        inline void RenderLineP();
        inline void RenderLineT();
        inline void RenderLinePT();
        void DrawWireframe(CTriangle* tri);
        inline void Render(CTriangle* tri);
        void SetCanvas(CCanvas* cv) {
            _canvas = cv;
        }
        void SetMode(int m) {
            _mode = m;
        }

        int GetMode() {
            return _mode;
        }

        void SetRenderer(CRenderer* rend) {
            _renderer = rend;
        }

        CRenderer* GetRenderer() {
            return _renderer;
        }
    private:
        bool _zbufferNegative;
        CRenderer* _renderer;
        int _width;
        int _height;
        int _mode;
        bool enableLighting;
        CBuffer<float>* _zbuffer;
        CCanvas* _canvas;
        CTexture* texture;
        CColor c,s;
        CColor color;
        int reflectivity, transparency;
        CColor bkgrd;
        CLightmap* _lightmap;

        int tw, th, tbitW, tbitH;
         int    lutID,r,
                x1,x2,x3,x4,y1,y2,y3;
         float z1,z2,z3,z4,z,dz,dzBase,zBase;
         int    x,y,k,dx,dy,offset,pos,temp,
                xL,xR,xBase,xMax,yMax,dxL,dxR,
            
                nx1,nx2,nx3,nx4,ny1,ny2,ny3,ny4,
                nxBase,nyBase,
                dnx4,dny4,
                dnx,dny,nx,ny,
                dnxBase,dnyBase,
            
                tx1,tx2,tx3,tx4,ty1,ty2,ty3,ty4,
                txBase,tyBase,
                dtx4,dty4,
                dtx,dty,tx,ty,
                dtxBase,dtyBase;

         
        CColor currentColor;
};


De code voor het tekenen van lijntjes voor een wireframe heb ik maar even weggelaten, net als RenderlineF en RenderLineT, aangezien daar geen probleem in zit (ze gebruiken geen lighting)

[ Voor 7% gewijzigd door MisterData op 21-03-2003 22:06 ]


Verwijderd

Ik zou graag die code doornemen voor je, maar kheb momenteel zelf teveel werk met een programmafout te debuggen :( Tprobleem is dat ik vaak ook over die kleine k*tfouten heen kijk ;(
[edit] en niet alle operatoren zijn duidelijk voor me ;(

[ Voor 14% gewijzigd door Verwijderd op 21-03-2003 23:09 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Verwijderd schreef op 21 March 2003 @ 23:00:
Ik zou graag die code doornemen voor je, maar kheb momenteel zelf teveel werk met een programmafout te debuggen :( Tprobleem is dat ik vaak ook over die kleine k*tfouten heen kijk ;(
[edit] en niet alle operatoren zijn duidelijk voor me ;(
Je bedoelt die >> en <<? over het algemeen is het zo dat:

x >> y = x*2^y
x << y = x/2^y

met ^ bedoel ik machtsverheffen. x >> 8 is gelijk aan x*256, maar een bitshift is iets sneller in de processor dan gewoon vermenigvuldigen. De processor hoeft met een bitshift alleen maar een paar bits te verschuiven :)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Wat voor normals gebruik je? face normals of vertex normals? Dat laatste is in theorie niet mogelijk, maar je neemt dan de gemiddelde normal van alle faces waar de vertex in zit en DIE normal gebruik je als normal voor je vertex.

Als je voor je vertices de normal neemt van de face die je aan het tekenen bent, dan krijg je niet goede belichting, want je object is dan flat faced en niet smooth. Je moet je normals in software rendering dan ook meenemen in je rasterisatie, de gouraudshading die je tekent.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData: je doet die shifts verkeerd om. x << y = x * 2y en x >> y = x / 2y

Aanvulling op de post van EfBe: je kunt de vertex normals te bepalen door eerst elke vertex normal op 0 te zetten, vervolgens doorloop je alle faces, waarbij je de face normal bij elke vertex-normal van die face optelt, en aan het eind normalizeer je alle vertex normals

in pseudo-code:
C++:
1
2
3
4
5
6
7
8
9
foreach (vertex in vertex_list)
    vertex.normal = [0, 0, 0];

foreach (face in face_list)
    foreach (vertex in face.vertex_list)
        vertex.normal += face.normal;

foreach (vertex in vertex_list)
    vertex.normal = normalize (vertex.normal);

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
.oisyn schreef op 22 maart 2003 @ 12:54:
MisterData: je doet die shifts verkeerd om. x << y = x * 2y en x >> y = x / 2y
Laten we het maar niet over het verschil tussen little-endian en big-endian hebben in dat geval :P
Aanvulling op de post van EfBe: je kunt de vertex normals te bepalen door eerst elke vertex normal op 0 te zetten, vervolgens doorloop je alle faces, waarbij je de face normal bij elke vertex-normal van die face optelt, en aan het eind normalizeer je alle vertex normals

in pseudo-code:
C++:
1
2
3
4
5
6
7
8
9
foreach (vertex in vertex_list)
    vertex.normal = [0, 0, 0];

foreach (face in face_list)
    foreach (vertex in face.vertex_list)
        vertex.normal += face.normal;

foreach (vertex in vertex_list)
    vertex.normal = normalize (vertex.normal);
Dit gebeurt al in de code:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void CVertex::RegenerateNormal() {  
    _neighbours.Restart();
    float nz = 0;
    float nx = 0;
    float ny = 0;

    CTriangle* tri;
    CVector wn;

    while(_neighbours.HasNext()) {
        tri = _neighbours.NextStack();

        wn = tri->GetWeightedNormal();
        nx += wn._x;
        ny += wn._y;
        nz += wn._z;
    }

    n = CVector(nx,ny,nz);
    n.Normalize();
}

CVector CTriangle::GetWeightedNormal() {
    return CVector::VectorProduct(_a->pos,_b->pos,_c->pos); 
}

void CTriangle::RegenerateNormal() {
    n=CVector::GetNormal(_a->pos,_b->pos,_c->pos);
}

 

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
MisterData schreef op 22 maart 2003 @ 13:45:
Laten we het maar niet over het verschil tussen little-endian en big-endian hebben in dat geval :P
Laten we dat niet doen, inderdaad, want dat heeft er niets mee te maken. :P ;)

Verwijderd

MisterData schreef op 22 maart 2003 @ 08:44:
[...]


Je bedoelt die >> en <<? over het algemeen is het zo dat:

x >> y = x*2^y
x << y = x/2^y

met ^ bedoel ik machtsverheffen. x >> 8 is gelijk aan x*256, maar een bitshift is iets sneller in de processor dan gewoon vermenigvuldigen. De processor hoeft met een bitshift alleen maar een paar bits te verschuiven :)
Bitshiften enzo ken ik wel hoor. Wat ik bedoelde was stuff zoals:
  • int overflow=pixel&0x1010100; RenderLine..(); _zbuffer _canvas

  • EfBe
  • Registratie: Januari 2000
  • Niet online
MisterData schreef op 22 March 2003 @ 13:45:
[...]
Dit gebeurt al in de code:
Hmmm. Staan ze dan naar binnen te wijzen ipv naar buiten? (ik heb niet naar je code gekeken, maar nu naar je screenshot kijkende is het idd niet echt flatshaded, dus die vertexnormal komt er wel goed uit, maar hij is ingedeukt lijkt het wel, die normals staan OF de verkeerde kant op te wijzen, OF je gouraudshader is niet goed. Wel lastig debuggen. Als je nu de vertex normals nu eerst eens tekent met lijntjes, dan kun je iig zien of die kloppen. Als dat het is, kun je je gouraudshader aan de tand voelen.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Soultaker schreef op 22 March 2003 @ 13:48:
[...]

Laten we dat niet doen, inderdaad, want dat heeft er niets mee te maken. :P ;)
Jawel, als je een little-endian getal gaat shiften dan is de uitkomst anders als dat je een big-endian getal gaat shiften natuurlijk :)

  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
EfBe schreef op 22 March 2003 @ 13:54:
[...]

Hmmm. Staan ze dan naar binnen te wijzen ipv naar buiten? (ik heb niet naar je code gekeken, maar nu naar je screenshot kijkende is het idd niet echt flatshaded, dus die vertexnormal komt er wel goed uit, maar hij is ingedeukt lijkt het wel, die normals staan OF de verkeerde kant op te wijzen, OF je gouraudshader is niet goed. Wel lastig debuggen. Als je nu de vertex normals nu eerst eens tekent met lijntjes, dan kun je iig zien of die kloppen. Als dat het is, kun je je gouraudshader aan de tand voelen.
En hoe kan ik die tekenen?
Verwijderd schreef op 22 March 2003 @ 13:48:
[...]


Bitshiften enzo ken ik wel hoor. Wat ik bedoelde was stuff zoals:

[list]int overflow=pixel&0x1010100;
Wat dat doet weet ik ook niet echt 8)7
RenderLine..();
RenderlineP = phongshaded, RenderlineF = flat, renderLineT = textured, renderlinePT = phong+textured :)
_zbuffer
float[width*height] zbuffer
_canvas
de buffer waar in getekent wordt (een int [width*height*3] dacht ik)

[ Voor 31% gewijzigd door MisterData op 22-03-2003 14:56 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

MisterData schreef op 22 maart 2003 @ 14:52:
[...]


Jawel, als je een little-endian getal gaat shiften dan is de uitkomst anders als dat je een big-endian getal gaat shiften natuurlijk :)


onzin, een shift naar links maakt het getal altijd groter, en een shift naar rechts maakt het getal altijd kleiner

litte-endianness vs. big-endiannes geeft alleen maar aan hoe een getal in het geheugen opgeslagen wordt. Bij de representatie ervan (dus het feitelijke getal zelf) staat de most-significant-bit altijd links en de least-significant-bit altijd rechts

Net als hoe wij getallen opschijven: de meest significante cijfers staan links, en de minst significante cijfers staan rechts

Een shift werkt dan ook op het getal, niet op het geheugen

[ Voor 4% gewijzigd door .oisyn op 22-03-2003 16:37 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
.oisyn schreef op 22 maart 2003 @ 16:36:

[...]


onzin, een shift naar links maakt het getal altijd groter, en een shift naar rechts maakt het getal altijd kleiner

litte-endianness vs. big-endiannes geeft alleen maar aan hoe een getal in het geheugen opgeslagen wordt. Bij de representatie ervan (dus het feitelijke getal zelf) staat de most-significant-bit altijd links en de least-significant-bit altijd rechts

Net als hoe wij getallen opschijven: de meest significante cijfers staan links, en de minst significante cijfers staan rechts

Een shift werkt dan ook op het getal, niet op het geheugen
Weer wat geleerd :) Nu snel weer debuggen :P

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 22 maart 2003 @ 13:48:
[...]


Bitshiften enzo ken ik wel hoor. Wat ik bedoelde was stuff zoals:
  • int overflow=pixel&0x1010100; RenderLine..(); _zbuffer _canvas


is dat een letterlijke koppiepeest? Dan weet ik ook niet wat het doet :)
Maar meestal wordt een dergelijke constructie gebruikt bij het snel blenden van kleuren... de kleuren (rood, groen, blauw en evt. alpha) staan meestal gecodeerd als 8 bits waarden in een 32 bits register. Als je blend kun je natuurlijk alle kleuren extracten, maar sneller is om gewoon de least-significant-bits van elk component op 0 te zetten, de 2 ints bij elkaar op te tellen, en dan 1 naar rechts te shiften

Het op 0 zetten van de lsb's is nodig omdat het anders voor kan komen dat bijvoorbeeld de lsb van groen gaat interferreren met de msb van blauw

En dat op 0 zetten gaat door te and'en met ~0x01010101

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • EfBe
  • Registratie: Januari 2000
  • Niet online
MisterData schreef op 22 March 2003 @ 14:53:
[...]
En hoe kan ik die tekenen?
Nou, een lijntje trekken met als startpunt de vertex en als endpunt de vertex + de vertex normal. Je moet dan een stekelig object krijgen. Zie je ze niet, zet dan even je filler van je polies uit, zodat je de normals toch ziet en mocht dat zo zijn, dan staan ze naar binnen en heb je ergens een minnetje fout staan :)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-08 13:19

.oisyn

Moderator Devschuur®

Demotivational Speaker



niet helemaal, mijn voorbeeld ging ervan uit dat er geen informatie is over welke faces van een vector gebruik maken (wat meestal ook het geval is, aangezien dat soort info vrij nutteloos is en alleen maar geheugen inneemt. Dit ligt natuurlijk anders als je de data nodig hebt om een progressive mesh algoritme of iets in die trand erop los te laten)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
.oisyn schreef op 22 maart 2003 @ 17:09:

[...]


niet helemaal, mijn voorbeeld ging ervan uit dat er geen informatie is over welke faces van een vector gebruik maken (wat meestal ook het geval is, aangezien dat soort info vrij nutteloos is en alleen maar geheugen inneemt. Dit ligt natuurlijk anders als je de data nodig hebt om een progressive mesh algoritme of iets in die trand erop los te laten)
OK, maar zo werkt het als het goed is ook :) Ik ga even die normals tekenen denk ik.

edit:
heb het even gedaan....


Ik krijg het volgende plaatje:

Afbeeldingslocatie: http://dev.trag.nl/meuk/3d-prob2.gif
Op zich niet verwonderlijk, want de debugger zegt ook al dat de projected normal-vector als x/y/z waarden heeft rond de 0 (waarden zoals 1,6665 en -1,347834)..... moet ik daar nog iets mee doen ofzo? Lijkt me niet dat dat klopt eik :(

[ Voor 25% gewijzigd door MisterData op 22-03-2003 18:16 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 21:49
Het probleem is opgelost. Het zat 'em in dat een paar methoden van CObject nog de normalmatrix mee-schaalden bij een Scale en dat mag natuurlijk niet :) Toch bedankt!
Pagina: 1