Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // file: ToonShader.fx
- //
- // summary: Toon Shader
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- ///////////////////////
- // Matrixs
- ///////////////////////
- /// <summary> The World Matrix.
- /// This information is sent to the shader from the engine
- /// and will use the engine World Matrix </summary>
- matrix World;
- /// <summary> same as the world matrix but this time with the
- /// View Matrix </summary>
- matrix View;
- /// <summary> same as the world matrix but this time with the
- /// Projection Matrix </summary>
- matrix Projection;
- ///////////////////////
- // Ambient Lighting
- ///////////////////////
- /// <summary> This is the Ambient lighting vaiables
- /// This can be defined outside of the shader
- /// but for not its best to leave a fixed version
- /// Variables:
- /// AmbientColor - Effects the colour of the ambiant lighting
- /// AmbientIntensity - How bright the ambiant lighting shines </summary>
- float4 AmbientColor = float4(1.0f, 1.0f, 1.0f, 1.0f); //eg rgba float4(1.0f, 1.0f, 1.0f, 1.0f);
- float AmbientIntensity = 0.5f; //eg 0.4f;
- ///////////////////////
- // Diffuse Lighting
- ///////////////////////
- /// <summary> This is the Diffuse lighting vaiables
- /// Variables:
- /// DiffuseColor - Effects the colour of the Diffuse lighting
- /// DiffuseIntensity - How bright the Diffuse lighting shines
- /// DiffuseLightDirection - The Direction of the Diffuse light </summary>
- float4 DiffuseColor = float4(1.0f, 1.0f, 1.0f, 1.0f); //eg rgba float4(1.0f, 1.0f, 1.0f, 1.0f);
- float DiffuseIntensity = 0.5f; //eg 0.4f
- float3 DiffuseLightDirection = float3(0.0f, 0.0f, 1.0f); //eg xyz float3(0.0f, 0.0f, 1.0f);
- int ShadingLevels = 4;
- float BorderThickness = 0.1f;
- float4 BorderColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
- float3 CameraPosition;
- ///////////////////////
- // Model Texture
- ///////////////////////
- /// <summary> The main texture for the model </summary>
- Texture2D ModelTexture;
- /// <summary> I am unsure what this does but from the looks of it
- /// it has something to do with how it gets the colour
- /// from the texture </summary>
- SamplerState SampleType
- {
- Filter = MIN_MAG_MIP_LINEAR;
- AddressU = Wrap;
- AddressV = Wrap;
- };
- ///////////////////////
- // Inputs and outputs
- // structures
- ///////////////////////
- /// <summary> This is the vertex shader structure.
- /// The vertex shader structure should be the same
- /// as the input layout described in engine </summary>
- struct VertexInputType
- {
- /// <summary> The position of the vertex
- /// xyzw. w is the scale default is guessed to be 1.0f
- /// to be sure you can just set w to 1.0f in the vertex
- /// shader. </summary>
- float4 Pos : POSITION0;
- /// <summary> The Colour of the vertex
- /// This is is not needed really but worth keeping </summary>
- float4 Color : COLOR0;
- /// <summary> Texture coordinates
- /// This is needed to place the texture onto the model </summary>
- float2 tex : TEXCOORD0;
- /// <summary> The normals are very important for lighting and other
- /// stuff such as bump maps. </summary>
- float3 Normal : NORMAL0;
- };
- /// <summary> This is the Pixel shader structure.
- /// The pixel shader structure will be obtained from
- /// vertex shader this has no effect on the vertex
- /// Layout of the engine it just happens this is the same
- /// as the vertex layout as it need all that information </summary>
- struct PixelInputType
- {
- float4 position : SV_POSITION;
- float2 tex : TEXCOORD0;
- float3 normal : NORMAL;
- float4 Color : COLOR0;
- };
- ///////////////////////
- // VertexShader pass0
- ///////////////////////
- /// <summary> Takes in a vertex shader structure called input </summary>
- PixelInputType VS(VertexInputType input)
- {
- /// <summary> A pixel shader structure is created
- /// called output this is what will be send to the
- /// pixel shader </summary>
- PixelInputType output;
- /// <summary> As I said about with the vertex structure the
- /// position also has a w value which is scale
- /// this is set to 1.0f which should be defualt </summary>
- input.Pos.w = 1.0f;
- /// <summary> Nothing really super special happens here but this
- /// is needed as it works out the vertex position based
- /// of the world then the view and then the projection </summary>
- output.position = mul(input.Pos, World);
- output.position = mul(output.position, View);
- output.position = mul(output.position, Projection);
- /// <summary> Stores the texture coord to the output as it will
- /// be needed by the pixel shader </summary>
- output.tex = input.tex;
- /// <summary> This i am a bit unsure of why it is needed but it works
- /// out the normal against the word matrix </summary>
- output.normal = mul(input.Normal, (float3x3)World);
- /// <summary> Agaian another area I am unsure since I have no idea
- /// what normalize does but it is a built in function
- /// of hlsl like mul. This just normalises the normals </summary>
- output.normal = normalize(output.normal);
- /// <summary> The colour of the vertex is set to the output colour </summary>
- output.Color = input.Color;
- /// <summary> returns the output which is sent to the pixel shader </summary>
- return output;
- }
- ///////////////////////
- // VertexShader pass0
- ///////////////////////
- /// <summary> This is where most of the magic happens visually as it works out the pixe
- /// output on the screen. This takes the output from the vertex shader </summary>
- float4 PS(PixelInputType input) : SV_Target//this SV_Target is impotant and would be COLOR0 in the old
- { //shader models
- //SV_Target can select a single type by calling
- //SV_Target0 to 3 (depending on the VS structure i beleive
- /// <summary> Determine the diffuse component by finding the angle between the light and the normal.
- /// The smaller the angle between the normal and the light direction, the closer the dot
- /// product will be to 1, and the brighter the pixel will be. </summary>
- float4 diffuse = dot( DiffuseLightDirection, input.normal ) * DiffuseIntensity * DiffuseColor;
- /// <summary> Calculate our ambient component </summary>
- float4 ambient = AmbientIntensity * AmbientColor;
- /// <summary> Return the total light component as a combination of the diffuse and ambient.
- // Saturate it to keep the color between 0 and 1. </summary>
- float4 color = saturate( diffuse + ambient );
- /// </summary>This is the important part of the toon shading and this is a great method I found from
- /// Daniel Greenheck @ Digit 7 allong with the lighting
- /// Unlike many other example which have set values which the shading should be
- /// this method allows x different shades of light. If later you decide toon lighting
- /// isn't so great you can change ShadingLevels to 100 and having it back to a smooth
- /// shading though it would not be recomended as you could do it without this calcluation<summary>
- /// <summary> Multiply by the number of shading levels so the color value can range from 0 to ShadingLevels </summary>
- color.rgb *= ShadingLevels;
- /// <summary> Round to the highest integer. This is what flattens out the color </summary>
- color.rgb = ceil(color.rgb);
- /// <summary> Redivide by the number of shading levels to normalize the values to between 0 and 1. </summary>
- color.rgb /= (float)ShadingLevels;
- /// <summary> Sample the pixel color from the texture using the sampler at this texture coordinate location </summary>
- float4 textureColor = ModelTexture.Sample(SampleType, input.tex);
- /// <summary> multiply the shading with the texture to get the result colour which will
- /// give the toon shaded look to a textured model </summary>
- color = color * textureColor;
- /// <summary> and finaly return the colour </summary>
- return color;
- }
- ///////////////////////
- // DepthShader
- ///////////////////////
- /// <summary> The Second part of this shader I took from a post on MSDN by
- /// ukstudentzine who used a depth normal map to produce the
- /// post process effect as it would make edge detection a lot easier </summary>
- /// <summary> Output structure for the vertex shader that renders normal and depth information. </summary>
- struct NormalDepthVertexShaderOutput
- {
- float4 Position : SV_POSITION;
- float2 tex : TEXCOORD0;
- float3 normal : NORMAL;
- float4 Color : COLOR0;
- };
- ///////////////////////
- // VertexShader pass1
- ///////////////////////
- // Alternative vertex shader outputs normal and depth values, which are then
- // used as an input for the edge detection filter in PostprocessEffect.fx.
- NormalDepthVertexShaderOutput VSN(VertexInputType input)
- {
- NormalDepthVertexShaderOutput output;
- /// <summary> As I said about with the vertex structure the
- /// position also has a w value which is scale
- /// this is set to 1.0f which should be defualt </summary>
- input.Pos.w = 1.0f;
- /// <summary> Nothing really super special happens here but this
- /// is needed as it works out the vertex position based
- /// of the world then the view and then the projection </summary>
- output.Position = mul(input.Pos, World);
- output.Position = mul(output.Position, View);
- output.Position = mul(output.Position, Projection);
- float3 worldNormal = mul(input.Normal, World);
- /// <summary> The output color holds the normal, scaled to fit into a 0 to 1 range. </summary>
- output.Color.rgb = (worldNormal + 1) / 2;
- /// <summary> The output alpha holds the depth, scaled to fit into a 0 to 1 range. </summary>
- output.Color.a = output.Position.z / output.Position.w;
- return output;
- }
- ///////////////////////
- // PixelShader pass1
- ///////////////////////
- /// <summary> Simple pixel shader for rendering the normal and depth information. </summary>
- float4 PSN(NormalDepthVertexShaderOutput input) : SV_Target
- {
- return input.Color;
- }
- ////////////////////////////////////////////////////////////////////////////////
- // Technique
- ////////////////////////////////////////////////////////////////////////////////
- /// <summary> I have kept the techniques seperate so they can be called seperatly without
- /// affecting the other effect. </summary>
- technique10 ToonShade
- {
- pass pass0
- {
- SetVertexShader(CompileShader(vs_4_0, VS()));
- SetPixelShader (CompileShader(ps_4_0, PS()));
- SetGeometryShader(NULL);
- }
- }
- technique10 DepthNorm
- {
- pass pass0
- {
- SetVertexShader(CompileShader(vs_4_0, VSN()));
- SetPixelShader (CompileShader(ps_4_0, PSN()));
- SetGeometryShader(NULL);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // End of ToonShader.fx
- ////////////////////////////////////////////////////////////////////////////////////////////////////
Advertisement
Add Comment
Please, Sign In to add comment