/*********************************************************************NVMH3****
$Revision$

Copyright NVIDIA Corporation 2007
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED
*AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES
WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.


To learn more about shading, shaders, and to bounce ideas off other shader
    authors and users, visit the NVIDIA Shader Library Forums at:

    http://developer.nvidia.com/forums/

******************************************************************************/

//// UN-TWEAKABLES - AUTOMATICALLY-TRACKED TRANSFORMS ////////////////

float4x4 WorldViewITXf : WorldViewInverseTranspose < string UIWidget="None"; >;
float4x4 WvXf : WorldView < string UIWidget="None"; >;
float4x4 ProjectionXf : Projection < string UIWidget="None"; >;

/// 2 * PI
#define PI_2 6.2831853071795864769252867665590057683943387987502

//// TWEAKABLE PARAMETERS ////////////////////

/// X Direction in Zebra Cylinder
float3 Xdir = float3(0, 1, 0);
/// Y Direction in Zebra Cylinder
float3 Ydir = float3(0, 0, 1);
/// Default to 12 stripes
float SampleSize = PI_2 / 12.0;
/// Equal spacing for on and off colors
float DutyCycle = 0.5;
/// The on color
float4 OnColor = float4(1,1,1,1);
/// The off color
float4 OffColor = float4(0,0,0,1);

//////// CONNECTOR DATA STRUCTURES ///////////

/* data from application vertex buffer */
struct appdata {
    float3 Position	: POSITION;
    float3 Normal	: NORMAL;
};

/* data passed from vertex shader to pixel shader */
struct vertexOutput {
    float4 HPosition	: SV_Position;
	float3 ViewPos		: TEXCOORD0;
	float3 ViewNormal   : TEXCOORD1;
};
 
///////// VERTEX SHADING /////////////////////

/*********** Generic Vertex Shader ******/

vertexOutput std_VS(appdata IN)
{
    vertexOutput OUT = (vertexOutput)0;
    OUT.ViewNormal = normalize(mul(IN.Normal,WorldViewITXf).xyz);
	float4 Po = float4(IN.Position,1);
    float4 Pv = mul(Po,WvXf);
	OUT.ViewPos = Pv.xyz;
    OUT.HPosition = mul(Pv,ProjectionXf);
    return OUT;
}

///////// PIXEL SHADING //////////////////////

// Utility function for gooch shading

float4 CylinderZebra(float3 R)
{
	float x = dot(Xdir,R);
	float y = dot(Ydir,R);
	float a = atan2(y,x);
	a = a < 0 ? a + PI_2 : a;
	a = fmod(a, SampleSize);
	return a < DutyCycle * SampleSize ? OnColor : OffColor;
}

float4 std_PS(vertexOutput IN) : SV_Target {
    float3 Vn = normalize(-IN.ViewPos);
    float3 Nn = normalize(IN.ViewNormal);
    float3 R = reflect(Vn,Nn);
	return CylinderZebra(R);
}

///// TECHNIQUES /////////////////////////////
technique10 ZebraStripes
{
    pass p0
    {
        SetVertexShader( CompileShader( vs_4_0, std_VS() ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, std_PS() ) );
    }
}

/////////////////////////////////////// eof //
