FFP shader and cleanup.

This commit is contained in:
Nick Blakely 2020-10-31 17:05:48 -07:00
parent a2b2fae204
commit e91ca889cd
4 changed files with 814 additions and 2 deletions

345
Shaders/fx/FFP.fx Normal file
View File

@ -0,0 +1,345 @@
//======================================================================================//
// filename: FixedFuncShader.fx //
// //
// author: Pedro V. Sander //
// ATI Research, Inc. //
// 3D Application Research Group //
// email: psander@ati.com //
// //
// Description: A programmable shader that emulates the fixed function pipeline //
// //
//======================================================================================//
// (C) 2003 ATI Research, Inc. All rights reserved. //
//======================================================================================//
#define PI 3.14f
//this file contains light, fog, and texture types
// (originally a include, inserted here)
#define NUM_LIGHTS 5
#define LIGHT_TYPE_NONE 0
#define LIGHT_TYPE_POINT 1
#define LIGHT_TYPE_SPOT 2
#define LIGHT_TYPE_DIRECTIONAL 3
#define LIGHT_NUM_TYPES 4
#define FOG_TYPE_NONE 0
#define FOG_TYPE_EXP 1
#define FOG_TYPE_EXP2 2
#define FOG_TYPE_LINEAR 3
#define FOG_NUM_TYPES 4
#define TEX_TYPE_NONE 0
#define TEX_TYPE_CUBEMAP 1
#define TEX_NUM_TYPES 2
#define TEXGEN_TYPE_NONE 0
#define TEXGEN_TYPE_CAMERASPACENORMAL 1
#define TEXGEN_TYPE_CAMERASPACEPOSITION 2
#define TEXGEN_TYPE_CAMERASPACEREFLECTIONVECTOR 3
#define TEXGEN_NUM_TYPES 4
// Structs and variables with default values
//fog settings
int iFogType = FOG_TYPE_LINEAR;
float4 vFogColor = float4(0.0f, 0.0f, 0.0f, 0.0f);
float fFogStart = 0;
float fFogEnd = 8845.00000;
float fFogDensity = .02f;
bool bFogRange : register(b4) = true;
int iTexType = TEX_TYPE_NONE;
int iTexGenType = TEXGEN_TYPE_NONE;
int g_NumLights;
struct DirectionalLight
{
float4 Diffuse;
float4 Specular;
float4 Ambient;
float3 Position;
float3 Direction;
};
struct Material
{
float4 Diffuse;
float4 Ambient;
float4 Specular;
float4 Emissive;
float Power;
};
DirectionalLight DirectionalLights[2] : DirectionalLights =
{
{
float4(0.398, 0.391, 0.523, 0.764),
float4(0.398, 0.391, 0.523, 0.764),
float4(0.398, 0.391, 0.523, 0.764),
float3(-1141, -182, 133),
float3(0.93, 0.35, 0)
},
{
float4(0.434, 0.402, 0.398, 0.712),
float4(0.434, 0.402, 0.398, 0.712),
float4(0.434, 0.402, 0.398, 0.712),
float3(-1138, -168, 133),
float3(-0.75, -0.165, -0.633)
},
};
Material g_Material : Material;
//transformation matrices
float4x4 matWorldViewProjection : WorldViewProjection;
float4x4 matWorldView : WorldView;
float4x4 matView : View;
float4x4 matWorld : World;
float4x4 matProjection : Projection;
float4x4 matWorldViewIT : WorldViewInverseTranspose;
float4x4 matViewIT : ViewInverseTranspose;
//function output structures
struct VS_OUTPUT
{
float4 Pos : POSITION;
float4 Color : COLOR0;
float4 ColorSpec : COLOR1;
float4 Tex0 : TEXCOORD0;
float Fog : FOG;
};
struct COLOR_PAIR
{
float4 Color : COLOR0;
float4 ColorSpec : COLOR1;
};
//-----------------------------------------------------------------------------
// Name: DoDirLight()
// Desc: Directional light computation
//-----------------------------------------------------------------------------
COLOR_PAIR DoDirLight(float3 N, float3 V, int i)
{
COLOR_PAIR Out;
float3 L = mul((float3x3)matViewIT, -normalize(DirectionalLights[i].Direction));
float NdotL = dot(N, L);
Out.Color = 0;// DirectionalLights[i].Ambient;
Out.ColorSpec = 0;
if(NdotL > 0.f)
{
//compute diffuse color
Out.Color += NdotL * DirectionalLights[i].Diffuse;
//add specular component
if(g_Material.Power > 0)
{
float3 H = normalize(L + V); //half vector
Out.ColorSpec = pow(max(0, dot(H, N)), g_Material.Power) * DirectionalLights[i].Specular;
}
}
return Out;
}
//-----------------------------------------------------------------------------
// Name: DoPointLight()
// Desc: Point light computation
//-----------------------------------------------------------------------------
//COLOR_PAIR DoPointLight(float4 vPosition, float3 N, float3 V, int i)
//{
// float3 L = mul((float3x3)matViewIT, normalize((lights[i].vPos-(float3)mul(matWorld,vPosition))));
// COLOR_PAIR Out;
// float NdotL = dot(N, L);
// Out.Color = lights[i].vAmbient;
// Out.ColorSpec = 0;
// float fAtten = 1.f;
// if(NdotL >= 0.f)
// {
// //compute diffuse color
// Out.Color += NdotL * lights[i].vDiffuse;
//
// //add specular component
// if(bSpecular)
// {
// float3 H = normalize(L + V); //half vector
// Out.ColorSpec = pow(max(0, dot(H, N)), fMaterialPower) * lights[i].vSpecular;
// }
//
// float LD = length(lights[i].vPos-(float3)mul(matWorld,vPosition));
// if(LD > lights[i].fRange)
// {
// fAtten = 0.f;
// }
// else
// {
// fAtten *= 1.f/(lights[i].vAttenuation.x + lights[i].vAttenuation.y*LD + lights[i].vAttenuation.z*LD*LD);
// }
// Out.Color *= fAtten;
// Out.ColorSpec *= fAtten;
// }
// return Out;
//}
//-----------------------------------------------------------------------------
// Name: vs_main()
// Desc: The vertex shader
//-----------------------------------------------------------------------------
VS_OUTPUT vs_main (float4 vPosition : POSITION0,
float3 vNormal : NORMAL0,
float2 tc : TEXCOORD0)
{
VS_OUTPUT Out = (VS_OUTPUT) 0;
vNormal = normalize(vNormal);
Out.Pos = mul(vPosition, matWorldViewProjection);
float3 P = mul(matWorldView, vPosition); //position in view space
float3 N = mul((float3x3)matWorldViewIT, vNormal); //normal in view space
float3 V = -normalize(P); //viewer
//automatic texture coordinate generation
Out.Tex0.xy = tc;
/*Out.Tex0 = float4((2.f * dot(V,N) * N - V) * (iTexGenType == TEXGEN_TYPE_CAMERASPACEREFLECTIONVECTOR)
+ N * (iTexGenType == TEXGEN_TYPE_CAMERASPACENORMAL)
+ P * (iTexGenType == TEXGEN_TYPE_CAMERASPACEPOSITION), 0);
Out.Tex0.xy += tc * (iTexGenType == TEXGEN_TYPE_NONE);*/
//light computation
Out.Color = g_Material.Ambient;
Out.ColorSpec = 0;
//directional lights
for(int i = 0; i < 2; i++)
{
COLOR_PAIR ColOut = DoDirLight(N, V, i);
Out.Color += ColOut.Color;
Out.ColorSpec += ColOut.ColorSpec;
}
////point lights
//for(int i = 0; i < iLightPointNum; i++)
//{
// COLOR_PAIR ColOut = DoPointLight(vPosition, N, V, i+iLightPointIni);
// Out.Color += ColOut.Color;
// Out.ColorSpec += ColOut.ColorSpec;
//}
////spot lights
//for(int i = 0; i < iLightSpotNum; i++)
//{
// COLOR_PAIR ColOut = DoSpotLight(vPosition, N, V, i+iLightSpotIni);
// Out.Color += ColOut.Color;
// Out.ColorSpec += ColOut.ColorSpec;
//}
//apply material color
Out.Color *= g_Material.Diffuse;
Out.ColorSpec *= g_Material.Specular;
// saturate
Out.Color = min(1, Out.Color);
Out.ColorSpec = min(1, Out.ColorSpec);
//apply fog
float d;
if(bFogRange)
d = length(P);
else
d = P.z;
Out.Fog = 1.f * (iFogType == FOG_TYPE_NONE)
+ 1.f/exp(d * fFogDensity) * (iFogType == FOG_TYPE_EXP)
+ 1.f/exp(pow(d * fFogDensity, 2)) * (iFogType == FOG_TYPE_EXP2)
+ saturate((fFogEnd - d)/(fFogEnd - fFogStart)) * (iFogType == FOG_TYPE_LINEAR);
return Out;
}
// Techniques
//the technique for the programmable shader (simply sets the vertex shader)
technique basic_with_shader
{
pass P0
{
SPECULARENABLE = (g_Material.Power > 0);
FOGENABLE = (iFogType != FOG_TYPE_NONE);
FOGCOLOR = (vFogColor);
VertexShader = compile vs_2_0 vs_main();
}
}
TEXTURE tex1;
TEXTURE tex2;
//Sampler for the diff mode
sampler DiffSampler1 = sampler_state
{
Texture = (tex1);
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
MaxAnisotropy = 8;
};
sampler DiffSampler2 = sampler_state
{
Texture = (tex2);
MinFilter = Point;
MagFilter = Point;
MipFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
AddressW = Wrap;
MaxAnisotropy = 8;
};
bool bDiffSensitivity = false;
//-----------------------------------------------------------------------------
// Name: ps_diff()
// Desc: Pixel shader for the diff mode
// Tiny errors: green. Larger errors: yellow to red.
//-----------------------------------------------------------------------------
float4 ps_diff (float2 tcBase : TEXCOORD0) : COLOR
{
float E = length(tex2D(DiffSampler1, tcBase) - tex2D(DiffSampler2, tcBase))/sqrt(3);
float4 C = float4(0.f,0.f,0.f,E);
if(E > 0.f)
{
if(E <= 1.f/255.f)
{
if(bDiffSensitivity)
{
C = float4(0.f,1.f,0.f,E);
}
}
else
{
C = lerp(float4(1.f,1.f,0.f,E), float4(1.f,0.f,0.f,E),E);
}
}
return C;
}
//technique for the diff mode
technique technique_diff
{
pass P0
{
PixelShader = compile ps_2_0 ps_diff();
}
}

