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以获得我们希望的结果。

  • 相关阅读:
    从零开始入门 K8s | 应用编排与管理
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    203. Remove Linked List Elements
    183. Customers Who Never Order
    182. Duplicate Emails
    181. Employees Earning More Than Their Managers
    1261. Find Elements in a Contaminated Binary Tree
    1260. Shift 2D Grid
  • 原文地址:https://www.cnblogs.com/wangyong/p/3105497.html
Copyright © 2011-2022 走看看