I m currently having a problem texturing a mesh that is generated using a marching tetrahedron algorithm. The code is in a .fx HLSL file. A description of the problem could be that the texture seems to move in accordance to the positioning of the camera. So for instance, if the camera is strafed left and right, the texture will also move left and right with it. The problem also occurs when panning the camera left and right.
这是一种奇怪的影响,非常难以描述,因此,我把一些图像贴上了正文,文本地址和地址定在Clamp上,以便更容易地展示问题。
https://i.stack.imgur.com/GksUW.png
https://i.stack.imgur.com/ZpgmV.png
如你所知,将照相机移至右边,也使文字走向正确。
我可能已经忽略了一个完全显而易见的东西,例如用某种矩阵(我尝试过)来乘。 一切帮助都会受到赞赏。
这里是我的粉碎法。
float4 DiffusePS( SurfaceVertex IN ) : SV_Target
页: 1
float4 AmbientColor = float4(0.2, 0.2, 0.2, 1);
float AmbientIntensity = 0.2;
float4 Kd = 0.5;
float4 diffuseLight = 0.5;
float4 Pos = GetWorldSpacePos( IN.Pos );
float3 N = normalize(IN.N);
float3 L1 = normalize(LightPos1 - Pos.xyz);
float3 L2 = normalize(LightPos2 - Pos.xyz);
float3 L3 = normalize(LightPos3 - Pos.xyz);
float NdotL1 = max(0, dot(N, L1));
float NdotL2 = max(0, dot(N, L2));
float NdotL3 = max(0, dot(N, L3));
float3 I = normalize(Pos.xyz);
float3 V = normalize(-Pos.xyz);
float4 vDiff = diffuseLight * Kd * NdotL1;
float4 vDiff2 = diffuseLight * Kd * NdotL2;
float4 vDiff3 = diffuseLight * Kd * NdotL3;
float3 Color = vDiff + vDiff2 + vDiff3;
float4 derp = rockTexture.Sample(RockSampler, IN.tex.xy);
return lerp(derp ,float4(Color, 1), 0.5);
感谢任何帮助
EDIT: The other of the .fx file
#define MAX_METABALLS 400
#define IOR 2.5
#define PI 3.1415
Buffer<float4> SampleDataBuffer;
struct SampleData
页: 1
float4 Pos : SV_Position;
float4 Field : TEXCOORD0; // Gradient in .xyz, value in .w
};
struct SurfaceVertex
页: 1
float4 Pos : SV_Position;
float3 N : NORMAL;
float2 tex : TEXCOORD;
};
cbuffer constants
页: 1
float R0Constant = ((1.0 - (1.0/IOR)) * (1.0 - (1.0/IOR))) / ((1.0 + (1.0/IOR)) * (1.0 + (1.0/IOR)));
float R0Inv = 1.0 - ((1.0 - (1.0/IOR)) * (1.0 - (1.0/IOR)))/((1.0 + (1.0/IOR)) * (1.0 + (1.0/IOR)));
};
cbuffer cb0 : register(b0)
页: 1
row_major float4x4 ProjInv;
row_major float3x3 ViewIT;
row_major float4x4 WorldViewProj;
row_major float4x4 World;
uint NumMetaballs;
float4 Metaballs[MAX_METABALLS]; // .xyz -> metaball center, .w -> metaball squared radius
float3 ViewportOrg;
float3 ViewportSizeInv;
float3 LightPos1; // view-space light position 1
float3 LightPos2; // view-space light position 2
float3 LightPos3; // view-space light position 3
};
Texture2D rockTexture;
SamplerState RockSampler
页: 1
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
float4 GetWorldSpacePos( float4 WindowPos )
页: 1
float4 ClipPos;
ClipPos.x = (2 * ((WindowPos.x - ViewportOrg.x) * ViewportSizeInv.x) - 1);
ClipPos.y = (-2 * ((WindowPos.y - ViewportOrg.y) * ViewportSizeInv.y) + 1);
ClipPos.z = ((WindowPos.z - ViewportOrg.z) * ViewportSizeInv.z);
ClipPos.w = 1;
float4 Pos;
Pos = mul(ClipPos, ProjInv); // backtransform clipspace position to get viewspace position
Pos.xyz /= Pos.w; // re-normalize
return Pos;
}
// Metaball function
// Returns metaball function value in .w and its gradient in .xyz
float4 Metaball(float3 Pos, float3 Center, float RadiusSq)
页: 1
float4 o;
float3 d = Pos - Center;
float DistSq = dot(d, d);
float InvDistSq = 1 / DistSq;
o.xyz = -2 * RadiusSq * InvDistSq * InvDistSq * d;
o.w = RadiusSq * InvDistSq;
return o;
}
SamplerState TriLinearSampler
页: 1
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
// Vertex shader calculates field contributions at each grid vertex
SampleData SampleFieldVS(float3 Pos : POSITION)
页: 1
SampleData o;
float3 WorldPos = mul(float4(Pos, 1), World).xyz;
// Sum up contributions from all metaballs
o.Field = 0;
for (uint i = 0; i<NumMetaballs; i++)
页: 1
//o.Field += WorldPos.y;
o.Field += Metaball(WorldPos, Metaballs[i].xyz, Metaballs[i].w);
}
// Transform position and normals
o.Pos = mul(float4(Pos.xyz, 1), WorldViewProj);
o.Field.xyz = -normalize(mul(o.Field.xyz, ViewIT)); // we want normals in view space
// Generate in-out flags
return o;
}
SampleData PassThroughVS(SampleData IN)
页: 1
SampleData OUT;
OUT = IN;
return OUT;
}
// Estimate where isosurface intersects grid edge with endpoints v0, v1
SurfaceVertex CalcIntersection(SampleData v0, SampleData v1)
页: 1
SurfaceVertex o;
// We re taking special care to generate bit-exact results regardless of traversal (v0,v1) or (v1, v0)
float t = (2.0 - (v0.Field.w + v1.Field.w)) / (v1.Field.w - v0.Field.w);
o.Pos = 0.5 * (t * (v1.Pos - v0.Pos) + (v1.Pos + v0.Pos));
o.N = 0.5 * (t * (v1.Field.xyz - v0.Field.xyz) + (v1.Field.xyz + v0.Field.xyz));
float4 worldPos = mul(World, o.Pos);
o.tex = worldPos.xy;
return o;
}
// This struct stores vertex indices of up to 4 edges from the input tetrahedron. The GS code below
// uses these indices to index into the input vertex set for interpolation along those edges.
// It basically encodes topology for the output triangle strip (of up to 2 triangles).
struct TetrahedronIndices
页: 1
uint4 e0;
uint4 e1;
};
[MaxVertexCount(4)]
void TessellateTetrahedraGS(lineadj SampleData In[4], inout TriangleStream<SurfaceVertex> Stream)
页: 1
// construct index for this tetrahedron
uint index = (uint(In[0].Field.w > 1) << 3) | (uint(In[1].Field.w > 1) << 2) | (uint(In[2].Field.w > 1) << 1) | uint(In[3].Field.w > 1);
// don t bother if all vertices out or all vertices in
if (index > 0 && index < 15)
页: 1
uint4 e0 = EdgeTableGS[index].e0;
uint4 e1 = EdgeTableGS[index].e1;
// Emit a triangle
Stream.Append( CalcIntersection(In[e0.x], In[e0.y]) );
Stream.Append( CalcIntersection(In[e0.z], In[e0.w]) );
Stream.Append( CalcIntersection(In[e1.x], In[e1.y]) );
// Emit additional triangle, if necessary
if (e1.z != 0) 页: 1
Stream.Append( CalcIntersection(In[e1.z], In[e1.w]) );
}
}
}
TextureCube EnvMap;
float FresnelApprox(float3 I, float3 N)
页: 1
return R0Constant + R0Inv * pow(1.0 - dot(I, N), 5.0);
}
float4 ShadeSurfacePS( SurfaceVertex IN ) : SV_Target
页: 1
float4 Pos = GetWorldSpacePos( IN.Pos );
float3 N = normalize(IN.N);
float3 L1 = normalize(LightPos1 - Pos.xyz);
float3 L2 = normalize(LightPos2 - Pos.xyz);
float3 L3 = normalize(LightPos3 - Pos.xyz);
float3 I = normalize(Pos.xyz);
float3 R = reflect(I, N);
float4 Reflected = EnvMap.Sample( TriLinearSampler, mul(ViewIT, R ) );
float NdotL1 = max(0, dot(N, L1));
float NdotL2 = max(0, dot(N, L2));
float NdotL3 = max(0, dot(N, L3));
float3 Color = NdotL1 * float3(1, 1, 1) + pow(max(dot(R, L1), 0), 32)
+ NdotL2 * float3(0.65, 0.6, 0.45) + pow(max(dot(R, L2), 0), 32)
+ NdotL3 * float3(0.7, 0.7, 0.8) + pow(max(dot(R, L3), 0), 32);
return lerp(EnvMap.Sample( TriLinearSampler, mul(ViewIT, R) ), float4(Color, 1), FresnelApprox(I, N) * 0.05 );
}
float4 SimplePS( SurfaceVertex IN, uniform float4 color ) : SV_Target
页: 1
return color;
}
float4 DiffusePS( SurfaceVertex IN ) : SV_Target
页: 1
float4 AmbientColor = float4(0.2, 0.2, 0.2, 1);
float AmbientIntensity = 0.2;
float4 Kd = 0.5;
float4 diffuseLight = 0.5;
float4 Pos = GetWorldSpacePos( IN.Pos );
float3 N = normalize(IN.N);
float3 L1 = normalize(LightPos1 - Pos.xyz);
float3 L2 = normalize(LightPos2 - Pos.xyz);
float3 L3 = normalize(LightPos3 - Pos.xyz);
float NdotL1 = max(0, dot(N, L1));
float NdotL2 = max(0, dot(N, L2));
float NdotL3 = max(0, dot(N, L3));
float3 I = normalize(Pos.xyz);
float3 V = normalize(-Pos.xyz);
float4 vDiff = diffuseLight * Kd * NdotL1;
float4 vDiff2 = diffuseLight * Kd * NdotL2;
float4 vDiff3 = diffuseLight * Kd * NdotL3;
float3 Color = vDiff + vDiff2 + vDiff3;
float4 derp = rockTexture.Sample(RockSampler, IN.tex.xy);
return lerp(derp ,float4(Color, 1), 0.5);
//return lerp(NoiseTexture.Sample( NoiseSampler, IN.tex ), float4(Color, 1), FresnelApprox(V, N) * 0.05 );
//return saturate(vDiff+vDiff2+vDiff3 + AmbientColor * AmbientIntensity);
}
DepthStencilState EnableDepthDSS
页: 1
DepthEnable = true;
DepthWriteMask = 1;
};
RasterizerState WireFrameRS
页: 1
MultiSampleEnable = True;
CullMode = None;
FillMode = WireFrame;
};
RasterizerState SolidRS
页: 1
MultiSampleEnable = True;
CullMode = None;
FillMode = Solid;
};
technique10 MarchingTetrahedraWireFrame
页: 1
pass P0
页: 1
SetRasterizerState( WireFrameRS );
SetDepthStencilState( EnableDepthDSS, 0 );
SetVertexShader( CompileShader( vs_4_0, SampleFieldVS() ) );
SetGeometryShader( CompileShader( gs_4_0, TessellateTetrahedraGS() ) );
SetPixelShader( CompileShader( ps_4_0, SimplePS( float4( 0.7, 0.7, 0.7, 1 ) ) ) );
}
}
// Tessellate isosurface in a single pass
technique10 MarchingTetrahedraSinglePassGS
页: 1
pass P0
页: 1
SetRasterizerState( SolidRS );
SetDepthStencilState( EnableDepthDSS, 0 );
SetVertexShader( CompileShader( vs_4_0, SampleFieldVS() ) );
SetGeometryShader( CompileShader( gs_4_0, TessellateTetrahedraGS() ) );
SetPixelShader( CompileShader( ps_4_0, DiffusePS() ) );
}
}
// Tessellate isosurface in two passes, streaming out VS results in-between
GeometryShader StreamOutGS = ConstructGSWithSO( CompileShader( vs_4_0, PassThroughVS() ), "SV_Position.xyzw; TEXCOORD0.xyzw" );
technique10 MarchingTetrahedraMultiPassGS
页: 1
pass P0
页: 1
SetVertexShader( CompileShader( vs_4_0, SampleFieldVS() ) );
SetGeometryShader( StreamOutGS );
SetPixelShader( NULL );
}
pass P1
页: 1
SetRasterizerState( SolidRS );
SetDepthStencilState( EnableDepthDSS, 0 );
SetVertexShader( CompileShader ( vs_4_0, PassThroughVS() ) );
SetGeometryShader( CompileShader( gs_4_0, TessellateTetrahedraGS() ) );
SetPixelShader( CompileShader( ps_4_0, DiffusePS() ) );
}
}