zoukankan      html  css  js  c++  java
  • Chapter8-Making Your Day Brighter之Lens Flare & put all together

          1. 我们先来看Lens FLare这个例子:

           经过了这一章后边几节基本上不再有什么新的东西了,都是对前两个例子的变换。

           唯一值得一提的是一个纹理缩放公式: 

    1 texCoord = (texCoord-0.5)*(Scale) + 0.5;

          不停的对可渲染纹理中的图像进行缩放,当Scale取负值的时候,就是带符号的缩放,实际上就是就是把图像旋转了180°。

          下边我们来看Vertex Shader的代码:   

     1 float4x4 view_proj_matrix;
     2 struct VS_OUTPUT
     3 {
     4 float4 Pos: POSITION;
     5 float2 texCoord: TEXCOORD0;
     6 float2 texCoord1: TEXCOORD1;
     7 float2 texCoord2: TEXCOORD2;
     8 float2 texCoord3: TEXCOORD3;
     9 float2 texCoord4: TEXCOORD4;
    10 };
    11 VS_OUTPUT vs_main(float4 Pos: POSITION)
    12 {
    13 VS_OUTPUT Out;
    14 // Simply output the position without transforming it
    15 Out.Pos = float4(Pos.xy, 0, 1);
    16 // Texture coordinates are setup so that the full texture
    17 // is mapped completely onto the screen
    18 float2 texCoord;
    19 texCoord.x = 0.5 * (1 + Pos.x - 1/128);
    20 texCoord.y = 0.5 * (1 - Pos.y - 1/128);
    21 Out.texCoord = texCoord;
    22 // Compute the scaled texture coordinates for the ghost images
    23 Out.texCoord1 = (texCoord-0.5)*(-2.0) + 0.5;
    24 Out.texCoord2 = (texCoord-0.5)*(2.0) + 0.5;
    25 Out.texCoord3 = (texCoord-0.5)*(-0.6) + 0.5;
    26 Out.texCoord4 = (texCoord-0.5)*(0.6) + 0.5;
    27 return Out;
    28 }

        一个普通的不能在普通的RTT了,Full texture纹理坐标还是要进行计算的(代码19-20行),因为它要用于进行计算缩放纹理坐标(scaled texture coordinates,代码23-26行)。

        下边我们再看Pixel Shader代码:

     1 float viewport_inv_height;
     2 float viewport_inv_width;
     3 float Glow_Factor;
     4 sampler Texture0;
     5 sampler Texture1;
     6 float4 ps_main (float2 texCoord: TEXCOORD0,
     7 float2 texCoord1: TEXCOORD1,
     8 float2 texCoord2: TEXCOORD2,
     9 float2 texCoord3: TEXCOORD3,
    10 float2 texCoord4: TEXCOORD4) : COLOR
    11 {
    12 // Sample all ghost pictures
    13 float4 col1 = tex2D(Texture0, texCoord1)*tex2D(Texture1, texCoord1).a;
    14 float4 col2 = tex2D(Texture0, texCoord2)*tex2D(Texture1, texCoord2).a;
    15 float4 col3 = tex2D(Texture0, texCoord3)*tex2D(Texture1, texCoord3).a;
    16 float4 col4 = tex2D(Texture0, texCoord4)*tex2D(Texture1, texCoord4).a;
    17 // Combine the ghost images together
    18 return (col1+col2+col3+col4)*Glow_Factor;
    19 }

           上边的Pixel Shader代码:

           第一行的 float viewport_inv_height;

             第二行的 float viewport_inv_width; 

             第六行的 float4 ps_main 的第一个参数float2 texCoord: TEXCOORD0都可以去掉, float2 texCoord: TEXCOORD0只在Vertex Shader中有作用,Pixel Shader中没有任何作用。

             然后我们再来看

             13 float4 col1 = tex2D(Texture0, texCoord1)*tex2D(Texture1, texCoord1).a;

             14 float4 col2 = tex2D(Texture0, texCoord2)*tex2D(Texture1, texCoord2).a;

             15 float4 col3 = tex2D(Texture0, texCoord3)*tex2D(Texture1, texCoord3).a;

             16 float4 col4 = tex2D(Texture0, texCoord4)*tex2D(Texture1, texCoord4).a;

              Q1:为什么Texture1的采样坐标不是float2 texCoord: TEXCOORD0呢(Texture0坐标是Full texture纹理坐标,Texture1是缩放后的纹理坐标)????

              A1:  我们拿绘制Ghost的第一个Pass中的采样来举例,如果使用Full texture纹理坐标会发生什么情况,正好做一个实验,如下图:

              第一幅图是未对缩放后的图片进行Mask处理,上边有很多的条纹(因为我们纹理采样使用的时clamp模式)

                                                                                                                  未对缩放后的图片进行透明度Mask处理

                第二幅图是对缩放后的图片进行Mask处理,但是使用的是Full texture纹理坐标:

                这个很容易理解,因为用来Mask的图像是在Full texture空间中进行的,所以它只对屏幕空间圆心处的像素进行保留,其他位置全部Mask掉;

                                                                          

             第三副图片就是该书中所采取的,利用缩放的纹理坐标采样Ghost,然后对缩放的纹理进行Mask,可以保证,在缩放后空间内,利用缩放后的Ghost图像正确的对图像进行Mask! ,消除硬边(实际上效果也不是很理想:(,有的地方也消除的不好)。

            Q2:值得注意的是,图像上放大的纹理,实际上纹理坐标是缩小的,图像缩小的纹理,实际上纹理坐标是放大的 :)

            A2:在Vertex shader中将纹理坐标进行了缩放,该纹理坐标被Route进了Pixel Shader中;

            然后在Pixel Shader中对纹理进行采样,不管我们的纹理坐标范围是多少,这个2维范围内的纹理都将按照对应的纹理地址模式被绘制到屏幕!!(理解这句是关键)

            如果在Vertex Shader中纹理坐标变换为X(0,2),Y(0,2),Route进Pixel Shader中,我们其实将该纹理进行X(0,2),Y(0,2)的采样,并将该采样范围的图像绘制到屏幕上;实际在屏幕上绘制了4遍,但是在我们看起来,图像是缩小了(clamp模式下,只有左上角部分有图像,其他部分是两个边颜色的Clamp);

           如果在Vertex Shader中纹理坐标变换为X(0,0.5),Y(0,0.5),Route进Pixel Shader中,我们其实将该纹理进行X(0,0.5),Y(0,0.5)的采样,并将该采样范围的图像绘制到屏幕上;实际在屏幕上绘制了四分之一的图像,但是在我们看起来,图像是放大了(这里我们就不管是不是Clamp了,因为根本不需要这个地址模式就可以确定纹理坐标范围内的颜色);

           (以上举例是以纹理坐标原点为中心的,以纹理为中心一个道理——这是我能想到的最好的解释方式了,If you have a better one, please let me know;)

           2. 然后我们再来看Put them together这个例子,实际上就是将Glare,Streak,Lens Flare放在一起,所有的Renderable texture,Pass,纹理资源,变量等等统统糅合在一起——这个简直就是噩梦:( ,组织数据繁琐一些,然后对Pixel Shader稍作修改。      

     //This is the final Pixel Shader Code...................
    //We need to apply some changes....
    1
    sampler Texture0; //This is for Ghost Image 2 3 sampler Texture1; //This is for Blooming 4 sampler Texture2; 5 sampler Texture3; 6 7 sampler Texture4; //This is for Streak 8 sampler Texture5; // 9 sampler Texture6; // 10 sampler Texture7; // 11 12 float Streak_Factor; 13 float Ghost_Factor; 14 float Glow_Factor1; 15 float Glow_Factor2; 16 float Glow_Factor3; 17 18 float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR 19 { 20 float4 col; 21 22 // Glow 23 col = float4((tex2D(Texture1,texCoord).xyz)*Glow_Factor1,1.0) + 24 float4((tex2D(Texture2,texCoord).xyz)*Glow_Factor2,0) + 25 float4((tex2D(Texture3,texCoord).xyz)*Glow_Factor3,0); 26 27 // Ghost 28 col += float4((tex2D(Texture0,texCoord).xyz),0); 29 30 // Streak 31 32 col += 33 float4((tex2D(Texture4,texCoord).xyz)*Streak_Factor,0) + 34 float4((tex2D(Texture5,texCoord).xyz)*Streak_Factor,0) + 35 float4((tex2D(Texture6,texCoord).xyz)*Streak_Factor,0) + 36 float4((tex2D(Texture7,texCoord).xyz)*Streak_Factor,0); 37 38 return col; 39 }

          注意line23, 只把在第一个颜色的α值设置为1,其他都为0,这样最终颜色的α值是1,根据http://www.cnblogs.com/infintyward/p/3244888.html中讲过的混合原理,将最终返回的颜色与后缓存进行混合。

          最终效果图如下。

                               

               //end

  • 相关阅读:
    第三次作业——《原型设计》
    第二次作业《熟悉使用工具》
    跟着《构建之法》学习软件工程(第一次作业)
    纯js代码实现手风琴特效
    HTML5
    为什么做前端要做好SEO
    让div盒子相对父盒子垂直居中的几种方法
    模板artTemplate
    bootstrap兼容问题
    移动常用的类库
  • 原文地址:https://www.cnblogs.com/infintyward/p/3250390.html
Copyright © 2011-2022 走看看