【OpenGL的著色器03】內置變量(gl_Position等)

目錄

一、說明

二、著色器的變量

2.1 著色器變量

2.2 著色器內置變量

三、最常見內置變量使用范例

3.1 常見著色器變量

3.2 示例1: gl_PointSize?

3.3 示例2:gl_Position?

3.4 gl_FragColor

3.5 渲染點片元坐標gl_PointCoord

3.6 gl_PointCoord應用案例

四、GPU的內置函數

4. 1 內置函數列表

4.2 角度與三角函數

4.3 指數函數

4.4 通用函數

4.5 幾何函數

4.6 矩陣函數

4.7 矢量函數

4.8 紋理查詢函數


一、說明

????????著色器的內置變量和內置函數很有必要說一說,因為,初入門的時候不知道著色器有多深的水準,必須將它所蘊涵的東西統統擺到桌面上,才能有所準備,有所認知,有所實用。本篇就是將著色器默認的變量函數統統擺出,混個臉熟。

二、著色器的變量

2.1 著色器變量

????????著色器有兩種變量:

  • 普通變量,著色器語言和C語言類似,需要先聲明后使用。
  • 內置變量,所謂內置變量就是不用聲明可以直接賦值,主要是為了實現特定的功能。?? ?

2.2 著色器內置變量

1) 頂點著色器內置變量

名稱類型描述
gl_Colorvec4輸入屬性-表示頂點的主顏色
gl_SecondaryColorvec4輸入屬性-表示頂點的輔助顏色
gl_Normalvec3輸入屬性-表示頂點的法線值
gl_Vertexvec4輸入屬性-表示物體空間的頂點位置
gl_MultiTexCoordnvec4輸入屬性-表示頂點的第n個紋理的坐標
gl_FogCoordfloat輸入屬性-表示頂點的霧坐標
gl_Positionvec4輸出屬性-變換后的頂點的位置,用于后面的固定的裁剪等操作。所有的頂點著色器都必須寫這個值。
gl_ClipVertexvec4輸出坐標,用于用戶裁剪平面的裁剪
gl_PointSizefloat點的大小
gl_FrontColorvec4正面的主顏色的varying輸出
gl_BackColorvec4背面主顏色的varying輸出
gl_FrontSecondaryColorvec4正面的輔助顏色的varying輸出
gl_BackSecondaryColorvec4背面的輔助顏色的varying輸出
gl_TexCoord[]vec4紋理坐標的數組varying輸出
gl_FogFragCoordfloat霧坐標的varying輸出

2)片段著色器內置變量

名稱類型描述
gl_Colorvec4包含主顏色的插值只讀輸入
gl_SecondaryColorvec4包含輔助顏色的插值只讀輸入
gl_TexCoord[]vec4包含紋理坐標數組的插值只讀輸入
gl_FogFragCoordfloat包含霧坐標的插值只讀輸入
gl_FragCoordvec4只讀輸入,窗口的x,y,z和1/w
gl_FrontFacingbool只讀輸入,如果是窗口正面圖元的一部分,則這個值為true
gl_PointCoordvec2點精靈的二維空間坐標范圍在(0.0, 0.0)到(1.0, 1.0)之間,僅用于點圖元和點精靈開啟的情況下。
gl_FragData[]vec4使用glDrawBuffers輸出的數據數組。不能與gl_FragColor結合使用。
gl_FragColorvec4輸出的顏色用于隨后的像素操作
gl_FragDepthfloat輸出的深度用于隨后的像素操作,如果這個值沒有被寫,則使用固定功能管線的深度值代替

三、最常見內置變量使用范例

3.1 常見著色器變量

內置變量名稱含義變量數值類型
gl_PointSize?點渲染模式,方形點區域渲染像素大小?float
gl_Position? ? ? ?頂點位置坐標???vec4
gl_FragColor? ? ?片元顏色值?? ?vec4
gl_FragCoord? ? ?片元坐標,單位像素???vec2
gl_PointCoord?? ?點渲染模式對應點像素坐標?? ?vec2

????????當WebGL執行繪制函數gl.drawArrays()繪制模式是點模式gl.POINTS的時候,頂點著色器語言main函數中才會用到內置變量gl_PointSize,使用內置變量gl_PointSize主要是用來設置頂點渲染出來的方形點像素大小。

3.2 示例1: gl_PointSize?

void main() {//給內置變量gl_PointSize賦值像素大小,注意值是浮點數gl_PointSize=20.0;
}//繪制函數繪制模式:點gl.POINTS
gl.drawArrays(gl.POINTS,0,點數量);

3.3 示例2:gl_Position?

