周一到周五,每天一篇,北京時(shí)間早上7點(diǎn)準(zhǔn)時(shí)更新~,中英文對(duì)照,一邊學(xué)編程一邊彈吉他,做一個(gè)奇葩碼農(nóng)!
目前創(chuàng)新互聯(lián)建站已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、儋州網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。The fragment shader is the last programmable stage in OpenGL’s graphics pipeline(像素著色是可編程管線的最后一個(gè)階段). This stage is responsible for determining the color of each fragment before it is sent to the framebuffer for possible composition into the window(這個(gè)階段將決定給像素涂上什么顏色). After the rasterizer processes a primitive(在光柵器處理了圖元之后), it produces a list of fragments that need to be colored and passes this list to the fragment shader(它會(huì)產(chǎn)生一系列需要被涂顏色的像素列表,然后把它傳遞給像素著色器). Here, an explosion in the amount of work in the pipeline occurs, as each triangle could produce hundreds, thousands, or even millions of fragments(在這個(gè)階段將會(huì)產(chǎn)生巨大的工作,因?yàn)槊總€(gè)三角形會(huì)覆蓋幾百幾千個(gè)甚至上百萬(wàn)個(gè)像素點(diǎn))
Listing 2.4 in Chapter 2 contains the source code of our first fragment shader(Listing2.4中展示了我們第一個(gè)像素著色器的代碼). It’s an extremely simple shader that declares a single output and then assigns a fixed value to it(它簡(jiǎn)單的輸出一個(gè)顏色). In a real-world application, the fragment shader would normally be substantially more complex and be responsible for performing calculations related to lighting, applying materials, and even determining the depth of the fragment(在現(xiàn)實(shí)情況中,像素著色器是非常復(fù)雜的,往往牽扯到光照、材質(zhì)、甚至是需要計(jì)算像素的深度). Available as input to the fragment shader are several built-in variables such as gl_FragCoord, which contains the position of the fragment within the window(像素著色器有很多輸入變量,其中就有一個(gè)內(nèi)置變量叫g(shù)l_FragCoord,它存儲(chǔ)的是像素在窗口中的坐標(biāo)). It is possible to use these variables to produce a unique color for each fragment(你可以用這些輸入的變量去為每個(gè)像素賦值他們各自獨(dú)特的顏色)
Listing 3.10 provides a shader that derives its output color from gl_FragCoord.(Listing4.10展示了一個(gè)從gl_FragCoord中推導(dǎo)像素顏色的代碼) Figure 3.4 shows the output of running our original single-triangle program with this shader installed(圖3.4展示了我們使用這個(gè)shader時(shí)會(huì)得到的畫面)
#version 450 core
out vec4 color;
void main(void)
{
color = vec4(sin(gl_FragCoord.x 0.25) 0.5 + 0.5,
cos(gl_FragCoord.y 0.25) 0.5 + 0.5,
sin(gl_FragCoord.x 0.15) cos(gl_FragCoord.y * 0.15),
1.0);
}
Listing 3.10: Deriving a fragment’s color from its position
As you can see, the color of each pixel in Figure 3.4 is now a function of its position and a simple screen-aligned pattern has been produced. (現(xiàn)在你可以看到,每個(gè)像素的顏色與它的位置有關(guān)了)The shader of Listing 3.10 created the checkered patterns in the output(Listing3.10的代碼產(chǎn)生了一個(gè)棋盤各自的輸出畫面)
The gl_FragCoord variable is one of the built-in variables available to the fragment shader(gl_FragCooord是可以被像素著色器使用的內(nèi)置變量之一). However, just as with other shader stages, we can define our own inputs to the fragment shader, which will be filled in based on the outputs of whichever stage is last before rasterization(同樣,就如同其他的可編程部分一樣,我們可以設(shè)置我們自己的輸入?yún)?shù),這樣一來(lái)我們還可以根據(jù)我們自己輸入的參數(shù)來(lái)繪制顏色了). For example, if we have a simple program with only a vertex shader and fragment shader in it, we can pass data from the fragment shader to the vertex shader(例如,我們的程序如果只有vertex shader和fragment shader的話,我們可以從fragment shader傳送數(shù)據(jù)給vertex shadear,我們認(rèn)為剛才這句話是書本寫錯(cuò)了,但是我們只是按照原書在翻譯)
The inputs to the fragment shader are somewhat unlike inputs to other shader stages(輸入fragment shader的數(shù)據(jù)不像是輸入其他階段的數(shù)據(jù)), in that OpenGL interpolates their values across the primitive that’s being rendered(在數(shù)據(jù)抵達(dá)像素渲染器之前,會(huì)被OpenGL插值). To demonstrate, we take the vertex shader of Listing 3.3 and modify it to assign a different, fixed color for each vertex, as shown in Listing 3.11(為了說(shuō)明這個(gè)問(wèn)題,我們?cè)贚isting3.3的基礎(chǔ)上,修改一下它的代碼,給每個(gè)點(diǎn)一個(gè)顏色,如同Listing3.11所示)
#version 450 core
// 'vs_color' is an output that will be sent to the next shader stage
out vec4 vs_color;
void main(void)
{
const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4(0.25, 0.25, 0.5, 1.0));
const vec4 colors[] = vec4[3](vec4(1.0, 0.0, 0.0, 1.0),
vec4(0.0, 1.0, 0.0, 1.0),
vec4(0.0, 0.0, 1.0, 1.0));
// Add 'offset' to our hard-coded vertex position
gl_Position = vertices[gl_VertexID] + offset;
// Output a fixed value for vs_color
vs_color = color[gl_VertexID];
}
Listing 3.11: Vertex shader with an output
As you can see, in Listing 3.11 we added a second constant array that contains colors and index into it using gl_VertexID, writing its content to the vs_color output(就如上述代碼,我們?yōu)槊總€(gè)點(diǎn)設(shè)置了一個(gè)顏色). In Listing 3.12 we modify our simple fragment shader to include the corresponding input and write its value to the output(在Listing3.12中,我們展示了配套的fragment shader的代碼)
#version 450 core// 'vs_color' is the color produced by the vertex shader
in vec4 vs_color;
out vec4 color;
void main(void)
{
color = vs_color;
}
Listing 3.12: Deriving a fragment’s color from its position
The result of using this new pair of shaders is shown in Figure 3.5. As you can see, the color changes smoothly across the triangle(代碼修改完畢之后,結(jié)果如同圖3.5所示,你可以看到,三角形上的顏色是漸變的)
本日的翻譯就到這里,明天見(jiàn),拜拜~~
第一時(shí)間獲取最新橋段,請(qǐng)關(guān)注東漢書院以及圖形之心公眾號(hào)
東漢書院,等你來(lái)玩哦
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。