Page 7 of 9

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 1:16 pm
by Ian
Good catch :)

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 2:52 pm
by Ian
Well,
this isn't 100% perfect, but maybe the closest we can emulate .. :)

Image

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 3:03 pm
by HarryTuttle
Excellent, can't wait to test it! :)

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 3:09 pm
by Ian
I'll push it in a bit, need to tidy a few bits up

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 4:04 pm
by Ian
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);

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 4:16 pm
by Ian
I honestly think that the version where we flipped the split was more accurate
Maybe I could use this method to try that..

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 4:24 pm
by HarryTuttle
Ok. I'll let you know, in case I'll upload some new screenshots.

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 5:36 pm
by HarryTuttle
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.

Re: Quad rendering bug

PostPosted: Sat Apr 08, 2017 5:44 pm
by Ian
Yeah, well increase the vertex count is a good approximation
But the hardware is doing something else ..

Re: Quad rendering bug

PostPosted: Sun Apr 09, 2017 11:03 am
by HarryTuttle
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.