I have a common method in hlsli
/// RendererShaderTypes.hlsli
///
static inline float4 OverlayColor(float2 texOverlay, float4 videoColor)
{
float4 texColor = float4(imageMixTexture[4].Sample(imageMixSampler[4], texOverlay));
if (texColor.r == keyColor.r &&
texColor.g == keyColor.g &&
texColor.b == keyColor.b)
{
return videoColor;
}
return lerp(texColor, videoColor, transparency);
}
It's called from more than one hlsl pixel shaders.
#include "RendererShaderTypes.hlsli"
float4 main(PSPosTexOverlay input) : SV_TARGET
{
return OverlayColor(input.texOverlay, backColor);
}
also called to another pixel shader
#include "RendererShaderTypes.hlsli"
float4 main(PSPosVideoTexture input) : SV_TARGET
{
// lookup color of video
float4 mixColor = mul(colorMatrix[0], VideoColor(imageMixSampler[0], imageMixTexture[0], input.texImage));
mixColor.rgb *= mixColor.a;
mixColor.a = 1.0f;
return OverlayColor(input.texOverlay, mixColor);
}
when compiled shows following warning. Any idea why it's showing?
warning X4000: use of potentially uninitialized variable (OverlayColor)
I don't know yet any satisfactory reason but I have solved the issue. Any function that calls a mid-function return statement will show the warning during compilation. I have re-writed one of above like this and the warning went away.
static inline float4 OverlayColor(int texIndex, float2 texOverlay, float4 videoColor)
{
float4 texColor = float4(imageMixTexture[4].Sample(imageMixSampler[4], texOverlay));
float4 overlayColor;
if (texColor.r == keyColor.r &&
texColor.g == keyColor.g &&
texColor.b == keyColor.b)
{
overlayColor = videoColor;
}
else
overlayColor = lerp(texColor, videoColor, transparency);
return overlayColor;
}
Here's a simple hull shader code that i made, to try to understand tessellation.
I just can't find anything wrong with this code, but the compile function always return false. Here's my code:
My input and output structures:
[domain("tri")] // indicates a triangle patch (3 verts)
[partitioning("fractional_odd")] // fractional avoids popping
// vertex ordering for the output triangles
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
// name of the patch constant hull shader
[patchconstantfunc("ConstantsHS")]
//[maxtessfactor(7.0)]
cbuffer TessellationBuffer
{
float tessellationAmount;
float3 padding;
};
struct VS_CONTROL_POINT_OUTPUT
{
float3 vWorldPos : POSITION;
float2 vTexCoord : TEXCOORD0;
float3 vNormal : NORMAL0;
};
struct HS_CONTROL_POINT_OUTPUT
{
float3 vWorldPos : POSITION;
float2 vTexCoord : TEXCOORD0;
float3 vNormal : NORMAL0;
};
struct HS_CONSTANT_DATA_OUTPUT
{
float Edges[3] : SV_TessFactor;
float Inside : SV_InsideTessFactor;
};
My functions:
HS_CONTROL_POINT_OUTPUT HS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint uCPID : SV_OutputControlPointID, uint patchId : SV_PrimitiveID )
{
HS_CONTROL_POINT_OUTPUT Output;
Output.vWorldPos = inputPatch[uCPID].vWorldPos;
Output.vTexCoord = inputPatch[uCPID].vTexCoord;
Output.vNormal = inputPatch[uCPID].vNormal;
return Output;
};
HS_CONSTANT_DATA_OUTPUT ConstantsHS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint PatchID : SV_PrimitiveID )
{
HS_CONSTANT_DATA_OUTPUT Output;
Output.Edges[0] = tessellationAmount;
Output.Edges[1] = tessellationAmount;
Output.Edges[2] = tessellationAmount;
Output.Inside = tessellationAmount;
return Output;
};
Thanks for any help.
The attributes have to be set on the entry point like below, then your hull shader is valid :
[domain("tri")] // indicates a triangle patch (3 verts)
[partitioning("fractional_odd")] // fractional avoids popping
// vertex ordering for the output triangles
[outputtopology("triangle_cw")]
[outputcontrolpoints(3)]
// name of the patch constant hull shader
[patchconstantfunc("ConstantsHS")]
//[maxtessfactor(7.0)]
HS_CONTROL_POINT_OUTPUT HS(InputPatch<VS_CONTROL_POINT_OUTPUT, 3> inputPatch, uint uCPID : SV_OutputControlPointID, uint patchId : SV_PrimitiveID )
On a side note, The command line tool FXC.exe would have print an error message that would have put you in the right direction : error X3000: syntax error: unexpected token 'cbuffer'
And i am unsure of what function you are referring to, D3DCompile return a HRESULT, not a boolean, and it also output a blob for you with the error messages in case of failure.
I am working on a game engine using DirectX 11 and am having trouble getting shaders to encode properly. I am precompiling shaders to .csh files and creating shaders with the byte codes.
I get this error when I try to create any shader, but for this example I will use my PassThrough vertex shader.
D3D11 ERROR: ID3D11Device::CreateVertexShader: Encoded Vertex Shader size doesn't match specified size. [ STATE_CREATION ERROR #166: CREATEVERTEXSHADER_INVALIDSHADERBYTECODE]
The Shader:
#include "../VertexLayouts.hlsli"
// structs in included file
struct PASS_THROUGH_VS
{
float3 pos : POSITION;
float2 texCoord : TEXCOORD;
};
struct PASS_THROUGH_PS
{
float4 pos : SV_POSITION;
float2 texCoord : TEXCOORD;
};
PASS_THROUGH_PS main( PASS_THROUGH_VS input )
{
PASS_THROUGH_PS output = (PASS_THROUGH_PS)(0);
output.pos = float4(input.pos, 1);
output.texCoord = input.texCoord;
return output;
}
with these settings:
PassThrough_PS properties
In Renderer.h
#include "Vertex Shaders\PassThrough_VS.csh"
In Renderer.cpp
HRESULT hrReturn;
hrReturn = CreateVertexShader(&PassThrough_VS, sizeof(PassThrough_VS), Pass_Through_VS);
if (FAILED(hrReturn)) {}
//return hrReturn;
HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
HRESULT hrReturn;
tVertShader newShader = {};
hrReturn = D3Device->CreateVertexShader(&ptrByteCode, szByteCodeLength, nullptr, &(newShader.m_id3dShader)); // WHERE ERROR OCCURS
if (FAILED(hrReturn))
return hrReturn;
newShader.m_ptrByteCode = ptrByteCode;
newShader.m_szByteCodeLength = szByteCodeLength;
D3VertexShaders[type] = newShader;
return hrReturn;
}
The problem is you are passing a pointer-to-a-pointer, so you aren't actually passing the shader blob data to Direct3D.
HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
HRESULT hrReturn;
tVertShader newShader = {};
hrReturn = D3Device->CreateVertexShader(&ptrByteCode, szByteCodeLength,
nullptr, &(newShader.m_id3dShader));
...
The correct code is:
HRESULT CRenderer::CreateVertexShader(const void* ptrByteCode, SIZE_T szByteCodeLength, eVertexShaderType type)
{
HRESULT hrReturn;
tVertShader newShader = {};
hrReturn = D3Device->CreateVertexShader(ptrByteCode, szByteCodeLength,
nullptr, &(newShader.m_id3dShader));
...
You should take a look at DirectX Tool Kit and the tutorials in particular.
You didn't include any details about the tVertShader type, but you could well have reference counting problems. Consider using Microsoft::WRL::ComPtr instead of raw pointers for managing the lifetimes of Direct3D COM objects. See this article.
I've been search for a good text methodolgy recently and found one at http://www.braynzarsoft.net/Articles/index.php?p=VA&article=Easy-Font-Rendering-in-DirectX-11 , which is a good site. I can't seem to get it to run! I've resolved most of the errors but, however on debug, I get HLSL errors:
D3D11: ERROR: ID3D11DeviceContext::Draw: The Vertex Shader expects application provided input data (which is to say data other than hardware auto-generated values such as VertexID or InstanceID). Therefore an Input Assembler object is expected, but none is bound. [ EXECUTION ERROR #349: DEVICE_DRAW_INPUTLAYOUT_NOT_SET ]
Creeped? I am! Since this message is spamming like mad, the issue is most likely happening in my DrawText() function or a bad implementation in the initialize function (Below)
The InitializeGeneralResources() function:
void InfiniteText::InitializeGeneralResources(){
float textureWidth=1024.0f;
UINT numLetters=32;
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_VS", "vs_5_0",0,0,0,&FontvsBuffer,0,0);
D3DX11CompileFromFile(L"Font.hlsl", NULL, NULL, "FONT_PS", "ps_5_0",0,0,0,&FontpsBuffer,&ppErrorMsgs,0);
iD3D.Device->CreateVertexShader(FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(), NULL, &Fontvs);
iD3D.Device->CreatePixelShader(FontpsBuffer->GetBufferPointer(),FontpsBuffer->GetBufferSize(), NULL, &Fontps);
ID3D11InputLayout* InLayout;
D3D11_INPUT_ELEMENT_DESC IEDesc[]={
{"POSITION",0,DXGI_FORMAT_R32G32B32_FLOAT,0,0,D3D11_INPUT_PER_VERTEX_DATA,0},
{"TEXCOORD",0,DXGI_FORMAT_R32G32_FLOAT,0,12,D3D11_INPUT_PER_VERTEX_DATA,0},
};
UINT NumElements = ARRAYSIZE(IEDesc);
iD3D.Device->CreateInputLayout(IEDesc,NumElements,FontvsBuffer->GetBufferPointer(),FontvsBuffer->GetBufferSize(),&InLayout);
iD3D.DeviceContext->IASetInputLayout(InLayout);
D3D11_SAMPLER_DESC FontSamplerDesc;
FontSamplerDesc.MaxAnisotropy=1;
FontSamplerDesc.AddressU=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressV=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.AddressW=D3D11_TEXTURE_ADDRESS_WRAP;
FontSamplerDesc.Filter=D3D11_FILTER_MIN_MAG_MIP_LINEAR;
FontSamplerDesc.MipLODBias=0.0f;
D3DX11CreateShaderResourceViewFromFile(iD3D.Device, L"Font.dds", NULL, NULL, &FontSRV, NULL);
iD3D.Device->CreateSamplerState(&FontSamplerDesc, &FontSRVSampler);
D3D11_BUFFER_DESC Vbufferdescription;
ZeroMemory(&Vbufferdescription, sizeof(Vbufferdescription));
Vbufferdescription.BindFlags=D3D11_BIND_VERTEX_BUFFER;
Vbufferdescription.Usage=D3D11_USAGE_DYNAMIC;
Vbufferdescription.CPUAccessFlags=D3D11_CPU_ACCESS_WRITE;
Vbufferdescription.ByteWidth=sizeof(VertexText)*6*numLetters;
Vbufferdescription.MiscFlags=0;
iD3D.Device->CreateBuffer(&Vbufferdescription, NULL, &FontVertexBuffer);
}
I have a rather simple HLSL file:
cbuffer ConstantBuffer:register( b0 )
{
float4x4 WVP;
}
struct VOut
{
float4 position : SV_POSITION;
float2 TexCoord : TEXCOORD0;
};
VOut FONT_VS(float4 position : POSITION, float2 TexCoord : TEXCOORD)
{
VOut output;
output.position = mul(position, WVP);
output.TexCoord = TexCoord;
return output;
}
float2 FONT_PS(float4 position : SV_POSITION, float2 TexCoord : TEXCOORD0) : SV_TARGET
{
return TexCoord;
}
(The DrawString() function)
bool InfiniteText::DrawString(char* Text, float xPos, float yPos){
int letterSize = sizeof(VertexText)*6;
int textSize = strlen(Text);
if(textSize > numLetters)
textSize=numLetters;
float cScreenWidth = 32.0f/iD3D.cWidth;
float cScreenHeight= 32.0f/iD3D.cHeight;
float TexelWidth= 32.0f/textureWidth;
D3D11_MAPPED_SUBRESOURCE MappedSub;
iD3D.DeviceContext->Map(FontVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedSub);
VertexText* Sprite = (VertexText*)MappedSub.pData;
const int indexA = static_cast<int>('A');
const int indexZ = static_cast<int>('Z');
for(int i=0; i<textSize;i++){
float thisStartX=xPos+(cScreenWidth*static_cast<char>(i));
float thisEndX=thisStartX + cScreenWidth;
float thisStartY=yPos;
float thisEndY=thisStartY + cScreenHeight;
Sprite[0].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
Sprite[1].Translation=XMFLOAT3(thisEndX,yPos,1.0f);
Sprite[2].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[3].Translation=XMFLOAT3(thisStartX,yPos,1.0f);
Sprite[4].Translation=XMFLOAT3(thisStartX,thisEndY,1.0f);
Sprite[5].Translation=XMFLOAT3(thisEndX,thisEndY,1.0f);
UINT TexLookup=0;
UINT Letter= static_cast<int>(Text[i]);
if (Letter < indexA || Letter > indexZ){
TexLookup=(indexA - indexZ) +1;
}
else{
TexLookup=(Letter-indexA);
}
float texStart = 0.0f + (TexelWidth*static_cast<float>(TexLookup));
float TexEnd = texStart + TexelWidth;
Sprite[0].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite[1].TextureCoord = XMFLOAT2(TexEnd,1.0f);
Sprite[2].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[3].TextureCoord = XMFLOAT2(texStart,1.0f);
Sprite[4].TextureCoord = XMFLOAT2(texStart,0.0f);
Sprite[5].TextureCoord = XMFLOAT2(TexEnd,0.0f);
Sprite= Sprite + 6;
}
iD3D.DeviceContext->Unmap(FontVertexBuffer,0); //MAP END
UINT stride=sizeof(VertexText);
UINT offset=0;
iD3D.DeviceContext->VSSetShader(iText.Fontvs,0,0);
iD3D.DeviceContext->PSSetShader(iText.Fontps,0,0);
//Projection=XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0, 0.0f, 1000.0f);
Projection=iD3D.mProjection;
iD3D.WorldCB.mWorldVP=XMMatrixTranspose(Projection);
iD3D.DeviceContext->UpdateSubresource(iD3D.MatrixBuffer, 0, NULL, &iD3D.WorldCB, 0, 0);
iD3D.DeviceContext->VSSetConstantBuffers(0,1,&iD3D.MatrixBuffer);
iD3D.DeviceContext->IASetVertexBuffers(0,1, &iText.FontVertexBuffer, &stride, &offset);
iD3D.DeviceContext->PSSetShaderResources(0,1, &iText.FontSRV);
iD3D.DeviceContext->PSSetSamplers(0,1,&iText.FontSRVSampler);
iD3D.DeviceContext->IASetPrimitiveTopology( D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
iD3D.DeviceContext->Draw(6*textSize,0);
return true;
}
If you made it this far, thank you. I think that it might be that my .hlsl file might not be configured properly to receive textures, and I might need to know how textures interface properly with the shader to produce the output. Thanks!
The HLSL was not written correctly to include Texture2D x: register( t0 ) or SamplerState x : register( s0 ), taking in necessary resources for the texture. Another problem has surfaced, but this question has been solved.
we have a GLSL fragment shader :
but the problem is in this code
vec4 TFSelection(StrVolumeColorMap volumeColorMap , vec4 textureCoordinate)
{
vec4 finalColor = vec4(0.0);
if(volumeColorMap.TransferFunctions[0].numberOfBits == 0)
{
return texture(volumeColorMap.TransferFunctions[0].TransferFunctionID,textureCoordinate.x);
}
if(textureCoordinate.x == 0)
return finalColor;
float deNormalize = textureCoordinate.x *65535/*255*/;
for(int i = 0; i < volumeColorMap.TransferFunctions.length(); i++)
{
int NormFactor = volumeColorMap.TransferFunctions[i].startBit + volumeColorMap.TransferFunctions[i].numberOfBits;
float minval = CalculatePower(2, volumeColorMap.TransferFunctions[i].startBit);
if(deNormalize >= minval)
{
float maxval = CalculatePower(2, NormFactor);
if(deNormalize <maxval)
{
//float tempPower = CalculatePower(2 , NormFactor);
float coord = deNormalize /maxval/*tempPower*/;
return texture(volumeColorMap.TransferFunctions[i].TransferFunctionID,coord);
}
}
}
return finalColor;
}
when we compile and link shader this message logs:
Sampler needs to be a uniform (global or parameter to main), need to
inline function or resolve conditional expression
with a simple change like maybe the shader link successfully like changing
float `coord = deNormalize /maxval
to
float coord = deNormalize .`
driver:nvidia 320.49