mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-25 00:12:52 +08:00
Spot lights geometry improvement, LodLights cone angles and game crash fixes
This commit is contained in:
parent
ea876743bc
commit
77e036e750
@ -589,7 +589,7 @@ namespace CodeWalker.GameFiles
|
|||||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
||||||
new MetaStructureEntryInfo_s(MetaName.timeAndStateFlags, 56, MetaStructureEntryDataType.Array, 0, 6, 0),
|
new MetaStructureEntryInfo_s(MetaName.timeAndStateFlags, 56, MetaStructureEntryDataType.Array, 0, 6, 0),
|
||||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedInt, 0, 0, 0),
|
||||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.HASH, 72, MetaStructureEntryDataType.Array, 0, 8, 0),
|
new MetaStructureEntryInfo_s(MetaName.hash, 72, MetaStructureEntryDataType.Array, 0, 8, 0),
|
||||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
||||||
new MetaStructureEntryInfo_s(MetaName.coneInnerAngle, 88, MetaStructureEntryDataType.Array, 0, 10, 0),
|
new MetaStructureEntryInfo_s(MetaName.coneInnerAngle, 88, MetaStructureEntryDataType.Array, 0, 10, 0),
|
||||||
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
new MetaStructureEntryInfo_s((MetaName)MetaTypeName.ARRAYINFO, 0, MetaStructureEntryDataType.UnsignedByte, 0, 0, 0),
|
||||||
|
@ -14110,7 +14110,7 @@ namespace CodeWalker.GameFiles
|
|||||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
||||||
new PsoStructureEntryInfo(MetaName.timeAndStateFlags, PsoDataType.Array, 56, 0, (MetaName)6),
|
new PsoStructureEntryInfo(MetaName.timeAndStateFlags, PsoDataType.Array, 56, 0, (MetaName)6),
|
||||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UInt, 0, 0, 0),
|
||||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.HASH, PsoDataType.Array, 72, 0, (MetaName)8),
|
new PsoStructureEntryInfo(MetaName.hash, PsoDataType.Array, 72, 0, (MetaName)8),
|
||||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
||||||
new PsoStructureEntryInfo(MetaName.coneInnerAngle, PsoDataType.Array, 88, 0, (MetaName)10),
|
new PsoStructureEntryInfo(MetaName.coneInnerAngle, PsoDataType.Array, 88, 0, (MetaName)10),
|
||||||
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
new PsoStructureEntryInfo((MetaName)MetaTypeName.ARRAYINFO, PsoDataType.UByte, 0, 0, 0),
|
||||||
|
@ -49,9 +49,9 @@ VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID)
|
|||||||
else if (InstType == 2)//spot (cone)
|
else if (InstType == 2)//spot (cone)
|
||||||
{
|
{
|
||||||
float arads = InstConeOuterAngle;
|
float arads = InstConeOuterAngle;
|
||||||
float3 cpos = ipos.xyz * (tan(arads) * extent);
|
float3 tpos = (ipos.xyz * sin(arads)) + float3(0, 0, ipos.w * cos(arads));
|
||||||
cpos.y += ipos.w * extent;
|
float3 cpos = ((ipos.w > 0) ? normalize(tpos) : tpos) * extent;
|
||||||
opos = (cpos.x * InstTangentX) + (cpos.y * InstDirection) + (cpos.z * InstTangentY);
|
opos = (cpos.x * InstTangentX) + (cpos.y * InstTangentY) + (cpos.z * InstDirection);
|
||||||
}
|
}
|
||||||
else if (InstType == 4)//capsule
|
else if (InstType == 4)//capsule
|
||||||
{
|
{
|
||||||
|
@ -47,9 +47,9 @@ VS_Output main(float4 ipos : POSITION, uint iid : SV_InstanceID)
|
|||||||
else if (LightType == 2)//spot (cone)
|
else if (LightType == 2)//spot (cone)
|
||||||
{
|
{
|
||||||
float arads = lodlight.OuterAngleOrCapExt;
|
float arads = lodlight.OuterAngleOrCapExt;
|
||||||
float3 cpos = ipos.xyz * (tan(arads) * extent);
|
float3 tpos = (ipos.xyz * sin(arads)) + float3(0, 0, ipos.w * cos(arads));
|
||||||
cpos.y += ipos.w * extent;
|
float3 cpos = ((ipos.w>0) ? normalize(tpos) : tpos) * extent;
|
||||||
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.Direction.xyz) + (cpos.z * lodlight.TangentY.xyz);
|
opos = (cpos.x * lodlight.TangentX.xyz) + (cpos.y * lodlight.TangentY.xyz) + (cpos.z * lodlight.Direction.xyz);
|
||||||
}
|
}
|
||||||
else if (LightType == 4)//capsule
|
else if (LightType == 4)//capsule
|
||||||
{
|
{
|
||||||
|
@ -1513,8 +1513,8 @@ namespace CodeWalker.Rendering
|
|||||||
light.TangentY = new Vector4(l.TangentY, 0.0f);
|
light.TangentY = new Vector4(l.TangentY, 0.0f);
|
||||||
light.Falloff = l.Falloff;
|
light.Falloff = l.Falloff;
|
||||||
light.FalloffExponent = Math.Max(l.FalloffExponent*0.01f, 0.5f);//is this right?
|
light.FalloffExponent = Math.Max(l.FalloffExponent*0.01f, 0.5f);//is this right?
|
||||||
light.InnerAngle = l.ConeInnerAngle * 0.0087266462f; //pi/360
|
light.InnerAngle = l.ConeInnerAngle * 0.012319971f; //pi/255
|
||||||
light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360
|
light.OuterAngleOrCapExt = l.ConeOuterAngleOrCapExt * 0.012319971f; //pi/255
|
||||||
var type = l.Type;
|
var type = l.Type;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -1036,8 +1036,8 @@ namespace CodeWalker.Rendering
|
|||||||
var tx = lodlight.TangentX;
|
var tx = lodlight.TangentX;
|
||||||
var ty = lodlight.TangentY;
|
var ty = lodlight.TangentY;
|
||||||
var extent = lodlight.Falloff;
|
var extent = lodlight.Falloff;
|
||||||
var innerAngle = lodlight.ConeInnerAngle * 0.0087266462f; //pi/360
|
var innerAngle = lodlight.ConeInnerAngle * 0.012319971f; //pi/255
|
||||||
var outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.0087266462f; //pi/360
|
var outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.012319971f; //pi/255
|
||||||
var type = lodlight.Type;
|
var type = lodlight.Type;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -1047,10 +1047,8 @@ namespace CodeWalker.Rendering
|
|||||||
RenderSelectionCircle(pos, Vector3.UnitY, Vector3.UnitZ, extent, colwht);
|
RenderSelectionCircle(pos, Vector3.UnitY, Vector3.UnitZ, extent, colwht);
|
||||||
break;
|
break;
|
||||||
case LightType.Spot:
|
case LightType.Spot:
|
||||||
float coneouterrad = extent * (float)Math.Tan(outerAngle);
|
RenderSelectionCone(pos, tx, ty, dir, (float)Math.Sin(outerAngle)*extent, (float)Math.Cos(outerAngle)*extent, colblu);
|
||||||
float coneinnerrad = extent * (float)Math.Tan(innerAngle);
|
RenderSelectionCone(pos, tx, ty, dir, (float)Math.Sin(innerAngle)*extent, (float)Math.Cos(innerAngle)*extent, colwht);
|
||||||
RenderSelectionCone(pos, tx, ty, dir, coneouterrad, extent, colblu);
|
|
||||||
RenderSelectionCone(pos, tx, ty, dir, coneinnerrad, extent, colwht);
|
|
||||||
break;
|
break;
|
||||||
case LightType.Capsule:
|
case LightType.Capsule:
|
||||||
outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.25f;
|
outerAngle = lodlight.ConeOuterAngleOrCapExt * 0.25f;
|
||||||
|
@ -90,7 +90,7 @@ namespace CodeWalker.Rendering
|
|||||||
VertexShader LightVS;
|
VertexShader LightVS;
|
||||||
PixelShader LightPS;
|
PixelShader LightPS;
|
||||||
PixelShader LightMSPS;
|
PixelShader LightMSPS;
|
||||||
UnitCone LightCone;
|
LightCone LightCone;
|
||||||
UnitSphere LightSphere;
|
UnitSphere LightSphere;
|
||||||
UnitCapsule LightCapsule;
|
UnitCapsule LightCapsule;
|
||||||
UnitQuad LightQuad;
|
UnitQuad LightQuad;
|
||||||
@ -160,8 +160,8 @@ namespace CodeWalker.Rendering
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LightCone = new UnitCone(device, bLodLightVS, 4, false);
|
LightCone = new LightCone(device, bLodLightVS, 2);
|
||||||
LightSphere = new UnitSphere(device, bLodLightVS, 4, true);
|
LightSphere = new UnitSphere(device, bLodLightVS, 3, true);
|
||||||
LightCapsule = new UnitCapsule(device, bLodLightVS, 4, false);
|
LightCapsule = new UnitCapsule(device, bLodLightVS, 4, false);
|
||||||
LightQuad = new UnitQuad(device, true);
|
LightQuad = new UnitQuad(device, true);
|
||||||
LightQuadLayout = new InputLayout(device, bDirLightVS, new[]
|
LightQuadLayout = new InputLayout(device, bDirLightVS, new[]
|
||||||
|
@ -20,12 +20,12 @@ namespace CodeWalker.Rendering
|
|||||||
private VertexBufferBinding vbbinding;
|
private VertexBufferBinding vbbinding;
|
||||||
private int indexcount;
|
private int indexcount;
|
||||||
|
|
||||||
private struct SphTri
|
private struct Tri
|
||||||
{
|
{
|
||||||
public int v1;
|
public int v1;
|
||||||
public int v2;
|
public int v2;
|
||||||
public int v3;
|
public int v3;
|
||||||
public SphTri(int i1, int i2, int i3)
|
public Tri(int i1, int i2, int i3)
|
||||||
{
|
{
|
||||||
v1 = i1;
|
v1 = i1;
|
||||||
v2 = i2;
|
v2 = i2;
|
||||||
@ -46,7 +46,7 @@ namespace CodeWalker.Rendering
|
|||||||
|
|
||||||
List<Vector4> verts = new List<Vector4>();
|
List<Vector4> verts = new List<Vector4>();
|
||||||
Dictionary<Vector4, int> vdict = new Dictionary<Vector4, int>();
|
Dictionary<Vector4, int> vdict = new Dictionary<Vector4, int>();
|
||||||
List<SphTri> curtris = new List<SphTri>();
|
List<Tri> curtris = new List<Tri>();
|
||||||
|
|
||||||
verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f));//top end (translated by VS!)
|
verts.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f));//top end (translated by VS!)
|
||||||
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal
|
verts.Add(new Vector4(0.0f, -1.0f, 0.0f, 0.0f));//top normal
|
||||||
@ -82,8 +82,8 @@ namespace CodeWalker.Rendering
|
|||||||
i1 = 2;
|
i1 = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
curtris.Add(new SphTri(0, i0, i1)); //fill the cone
|
curtris.Add(new Tri(0, i0, i1)); //fill the cone
|
||||||
curtris.Add(new SphTri(1, i1+1, i0+1)); //bottom cap triangles
|
curtris.Add(new Tri(1, i1+1, i0+1)); //bottom cap triangles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -149,4 +149,160 @@ namespace CodeWalker.Rendering
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class LightCone
|
||||||
|
{
|
||||||
|
private Buffer VertexBuffer { get; set; }
|
||||||
|
private Buffer IndexBuffer { get; set; }
|
||||||
|
private InputLayout InputLayout { get; set; }
|
||||||
|
private VertexBufferBinding vbbinding;
|
||||||
|
private int indexcount;
|
||||||
|
|
||||||
|
private struct Tri
|
||||||
|
{
|
||||||
|
public Vector4 v1;
|
||||||
|
public Vector4 v2;
|
||||||
|
public Vector4 v3;
|
||||||
|
public Tri(Vector4 i1, Vector4 i2, Vector4 i3)
|
||||||
|
{
|
||||||
|
v1 = i1;
|
||||||
|
v2 = i2;
|
||||||
|
v3 = i3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public LightCone(Device device, byte[] vsbytes, int detail)
|
||||||
|
{
|
||||||
|
|
||||||
|
InputLayout = new InputLayout(device, vsbytes, new[]
|
||||||
|
{
|
||||||
|
new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var tris = new List<Tri>();
|
||||||
|
var newtris = new List<Tri>();
|
||||||
|
var curtris = new List<Tri>();
|
||||||
|
|
||||||
|
curtris.Clear();//"cone" triangles
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(-1, 0, 0, 1), new Vector4(0, -1, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(0, 1, 0, 1), new Vector4(-1, 0, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(1, 0, 0, 1), new Vector4(0, 1, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 0, 0), new Vector4(0, -1, 0, 1), new Vector4(1, 0, 0, 1)));
|
||||||
|
for (int i = 0; i < detail; i++)
|
||||||
|
{
|
||||||
|
foreach (var tri in curtris)
|
||||||
|
{
|
||||||
|
var v1 = tri.v1;
|
||||||
|
var v2 = tri.v2;
|
||||||
|
var v3 = tri.v3;
|
||||||
|
var v4 = new Vector4(Vector3.Normalize((v2 + v3).XYZ() * 0.5f), 1);
|
||||||
|
newtris.Add(new Tri(v1, v2, v4));
|
||||||
|
newtris.Add(new Tri(v1, v4, v3));
|
||||||
|
}
|
||||||
|
curtris = newtris;
|
||||||
|
newtris = new List<Tri>();
|
||||||
|
}
|
||||||
|
tris.AddRange(curtris);
|
||||||
|
|
||||||
|
curtris.Clear();//hemisphere triangles
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(0, -1, 0, 1), new Vector4(-1, 0, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(-1, 0, 0, 1), new Vector4(0, 1, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(0, 1, 0, 1), new Vector4(1, 0, 0, 1)));
|
||||||
|
curtris.Add(new Tri(new Vector4(0, 0, 1, 1), new Vector4(1, 0, 0, 1), new Vector4(0, -1, 0, 1)));
|
||||||
|
for (int i = 0; i < detail; i++)
|
||||||
|
{
|
||||||
|
foreach (var tri in curtris)
|
||||||
|
{
|
||||||
|
var v1 = tri.v1;
|
||||||
|
var v2 = tri.v2;
|
||||||
|
var v3 = tri.v3;
|
||||||
|
var v4 = new Vector4(Vector3.Normalize((v1 + v2).XYZ() * 0.5f), 1);
|
||||||
|
var v5 = new Vector4(Vector3.Normalize((v2 + v3).XYZ() * 0.5f), 1);
|
||||||
|
var v6 = new Vector4(Vector3.Normalize((v3 + v1).XYZ() * 0.5f), 1);
|
||||||
|
newtris.Add(new Tri(v1, v4, v6));
|
||||||
|
newtris.Add(new Tri(v4, v2, v5));
|
||||||
|
newtris.Add(new Tri(v4, v5, v6));
|
||||||
|
newtris.Add(new Tri(v6, v5, v3));
|
||||||
|
}
|
||||||
|
curtris = newtris;
|
||||||
|
newtris = new List<Tri>();
|
||||||
|
}
|
||||||
|
tris.AddRange(curtris);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var verts = new List<Vector4>();
|
||||||
|
var vdict = new Dictionary<Vector4, int>();
|
||||||
|
var idata = new List<uint>();
|
||||||
|
uint addVert(Vector4 v)
|
||||||
|
{
|
||||||
|
if (vdict.TryGetValue(v, out int i)) return (uint)i;
|
||||||
|
var n = verts.Count;
|
||||||
|
verts.Add(v);
|
||||||
|
vdict[v] = n;
|
||||||
|
return (uint)n;
|
||||||
|
}
|
||||||
|
foreach (var tri in tris)
|
||||||
|
{
|
||||||
|
idata.Add(addVert(tri.v1));
|
||||||
|
idata.Add(addVert(tri.v2));
|
||||||
|
idata.Add(addVert(tri.v3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VertexBuffer = Buffer.Create(device, BindFlags.VertexBuffer, verts.ToArray());
|
||||||
|
vbbinding = new VertexBufferBinding(VertexBuffer, 16, 0);
|
||||||
|
|
||||||
|
IndexBuffer = Buffer.Create(device, BindFlags.IndexBuffer, idata.ToArray());
|
||||||
|
indexcount = idata.Count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Draw(DeviceContext context)
|
||||||
|
{
|
||||||
|
context.InputAssembler.InputLayout = InputLayout;
|
||||||
|
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||||
|
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||||
|
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||||
|
|
||||||
|
context.DrawIndexed(indexcount, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawInstanced(DeviceContext context, int count)
|
||||||
|
{
|
||||||
|
context.InputAssembler.InputLayout = InputLayout;
|
||||||
|
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
|
||||||
|
context.InputAssembler.SetVertexBuffers(0, vbbinding);
|
||||||
|
context.InputAssembler.SetIndexBuffer(IndexBuffer, Format.R32_UInt, 0);
|
||||||
|
|
||||||
|
context.DrawIndexedInstanced(indexcount, count, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (VertexBuffer != null)
|
||||||
|
{
|
||||||
|
VertexBuffer.Dispose();
|
||||||
|
VertexBuffer = null;
|
||||||
|
}
|
||||||
|
if (IndexBuffer != null)
|
||||||
|
{
|
||||||
|
IndexBuffer.Dispose();
|
||||||
|
IndexBuffer = null;
|
||||||
|
}
|
||||||
|
if (InputLayout != null)
|
||||||
|
{
|
||||||
|
InputLayout.Dispose();
|
||||||
|
InputLayout = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user