Quad rendering bug

Technical discussion for those interested in Supermodel development and Model 3 reverse engineering. Prospective contributors welcome.
Forum rules
Keep it classy!

  • No ROM requests or links.
  • Do not ask to be a play tester.
  • Do not ask about release dates.
  • No drama!

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 1:16 pm

Good catch :)
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 2:52 pm

Well,
this isn't 100% perfect, but maybe the closest we can emulate .. :)

Image
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby HarryTuttle » Sat Apr 08, 2017 3:03 pm

Excellent, can't wait to test it! :)
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 3:09 pm

I'll push it in a bit, need to tidy a few bits up
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 4:04 pm

Try it for yourself and see what you think before I push it ..

Code: Select all
void CNew3D::GenerateVertex(Vertex &newVertex, const R3DPoly& poly)
{
   newVertex.color[0] = (poly.v[0].color[0] + poly.v[1].color[0] + poly.v[2].color[0] + poly.v[3].color[0]) / 4;
   newVertex.color[1] = (poly.v[0].color[1] + poly.v[1].color[1] + poly.v[2].color[1] + poly.v[3].color[1]) / 4;
   newVertex.color[2] = (poly.v[0].color[2] + poly.v[1].color[2] + poly.v[2].color[2] + poly.v[3].color[2]) / 4;
   newVertex.color[3] = (poly.v[0].color[3] + poly.v[1].color[3] + poly.v[2].color[3] + poly.v[3].color[3]) / 4;

   newVertex.normal[0] = (poly.v[0].normal[0] + poly.v[1].normal[0] + poly.v[2].normal[0] + poly.v[3].normal[0]) / 4;
   newVertex.normal[1] = (poly.v[0].normal[1] + poly.v[1].normal[1] + poly.v[2].normal[1] + poly.v[3].normal[1]) / 4;
   newVertex.normal[2] = (poly.v[0].normal[2] + poly.v[1].normal[2] + poly.v[2].normal[2] + poly.v[3].normal[2]) / 4;

   newVertex.pos[0] = (poly.v[0].pos[0] + poly.v[1].pos[0] + poly.v[2].pos[0] + poly.v[3].pos[0]) / 4;
   newVertex.pos[1] = (poly.v[0].pos[1] + poly.v[1].pos[1] + poly.v[2].pos[1] + poly.v[3].pos[1]) / 4;
   newVertex.pos[2] = (poly.v[0].pos[2] + poly.v[1].pos[2] + poly.v[2].pos[2] + poly.v[3].pos[2]) / 4;

   newVertex.texcoords[0] = (poly.v[0].texcoords[0] + poly.v[1].texcoords[0] + poly.v[2].texcoords[0] + poly.v[3].texcoords[0]) / 4;
   newVertex.texcoords[1] = (poly.v[0].texcoords[1] + poly.v[1].texcoords[1] + poly.v[2].texcoords[1] + poly.v[3].texcoords[1]) / 4;
}

