我使用单个Quad和片段着色器在WebGL
中绘制圆/椭圆,以便以独立于分辨率的方式绘制它们(边缘距离抗锯齿)
目前我的片段着色器是:
'#extension GL_OES_standard_derivatives : enable',
'precision mediump float;',
'varying vec2 coord;',
'vec4 circleColor = vec4(1.0, 0.5, 0.0, 1.0);',
'vec4 outlineColor = vec4(0.0, 0.0, 0.0, 1.0);',
'uniform float strokeWidth;',
'float outerEdgeCenter = 0.5 - strokeWidth;',
'void main(void){',
'float dx = 0.5 - coord.x;',
'float dy = 0.5 - coord.y;',
'float distance = sqrt(dx*dx + dy*dy);',
'float delta = fwidth(distance);',
'float alpha = 1.0 - smoothstep(0.45 - delta, 0.45, distance);',
'float stroke = 1.0 - smoothstep(outerEdgeCenter - delta, outerEdgeCenter + delta, distance);',
'gl_FragColor = vec4( mix(outlineColor.rgb, circleColor.rgb, stroke), alpha );',
'}'
这会创建一个带有黑色轮廓的橙色圆圈,无论大小如何,它都是完全抗锯齿的。
然而,只要我变换四边形(缩放它)以将圆形变成椭圆形,distance
计算就会随之变换,从而使轮廓也可以缩放。我的理解是,我会以某种方式需要通过反转它来解释四边形的变换。
我想要的是distance
即使变换四边形也能保持均匀,实际上在整个圆/椭圆周围产生一个恒定的宽度轮廓。
非常感谢任何帮助。
答案 0 :(得分:1)
问题是,你的片段着色器(FS)现在是一种黑盒子(因为代码缺乏信息)。
你的FS写在方形空间内工作。因此,它始终在x
和y
大小相同的空间中呈现圆圈(-1.0; 1.0间隔)。
虽然quad被转换到外部(在VS或其他任何地方),但是还没有办法如何在FS中反映这种转换。
为了解决这个问题,我建议将有关扩展的其他信息推送到FS。类似Shadertoy的内容在着色器输入中提供:
uniform vec3 iResolution; // viewport resolution (in pixels)
除了这不是屏幕尺寸的分辨率,而是关于四次变换的信息,所以类似:
varying vec2 trans;
// where value (1.0, 1.0) mean no transformation
然后您可以使用此值来计算不同的笔画。我宁愿为它计算唯一的dx和dy值,而不是反转当前笔划的变换。
有更多方法可以实现工作解决方案,这取决于您以后如何使用它(应该可以进行哪种转换等)。所以我只提出基本但最简单的解决方案。