468
Shaders/fx/FixedFuncEMU.fx Normal file
View File

@ -0,0 +1,468 @@
// FixedFuncEMU.fx
// Copyright (c) 2005 Microsoft Corporation. All rights reserved.
//
struct VSSceneIn
{
float3 pos : POSITION; //position of the particle
float3 norm : NORMAL; //velocity of the particle
float2 tex : TEXTURE0; //tex coords
};
struct VSSceneOut
{
float4 pos : SV_Position; //position
float2 tex : TEXTURE0; //texture coordinate
float3 wPos : TEXTURE1; //world space pos
float3 wNorm : TEXTURE2; //world space normal
float4 colorD : COLOR0; //color for gouraud and flat shading
float4 colorS : COLOR1; //color for specular
float fogDist : FOGDISTANCE; //distance used for fog calculations
float3 planeDist : SV_ClipDistance0; //clip distance for 3 planes
};
struct PSSceneIn
{
float4 pos : SV_Position; //position
float2 tex : TEXTURE0; //texture coordinate
float3 wPos : TEXTURE1; //world space pos
float3 wNorm : TEXTURE2; //world space normal
float4 colorD : COLOR0; //color for gouraud and flat shading
float4 colorS : COLOR1; //color for specular
float fogDist : FOGDISTANCE; //distance used for fog calculations
};
struct Light
{
float4 Position;
float4 Diffuse;
float4 Specular;
float4 Ambient;
float4 Atten;
};
#define FOGMODE_NONE 0
#define FOGMODE_LINEAR 1
#define FOGMODE_EXP 2
#define FOGMODE_EXP2 3
#define E 2.71828
cbuffer cbLights
{
float4 g_clipplanes[3];
Light g_lights[8];
};
cbuffer cbPerFrame
{
float4x4 g_mWorld;
float4x4 g_mView;
float4x4 g_mProj;
float4x4 g_mInvProj;
float4x4 g_mLightViewProj;
};
cbuffer cbPerTechnique
{
bool g_bEnableLighting = true;
bool g_bEnableClipping = true;
bool g_bPointScaleEnable = false;
float g_pointScaleA;
float g_pointScaleB;
float g_pointScaleC;
float g_pointSize;
//fog params
int g_fogMode = FOGMODE_NONE;
float g_fogStart;
float g_fogEnd;
float g_fogDensity;
float4 g_fogColor;
};
cbuffer cbPerViewChange
{
//viewport params
float g_viewportHeight;
float g_viewportWidth;
float g_nearPlane;
};
cbuffer cbImmutable
{
float3 g_positions[4] =
{
float3( -0.5, 0.5, 0 ),
float3( 0.5, 0.5, 0 ),
float3( -0.5, -0.5, 0 ),
float3( 0.5, -0.5, 0 ),
};
};
Texture2D g_txDiffuse;
Texture2D g_txProjected;
SamplerState g_samLinear
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
DepthStencilState DisableDepth
{
DepthEnable = FALSE;
DepthWriteMask = ZERO;
};
DepthStencilState EnableDepth
{
DepthEnable = TRUE;
DepthWriteMask = ALL;
};
struct ColorsOutput
{
float4 Diffuse;
float4 Specular;
};
// camerPos = WorldView
ColorsOutput CalcLighting( float3 worldNormal, float3 worldPos, float3 cameraPos )
{
ColorsOutput output = (ColorsOutput)0.0;
for(int i=0; i<8; i++)
{
float3 toLight = g_lights[i].Position.xyz - worldPos;
float lightDist = length( toLight );
float fAtten = 1.0/dot( g_lights[i].Atten, float4(1,lightDist,lightDist*lightDist,0) );
float3 lightDir = normalize( toLight );
float3 halfAngle = normalize( normalize(-cameraPos) + lightDir );
output.Diffuse += max(0,dot( lightDir, worldNormal ) * g_lights[i].Diffuse * fAtten) + g_lights[i].Ambient;
output.Specular += max(0,pow( dot( halfAngle, worldNormal ), 64 ) * g_lights[i].Specular * fAtten );
}
return output;
}
//
// VS for emulating fixed function pipeline
//
VSSceneOut VSScenemain(VSSceneIn input)
{
VSSceneOut output = (VSSceneOut)0.0;
//output our final position in clipspace
float4 worldPos = mul( float4( input.pos, 1 ), g_mWorld );
float4 cameraPos = mul( worldPos, g_mView ); //Save cameraPos for fog calculations
output.pos = mul( cameraPos, g_mProj );
//save world pos for later
output.wPos = worldPos;
//save the fog distance for later
output.fogDist = cameraPos.z;
//find our clipping planes (fixed function clipping is done in world space)
if( g_bEnableClipping )
{
worldPos.w = 1;
//calc the distance from the 3 clipping planes
output.planeDist.x = dot( worldPos, g_clipplanes[0] );
output.planeDist.y = dot( worldPos, g_clipplanes[1] );
output.planeDist.z = dot( worldPos, g_clipplanes[2] );
}
else
{
output.planeDist.x = 1;
output.planeDist.y = 1;
output.planeDist.z = 1;
}
//do gouraud lighting
if( g_bEnableLighting )
{
float3 worldNormal = normalize( mul( input.norm, (float3x3)g_mWorld ) );
output.wNorm = worldNormal;
ColorsOutput cOut = CalcLighting( worldNormal, worldPos, cameraPos );
output.colorD = cOut.Diffuse;
output.colorS = cOut.Specular;
}
else
{
output.colorD = float4(1,1,1,1);
}
//propogate texture coordinate
output.tex = input.tex;
return output;
}
//
// VS for rendering in screen space
//
PSSceneIn VSScreenSpacemain(VSSceneIn input)
{
PSSceneIn output = (PSSceneIn)0.0;
//output our final position
output.pos.x = (input.pos.x / (g_viewportWidth/2.0)) -1;
output.pos.y = -(input.pos.y / (g_viewportHeight/2.0)) +1;
output.pos.z = input.pos.z;
output.pos.w = 1;
//propogate texture coordinate
output.tex = input.tex;
output.colorD = float4(1,1,1,1);
return output;
}
//
// GS for flat shaded rendering
//
[maxvertexcount(3)]
void GSFlatmain( triangle VSSceneOut input[3], inout TriangleStream<VSSceneOut> FlatTriStream )
{
VSSceneOut output;
//
// Calculate the face normal
//
float3 faceEdgeA = input[1].wPos - input[0].wPos;
float3 faceEdgeB = input[2].wPos - input[0].wPos;
//
// Cross product
//
float3 faceNormal = cross(faceEdgeA, faceEdgeB);
//
//calculate the face center
//
float3 faceCenter = (input[0].wPos + input[1].wPos + input[2].wPos)/3.0;
//find world pos and camera pos
float4 worldPos = float4( faceCenter, 1 );
float4 cameraPos = mul( worldPos, g_mView );
//do shading
float3 worldNormal = normalize( faceNormal );
ColorsOutput cOut = CalcLighting( worldNormal, worldPos, cameraPos );
for(int i=0; i<3; i++)
{
output = input[i];
output.colorD = cOut.Diffuse;
output.colorS = cOut.Specular;
FlatTriStream.Append( output );
}
FlatTriStream.RestartStrip();
}
//
// GS for point rendering
//
[maxvertexcount(12)]
void GSPointmain( triangle VSSceneOut input[3], inout TriangleStream<VSSceneOut> PointTriStream )
{
VSSceneOut output;
//
// Calculate the point size
//
//float fSizeX = (g_pointSize/g_viewportWidth)/4.0;
float fSizeY = (g_pointSize/g_viewportHeight)/4.0;
float fSizeX = fSizeY;
for(int i=0; i<3; i++)
{
output = input[i];
//find world pos and camera pos
float4 worldPos = float4(input[i].wPos,1);
float4 cameraPos = mul( worldPos, g_mView );
//find our size
if( g_bPointScaleEnable )
{
float dEye = length( cameraPos.xyz );
fSizeX = fSizeY = g_viewportHeight * g_pointSize *
sqrt( 1.0f/( g_pointScaleA + g_pointScaleB*dEye + g_pointScaleC*(dEye*dEye) ) );
}
//do shading
if(g_bEnableLighting)
{
float3 worldNormal = input[i].wNorm;
ColorsOutput cOut = CalcLighting( worldNormal, worldPos, cameraPos );
output.colorD = cOut.Diffuse;
output.colorS = cOut.Specular;
}
else
{
output.colorD = float4(1,1,1,1);
}
output.tex = input[i].tex;
//
// Emit two new triangles
//
for(int i=0; i<4; i++)
{
float4 outPos = mul( worldPos, g_mView );
output.pos = mul( outPos, g_mProj );
float zoverNear = (outPos.z)/g_nearPlane;
float4 posSize = float4( g_positions[i].x*fSizeX*zoverNear,
g_positions[i].y*fSizeY*zoverNear,
0,
0 );
output.pos += posSize;
PointTriStream.Append(output);
}
PointTriStream.RestartStrip();
}
}
//
// Calculates fog factor based upon distance
//
float CalcFogFactor( float d )
{
float fogCoeff = 1.0;
if( FOGMODE_LINEAR == g_fogMode )
{
fogCoeff = (g_fogEnd - d)/(g_fogEnd - g_fogStart);
}
else if( FOGMODE_EXP == g_fogMode )
{
fogCoeff = 1.0 / pow( E, d*g_fogDensity );
}
else if( FOGMODE_EXP2 == g_fogMode )
{
fogCoeff = 1.0 / pow( E, d*d*g_fogDensity*g_fogDensity );
}
return clamp( fogCoeff, 0, 1 );
}
//
// PS for rendering with clip planes
//
float4 PSScenemain(PSSceneIn input) : SV_Target
{
//calculate the fog factor
float fog = CalcFogFactor( input.fogDist );
//calculate the color based off of the normal, textures, etc
float4 normalColor = g_txDiffuse.Sample( g_samLinear, input.tex ) * input.colorD + input.colorS;
//calculate the color from the projected texture
float4 cookieCoord = mul( float4(input.wPos,1), g_mLightViewProj );
//since we don't have texldp, we must perform the w divide ourselves befor the texture lookup
cookieCoord.xy = 0.5 * cookieCoord.xy / cookieCoord.w + float2( 0.5, 0.5 );
float4 cookieColor = float4(0,0,0,0);
if( cookieCoord.z > 0 )
cookieColor = g_txProjected.Sample( g_samLinear, cookieCoord.xy );
//for standard light-modulating effects just multiply normalcolor and coookiecolor
normalColor += cookieColor;
return fog * normalColor + (1.0 - fog)*g_fogColor;
}
//
// PS for rendering with alpha test
//
float4 PSAlphaTestmain(PSSceneIn input) : SV_Target
{
float4 color = g_txDiffuse.Sample( g_samLinear, input.tex ) * input.colorD;
if( color.a < 0.5 )
discard;
return color;
}
//
// RenderSceneGouraud - renders gouraud-shaded primitives
//
technique10 RenderSceneGouraud
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PSScenemain() ) );
SetDepthStencilState( EnableDepth, 0 );
}
}
//
// RenderSceneFlat - renders flat-shaded primitives
//
technique10 RenderSceneFlat
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
SetGeometryShader( CompileShader( gs_4_0, GSFlatmain() ) );
SetPixelShader( CompileShader( ps_4_0, PSScenemain() ) );
SetDepthStencilState( EnableDepth, 0 );
}
}
//
// RenderScenePoint - replaces d3dfill_point
//
technique10 RenderScenePoint
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
SetGeometryShader( CompileShader( gs_4_0, GSPointmain() ) );
SetPixelShader( CompileShader( ps_4_0, PSScenemain() ) );
SetDepthStencilState( EnableDepth, 0 );
}
}
//
// RenderScreneSpace - shows how to render something in screenspace
//
technique10 RenderScreenSpaceAlphaTest
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSScreenSpacemain() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PSAlphaTestmain() ) );
SetDepthStencilState( DisableDepth, 0 );
}
}
//
// RenderScreneSpace - shows how to render something in screenspace
//
technique10 RenderTextureOnly
{
pass p0
{
SetVertexShader( CompileShader( vs_4_0, VSScenemain() ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, PSScenemain() ) );
SetDepthStencilState( EnableDepth, 0 );
}
}

View File

@ -100,7 +100,6 @@ VS_OUTPUT_BUMP LandBumpVS(
Output.LandBumpDiffuse = vDiffuse2 * .5f;
Output.LandBumpDiffuse.a = 1.0f;
//Output.LandDiffuse
Output.LandDiffuse.rgb = vDiffuse;
Output.LandDiffuse.a = 1.0f;

View File

@ -32,7 +32,7 @@ float4 MainPS(const PS_INPUT input) : COLOR0
// C26: {minfog, maxfog, 1.0f / (maxfog - minfog), 1.0}
float4 const44 : register(c44);
matrix<float, 4, 4> matWorld : WorldViewProjectionTranspose : register(c2);
matrix<float, 4, 4> matWorld : OceanWorldViewProjection : register(c2);
float4 fog : register (c26);
texture tex0;
texture tex1;