????????gl_Position內置變量主要和頂點相關,出現的位置是頂點著色器語言的main函數中。gl_Position內置變量表示最終傳入片元著色器片元化要使用的頂點位置坐標。

????????如果只有一個頂點,直接在給頂點著色器中設置內置變量gl_Position賦值就可以,內置變量gl_Position的值是四維向量vec4(x,y,z,1.0),前三個參數表示頂點的xyz坐標值,第四個參數是浮點數1.0。

void main() {//頂點位置,位于坐標原點gl_Position = vec4(0.0,0.0,0.0,1.0);
}

????????如果你想完全理解內置變量gl_Position,必須建立逐頂點的概念,如果javascript語言中出現一個變量賦值,你可以理解為僅僅執行一次,但是對于著色器中不能直接這么理解,如果有多個頂點,你可以理解為每個頂點都要執行一遍頂點著色器主函數main中的程序。

????????多個頂點的時候,內置變量gl_Position對應的值是attribute關鍵字聲明的頂點位置坐標變量apos,頂點位置坐標變量apos變量對應了javascript代碼中多個頂點位置數據。

<!-- 頂點著色器源碼 -->
<script id="vertexShader" type="x-shader/x-vertex">
? //attribute聲明vec4類型變量apos
? attribute vec4 apos;
? void main() {
? ? //頂點坐標apos賦值給內置變量gl_Position
? ? //逐頂點處理數據
? ? gl_Position = apos;
? }
</script>

????????逐頂點處理的案例:WebGL的每一個頂點位置坐標都會通過平移矩陣m4進行矩陣變換,相當于批量操作所有的頂點數據,進行了平移,只是平移的計算通過矩陣乘法運算完成的而已。所謂的逐頂點,在這里體現的就是每一個頂點都會執行main函數中的矩陣變換。你可以參照生活的流水線去理解,比如多個同樣的設備從我這里經過,我會分別對他們進行同樣的操作,比如安裝一個零件。

<!-- 頂點著色器源碼 -->
<script id="vertexShader" type="x-shader/x-vertex">
? //attribute聲明vec4類型變量apos
? attribute vec4 apos;
? void main() {
? ? //創建平移矩陣(沿x軸平移-0.4)
? ? //1 ? 0 ? 0 ?-0.4
? ? //0 ? 1 ? 0 ? ?0
? ? //0 ? 0 ? 1 ? ?0
? ? //0 ? 0 ? 0 ? ?1
? ? mat4 m4 = mat4(1,0,0,0, ?0,1,0,0, ?0,0,1,0, ?-0.4,0,0,1);
? ? //平移矩陣m4左乘頂點坐標(vec4類型數據可以理解為線性代數中的nx1矩陣,即列向量)
? ? // 逐頂點進行矩陣變換
? ? gl_Position = m4*apos;
? }

</script>


## gl_Position的頂點數據傳遞
attribute聲明的頂點變量數據如何通過javascript的WebGL API批量傳遞所有頂點數據。

<script>
? ? //頂點著色器源碼
? ? var vertexShaderSource = document.getElementById( 'vertexShader' ).innerText;
? ? //片元著色器源碼
? ? var fragShaderSource = document.getElementById( 'fragmentShader' ).innerText;
? ? //初始化著色器
? ? var program = initShader(gl,vertexShaderSource,fragShaderSource);
? ? //獲取頂點著色器的位置變量apos,即aposLocation指向apos變量。
? ? var aposLocation = gl.getAttribLocation(program,'apos');

? ? //類型數組構造函數Float32Array創建頂點數組
? ? var data=new Float32Array([0.5,0.5,-0.5,0.5,-0.5,-0.5,0.5,-0.5]);

? ? //創建緩沖區對象
? ? var buffer=gl.createBuffer();
? ? //綁定緩沖區對象,激活buffer
? ? gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
? ? //頂點數組data數據傳入緩沖區
? ? gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
? ? //緩沖區中的數據按照一定的規律傳遞給位置變量apos
? ? gl.vertexAttribPointer(aposLocation,2,gl.FLOAT,false,0,0);
? ? //允許數據傳遞
? ? gl.enableVertexAttribArray(aposLocation);
...
</script>


3.4 示例3:gl_FragColor

gl_FragColor內置變量主要用來設置片元像素的顏色,出現的位置是片元著色器語言的main函數中。

內置變量gl_Position的值是四維向量vec4(r,g,b,a),前三個參數表示片元像素顏色值RGB,第四個參數是片元像素透明度A,1.0表示不透明,0.0表示完全透明。

// 片元顏色設置為紅色
gl_FragColor = vec4(1.0,0.0,0.0,1.0);

