詳解OpenGL Shader抗鋸齒的實現
繪制圓形鋸齒問題
普通繪制圓形形狀時可以看到圖形邊緣會有明顯鋸齒現象並不像真實圓形形狀一樣圓潤邊緣平滑。在glsl
中這種情況是常見情況,這裡是可以借助glsl
內置函數來消除鋸齒現象。
vec3 sdfCircle(vec2 uv,float r,vec3 value){ float d = length(uv) - r; return d > 0. ? vec3(0.3294, 0.3294, 0.9333) : value; // 大於0超出畫圓范圍,小於0在畫圓范圍內 } void main() { vec2 uv = gl_FragCoord.xy / iResolution.xy; uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5> uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5> vec3 circle = sdfCircle(uv,0.4,vec3(1.)); circle = mix(circle,sdfCircle(uv,0.3,vec3(1.)),0.5); circle = mix(circle,sdfCircle(uv,0.2,vec3(1.)),0.7); gl_FragColor = vec4(circle,.9); }
smoothstep函數介紹
smoothstep(a, b, x)
函數結果范圍:
返回值 | 條件 |
---|---|
0 | x<a<b 或 x>a>b |
1 | x<b<a 或 x>b>a |
某個值 | 根據x在[a,b]或[b,a]區間范圍內,返回一個在[0,1]之間的值 |
內置函數smoothstep
就能實現繪制圓形圖形的抗鋸齒效果。可能之前有使用過內置函數step
同樣都是步進式
功能函數,不同於step
函數可以理解為if-else
而smoothstep
函數是平滑過渡的。
抗鋸齒實現
使用smoothstep
實現抗鋸齒功能需要修改一下原先的畫圓公式。原來隻需要使用到length(uv) - r
來判斷是否選擇繪制圓的顏色,而現在需要修改成通過smoothstep(m-0.002,m+0.002,length(uv) - 0.2)
計算值作為mix
函數混合系數值來實現平滑過渡到畫圓色值,這樣就能實現抗鋸齒瞭。
vec2 uv = gl_FragCoord.xy / iResolution.xy; uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5> uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5> float m = 0.2; m = smoothstep(m-0.002,m+0.002,length(uv) - 0.2); vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m); gl_FragColor = vec4(pixel,1.0);
如果把腳本其中m-0.002,m+0.002
把0.002
范圍進行修改。例如修改成0.02
,運行結果可以發現圓形變模糊瞭。這就是區間過大導致平滑區間漸變范圍在肉眼可見范圍瞭,因此設置一個適當過渡區間才能實現較好的抗鋸齒效果。
擴展
清楚實現抗鋸齒原理之後,可以根據需要自行實現一個平滑過渡函數來實現抗鋸齒功能。類似像以下兩個自制平滑過渡函數最終實現效果幾乎看不出太大區別。
自制smoothstep函數抗鋸齒
float smootherstep(float edge0, float edge1, float x) { float t = (x - edge0)/(edge1 - edge0); float t1 = t*t*t*(t*(t*6. - 15.) + 10.); return clamp(t1, 0.0, 1.0); } void main() { vec2 uv = gl_FragCoord.xy / iResolution.xy; uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5> uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5> float m = 0.2; m = smootherstep(m-0.002,m+0.002,length(uv) - 0.2); vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m); gl_FragColor = vec4(pixel,1.0); }
自制linearstep函數抗鋸齒
float linearstep(float edge0, float edge1, float x) { float t = (x - edge0)/(edge1 - edge0); return clamp(t, 0.0, 1.0); } void main(){ vec2 uv = gl_FragCoord.xy / iResolution.xy; uv -= 0.5; // x: <-0.5, 0.5>, y: <-0.5, 0.5> uv.x *= iResolution.x/iResolution.y; // x: <-0.5, 0.5> * aspect ratio, y: <-0.5, 0.5> float m = 0.2; m = linearstep(m-0.002,m+0.002,length(uv) - 0.2); vec3 pixel = mix(vec3(1.),vec3(0.3294, 0.3294, 0.9333),m); gl_FragColor = vec4(pixel,1.0); }
smoothstep
linearstep
以上就是詳解OpenGL Shader抗鋸齒的實現的詳細內容,更多關於OpenGL Shader抗鋸齒的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- OpenGL Shader實現物件材料效果詳解
- OpenGL Shader實現陰影遮罩效果
- 詳解OpenGL Shader彩虹條紋效果的實現
- OpenGL Shader實現光照發光體特效
- OpenGL Shader實現簡單轉場效果詳解