Normal Map aus Bump-Map berechnen
-
Hallo,
ich habe einen HLSL Shader, der aus einer Bump Map eine Normal-Map berechen soll://-------------------------------------------------------------------------------------- // Global variables //-------------------------------------------------------------------------------------- cbuffer cb0 { float4 g_MaterialAmbientColor; // Material's ambient color float4 g_MaterialDiffuseColor; // Material's diffuse color float3 g_vLightDir; // Light's direction in world space float4 g_LightDiffuse; // Light's diffuse color float g_fTime; // App's time in seconds float4x4 g_mWorld; // World matrix for object float4x4 g_mWorldViewProjection; // World * View * Projection matrix //Für Full-Screen-Rendering float4 QuadPositionTexCoordsFullScreen[] = { float4(-1,-1,0,1), float4(-1,+1,0,0), float4(+1,-1,1,1), float4(+1,+1,1,0), }; } Texture2D g_MeshTexture; // Color texture for mesh //-------------------------------------------------------------------------------------- // Texture samplers //-------------------------------------------------------------------------------------- SamplerState MeshTextureSampler { Filter = MIN_MAG_MIP_LINEAR; AddressU = Wrap; AddressV = Wrap; }; //-------------------------------------------------------------------------------------- // Vertex shader output structure //-------------------------------------------------------------------------------------- struct VS_OUTPUT { float4 Position : SV_Position; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1) float2 TextureUV : TEXCOORD0; // vertex texture coords }; VS_OUTPUT RenderWithTextureFullScreenVS(uint VertexId: SV_VertexID) { VS_OUTPUT Output = (VS_OUTPUT)0; Output.Position = float4(QuadPositionTexCoordsFullScreen[VertexId].xy, 0, 1); Output.Diffuse.rgb = float3(0.5f, 0.5f, 1.0f); Output.Diffuse.a = 1.0f; Output.TextureUV = QuadPositionTexCoordsFullScreen[VertexId].zw; return Output; } float4 RenderScenePS( VS_OUTPUT In ) : SV_Target { float4 normalTap = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV); float3 tanNormal = normalTap.xyz * 2.0 - float3( 1.0, 1.0, 1.0 ); float mapSize = 512.0; float bumpHeight = 2.0; float normalTapOver = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV+ float2( 1.0 / mapSize, 0.0 )) * 2.0 - 1.0; float normalTapUp = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV + float2( 0.0, 1.0 / mapSize ) ) * 2.0 - 1.0; tanNormal *= bumpHeight; normalTapOver *= bumpHeight; normalTapUp *= bumpHeight; float3 eugTanNormal = normalize( float3( tanNormal.x - normalTapOver, ( tanNormal.x - normalTapUp ), 1.0 ) ); tanNormal = eugTanNormal; return float4(tanNormal, 1); } technique11 RenderSceneX { pass P0 { SetVertexShader( CompileShader(vs_4_0, RenderWithTextureFullScreenVS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader(ps_4_0, RenderScenePS() ) ); } }
Wenn ich ihn mit dieser Bump-Map ausführe:
http://imageshack.us/photo/my-images/10/bumpdq.png/Kommt das bei raus:
http://imageshack.us/photo/my-images/263/rttmr.png/Aber eigentlich sollte so etwas rauskommen:
http://imageshack.us/photo/my-images/849/bumpn.png/ (mit GIMP erzeugt)Was mache ich falsch?
-
Ich habe das mal auf die Schnelle ausprobiert und meine Vermutung bestätigt.
Das soll-Bild verwendet nur die obere Hälfte des Farbberreiches. Also Anstelle des ganzen RGBA Bereiches 0 - 255 (bzw. 0.0 - 1.0), den Bereich 128 - 255 (bzw. 0.5 - 1.0).
Entweder die Berrechnungen darauf umstellen, oder am Ende korrigieren:
R = R / 2 + 0.5
G = G / 2 + 0.5
B = B / 2 + 0.5
A = A / 2 + 0.5Und anschließend noch einen einfachen Weichzeichner (oder Antialiasing) wie auch immer du dass nenen möchtest.
-
Ok, es funktioniert.
Danke!!!