1. 程式人生 > >【OpenGL ES】片段著色器

【OpenGL ES】片段著色器

1、管線

片段著色器在OpenGL ES 3.0的可程式設計管線的位置如下圖所示。
這裡寫圖片描述

2、輸入輸出

片段著色器為片段操作提供了通用功能的可程式設計方法,輸入和輸出如下圖所示。
這裡寫圖片描述

輸入或者可變值,in,是頂點著色器生成的插值資料,頂點著色器輸出跨圖元進行插值,並作為輸入傳遞給片段著色器。
統一變數,uniform,是片段著色器使用的狀態,為常量值,在每個片段上不會變化。
取樣器,sampler2D,用於訪問著色器中的紋理物件。
輸入,還包括程式碼,即片段著色器原始碼或者二進位制程式碼,描述在片段上執行的操作。
輸出,是一個或多個片段顏色,傳遞到管線的逐片段操作部分,輸出顏色的數量取決於使用了多少個顏色附著。

3、內建特殊變數

片段著色器中可用的內建特殊變數包括gl_FragCoord、gl_FrontFacing、gl_PointCoord、gl_FragDepth。
gl_FragCoord,只讀,儲存片段的相對視窗座標(x, y, z, 1/w)。例如,用於較少陰影貼圖鋸齒失真的技術,可以使用視窗座標作為某個隨機噪聲貼圖紋理讀取的偏移量,噪聲貼圖的值用於旋轉陰影貼圖的過濾核心。
gl_FrontFacing,只讀,片段屬於圖元的正面時為ture,否則為false。
gl_PointCoord,只讀,儲存點的紋理座標,在點的光柵化階段自動生成,處於[0, 1]區間內。
gl_FragDepth,只寫,覆蓋片段的固定功能深度值。這個功能可能禁用許多GPU的深度優化,應該謹慎使用,因為許多GPU有所謂的Early-Z功能,在執行片斷著色器之前進行深度測試,這樣不能通過深度測試的片段永遠不會被著色,從而保護了效能,所以使用gl_FragDepth時,必須禁用Early-Z功能。

4、內建常量

片段著色器相關的內建常量如下,每個內建常量所指定的值是所有OpenGL ES 3.0實現必須支援的最小值。

const mediump int glMaxFragmentInputVectors = 15;
const mediump int glMaxTextureImageUnits = 16;
const mediump int glMaxFragmentUniformVectors = 224;
const mediump int glMaxDrawBuffers = 4;
const mediump int glMinProgramTexelOffset = -8
; const mediump int glMaxProgramTexelOffset = 7;

5、精度限定符

精度限定符,在頂點著色器和片段著色器中不同,片段著色器中沒有預設精度,每個片斷著色器必須宣告一個預設精度或者對所有變數宣告提供精度限定符。

6、多重紋理

#version 300 es
precision mediump float;
in vec2 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform sampler2D s_baseMap;
uniform sampler2D s_lightMap;
void main()
{
    vec4 baseColor;
    vec4 lightColor;
    baseColor = texture( s_baseMap, v_texCoord );
    lightColor = texture( s_lightMap, v_texCoord );
    outColor = baseColor * (lightColor + 0.25);
}

這裡使用了兩個取樣器,每個紋理使用一個,它們共用一個紋理座標,在典型的紋理貼圖照明中,基本貼圖和照明貼圖應該有一組單獨的紋理座標,照明貼圖通常混合到單一的大型紋理中,紋理座標可以使用離線工具生成。例子中,載入了一個基本紋理貼圖和照明紋理貼圖,這兩個紋理貼圖以及最後的兩重紋理效果如下圖。
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

7、霧化

霧化,是渲染3D場景的一種常用技術,可以用於減小繪圖距離,並且清除靠近觀看者的幾何體的突現現象。霧化的計算有幾種可能的方式,使用可程式設計片段著色器,就不必侷限於任何特定的方程式。要計算任何型別的霧化,需要兩個輸入,畫素到眼睛的距離以及霧化的顏色。要計算線性霧化,還需要霧化所覆蓋的最小和最大距離範圍。線性霧化因子方程式為(最大距離-眼睛距離)/(最大距離-最小距離)。計算一個線性霧化因子,用於乘以霧化顏色,這個顏色限制在[0.0, 1.0]的區間內,然後和片段的總體顏色進行線性插值,以算出最終的顏色。到眼睛的距離最好在頂點著色器中算出,然後用可變變數進行跨圖元插值。下面例子的頂點著色器計算了到眼睛的距離。

