Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Matrix */
- float4x4 xWorld;
- float4x4 xView;
- float4x4 xProjection;
- /* Lights */
- float4 xAmbientColor;
- float xAmbientIntensity;
- float3 xDiffuseDirection;
- float4 xDiffuseColor;
- float xDiffuseIntensity;
- bool xAmbientOnly; // If true, will not be affected by Diffuse.
- /* Shadows */
- bool xReceiveShadow;
- float4x4 xLightsWorldViewProjection;
- /* Textures */
- texture xTexture;
- texture xTexShadow;
- float xAlphaClipThreshold = 0.75;
- /* Other */
- float xAlpha; // Transparency.
- /* MAIN */
- struct MainVertexInput
- {
- float4 Position : POSITION0;
- float4 Normal : NORMAL0;
- float2 TextureCoordinate : TEXCOORD0;
- float4 Color : COLOR0;
- };
- // The output from the vertex shader, used for later processing
- struct MainVertexToPixel
- {
- float4 Position : POSITION0;
- float4 Pos2DAsSeenByLight : TEXCOORD0;
- float4 Normal : TEXCOORD1;
- float2 TextureCoordinate : TEXCOORD2;
- float4 Color : COLOR0;
- };
- /* SHADOWS */
- struct ShadowVertexToPixel
- {
- float4 Position : POSITION;
- float4 Position2D : TEXCOORD0;
- float2 TextureCoordinate : TEXCOORD1;
- };
- struct ShadowPixelToFrame
- {
- float4 Color : COLOR0;
- };
- // Used for the main mesh rendering.
- sampler2D MainSampler = sampler_state {
- Texture = (xTexture);
- MinFilter = Linear;
- MagFilter = Linear;
- AddressU = Wrap;
- AddressV = Wrap;
- };
- // Used when rendering meshes for Shadow Map.
- sampler2D ShadowMapSamplerPoint = sampler_state {
- Texture = (xTexture);
- MinFilter = POINT;
- MagFilter = POINT;
- AddressU = Wrap;
- AddressV = Wrap;
- };
- // Used when reading Shadow Map texture over the top of the world.
- sampler ShadowMapSamplerLinear = sampler_state {
- texture = (xTexShadow);
- magfilter = LINEAR;
- minfilter = LINEAR;
- mipfilter = LINEAR;
- AddressU = clamp;
- AddressV = clamp;
- };
- /*
- The VertexShader is used to manipulate vertex data.
- It gets a MainVertexInput object as input, and outputs a MainVertexToPixel object.
- */
- MainVertexToPixel MainVertexShader(MainVertexInput input)
- {
- MainVertexToPixel output;
- // Standard positioning code
- float4 worldPosition = mul(input.Position, xWorld);
- float4 viewPosition = mul(worldPosition, xView);
- output.Position = mul(viewPosition, xProjection);
- // Shadow
- output.Pos2DAsSeenByLight = mul(input.Position, xLightsWorldViewProjection);
- // Normals cannot be imported as float4s. The 4th value in a Normal must always be 0, or else weird calculations will happen.
- // Transform (rotate) the normal the same way that the model has been transformed and pass it to the Pixel Shader.
- output.Normal = mul(float4(input.Normal.xyz, 0), xWorld);
- output.TextureCoordinate = input.TextureCoordinate;
- output.Color = input.Color;
- return output;
- }
- /* The Pixel Shader manipulates all pixels of the model. Its input is the output from the Vertex Shader. */
- float4 MainPixelShader(MainVertexToPixel input) : COLOR0
- {
- float2 ProjectedTexCoords;
- ProjectedTexCoords[0] = input.Pos2DAsSeenByLight.x / input.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
- ProjectedTexCoords[1] = -input.Pos2DAsSeenByLight.y / input.Pos2DAsSeenByLight.w / 2.0f + 0.5f;
- // Intensity of the shadow on any shaded area.
- float diffuseLightingFactor = 0.6;
- if (xReceiveShadow)
- {
- // Clip the lighting only to the shaded area (not in use. I want all areas outside the shaded area to be fully lit).
- /*if ((saturate(ProjectedTexCoords).x == ProjectedTexCoords.x) &&
- (saturate(ProjectedTexCoords).y == ProjectedTexCoords.y))
- {*/
- float4 t = tex2D(ShadowMapSamplerLinear, ProjectedTexCoords);
- float depthStoredInShadowMap = t.r;
- float realDistance = input.Pos2DAsSeenByLight.z / input.Pos2DAsSeenByLight.w;
- // If the area is lit, then don't affect its lighting.
- if ((realDistance - 1.0f / 100.0f) <= depthStoredInShadowMap)
- {
- diffuseLightingFactor = 1;
- }
- //}
- }
- else
- {
- // This mesh won't receive shadows. Don't affect its lighting.
- diffuseLightingFactor = 1;
- }
- float4 diffuse = input.Color + xAmbientColor * xAmbientIntensity;
- // Only apply diffuse when necessary.
- if (!xAmbientOnly)
- {
- float4 normal = normalize(input.Normal);
- float4 NdotL = saturate(dot(normal, float4(-xDiffuseDirection, 1.0)));
- diffuse += NdotL;
- diffuse *= xDiffuseIntensity;
- }
- diffuse *= xDiffuseColor;
- float4 textureColor = tex2D(MainSampler, input.TextureCoordinate);
- float4 color = diffuse * textureColor * diffuseLightingFactor;
- // Cut off the sides of transparent textures.
- color.a = textureColor.a;
- clip(color.a < xAlphaClipThreshold ? -1 : 1);
- color.a *= xAlpha;
- return color;
- }
- // Simple vert to pixel. Textures are included to allow for more accurate shadows on meshes with transparent textures.
- ShadowVertexToPixel ShadowVertexShader(float4 inPos : POSITION, float2 textureCoordinate : TEXCOORD0)
- {
- ShadowVertexToPixel output = (ShadowVertexToPixel)0;
- output.Position = mul(inPos, xLightsWorldViewProjection);
- output.Position2D = output.Position;
- output.TextureCoordinate = textureCoordinate;
- return output;
- }
- ShadowPixelToFrame ShadowPixelShader(ShadowVertexToPixel input)
- {
- ShadowPixelToFrame output = (ShadowPixelToFrame)0;
- // Determine the alpha of each pixel (to cut out of the shadow if its transparent).
- float textureAlpha = tex2D(ShadowMapSamplerPoint, input.TextureCoordinate).a;
- clip(textureAlpha < xAlphaClipThreshold ? -1 : 1);
- output.Color = input.Position2D.z / input.Position2D.w;
- output.Color.a = textureAlpha;
- return output;
- }
- /**************/
- /* TECHNIQUES */
- /**************/
- // Draw the main scene (draw after drawing the ShadowMap technique).
- technique ShadowedScene
- {
- pass Pass1
- {
- VertexShader = compile vs_2_0 MainVertexShader();
- PixelShader = compile ps_2_0 MainPixelShader();
- }
- }
- // Draw the shadow map to a texture.
- technique ShadowMap
- {
- pass Pass2
- {
- VertexShader = compile vs_2_0 ShadowVertexShader();
- PixelShader = compile ps_2_0 ShadowPixelShader();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement