An Introduction to HLSL in XNA

本文通过两部分介绍了HLSL的基础知识,包括如何构建顶点和像素着色器,使用纹理映射到模型上,并设置渲染状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FW:  http://www.stromcode.com/2008/04/02/an-introduction-to-hlsl-part-i/

An Introduction to HLSL (Part I)

April 2, 2008

introtoshaders_title.jpgIn a previous article we looked at how to use custom shaders when rendering models, or as post-processing effects when applied to an entire scene. Now let’s look at how to build our own shaders.

<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script> width="468" scrolling="no" height="15" frameborder="0" allowtransparency="true" hspace="0" vspace="0" marginheight="0" marginwidth="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-4918349833220447&dt=1212402159164&lmt=1212402158&prev_slotnames=5585453236&output=html&slotname=2273068045&correlator=1212402158698&url=http%3A%2F%2Fwww.stromcode.com%2F2008%2F04%2F02%2Fan-introduction-to-hlsl-part-i%2F&ref=http%3A%2F%2Fwww.stromcode.com%2Fcategory%2Fxna%2F&frm=0&cc=100&ga_vid=2992875446891075600.1212401973&ga_sid=1212401973&ga_hid=1429208539&ga_fc=true&flash=0&u_h=900&u_w=1440&u_ah=870&u_aw=1440&u_cd=32&u_tz=480&u_his=1&u_java=true&u_nplug=13&u_nmime=40" name="google_ads_frame">

For this project, I’ll be using the same code from the Intro to Effects and Post-Processing article. This code is already set up to drop effects on models and to use effects as post-processors. So you’ll need to already know how to use effects in both contexts in order to follow along.

We’ll move through the non-HLSL stuff quickly. First, add a new effect file to your project. I keep all of mine in a content folder called FX. XNA builds a simple effect file template for you.

Let’s start with this template. If you build and run your project, you see something less than stellar.

040208_screen1.jpg
Our first boring effect

So let’s begin with this simple effect file and try to figure out what it’s doing.

First of all, every effect file consists of a vertex shader, and a pixel shader. In short, the vertex shader is able to manipulate a vertex property, like its location and its color. The pixel shader is receives the output of the vertex shader, and is able to perform per-pixel operations, which can mean lighting, coloring, texturing, multi-texturing, and so on.

This represents two of the three stages in the pixel processing pipeline. The missing stage, the geometry stage, sits between these two. XNA does not support geometry shaders, so we don’t need to worry about this stage. All we need to know is what happens between the vertex and pixel shader stages. Basically, once the vertices get transformed, colored, and so on by the vertex shader, the rasterizer converts the triangles in our primitives to pixels ready for the screen. Our pixel shader outputs the color of each pixel.

So if we look now at our default effect file, we can start tearing it apart.

Let’s look at the header first.

  1.  
  2. float4×4 World;
  3. float4×4 View;
  4. float4×4 Projection;
  5.  

This is where we specify what parameters we need passed in to our effect. Remember, that looks like this:

  1.  
  2. myEffect. Parameters [ "World" ]. SetValue (world );
  3. myEffect. Parameters [ "View" ]. SetValue (view );
  4. myEffect. Parameters [ "Projection" ]. SetValue (projection );
  5.  

That sets up the matrices that the vertex shader is going to need to to translate the raw vertices to their final, screen coordinates. Also note that the HLSL float4×4 and the XNA Matrix types are equivalent. We don’t need to do anything special to get our Matrix values ready for HLSL.

Next we’ve got a couple struct definitions:

  1.  
  2. struct VertexShaderInput {
  3.     float4 Position : POSITION0;
  4. };
  5.  
  6. struct VertexShaderOutput {
  7.     float4 Position : POSITION0;
  8. };
  9.  

Here we simply specify what the input and output of our vertex shader looks like. XNA will automatically pass in the correct values, and the correct amount of values, here. In this default effect, we’re only asking for the vertex position. We’ll use our three matrices to translate this position and then return the translated position. Consequently, our input and output structs are identical. Note here that a HLSL float4 type is identical to an XNA Vector4 type. Our vertex shaders may also process color. In that case, you’d want to add a float4 to the input and output structs for a RGBA color value.

After the struct definitions, we actually define out vertex shader function.

  1.  
  2. VertexShaderOutput VertexShaderFunction (VertexShaderInput input ) {
  3.     VertexShaderOutput output;    
  4.     float4 worldPosition = mul (input. Position, World );
  5.     float4 viewPosition = mul (worldPosition, View );
  6.     output. Position = mul (viewPosition, Projection );
  7.  
  8.     return output;
  9. }
  10.  

This is quite simple. We define a function that takes a VertextShaderInput struct as a parameter, and returns a VertexShaderOutput struct. Internally, it multiplies — via the mul() function — our vertex by the world, view and projection matrices, and returns the resulting vertex location. That’s it. This is something you’ve done using BasicEffect a bunch of times, and here’s what it looks like in HLSL.

Next, we define the pixel shader function:

  1.  
  2. float4 PixelShaderFunction (VertexShaderOutput input ) : COLOR0 {
  3.     return float4 ( 1, 0, 0, 1 );
  4. }
  5.  

Our pixel shader function returns a float4 (we could have defined this as a struct called PixelShaderOutput or something similar if we wanted). There is one new thing here though, the COLOR0 at the end of the function header. In fact, we saw that earlier, with POSITION0. What does that mean?

These are semantics. They basically define common elements between our game code, and our HLSL. Remember I said that the vertex position would get automatically passed in to our vertex shader without us having to do anything special? This is because the POSITION0 is a semantic meaning vertex position. The 0 at the end means, “the first one”. We can define POSITION1, COLOR3, or whatever depending on how many inputs to the function we’re going to have.

As for the pixel shader function, can you figure out what it does? I basically ignores the pixel position returned by the vertex shader, ignores whatever color data was associated with that pixel (since we never received the colors of the vertices, we couldn’t have done anything with it anyways), and returns a color value. In this case, it returns pure red with alpha 1.0.

The last step is to wrap this up into a technique, and a pass for that technique:

  1.  
  2. technique Main {
  3.     pass Pass0 {
  4.         VertexShader = compile vs_1_1 VertexShaderFunction ( );
  5.         PixelShader = compile ps_1_1 PixelShaderFunction ( );
  6.     }
  7. }
  8.  

We have one technique, called Main, which has one pass, called Pass0. And then we just tell it to compile a Vertex Shader 1.1 and a Pixel Shader 1.1 out of the two functions we’ve defined for each.

Well, that is the most basic introduction we could possibly do. We looked at the bare minimum of vertex and pixel shaders and made sense of the most basic effect file imaginable. In part 2, we’ll go a little deeper and actually make a shader that does something.

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值