OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: I See Dead Kittehs.. part 1 - JaJDoo Shader Guide - Basics
View page
Source of version: 11
(current)
!:::Oh hai::: !:::or::: !:::Basic texturing::: !:::And::: !:::Multiple outputs::: {maketoc} !!Construction started Before we begin, let’s talk about how structs serve us in HLSL. Well, you probably guessed that sometimes we will want to return more than a single value from the programs. In order to do so, we usually use IN and OUT structs. (* IN and OUT not being keywords, just emphasis on my transmission). Take a look at the following declarations: {CODE(wrap="1", colors="c++")} // TEXCOORD[n] semantic will be explained shortly struct VertexIn { float4 pos : POSITION; float2 texco : TEXCOORD; }; struct VertexOut { float4 pos : POSITION; float2 texco : TEXCOORD; }; // structs are accessed like in C ([name].[field] = [new value] ) {CODE} in this example, I defined two structs: VertexIn and VertexOut, serving as input data for vertex program and its output object, respectively. It is somewhat accepted to use the same struct for vertex program output and pixel program input, since this follows the rendering flow in logic. But be warned, most of vertex output semantics are NOT acceptable as pixel input. You can only share VS output and PS input if you are not attempting to access variables using vertex output semantics in the pixel shader. Input and output structs can only contain accepted input and output semantics, other things (such as the shared matrices) must be passed as uniform. Take a careful look at the VS and PS in/out semantics. Review this link when you write your own shaders: http://msdn.microsoft.com/en-us/library/bb509647%28VS.85%29.aspx !!My textures, let me show you them Using the two structs we wrote above, we will start writing a simple texturing shader, and a few simple texture manipulating shaders. First of; how do we use our new structs as input and output for our programs? It goes like this: {CODE(wrap="1", colors="c++")} // remember to add the World-View-Projection matrix when exporting to OGRE VertexOut mainVS(VertexIn input) { VertexOut output = (VertexOut)0; // initialize with 0 values all over // put values to output before returning it; return output; } float4 mainPS(float2 uv : TEXCOORD ) : COLOR { }{CODE} Though it is not needed for our current program, I provided this example of struct usage. !!Sampler The second thing we will need before we can use a texture is an image sampler. A sampler is use to determine the specific color in a specific point along the mash. There are a few types of samplers; 1d, 2d, 3d and cubic (and something else that I forgot). For this program we will use the sampler2D. !!!Creating the sampler: We will have to define two things: a texture and the sampler. __Important note: Sampler2D and sampler2D are not the same!__ {CODE(wrap="1", colors="c++")}Texture [name]; // dx9 style declaration sampler2D [name] = sampler_state { Texture = < [name you defined] >; };{CODE} Load a texture for your material; After you define the texture and compile, the texture will appear on the material properties window (right side of the screen). Add some picture, preferably a lolcat. My texture is called xtex. Clicking on the value will allow you to load a picture. {IMG(src="display1813")}{IMG} !!!Changes: The pixel program (first time since we started) now gets input. It receives a texture coordinates (a float2: x + y or u + v, depends on who you ask) requested by the drawing loop. Now we need to use this coordinates with out sampler to draw the texture to the object; in order to do so we use a function called tex2D. Its input is: ( sampler-state, {LEX(pagename="UV Coordinates")}texture coordinates{LEX} ), and return the color value of that specific point of the picture. {IMG(src="display1814")}{IMG} …Result on a plane That’s about it. Now to complicate things… !!!Sampler stuff (somewhat not OGRE related) If you zoom in very close or out very far (or just look at the picture) you will notice it doesn’t mipmap nor does it interpolate values. The result is a very sharp edged texture. In order to change that we can set some basic sampler option. In the following I defined using a linear interpolation function for the sampler. {CODE(wrap="1", colors="c++")}// dx9 style declaration sampler2D [name] = sampler_state { Texture = < [name you defined] >; MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; }; {CODE} {IMG(src="display1816")}{IMG}{IMG(src="display1815")}{IMG} Before and after… left side uglier – srsly !!Exporting to ogre Although you do know how to move your code to OGRE already, there are a few things we must discuss. !!!The sampler You cannot declare the sampler as we did earlier when we move the code to OGRE. We need to pass it as uniform. …uniform sampler2D |name|… …In PS input. (You will not need to pass it from the material however, OGRE will handle that) {REMARKSBOX(type="tip",title="You know what box it is…")}Feeling smart? Want to learn more about samplers? http://msdn.microsoft.com/en-us/library/bb509644%28VS.85%29.aspx {REMARKSBOX} !!!The material You will also need to add a texture unit to your pass: {CODE(wrap="1", colors="c++")}………… pass { texture_unit { texture [texture name + extension] 2d // can also be 1d,3d or cubic ^ } ………… {CODE} !!About the input and output Note that you can numerate all input and output semantics (such as TEXCOOR1) This is used when more than one data is passed with the same semantic. This is important because data kept in TEXCOORn (for instance) will be the same data everywhere in the same execution of the shader (per vertex/pixel run). This means you don’t need to ‘physically’ pass things from vertex to pixel programs like you do when you share structs. Unlike in FXC, in OGRE, if you do not set TEXCOORD in the VS, it will be blank in the PS. (FXC spoils you here). Therefore all TEXCOORD data you wish to use in the PS will have to be return in the VS, even if not ‘physically’ linked with same struct. !!!first option: shared structs {CODE(wrap="1", colors="c++")}struct VertexIn { float4 pos : POSITION; float2 texco : TEXCOORD0; }; struct VertexOut { float4 pos : POSITION; float2 texco : TEXCOORD0; }; VertexOut mainVS( VertexIn input, uniform float4x4 worldViewProj_m) { VertexOut output = (VertexOut)0; output.pos = mul( input.pos, worldViewProj_m ); output.texco = input.texco; return output; } float4 mainPS( VertexOut input, uniform sampler2D image ) : COLOR { return tex2D(image, input.texco); } {CODE} While valid in all accounts, it can be volatile (since PS cannot accept POSITION semantic). You can pass it this way, but trying to use the VS output data that isn’t valid in PS will cause a critical error (as happens to many novice HLSL users trying to pass normals for the first time). !!!Second option: separate structs __NOTE: for teaching purposes, we will use this style throughout part one because it’s very organized and emphasize what can or cannot be sent from vertex program to pixel program.__ {CODE(wrap="1", colors="c++")}struct VertexIn { float4 pos : POSITION; float2 texco : TEXCOORD0; }; struct VertexOut { float4 pos : POSITION; float2 texco : TEXCOORD0; }; struct pixelInput { float2 texco : TEXCOORD0; }; VertexOut VS( VertexIn input, uniform float4x4 worldViewProj_m ) { VertexOut output = (VertexOut)0; output.pos = mul( worldViewProj_m, input.pos ); output.texco = input.texco; return output; } float4 PS( pixelInput input, uniform sampler2D image ) : COLOR0 { return tex2D( image, input.texco ); } {CODE} We create separate structs for pixel and vertex, and use TEXCOOR0 as a bridge – it is set in the vertex program and used in the pixel one. Although it’s the most organized method (to the eyes), it can get smaller shaders to use a lot of unneeded length. !!!Third option: in, out and inout keyword You either love and use it solely, or ignore it completely. You can define input arguments as either in, out or inout. In that method, you can define your programs with no return value (void). While appealing without being volatile, it might cause some confusion and a very lengthily input list. Here’s how it goes: This method is somewhat popular with GLSL users that use HLSL as well, since GLSL works like this. In arguments are just like any input you used so far, but will not be passed forward. Out arguments are received blank, and will be passed forward. Inout arguments are like in, but are passed forward like outs. Note that both out and inout must be declared as input argument as well. {CODE(wrap="1", colors="c++")} void VS( inout float4 pos : POSITION, inout float2 texco : TEXCOORD0, uniform float4x4 worldViewProj_m ) { pos = mul( worldViewProj_m, pos ); } void PS( in float2 texco : TEXCOORD0, out float4 finColor : COLOR, uniform sampler2D image ) { finColor = tex2D(image, texco); }{CODE} Each one of these methods has its ups and downs, choose to your liking. But again, pick one and stick with it.
Search by Tags
Search Wiki by Freetags
Latest Changes
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
...more
Search
Find
Advanced
Search Help
Online Users
123 online users