#version 300
uniform mat4 u_matViewProjection;
uniform mat4 u_matView;
uniform vec4 u_eyePos;
in vec4 a_vertex;
in vec2 a_texCoord0;
out vec2 v_texCoord;
out float v_eyeDist;
void main( void )
{
    // Transform vertex to view-space
    vec4 vViewPos = u_matView * a_vertex;
    // Compute the distance to eye
    v_eyeDist = sqrt( (vViewPos.x - u_eyePos.x) *
                      (vViewPos.x - u_eyePos.x) +
                      (vViewPos.y - u_eyePos.y) *
                      (vViewPos.y - u_eyePos.y) +
                      (vViewPos.z - u_eyePos.z) *
                      (vViewPos.z - u_eyePos.z) );                      
    gl_Position = u_matViewProjection * a_vertex;
    v_texCoord  = a_texCoord0.xy;
}

下面例子的片段著色器渲染了線性霧化。

#version 300
precision mediump float;
uniform vec4 u_fogColor;
uniform float u_fogMaxDist;
uniform float u_fogMinDist;
uniform sampler2D baseMap;
in vec2 v_texCoord;
in float v_eyeDist;
layout( location = 0 ) out vec4 outColor;
float computeLinearFogFactor()
{
   float factor;
   // Compute linear fog equation
   factor = (u_fogMaxDist - v_eyeDist) /
            (u_fogMaxDist - u_fogMinDist );   
   // Clamp in the [0,1] range
   factor = clamp( factor, 0.0, 1.0 );           
   return factor;            
}
void main( void )
{
    float fogFactor = computeLinearFogFactor();
    vec4 baseColor = texture( baseMap, v_texCoord );   
    // Compute final color as a lerp with fog factor
    outColor = baseColor * fogFactor + 
               u_fogColor * (1.0 - fogFactor); 
}

線性霧化效果圖如下。
這裡寫圖片描述

8、Alpha測試

Alpha測試,是傳統的固定功能管線中的功能,在OpenGL ES 3.0中不存在,不過可以使用discard關鍵字實現相同的效果。下面是通過著色器實現Alpha測試功能的例子。

#version 300
uniform mat4 u_matViewProjection;
in vec4 a_vertex;
in vec2 a_texCoord0;
out vec2 v_texCoord;
void main( void )
{
    gl_Position = u_matViewProjection * a_vertex;
    v_texCoord = a_texCoord0.xy;
}

#version 300
precision mediump float;
uniform sampler2D baseMap;
in vec2 v_texCoord;
layout( location = 0 ) out vec4 outColor;
void main( void )
{
   vec4 baseColor = texture( baseMap, v_texCoord );
   if( baseColor.a < 0.25 )
   {
      discard;
   }
   else
   {
      outColor = baseColor;
   }
}

Alpha測試的效果圖如下。
這裡寫圖片描述

9、使用者裁剪平面

一般情況下,所有圖元根據組成視錐的六個平面進行裁剪,但是,使用者有時候可能想要根據一個或者多個額外的使用者裁剪平面進行裁剪。例如,渲染反射時,需要根據反射平面翻轉幾何形狀,然後將其渲染到螢幕外紋理中,在渲染到紋理時,需要根據反射平面裁剪幾何形狀,這就需要使用者裁剪平面。下面的例子用到了使用者裁剪平面,以及效果圖如下所示。

#version 300
uniform vec4 u_clipPlane;
uniform mat4 u_matViewProjection;
in vec4 a_vertex;
out float v_clipDist;
void main( void )
{
    // Compute the distance between the vertex and
    // the clip plane
    v_clipDist = dot( a_vertex.xyz, u_clipPlane.xyz ) + 
                 u_clipPlane.w;
    gl_Position = u_matViewProjection * a_vertex;
}

#version 300
precision mediump float;
in float v_clipDist;
layout( location = 0 ) out vec4 outColor;
void main( void )
{
    // Reject fragments behind the clip plane
    if( v_clipDist < 0.0 )
       discard;
    outColor = vec4( 0.5, 0.5, 1.0, 0.0 );    
}

這裡寫圖片描述

相關推薦

OpenGL ES片段著色

1、管線 片段著色器在OpenGL ES 3.0的可程式設計管線的位置如下圖所示。 2、輸入輸出 片段著色器為片段操作提供了通用功能的可程式設計方法,輸入和輸出如下圖所示。 輸入或者可變值,in,是頂點著色器生成的插值資料,頂點著色器輸出跨圖元進

OpenGL ES頂點著色

1、輸入輸出 頂點著色器可用於傳統的基於頂點操作,例如通過矩陣變換位置、計算照明方程式以生成逐頂點的顏色以及生成或者變換紋理座標。頂點著色器的輸入、輸出如下圖所示。 輸入變數或屬性:用頂點陣列提供的逐頂點資料。 統一變數和統一變數緩衝區:頂點著色器使用

OpenGL ES著色Shader與程式Program

在OpenGL ES 3程式中,Shader和Program是兩個重要的概念,至少需要建立一個頂點Shader物件、一個片段Shader物件和一個Program物件,才能用著色器進行渲染,理解Shader物件和Program物件的最佳方式是將它們比作C語言的編譯

OpenGL ES幀緩衝區物件FBO

