(1)
Engine\Shaders\Private\LocalVertexFactory.ush
Result.PrimitiveId = GetPrimitiveId(Interpolants);
(2)
Engine\Shaders\Private\SceneData.ush
(3)
PrimitiveId 是一个 Entity ,不是一个 Face 三角形
G:\UnrealEngine-git\Engine\Shaders\Private\LocalVertexFactoryCommon.ush
uint GetPrimitiveId(FVertexFactoryInterpolantsVSToPS Interpolants)
{
#if VF_USE_PRIMITIVE_SCENE_DATA
return Interpolants.PrimitiveId;
#else
return 0;
#endif
}
(1)
Engine\Shaders\Private\SceneData.ush
// Fetch from scene primitive buffer
FPrimitiveSceneData GetPrimitiveData(uint PrimitiveId)
{
// Note: layout must match FPrimitiveSceneShaderData in C++
// Relying on optimizer to remove unused loads
FPrimitiveIndex PrimitiveIndex = SetupPrimitiveIndexes(PrimitiveId);
FPrimitiveSceneData PrimitiveData;
PrimitiveData.LocalToWorld[0] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 0);
PrimitiveData.LocalToWorld[1] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 1);
PrimitiveData.LocalToWorld[2] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 2);
PrimitiveData.LocalToWorld[3] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 3);
PrimitiveData.InvNonUniformScaleAndDeterminantSign = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 4);
PrimitiveData.ObjectWorldPositionAndRadius = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 5);
PrimitiveData.WorldToLocal[0] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 6);
PrimitiveData.WorldToLocal[1] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 7);
PrimitiveData.WorldToLocal[2] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 8);
PrimitiveData.WorldToLocal[3] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 9);
PrimitiveData.PreviousLocalToWorld[0] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 10);
PrimitiveData.PreviousLocalToWorld[1] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 11);
PrimitiveData.PreviousLocalToWorld[2] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 12);
PrimitiveData.PreviousLocalToWorld[3] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 13);
PrimitiveData.PreviousWorldToLocal[0] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 14);
PrimitiveData.PreviousWorldToLocal[1] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 15);
PrimitiveData.PreviousWorldToLocal[2] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 16);
PrimitiveData.PreviousWorldToLocal[3] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 17);
PrimitiveData.ActorWorldPosition = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 18).xyz;
PrimitiveData.UseSingleSampleShadowFromStationaryLights = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 18).w;
PrimitiveData.ObjectBounds = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 19).xyz;
PrimitiveData.LpvBiasMultiplier = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 19).w;
PrimitiveData.DecalReceiverMask = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 20).x;
PrimitiveData.PerObjectGBufferData = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 20).y;
PrimitiveData.UseVolumetricLightmapShadowFromStationaryLights = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 20).z;
PrimitiveData.DrawsVelocity = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 20).w;
PrimitiveData.ObjectOrientation = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 21);
PrimitiveData.NonUniformScale = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 22);
PrimitiveData.LocalObjectBoundsMin = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 23).xyz;
PrimitiveData.LightingChannelMask = asuint(LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 23).w);
PrimitiveData.LocalObjectBoundsMax = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 24).xyz;
PrimitiveData.LightmapDataIndex = asuint(LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 24).w);
PrimitiveData.PreSkinnedLocalBoundsMin = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 25).xyz;
PrimitiveData.SingleCaptureIndex = asuint(LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 25).w);
PrimitiveData.PreSkinnedLocalBoundsMax = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 26).xyz;
PrimitiveData.OutputVelocity = asuint(LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 26).w);
UNROLL
for (int i = 0; i < NUM_CUSTOM_PRIMITIVE_DATA; i++)
{
PrimitiveData.CustomPrimitiveData[i] = LoadPrimitivePrimitiveSceneDataElement(PrimitiveIndex, 27 + i);
}
return PrimitiveData;
}
(1)
Engine\Shaders\Private\VertexFactoryCommon.ush
(1)
RWBuffer : 基本类型 Buffer
RWByteAddressBuffer : Byte 类型 Buffer
RWStructuredBuffer : 模板 T Buffer
https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-rwstructuredbuffer
(1)
https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-rwtexture2d
Because a RWTexture2D object is a UAV-type object, its properties differ from a shader resource view (SRV)-type object, such as a Texture2D object. For example, you can read from and write to a RWTexture2D object, but you can only read from a Texture2D object.
A RWTexture2D object cannot use methods from a Texture2D object, such as Sample. However, because you can create multiple view types to the same resource, you can declare multiple texture types as a single texture in multiple shaders. For example, the following code snippets show how you can declare and use a RWTexture2D object as tex in a compute shader and then declare and use a Texture2D object as tex in a pixel shader.
Note
The runtime enforces certain usage patterns when you create multiple view types to the same resource. For example, the runtime does not allow you to have both a UAV mapping for a resource and SRV mapping for the same resource active at the same time.
The following code is for the compute shader:
RWTexture2D<float> tex;
[numthreads(groupDim_x, groupDim_y, 1)]
void main(
uint3 groupId : SV_GroupID,
uint3 groupThreadId : SV_GroupThreadID,
uint3 dispatchThreadId : SV_DispatchThreadID,
uint groupIndex : SV_GroupIndex)
{
tex [dispatchThreadId.xy] = <something>;
}
The following code is for the pixel shader:
struct PixelShaderInput
{
float4 pos : SV_POSITION;
float2 tex : TEXTURE;
};
Texture2D<float> tex;
float4 main(PixelShaderInput input) : SV_TARGET
{
return tex.Sample(TextureSampler, input.tex);
}
(1)
Spherical Harmonics, Precomputed Radiance Transfer and Realtime Radiosity in Computer Games
/**
* Cube texel solid angle computation based on formula from Manne Öhrström's
* thesis - "Spherical Harmonics, Precomputed Radiance Transfer and Realtime Radiosity in Computer Games".
*/
float AreaElement(float x, float y)
{
// Equation 7.12
return atan2(x * y, sqrt(x * x + y * y + 1));
}
G:\UnrealEngine-git\Engine\Shaders\Private\RayTracing\SkyLightMipTreeCommon.ush