|
@@ -0,0 +1,113 @@
|
|
|
|
+float4x4 World;
|
|
|
|
+float4x4 View;
|
|
|
|
+float4x4 Projection;
|
|
|
|
+
|
|
|
|
+sampler TextureSampler : register(s0);
|
|
|
|
+
|
|
|
|
+float _OutlineWidth = 3;
|
|
|
|
+float4 _OutlineColor = float4(1, 1, 0, 1);
|
|
|
|
+float _ThresholdEnd = 0.25;
|
|
|
|
+float _OutlineSmoothness = 1.0;
|
|
|
|
+float _OutlineMipLevel = 0;
|
|
|
|
+
|
|
|
|
+// TODO: add effect parameters here.
|
|
|
|
+
|
|
|
|
+struct VertexShaderInput
|
|
|
|
+{
|
|
|
|
+ float4 Position : POSITION0;
|
|
|
|
+ float4 Color : COLOR0;
|
|
|
|
+ float4 TextureCoordinate : TEXCOORD0;
|
|
|
|
+ float4 Color2 : COLOR1;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct VertexShaderOutput
|
|
|
|
+{
|
|
|
|
+ float4 Position : POSITION0;
|
|
|
|
+ float4 Color : COLOR0;
|
|
|
|
+ float4 TextureCoordinate : TEXCOORD0;
|
|
|
|
+ float4 Color2 : COLOR1;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
|
|
|
|
+{
|
|
|
|
+ VertexShaderOutput output;
|
|
|
|
+
|
|
|
|
+ float4 worldPosition = mul(input.Position, World);
|
|
|
|
+ float4 viewPosition = mul(worldPosition, View);
|
|
|
|
+ output.Position = mul(viewPosition, Projection);
|
|
|
|
+ output.TextureCoordinate = input.TextureCoordinate;
|
|
|
|
+ output.Color = input.Color;
|
|
|
|
+ output.Color2 = input.Color2;
|
|
|
|
+
|
|
|
|
+ return output;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
|
|
|
|
+{
|
|
|
|
+ float4 texColor = tex2D(TextureSampler, input.TextureCoordinate);
|
|
|
|
+ float alpha = texColor.a * input.Color.a;
|
|
|
|
+ float4 output;
|
|
|
|
+ output.a = alpha;
|
|
|
|
+ output.rgb = ((texColor.a - 1.0) * input.Color2.a + 1.0 - texColor.rgb) * input.Color2.rgb + texColor.rgb * input.Color.rgb;
|
|
|
|
+
|
|
|
|
+ return output;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Outline pass
|
|
|
|
+#define _USE8NEIGHBOURHOOD_ON
|
|
|
|
+
|
|
|
|
+float4 PixelShaderFunctionOutline(VertexShaderOutput i) : COLOR0
|
|
|
|
+{
|
|
|
|
+ float4 texColor = float4(0,0,0,0);
|
|
|
|
+
|
|
|
|
+ float uvDeltaPerPixel = max(ddx(i.TextureCoordinate), ddy(i.TextureCoordinate));
|
|
|
|
+ float outlineWidthCompensated = _OutlineWidth * uvDeltaPerPixel;
|
|
|
|
+ float xOffset = outlineWidthCompensated;
|
|
|
|
+ float yOffset = outlineWidthCompensated;
|
|
|
|
+ float xOffsetDiagonal = outlineWidthCompensated * 0.7;
|
|
|
|
+ float yOffsetDiagonal = outlineWidthCompensated * 0.7;
|
|
|
|
+
|
|
|
|
+ float pixelCenter = tex2D(TextureSampler, i.TextureCoordinate).a;
|
|
|
|
+
|
|
|
|
+ float4 uvCenterWithLod = float4(i.TextureCoordinate.xy, 0, _OutlineMipLevel);
|
|
|
|
+ float pixelTop = tex2Dlod(TextureSampler, uvCenterWithLod + float4(0, yOffset, 0, 0)).a;
|
|
|
|
+ float pixelBottom = tex2Dlod(TextureSampler, uvCenterWithLod + float4(0, -yOffset, 0, 0)).a;
|
|
|
|
+ float pixelLeft = tex2Dlod(TextureSampler, uvCenterWithLod + float4(-xOffset, 0, 0, 0)).a;
|
|
|
|
+ float pixelRight = tex2Dlod(TextureSampler, uvCenterWithLod + float4(xOffset, 0, 0, 0)).a;
|
|
|
|
+#ifdef _USE8NEIGHBOURHOOD_ON
|
|
|
|
+ float numSamples = 8;
|
|
|
|
+ float pixelTopLeft = tex2Dlod(TextureSampler, uvCenterWithLod + float4(-xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
|
|
|
|
+ float pixelTopRight = tex2Dlod(TextureSampler, uvCenterWithLod + float4(xOffsetDiagonal, yOffsetDiagonal, 0, 0)).a;
|
|
|
|
+ float pixelBottomLeft = tex2Dlod(TextureSampler, uvCenterWithLod + float4(-xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
|
|
|
|
+ float pixelBottomRight = tex2Dlod(TextureSampler, uvCenterWithLod + float4(xOffsetDiagonal, -yOffsetDiagonal, 0, 0)).a;
|
|
|
|
+ float average = (pixelTop + pixelBottom + pixelLeft + pixelRight +
|
|
|
|
+ pixelTopLeft + pixelTopRight + pixelBottomLeft + pixelBottomRight)
|
|
|
|
+ * i.Color.a / numSamples;
|
|
|
|
+#else // 4 neighbourhood
|
|
|
|
+ float numSamples = 1;
|
|
|
|
+ float average = (pixelTop + pixelBottom + pixelLeft + pixelRight) * i.Color.a / numSamples;
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ float thresholdStart = _ThresholdEnd * (1.0 - _OutlineSmoothness);
|
|
|
|
+ float outlineAlpha = saturate((average - thresholdStart) / (_ThresholdEnd - thresholdStart)) - pixelCenter;
|
|
|
|
+ texColor.rgba = lerp(texColor, _OutlineColor, outlineAlpha);
|
|
|
|
+ return texColor;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+technique Technique1
|
|
|
|
+{
|
|
|
|
+ pass OutlinePass
|
|
|
|
+ {
|
|
|
|
+ // TODO: set renderstates here.
|
|
|
|
+
|
|
|
|
+ VertexShader = compile vs_3_0 VertexShaderFunction();
|
|
|
|
+ PixelShader = compile ps_3_0 PixelShaderFunctionOutline();
|
|
|
|
+ }
|
|
|
|
+ pass Pass2
|
|
|
|
+ {
|
|
|
|
+ // TODO: set renderstates here.
|
|
|
|
+
|
|
|
|
+ VertexShader = compile vs_2_0 VertexShaderFunction();
|
|
|
|
+ PixelShader = compile ps_2_0 PixelShaderFunction();
|
|
|
|
+ }
|
|
|
|
+}
|