float SpecPower <string Enable = "true"; > = 32;
texture tNewDiffuse < string TextureType = "2D"; >;
texture tEnvMap0 < string TextureType = "Cube"; >;
// Always include this in your shader files in order to have the core Engine-set variables available for use #include "Types.h" //----------------------------------------------------- // Our Basic Settings //----------------------------------------------------- // Defines a texture as exposed -- being settable -- within the 3dsmax shader tool and Reality Builder // Our Diffuse texture map texture tNewDiffuse < string TextureType = "2D"; >; // Exposed U and V tiling values for the diffuse texture float NewDiffuseUTile<string Enable = "true"; > = 1; float NewDiffuseVTile<string Enable = "true"; > = 1; // Sets up a texture sampler used by the pixel shader that contains the diffuse texture sampler sNewDiffuse = sampler_state { SRGBTexture = (useSRGB); Texture = (tNewDiffuse ); AddressU = Wrap; AddressV = Wrap; MinFilter = (texFilter); MagFilter = (texFilter); MaxAnisotropy = (maxAnisotropy); }; // Defines a texture as exposed -- being settable -- within the 3dsmax shader tool and Reality Builder // Our Bump texture map -- note this is actually expecting an RGB/RGBA normal map, NOT a greyscale bump map // (the terminology is often interchangeable, but all Reality bump maps must actually be as normal maps before used in shaders). texture tNewBump < string TextureType = "2D"; >; // Exposed U and V tiling values for the normal map texture float NewBumpUTile<string Enable = "true"; > = 1; float NewBumpVTile<string Enable = "true"; > = 1; // Sets up a texture sampler used by the pixel shader that contains the normal map texture sampler sNewBump = sampler_state { SRGBTexture = (useSRGB); Texture = (tNewBump ); AddressU = Wrap; AddressV = Wrap; MinFilter = (texFilter); MagFilter = (texFilter); MaxAnisotropy = (maxAnisotropy); }; //----------------------------------------------------------------------------- // Our New Shader //----------------------------------------------------------------------------- /* This is a structure that the Vertex Shader fills out and passes to the Pixel Shader. Effectively, by storing float values into up 8 float4 TexCoord slots (on ps 2.0), you can pass data from Vertex Shader calculations to the Pixel Shader. For this basic Diffuse NL shader, we need to pass the Light Tangent (for L), the Light Distance (for attenuation), the Base (Diffuse) and Bump xy texture coordinates, and the view-space transformation that will allow us to blend over previous pixels in the framebuffer in secondary passes (more on this below). Thus, you can see the NewShader_Point_Pixel strcuture contains 4 TexCoords to store those data. The Position and Fog members are required to fill out in the Vertex Shader, as they determine the basic transformation of the vertex (this can be altered in a Vertex Shader supporting character animation), and its D3D fog value (which we don't use, instead fog can more effectively be calculated in the pixel shader).*/ struct NewShader_Point_Pixel { float3 LightTangent : TEXCOORD0; float3 LightDist : TEXCOORD1; float4 BaseAndBump : TEXCOORD2; float4 Pos : TEXCOORD3; float4 Position : POSITION; float Fog : FOG; }; // Our simple Diffuse NL Vertex Shader takes the standard Vertex structure as input. NewShader_Point_Pixel V_NewShader_Point( Vertex IN) { // Declares the structure to fill out and return NewShader_Point_Pixel OUT; // Transforms (multiplies) the texture coordinate by the tiling values for Diffuse and Bump maps, // and stores these in the appropriate output vars to pass to Pixel Shader OUT.BaseAndBump.xy = Transform(IN.TexCoord0,float2(NewDiffuseUTile, NewDiffuseVTile)); OUT.BaseAndBump.zw = Transform(IN.TexCoord0,float2(NewBumpUTile, NewBumpVTile)); // Located in Types.h, this handy function sets the LightTangent and LightDistanace based on // the passed Vertex structure, and the Light vars defined in Types.h CalculateLighting(IN,OUT.LightTangent,OUT.LightDist); // Transforms the Vertex into view space OUT.Position = mul(IN.Pos,mWorldViewProjection); // We also want to retain this transformation for access in the Pixel Shader, why we do so is described below in the Pixel Shader OUT.Pos = OUT.Position; // No fog, a more complex shader would just apply per-pixel fog in the Pixel Shader using the appropriate Types.h function OUT.Fog = 1;; // return our fully filled structure to pass to the Pixel Shader return OUT; } // Take the Vertex Shader's output structure as input float4 P_NewShader_Point( NewShader_Point_Pixel IN ) : COLOR { // Select the Diffuse pixel color according to the current diffuse texture coordinate float4 Diffuse = tex2D(sNewDiffuse, IN.BaseAndBump.xy); // Select the Bump pixel color according to the current bump map texture coordinate float4 Bump = tex2D(sNewBump, IN.BaseAndBump.zw); // All normalizations and length-dependent calculations should be done in the Pixel Shader, // not the Vertex Shader, so that per-pixel length values are employed float3 L = normalize(IN.LightTangent); // Returns the Normal in tangent space (the R and G components of the bump map equate to X and Y Vector components) float3 N = GetNormal(Bump); // The dot product of the LightTangent and the Normal determines a factor of the brightness of the light on the surface // Saturate to avoid negative values (a surface facing away from the incident Light should not be lit at all) float NL = saturate(dot(N,L)); // Multiply out our values, factoring in attenation // the GetAttenuation function returns a clamped 0 to 1 attenuation based on a Light's spherical radius, // 1 being at the center of the Light and 0 being anywhere beyond its radius. float4 color = float4(Diffuse.rgb*LightColor.rgb*NL*GetAttenuation(IN.LightDist),1); // We use IN.Pos view-space transformation to get the corresponding pixel in the HDR Color Buffer to do a manual color blend, // since HDR Alpha Blending is not supported in ps 2.0. bHDRBlend, set by the Engine, is only true on secondary passes. if(bHDRBlend) color = color + GetColorBuffer(IN.Pos); // return the final color and we're done! return color; } // This technique name is what you'll see listed in Reality Builder as a selectable technique when you open the shader fx file technique NewShaderPoint { pass p0 { alphablendenable = (0); AlphaTestEnable = (0); SrcBlend = (SourceBlend); DestBlend = (DestBlend); vertexshader = compile vs_2_0 V_NewShader_Point(); pixelshader = compile ps_2_0 P_NewShader_Point(); } }