zoukankan      html  css  js  c++  java
  • HLSL之环境光

         一直想学习Shader,却总是断断续续的,触及不到精髓部分。于是,决定从最基础的开始学习,做好笔记,尽快成为Shader达人.....既然选择了学习,就要风雨兼程,一路向前~

          第一篇之环境光:

          环境光是没有方向的,在一个空间中所有模型照射到的环境光的颜色都是相同的,比如在一个漆黑的房间里什么也看不到,环境光通常为0,而在一个明亮的房间里,就能够看到物体,此时让物体可以进入你视觉的即是因为环境光不为0。

          环境光除了颜色以外,通常还有个用来表示光照的强弱的强度参数

          环境光的公式是: I = Aintensity* Acolor

          其中I是光的实际颜色,Aintensity是光的强度(通常在0.0和1.0之间),Acolor环境光的颜色,这个颜色可以是硬编码的值,参数或纹理。

       

          接下来用XNA4.0+VS2010来实现一个简单的程序,并贴出其效果图。

          

           第一步:新建fx文件(Ambient.fx)

           首先需要在项目的Content目录下建立这个文件,在自动生成好的fx文件中,已经帮我们定义好了基本的模板,包括顶点的输入结构(VertexShaderInput)和顶点输出结构(VertexShaderOutput),同时定义好了顶点着色方法(VertexShaderFunction)以及像素着色方法(PixelShaderFunction)。除此之外还有三个4*4的矩阵,分别是world,view,project。

          Vertex shader:顶点渲染,处理从顶点缓冲区加载的模型顶点信息传递到shader中,顶点结构中通常可以包括:位置、颜色、法线、切线等信息,由于环境光只需要对位置进行处理,所以这里我们只定义了一个位置信息。

    struct VertexShaderInput
    {
        float4 Position : POSITION0;
    };
    
    struct VertexShaderOutput
    {
        float4 Position : POSITION0;
    };
    

           在shader中,数据之间的传值借助寄存器,比如上面代码中出现得POSITION0,表示位置信息会放在名称叫POSITION这个寄存器里面。

           接着,则是处理获取到的模型位置并进行转换 (将默认的VertexShaderFunction改成了VertexShaderAmbient)

    VertexShaderOutput VertexShaderAmbient(VertexShaderInput input)
    {
        VertexShaderOutput output;
    
        float4 worldPosition = mul(input.Position, World);
        float4 viewPosition = mul(worldPosition, View);
        output.Position = mul(viewPosition, Projection);
    
        return output;
    }
    

        通过三个矩阵的转换,模型的顶点位置已经正确的转换到当前空间了,下一步则是像素着色,添加光照信息。

        Pixel Shader:逐像素渲染,对给定的模型、对象、顶点额所有像素进行处理,将Vertex Shader的输出值作为它的输入值

    float4 PixelShaderAmbient(VertexShaderOutput input) : COLOR0
    {
        float aIntensity= 0.4f; //颜色强度
        float4 aColor= {1,0,0,1}; 
    
        return aColor*aIntensity;
    }
    

         同样,对于返回值,我们保存在COLOR寄存器里面。

         最后,我们必须定义technique并将pixel shader和vertex shader函数绑定到technique上

    technique AmbientLight
    {
        pass Pass0
        {
            VertexShader = compile vs_2_0 VertexShaderAmbient();
            PixelShader = compile ps_2_0 PixelShaderAmbient();
        }
    }
    

        到此,一个简单的shader就编写完成了,那么下面我们看看在XNA程序中如何调用。

        第一:声明一个Effect对象

      /// <summary>
      /// effect for shader
      /// </summary>
      private Effect effect;
    

        第二:加载fx文件

     effect = Content.Load<Effect>("Ambient");

        第三:利用effect渲染模型

      effect.CurrentTechnique = effect.Techniques["AmbientLight"];
    
      //遍历所有的pass
      foreach (EffectPass pass in effect.CurrentTechnique.Passes)
      {
          pass.Apply();
          foreach (ModelMesh mesh in model.Meshes)
          {
                Matrix worldMatrix = modelTransform[mesh.ParentBone.Index] * Matrix.CreateScale(30.0f) * Matrix.CreateRotationY(angle) * Matrix.CreateRotationX(angle);
                foreach (ModelMeshPart part in mesh.MeshParts)
                {
                     effect.Parameters["World"].SetValue(worldMatrix);
                     effect.Parameters["View"].SetValue(viewMatrix);
                     effect.Parameters["Projection"].SetValue(projectMatrix);
    
                     VertexBuffer vb = part.VertexBuffer;
                     graphics.GraphicsDevice.SetVertexBuffer(part.VertexBuffer);
                     graphics.GraphicsDevice.Indices = part.IndexBuffer;
    
                    graphics.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList , part.VertexOffset , 0 , part.NumVertices , part.StartIndex , part.PrimitiveCount);
                }
            }
        }
    

           这样就可以达到上面截图的效果,注:一个Shader可以有一个或一个以上的technique。每个technique都有一个唯一的名称,我们可以通过设置Effect类中的CurrentTechnique属性选择使用哪个technique。同时,一个technique可以有一个或多个passes,但请确保处理所有passes以获得我们希望的结果。

  • 相关阅读:
    POJ2965(The Pilots Brothers' refrigerator)
    POJ1753(Flip Game)
    POJ3253(Fence Repair)
    山东理工大学的训练计划
    loutsScript 常用代码
    《大道至简》读后感
    2019暑第三周
    2019暑第二周
    2019暑第一周
    关于13组作品《TD tree》的使用感想
  • 原文地址:https://www.cnblogs.com/wangyong/p/3105497.html
Copyright © 2011-2022 走看看