XNA 到 HLSL float2 的距离向量
XNA Distance Vector to HLSL float2
我使用这个像素着色器对纹理应用了噪声效果。
float2 noisePower;
float noiseFrequency;
float camMoveX;
float camMoveY;
texture noiseTexture;
sampler2D noiseSampler = sampler_state
{
Texture = <noiseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
texture water;
sampler2D waterSampler = sampler_state
{
Texture = <water>;
};
float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : COLOR
{
float2 camMove = float2(camMoveX, camMoveY);
//float4 camMoveTransform = mul(WorldViewProjection, camMove);
float4 noise = tex2D(noiseSampler, texCoord.xy * noiseFrequency);
float2 offset = (noisePower * (noise.xy - 0.5f) * 2.0f);
float4 color = tex2D(waterSampler, texCoord.xy + offset.xy);
return color;
}
technique oceanRipple
{
pass P0
{
PixelShader = compile PS_SHADERMODEL MainPS();
}
};
我试图通过我的相机在游戏中的移动来抵消噪音。
我认为它看起来像这样:
float4 noise = tex2D(noiseSampler, (texCoord.xy - camMove.xy) * noiseFrequency);
因此,如果相机按矢量 (1, 0) 移动一帧(在世界 space 中),我希望抵消噪声采样的位置,使其采样相同移动相机时的世界水位置。
我在将这个距离向量转换为 HLSL 可以使用的东西时遇到了问题。
由于 HLSL 将坐标视为在 0 和 1 之间归一化,因此我尝试在 XNA 中像这样设置 camMoveX 和 Y:
camDisX = (camMove.X / GameOptions.PrefferedBackBufferWidth)
然后将这些值传递给着色器。
不幸的是,这不起作用。我应该如何将这个距离向量转换为 HLSL 可以使用的东西?我应该使用顶点着色器和 worldViewProj 矩阵来解决这个问题吗?
这里有一个short clip来演示一下。
不使用帧间的相机移动距离来计算偏移量,而是使用相机位置,可以从视图矩阵转置的最后一列中提取,也可以通过累积相机移动来计算每帧。
float4 noise = tex2D(noiseSampler, (texCoord.xy + camPos.xy) * noiseFrequency);
从直觉上讲,这更有意义:如果相机远离某个原点 (a, b),则纹理需要在远离该原点的 (a, b) 处进行采样,以显示静止。这与相机移动的速度无关。
在找到解决方案后更新此内容。我最终得到以下结果:
camMove.X = ((_cam.Position.X % GameOptions.PrefferedBackBufferWidth) / (GameOptions.PrefferedBackBufferWidth));
camMove.Y = ((_cam.Position.Y % GameOptions.PrefferedBackBufferHeight) / (GameOptions.PrefferedBackBufferHeight));
我使用这个像素着色器对纹理应用了噪声效果。
float2 noisePower;
float noiseFrequency;
float camMoveX;
float camMoveY;
texture noiseTexture;
sampler2D noiseSampler = sampler_state
{
Texture = <noiseTexture>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
texture water;
sampler2D waterSampler = sampler_state
{
Texture = <water>;
};
float4 MainPS(float4 pos : SV_POSITION, float4 color1 : COLOR0, float2 texCoord : TEXCOORD0) : COLOR
{
float2 camMove = float2(camMoveX, camMoveY);
//float4 camMoveTransform = mul(WorldViewProjection, camMove);
float4 noise = tex2D(noiseSampler, texCoord.xy * noiseFrequency);
float2 offset = (noisePower * (noise.xy - 0.5f) * 2.0f);
float4 color = tex2D(waterSampler, texCoord.xy + offset.xy);
return color;
}
technique oceanRipple
{
pass P0
{
PixelShader = compile PS_SHADERMODEL MainPS();
}
};
我试图通过我的相机在游戏中的移动来抵消噪音。
我认为它看起来像这样:
float4 noise = tex2D(noiseSampler, (texCoord.xy - camMove.xy) * noiseFrequency);
因此,如果相机按矢量 (1, 0) 移动一帧(在世界 space 中),我希望抵消噪声采样的位置,使其采样相同移动相机时的世界水位置。
我在将这个距离向量转换为 HLSL 可以使用的东西时遇到了问题。
由于 HLSL 将坐标视为在 0 和 1 之间归一化,因此我尝试在 XNA 中像这样设置 camMoveX 和 Y:
camDisX = (camMove.X / GameOptions.PrefferedBackBufferWidth)
然后将这些值传递给着色器。
不幸的是,这不起作用。我应该如何将这个距离向量转换为 HLSL 可以使用的东西?我应该使用顶点着色器和 worldViewProj 矩阵来解决这个问题吗?
这里有一个short clip来演示一下。
不使用帧间的相机移动距离来计算偏移量,而是使用相机位置,可以从视图矩阵转置的最后一列中提取,也可以通过累积相机移动来计算每帧。
float4 noise = tex2D(noiseSampler, (texCoord.xy + camPos.xy) * noiseFrequency);
从直觉上讲,这更有意义:如果相机远离某个原点 (a, b),则纹理需要在远离该原点的 (a, b) 处进行采样,以显示静止。这与相机移动的速度无关。
在找到解决方案后更新此内容。我最终得到以下结果:
camMove.X = ((_cam.Position.X % GameOptions.PrefferedBackBufferWidth) / (GameOptions.PrefferedBackBufferWidth));
camMove.Y = ((_cam.Position.Y % GameOptions.PrefferedBackBufferHeight) / (GameOptions.PrefferedBackBufferHeight));