float4 ps_main( float4 Diff: COLOR0 ) : COLOR
{
return 1;
}
sampler RT;
const float off = 1.0 / 256.0;
float4 ps_main( float2 TexCoord : TEXCOORD0 ) : COLOR
{
// Sample the neighbor pixels
float s00 = tex2D(RT, TexCoord + float2(-off, -off));
float s01 = tex2D(RT, TexCoord + float2( 0, -off));
float s02 = tex2D(RT, TexCoord + float2( off, -off));
float s10 = tex2D(RT, TexCoord + float2(-off, 0));
float s12 = tex2D(RT, TexCoord + float2( off, 0));
float s20 = tex2D(RT, TexCoord + float2(-off, off));
float s21 = tex2D(RT, TexCoord + float2( 0, off));
float s22 = tex2D(RT, TexCoord + float2( off, off));
// Sobel filter in X and Ydirection
float sobelX = s00 + 2 * s10 + s20 - s02 - 2 * s12 - s22;
float sobelY = s00 + 2 * s01 + s02 - s20 - 2 * s21 - s22;
// Find edge
float edgeSqr = (sobelX * sobelX + sobelY * sobelY);
return 1.0-(edgeSqr > 0.07 * 0.07);
}
float4x4 view_proj_matrix;
float depthScale;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float texCoord: TEXCOORD;
};
VS_OUTPUT main(float4 Pos: POSITION)
{
VS_OUTPUT Out;
// Transform vertex position
Out.Pos = mul(view_proj_matrix, Pos);
// Pass the scaled depth value as a texture coordinate
Out.texCoord = depthScale * Out.Pos.z;
return Out;
}
float4 main(float depth: TEXCOORD) : COLOR
{
// Simply output the depth to the texture as a color
return depth;
}
判读边缘的条件变成视线和法线的夹角。
float edge = 1 - (dot(Normal,ViewVec)>0.07);
float4x4 view_proj_matrix;
float4 Light1_Position;
float4 Light1_Attenuation;
float4 Light1_Color;
struct VS_OUTPUT
{
float4 Pos: POSITION;
float2 TexCoord: TEXCOORD0;
float2 Color: COLOR0;
};
float4 Light_PointDiffuse(float3 VertPos, float3 VertNorm, float3 LightPos,
float4 LightColor, float4 LightAttenuation)
{
// Determine the distance from the light to the vertex and the direction
float3 LightDir = LightPos - VertPos;
float Dist = length(LightDir);
LightDir = LightDir / Dist;
// Compute distance based attenuation. This is defined as:
// Attenuation = 1 / ( LA.x + LA.y*Dist + LA.z*Dist*Dist )
float DistAttn = clamp(0,1, 1 / ( LightAttenuation.x +
LightAttenuation.y * Dist +
LightAttenuation.z * Dist * Dist ));
// Compute suface/light angle based attenuation defined as dot(N,L)
// Note : This must be clamped as it may become negative.
float AngleAttn = clamp(0, 1, dot(VertNorm, LightDir) );
// Compute final lighting
return LightColor * DistAttn * AngleAttn;
}
VS_OUTPUT vs_main(float4 inPos: POSITION, float3 inNormal: NORMAL,float2 inTxr: TEXCOORD0)
{
VS_OUTPUT Out;
// Compute the projected position and send out the texture coordinates
Out.Pos = mul(view_proj_matrix, inPos);
Out.TexCoord = inTxr;
// Output the ambient color
float4 Color = float4(0.4,0.4,0.4,1);
// Compute light contribution
Color += Light_PointDiffuse(inPos, inNormal, Light1_Position,
Light1_Color, Light1_Attenuation);
// Output Final Color
Out.Color = Color;
return Out;
}
sampler Texture0;
float4 ps_main( float2 Tex: TEXCOORD0, float4 Diffuse:COLOR0) : COLOR
{
// Clamp diffuse to a fixed set of values and modulate with
// the texture color
Diffuse = (int)(Diffuse * 4) / 4.0;
return Diffuse*tex2D(Texture0, Tex);
}
结果
在shader中用两个float3来记录每个贴图的blend值,其实函数根据diffuse的光强。
float hatchFactor = diffuse * 6.0;
float4 Light_Direction;
float4x4 view_matrix;
float4x4 view_proj_matrix;
struct VS_OUTPUT
{
float4 Pos : POSITION0;
float2 TexCoord : TEXCOORD0;
float3 HatchWeights0 : TEXCOORD1;
float3 HatchWeights1 : TEXCOORD2;
};
VS_OUTPUT vs_main( float4 inPos: POSITION0, float3 inNormal: NORMAL0,
float2 inTexCoord : TEXCOORD0 )
{
VS_OUTPUT Out;
// Compute projected position and transfer texture
// coordinates for the object
Out.Pos = mul( view_proj_matrix, inPos );
Out.TexCoord = inTexCoord;
// Determine a simple diffuse lighting component based
// on a directional light in view space
float3 pos_world = mul( view_matrix, inPos );
float3 normal_world = normalize(mul( (float3x3)view_matrix,
inNormal ));
float diffuse = min(1.0,max(0,dot(-Light_Direction,normal_world)));
diffuse = diffuse * diffuse;
diffuse = diffuse * diffuse;
float hatchFactor = diffuse * 6.0;
float3 weight0 = 0.0;
float3 weight1 = 0.0;
// Determine the weights for the hatch textures based on the
// hatch factor which is simply proportional to the diffuse
// lighting. In other words, the more lit the object, the less
// dense the hatching will be.
if (hatchFactor>5.0) { weight0.x = 1.0; }
else if (hatchFactor>4.0)
{
weight0.x = 1.0 - (5.0 - hatchFactor);
weight0.y = 1.0 - weight0.x;
}
else if (hatchFactor>3.0)
{
weight0.y = 1.0 - (4.0 - hatchFactor);
weight0.z = 1.0 - weight0.y;
}
else if (hatchFactor>2.0)
{
weight0.z = 1.0 - (3.0 - hatchFactor);
weight1.x = 1.0 - weight0.z;
}
else if (hatchFactor>1.0)
{
weight1.x = 1.0 - (2.0 - hatchFactor);
weight1.y = 1.0 - weight1.x;
}
else if (hatchFactor>0.0)
{
weight1.y = 1.0 - (1.0 - hatchFactor);
weight1.z = 1.0 - weight1.y;
}
Out.HatchWeights0 = weight0;
Out.HatchWeights1 = weight1;
return Out;
}
sampler Hatch0;
sampler Hatch1;
sampler Hatch2;
sampler Hatch3;
sampler Hatch4;
sampler Hatch5;
sampler Base;
float4 ps_main( float2 TexCoord: TEXCOORD0,
float3 HatchWeights0: TEXCOORD1,
float3 HatchWeights1 : TEXCOORD2) : COLOR
{
// Sample eatch hatch texture based on the object's texture
// coordinates and weight the pattern based on the factor
// determined from the lighting.
float4 hatchTex0 = tex2D(Hatch0,TexCoord) * HatchWeights0.x;
float4 hatchTex1 = tex2D(Hatch1,TexCoord) * HatchWeights0.y;
float4 hatchTex2 = tex2D(Hatch2,TexCoord) * HatchWeights0.z;
float4 hatchTex3 = tex2D(Hatch3,TexCoord) * HatchWeights1.x;
float4 hatchTex4 = tex2D(Hatch4,TexCoord) * HatchWeights1.y;
float4 hatchTex5 = tex2D(Hatch5,TexCoord) * HatchWeights1.z;
// Combine all patterns, the final color is simply the sum
// of all hatch patterns.
float4 hatchColor = hatchTex0 +
hatchTex1 +
hatchTex2 +
hatchTex3 +
hatchTex4 +
hatchTex5;
return hatchColor;
}