理解內置變量gl_Position需要建立逐頂點的概念,對于內置變量gl_FragColor而言,需要建立逐片元的概念。頂點經過片元著色器片元化以后,得到一個個片元,或者說像素點,然后通過內置變量gl_FragColor給每一個片元設置顏色值,所有片元可以使用同一個顏色值,也可能不是同一個顏色值,可以通過特定算法計算或者紋理像素采樣。

根據位置設置漸變色

? void main() {
? ? // 片元沿著x方向漸變
? ? gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0,1.0,0.0,1.0);
? }

紋理采樣

// 接收插值后的紋理坐標
varying vec2 v_TexCoord;
// 紋理圖片像素數據
uniform sampler2D u_Sampler;
void main() {
? // 采集紋素,逐片元賦值像素值
? gl_FragColor = texture2D(u_Sampler,v_TexCoord);
}

片元坐標gl_FragCoord
內置變量gl_FragCoord表示WebGL在canvas畫布上渲染的所有片元或者說像素的坐標,坐標原點是canvas畫布的左上角,x軸水平向右,y豎直向下,gl_FragCoord坐標的單位是像素,gl_FragCoord的值是vec2(x,y),通過gl_FragCoord.x、gl_FragCoord.y方式可以分別訪問片元坐標的縱橫坐標。

下面代碼是把canvas畫布上不同區域片元設置為不同顏色。

<!-- 片元著色器源碼 -->
<script id="fragmentShader" type="x-shader/x-fragment">
? void main() {
? ? // 根據片元的x坐標,來設置片元的像素值
? ? if(gl_FragCoord.x < 300.0){
? ? ? // canvas畫布上[0,300)之間片元像素值設置
? ? ? gl_FragColor = vec4(1.0,0.0,0.0,1.0);
? ? }else if (gl_FragCoord.x <= 400.0) {
? ? ? // canvas畫布上(300,400]之間片元像素值設置
? ? ? gl_FragColor = vec4(0.0,1.0,0.0,1.0);
? ? }else {
? ? ? // canvas畫布上(400,500]之間片元像素值設置
? ? ? gl_FragColor = vec4(0.0,0.0,1.0,1.0);
? ? } ? ?
? ? // 所有片元設置為紅色
? ? // gl_FragColor = vec4(1.0,0.0,0.0,1.0);
? }
</script>


片元的顏色隨著坐標變化(設置一個漸變色效果)

<!-- 片元著色器源碼 -->
<script id="fragmentShader" type="x-shader/x-fragment">
? void main() {
? ? // 片元沿著x方向漸變
? ? gl_FragColor = vec4(gl_FragCoord.x/500.0*1.0,1.0,0.0,1.0);
? }
</script>



3.5 渲染點片元坐標gl_PointCoord


????????如果你想了解內置變量gl_PointCoord表示的坐標含義,就需要了解 GL繪制函數gl.drawArrays()的繪制模式參數gl.POINTS。

????????繪制函數gl.drawArrays()繪制模式參數設置為點渲染模式gl.POINTS,WebGL會把頂點渲染為一個方形區域,在頂點著色器代碼中可以通過內置變量gl_PointSize設置頂點渲染的方向區域像素大小。

????????一個頂點渲染為一個方形區域,每個方形區域可以以方向區域的左上角建立一個直角坐標系,然后使用內置變量gl_PointCoord描述每個方形區域中像素或者說片元的坐標,比如方形區域的左上角坐標是(0.0,0.0),每個方形區域幾何中心坐標是(0.5,0.5),右下角坐標是(1.0,1.0)。

????????注意內置變量gl_PointCoord和gl_FragCoord表示的像素坐標含義不同,查看下圖表示。


// 點繪制模式渲染10個頂點
gl.drawArrays(gl.POINTS,0,10);

頂點著色器中通過內置變量gl_PointSize設置點渲染的方形區域像素尺寸。

void main() {
? //點渲染的方形區域像素大小
? gl_PointSize = 20.0;
? ...
}


3.6 gl_PointCoord應用案例


????????gl.POINTS繪制模式點默認渲染效果是方形區域,通過下面片元著色器代碼設置可以把默認渲染效果更改為圓形區域。

<!-- 片元著色器源碼 -->
<script id="fragmentShader" type="x-shader/x-fragment">
? precision lowp float;// 所有float類型數據的精度是lowp
? void main() {
? ? // 計算方形區域每個片元距離方形幾何中心的距離
? ? // gl.POINTS模式點渲染的方形區域,方形中心是0.5,0.5,左上角是坐標原點,右下角是1.0,1.0,
? ? float r = distance(gl_PointCoord, vec2(0.5, 0.5));
? ? //根據距離設置片元
? ? if(r < 0.5){
? ? ? // 方形區域片元距離幾何中心半徑小于0.5,像素顏色設置紅色
? ? ? gl_FragColor = vec4(1.0,0.0,0.0,1.0);
? ? }else {
? ? ? // 方形區域距離幾何中心半徑不小于0.5的片元剪裁舍棄掉:
? ? ? discard;
? ? }
? }