1、FBO 使用OpenGL ES,一般要通過EGL來配置本地視窗系統,關於EGL的介紹可參照“【OpenGL ES】EGL簡介”http://blog.csdn.net/ieearth/article/details/71180457。預設情況下,OpenG

OpenGL ES頂點緩衝區物件VBO與頂點陣列物件VAO

頂點屬性即頂點資料,可以通過頂點陣列逐頂點指定,也可以為所有頂點指定一個常量,所有OpenGL ES 3.0實現必須支援至少16個頂點屬性,應用程式可以通過glGetIntegerv查詢GL_MAX_VERTEX_ATTRIBS得到支援的最大定點屬性個數。

OpenGL ES 2.0 著色語言

OpenGL 著色器中使用的是著色語言GLSL。著色語言源自C語言,提供了豐富的原生型別,如向量、矩陣等,還有大量的內建函式,這在處理3D圖形時可以更加高效、易用。下面是整理的是OpenGL ES2.0的GLSL語言。 基本資料型別 標量 GLSL中的

OpenGL ES紋理

1、2D紋理 2D紋理是OpenGL ES中最基本和最常用的紋理形式,它是一個影象資料的二維陣列,紋理座標(s, t)或(u, v)用作紋理影象中的索引,代表用於查詢一個紋理貼圖的規範化座標。紋理影象的左下角由st座標(0.0, 0.0)指定,右上角由座標(1

OpenGL ES 3.0 簡單的頂點和片段著色

char fShaderStr[] = 1、 "#version 300 es \n" 2、 "precision mediump float; \n" 3、 "out vec4 fragColor;

Unity Shader學習筆記(二)最基本的頂點片段著色

分享一個基本的頂點片段著色器,可以實現紋理取樣。目前沒有加入光照和陰影效果。 這個Shader可以作為基本的模板,進行更加細節的修改與開發。這裡就簡單分享一下吧。 Shader "Unlit/unl

UnityShader自學日誌透明著色

新建一個Standard Surface Shader,將其命名為Glass 1、開啟Glass,將其名稱改為"PACKT/Glass" 2、在Subshader下面,找到Tags一行,將Opaque改為Transparent(即從“不透明”改為“透明”) 3、找到著色

OpenGL ES 2.0如何顯示出非2的N次冪的貼圖。(NPOT)

在繫結紋理後,新增下面四行程式碼 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(G

OpenGL中,頂點著色的輸出是如何傳遞到片段著色的?

我正在學習OpenGL,基本已理解管線原理,但是有一個問題一直沒明白:我們知道頂點著色器可以傳遞變數到片段著色器,然而片段著色器和頂點著色器並不是1:1呼叫的。比如一個三角形有三個頂點,呼叫三次頂點著色器,三角形光柵話後會有很多的片段(插值的結果),每個片段都會呼叫一次片段著色器。那麼問題來了,片段著色器的輸

Learn OpenGL(四)——片段著色(Fragment Shader)

片段著色器(Fragment Shader)        片段著色器是第二個也是最終我們打算建立的用於渲染三角形的著色器。 片段著色器的全部, 都是用來計算你的畫素的最後顏色輸出。 為了讓事情比較簡

.netcore基礎MVC制Controller依賴註入

singleton RF rec clas dmv ted ace tco return 廢話少說,直接上代碼 首先我們得有一個接口類和一個實現類,方便後面註入MVC裏 接口類 public interface IWeatherProvider {

UOJ386UNR #3鴿子固定 鏈表

\n class 次方 print 維護 刪掉 sca clu reverse 題目描述   有 \(n\) 個物品,每個物品有兩個屬性:權值 \(v\) 和大小 \(s\)。   你要選出 \(m\) 個物品,使得你選出的物品的權值的和的 \(d_v\) 減掉大小的極差的

python開發函數:裝飾的誕生

inner 調用 pri 不一致 foo 實現 int 功能 運行 計算函數的運行時間 import time def bar(): print("in the bar") time.sleep(2) def foo(func): start_ti

android平臺下OpenGL ES 3.0著色語言基礎知識(下)

OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E

lris.commons檔案讀取FileContentGetter的實現

FileContentGetter是原xqq.commons中用於檔案讀取的一個類,其中集成了一些通用的對錶格檔案或者文字檔案的讀取方法。 最早應用在單位上班時的drp專案中,其中的一些方法也使用了drp.commons.util中的工具。之後xuqiaoqiao.cc專案,ss18專案,lina專案,畢業

Unity shader之頂點和片段著色Vertex and Fragment Shader

Unity shader中的頂點片面著色器是我們專案中使用次數最多的著色器,因此今天來簡單的學習一下VF Shader。 VF Shader的基本寫法如下: // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with

jzoj3658. NOI2014模擬文字編輯(editor)

題目描述 Description Input Output 對於每個詢問輸出一個字元表示答案。 Sample Input 9 I 0 o I 0 r I 0 z R 1 3 Q 1 D 1 1 Q 1 C 2 2 0 Q 1 Sample Output or