我如何在 HLSL 中设置没有噪声的纹理值的 UV 协调
how do i set UV coordination from Texture value without noise in HLSL
我有 UV 渲染通道(RG 图像)
我想将 uv pass 纹理值设置为没有噪音的 UV 坐标
当我测试它时,结果应该像下图那样像素化噪声
我已经在其他着色器语言(如 cgprogramm 和 GLSL)中对其进行了测试
也统一测试一下
并尝试将 Zdepth 用于 mipmap,但我无法获得抗锯齿结果
所有结果都一样
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldInverseTranspose;
float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;
float3 DiffuseLightDirection = float3(1, 0, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;
float Shininess = 200;
float4 SpecularColor = float4(1, 1, 1, 1);
float SpecularIntensity = 1;
float3 ViewVector = float3(1, 0, 0);
texture ModelTexture;
texture UvTexture;
sampler2D textureSampler = sampler_state {
Texture = (ModelTexture);
MinFilter = Point;
MagFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
};
sampler2D textureSamplerUV = sampler_state {
Texture = (UvTexture);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float4 Normal : NORMAL0;
float2 TextureCoordinate : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 Color : COLOR0;
float3 Normal : TEXCOORD0;
float2 TextureCoordinate : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
float4 normal = normalize(mul(input.Normal, WorldInverseTranspose));
float lightIntensity = dot(normal, DiffuseLightDirection);
output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
output.Normal = normal;
output.TextureCoordinate = input.TextureCoordinate;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//******* is here
float4 textureColorUV = tex2D(textureSamplerUV, input.TextureCoordinate);
float2 cord = float2(textureColorUV[0],textureColorUV[1]);
float4 textureColor = tex2D(textureSampler, cord);
return saturate(textureColor);
}
technique Textured
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
不是噪声,是点采样。 Min 和 Mag 应该是线性的。 Mip 应该是 Point ( bi linear ) 或 Linear ( tri linear ) 以使用 mipmaps
附带说明一下,您可以对 uv 纹理使用点采样以获得边缘上的正确值,但您不必在此处使用点采样器,它们可能比现代硬件上的常规过滤慢。您当然可以确保为纹理获取生成的纹理坐标对齐良好,但如果您可以访问 DX11,则有一个更简单的解决方案。
如果我正在编写您的着色器,最简单的方法是在像素着色器中使用 SV_Position 和括号运算符:
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//*******
float2 uv = textureSamplerUV[input.Position].rg;
float4 textureColor = texture.Sample( sampler, uv );
return (textureColor); // unless you use a non unorm format, saturate not necessary.
}
我找到了噪音的原因
我的 uv 图像是普通字节图像 R(255)G(255)B(255)
并且纹理 W 和 H 拆分为仅 255 个原始和列并且是不够的 - 这是看到噪音的主要原因
我将我的 UV 图像替换为 16 位图像并解决了问题
我的新 UV 图像将纹理拆分为 65535 原始和列
我有 UV 渲染通道(RG 图像)
我想将 uv pass 纹理值设置为没有噪音的 UV 坐标
当我测试它时,结果应该像下图那样像素化噪声
我已经在其他着色器语言(如 cgprogramm 和 GLSL)中对其进行了测试
也统一测试一下
并尝试将 Zdepth 用于 mipmap,但我无法获得抗锯齿结果
所有结果都一样
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldInverseTranspose;
float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;
float3 DiffuseLightDirection = float3(1, 0, 0);
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;
float Shininess = 200;
float4 SpecularColor = float4(1, 1, 1, 1);
float SpecularIntensity = 1;
float3 ViewVector = float3(1, 0, 0);
texture ModelTexture;
texture UvTexture;
sampler2D textureSampler = sampler_state {
Texture = (ModelTexture);
MinFilter = Point;
MagFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
};
sampler2D textureSamplerUV = sampler_state {
Texture = (UvTexture);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
struct VertexShaderInput
{
float4 Position : POSITION0;
float4 Normal : NORMAL0;
float2 TextureCoordinate : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 Color : COLOR0;
float3 Normal : TEXCOORD0;
float2 TextureCoordinate : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
float4 normal = normalize(mul(input.Normal, WorldInverseTranspose));
float lightIntensity = dot(normal, DiffuseLightDirection);
output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
output.Normal = normal;
output.TextureCoordinate = input.TextureCoordinate;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//******* is here
float4 textureColorUV = tex2D(textureSamplerUV, input.TextureCoordinate);
float2 cord = float2(textureColorUV[0],textureColorUV[1]);
float4 textureColor = tex2D(textureSampler, cord);
return saturate(textureColor);
}
technique Textured
{
pass Pass1
{
VertexShader = compile vs_1_1 VertexShaderFunction();
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
不是噪声,是点采样。 Min 和 Mag 应该是线性的。 Mip 应该是 Point ( bi linear ) 或 Linear ( tri linear ) 以使用 mipmaps
附带说明一下,您可以对 uv 纹理使用点采样以获得边缘上的正确值,但您不必在此处使用点采样器,它们可能比现代硬件上的常规过滤慢。您当然可以确保为纹理获取生成的纹理坐标对齐良好,但如果您可以访问 DX11,则有一个更简单的解决方案。
如果我正在编写您的着色器,最简单的方法是在像素着色器中使用 SV_Position 和括号运算符:
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
//*******
float2 uv = textureSamplerUV[input.Position].rg;
float4 textureColor = texture.Sample( sampler, uv );
return (textureColor); // unless you use a non unorm format, saturate not necessary.
}
我找到了噪音的原因
我的 uv 图像是普通字节图像 R(255)G(255)B(255)
并且纹理 W 和 H 拆分为仅 255 个原始和列并且是不够的 - 这是看到噪音的主要原因
我将我的 UV 图像替换为 16 位图像并解决了问题
我的新 UV 图像将纹理拆分为 65535 原始和列