Ну вот дошло дело до реализации, написал простой шейдер воды (отражения от кубмэпа) без преломления и отражения сцены. Есть проблема: Чем дальше камера отдаляется от центра координат, тем сильнее искажается отражение. Если кто уже писал шейдеры воды, помогите разобраться...
//CompilerOptions = ParentNamespace, InternalClass
float4x4 World : WORLD;
float4x4 View : VIEW;
float4x4 Projection : PROJECTION;
float3 lightDirection = float3(-1, -1, -1);
float3 specularColor = float3(1, 1, 1);
float3 color = float3(0.6, 0.6, 1);
float alpha = 1.0;
float time = 0.0;
float3 viewPoint : VIEWPOINT;
float specularIntensity = 1.0;
float specularPower = 80;
texture EnvironmentMap;
sampler environmentSampler = sampler_state
{
Texture = (EnvironmentMap);
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
MIPFILTER = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
texture NormalMap;
sampler normalSampler = sampler_state
{
Texture = (NormalMap);
MagFilter = LINEAR;
MinFilter = LINEAR;
Mipfilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float3 Binormal : BINORMAL0;
float3 Normal : NORMAL0;
float3 Tangent : TANGENT0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float3 tgtLightDir : TEXCOORD1;
float3 tgtEyeDir : TEXCOORD2;
float3 pos : TEXCOORD3;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 pos = mul(input.Position, World);
float3 viewDirection = pos - viewPoint;
pos = mul(pos, View);
pos = mul(pos, Projection);
float3x3 tgtSpace;
tgtSpace[0] = mul(normalize(input.Tangent), World);
tgtSpace[1] = mul(normalize(input.Binormal), World);
tgtSpace[2] = mul(normalize(input.Normal), World);
output.Position = pos;
output.TexCoord = input.TexCoord + time;
output.tgtLightDir = normalize(mul(tgtSpace, -lightDirection));
output.tgtEyeDir = normalize(mul(tgtSpace, viewDirection));
output.pos = pos;
return output;
}
float4 PixelShaderFunctionNoSpecular(VertexShaderOutput input): COLOR0
{
float3 normal = 2 * tex2D (normalSampler, input.TexCoord) - 1.0;
float3 ref = reflect(input.tgtEyeDir, normal);
float3 envColor = texCUBE(environmentSampler, ref.xzy);
float diffuse = saturate(dot(normal, -input.tgtLightDir));
float3 halfVector = normalize(-input.tgtLightDir + input.tgtEyeDir);
float specular = specularIntensity * pow(dot(normal, halfVector), specularPower) ;
return float4( color * diffuse + envColor + specular, alpha);
}
technique WaterRenderTechnique
{
pass Pass1
{
VertexShader = compile vs_2_0 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunctionNoSpecular();
}
}
Скрины работы текущего шейдера
вот тут