</script>

????????通過gl_PointCoord返回的是片元縱橫坐標vec2(x,y),自然通過xy分量gl_PointCoord.x、gl_PointCoord.y方式可以分別訪問片元坐標的橫坐標、縱坐標,
? ? ? ? ? ? ? ? ? ? ? ??

四、GPU的內置函數

4. 1 內置函數列表

4.2 角度與三角函數

4.3 指數函數

4.4 通用函數


?

4.5 幾何函數

4.6 矩陣函數

4.7 矢量函數

4.8 紋理查詢函數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/711895.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711895.shtml
英文地址,請注明出處:http://en.pswp.cn/news/711895.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【PyTorch][chapter 20][李宏毅深度學習]【無監督學習][ GAN]【實戰】

前言 本篇主要是結合手寫數字例子,結合PyTorch 介紹一下Gan 實戰 第一輪訓練效果 第20輪訓練效果,已經可以生成數字了 68 輪 目錄&#xff1a; 谷歌云服務器&#xff08;Google Colab&#xff09; 整體訓練流程 Python 代碼 一 谷歌云服務器&#xff08;Google Colab&…

Linux學習-字符串數組和字符串

目錄 使用場景 字符型數組定義&#xff1a; 初始化 數組儲存 打印 字符型數組常見函數 常見操作 strcpy&#xff1a;字符串拷貝 strcat&#xff08;str1&#xff0c;str2&#xff09;字符串拼接 strcmp&#xff1a;字符串比較 注意&#xff1a; 二維字符型數…

Open CASCADE學習|曲線曲面連續性

1、曲線的連續性 曲線的連續性是三維建模、動畫設計等領域中非常重要的一個概念&#xff0c;它涉及到曲線在不同點之間的連接方式和光滑程度。下面將詳細介紹曲線的連續性&#xff0c;包括C連續性和G連續性。 1.1C連續性&#xff08;參數連續性&#xff09; C連續性是指曲線…

使用MyBatisPlus實現向數據庫中存儲List類型的數據

使用MyBatisPlus實現向數據庫中存儲List類型的數據 問題描述 建表時&#xff0c;表中的這五個字段為json類型 但是在入庫的時候既不能寫入數據&#xff0c;也不能查詢出數據。 解決方案&#xff1a; 1.首先明確&#xff0c;數據存入的時候是經過了數據類型轉化&#xff0c…

中國電子學會2020年06月真題C語言軟件編程等級考試三級(含詳細解析答案)

中國電子學會考評中心歷屆真題&#xff08;含解析答案&#xff09; C語言軟件編程等級考試三級 2020年06月 編程題五道 總分:100分一、最接近的分數&#xff08;20分&#xff09; 分母不超過N且小于A/B的最大最簡分數是多少? 時間限制: 1000ms 內存限制: 65536kb 輸入…

數據之光:探索數據庫技術的演進之路

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

喜訊!持安科技CEO何藝獲評安全419《2023年度十大優秀創業者》

近日&#xff0c;由網絡安全產業資訊媒體安全419主辦的《年度策劃》2023年度十大優秀創業者正式出爐&#xff0c;零信任辦公安全技術創新企業持安科技創始人兼CEO何藝&#xff0c;獲評十大優秀創業者。 這是安全419第二屆推出該項目的評選活動&#xff0c;安全419編輯老師在多年…

抽象類、模板方法模式

抽象類概述 在Java中abstract是抽象的意思&#xff0c;如果一個類中的某個方法的具體實現不能確定&#xff0c;就可以申明成abstract修飾的抽象方法&#xff08;不能寫方法體了&#xff09;&#xff0c;這個類必須用abstract修飾&#xff0c;被稱為抽象類。 抽象方法定義&…

【解決】修改 UI界面渲染層級 的常見誤區

開發平臺&#xff1a;Unity 2021版本 ? 問題描述 Unity 中管理 UI 上顯示元素的前后層級關系大致為以下兩種方式&#xff1a; 方式一&#xff1a;修改UI元素隊列順序與層級方式二&#xff1a;使用 Canvas 組件中的 Override Sort 屬性配置 方式二 對應復雜的 UI 層級關系將常…

這些單片機匯編語言的錯誤,你還在犯錯嗎?

