前言
期待您移步上篇:OpenGL筆記十四:GLSL語法
頂點著色器
- 業(yè)務
1.矩陣變換位置
2.計算光照公式?成逐頂點顏?
3.?成/變換紋理坐標
- 總結(jié): 它可以?于執(zhí)??定義計算哮幢,實施新的變換,照明或者傳統(tǒng)的固定功能所不允許的基于頂點的效果。
- 內(nèi)建特殊變量
gl_VertexID
,是一個輸入變量。用于保存頂點的整數(shù)索引衙猪。gl_VertexID 是整數(shù)型變量,用 highp 精度限定修飾符聲明。
gl_InstanceID
堵幽,是一個輸入變量狗超。用于保存實例化繪圖調(diào)用中圖元的實例編號。對于常規(guī)的繪圖調(diào)用谐檀,該值為0抡谐;gl_InstanceID 是整數(shù)型變量,用 highp 精度限定修飾符聲明桐猬。
gl_Position
麦撵,用于輸出頂點位置的裁剪坐標。該值在裁剪和視口變換用于執(zhí)行相應的圖元裁剪以及從裁剪坐標到屏幕坐標的頂點位置轉(zhuǎn)換溃肪。如果頂點著色器位寫入 gl_Position 免胃,則 gl_Position 的值未定義。 gl_Position 是浮點型變量惫撰,用 highp 精度限定修飾符聲明羔沙。
gl_PointSize
,可以寫入像素標識點精靈(即像素點)的尺寸厨钻,在渲染點精靈時使用扼雏。頂點著色器輸出的 gl_PointSize 值被限定在 OpenGL ES 3.0 實現(xiàn)支持的費平滑點大小范圍之內(nèi)。gl_PointSize 是浮點型變量夯膀,用 highp 精度限定修飾符聲明诗充。
gl_FrontFacing
,是一個特殊變量诱建,但不是由頂點著色器直接寫入的蝴蜓,而是根據(jù)頂點著色器生成的位置值和渲染圖元的類型生成的。gl_FrontFacing 是一個布爾值類型俺猿。
在頂點著色器內(nèi)可用的唯一內(nèi)鍵 Uniform 狀態(tài)是窗口坐標中的深度范圍茎匠。這些由內(nèi)建統(tǒng)一變量名 gl_DepthRange
給出。
struct gl_DepthRangeParameters
{
highp float near; //near z
highp float far; //near far
highp float diff; //far - near
}
uniform gl_DepthRangeParameters gl_DepthRange;
- 內(nèi)建常量
const mediump int gl_MaxVertexAttribs = 16;
const mediump int gl_MaxVertexUniformVectors = 256;
const mediump int gl_MaxVertexOutputVectors = 16;
const mediump int gl_MaxVertexTextureImageUnits = 16;
const mediump int gl_MaxCombinedTextureImageUnits = 32;
gl_MaxVertexAttribs
:可以指定得頂點數(shù)據(jù)的最大數(shù)量押袍。
gl_MaxVertexUniformVectors
:頂點著色器可以使用的 vect4 Uniform 變量的最大數(shù)量诵冒。
gl_MaxVertexOutputVectors
:輸出向量的最大數(shù)量。
gl_MaxVertexTextureImageUnits
:頂點著色器可用紋理單元的最大數(shù)量伯病。
gl_MaxCombinedTextureImageUnits
:頂點/片元著色器中的可用紋理單元的最大數(shù)量的總和造烁。
-
矩陣變換
MVP矩陣(模型-視圖-投影矩陣) 頂點著色器的位置輸入保存的是物體坐標,而輸出的坐標保存為剪裁坐標午笛。MVP矩陣是3D圖形中進行這種變化的3個非常重要的變換矩陣的乘積:模型矩陣惭蟋,視圖矩陣和投影矩陣。
組成MVP矩陣的每個單獨矩陣執(zhí)行的變換如下:
- 模型矩陣 -- 將物體坐標變換為世界坐標
- 視圖矩陣 -- 將世界坐標變換為眼睛坐標(觀察坐標)
- 投影矩陣 -- 講眼睛坐標(觀察者坐標)變換為裁剪坐標
片元著色器
- 業(yè)務
1.計算顏?
2.獲取紋理值
3.往像素點中填充顏?值(紋理值/顏?值)
- 總結(jié): 它可以?于圖?/視頻/圖形中每個像素的顏?填充(?如給視頻添加濾鏡药磺,實際上就是將視頻中每個圖?的像素點顏?填充進?修改)告组。
- 內(nèi)建特殊變量
gl_FragCoord
:片元著色器中一個只讀變量,這個變量保存片元的窗口相對坐標癌佩。
gl_FrontFacing
:片元著色器中額的一個只讀變量木缝,為布爾類型變量便锨,正面圖元時為true,否則為false我碟。
gl_PointCoord
:只讀變量放案,可以在渲染點精靈使用,保存點精靈的紋理坐標矫俺,這個坐標在點精靈光柵化期間自動生成吱殉,處于(0,1)區(qū)間。
gl_FragDepth
:一個只寫輸出變量厘托,在片元著色器寫入時友雳,覆蓋片元的固定功能深度值。盡量減少手動實現(xiàn)深度值寫入铅匹。這個功能需要謹慎使用押赊,因為它可能禁用許多GPU的深度優(yōu)化。例如:許多GPU都有"Early -Z"的功能包斑,在執(zhí)行片元著色器之前進行深度測試流礁,使用"Early -Z"的好處就是不能通過深度測試的片元就不會被著色(從而減少了著色器調(diào)用次數(shù),提高性能)罗丰,但是使用 gl_FragDepth 就必須禁用該功能崇棠,因為GPU在執(zhí)行著色器之前不知道深度值。
- 內(nèi)建常量
const mediump int gl_MaxFragmentInputVectors = 15;
const mediump int gl_MaxTextureImageUnits = 16;
const mediump int gl_MaxFragmentUniformVectors = 224;
const mediump int gl_MaxDrawBuffers = 4;
const mediump int gl_MinProgramTexelOffset = -8;
const mediump int gl_MaxProgramTexelOffset = 7;
gl_MaxFragmentInputVectors
:片元著色器輸入的最大數(shù)量
gl_MaxFragmentUniformVectors
:可用紋理圖像單元的最大數(shù)量
gl_MaxFragmentUniformVectors
:片元著色器可用vec4 Uniform變量的最大數(shù)量
gl_MaxDrawBuffers
:多重渲染目標最大支持數(shù)量
- 多個紋理單元渲染
- 1.片元著色器(服務端)代碼:
attribute vec2 v_texCoord;
uniform sampler2D s_baseMap;
uniform sampler2D s_SecondMap;
void main() {
vec4 baseColor;
vec4 secondColor;
baseColor = texture(s_baseMap,v_texCoord);
secondColor = texture(s_SecondMap,v_texCoord);
gl_FragColor = baseColor * secondColor;
}
- 2.客戶端代碼:
//將各個紋理對象綁定到紋理單元0和1,為采樣器設置數(shù) 值,將采集器綁定到對應的紋理單元
glActiveTexutre(GL_TEXTURE0);
glBindTeture(GL_TEXTURE_2D,baseMapTexId);
glUniformli(baseMapTexId,0);
glActiveTexutre(GL_TEXTURE1);
glBindTeture(GL_TEXTURE_2D,secondMapTexId);
glUniformli(secondMapTexId,1);
-
內(nèi)建函數(shù)
常?內(nèi)建函數(shù):
dot :點乘
cross :叉乘
texture2D :?于對紋理采樣
normalize :對?個向量規(guī)格化
clamp :將?個向量固定在?個最?值和最?值之間
光照特性
- 發(fā)射光:由物體??發(fā)光
- 環(huán)境光:就是在環(huán)境中充分散射的光丸卷,?且?法分辨它的?向
- 漫反射光:光線來?某個?向,但在物體上各個?向反射
- 鏡??光:光線來??個特定的?向询刹,然后在物體表?上以?個特定的 ?向反射出去
材質(zhì)屬性
- 泛射材質(zhì)
- 漫反射材質(zhì)
- 鏡?反射材質(zhì)
- 發(fā)射材質(zhì)
光照計算
1.環(huán)境光的計算
環(huán)境光 = 環(huán)境因子 * 物體的材質(zhì)顏?
2.發(fā)射光的計算
發(fā)射顏? = 物體的反射材質(zhì)顏?
3.漫反射光計算
漫反射顏? = 光源的漫反射顏? * 物體的漫發(fā)射材質(zhì)顏? * DiffuseFactor
DiffuseFactor = max(0,dot(N,L))
漫反射因?DiffuseFactor 是光線 與頂點法線向量的點積
4.鏡?光計算
鏡?反射顏? = 光源的鏡?光的顏? * 物體的鏡?材質(zhì)顏? * SpecularFactor
SpecularFactor = power(max(0,dot(N,H)),shininess)
H :視線向量E 與 光線向量L 的半向量
dot(N,H) :H,N的點積?何意義,平?線與法線夾?角的cos值
shiniess : ?光的反光度
光照計算
光照顏? = (環(huán)境顏? + 漫反射顏? + 鏡?反射顏?) * 衰減因?
衰減因?
衰減因? = 1.0/(距離衰減常量 + 線性衰減常量 * 距離 + ?次衰減常量 * 距離的平?)
注:
- 距離衰減常量,線性衰減常量和?次衰減常量均為常量值
- 環(huán)境光谜嫉,漫反射光和鏡?光的強度都會受距離的增??衰減,只有發(fā)射光和全局環(huán)境光的強度不會受影響
聚光燈因?
聚光燈夾?角cos值 = power(max(0,dot(單位光源位置凹联,單位光線向量)),聚光燈指數(shù))
- 單位光線向量是從光源指向頂點的單位向量
- 聚光燈指數(shù)沐兰,表示聚光燈的亮度程度
- 公式解讀:單位光源位置 * 單位光線向量 點積 的 聚光燈指數(shù)次?
增加過渡計算
聚光燈因? = clamp((外環(huán)的聚光燈?角度cos值 - 當前頂點的聚光燈?角度cos值)/ (外環(huán)的聚光燈?角度cos值- 內(nèi)環(huán)聚光燈的?角度的cos值),0,1)
光照計算終極公式
光照顏? = 發(fā)射顏? + 全局環(huán)境顏? + (環(huán)境顏? + 漫反射顏? + 鏡?反 射顏?) * 聚光燈效果 * 衰減因?
期待您移步下篇:OpenGL筆記十六:CAEmitterLayer粒子效果