what is the difference between matrix and float4x4 in HLSL - directx

When I define the cBuffer in hlsl, some examples shows
cbuffer cbPerObject
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
And the other shows
cbuffer cbPerObject
{
float4x4 worldMatrix;
float4x4 viewMatrix;
float4x4 projectionMatrix;
};
Does it means that type of matrix can have unlimited elements but float4x4 can just hold the first 16 elements?
which one do you prefer in HLSL?

To support older DirectX 8 era HLSL programs, matrix by itself is a typedef for matrix<float,4,4>. BTW, float4x4 is also a typedef for matrix<float,4,4>.
See HLSL, User-Defined Type

Related

How to pass an array from the vertex shader to the fragment shader, in Metal

In GLSL, I would simply use out vec3 array[10];, to pass an array from the vertex shader to the fragment shader. In Metal, however, I thought to do it this way:
struct FragmentIn {
float4 position [[position]];
float3 array[10];
};
This produces the following error:
Type 'FragmentIn' is not valid for attribute 'stage_in' because field 'array' has invalid type 'float3 [10]'
How can I solve this issue? I need to do certain calculations with per-vertex data that the fragment shader will use.
You need to "unroll" the array:
struct FragmentIn {
float4 position [[position]];
float3 thing0;
float3 thing1;
float3 thing2;
float3 thing3;
float3 thing4;
float3 thing5;
float3 thing6;
float3 thing7;
float3 thing8;
float3 thing9;
};

Different vertex formats in a Metal shader

My renderer supports 2 vertex formats:
typedef struct
{
packed_float3 position;
packed_float2 texcoord;
packed_float3 normal;
packed_float4 tangent;
packed_float4 color;
} vertex_ptntc;
typedef struct
{
packed_float3 position;
packed_float2 texcoord;
packed_float4 color;
} vertex_ptc;
One of my shader library's vertex shader signature is as follows:
vertex ColorInOut unlit_vertex(device vertex_ptc* vertex_array [[ buffer(0) ]],
constant uniforms_t& uniforms [[ buffer(1) ]],
unsigned int vid [[ vertex_id ]])
Some of the meshes rendered by this shader will use one format and some will use the other. How do I support both formats? This shader only uses the attributes in vertex_ptc. Do I have to write another vertex shader?
When defining the shader function argument as an array of structures (as you're doing), the structure definition in the shader vertex function must match the exact shape and size of the actual structures in the buffer (including padding).
Have you considered defining the input in terms of the [[stage_in]] qualifier, and vertex descriptors? This will allow you to massage the vertex input on a shader-by-shader basis, by using an [[attribute(n)]] qualifier on each element of the structure declared for each shader function. You would define a vertex descriptor for each structure.

Normal calculations in vertex shader?

I'm using the rastertek framework for terrain generation. I've got the terrain rendered from the vertex shader but I don't know how to calculate the normals in the shader. Theres a function call in one of the classes that generates the normals from the terrain but this only works if the terrain was generated on the cpu. Heres the code for the vertex shader I'm using:
////////////////////////////////////////////////////////////////////////////////
// Filename: terrain.vs
////////////////////////////////////////////////////////////////////////////////
#include "terrain.fx"
/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
float4 position : POSITION;
float3 normal : NORMAL;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float3 normal : NORMAL;
};
////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType TerrainVertexShader(VertexInputType input)
{
PixelInputType output;
input.position.y = input.position.y + terrain(input.position.x,input.position.z);
// Change the position vector to be 4 units for proper matrix calculations.
input.position.w = 1.0f;
// Calculate the position of the vertex against the world, view, and projection matrices.
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
// Calculate the normal vector against the world matrix only.
output.normal = mul(input.normal, (float3x3)worldMatrix);
// Normalize the normal vector.
output.normal = normalize(output.normal);
return output;
}
Your big problem with generating normals in a shader is that you need knowledge of surrounding vertices. This is something you can overcome with a geometry shader but not with a vertex shader. A simple way to calculate the normal is to calculate the polygon normals (take the vector formed from 2 edges and cross product them for the face normal) of all polys that hit the vertex you are looking at and then add them up and normalise. As such if you haven't got access to a geometry shader the only real solution is to use the CPU. Even then this is not the best way to calculate the vertex normals. You may still find it better to use a more complex algorithm yet and that will give you even more problems! So yeah, CPU or geometry shader ... those are, basically, your options.

DirectX 11 Shader Error. Pixel Shader receiving only NaN

