1. 程式人生 > >【Shader特效7】磚頭牆壁紋理和排球紋理片元著色器實現

【Shader特效7】磚頭牆壁紋理和排球紋理片元著色器實現

磚頭牆壁紋理片元著色器實現(Shader特效7)

最近在研究一個使用片元著色器完成牆壁紋理和排球紋理的例子,在這裡進行總結一些演算法和開發過程。我都將我的程式碼放到了我的github上https://github.com/ModestBean/ShaderSample。本人的知識有限,如果本節內容有錯誤和不合理之處,還請朋友們多多指出,我會虛心接受每一個建議。
#####參考內容:

  • 《OpenGL ES 3.X 遊戲開發 下卷》

牆壁紋理執行效果

這裡寫圖片描述

排球紋理執行效果

這裡寫圖片描述
##牆壁紋理基本原理
這裡寫圖片描述
通過以上的圖片可以這樣計算
1、首先通過每一行的高度計算出每一個頂點的所屬行。奇數行與偶數行的磚塊不能夠重疊,否則看不出效果,所以奇數行相對偶數行有一個偏移量,這也就是需要計算行號的目的了。
2、將一行分解成圖中的1,2,3部分分別計算即可。
##排球紋理基本原理
排球紋理原理就不再多講了,與牆壁紋理類似,將經度劃分成8個區域,給定不用顏色,將緯度劃分成3個區域,兩極為白色。
##牆壁紋理程式碼部分
commonTexLight.frag

#version 400
#extension GL_ARB_separate_shader_objects : enable//開啟separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable//開啟shading_language_420pack
layout (location = 0) in vec3 vposition;//頂點著色器傳入的頂點位置
layout (location = 1) in vec2 mcLongLat;//頂點著色器傳入的頂點位置(經度,緯度)(偏航角,俯仰角)
layout (location = 0) out vec4 outColor;//輸出到渲染管線的片元顏色值
void main(){//主方法
   vec3 bColor=vec3(0.678,0.231,0.129);//磚塊的顏色
   vec3 mColor=vec3(0.763,0.657,0.614);//水泥的顏色
   vec3 color;//片元的最終顏色
   //計算當前位於奇數還是偶數行(這裡的12是指每一行的高度)求得的結果為0或者1
   int row=int(mod((mcLongLat.y+90.0)/12.0,2.0));
   //計算當前片元是否在此行區域1中的輔助變數,結果為0~11將牆壁的每一行分段化
   float ny=mod(mcLongLat.y+90.0,12.0);
   //每行的磚塊偏移值,奇數行偏移半個磚塊
   float oeoffset=0.0;
   //當前片元是否在此行區域3中的輔助變數
   float nx;
   if(ny>10.0){//圖中的1部分
       color=mColor;//採用水泥色著色
   }else{//圖中的2,3部分
   if(row==1){//若為奇數行則偏移半個磚塊
        oeoffset=11.0;
   }
   //計算當前片元是否在此行區域3中的輔助變數
   nx=mod(mcLongLat.x+oeoffset,22.0);
   if(nx>20.0){//圖中的2部分
       color=mColor;
   }else{//圖中的3部分
    color=bColor;//採用磚塊色著色
    }
   } //將片元的最終顏色傳遞進渲染管線
     outColor=vec4(color,0);
}
#version 400
#extension GL_ARB_separate_shader_objects : enable//開啟separate_shader_objects
#extension GL_ARB_shading_language_420pack : enable//開啟shading_language_420pack
layout (location = 0) in vec3 vposition;//頂點著色器傳入的頂點位置
layout (location = 1) in vec2 mcLongLat;//頂點著色器傳入的頂點位置(偏航角,仰角)
layout (location = 0) out vec4 outColor;//輸出到渲染管線的片元顏色值
void main(){//主方法
    vec3 color;
      if(abs(mcLongLat.y)>75.0){
      	  color = vec3(1.0,1.0,1.0);//兩邊是白色
      }else{
         int colorNum = int(mcLongLat.x/45.0);//顏色號
         if(colorNum == 0){
         	color = vec3(1.0,0.0,0.0);//0號顏色
         }else if(colorNum == 1){
         	color = vec3(0.0,1.0,0.0);//1號顏色
         }else if(colorNum == 2){
         	color = vec3(0.0,0.0,1.0);//2號顏色
         }else if(colorNum == 3){
         	color = vec3(1.0,1.0,0.0);//3號顏色
         }else if(colorNum == 4){
         	color = vec3(1.0,0.0,1.0);//4號顏色
         }else if(colorNum == 5){
         	color = vec3(0.0,1.0,1.0);//5號顏色
         }else if(colorNum == 6){
         	color = vec3(0.3,0.4,0.7);//6號顏色
         }else if(colorNum == 7){
         	color = vec3(0.3,0.7,0.2);//7號顏色
         }
      }
     outColor = vec4(color,1.0);//將顏色擴充為帶Alpha通道的vec4型別
}