//
// Project:
//
// D3D RightMark
//
// Description:
//
// Effect file for "Pixel Shading 4 Arithmetic" test.
//
// Effect Version:
//
// DirectX 10.0 (Apr 2007 SDK Update)
//
// Shader Profile:
//
// Pixel Shaders 4.0
//
// Vertex Shaders 4.0
//
//
// Global Variables
//
cbuffer cb0
{
float fGeometryScale = 0.01;
float fMaterialPower = 32.0;
float fPI = 3.14159;
}
// Light
struct rm_light
{
float4 vPosition;
float4 vDiffuse;
float4 vSpecular;
float fAttenuation;
};
cbuffer cb1
{
rm_light Light;
float4 vCameraPos; // Camera Position
float4x4 mW; // World Matrix
float4x4 mWVP; // World * View * Projection Matrix
float fTime;
int nShaderType;
bool nSSAA;
}
// Textures
Texture1D texLookup;
Texture2D texNormal;
//
// Samplers
//
SamplerState AnisoSampler
{
Filter = ANISOTROPIC;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
MaxAnisotropy = 16;
};
SamplerState LinearSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
SamplerState LinearClampSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
AddressW = Clamp;
};
SamplerState PointSampler
{
Filter = MIN_MAG_MIP_POINT;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
};
//-----------------------------------------------------------------------------------------
// State Structures
//-----------------------------------------------------------------------------------------
BlendState NoBlending
{
AlphaToCoverageEnable = FALSE;
BlendEnable[0] = FALSE;
};
RasterizerState CullBack
{
CullMode = Back;
};
//
// Shaders
//
struct VS_IN
{
float4 vPosition : POSITION;
float2 vTexCoord : TEXCOORD;
float3 vNormal : NORMAL;
};
//
// Marble Shader ( (c) Paul Baker )
//
struct MINERAL_DATA
{
float4 vPosition : SV_POSITION;
float3 vTexCoord : TEXCOORD0;
float3 vNormal : TEXCOORD1;
float3 vView : TEXCOORD2;
float3 vLight : TEXCOORD3;
float2 vBumpCoord : TEXCOORD4;
};
MINERAL_DATA MineralVS( VS_IN In )
{
MINERAL_DATA o;
// Vertex Position -> World Space
float4 vPositionWorld = mul( In.vPosition, mW );
// Output the 3d texture coords
o.vTexCoord = (In.vPosition.xyz + 100.0) * 0.0008;
// Calculate the world space normal
o.vNormal = mul( In.vNormal.xyz, mW );
// View Vector
o.vView = vPositionWorld - vCameraPos.xyz;
// Light Vector
o.vLight = ( Light.vPosition.xyz - vPositionWorld * fGeometryScale ) * Light.fAttenuation;
// Bump coords
o.vBumpCoord = In.vTexCoord;
// Position
o.vPosition = mul( In.vPosition, mWVP );
// Finalize
return o;
}
float Random(float3 vCoord)
{
int3 rnd = (int)(vCoord * 1000000);
return (float)( ((rnd.x * rnd.y + rnd.z) >> 16) & 0x7fff ) / 32767.0;
}
float GetWeight(float3 vCoord)
{
float3 c = saturate(vCoord);
return 4.0 *
( 1 - ( 3*c.x*c.x - 2*c.x*c.x*c.x ) ) *
( 1 - ( 3*c.y*c.y - 2*c.y*c.y*c.y ) ) *
( 1 - ( 3*c.z*c.z - 2*c.z*c.z*c.z ) );
}
float3 GetGradient(float3 vCoord)
{
float phi = 2.0 * fPI * Random(vCoord);
float theta = fPI * Random(vCoord);
float sin_phi, cos_phi;
float sin_theta, cos_theta;
sincos(phi, sin_phi, cos_phi);
sincos(theta, sin_theta, cos_theta);
return float3(
cos_theta * cos_phi,
cos_theta * sin_phi,
sin_theta);
}
const float3 c_GridOffset[8] = {
float3( 0, 0, 0 ),
float3( 0.015625, 0.0, 0.0 ),
float3( 0.0, 0.015625, 0.0 ),
float3( -0.015625, 0.0, 0.0 ),
float3( 0.0,-0.015625, 0.015625 ),
float3( 0.015625, 0.0, 0.0 ),
float3( 0.0, 0.015625, 0.0 ),
float3( -0.015625, 0.0, 0.0 ),
};
float4 MineralPS( MINERAL_DATA In ) : SV_TARGET
{
// LIGHTING CALCULATIONS
float3 normal = normalize( In.vNormal );
float3 view = normalize( In.vView );
float3 light = normalize( In.vLight );
float attenuation = saturate( 1.0 - dot( In.vLight, In.vLight ) );
normal = texNormal.Sample( AnisoSampler, In.vBumpCoord ) * 2 - 1;
// Calculate L dot N (world space) and add ambient
float diffuse = saturate( saturate( dot( light, normal ) ) + 0.4 );
// Calculate the reflection vector, R=2(L.N)N-L
float3 reflection = reflect( normal, light );
// Calculate R dot V (world space)
float specular = saturate( dot( reflection, view ) );
// Calculate the lighting contributions
specular = pow( specular, fMaterialPower );
// TEXTURE CALCULATIONS
float3 noise = 0;
float3 noise2 = 0;
// Calculate the position of one grid corner of the cube
float3 gridCorner = floor( In.vTexCoord * 64.0 ) * 0.015625;
for ( int i = 0; i < 8; ++i )
{
gridCorner += c_GridOffset[i];
// Sample the gradient texture at this point
float3 gradient = GetGradient( gridCorner );
// Calculate the vector from the grid corner
float3 cornerVector = ( In.vTexCoord - gridCorner ) * 64.0;
// Dot the vector with the gradient
float gradientDotCornerVector = dot( cornerVector, gradient );
// Look up the weighting factor this corner will have on the result
float3 absCornerVector = abs( cornerVector );
float3 weighting = GetWeight( absCornerVector );
// Bias the dot product by the weighting factor and save in noise
noise += gradientDotCornerVector * weighting;
}
// Now repeat for the second octave, using iTexCoords*2 and saving the result in noise2
gridCorner = floor( 2 * In.vTexCoord * 64.0 ) * 0.015625;
for ( int i = 0; i < 8; ++i )
{
gridCorner += c_GridOffset[i];
// Sample the gradient texture at this point
float3 gradient = GetGradient( gridCorner );
// Calculate the vector from the grid corner
float3 cornerVector = ( In.vTexCoord - gridCorner ) * 64.0;
// Dot the vector with the gradient
float gradientDotCornerVector = dot( cornerVector, gradient );
// Look up the weighting factor this corner will have on the result
float3 absCornerVector = abs( cornerVector );
float3 weighting = GetWeight( absCornerVector );
// Bias the dot product by the weighting factor and save in noise
noise2 += gradientDotCornerVector * weighting;
}
// Final noise value
noise = noise + 0.5 * noise2;
// Calculate sin(120*(iTexCoords.x+iTexCoords.z)+3*noise) to get marble effect
noise *= 3;
noise += 120 * In.vTexCoord.x;
noise += 120 * In.vTexCoord.z;
noise = sin( noise.x );
// Scale and bias the texture coordinate from [-1, 1] to [0, 1]
noise = noise * 0.65 + 0.35;
// Look up color in 1d texture
noise = texLookup.SampleLevel( LinearSampler, noise, 0 );
// Modulate the result by the diffuse lighting and add specular
return float4( attenuation * (diffuse * noise + specular), 1);
}
//
// Noise-based fire shader
//
struct FIRE_DATA
{
float4 vPosition : SV_POSITION;
float3 vTexCoord0 : TEXCOORD0;
float3 vTexCoord1 : TEXCOORD1;
};
FIRE_DATA FireVS( VS_IN In )
{
FIRE_DATA o;
// Position
o.vPosition = mul( In.vPosition, mWVP );
// Output the 3d texture coords
o.vTexCoord0 = (In.vPosition.yzx + 100.0 - fTime * 15) * 0.0018;
o.vTexCoord1 = (In.vPosition.yzx + 100.0 - fTime * 6) * 0.00021;
// Finalize
return o;
}
float4 FirePS ( FIRE_DATA In ) : SV_TARGET
{
// TEXTURE CALCULATIONS
float noises[4];
for ( int j = 0; j < 4; ++j )
{
// Calculate the position of one grid corner of the cube
noises[j] = 0;
float3 texCoord = ((j & 1) + 1) * ((j & 2) ? In.vTexCoord1 : In.vTexCoord0);
float3 gridCorner = floor( texCoord * 64.0 ) * 0.015625;
for ( int i = 0; i < 8; ++i )
{
gridCorner += c_GridOffset[i];
// Sample the gradient texture at this point
float3 gradient = GetGradient( gridCorner );
// Calculate the vector from the grid corner
float3 cornerVector = ( texCoord - gridCorner ) * 64.0;
// Dot the vector with the gradient
float gradientDotCornerVector = dot( cornerVector, gradient );
// Look up the weighting factor this corner will have on the result
float3 absCornerVector = abs( cornerVector );
float3 weighting = GetWeight( absCornerVector );
// Bias the dot product by the weighting factor and save in noise
noises[j] += gradientDotCornerVector * weighting;
}
}
float3 noise[2];
for ( int j = 0; j < 2; ++j )
{
noise[j] = noises[j*2] + 0.5 * noises[j*2+1];
// Calculate sin(120*(iTexCoords.x+iTexCoords.z)+3*noise) to get marble effect
float3 texCoord = (j & 1) ? In.vTexCoord1 : In.vTexCoord0;
noise[j] *= 3;
noise[j] += 120 * texCoord.x;
noise[j] += 120 * texCoord.z;
noise[j] = sin( noise[j].x );
}
// Final noise value
float3 fnoise = lerp( noise[0], noise[1], 0.7 );
// Scale and bias the texture coordinate from [-1, 1] to [0, 1]
fnoise = fnoise * 0.65 + 0.35;
// Look up color in 1d texture
fnoise = texLookup.SampleLevel( LinearSampler, fnoise, 0 );
if ( fnoise.x < 0.2 ) discard;
return float4( fnoise, 1);
}