opengl es - Thick 3D textured lines with constant screen width -
i'm trying draw 3d textured lines constant screen width. (opengl es 2.0)
in reality wanted have simple "volumetric" lines minimum guaranteed (clamped) screen width. when far away don't become thin.
any input on how there appreciated but have feedback on problem i'm facing right now. misunderstanding of how perspective correct interpolation works...
so have triangle strip this:
struct tvtx { vec3 mpos; vec3 mdir; vec2 mtexcoord; }; auto vtxs = std::vector< tvtx >{ { vec3{ -1,0,0 }, vec3{ 1,0,0 }, vec2{ -1, 1 } }, { vec3{ -1,0,0 }, vec3{ 1,0,0 }, vec2{ -1, -1 } }, { vec3{ -1,0,0 }, vec3{ 1,0,0 }, vec2{ 0, 1 } }, { vec3{ -1,0,0 }, vec3{ 1,0,0 }, vec2{ 0, -1 } }, { vec3{ 1,0,0 }, vec3{ 1,0,0 }, vec2{ 0, 1 } }, { vec3{ 1,0,0 }, vec3{ 1,0,0 }, vec2{ 0, -1 } }, { vec3{ 1,0,0 }, vec3{ 1,0,0 }, vec2{ 1, 1 } }, { vec3{ 1,0,0 }, vec3{ 1,0,0 }, vec2{ 1, -1 } } };
and transform in "world" space this:
pt1 = vec3{ -0.450794667, 0.454502404,-0.437951744 }; pt2 = vec3{ -0.248224616,0.682369053, -0.886776387 }; auto center = ( pt1 + pt2 ) * 0.5f; auto right = normalize( pt2 - pt1 ); auto = normalize( cross( vec3( 0,0,1 ), right ) ); auto forw = cross( right, ); auto mtx = mat4{ vec4( right, 0.0 ), vec4( up, 0.0 ), vec4( forw, 0.0 ), vec4( center, 1.0f ) };
my vertex shader like:
attribute vec3 apos; attribute vec3 adir; attribute vec2 atexcoord; uniform mat4 umvpmtx; uniform vec2 uscreenextent; // half size of screen uniform vec2 uinflate; // amount of line "grow" in pixels varying mediump vec2 vtexcoord; void main() { vec4 clippos1 = umvpmtx * vec4( apos, 1.0 ); // point on "direction" line, transform in screen , screen space direction vector // don't know how transform direction vector world screen space, naive way not work ( mvp * vec4( adir, 0.0 ) ) vec4 clippos2 = umvpmtx * vec4( apos + adir * 1000.0, 1.0 ); vec2 ndc1 = vec2( clippos1 ) / clippos1.w; vec2 ndc2 = vec2( clippos2 ) / clippos2.w; vec2 sc1 = ndc1 * uscreenextent; vec2 sc2 = ndc2 * uscreenextent; vec2 dir = normalize( sc2 - sc1 ) * sign( clippos1.w * clippos2.w ); // reduce damage if points lie on opposite sides of origin vec2 perp = vec2( -dir.y, dir.x ); vec2 sc = sc1 + dir * atexcoord.x * uinflate.x + perp * atexcoord.y * uinflate.y; vtexcoord = atexcoord; // bring clip space gl_position = vec4( sc / uscreenextent * clippos1.w, clippos1.zw ); }
fragment shader like:
varying mediump vec2 vtexcoord; void main() { mediump float dist = clamp( length( vtexcoord ), 0.0, 1.0 ); gl_fragcolor = vec4( mix( vec3( 1.0, 0.25, 0.25 ), vec3( 0.25, 1.0, 0.25 ), dist ), 1.0 ); }
notice atexcoord go -1 1!
what like:
the above picture has uinflate.x = 0, not have round caps...
what quad centered red line, fading green. because way alter x , y coordinates in screen space without touching z , w components gives triangles not co-planar anymore? have hard time visualizing this...
update
triangles co-planar in eye space size quite different (in eye space). looks quad on screen not quad anymore in eye space. guess main problem (because of perspective correct interpolation ??). question remains: how draw 3d textured lines constant (or controlled) screen width. 3d mean lines depth tested other 3d content.
Comments
Post a Comment