首頁 > 軟體

OpenGL Shader實現光照發光體特效

2022-02-11 22:00:19

內發光原理

內發光原理簡單概況是:取樣周邊畫素alpha取平均值疊加效果。概括來說似乎好像特別簡單,但需要一定的理解和消化。發光物體可以當做是一個圓形物件,去採集圓形物件周邊畫素值。例如已知圓形半徑是R,角度是Angle,然後根據半徑和角度推導算出當前畫素座標位置,用當前畫素座標位置得到透明度再去做計算。

但其實在陰影遮罩效果中似乎已經介紹過了同樣能夠通過。不同點在於陰影遮蓋是利用圓形繪製向外部暈染而內發光效果是作用於內部。

發光體實現

首先採用繪製圓的方法實現RGB疊加。可以看到中心位置繪製圓的位置顏色較深,向外擴散顏色逐漸暗淡。效果雖然不對但已經知道下一步該怎麼實現了。

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5;
    uv.x *= iResolution.x/iResolution.y; 
    vec3 color = vec3(0.);
    float glow = length(uv);
    color += glow;
    gl_FragColor = vec4(color,1.);
}

通過取反操作,可用一個數除以length(uv)再相乘一個小數來稍微減小值的大小。從最終結果可以看到所期望的效果。對比之前效果展示相除相當於對原結果取反,原先內部是數值最小,相除之後內部數值變成最大。

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5;
    uv.x *= iResolution.x/iResolution.y; 
    vec3 color = vec3(0.);
    float glow = 0.05 * 3./length(uv);
    color += glow;
    gl_FragColor = vec4(color,1.);
}

但過渡效果泛白範圍似乎過大了一些繼續對原演演算法進行優化。增加pow方法將數值變得更小一些。

float getGlow(float dist, float radius, float intensity){
    return pow(radius/dist, intensity);
}

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    uv -= 0.5;
    uv.x *= iResolution.x/iResolution.y; 
    vec3 color = vec3(0.);
    float glow = 0.05 * getGlow(length(uv), 1., 2.);
    color += glow;
    gl_FragColor = vec4(color,1.);
}

擴充套件效果

小太陽

改變發光位置和發光顏色模擬實現太陽光照的效果。

float getGlow(float dist, float radius, float intensity){
    return radius/dist;
}

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec3 color = vec3(0.);

    vec2 uv2 = uv;
    uv2 -=1.0;
    float glow = 0.09 * 3./length(uv2);
    color += (5.0 * vec3(0.02 * glow) + vec3(0.9686, 0.6941, 0.0) * glow);
    gl_FragColor = vec4(color,1.);
}

光源移動效果

float getGlow(float dist, float radius, float intensity){
    return radius/dist;
}

void main() {
    vec2 uv = gl_FragCoord.xy / iResolution.xy;
    vec3 color = texture(iChannel1,uv).rgb;

    float position = sin(iTime) / 2.;
    vec2 uv2 = uv;
    uv2 -=0.5;
    uv2.x *= iResolution.x/iResolution.y; 
    uv2 += position;
    float glow = 0.09 * 3./length(uv2);
    color += (5.0 * vec3(0.02 * glow));
    gl_FragColor = vec4(color,1.);
}

以上就是OpenGL Shader實現光照發光體特效的詳細內容,更多關於OpenGL Shader光照發光體的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com