void CNew3D::AddTriangle(const Vertex& v1, const Vertex& v2, const Vertex& v3, const R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
{
   //=====
   Poly p;
   //=====

   p.p1 = v1;
   p.p2 = v2;
   p.p3 = v3;

   //multiply face attributes with vertex attributes if required
   for (int i = 0; i < 4; i++) {
      p.p1.color[i] = p.p1.color[i] * r3dPoly.faceColour[i];
      p.p2.color[i] = p.p2.color[i] * r3dPoly.faceColour[i];
      p.p3.color[i] = p.p3.color[i] * r3dPoly.faceColour[i];
   }

   polyArray.emplace_back(p);
}

void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
{
   //====================
   V3::Vec3   normal;
   float      dotProd;
   bool      clockWise;
   //====================

   V3::createNormal(r3dPoly.v[0].pos, r3dPoly.v[1].pos, r3dPoly.v[2].pos, normal);

   dotProd      = V3::dotProduct(normal, r3dPoly.faceNormal);
   clockWise   = dotProd >= 0;

   if (r3dPoly.number == 3) {

      if (clockWise) {
         AddTriangle(r3dPoly.v[0], r3dPoly.v[1], r3dPoly.v[2], r3dPoly, polyArray);
      }
      else {
         AddTriangle(r3dPoly.v[2], r3dPoly.v[1], r3dPoly.v[0], r3dPoly, polyArray);
      }

   }

   else if (r3dPoly.number == 4) {

      //=================
      Vertex   newVertex;
      bool   clockWise2;
      //=================

      // check for the evil quads that overlap themselves and change the winding ..

      V3::createNormal(r3dPoly.v[0].pos, r3dPoly.v[2].pos, r3dPoly.v[3].pos, normal);

      dotProd      = V3::dotProduct(normal, r3dPoly.faceNormal);
      clockWise2   = dotProd >= 0;

      if (clockWise != clockWise2) {

         if (clockWise) {
            AddTriangle(r3dPoly.v[0], r3dPoly.v[1], r3dPoly.v[2], r3dPoly, polyArray);
         }
         else {
            AddTriangle(r3dPoly.v[2], r3dPoly.v[1], r3dPoly.v[0], r3dPoly, polyArray);
         }

         if (clockWise2) {
            AddTriangle(r3dPoly.v[0], r3dPoly.v[2], r3dPoly.v[3], r3dPoly, polyArray);
         }
         else {
            AddTriangle(r3dPoly.v[0], r3dPoly.v[3], r3dPoly.v[2], r3dPoly, polyArray);
         }
         
         return;
      }

      GenerateVertex(newVertex, r3dPoly);

      if (clockWise) {
         AddTriangle(r3dPoly.v[0], r3dPoly.v[1], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[1], r3dPoly.v[2], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[2], r3dPoly.v[3], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[3], r3dPoly.v[0], newVertex, r3dPoly, polyArray);
      }
      else {
         AddTriangle(r3dPoly.v[0], r3dPoly.v[3], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[3], r3dPoly.v[2], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[2], r3dPoly.v[1], newVertex, r3dPoly, polyArray);
         AddTriangle(r3dPoly.v[1], r3dPoly.v[0], newVertex, r3dPoly, polyArray);
      }
   }
}


header file

Code: Select all
   void GenerateVertex(Vertex &newVertex, const R3DPoly& poly);
   void AddTriangle(const Vertex& v1, const Vertex& v2, const Vertex& v3, const R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 4:16 pm

I honestly think that the version where we flipped the split was more accurate
Maybe I could use this method to try that..
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby HarryTuttle » Sat Apr 08, 2017 4:24 pm

Ok. I'll let you know, in case I'll upload some new screenshots.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: Quad rendering bug

Postby HarryTuttle » Sat Apr 08, 2017 5:36 pm

Ian wrote:I honestly think that the version where we flipped the split was more accurate
Maybe I could use this method to try that..


I think you're right about the accuracy of the flipped split, in fact in many cases the specular has a sort of "diamond" shape. I checked by reloading the savestates used to produce the former series of screenshots of Harley and Dirt Devils (however Scud is more close to the original). Tomorrow I'll upload some example.

There must be some sort of condition that triggers the split flipping. In one of my tests I noticed that sometimes, in the same quad, the normal of a triangle built from vertices 0,1,2 is different from the one build from vertices 1,2,3 (flipped split). In that case, after being multiplied by the same face normal, they'll generate different winding. Could be a sort of hint?

I saw also, from the link you posted, that one can use the geometry shader to create a quad, but GPUs older than opengl 3.2 are out of luck.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

Re: Quad rendering bug

Postby Ian » Sat Apr 08, 2017 5:44 pm

Yeah, well increase the vertex count is a good approximation
But the hardware is doing something else ..
Ian
 
Posts: 2044
Joined: Tue Feb 23, 2016 9:23 am

Re: Quad rendering bug

Postby HarryTuttle » Sun Apr 09, 2017 11:03 am

Just a quick update with some screenshots of "bad" quads with the new method:
hl_10.jpeg
hl_10.jpeg (244.9 KiB) Viewed 9332 times

dd_02.jpeg
dd_02.jpeg (235.63 KiB) Viewed 9332 times


Ian, based on the geometry shader solution you linked: http://www.informit.com/articles/article.aspx?p=2120983&seqNum=2, I wonder if could be possible to send those quad vertex data (color, texture coordinates and normals) as uniforms in fragment and vertex shader to obtain the same effect.
User avatar
HarryTuttle
 
Posts: 646
Joined: Thu Mar 09, 2017 8:57 am

PreviousNext

Return to The Dark Room

Who is online

Users browsing this forum: No registered users and 1 guest