Skip to content

Instantly share code, notes, and snippets.

@Const-me
Created October 30, 2022 19:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Const-me/b6930103b0193b2694a3375a0760a60e to your computer and use it in GitHub Desktop.
Save Const-me/b6930103b0193b2694a3375a0760a60e to your computer and use it in GitHub Desktop.
cbuffer CB_PROJ
{
matrix camera;
};
struct VOut
{
float3 position : POSITION;
float3 r_s : NORMAL;
uint bits : BLENDINDICES;
};
struct GOut
{
float4 pos : SV_Position;
float3 position : POSITION;
float3 n : NORMAL;
float2 tex : TEXCOORD;
uint pID : SV_PrimitiveID;
};
// Compute [cos(angle), sin(angle)]
inline float2 direction( float angle )
{
float2 res;
sincos( angle, res.y, res.x );
return res;
}
// Rotate 2D vector by angle, using another vector with [ cos(angle), sin(angle) ] values
inline float2 rotateVector( float2 v, float2 dir )
{
float2 res;
res.x = dot( v, float2( dir.x, -dir.y ) );
res.y = dot( v, dir.yx );
return res;
}
// xy = rs.yz 2D vector, rotated by rs.x angle (in radians)
// zw = [ rs.y, -rs.z ] 2D vector, rotated by the same angle
inline float4 computeRotations( float3 rs )
{
const float2 dir = direction( rs.x );
float4 v = rs.yzyz;
v.w = -v.w;
v.xy = rotateVector( v.xy, dir );
v.zw = rotateVector( v.zw, dir );
return v;
}
// Unpack these bits, make a vector with [ x1, y1, x2, y2 ] texture coordinates for the quad
inline float4 unpackTexCoords( uint bits )
{
const uint4 bytes = ( bits >> uint4( 0, 8, 16, 24 ) ) & 0xFFu;
const float4 floats = ( float4 )( int4 )( bytes );
float4 tc = float4( floats.xz, 1.0, -1.0 ) / floats.ywyw;
tc.zw += tc.xy;
return tc;
}
// Transform the 3D vector with the 4x4 camera matrix in the constant buffer
inline float4 transformPosition( float3 pos )
{
return mul( float4( pos, 1.0f ), camera );
}
[maxvertexcount( 4 )]
void main( point VOut gin[ 1 ], uint pID : SV_PrimitiveID, inout TriangleStream<GOut> triStream )
{
GOut output;
// The original HLSL rotated 4 2D vectors [ -a, -b ], [ -a, b ], [ a, -b ] and [ a, b ] by the same angle
// The inputs are 2 pairs of 2 vectors of opposite directions.
// We can rotate just two of them, and use negate for other two. Saves couple math instructions in this shader.
const float4 rs = computeRotations( gin[ 0 ].r_s );
const float4 tc = unpackTexCoords( gin[ 0 ].bits );
output.pID = pID;
output.n = float3( 0.0f, 0.0f, -1.0f );
output.position = gin[ 0 ].position;
output.position.xy -= rs.xy;
output.pos = transformPosition( output.position );
output.tex = tc.xy;
triStream.Append( output );
output.position = gin[ 0 ].position;
output.position.xy -= rs.zw;
output.pos = transformPosition( output.position );
output.tex = tc.xw;
triStream.Append( output );
output.position = gin[ 0 ].position;
output.position.xy += rs.zw;
output.pos = transformPosition( output.position );
output.tex = tc.zy;
triStream.Append( output );
output.position = gin[ 0 ].position;
output.position.xy += rs.xy;
output.pos = transformPosition( output.position );
output.tex = tc.zw;
triStream.Append( output );
}
@Zenefess
Copy link

I have rewritten my shader based on your changes but, unfortunately, there was no difference in performance; not even by a small margin.

Thanks for all the help, mate. As much as I would like to think I can go back to coding after 14 years and remember everything like it was yesterday, it just isn't the case. But I am happy with how quickly my skill is coming back; it's all helping to make learning Direct3D 11 a very fast process. I just have to remember to be patient with myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment