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

  • 相关阅读:
    light oj 1105 规律
    light oj 1071 dp(吃金币升级版)
    light oj 1084 线性dp
    light oj 1079 01背包
    light oj 1068 数位dp
    light oj 1219 树上贪心
    light oj 1057 状压dp TSP
    light oj 1037 状压dp
    矩阵快速幂3 k*n铺方格
    矩阵快速幂2 3*n铺方格
  • 原文地址:https://www.cnblogs.com/infintyward/p/3250390.html
Copyright © 2011-2022 走看看