在單片機開發中&#xff0c;很多工程師會選擇匯編語言來作為底層編程&#xff0c;來直接控制硬件和高校執行命令&#xff0c;然而因為匯編語言是直接與硬件交互&#xff0c;所以很容易出現錯誤&#xff0c;本文將基于Keil C51匯編器的環境總結單片機匯編語言常見的錯誤&#xf…

人工智能_大模型010_Centos7.9中CPU安裝ChatGLM3-6B大模型_安裝使用_010---人工智能工作筆記0145

從一個空的虛擬機開始安裝: https://www.modelscope.cn/models/ZhipuAI/chatglm3-6b/files 可以看到這里有很多的數據文件,那么這里 這里點擊模型文件就可以下載,這個就是chatglm3-6B的文件,需要點擊每個文件,然后點擊右邊的下載,把文件都下載下來 右側有下載按鈕.點擊下載可…

使用Fabric創建的canvas畫布背景圖片,自適應畫布寬高

之前的文章寫過vue2使用fabric實現簡單畫圖demo&#xff0c;完成批閱功能&#xff1b;但是功能不完善&#xff0c;對于很大的圖片就只能顯示一部分出來&#xff0c;不符合我們的需求。這就需要改進&#xff0c;對我們設置的背景圖進行自適應。 有問題的canvas畫布背景 修改后的…

Unity2023.1.19_ECS

Unity2023.1.19_ECS 在學習的路上一往無前的遇到了好東西&#xff0c;官方的EntityComponnentSystemSamples的Repository&#xff0c;這是一個包含實體&#xff0c;圖形&#xff0c;網絡&#xff0c;物理案例的全方位案例教程。 又找見接下來要干的事情了&#xff01;學習永無…

【rust】11、所有權

文章目錄 一、背景二、Stack 和 Heap2.1 Stack2.2 Heap2.3 性能區別2.4 所有權和堆棧 三、所有權原則3.1 變量作用域3.2 String 類型示例 四、變量綁定背后的數據交互4.1 所有權轉移4.1.1 基本類型: 拷貝, 不轉移所有權4.1.2 分配在 Heap 的類型: 轉移所有權 4.2 Clone(深拷貝)…

Quartz 任務調度框架源碼閱讀解析

概念: quartz 是一個基于JAVA的定時任務調度框架 案例: <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency>JobDetail job JobBuilder.newJob(Sc…

每日一練 | 華為認證真題練習Day191

1、在沒有啟用BGP路徑負載分擔的情況下&#xff0c;哪種BGP路由會發送BGP鄰居? A. 從所有鄰居學到的所有BGP路由。 B. 只有從IBGP學到的路由。 C. 只有從EBGP學到的路由。 D. 只有被BGP優選的最佳路由。 2、第三類LSA的LINK ID是 A. 生成這條LSA的路由器的ROUTER ID B. …

LeetCode 刷題 [C++] 第236題.二叉樹的最近公共祖先

題目描述 給定一個二叉樹, 找到該樹中兩個指定節點的最近公共祖先。 百度百科中最近公共祖先的定義為&#xff1a;“對于有根樹 T 的兩個節點 p、q&#xff0c;最近公共祖先表示為一個節點 x&#xff0c;滿足 x 是 p、q 的祖先且 x 的深度盡可能大&#xff08;一個節點也可以…

大數據分析案例-基于SVM支持向量機算法構建手機價格分類預測模型

&#x1f935;?♂? 個人主頁&#xff1a;艾派森的個人主頁 ?&#x1f3fb;作者簡介&#xff1a;Python學習者 &#x1f40b; 希望大家多多支持&#xff0c;我們一起進步&#xff01;&#x1f604; 如果文章對你有幫助的話&#xff0c; 歡迎評論 &#x1f4ac;點贊&#x1f4…

矩陣爆破逆向之條件斷點的妙用

不知道你是否使用過IDA的條件斷點呢&#xff1f;在IDA進階使用中&#xff0c;它的很多功能都有大作用&#xff0c;比如&#xff1a;ida-trace來跟蹤調用流程。同時IDA的斷點功能也十分強大&#xff0c;配合IDA-python的輸出語句能夠大殺特殺&#xff01; 那么本文就介紹一下這…

【JAVA】JDK內置工具之appletviewer

下載java 下載java的時候會先下載Java jdk&#xff0c;Java Development Kit Java開發工具包。 然后會下載jre&#xff0c;也就是Java Runtime Environment Java運行環境。什么是JDK、JRE&#xff1f;_java中的jdk,jre代表什么-CSDN博客 下載之后先找到java下的bin文件&#x…