Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This partly continues my previous answer, but is actually quite different since I got a couple of central things wrong in that answer.</p> <p>To allow the fragment shader to only shade between two curves, two sets of "texture" coordinates are supplied as varying variables, to which the technique of Loop-Blinn is applied.</p> <pre><code>varying vec2 texCoord1,texCoord2; varying float insideOutside; varying vec4 col; void main() { float f1 = texCoord1[0] * texCoord1[0] - texCoord1[1]; float f2 = texCoord2[0] * texCoord2[0] - texCoord2[1]; float alpha = (sign(insideOutside*f1) + 1) * (sign(-insideOutside*f2) + 1) * 0.25; gl_FragColor = vec4(col.rgb, col.a * alpha); } </code></pre> <p>So far, easy. The hard part is setting up the texture coordinates in the geometry shader. Loop-Blinn specifies them for the three vertices of the control triangle, and they are interpolated appropriately across the triangle. But, here we need to have the same interpolated values available while actually rendering a different triangle.</p> <p>The solution to this is to find the linear function mapping from (x,y) coordinates to the interpolated/extrapolated values. Then, these values can be set for each vertex while rendering a triangle. Here's the key part of my code for this part.</p> <pre><code> vec2[3] tex = vec2[3]( vec2(0,0), vec2(0.5,0), vec2(1,1) ); mat3 uvmat; uvmat[0] = vec3(pos2[0].x, pos2[1].x, pos2[2].x); uvmat[1] = vec3(pos2[0].y, pos2[1].y, pos2[2].y); uvmat[2] = vec3(1, 1, 1); mat3 uvInv = inverse(transpose(uvmat)); vec3 uCoeffs = vec3(tex[0][0],tex[1][0],tex[2][0]) * uvInv; vec3 vCoeffs = vec3(tex[0][1],tex[1][1],tex[2][1]) * uvInv; float[3] uOther, vOther; for(i=0; i&lt;3; i++) { uOther[i] = dot(uCoeffs,vec3(pos1[i].xy,1)); vOther[i] = dot(vCoeffs,vec3(pos1[i].xy,1)); } insideOutside = 1; for(i=0; i&lt; gl_VerticesIn; i++){ gl_Position = gl_ModelViewProjectionMatrix * pos1[i]; texCoord1 = tex[i]; texCoord2 = vec2(uOther[i], vOther[i]); EmitVertex(); } EndPrimitive(); </code></pre> <p>Here pos1 and pos2 contain the coordinates of the two control triangles. This part renders the triangle defined by pos1, but with texCoord2 set to the translated values from the pos2 triangle. Then the pos2 triangle needs to be rendered, similarly. Then the gap between these two triangles at each end needs to filled, with both sets of coordinates translated appropriately. </p> <p>The calculation of the matrix inverse requires either GLSL 1.50 or it needs to be coded manually. It would be better to solve the equation for the translation without calculating the inverse. Either way, I don't expect this part to be particularly fast in the geometry shader.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload