溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

發(fā)布時(shí)間:2022-02-14 09:49:42 來源:億速云 閱讀:235 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要介紹了OpenGL Shader如何實(shí)現(xiàn)光照發(fā)光體特效,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

內(nèi)發(fā)光原理

內(nèi)發(fā)光原理簡(jiǎn)單概況是:采樣周邊像素alpha取平均值疊加效果。概括來說似乎好像特別簡(jiǎn)單,但需要一定的理解和消化。發(fā)光物體可以當(dāng)做是一個(gè)圓形對(duì)象,去采集圓形對(duì)象周邊像素值。例如已知圓形半徑是R,角度是Angle,然后根據(jù)半徑和角度推導(dǎo)算出當(dāng)前像素坐標(biāo)位置,用當(dāng)前像素坐標(biāo)位置得到透明度再去做計(jì)算。

但其實(shí)在陰影遮罩效果中似乎已經(jīng)介紹過了同樣能夠通過。不同點(diǎn)在于陰影遮蓋是利用圓形繪制向外部暈染而內(nèi)發(fā)光效果是作用于內(nèi)部。

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

發(fā)光體實(shí)現(xiàn)

首先采用繪制圓的方法實(shí)現(xiàn)RGB疊加。可以看到中心位置繪制圓的位置顏色較深,向外擴(kuò)散顏色逐漸暗淡。效果雖然不對(duì)但已經(jīng)知道下一步該怎么實(shí)現(xiàn)了。

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.);
}

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

通過取反操作,可用一個(gè)數(shù)除以length(uv)再相乘一個(gè)小數(shù)來稍微減小值的大小。從最終結(jié)果可以看到所期望的效果。對(duì)比之前效果展示相除相當(dāng)于對(duì)原結(jié)果取反,原先內(nèi)部是數(shù)值最小,相除之后內(nèi)部數(shù)值變成最大。

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.);
}

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

但過渡效果泛白范圍似乎過大了一些繼續(xù)對(duì)原算法進(jìn)行優(yōu)化。增加pow方法將數(shù)值變得更小一些。

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.);
}

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

擴(kuò)展效果

小太陽(yáng)

改變發(fā)光位置和發(fā)光顏色模擬實(shí)現(xiàn)太陽(yáng)光照的效果。

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.);
}

OpenGL?Shader如何實(shí)現(xiàn)光照發(fā)光體特效

光源移動(dòng)效果

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如何實(shí)現(xiàn)光照發(fā)光體特效

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“OpenGL Shader如何實(shí)現(xiàn)光照發(fā)光體特效”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI