From 6d164e6e479238a56a6474a919a1f62e6b1a6f6c Mon Sep 17 00:00:00 2001 From: Chris Laurel Date: Tue, 3 Aug 2004 08:57:13 +0000 Subject: [PATCH] Add new shaders for handling combined base and specular maps in the GeForce FX render path. --- celestia.iss | 2 ++ shaders/texphong_alpha_arb.vp | 65 ++++++++++++++++++++++++++++++++++ shaders/texphong_alpha_nv.fp | 55 ++++++++++++++++++++++++++++ src/celengine/fragmentprog.cpp | 3 ++ src/celengine/fragmentprog.h | 1 + src/celengine/render.cpp | 12 +++++-- src/celengine/vertexprog.cpp | 3 ++ src/celengine/vertexprog.h | 1 + 8 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 shaders/texphong_alpha_arb.vp create mode 100644 shaders/texphong_alpha_nv.fp diff --git a/celestia.iss b/celestia.iss index 27a7fa8a5..424936da0 100644 --- a/celestia.iss +++ b/celestia.iss @@ -255,6 +255,7 @@ Source: "shaders\shadowtex_arb.vp"; DestDir: "{app}/shaders"; Flags: ignore Source: "shaders\simple_arb.vp"; DestDir: "{app}/shaders"; Flags: ignoreversion Source: "shaders\specular_arb.vp"; DestDir: "{app}/shaders"; Flags: ignoreversion Source: "shaders\texphong_arb.vp"; DestDir: "{app}/shaders"; Flags: ignoreversion +Source: "shaders\texphong_alpha_arb.vp"; DestDir: "{app}/shaders"; Flags: ignoreversion ; Shaders (NV pixel) @@ -264,6 +265,7 @@ Source: "shaders\eclipse1_nv.fp"; DestDir: "{app}/shaders"; Flags: ignore Source: "shaders\eclipse2_nv.fp"; DestDir: "{app}/shaders"; Flags: ignoreversion Source: "shaders\shadow_on_rings_nv.fp"; DestDir: "{app}/shaders"; Flags: ignoreversion Source: "shaders\texphong_nv.fp"; DestDir: "{app}/shaders"; Flags: ignoreversion +Source: "shaders\texphong_alpha_nv.fp"; DestDir: "{app}/shaders"; Flags: ignoreversion ; Models diff --git a/shaders/texphong_alpha_arb.vp b/shaders/texphong_alpha_arb.vp new file mode 100644 index 000000000..aa6674f06 --- /dev/null +++ b/shaders/texphong_alpha_arb.vp @@ -0,0 +1,65 @@ +!!ARBvp1.0 + +# Set up for phong shading fragment program. + +ATTRIB iPos = vertex.position; +ATTRIB iNormal = vertex.normal; +ATTRIB iTex0 = vertex.texcoord[0]; +PARAM mvp[4] = { state.matrix.mvp }; +PARAM lightDir = program.env[0]; +PARAM eyePos = program.env[1]; +PARAM diffuse = program.env[2]; +PARAM specExp = program.env[4]; +PARAM specular = program.env[3]; +PARAM ambient = program.env[5]; +PARAM zero = 0; +PARAM one = 1; +OUTPUT oPos = result.position; +OUTPUT oColor = result.color; +OUTPUT oSpecColor = result.color.secondary; +OUTPUT oTex0 = result.texcoord[0]; +OUTPUT oNormal = result.texcoord[1]; +OUTPUT oHalfAngle = result.texcoord[2]; +OUTPUT oFog = result.fogcoord; + +TEMP diffuseFactor; +TEMP eyeVec; +TEMP halfAngle; +TEMP dotProds; + +# Transform the vertex by the modelview matrix +DP4 oPos.x, mvp[0], iPos; +DP4 oPos.y, mvp[1], iPos; +DP4 oPos.z, mvp[2], iPos; +DP4 oPos.w, mvp[3], iPos; + +# Compute the diffuse light component +DP3 diffuseFactor, iNormal, lightDir; +# Clamp the diffuse component to zero +MAX diffuseFactor, diffuseFactor, zero; + +# Get the vector from the eye to the vertex +SUB eyeVec, eyePos, iPos; + +# Normalize it +DP3 eyeVec.w, eyeVec, eyeVec; +RSQ eyeVec.w, eyeVec.w; +MUL eyeVec, eyeVec, eyeVec.w; + +# Haze +DP3 diffuseFactor.y, iNormal, eyeVec; +SUB diffuseFactor.y, one, diffuseFactor.y; +MUL oFog.x, diffuseFactor.x, diffuseFactor.y; + +# Compute the half angle vector for specular lighting +ADD halfAngle, eyeVec, lightDir; +DP3 halfAngle.w, halfAngle, halfAngle; +RSQ halfAngle.w, halfAngle.w; +MUL halfAngle, halfAngle, halfAngle.w; + +# Output the texture +MOV oTex0, iTex0; +MOV oNormal, iNormal; +MOV oHalfAngle, halfAngle; + +END diff --git a/shaders/texphong_alpha_nv.fp b/shaders/texphong_alpha_nv.fp new file mode 100644 index 000000000..7e6434413 --- /dev/null +++ b/shaders/texphong_alpha_nv.fp @@ -0,0 +1,55 @@ +!!FP1.0 + +# Diffuse * texture + specular +# Specular term is modulated by a gloss factor stored in the alpha channel +# +# Textures: +# TEX0 - base texture with specular factor in alpha +# +# Interpolants: +# f[TEX0] - base texture coordinates +# f[TEX1] - surface normal in object space +# f[TEX2] - half angle vector in object space +# +# Constants: +# p[0] - object space light vector +# p[2] - diffuse color +# p[3] - specular color +# p[4].x - specular exponent +# p[5] - ambient color + +MOV R0, f[TEX1]; # surface normal in R0 +MOV R1, f[TEX2]; # half angle vector in R1 + +# Normalize the surface normal (consider using a normalization cube map) +DP3 R0.w, R0, R0; +RSQ R0.w, R0.w; +MUL R0.xyz, R0, R0.w; + +# Normalize the half-angle vector +DP3 R1.w, R1, R1; +RSQ R1.w, R1.w; +MUL R1.xyz, R1, R1.w; + +# Compute the diffuse term +DP3 R2.x, R0, p[0]; + +# Compute the specular dot product +DP3 R2.y, R0, R1; + +# Specular exponent in w +MOV R2.w, p[4].x; + +LIT R3, R2; + +TEX H0, f[TEX0], TEX0, 2D; # Sample the base texture +MULX H2, R3.y, p[2]; # Diffuse color * diffuse factor +ADDX_SAT H2, H2, p[5]; # Add ambient light to get 'scene color' +MULX H0, H2, H0; # Base texture * scene color +MULX R3.z, R3.z, H0.w; # Multiply the specular factor by the gloss map value +MULX R3.z, R3.z, R3.y; # Multiply the specular factor by the diffuse factor +MADX H0, R3.z, p[3], H0; # Multiply the specular factor by + # the specular color and add it in +MOVX o[COLR], H0; + +END diff --git a/src/celengine/fragmentprog.cpp b/src/celengine/fragmentprog.cpp index 5bee36e6b..66bd160cc 100644 --- a/src/celengine/fragmentprog.cpp +++ b/src/celengine/fragmentprog.cpp @@ -23,6 +23,7 @@ unsigned int fp::eclipseShadow2 = 0; unsigned int fp::texDiffuse = 0; unsigned int fp::texDiffuseBump = 0; unsigned int fp::texSpecular = 0; +unsigned int fp::texSpecularAlpha = 0; class FragmentProcessorNV : public FragmentProcessor @@ -133,6 +134,8 @@ FragmentProcessor* fp::initNV() return NULL; if (!LoadNvFragmentProgram("shaders/texphong_nv.fp", texSpecular)) return NULL; + if (!LoadNvFragmentProgram("shaders/texphong_alpha_nv.fp", texSpecularAlpha)) + return NULL; cout << "All NV fragment programs loaded successfully.\n"; diff --git a/src/celengine/fragmentprog.h b/src/celengine/fragmentprog.h index 41d52d517..874656f5b 100644 --- a/src/celengine/fragmentprog.h +++ b/src/celengine/fragmentprog.h @@ -50,6 +50,7 @@ namespace fp extern unsigned int texDiffuse; extern unsigned int texDiffuseBump; extern unsigned int texSpecular; + extern unsigned int texSpecularAlpha; }; diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index 862967d57..b1068436a 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -3172,9 +3172,17 @@ static void renderSphere_FP_VP(const RenderInfo& ri, } else if (ri.specularColor != Color::Black) { - vproc->use(vp::perFragmentSpecular); fproc->enable(); - fproc->use(fp::texSpecular); + if (ri.glossTex == NULL) + { + vproc->use(vp::perFragmentSpecularAlpha); + fproc->use(fp::texSpecularAlpha); + } + else + { + vproc->use(vp::perFragmentSpecular); + fproc->use(fp::texSpecular); + } fproc->parameter(fp::DiffuseColor, ri.sunColor * ri.color); fproc->parameter(fp::SunDirection, ri.sunDir_obj); fproc->parameter(fp::SpecularColor, ri.specularColor); diff --git a/src/celengine/vertexprog.cpp b/src/celengine/vertexprog.cpp index 5fa3060dd..b251e22e6 100644 --- a/src/celengine/vertexprog.cpp +++ b/src/celengine/vertexprog.cpp @@ -32,6 +32,7 @@ unsigned int vp::cometTail = 0; unsigned int vp::nightLights = 0; unsigned int vp::glossMap = 0; unsigned int vp::perFragmentSpecular = 0; +unsigned int vp::perFragmentSpecularAlpha = 0; class VertexProcessorNV : public VertexProcessor @@ -258,6 +259,8 @@ VertexProcessor* vp::initARB() return NULL; if (!LoadARBVertexProgram("shaders/texphong_arb.vp", perFragmentSpecular)) return NULL; + if (!LoadARBVertexProgram("shaders/texphong_alpha_arb.vp", perFragmentSpecularAlpha)) + return NULL; } cout << "All ARB vertex programs loaded successfully.\n"; diff --git a/src/celengine/vertexprog.h b/src/celengine/vertexprog.h index bd5537774..6fe20565d 100644 --- a/src/celengine/vertexprog.h +++ b/src/celengine/vertexprog.h @@ -64,6 +64,7 @@ namespace vp extern unsigned int nightLights; extern unsigned int glossMap; extern unsigned int perFragmentSpecular; + extern unsigned int perFragmentSpecularAlpha; };