我正在学习C++和DirectX,并且我注意到在尝试保持HLSL着色器和C++代码中的结构同步时有很多重复.我想分享结构,因为两种语言都有相同的#include语义和头文件结构.我遇到了成功
// ColorStructs.h
#pragma once
#ifdef __cplusplus
#include <DirectXMath.h>
using namespace DirectX;
using float4 = XMFLOAT4;
namespace ColorShader
{
#endif
struct VertexInput
{
float4 Position;
float4 Color;
};
struct PixelInput
{
float4 Position;
float4 Color;
};
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
但问题是在编译这些着色器时,FXC告诉input parameter 'input' missing sematics我Pixel着色器的主要功能:
#include "ColorStructs.h"
void main(PixelInput input)
{
// Contents elided
}
Run Code Online (Sandbox Code Playgroud)
我知道我需要有类似的语义,float4 Position : POSITION但我无法想出一种不违反C++语法的方法.
有没有办法让HLSL和C++之间的结构保持一致?或者它是不可行的,并且需要复制两个源树之间的结构?
在HLSL中有很多矩阵乘法,虽然我理解如何以及在何处使用它们但我不确定它们是如何派生出来的或它们的实际目标是什么.
所以我想知道是否有在线资源可以解释这一点,我特别好奇是通过投影矩阵将世界矩阵乘以视图矩阵和世界+视图矩阵背后的目的是什么.
只需要找出一种方法,使用Pixel Shader将纹理投影到任意用户定义的四边形.
将接受四边形四边的坐标:
/// <defaultValue>0,0</defaultValue>
float2 TopLeft : register(c0);
/// <defaultValue>1,0</defaultValue>
float2 TopRight : register(c1);
/// <defaultValue>0,1</defaultValue>
float2 BottomLeft : register(c2);
/// <defaultValue>1,1</defaultValue>
float2 BottomRight : register(c3);
Run Code Online (Sandbox Code Playgroud)
尝试了几种插值算法,但无法设法使其正确.
你们认为我有什么样的样本可以修改以获得理想的结果吗?
在着色器模型 3.0 中,我很确定这是否定的,但我还是想问这个,
在着色器模型 5.0 中,您可以在顶点着色器中对纹理进行采样吗?
如果我想为每个顶点提供大量补充信息,我有哪些选择?
编辑:显然可以进行顶点纹理提取,如此处所示,但是当我在 hlsl 着色器模型 5 程序中尝试它时,出现错误
错误 X4532:无法将表达式映射到 vs_5_0 指令集
我正在努力理解DirectX中的常量缓冲区.我见过两种语法
float4 myVar;
Run Code Online (Sandbox Code Playgroud)
在着色器文件的顶级声明
cbuffer myBuffer
{
float4 myVar;
}
Run Code Online (Sandbox Code Playgroud)
详见http://msdn.microsoft.com/en-gb/library/windows/desktop/bb509581(v=vs.85).aspx
我知道需要将常量缓冲区分配给插槽(从零开始索引),并且可以在代码中设置.
我看了(SlimDX VS SharpDX)的两个框架似乎有不同的习惯来设置他们 - 按插槽编号由字符串名称(通过着色器反射?)和SharpDX SlimDX - 虽然它并不清楚其中从获得的插槽号?
任何人都可以了解两种语法之间的差异,如果它们实际上是不同的,如何将槽号分配给.fx文件中的声明以及如何在着色器之间共享槽号?
任何帮助赞赏
我正在研究片段着色器。它可以工作,但仍然需要一些优化。
据我所知,GLSL中的大多数情况分支都是扁平化的,因此两种情况都被执行。我已经消除了大部分 if-else 条件,但其中一些条件必须保持原样,因为这两个分支的执行成本都很高。我知道,在 HLSL 中有一个[branch]针对此问题的关键字。但如何才能解决它呢GLSL?
我的代码如下所示(条件不统一,它们的结果取决于着色器中的计算):
if( condition ) {
expensive calculations...
}
if( condition2 ) {
expensive calculations...
}
if( condition3 ) {
expensive calculations...
}
...
Run Code Online (Sandbox Code Playgroud)
一项“昂贵的计算”可以修改条件所依赖的变量。有可能执行多个计算。
我知道,有些较旧的或移动 GPU 根本不支持分支。在这种情况下,与此问题无关
两者看起来都是HLSL着色器语言,但是它们之间有什么区别呢?
将 .hlsl 扩展名更改为 .hlsli 是否重要,反之亦然?
我发现的一篇文章说 .hlsli 文件不会进入编译,这是正确的吗?(谈论.hlsli的文章太少了,对此没有信心......)
只使用 .hlsli 文件好还是应该始终有一些 .hlsl 文件?
如果有人能说出它们之间的相同/差异以及它们的用法,我们将不胜感激。谢谢。
我目前正在编写一个HLSL用于基本高斯模糊的着色器。着色器代码很简单,但我不断收到错误:
不在 dx9 兼容模式下时,DX9 风格特性将被禁用。(法律公告#:19)
这告诉我,我的代码中的第 19 行是问题所在,我相信它要么是由于该特定行引起的tex2D,要么是Sampler在该特定行中。
#include "Common.hlsl"
Texture2D Texture0 : register(t0);
SamplerState Sampler : register(s0);
float4 PSMain(PixelShaderInput pixel) : SV_Target {
float2 uv = pixel.TextureUV; // This is TEXCOORD0.
float4 result = 0.0f;
float offsets[21] = { ... };
float weights[21] = { ... };
// Blur horizontally.
for (int x = 0; x < 21; x++)
result += tex2D(Sampler, float2(uv.x + offsets[x], uv.y)) * weights[x];
return result;
}
Run Code Online (Sandbox Code Playgroud)
请参阅下面有关代码的注释和我的问题。
假设我想使用计算着色器来运行 Kernel_X,线程尺寸为 (8, 1, 1)。
我可以将其设置为:
在脚本中:
Shader.Dispatch(Kernel_X, 8, 1, 1);
Run Code Online (Sandbox Code Playgroud)
在着色器中:
[numthreads(1,1,1)]
void Kernel_X(uint id : SV_DispatchThreadID) { ... }
Run Code Online (Sandbox Code Playgroud)
或者我可以这样设置:
在脚本中:
Shader.Dispatch(Kernel_X, 1, 1, 1);
Run Code Online (Sandbox Code Playgroud)
在着色器中:
[numthreads(8,1,1)]
void Kernel_X(uint id : SV_DispatchThreadID) { ... }
Run Code Online (Sandbox Code Playgroud)
据我所知,在这段代码的末尾,维度将是 (8, 1, 1); 然而,我想知道交换数字实际上有何不同。我的猜测是,运行 Dispatch (Kernel_X, 8, 1, 1) 会“运行”1x1x1 内核 8 次,而运行 numthreads(8,1,1) 将运行 8x1x1 内核一次。
hlsl ×10
directx ×4
shader ×4
directx-11 ×2
c++ ×1
cg ×1
direct3d11 ×1
glsl ×1
glsles ×1
math ×1
matrix ×1
opengl ×1
opengl-es ×1
pixel-shader ×1
visual-c++ ×1
wpf ×1