Hy everyone. I started re-coding my engine to convert it to directx 11. I'm now trying to get the basics working, but this error is really stoping me.
I created a basic shader, a simple dot product of the normal and the view. I got it to compile without errors, but it dosnt works.
It just totaly deforms the input mesh. I started debugging in vs2012, and found out that the pixel shader was getting as input all NaNs. I attached two screens and the shader code, if someone can provide any ideas, it would be really apriciated.
Vertex Shader
//----------------------------------------------------------------------------
// Constant Buffer Variables
//----------------------------------------------------------------------------
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
//float3 CameraPos;
float Power;
}
//---------------------------------------------------------------------------
struct VS_INPUT
{
float4 Pos : POSITION;
float3 Normal : NORMAL;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float3 Normal : TEXCOORD0;
};
//--------------------------------------------------------------------------
// Vertex Shader
//-------------------------------------------------------------------------------
VS_OUTPUT VS( VS_INPUT input)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Pos = mul( input.Pos, World );
output.Pos = mul( output.Pos, View );
output.Pos = mul( output.Pos, Projection );
output.Normal = mul( float4( input.Normal, 1 ), World ).xyz;
//output.wNormal = input.Normal;
return output;
}
And here the Pixel Shader
//------------------------------------------------------------------------------
// Constant Buffer Variables
//------------------------------------------------------------------------------
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
float Power;
}
//------------------------------------------------------------------------------
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float3 wNormal : TEXCOORD0;
};
//-----------------------------------------------------------------------------
// Pixel Shader
//-----------------------------------------------------------------------------
float4 PS( VS_OUTPUT input) : SV_Target
{
//return pow(dot(input.wNormal,float3(0,0,0)),Power); // fixed camera, just for now
return float4(0.1,0.6,0.1,1);
}
And at last, i created a xml file structure for my shaders, that i then parse, dont know if it relevant, but
<?xml version="1.0" encoding="utf-8"?>
<vs path = "D:\\Documentos\\Visual Studio 2012\\Projects\\Fusion Engine\\Tests\\ConstantLighting_VS.hlsl" name ="VS" target = "vs_4_0">
</vs>
<ps path = "D:\\Documentos\\Visual Studio 2012\\Projects\\Fusion Engine\\Tests\\ConstantLighting_PS.hlsl" name ="PS" target = "ps_4_0">
<val1 type = "scalar" value = "0.456645" name = "Power"/>
</ps>
You could just use #pragma pack_matrix(row_major) in your shader instead of tranposing matrices on the cpu side
Try simply concatenating the WorldViewProjection matrices into one, before calling the vertex function. Hopefully all of those compnenets were okay, not, say, all zero's? You might also want to explicitly set the matrix type in your HLSL code as "matrix <float, 4, 4>" or just declare the transform(s) as "float4x4".
Ok, i solved it. You MUST use DirectX::XMMatrixTranspose() when you pass any matrix to the shader.
Tricky DirectX ;)
Only in DirectX 11 you have to transpose the matrices berfore sending them to shader. They changed the way you keep and work with structures in shaders

errorX3013: vertex shader does not take 0 arguments

I am starting to play around with the Shader Model 4.0 and I'm trying to setup a basic sample project. (Basically rendering and light up a cube)
But atm. I am totally stuck at the most basic part. My Vertex Shader won't compile with the following error message:
Error 1 Errors compiling ...\x.fx:
...\x.fx(32,43): error X3013: 'VertexShaderFunction': function does not take 0 parameters ...\x.fx 32 43 ...
my code until now:
float4x4 World;
float4x4 View;
float4x4 Projection;
struct VS_INPUT
{
float4 Position : POSITION;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
};
VS_OUTPUT VertexShaderFunction(in VS_INPUT input)
{
VS_OUTPUT output;
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
return output;
}
technique Technique1
{
pass Pass1
{
SetVertexShader( Compile( vs_4_1, VertexShaderFunction() ) );
SetGeometryShader(NULL);
SetPixelShader( NULL );
}
}
the VS_INPUT parameter is clearly marked as input and not as uniform. The struct assigns every member (well the only one) an input semantic. Does anyone have an idea why this is not compiling properly?
I am using Win7 Ultimate + DirectX11 + XNA GameStudio 4.0,
my graphics card is an Intel GMA 4500MHD (so it should allow for shader model 4.0)
and her I go, answering my own question - what a stupid mistake (and hard to find):
it is CompileShader() and not Compile()

Resources