Well, I wrote a nice little terrain texturing shader in HLSL (it's not great, but give me a break, it's my first attempt at one :P). Unfortunately, I now need it in HLSL, I've tried tweaking it to be Cg compatible and compiling with the GLSL profiles. That failed miserably. So I went and ported it manually (which wasn't actually too bad). Now the problem is, the textures don't show up at all.
The original HLSL code is (ignore the highlighting):
//---------------------------------
// Projection Matrices and stuff...
//---------------------------------
float4x4 world : WorldViewProjection;
//---------------------------------
// User definable parameter
//---------------------------------
float HighAltDef <
string UIName = "High Altitude";
string UIWidget = "slider";
float UImin = 0;
float UImax = 50;
float UIstep = 0.1;
> = 25;
float HighFringeSize <
string UIName = "High Fringe Size";
string UIWidget = "slider";
float UImin = 0;
float UImax = 25;
float UIstep = 0.1;
> = .5;
float LowFringeSize <
string UIName = "Low Fringe Size";
string UIWidget = "slider";
float UImin = 0;
float UImax = 25;
float UIstep = 0.1;
> = .5;
float Tiles <
string UIName = "Tile";
string UIWidget = "slider";
float UImin = 0;
float UImax = 32;
float UIstep = 0.1;
> = 1;
float3 LightPos : POSITION <
string UIName = "Light Position";
string object = "spotlight";
> = {-150, 0, 50};
float3 LightColor <
string UIName = "Light Color";
string UIWidget = "color";
> = {1, 1, 1};
//---------------------------------
// Textures
//---------------------------------
texture highAlt;
texture lowAlt;
texture fringeTex;
//---------------------------------
// Texture Samplers
//---------------------------------
sampler2D high = sampler_state {
texture = (highAlt);
mipfilter = linear;
minfilter = linear;
magfilter = linear;
};
sampler2D low = sampler_state {
texture = (lowAlt);
mipfilter = linear;
minfilter = linear;
magfilter = linear;
};
sampler2D fringe = sampler_state {
texture = (fringeTex);
mipfilter = linear;
minfilter = linear;
magfilter = linear;
};
//---------------------------------
// Application->Vertex Pipeline
//---------------------------------
struct a2v {
float4 position : POSITION0;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
//---------------------------------
// Vertex Pipe to Pixel Pipe
//---------------------------------
struct v2p {
float4 position : POSITION;
float4 pos : TEXCOORD0;
float3 normal : TEXCOORD1;
float2 uv : TEXCOORD2;
float height : TEXCOORD3;
};
//---------------------------------
// Pixel Pipe to Frame
//---------------------------------
struct p2f {
float4 color : COLOR;
};
//---------------------------------
// Vertex Shader
//---------------------------------
void vs(in a2v IN, out v2p OUT) {
// Output Position
OUT.position = mul(IN.position, world);
OUT.pos = OUT.position;
// Normal transfer
OUT.normal = IN.normal;
// Output Texture Coordinates
OUT.uv = IN.uv;
// Store vertex height
OUT.height = IN.position.y;
}
//---------------------------------
// Pixel Shader
//---------------------------------
void ps(in v2p IN, out p2f OUT) {
if(IN.height > HighAltDef) {
float fringepoint = clamp((IN.height - HighAltDef) / HighFringeSize, 0, 1);
OUT.color = tex2D(high, IN.uv * Tiles) * fringepoint + tex2D(fringe, IN.uv * Tiles) * (1 - fringepoint);
} else {
float fringepoint = clamp((HighAltDef - IN.height) / LowFringeSize, 0, 1);
OUT.color = tex2D(low, IN.uv * Tiles) * fringepoint + tex2D(fringe, IN.uv * Tiles) * (1 - fringepoint);
}
// Per-Pixel lighting
float3 pworld = mul(IN.pos, world).xyz;
float3 normal = mul(IN.normal, world).xyz;
float3 light = normalize(LightPos - pworld);
float intense = clamp(dot(normal, light), 0, 1);
float4 color = float4(LightColor * intense, 1);
color.rgb += 0.5;
OUT.color *= color;
}
//---------------------------------
// Techniques
//---------------------------------
technique Textured {
pass p0 {
vertexshader = compile vs_1_1 vs();
pixelshader = compile ps_2_0 ps();
}
}
The GLSL version I've created is as follows:
Vertex
varying float height;
varying vec3 normal;
varying vec4 pos;
void main() {
height = gl_Vertex.y;
normal = gl_Normal;
pos = gl_Vertex;
gl_Position = ftransform();
}
Fragment
uniform float HighAltDef;
uniform float Tiles;
uniform float HighFringeSize;
uniform float LowFringeSize;
uniform vec3 LightPos;
uniform sampler2D high;
uniform sampler2D low;
uniform sampler2D fringe;
uniform vec3 LightColor;
varying float height;
varying vec3 normal;
varying vec4 pos;
void main() {
if(height > HighAltDef) {
float fringep = clamp((height - HighAltDef) / HighFringeSize, 0.0, 1.0);
gl_FragColor = texture2D(high, gl_TexCoord[0].st * Tiles) * fringep + texture2D(fringe, gl_TexCoord[0].st * Tiles) * (1.0 - fringep);
} else {
float fringep = clamp((HighAltDef - height) / LowFringeSize, 0.0, 1.0);
gl_FragColor = texture2D(low, gl_TexCoord[0].st * Tiles) * fringep + texture2D(fringe, gl_TexCoord[0].st * Tiles) * (1.0 - fringep);
}
vec4 WorldPos = pos * gl_ModelViewProjectionMatrix;
vec3 light = normalize(LightPos - WorldPos.xyz);
float intense = clamp(dot(normal, light), 0.0, 1.0);
vec4 color = vec4(LightColor * intense, 1);
color.rgb += 0.5;
gl_FragColor *= color;
}
I assume I must be doing something wrong in the Fragment shader because I end up with a shaded red block of land. I can't see anything that could be wrong, but this is only the second day I've done anything with shader writing.
Thanks.