I am using DirectX for rendering video, but the issue is video is blur when downscale the video frame.
As I know, I need to write an high-quality down-scale filter in shader.hlsl file:
My current shader code:
struct VS_INPUT
{
float3 inPos : POSITION;
float2 inTexCoord : TEXCOORD;
};
struct VS_OUTPUT
{
float4 outPosition : SV_POSITION;
float2 outTexCoord : TEXCOORD;
};
VS_OUTPUT vs_main(VS_INPUT input)
{
VS_OUTPUT output;
output.outPosition = float4(input.inPos, 1.0f);
output.outTexCoord = input.inTexCoord;
return output;
}
struct PS_INPUT
{
float4 inPosition : SV_POSITION;
float2 inTexCoord : TEXCOORD;
};
Texture2D luminanceChannel : TEXTURE: register(t0);
Texture2D chrominanceChannel : TEXTURE: register(t1);
SamplerState defaultSampler : SAMPLER: register(s0);
static const float3x3 YUVtoRGBCoeffMatrix =
{
1.164383f, 1.164383f, 1.164383f,
0.000000f, -0.391762f, 2.017232f,
1.596027f, -0.812968f, 0.000000f
};
float3 ConvertYUVtoRGB(float3 yuv)
{
yuv -= float3(0.062745f, 0.501960f, 0.501960f);
yuv = mul(yuv, YUVtoRGBCoeffMatrix);
return saturate(yuv);
}
float4 PS(PS_INPUT input) : SV_TARGET
{
float y = luminanceChannel.Sample(defaultSampler, input.inTexCoord);
float2 uv = chrominanceChannel.Sample(defaultSampler, input.inTexCoord);
return float4(ConvertYUVtoRGB(float3(y, uv)), 1.f);
}
Can you give me a guide for it? Thanks.
Related
I'm working on a graphics program in DirectX11 which takes a heightmap, manipulates a plane based on the heightmap, calculates the normals, and lights the scene with a directional light. I'm trying to get shadow mapping to work with the directional light, but whenever I do the depth test in the pixel shader it always returns 1, instead of the expected value.
Here's my main pixel shader
Texture2D t0 : register(t0);
Texture2D t1 : register(t1);
SamplerState s0 : register(s0);
SamplerState s1 : register(s1);
cbuffer LightBuffer : register(b0)
{
float4 diffuseColour;
float3 lightDirection;
float padding;
}
struct InputType
{
float4 position : SV_POSITION;
float4 tex: TEXCOORD0;
float3 normal : normal;
float4 lightViewPos : TEXCOORD1;
};
float4 calculateLighting(float3 lightDirection, float3 normal, float4 diffuse)
{
float intensity = saturate(dot(normal, lightDirection));
float4 colour = saturate(diffuse * intensity);
return colour;
}
float4 main(InputType input) : SV_TARGET
{
float depthValue;
float lightDepthValue;
float shadowMapBias = 0.005f;
float4 colour = float4(0.f, 0.f, 0.f, 1);
float4 textureColour = t0.Sample(s0, input.tex.xy);
float2 pTexCoord = input.lightViewPos.xy / input.lightViewPos.w;
pTexCoord *= float2(0.5, -0.5);
pTexCoord += float2(0.5, 0.5);
if (pTexCoord.x < 0.0f || pTexCoord.x > 1.0f ||
pTexCoord.y < 0.0f || pTexCoord.y > 1.0f)
{
return textureColour;
}
depthValue = t1.Sample(s1, pTexCoord).r;
lightDepthValue = input.lightViewPos.z / input.lightViewPos.w;
lightDepthValue -= shadowMapBias;
if (lightDepthValue < depthValue)
{
//colour = float4(1, 1, 1, 1);
colour = calculateLighting(-lightDirection, input.normal, diffuseColour);
}
// This is a test to see what the depth value outputs as
if (depthValue == 0)
return float4(1, 0, 1, 1);
else if (depthValue == 1)
return float4(1, 1, 1, 1); // Always returns this
else
return float4(0, 1, 0, 1);
//return float4(depthValue, depthValue, depthValue, 1.0f);
// return saturate(colour * textureColour);
}
My depth vertex shader:
Texture2D t0 : register(t0);
SamplerState s0 : register(s0);
cbuffer MatrixBuffer : register(b0)
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
}
struct InputType
{
float4 position : position;
float2 tex : TEXCOORD0;
};
struct OutputType
{
float4 position : SV_POSITION;
float4 depthPosition : TEXCOORD0;
};
OutputType main(InputType input)
{
OutputType output;
output.position = mul(input.position, worldMatrix);
if (t0.SampleLevel(s0, input.tex, 0).r > 0.05f)
output.position.y += (t0.SampleLevel(s0, input.tex, 0).r * 50.0f);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.depthPosition = output.position;
return output;
}
And my depth pixel shader:
struct InputType
{
float4 position : SV_POSITION;
float4 depthPosition : TEXCOORD0;
};
float4 main(InputType input) : SV_Target
{
float depthValue;
depthValue = input.depthPosition.z / input.depthPosition.w;
return float4(depthValue, depthValue, depthValue, 1.0f);
}
I know the depth data is being written to the render texture correctly as I have a preview of it on the screen current view + normals shown to demonstrate topography instead of a flat white plane.
I'm new to directx and I need to set up opacity in my shaders. I don't use textures or anything and I just need to add opacity to whole objects based on one variable in shader.
I've tried to simply put this variable in shader's output color alpha channel, but it didn't work and I guess that the solution of this problem is not in shaders. This is my shader so far.
cbuffer ConstantBuffer : register(b0)
{
matrix World;
matrix View;
matrix Projection;
float4 vLigthDir[2];
float4 vLigthColor[2];
float4 vOutputColor;
float intensity;
float3 colors;
}
struct VS_INPUT
{
float4 pos : POSITION;
float3 norm : NORMAL;
};
struct PS_INPUT
{
float4 pos : SV_POSITION;
float3 norm : TEXCOORD0;
};
PS_INPUT VS(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT) 0;
output.pos = mul(input.pos, World);
output.pos = mul(output.pos, View);
output.pos = mul(output.pos, Projection);
output.norm = mul(input.norm, World);
return output;
}
float4 PS(PS_INPUT input) : SV_Target
{
float4 finalColor = 0;
finalColor.r = colors.r;
finalColor.g = colors.g;
finalColor.b = colors.b;
finalColor.a = intensity;
return finalColor;
}
float4 PSSolid(PS_INPUT input) : SV_Target
{
return vOutputColor;
}
//Create BlendState
D3D11_BLEND_DESC blendDesc;
blendDesc.AlphaToCoverageEnable = false;
blendDesc.IndependentBlendEnable = false;
blendDesc.RenderTarget[0].BlendEnable = true;
blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
hr = g_pd3dDevice->CreateBlendState(&blendDesc, &pBlendState);
//Using BlendState
float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
UINT sampleMask = 0xffffffff;
g_pImmediateContext->OMGetBlendState(&pBlendState, blendFactor, &sampleMask);
///////////Rendering geometry part///////////
g_pImmediateContext->OMGetBlendState(NULL, NULL, NULL);
I expect some objects to have opacity, but instead nothing happenening at all, there are just solid color.
So I have added MRT to my program.
The Problem: My two textures (normalMap and positionMap) are empty (only filled with the clearcolor)..
I use them like this:
Inside of my header:
ID3D10RenderTargetView** m_ppBuffer;
ID3D10Texture** m_ppTextures;
ID3D10ShaderResourceView** m_ppshaderView;
Each Frame:
this->m_pDevice->OMSetRenderTargets(this->m_TextureCount, this->m_ppBuffer, this->m_pDepthBuffer);
for (int32 i = 0; i < this->m_TextureCount; i++)
this->m_pDevice->ClearRenderTargetView(this->m_pBuffer[i], a_Color.colors);
....
....
this->m_pEffect->GetVariableByName("DiffuseMap")->AsShaderResource()->SetResource(m_ppshaderView[0]);
this->m_pEffect->GetVariableByName("NormalMap")->AsShaderResource()->SetResource(m_ppshaderView[1]);
this->m_pEffect->GetVariableByName("PositionMap")->AsShaderResource()->SetResource(m_ppshaderView[2]);
this->m_pDevice->IASetInputLayout(this->m_pInputLayout);
this->m_pTechnique->GetPassByIndex(0)->Apply(0);
this->m_pDevice->IASetPrimitiveTopology(primitiveTopology);
this->m_pDevice->Draw(a_Vertices, 0);
My Shader which I use to draw onto the rendertargets:
float4x4 Scale;
float4x4 Rotation;
float4x4 Translation;
float4x4 View;
float4x4 Projection;
Texture2D Diffuse;
SamplerState TextureSampler
{
Filter = MIN_MAG_MIP_Linear;
AddressU = WRAP;
AddressV = WRAP;
};
struct VertexShaderInput
{
float3 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL0;
};
struct VertexShaderOutput
{
float4 PositionOut : SV_POSITION;
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL0;
};
struct PixelShaderOutput
{
float4 colorMap: SV_TARGET0;
float4 normalMap: SV_TARGET1;
float4 positionMap: SV_TARGET2;
};
VertexShaderOutput VS_MAIN(VertexShaderInput input)
{
VertexShaderOutput Output = (VertexShaderOutput)0;
float4 pos = float4(input.Position.xyz, 1);
float4x4 Model = mul(mul(Scale,Rotation),Translation);
float4x4 MVP = mul(mul(Model,View),Projection);
Output.Position = mul(pos,MVP);
Output.PositionOut = mul(pos,MVP);
Output.UV = input.UV;
Output.Color = input.Color;
Output.Normal = input.Normal;
return Output;
}
PixelShaderOutput PS_MAIN(VertexShaderOutput input)
{
PixelShaderOutput output;
float4 blend = Diffuse.Sample(TextureSampler, input.UV);
output.colorMap = blend;
output.normalMap = float4(input.Normal,1);
output.positionMap = float4(input.Position.xyz,1);
return output;
}
RasterizerState Culling
{
CullMode = 1;
};
technique10 Main
{
pass p0
{
SetRasterizerState(Culling);
SetVertexShader(CompileShader(vs_4_0, VS_MAIN()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS_MAIN()));
}
};
After that, I render my Rendertargets using one Quad and this shader.
TextureID is a value I defined in code so I can switch between the rendertarget textures during runtime using my arrows.
float4x4 Scale;
float4x4 Rotation;
float4x4 Translation;
float4x4 View;
float4x4 Projection;
float textureID;
Texture2D DiffuseMap;
Texture2D NormalMap;
Texture2D PositionMap;
SamplerState TextureSampler
{
Filter = MIN_MAG_MIP_Linear;
AddressU = WRAP;
AddressV = WRAP;
};
struct VertexShaderInput
{
float3 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL;
};
struct VertexShaderOutput
{
float4 Position : SV_POSITION;
float2 UV : TEXCOORD0;
float3 Color : COLOR0;
float3 Normal : NORMAL;
};
struct PixelShaderOutput
{
float4 color: SV_TARGET0;
};
VertexShaderOutput VS_MAIN(VertexShaderInput input)
{
VertexShaderOutput Output = (VertexShaderOutput)0;
float4 pos = float4(input.Position.xyz, 1);
float4x4 Model = mul(mul(Scale,Rotation),Translation);
float4x4 MVP = mul(mul(Model,View),Projection);
Output.Position = mul(pos,MVP);
Output.UV = input.UV;
Output.Color = input.Color;
Output.Normal = input.Normal;
return Output;
}
PixelShaderOutput PS_MAIN(VertexShaderOutput input)
{
PixelShaderOutput output;
float4 blend = DiffuseMap.Sample(TextureSampler, input.UV);
float4 norm = NormalMap.Sample(TextureSampler, input.UV);
float4 pos = PositionMap.Sample(TextureSampler, input.UV);
blend.a = 1;
if(textureID == 0.0)
output.color = blend;
else if(textureID == 1.0)
output.color = norm;
else
output.color = pos;
return output;
}
RasterizerState Culling
{
CullMode = 1;
};
technique10 Main
{
pass p0
{
SetRasterizerState(Culling);
SetVertexShader(CompileShader(vs_4_0, VS_MAIN()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS_MAIN()));
}
};
I used the graphic debugger and that gave me the reason why it did not work!
I forgot to set the BlendState for my other Rendertarget's. Setting BlendEnable to true fixed it finally.
I am in the process of implementing lighting in my DirectX 11 project. The problem I have is that when I try to access a cbuffer value from the Pixel Shader function it's just returning float3(0, 0, 0) meanwhile when I access the same value in the Vertex Shader function it returns the correct value. Here is the shader:
/*********************************************\
VERTEX SHADER
\*********************************************/
//Constant buffers
cbuffer Object : register(cb0) {
float4x4 WorldMatrix;
};
cbuffer Camera : register(cb1) {
float4x4 ViewMatrix;
float4x4 ProjectionMatrix;
};
cbuffer LightBuffer : register(cb2) {
float3 AmbientColor;
}
//IO Structs
struct VS_INPUT {
float3 Position : POSITION;
float2 UV : TEXCOORD;
float3 Normal : NORMAL;
};
struct VS_OUTPUT {
float4 Position : SV_POSITION;
float2 UV : TEXCOORD;
float3 Normal : NORMAL;
};
VS_OUTPUT VS(VS_INPUT input){
VS_OUTPUT output;
float4 Position;
//Multiply position with AmbientColor (should be 1, 1, 1), position unchanged
Position = mul(ViewMatrix, float4(input.Position * AmbientColor, 1));
Position = mul(ProjectionMatrix, Position);
Position = mul(WorldMatrix, Position);
output.Position = Position;
output.UV = input.UV;
output.Normal = mul(WorldMatrix, input.Normal);
return output;
}
/*********************************************\
PIXEL SHADER
\*********************************************/
SamplerState TextureState;
Texture2D<float4> Texture;
float4 PS(VS_OUTPUT input) : SV_TARGET {
float4 MaterialColor = Texture.Sample(TextureState, input.UV);
//Multiply color with AmbientColor (should be 1, 1, 1), returns black
float3 FinalColor = MaterialColor.xyz * AmbientColor;
return float4(FinalColor, MaterialColor.a);
}
Here's is the value I'm sending (c++):
_LightsUniform.AmbientColor = XMFLOAT3(1, 1, 1);
DeviceContext->UpdateSubresource(_LightBuffer, 0, NULL, &_LightsUniform, 0, 0);
DeviceContext->VSSetConstantBuffers(2, 1, &_LightBuffer);
DeviceContext->PSSetConstantBuffers(2, 1, &_LightBuffer);
Here is the result:
http://i.gyazo.com/357f1ed3ea33e6569ad2346b368cd975.png
And result without multiplying color: http://gyazo.com/b60b385daa94d3373e9552a523928e3f
I can't see what is wrong. Anybody else had the same issue?
I found the problem. Turns out that the registers for my cbuffer(s) were wrong, I used cb# where b# should be used. (I misunderstood what was written here: https://msdn.microsoft.com/en-us/library/windows/desktop/hh447212(v=vs.85).aspx)
Wrong code:
cbuffer LightBuffer : register(cb2) {
Changed to:
cbuffer LightBuffer : register(b2) {
I have the following vertex and pixel shaders:
struct VS_INPUT
{
float4 Position : POSITION0;
float2 TexCoord : TEXCOORD0;
float4 Color : TEXCOORD1;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
float4x4 projview_matrix;
VS_OUTPUT vs_main(VS_INPUT Input)
{
VS_OUTPUT Output;
Output.Position = mul(Input.Position, projview_matrix);
Output.Color = Input.Color;
Output.TexCoord = Input.TexCoord;
return Output;
}
px
texture tex;
sampler2D s = sampler_state {
texture = <tex>;
};
float4 ps_main(VS_OUTPUT Input) : COLOR0
{
float4 pixel = tex2D(s, Input.TexCoord.xy);
return pixel;
}
This is for a 2d game. The vertices of the quads contain tinting colors that I want to use to tint the bitmap. How can I obtain the color of the current vertex so I can multiply it in the pixel shader by the current pixel color?
Thanks
In your pixel shader, do:
float4 pixel = tex2D(s, Input.TexCoord.xy) * Input.Color;
The Input.Color value will be linearly interpreted across your plane for you, just like Input.TexCoord is. To blend two color vectors together, you simply multiply them together. It may also be advisable to do:
float4 pixel = tex2D(s, Input.TexCoord.xy) * Input.Color;
pixel = saturate(pixel);
The saturate() function will clip each RGB value in your color in the range of 0.0 to 1.0, which may avoid any possible display artifacts.