unity-game-enginescalehlslgeometry-shader

Scaling seperate triangles (in geometry shader?)


For a masking object, I am trying to scale each triangle individually. If I scale the object as a whole, the points further away from the center will get moved too far and I just want the object to have 'more body'. Since I use it as a mask, it doesn't matter if the triangles end up overlapping.

Although looking at this might hurt someone deep inside, this is actually what I'm trying to achieve: Example scaling 2 triangles in single mesh

I thought this was best done in a shader and I thought this could be achieved in the geometry shader since I need to know the center of the triangle. I came up with the code below, but things keep acting... strange.

                float3 center = (IN[0].vertex.xyz + IN[1].vertex.xyz + IN[2].vertex.xyz) / 3;


                for (int i = 0; i < 3; i++)
                {
                    float3 distance = IN[i].vertex.xyz - center.xyz;
                    float3 normal = normalize(distance);
                    distance = abs(distance);
                    float scale = 1;
                    float3 pos = IN[i].vertex.xyz + (distance * normal.xyz * (scale - 1));
                    o.pos.xyz = pos.xyz;
                    o.pos.w = IN[i].vertex.w;
                    tristream.Append(o);
                }

My plan was to calculate the center of the triangle and than calculate the distance between the center and each point. I would than take the normal of this distance to know in which direction I would have to move the vertex and change the position by adding the distance * normal(direction) * scale to the original position of the vertex. Yet, it seems the triangles change when you rotate the camera, so I would doubt it if this is right. Does anyone know what could be wrong?

(Just some notes: the mesh is basically 2D, only changing across the x- and z-axis (if this matters). I did abs(distance) since I thought it would cancel out the normal if both would be negative. I'm not sure if this is necessary. I did scale -1 since a scale of 1 would result in the mesh staying the same. A scale of 2 should result in all triangles being twice as big. I have no clue on what to do with the w value, but keeping the old value at least doesn't screw up that much. Perhaps here lays the problem? I thought this value should always be 1 for matrix multiplications. )


Solution

  • Oke, so besides using a way to 'complex' formula to calculate the new position of each point. (Better way at https://math.stackexchange.com/questions/1563249/how-do-i-scale-a-triangle-given-its-cartesian-cooordinates). I found out that it somehow indeed had to do with the w-value. As I always thought this was mainly a helper variable, it would be awesome if someone could explain how that values screwed things over.

    Anyways, including that value in the equation it works fine.

    
                    float4 center = (IN[0].vertex.xyzw + IN[1].vertex.xyzw + IN[2].vertex.xyzw) / 3;
    
                    for (int i = 0; i < 3; i++)
                    {
                        float scale = 2;
                        float4 pos = (IN[i].vertex.xyzw * scale) - center.xyzw;
                        o.pos.xyzw = pos.xyzw;
                        tristream.Append(o);
                    }
    

    This works just fine :)