forked from microsoft/Xbox-ATG-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SimpleInstancing.hlsli
119 lines (102 loc) · 4.51 KB
/
SimpleInstancing.hlsli
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
//--------------------------------------------------------------------------------------
// SimpleInstancing.hlsli
//
// Simple shaders demonstrating how to perform instanced drawing.
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "Shared.h"
//--------------------------------------------------------------------------------------
// Name: InstancingConstants
// Desc: Constant buffer containing clip-space transform.
//--------------------------------------------------------------------------------------
cbuffer InstancingConstants
{
float4x4 Clip; // Clip transform
};
//--------------------------------------------------------------------------------------
// Name: Lights
// Desc: Constant buffer containing lighting information.
//--------------------------------------------------------------------------------------
cbuffer Lights
{
float4 Directional;
float4 PointPositions[ c_pointLightCount ];
float4 PointColors[ c_pointLightCount ];
};
//--------------------------------------------------------------------------------------
// Name: InstancedVertex
// Desc: Structure containing vertex definition for instanced drawing.
// The incoming vertices arrive from 3 streams - one of which contains
// per-primitive information, the other two per-instance.
//--------------------------------------------------------------------------------------
struct InstancedVertex
{
float3 Position : POSITION; // Vertex position (per primitive)
float3 Normal : NORMAL; // Vertex normal (per primitive)
float4 InstRotation : I_ROTATION; // Orientation quaternion (per instance)
float4 InstPosScale : I_POSSCALE; // Position and scale (per instance)
float4 InstColor : I_COLOR; // Color (per instance)
};
//--------------------------------------------------------------------------------------
// Name: Interpolants
// Desc: Interpolated values passed to the pixel shader.
//--------------------------------------------------------------------------------------
struct Interpolants
{
float4 Position : SV_POSITION;
float3 Normal : TEXCOORD0;
float4 Color : TEXCOORD1;
float3 WorldPos : TEXCOORD2;
};
//--------------------------------------------------------------------------------------
// Name: RotateVectorByQuaternion
// Desc: Rotate a vector using a quaternion.
//--------------------------------------------------------------------------------------
float3 RotateVectorByQuaternion( float4 Q, float3 V )
{
return V + 2.0f * cross( Q.xyz, cross( Q.xyz, V ) + Q.w * V );
}
//--------------------------------------------------------------------------------------
// Name: VSMain()
// Desc: Vertex Shader main entrypoint.
//--------------------------------------------------------------------------------------
Interpolants VSMain( InstancedVertex In )
{
Interpolants Out = ( Interpolants ) 0;
// Scale.
float3 position = In.Position * In.InstPosScale.w;
// Rotate vertex position and normal based on instance quaternion...
position = RotateVectorByQuaternion( In.InstRotation, position );
float3 normal = RotateVectorByQuaternion( In.InstRotation, In.Normal );
// Move to world space.
position += In.InstPosScale.xyz;
// ...and clip.
Out.Position = mul( float4( position, 1 ), Clip );
// World space transform
Out.WorldPos = position;
// Finally, output normal and color
Out.Normal = normal;
Out.Color = In.InstColor;
return Out;
}
//--------------------------------------------------------------------------------------
// Name: PSMain()
// Desc: Pixel Shader main entrypoint.
//--------------------------------------------------------------------------------------
float4 PSMain( Interpolants In ) : SV_Target
{
float4 colorOut = 0;
// Directional component:
colorOut = saturate( dot( In.Normal, Directional.xyz ) ) * In.Color * 0.5;
for( uint i = 0; i < c_pointLightCount; ++i )
{
float3 pointDirection = PointPositions[ i ].xyz - In.WorldPos;
float d = length( pointDirection );
float attenuation = max( 0, 1.0f - ( dot( pointDirection, pointDirection ) / 500 ) );
pointDirection = normalize( pointDirection );
colorOut += saturate( dot( In.Normal, pointDirection ) ) * In.Color * PointColors[ i ] * attenuation;
}
return colorOut + ( ( sign( In.Color.a ) * In.Color ) );
}