Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
//-------------------------------------------------------------------------------------- // Globale Variablen //-------------------------------------------------------------------------------------- float4 g_MaterialDiffuseColor; // Materialstreufarbe float4 g_MaterialAmbientColor; // Materialhintergrundfarbe float4 g_MaterialSpecularColor; // Materialglanzfarbe float4 g_LightDiffuse; // Streufarbe des Lichts float4 g_LightAmbient; // Hintergrundfarbe des Lichts float4 g_LightSpecular; // Glanzfarbe des Lichts float3 g_LightPos; // Lichtposition im "world space" float g_fPhongExponent; // Glanzstärke float3 g_ViewPos; // Beobachter-Postition texture g_MeshTexture; // Modelltextur (Color Texture) texture g_NormalTexture; // (Normal Texture) texture g_SpecularTexture; float4x4 g_mWorld; // Weltmatrix für Objekt float4x4 g_mWorldTrans; // Transponierte Weltmatrix für Objekt float4x4 g_mWorldViewProjection; // Welt * Sicht * Projektion Matrix //-------------------------------------------------------------------------------------- // Textur Sampler //-------------------------------------------------------------------------------------- sampler MeshTextureSampler = sampler_state { Texture = <g_MeshTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; sampler MeshNTextureSampler = sampler_state { Texture = <g_NormalTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; sampler MeshSTextureSampler = sampler_state { Texture = <g_SpecularTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; //-------------------------------------------------------------------------------------- // Vertex Shader Ausgabe-Struktur //-------------------------------------------------------------------------------------- struct VS_OUTPUT { float4 Position : POSITION; // Vertex Position float2 TextureUV : TEXCOORD0; // Vertex Textur Koord float3 Normal : TEXCOORD1; // Normale float3 Tangent : TEXCOORD2; // Tangente float3 Binormal : TEXCOORD3; // Binormale float3 Light : TEXCOORD4; // Lichtvektor float3 View : TEXCOORD5; // Viewvektor }; //-------------------------------------------------------------------------------------- // Vertex Shader //-------------------------------------------------------------------------------------- VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, float3 vNormal : NORMAL, float3 vTangent : TANGENT, float2 vTexCoord0 : TEXCOORD0, uniform bool bTexture) { VS_OUTPUT Output; float3 vNormalWorldSpace; float3 vTangentWorldSpace; float3 vBinormalWorldSpace; float4 vVertexWorldSpace; // Transform the position from object space to homogeneous projection space Output.Position = mul(vPos, g_mWorldViewProjection); // Transform the normal from Texture/Tangent space to world space Output.Normal = mul(vNormal, (float3x3)g_mWorldTrans); // Transform the tangent from Texture/Tangent space to world space Output.Tangent = mul(vTangent, (float3x3)g_mWorldTrans); // Set up the tangent frame in world space Output.Binormal = cross( Output.Normal, Output.Tangent ); // Vertex to world Space vVertexWorldSpace = mul(vPos, g_mWorld); // Build the light vector from Light Source to Vertex Output.Light = g_LightPos - float3(vVertexWorldSpace.x, vVertexWorldSpace.y, vVertexWorldSpace.z); // Build view vector Output.View = g_ViewPos - float3(vVertexWorldSpace.x, vVertexWorldSpace.y, vVertexWorldSpace.z); // Textur Koordinaten setzen if( bTexture ) Output.TextureUV = vTexCoord0; else Output.TextureUV = 0; return Output; } //-------------------------------------------------------------------------------------- // Pixel Shader Ausgabe-Struktur //-------------------------------------------------------------------------------------- struct PS_OUTPUT { float4 RGBColor : COLOR0; // Pixel color }; //-------------------------------------------------------------------------------------- // Pixel Shader //-------------------------------------------------------------------------------------- PS_OUTPUT RenderScenePS( VS_OUTPUT In, uniform bool bTexture, uniform bool bSpecularOnly) { PS_OUTPUT Output; float3 vrgb = float3(0,0,0);; float3 vDiffuse = float3(0,0,0); // Load NormalMap float3 vTexNormal = tex2D(MeshNTextureSampler, In.TextureUV); // Load GlossMap and calc glossValue float3 vTexGloss = tex2D(MeshSTextureSampler, In.TextureUV); float fTexGloss = 0.299f*vTexGloss.x; fTexGloss = fTexGloss*g_fPhongExponent; //4 // Normalize and Move the lightvector from tangent space to world space float3x3 mTangentFrame = { In.Binormal, In.Tangent, In.Normal }; mTangentFrame = transpose(mTangentFrame); float3 vLight = normalize(In.Light); vLight = mul(vLight, (float3x3)mTangentFrame); vLight = normalize(vLight); // Normalize and Move the viewvector from tangent space to world space float3 vView = normalize(In.View); vView = mul(vView, (float3x3)mTangentFrame); vView = normalize(vView); // If using a signed texture, we must unbias the normal map data vTexNormal = (vTexNormal*2)-1; // Streukomponente berechnen float fNdotV = saturate(dot(vTexNormal, vLight)); vDiffuse = g_MaterialDiffuseColor * g_LightDiffuse * fNdotV; // Glanzkomponente berechnen if (bSpecularOnly) { float3 vReflectionWorldSpace = float3(0,0,0); float3 vSpecular = float3(0,0,0); if ((dot(vTexNormal, vLight)) >= 0) { vReflectionWorldSpace = 2*vTexNormal*fNdotV - vLight; vSpecular = g_MaterialSpecularColor * g_LightSpecular * pow(max(0,dot(vReflectionWorldSpace, vView)), fTexGloss); } vrgb = vDiffuse + vSpecular; } else vrgb = vDiffuse; Output.RGBColor.a = 1.0f; // Textur laden und mit Diffus-Farbe multiplizieren if( bTexture ) Output.RGBColor.rgb = tex2D(MeshTextureSampler, In.TextureUV) * vrgb; else Output.RGBColor.rgb = vrgb; return Output; } //-------------------------------------------------------------------------------------- // Rendern //-------------------------------------------------------------------------------------- technique RenderSceneWithTexture1Light2 { pass P0 { VertexShader = compile vs_2_0 RenderSceneVS( true); PixelShader = compile ps_2_0 RenderScenePS( true, true); } } |
Zitat
Jedoch würde ich empfehlen, statt die Normalen zu transformieren, einfach die Position des Lichtes vor der übergabe an den Shader mit der invertierten Weltmatrix zu transformieren. Natrürlich musst du dann die Position des Betrachters genauso transformieren und sparst dir damit wiederum die Transformation der Positionen.
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
//-------------------------------------------------------------------------------------- // Globale Variablen //-------------------------------------------------------------------------------------- float4 g_MaterialDiffuseColor; // Materialstreufarbe float4 g_MaterialAmbientColor; // Materialhintergrundfarbe float4 g_MaterialSpecularColor; // Materialglanzfarbe float4 g_LightDiffuse; // Streufarbe des Lichts float4 g_LightAmbient; // Hintergrundfarbe des Lichts float4 g_LightSpecular; // Glanzfarbe des Lichts float3 g_LightPos; // Lichtposition im "world space" float g_fPhongExponent; // Glanzstärke float3 g_ViewPos; // Beobachter-Postition texture g_MeshTexture; // Modelltextur (Color Texture) texture g_NormalTexture; // (Normal Texture) texture g_SpecularTexture; float4x4 g_mWorld; // Weltmatrix für Objekt float4x4 g_mWorldTrans; // Transponierte Weltmatrix für Objekt float4x4 g_mWorldViewProjection; // Welt * Sicht * Projektion Matrix //-------------------------------------------------------------------------------------- // Textur Sampler //-------------------------------------------------------------------------------------- sampler MeshTextureSampler = sampler_state { Texture = <g_MeshTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; sampler MeshNTextureSampler = sampler_state { Texture = <g_NormalTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; sampler MeshSTextureSampler = sampler_state { Texture = <g_SpecularTexture>; MipFilter = Anisotropic; MinFilter = Anisotropic; MagFilter = Anisotropic; MaxAnisotropy = 16; }; //-------------------------------------------------------------------------------------- // Vertex Shader Ausgabe-Struktur //-------------------------------------------------------------------------------------- struct VS_OUTPUT { float4 Position : POSITION; // Vertex Position float2 TextureUV : TEXCOORD0; // Vertex Textur Koord float3 Light : TEXCOORD1; // Lichtvektor float3 View : TEXCOORD2; // Viewvektor }; //-------------------------------------------------------------------------------------- // Vertex Shader //-------------------------------------------------------------------------------------- VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, float3 vNormal : NORMAL, float3 vTangent : TANGENT, float2 vTexCoord0 : TEXCOORD0) { VS_OUTPUT Output; float3 vBinormal; // Transform the position from object space to homogeneous projection space Output.Position = mul(vPos, g_mWorldViewProjection); // Set up the binormal vBinormal = cross(vNormal, vTangent); // Set up the tangent frame , transforms from object to tangent space float3x3 objToTangent = transpose(float3x3(vTangent, vBinormal, vNormal)); // Build the light vector from Light Source to Vertex, calc in object space, transform to tangent space float3 l = mul(g_LightPos - vPos.xyz, objToTangent); // Build view vector float3 v = mul(g_ViewPos - vPos.xyz, objToTangent); // Normalize vectors Output.Light = normalize(l); Output.View = normalize(v); // Textur Koordinaten setzen Output.TextureUV = vTexCoord0; return Output; } //-------------------------------------------------------------------------------------- // Pixel Shader Ausgabe-Struktur //-------------------------------------------------------------------------------------- struct PS_OUTPUT { float4 RGBColor : COLOR0; // Pixel color }; //-------------------------------------------------------------------------------------- // Pixel Shader //-------------------------------------------------------------------------------------- PS_OUTPUT RenderScenePS( VS_OUTPUT In) { PS_OUTPUT Output; // load normal map float3 vTexNormal = tex2D(MeshNTextureSampler, In.TextureUV); // Load gloss map and calc gloss value float3 vTexGloss = tex2D(MeshSTextureSampler, In.TextureUV); float fTexGloss = 0.299f * vTexGloss.x * g_fPhongExponent; // normalize light and view vectors float3 vLight = normalize(In.Light); float3 vView = normalize(In.View); // we are using a signed texture, we must unbias the normal map data vTexNormal = (vTexNormal*2)-1; // Streukomponente float fNdotV = saturate(dot(vTexNormal, vLight)); float3 vDiffuse = g_MaterialDiffuseColor * g_LightDiffuse * fNdotV; // Glanzkomponente float3 vReflectionWorldSpace = 2*vTexNormal*fNdotV - vLight; float3 vSpecular = g_MaterialSpecularColor * g_LightSpecular * pow(max(0,dot(vReflectionWorldSpace, vView)), fTexGloss); // End-Farbe float3 vrgb = vDiffuse + vSpecular; // Textur laden, mit End-Farbe multiplizieren Output.RGBColor.rgb = tex2D(MeshTextureSampler, In.TextureUV) * vrgb; Output.RGBColor.a = 1.0f; return Output; } //-------------------------------------------------------------------------------------- // Rendern //-------------------------------------------------------------------------------------- technique RenderSceneWithTexture1Light2 { pass P0 { VertexShader = compile vs_2_0 RenderSceneVS(); PixelShader = compile ps_2_0 RenderScenePS(); } } |
Quellcode |
|
1 |
float3x3 objToTangent = transpose(float3x3(vTangent, vBinormal, vNormal)); |
Quellcode |
|
1 |
float fTexGloss = 0.299f * vTexGloss.x * g_fPhongExponent; |
Zitat
// we are using a signed texture, we must unbias the normal map data
Quellcode |
|
1 |
vBinormal = cross(vNormal, vTangent); |
Quellcode |
|
1 |
vTexNormal = (2*vTexNormal)-1; |
Zitat von »"dot"«
normalerweise multipliziert man den fertigen specular anteil mit dem gloss faktor und nicht den exponenten...
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
//-------------------------------------------------------------------------------------- // Pixel Shader //-------------------------------------------------------------------------------------- PS_OUTPUT RenderScenePS( VS_OUTPUT In) { PS_OUTPUT Output; // load normal map; we are using a signed texture, we must unbias the normal map data float3 vTexNormal = tex2D(MeshNTextureSampler, In.TextureUV); vTexNormal = (2*vTexNormal)-1; // Load gloss map and calc gloss value float3 vTexGloss = tex2D(MeshSTextureSampler, In.TextureUV); float fTexGloss = 0.299f * vTexGloss.x; // normalize light and view vectors float3 vLight = normalize(In.Light); float3 vView = normalize(In.View); // diffuse part float fNdotL = saturate(dot(vTexNormal, vLight)); float3 vDiffuse = g_MaterialDiffuseColor * g_LightDiffuse * fNdotL; // specular part float3 vReflectionWorldSpace = 2*fNdotL*vTexNormal - vLight; float3 vSpecular = g_MaterialSpecularColor * g_LightSpecular; // ... and multiply with factor vSpecular = vSpecular * fTexGloss * pow(saturate(dot(vView, vReflectionWorldSpace)), g_fPhongExponent); // final color float3 vrgb = vDiffuse + vSpecular; // load texture, multiply with final color Output.RGBColor.rgb = tex2D(MeshTextureSampler, In.TextureUV) * vrgb; Output.RGBColor.a = 1.0f; return Output; } |
Zitat von »"dot"«
kann sein, dass ich grad genau falsch rum denke, aber dein tangent space sollte doch linkshändig sein oder?
Quellcode
1 vBinormal = cross(vNormal, vTangent);
müsste das dann nicht tangent x normal heißen?
wie berechnest du deine tangent vektoren?
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
tbResult CPhongLightingMesh::KugelHalbe_Mantel(float fRadius, int iSegmentY, int iSegmentR) { char acString[64]; //Halbkugelparameter prüfen - min 1 iSegmentY, min 3 iSegmentR) if ((fRadius<=0.0f)||(iSegmentY < 1)||(iSegmentR < 3)) TB_ERROR("Halbkugel mit falschem Parameter intitalisiert!", TB_ERROR); //Halbkugelparameter setzen m_fHaKuRadius = fRadius; m_iHaKuSegmentY = iSegmentY; m_iHaKuSegmentR = iSegmentR; // Effekt Index und VertexBuffer erstellen m_pPSQEffect = new tbEffect; m_pKVB = new tbVertexBuffer; m_pKIB = new tbIndexBuffer; //VB initialisieren - Oberseite der Kugel: 1 + m_iHaKuSegmentY*m_iHaKuSegmentR int NumVertices = 1 + m_iHaKuSegmentY*m_iHaKuSegmentR; if(m_pKVB->Init(NumVertices * sizeof(SPSQVertex), sizeof(SPSQVertex), PSQ_VERTEX_FVF, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT)) { return TB_ERROR; } //IB initialisieren - Bei 1. SegmentY: m_iHaKuSegmentR-Dreiecke //Plus jedes weitere SegmentY: 2*m_iHaKuSegmentR-Dreiecke int NumIndices = 3*m_iHaKuSegmentR; for (int i=1; i<m_iHaKuSegmentY; i++) NumIndices += 6*m_iHaKuSegmentR; if(m_pKIB->Init(NumIndices * sizeof(WORD), sizeof(WORD), D3DFMT_INDEX16)) { return TB_ERROR; } //Indizies WORD wIndex; //1.Segment for (int i=0; i<m_iHaKuSegmentR; i++) { wIndex = i+1; m_pKIB->AddIndex(&wIndex); wIndex = 0; m_pKIB->AddIndex(&wIndex); if (i != m_iHaKuSegmentR-1) wIndex = i+2; else wIndex = 1; m_pKIB->AddIndex(&wIndex); } //weitere Segmente for (int j=1; j<m_iHaKuSegmentY; j++) { for (int i=0; i<m_iHaKuSegmentR; i++) { wIndex = i+1+m_iHaKuSegmentR*j; m_pKIB->AddIndex(&wIndex); wIndex = i+1+m_iHaKuSegmentR*(j-1); m_pKIB->AddIndex(&wIndex); if (i != m_iHaKuSegmentR-1) wIndex = i+2+m_iHaKuSegmentR*j; else wIndex = i+2+m_iHaKuSegmentR*(j-1); m_pKIB->AddIndex(&wIndex); wIndex = i+1+m_iHaKuSegmentR*(j-1); m_pKIB->AddIndex(&wIndex); if (i != m_iHaKuSegmentR-1) wIndex = i+2+m_iHaKuSegmentR*(j-1); else wIndex = i+2+m_iHaKuSegmentR*(j-2); m_pKIB->AddIndex(&wIndex); if (i != m_iHaKuSegmentR-1) wIndex = i+2+m_iHaKuSegmentR*j; else wIndex = i+2+m_iHaKuSegmentR*(j-1); m_pKIB->AddIndex(&wIndex); } } // Den Index-Buffer aktualisieren if(m_pKIB->Update()) return TB_ERROR; // Textur laden m_pPSQTex = tbTextureManager::GetTexture(TEXTURE, 1); m_pPSQNTex = tbTextureManager::GetTexture(NORMAL_TEXTURE, 1); m_pPSQSTex = tbTextureManager::GetTexture(SPECULAR_TEXTURE, 1); // Effekt laden if(m_pPSQEffect == NULL) return TB_ERROR; if(m_pPSQEffect->Init("Data\\PhongLighting.fx")) return TB_ERROR; // Vertices SPSQVertex Vertex; // Spitze Vertex.vPosition = tbVector3(0.0f, m_fHaKuRadius, 0.0f); Vertex.vNormal = tbVector3(0.0f, 1.0f, 0.0f); Vertex.vTangent = tbVector3(1.0f, 0.0f, 0.0f);//<------------------------------------HIER WIRD DIE TANGENTE GESETZT Vertex.vTexture = tbVector2(0.0f, 0.0f); m_pKVB->SetVertex(0, &Vertex); // Segmentbildende Vertices float val = (TB_PI/2.0f)/m_iHaKuSegmentY; float valR = (2.0f*TB_PI)/m_iHaKuSegmentR; for (int j=m_iHaKuSegmentY-1; j>=0; j--) { float height = m_fHaKuRadius* sinf(val*j); for (int i=0; i<m_iHaKuSegmentR; i++) { Vertex.vPosition = tbVector3(m_fHaKuRadius* cosf(valR*i)*cosf(val*j), height, m_fHaKuRadius* sinf(valR*i)*cosf(val*j)); Vertex.vNormal = tbVector3(cosf(valR*i)*cosf(val*j), height, sinf(valR*i)*cosf(val*j)); Vertex.vTexture = tbVector2(cosf(valR*i)*cosf(val*j), sinf(valR*i)*cosf(val*j)); m_pKVB->SetVertex(i+1+m_iHaKuSegmentR*(m_iHaKuSegmentY-j-1), &Vertex); } } if(m_pKVB->Update()) return TB_ERROR; TB_INFO("Halbkugel initialisiert"); m_pPSQNumTechniques = m_pPSQEffect->GetNumTechniques(); m_pPSQTechnique = 0; m_fShininess = 128; return TB_OK; } |
Zitat
wenn ich
Code:
vTexNormal = (2*vTexNormal)-1;
verwende und die normalen als output durchgebe, schauts so aus:
http://img292.imageshack.us/img292/4826/screenshot20yz7.jpg
sonst:
http://img481.imageshack.us/img481/2756/screenshot19dq0.jpg
Zitat
die png file (=normal map) ist:
http://img58.imageshack.us/img58/9112/16tile01bumpiz1.png
Zitat
die tangenten setz ich für alle vertices einfach auf (1,0,0)
Werbeanzeige