随笔 - 32  文章 - 94  trackbacks - 0
<2009年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

常用链接

留言簿(8)

随笔分类

随笔档案

好友连接

搜索

  •  

最新评论

阅读排行榜

评论排行榜

很早就想学习shader了,当时看着那本《openGL超级宝典》的高级shader语言看了2遍,却被误导到了那些什么shaderObject,shaderProgramme的概念上,还一直在思考一个Programme和Object之间的关系。
诸如包含和被包含、一对多,还有在程序中何时准备,何时释放的问题(曾看过网上一个例子,在游戏循环中居然不断重新编译)。

因为被这些问题搞混了很久,所以觉得应该找本更详细的书看,于是就找了本《openGL shading language》英文版电子书,前面5章的内容仍然是那些渲染管线的老问题,因为害怕会漏点什么,都耐着性子看,业余时间看了10天左右,才看到第6章一个入门的例子,还有第七章解决了以前困扰着的问题。

接下来用了那个RenderMonkey明明白白地试验了第6章的那个例子,试验时又冒出了不少数学问题,例如:vs中的法线变换为什么不用gl_ModelViewMatrix去乘、矩阵的各种运算公式等等,哎,都怪大一时线性代数学的太烂。

以下是按照“橙宝书”第六章的砖块,这一章后面留给读者有关解决颜色锯齿的问题,弄了半天.....
另外,RenderMonkey添加中文注释时,有时候居然会出什么“type name expected at token "<undefined>"”,然后编译不通过,也弄了半天...
uniform vec3 f3LightPos;
const float specularContribution=0.4;
const float diffuseContribution=1.0-specularContribution;

varying 
float LightIntensity;
varying vec2  MCposition;

void main(void)
{
   vec3 ecPosition 
= vec3(gl_ModelViewMatrix * gl_Vertex);//在眼坐标系中物体的坐标
   
   vec3 tnorm     
= normalize(gl_NormalMatrix * gl_Normal);//在眼坐标系中的法线
   
   vec3 lightEyePos
=vec3(vec4(f3LightPos,1.0));
   
   vec3 lightVec   
= normalize(lightEyePos - ecPosition);//灯光方向(跟着眼睛移动)
   
   vec3 reflectVec 
= reflect(-lightVec, tnorm);//反射方向
   vec3 viewVec    = normalize(-ecPosition);//眼睛的前方向
   float diffuse   = max(dot(lightVec, tnorm), 0.0);//光线和法线的乘积
   float spec      = 0.0;

    
if (diffuse > 0.0)
    
{
        spec 
= max(dot(reflectVec, viewVec), 0.0);//反射光 
        spec = pow(spec, 2.0);
    }


    LightIntensity 
= diffuseContribution * diffuse +specularContribution * spec;


    MCposition
=gl_Vertex.xy;


   gl_Position 
=gl_ProjectionMatrix*gl_ModelViewMatrix * gl_Vertex;// ftransform();
}

uniform vec4 BrickColor;
uniform vec4 EdgeColor;
uniform vec2 f2BrickSize;
uniform vec2 f2BrickInnerPerc;

varying vec2 MCposition;
varying 
float LightIntensity;

void main(void)
{
   vec4  color;
   vec2  position, useBrick;
   position
=MCposition*0.02/f2BrickSize;
   
//在贴图为参考比例
   if (fract(position.y * 0.5> 0.5)
      position.x 
+= 0.5;
      

   position 
= fract(position);//在贴图上
   
   
   
float smallX=(1.0-f2BrickInnerPerc.x)/2.0;
   
float bigX=1.0-smallX;
   
   
   
float smallY=(1.0-f2BrickInnerPerc.y)/2.0;
   
float bigY=1.0-smallY;

   
if(position.x>0.5)
      useBrick.x 
= 1.0-smoothstep(bigX-0.03, bigX+0.03,position.x);
   
else
   
{
   
//useBrick.x = step(position.x, f2BrickInnerPerc.x);
     useBrick.x = smoothstep(smallX-0.03, smallX+0.03,position.x);
      }

   
if (position.y>0.5)
      useBrick.y 
= 1.0-smoothstep(bigY-0.03, bigY+0.03,position.y);
   
else
   
{
   
//useBrick.y = step(position.y, f2BrickInnerPerc.y);
   useBrick.y = smoothstep(smallY-0.03, smallY+0.03,position.y);
   }


  
// useBrick.x = step(position.x, f2BrickInnerPerc.x);
  
// useBrick.y = step(position.y, f2BrickInnerPerc.y);

    color  
= mix(EdgeColor,BrickColor , useBrick.x * useBrick.y);

   
   color
=color*LightIntensity;
   
   gl_FragColor 
= vec4( color.rgb, 1.0 );
}




接下来学习的主要问题:

shader环境配置、语法等烦问题都解决了,也能看明白RenderMonkey自带的一些比较简单的例子的整体思路。

但是每个例子中的细节部分,每个具体步骤的计算,却不明白。因此现在是看懂例子的大概,但是要我重新写一个,或者指出例子中某个具体计算的作用,或者脑里想象例子中某个具体步骤产生的效果,肯定不会...
posted on 2009-09-15 23:30 陈昱(CY) 阅读(1734) 评论(4)  编辑 收藏 引用 所属分类: 图形学

FeedBack:
# re: 学习shader第一步 2009-09-16 10:13 StarX
好大一条虫子啊,哈哈。。  回复  更多评论
  
# re: 学习shader第一步 2009-09-16 10:57 Touchsoft
“但是每个例子中的细节部分,每个具体步骤的计算,却不明白。”
别说Shader,同样对于是些简单的3D程序,我经常搞不懂这些。  回复  更多评论
  
# re: 学习shader第一步 2009-09-16 15:21 凡客诚品
好大的一条啊~~  回复  更多评论
  
# re: 学习shader第一步 2009-09-21 09:46 Sunshine Alike
我想说这像一根大香肠,哈哈  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理