get view-space normal
get view-space normal
Color = tex2D(texNormal,IN.Texcoord1).xyz * 2 - 1;
Color.z is the depth
Color.z= sqrt( 1 - Color.x * Color.x - Color.y * Color.y );
return Color; (for test)
but the normal is static. How convert it to view-sapce ???
mul(Color,matWorldViewProjection) ??? I don't know
http://www.guerrilla-games.com/publicat ... _dev07.pdf
http://cmpmedia.vo.llnwd.net/o1/vault/g ... ghting.pdf
Color.z is the depth
Color.z= sqrt( 1 - Color.x * Color.x - Color.y * Color.y );
return Color; (for test)
but the normal is static. How convert it to view-sapce ???
mul(Color,matWorldViewProjection) ??? I don't know
http://www.guerrilla-games.com/publicat ... _dev07.pdf
http://cmpmedia.vo.llnwd.net/o1/vault/g ... ghting.pdf
searching
How get t,b,n in correct world space ?
float3 Normal = mul(matWorldInverse,IN.Normal);
float3 Tangent = float3(abs(Normal.y)+abs(Normal.z),abs(Normal.x),0);
float3 Binormal = cross(Tangent,Normal);
Code: Select all
1 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
2 // Zen GeometricBufferGen Shading Shader
3 //
4 // Copyright (C) 2008 - 2009 Matthew Alan Gray
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 // claim that you wrote the original software. If you use this software
16 // in a product, an acknowledgment in the product documentation would be
17 // appreciated but is not required.
18 // 2. Altered source versions must be plainly marked as such, and must not be
19 // misrepresented as being the original software.
20 // 3. This notice may not be removed or altered from any source distribution.
21 //
22 // Matthew Alan Gray mgray@indiezen.org
23 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
24
25 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
26 // Vertex Shader input struct
27 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
28 struct VIn
29 {
30 float4 pos : POSITION; // World space vertex position
31
32 float3 n : NORMAL; // World space vertex normal
33
34 float3 b : BINORMAL; // World space vertex binormal
35
36 float3 t : TANGENT; // World space vertex tangent
37
38 float2 uv : TEXCOORD0; // Vertex Texture UV coordinates
39 };
40
41 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
42 // Vertex Shader output struct
43 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
44 struct VOut
45 {
46 float4 pos : POSITION; // Clip space vertex position
47
48 float4 hpos : TEXCOORD0; // Clip space vertex position
49
50 float2 uv : TEXCOORD1; // Vertex Texture UV coordinates
51
52 float3x3 tangentToView : TEXCOORD2; // Vertex tangent space to
53 // view space transformation matrix
54 };
55
56 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
57 // GeometricBufferGen Vertex Shader
58 //
59 // Uniform Variables
60 // * _worldView - World View matrix
61 // * _inverseTransposeWorldView - Inverse Transpose World View matrix
62 // * _worldViewProjection - World View Projection matrix
63 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
64 VOut GeometricBufferGen_vs(VIn _in,
65 uniform float4x4 _worldView,
66 uniform float3x3 _inverseTransposeWorldView,
67 uniform float4x4 _worldViewProjection)
68 {
69 VOut OUT = (VOut)0;
70
71 // Transform the world space coordinates into homogeneous clip space.
72 OUT.pos = mul( _worldViewProjection, _in.pos );
73 OUT.hpos = OUT.pos;
74
75 // Pass uv texture coordinates to the pixel shader.
76 OUT.uv = _in.uv;
77
78 // Calculate tangent space to view space matrix.
79 OUT.tangentToView[0] = mul( _inverseTransposeWorldView, _in.t );
80 OUT.tangentToView[1] = mul( _inverseTransposeWorldView, _in.b );
81 OUT.tangentToView[2] = mul( _inverseTransposeWorldView, _in.n );
82
83 return OUT;
84 }
85
86 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
87 // Pixel Shader input struct
88 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
89 struct PIn
90 {
91 float4 hpos : TEXCOORD0; // Clip space pixel position
92
93 float2 uv : TEXCOORD1; // Pixel UV texture coordinates
94
95 float3x3 tangentToView : TEXCOORD2; // Pixel tangent space to world
96 // view transformation matrix
97 };
98
99 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
100 // Pixel Shader output struct
101 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
102 struct POut
103 {
104 float depthBuf : DEPTH; // Depth/Stencil Render Target
105
106 float4 lightBuf : COLOR0; // Accumulated Light Render Target
107
108 float2 normalBuf : COLOR1; // Normal Map Render Target
109
110 float4 motionSpecularityBuf : COLOR2; // Motion/Specularity Render Target
111
112 float4 diffuseOcclusionBuf : COLOR3; // Diffuse/Occlusion Render Target
113 };
114
115 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
116 // GeometricBufferGen Pixel Shader
117 //
118 // Uniform Variables
119 // * _lightMap - initialization accumulated light map (sampler2D)
120 // * _normalMap - tangent space normal map (sampler2D)
121 // * _specularMap - specular power/roughness and intensity map (sampler2D)
122 // * _diffuseMap - diffuse and occlusion map (sampler2D)
123 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
124 POut GeometricBufferGen_ps(PIn _in,
125 uniform sampler2D _lightMap,
126 uniform sampler2D _normalMap,
127 uniform sampler2D _specularMap,
128 uniform sampler2D _diffuseMap)
129 {
130 POut OUT = (POut)0;
131
132 // Compute the pixel depth
133 OUT.depthBuf = _in.hpos.z;
134
135 // Initialize the light accumulation pixel
136 OUT.lightBuf = tex2D( _lightMap, _in.uv );
137
138 // Compute the normal map pixel
139 // @{
140 float3 n = tex2D( _normalMap, _in.uv ).xyz * 2.0 - 1.0;
141
142 // Transform normal from tangent space to view space
143 n = normalize( mul( _in.tangentToView, n ) );
144
145 OUT.normalBuf.xy = n.xy;
146 // @}
147
148 // Initialize the motion/specularity pixel
149 OUT.motionSpecularityBuf = tex2D( _specularMap, _in.uv );
150
151 // Initialize the diffuse/occlusion pixel
152 OUT.diffuseOcclusionBuf = tex2D( _diffuseMap, _in.uv );
153
154 return OUT;
155 }
float3 Normal = mul(matWorldInverse,IN.Normal);
float3 Tangent = float3(abs(Normal.y)+abs(Normal.z),abs(Normal.x),0);
float3 Binormal = cross(Tangent,Normal);
Olvida eso de la generacion del tangent space en el shader.
Irrlicht es capaz de pasar la tangente y la binormal, el problema es que no los pasa en TANGENT0 o BINORMAL0, sino en TEXCOORD1 y TEXCOORD2, respectivamente. Eso si, tienes que calcular el tangent space en la malla.
tienes que pasar la normal, la binormal y la tangente al pixel shader. Asi que en el vertex shader hacemos esto...
Con respecto a lo otro, no se, miraré los pdfs a ver que sale.
Irrlicht es capaz de pasar la tangente y la binormal, el problema es que no los pasa en TANGENT0 o BINORMAL0, sino en TEXCOORD1 y TEXCOORD2, respectivamente. Eso si, tienes que calcular el tangent space en la malla.
Code: Select all
VS_INPUT{
...
float3 normal : NORMAL0;
float3 tangent : TEXCOORD1;//fijate aqui!
float3 binormal : TEXCOORD2; //OJO! no estan donde se supone que deberian!
...
};
Code: Select all
...
OUT.normal = mul(IN.normal,matWorldInv);
OUT.tangent = mul(IN.normal,matWorldInv);
OUT.binormal = mul(IN.normal,matWorldInv);
...
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
gracias mel, este es el shader en hlsl.
I think that work.
Can I work with 2 uvmaps when I to use createMeshWithTangents, how?.
I think that work.
Code: Select all
float4x4 matWorldViewInv;
float4x4 matWorlViewProjection;
//--------------------------------------------
sampler2D tex1 : register(s0);
//--------------------------------------------
struct VS_INPUT
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 Texcoord1 : TEXCOORD0;
float3 Tangent : TEXCOORD1;
float3 Binormal : TEXCOORD2;
};
//--------------------------------------------
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord1 : TEXCOORD0;
float3 vNormal : TEXCOORD1;
float3 vTangent : TEXCOORD2;
float3 vBinormal : TEXCOORD3;
float3x3 tangentToView : TEXCOORD4;
};
//--------------------------------------------
struct PS_INPUT
{
float2 Texcoord1 : TEXCOORD0;
float3 vNormal : TEXCOORD1;
float3 vTangent : TEXCOORD2;
float3 vBinormal : TEXCOORD3;
float3x3 tangentToView : TEXCOORD4;
};
//--------------------------------------------
VS_OUTPUT main_vs( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.Texcoord1 = IN.Texcoord1;
OUT.Position = mul(IN.Position,matWorlViewProjection);
OUT.vNormal = mul(matWorldViewInv,IN.Normal);
OUT.vTangent = mul(matWorldViewInv,IN.Tangent);
OUT.vBinormal = mul(matWorldViewInv,IN.Binormal);
OUT.tangentToView[0] = OUT.vTangent;
OUT.tangentToView[1] = OUT.vBinormal;
OUT.tangentToView[2] = OUT.vNormal;
return( OUT );
}
//--------------------------------------------
float4 main_ps( PS_INPUT IN ) : COLOR0
{
float4 Color;
Color.w = 1;
Color.xyz = tex2D(tex1,IN.Texcoord1).xyz * 2 - 1;
Color.xyz = normalize(mul(Color.xyz,IN.tangentToView));
Color.z = sqrt( 1 - Color.x * Color.x - Color.y * Color.y );
return Color;
}
//--------------------------------------------
no va a funcionar, porque usted es la regeneración de la componente Z de normal
usted no será capaz de regenerar el normal si Z es negativo
lo que tiene que tener la normal en viewspace por escrito a la textura
Estoy asumiendo que usted tiene un deferred renderer?
no funcionarà, ja que s'estan regenerant el component Z normal
vostè no serà capaç de regenerar el normal si Z és negatiu
el que ha de tenir la normal en viewspace per escrit a la textura
Estic assumint que vostè té un deferred renderer?
Ce ne marchera pas, parce que vous régénére de la composante Z de normale
vous ne serez pas en mesure de régénérer la normale, si Z est négatif. Donc vous besoin avoir la normale dans le viewspace écrite à la texture
Je suppose que vous avez un deferred renderer?
To nie zadziala, poniewaz regenerujesz component Z normal'a. Ty nie bedziesz wstanie zregenerowac go jesli Z jest negatywne. Dlatego musisz miec normal w viewspace zapisany w teksturze. Zakladam ze masz deferred renderer?
Ni fydd yn gweithio, am eich bod yn adfywio'r gydran Z arferol
ni fyddwch yn gallu adfywio arferol os yn negyddol Z
felly mae'n rhaid i chi gael y arferol mewn viewspace ysgrifenedig i'r gwead
Yr wyf yn tybio bod gennych renderer gohiriedig
Right how many more languages do you want this in?
usted no será capaz de regenerar el normal si Z es negativo
lo que tiene que tener la normal en viewspace por escrito a la textura
Estoy asumiendo que usted tiene un deferred renderer?
no funcionarà, ja que s'estan regenerant el component Z normal
vostè no serà capaç de regenerar el normal si Z és negatiu
el que ha de tenir la normal en viewspace per escrit a la textura
Estic assumint que vostè té un deferred renderer?
Ce ne marchera pas, parce que vous régénére de la composante Z de normale
vous ne serez pas en mesure de régénérer la normale, si Z est négatif. Donc vous besoin avoir la normale dans le viewspace écrite à la texture
Je suppose que vous avez un deferred renderer?
To nie zadziala, poniewaz regenerujesz component Z normal'a. Ty nie bedziesz wstanie zregenerowac go jesli Z jest negatywne. Dlatego musisz miec normal w viewspace zapisany w teksturze. Zakladam ze masz deferred renderer?
Ni fydd yn gweithio, am eich bod yn adfywio'r gydran Z arferol
ni fyddwch yn gallu adfywio arferol os yn negyddol Z
felly mae'n rhaid i chi gael y arferol mewn viewspace ysgrifenedig i'r gwead
Yr wyf yn tybio bod gennych renderer gohiriedig
Right how many more languages do you want this in?
No I dont get offended by people speaking their languages because I would be a racist prick like the majority of the english population between the ages of 12 to 18, but keep in mind that the post will be searched by people with similar problems. Now it would be useful to provide an english translation for all the explanations, because google translate does have real issues.
And when I stuck it in g_translate I got a vague idea, you are not doing deferred but normal map reading, the Z reconstruction method is fine but it will give you extra computation time also the depth map MAY not be normalized (bad interpolation/filtering, although most of the time it should be correct). The only time it comes useful is if you use the LUMINANCE format for your normal map (just two 8 bit values) for compression. Even when using the relief map you will still have 1 channel free and not used, so no performance or memory boost. The method is 100% correct though so you can use it, as all normal maps face towards the camera (Z or Y positive)
And when I stuck it in g_translate I got a vague idea, you are not doing deferred but normal map reading, the Z reconstruction method is fine but it will give you extra computation time also the depth map MAY not be normalized (bad interpolation/filtering, although most of the time it should be correct). The only time it comes useful is if you use the LUMINANCE format for your normal map (just two 8 bit values) for compression. Even when using the relief map you will still have 1 channel free and not used, so no performance or memory boost. The method is 100% correct though so you can use it, as all normal maps face towards the camera (Z or Y positive)
-
- Posts: 126
- Joined: Wed Sep 29, 2010 8:23 pm
-
- Posts: 126
- Joined: Wed Sep 29, 2010 8:23 pm
First one translated.Mel wrote: Forget about the generation of the tangent space in the shader.
Irrlicht is capable of passing the tangent and binormal, the problem is that it doesn't pass them in TANGENT0 or BINORMAL0, rather it passes them in TEXCOORD1 and TEXTCOORD2, respectively. So, you have to calculate the tangent space manually (??? I think this is slang I am not familiar with...)
You have to pas the normal, binormal and the tangent to the pixel shader. This is what you do in the pixel shader...Code: Select all
VS_INPUT{ ... float3 normal : NORMAL0; float3 tangent : TEXCOORD1;//Look here! float3 binormal : TEXCOORD2; //Keep an eye out! They aren't where //you would expect them to be! ... };
Concerning everything else, I don't know, I'll check the pdfs to see what comes out.Code: Select all
... OUT.normal = mul(IN.normal,matWorldInv); OUT.tangent = mul(IN.normal,matWorldInv); OUT.binormal = mul(IN.normal,matWorldInv); ...
Last edited by macron12388 on Fri Dec 17, 2010 12:00 am, edited 1 time in total.
-
- Posts: 126
- Joined: Wed Sep 29, 2010 8:23 pm
Second one translated.kaos wrote:Thanks mel, this is the shader in hlsl
I think that'll work.
How can I work with 2 uvmaps when I use createMeshWithTangents.Code: Select all
float4x4 matWorldViewInv; float4x4 matWorlViewProjection; //-------------------------------------------- sampler2D tex1 : register(s0); //-------------------------------------------- struct VS_INPUT { float4 Position : POSITION0; float3 Normal : NORMAL0; float2 Texcoord1 : TEXCOORD0; float3 Tangent : TEXCOORD1; float3 Binormal : TEXCOORD2; }; //-------------------------------------------- struct VS_OUTPUT { float4 Position : POSITION0; float2 Texcoord1 : TEXCOORD0; float3 vNormal : TEXCOORD1; float3 vTangent : TEXCOORD2; float3 vBinormal : TEXCOORD3; float3x3 tangentToView : TEXCOORD4; }; //-------------------------------------------- struct PS_INPUT { float2 Texcoord1 : TEXCOORD0; float3 vNormal : TEXCOORD1; float3 vTangent : TEXCOORD2; float3 vBinormal : TEXCOORD3; float3x3 tangentToView : TEXCOORD4; }; //-------------------------------------------- VS_OUTPUT main_vs( VS_INPUT IN ) { VS_OUTPUT OUT; OUT.Texcoord1 = IN.Texcoord1; OUT.Position = mul(IN.Position,matWorlViewProjection); OUT.vNormal = mul(matWorldViewInv,IN.Normal); OUT.vTangent = mul(matWorldViewInv,IN.Tangent); OUT.vBinormal = mul(matWorldViewInv,IN.Binormal); OUT.tangentToView[0] = OUT.vTangent; OUT.tangentToView[1] = OUT.vBinormal; OUT.tangentToView[2] = OUT.vNormal; return( OUT ); } //-------------------------------------------- float4 main_ps( PS_INPUT IN ) : COLOR0 { float4 Color; Color.w = 1; Color.xyz = tex2D(tex1,IN.Texcoord1).xyz * 2 - 1; Color.xyz = normalize(mul(Color.xyz,IN.tangentToView)); Color.z = sqrt( 1 - Color.x * Color.x - Color.y * Color.y ); return Color; } //--------------------------------------------
I am sorry, i spoke in spanish for his clarity's sake.
I did some tests, and THIS works exactly as the one Guerrilla uses in Killzone2: I am picking your example to save some writting
This code is pretty straight. The good thing is that the values of this shader are suitable for an ARGB 32 bit texture. I think it should be very useful to have an OpenGL counterpart.
I did some tests, and THIS works exactly as the one Guerrilla uses in Killzone2: I am picking your example to save some writting
Code: Select all
float4x4 matViewInv; //inverse of the view matrix!
float4x4 matWorlViewProjection;
//--------------------------------------------
sampler2D tex1 : register(s0);//This is the normal map.
//--------------------------------------------
struct VS_INPUT
{
float4 Position : POSITION0;
float3 Normal : NORMAL0;
float2 Texcoord1 : TEXCOORD0;
float3 Tangent : TEXCOORD1;
float3 Binormal : TEXCOORD2;
};
//--------------------------------------------
struct VS_OUTPUT
{
float4 Position : POSITION0;
float2 Texcoord1 : TEXCOORD0;
float3 vNormal : TEXCOORD1;
float3 vTangent : TEXCOORD2;
float3 vBinormal : TEXCOORD3;
float3x3 tangentToView : TEXCOORD4;
};
//--------------------------------------------
struct PS_INPUT
{
float2 Texcoord1 : TEXCOORD0;
float3 vNormal : TEXCOORD1;
float3 vTangent : TEXCOORD2;
float3 vBinormal : TEXCOORD3;
float3x3 tangentToView : TEXCOORD4;
};
//--------------------------------------------
VS_OUTPUT main_vs( VS_INPUT IN )
{
VS_OUTPUT OUT;
OUT.Texcoord1 = IN.Texcoord1;
OUT.Position = mul(IN.Position,matWorlViewProjection);
OUT.vNormal = mul(matViewInv,IN.Normal);
OUT.vTangent = mul(matViewInv,IN.Tangent);
OUT.vBinormal = mul(matViewInv,IN.Binormal);
OUT.tangentToView[0] = OUT.vTangent;
OUT.tangentToView[1] = OUT.vBinormal;
OUT.tangentToView[2] = OUT.vNormal;
return( OUT );
}
//--------------------------------------------
float4 main_ps( PS_INPUT IN ) : COLOR0
{
float4 Color;
Color.w = 1;
Color.xyz = tex2D(tex1,IN.Texcoord1).xyz * 2 - 1;
Color.xyz = normalize(mul(Color.xyz,IN.tangentToView));
return float4(Color.xy,-Color.z,1);
//Z is actually calculated, but not shown, you have to revert its value because it is negative. You must keep that in mind also.
}
//--------------------------------------------
Last edited by Mel on Fri Dec 17, 2010 12:09 am, edited 1 time in total.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
-
- Posts: 126
- Joined: Wed Sep 29, 2010 8:23 pm