Created
October 30, 2022 19:20
-
-
Save Const-me/b6930103b0193b2694a3375a0760a60e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.