【发布时间】:2014-09-25 18:24:59
【问题描述】:
我正在尝试从 HLSL 中的高度图创建法线贴图。我关注了这个用于 GLSL 的https://stackoverflow.com/a/5284527/451136。以下是我将 GLSL 翻译成 HLSL 的方法:
GLSL:
uniform sampler2D unit_wave
noperspective in vec2 tex_coord;
const vec2 size = vec2(2.0,0.0);
const ivec3 off = ivec3(-1,0,1);
vec4 wave = texture(unit_wave, tex_coord);
float s11 = wave.x;
float s01 = textureOffset(unit_wave, tex_coord, off.xy).x;
float s21 = textureOffset(unit_wave, tex_coord, off.zy).x;
float s10 = textureOffset(unit_wave, tex_coord, off.yx).x;
float s12 = textureOffset(unit_wave, tex_coord, off.yz).x;
vec3 va = normalize(vec3(size.xy,s21-s01));
vec3 vb = normalize(vec3(size.yx,s12-s10));
vec4 bump = vec4( cross(va,vb), s11 );
HLSL:
sampler2D image : register(s0);
noperspective float2 TEXCOORD;
static const float2 size = (2.0,0.0);
static const int3 off = (-1,0,1);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(image, uv);
float s11 = color.x;
float s01 = tex2D(image, uv + off.xy).x;
float s21 = tex2D(image, uv + off.zy).x;
float s10 = tex2D(image, uv + off.yx).x;
float s12 = tex2D(image, uv + off.yz).x;
float3 va = normalize((size.xy,s21-s01));
float3 vb = normalize((size.yx,s12-s10));
float4 bump = (cross(va,vb), s11);
return bump;
}
输出是黑白图像,较暗的像素更透明(因为 alpha 是高度)。
如何从高度图生成像 http://www.filterforge.com/filters/3051-normal.jpg 这样的法线贴图?
编辑
我遵循了 megadan 的建议,并且我还修复了一些合成错误。这是有效的 HLSL 代码:
float Width : register(C0);
float Height : register(C1);
sampler2D image : register(s0);
noperspective float2 TEXCOORD;
static const float2 size = {2.0,0.0};
static const float3 off = {-1.0,0.0,1.0};
static const float2 nTex = {Width, Height};
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = tex2D(image, uv.xy);
float2 offxy = {off.x/nTex.x , off.y/nTex.y};
float2 offzy = {off.z/nTex.x , off.y/nTex.y};
float2 offyx = {off.y/nTex.x , off.x/nTex.y};
float2 offyz = {off.y/nTex.x , off.z/nTex.y};
float s11 = color.x;
float s01 = tex2D(image, uv.xy + offxy).x;
float s21 = tex2D(image, uv.xy + offzy).x;
float s10 = tex2D(image, uv.xy + offyx).x;
float s12 = tex2D(image, uv.xy + offyz).x;
float3 va = {size.x, size.y, s21-s01};
float3 vb = {size.y, size.x, s12-s10};
va = normalize(va);
vb = normalize(vb);
float4 bump = {(cross(va,vb)) / 2 + 0.5, 1.0};
return bump;
}
我读到 Direct3D 10.1 或更高版本支持使用 GetDimensions 自动获取纹理的宽度和高度,因此必须将纹理的宽度和高度传递给着色器,因为我需要它与 Direct3D 9 兼容也是。
【问题讨论】:
标签: opengl textures glsl shader hlsl