opengl - Normal map from height map -
i trying create normal map height map in hlsl. followed https://stackoverflow.com/a/5284527/451136 glsl. here how translated 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;  } the output black , white image, darker pixels being more transparent (since alpha height). 
 how can generate normal map http://www.filterforge.com/filters/3051-normal.jpg height map?
edit 
 followed megadan's suggestions , , had synthax errors fixed. here working hlsl code:
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;  } i read using getdimensions automatically width , height of texture supported on direct3d 10.1 or higher, width , height of texture must passed shader since need compatible direct3d 9 well.
one possibility normals pointing in wrong direction. happen because opengl uses texture coordinates origin @ bottom left of image y axis points , directx uses texture coordinates origin @ top left y axis points down.
if map out code taking height samples directx, you'll see s01 left, s21 right, s10 top, , s12 bottom. in opengl s10 , s12 reversed.
when create vector vb subtracting s10 s12 point 1 way directx , opposite way opengl. when take cross product between 2 vectors, forms perpendicular vector can point in either of 2 directions depending on order of cross product using right hand rule: http://en.wikipedia.org/wiki/cross_product. cause cross products directx , opengl point in opposite directions.
so, if issue, fix swap order of vectors in cross product or swap locations of s10 , s12 samples.
there issue texture coordinates. uv should in range of [0, 1]. when add off it, puts out of range , result depends on whatever texture addressing mode active. in each of tex2d samples, you'll need divide first component of off texture width , second texture height.
finally, result of cross product have values in range [-1, 1]. if want store color, need convert these [0, 1]. cross(vb, va) * 0.5 + 0.5 work. when normal maps sampled in shader, colors converted normal range of [-1, 1].
Comments
Post a Comment