问题描述
更新
因此,通过从QShaderProgramBuilder
打印已编译的着色器代码,我发现该着色器几乎可以工作,唯一的问题是对renderClicks
的调用。这行
fragColor = (((renderClicks(clicks[10],colors[10],(((((((phongFunction(ka,kd,ks,shininess,worldPosition,normalize(((eyePosition - worldPosition))),normalize(worldnormal)))))))))))));
应该看起来像这样
fragColor = (((renderClicks(clicks,colors,normalize(worldnormal)))))))))))));
但是由于制服的名称是clicks[10]
和colors[10]
,所以我不确定是否可以解决。
问题
我在项目中使用QSceneLoader
自动加载对象。现在,我想可视化对象3D表面上的点击。为此,我将遍历由场景加载器创建的实体层次结构,直到到达QShaderProgramBuilder
。接下来,我将使用setFragmentShadergraph
替换着色器程序构建器中的片段着色器图-很遗憾,您不能提供包含正常着色器代码的文本文件。
我以default phong graph from GitHub为起点,并添加了自己的制服-点击次数和点击次数的颜色,均为vec3
数组。不幸的是,直到我从两者中删除了数组定义之后,着色器才起作用。
当我在任意位置删除数组定义(即,用vec3 clicks
代替vec3 clicks[10]
并通过QVector3D
而不是QVector<QVector3D>
时,我得到了渲染的普通场景
我也找不到Qt3D节点编辑器mentioned here,但我怀疑它能否解决我的问题,因为在YouTube上的视频中似乎没有任何声明数组的选项。 / p>
那么,关于如何在着色器图中正确使用统一数组的任何想法吗?
注意:我已经检查了OpenGL版本4.6,所以这应该不是问题。
注意2:如果有人需要一个示例项目,请告诉我。我开始创建一个,但是即使尝试将其缩小也变得很大。尚未完成,但我可以完成并将其上传到GitHub。
代码
这是我从C ++提供数据作为参数的方式:
Qt3DRender::QParameter *clicksParameter = new Qt3DRender::QParameter(QStringLiteral("clicks"),m_clicks.constData());
我更改了着色器图,以包括以下新的prototype
:
"prototypes": {
"renderClicks": {
"inputs": ["clicks[10]","colors[10]","currentColor"],"outputs": ["result"],"parameters": {
"type": {
"type": "QShaderLanguage::VariableType","value": "QShaderLanguage::Vec4"
}
},"rules": [{
"format": {
"api": "OpenGLCoreProfile","major": 3,"minor": 0
},"headerSnippets": [
"#pragma include :shaders/poseeditor/clicksRendering.inc.frag"
],"substitution": "vec4 $result = renderClicks($clicks,$colors,$currentColor);"
}]
}
},"nodes": ...
引用了clicksRendering.inc.frag
中的以下着色器代码:
vec4 renderClicks(vec3 clicks[10],vec3 colors[10],vec4 currentColor) {
return currentColor;
}
然后我添加了以下新的nodes
:
...
{
"uuid": "{00000000-0000-0000-0000-000000000026}","type": "input","parameters": {
"name": "clicks[10]","qualifier": {
"type": "QShaderLanguage::StorageQualifier","value": "QShaderLanguage::Uniform"
},"type": {
"type": "QShaderLanguage::VariableType","value": "QShaderLanguage::Vec3"
}
}
},{
"uuid": "{00000000-0000-0000-0000-000000000027}","parameters": {
"name": "colors[10]",{
"uuid": "{00000000-0000-0000-0000-000000000028}","type": "renderClicks"
},...
我还更改了最后的边缘,以使最终的phong颜色通过我的自定义函数传递:
...
{
"sourceUuid": "{00000000-0000-0000-0000-000000000026}","sourcePort": "value","targetUuid": "{00000000-0000-0000-0000-000000000028}","targetPort": "clicks"
},{
"sourceUuid": "{00000000-0000-0000-0000-000000000027}","targetPort": "colors"
},{
"sourceUuid": "{00000000-0000-0000-0000-000000000024}","sourcePort": "outputColor","targetPort": "currentColor"
},{
"sourceUuid": "{00000000-0000-0000-0000-000000000028}","sourcePort": "result","targetUuid": "{00000000-0000-0000-0000-000000000025}","targetPort": "fragColor"
}
...
其他信息
我尝试从新[10]
的{{1}}中删除inputs
部分。这将输出错误和错误的着色器代码:
prototype
因此,除了调用const int MAX_LIGHTS = 8;
const int TYPE_POINT = 0;
const int TYPE_DIRECTIONAL = 1;
const int TYPE_SPOT = 2;
struct Light {
int type;
vec3 position;
vec3 color;
float intensity;
vec3 direction;
float constantAttenuation;
float linearattenuation;
float quadraticAttenuation;
float cutOffAngle;
};
uniform Light lights[MAX_LIGHTS];
uniform int lightCount;
// Pre-convolved environment maps
struct EnvironmentLight {
samplerCube irradiance; // For diffuse contribution
samplerCube specular; // For specular contribution
};
uniform EnvironmentLight envLight;
uniform int envLightCount = 0;
#line 52
void adsModel(const in vec3 worldPos,const in vec3 worldnormal,const in vec3 worldView,const in float shininess,out vec3 diffuseColor,out vec3 specularColor)
{
diffuseColor = vec3(0.0);
specularColor = vec3(0.0);
// We perform all work in world space
vec3 n = normalize(worldnormal);
vec3 s = vec3(0.0);
for (int i = 0; i < lightCount; ++i) {
float att = 1.0;
float sDotN = 0.0;
if (lights[i].type != TYPE_DIRECTIONAL) {
// Point and Spot lights
// Light position is already in world space
vec3 sUnnormalized = lights[i].position - worldPos;
s = normalize(sUnnormalized); // Light direction
// Calculate the attenuation factor
sDotN = dot(s,n);
if (sDotN > 0.0) {
if (lights[i].constantAttenuation != 0.0
|| lights[i].linearattenuation != 0.0
|| lights[i].quadraticAttenuation != 0.0) {
float dist = length(sUnnormalized);
att = 1.0 / (lights[i].constantAttenuation +
lights[i].linearattenuation * dist +
lights[i].quadraticAttenuation * dist * dist);
}
// The light direction is in world space already
if (lights[i].type == TYPE_SPOT) {
// Check if fragment is inside or outside of the spot light cone
if (degrees(acos(dot(-s,lights[i].direction))) > lights[i].cutOffAngle)
sDotN = 0.0;
}
}
} else {
// Directional lights
// The light direction is in world space already
s = normalize(-lights[i].direction);
sDotN = dot(s,n);
}
// Calculate the diffuse factor
float diffuse = max(sDotN,0.0);
// Calculate the specular factor
float specular = 0.0;
if (diffuse > 0.0 && shininess > 0.0) {
float normFactor = (shininess + 2.0) / 2.0;
vec3 r = reflect(-s,n); // Reflection direction in world space
specular = normFactor * pow(max(dot(r,worldView),0.0),shininess);
}
// Accumulate the diffuse and specular contributions
diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
specularColor += att * lights[i].intensity * specular * lights[i].color;
}
}
vec4 phongFunction(const in vec4 ambient,const in vec4 diffuse,const in vec4 specular,const in vec3 worldPosition,const in vec3 worldnormal)
{
// Calculate the lighting model,keeping the specular component separate
vec3 diffuseColor,specularColor;
adsModel(worldPosition,worldnormal,worldView,diffuseColor,specularColor);
// Combine spec with ambient+diffuse for final fragment color
vec3 color = (ambient.rgb + diffuseColor) * diffuse.rgb
+ specularColor * specular.rgb;
return vec4(color,diffuse.a);
}
#line 11
uniform vec3 clicks[10];
uniform vec3 colors[10];
vec4 renderClicks(vec3 clicks[10],vec4 currentColor) {
return currentColor;
}
#line 15
out vec4 fragColor;
void main()
{
fragColor = (((renderClicks(clicks[10],normalize(worldnormal)))))))))))));
}
之外,着色器看起来还不错。但是我不知道是否可以摆脱renderClicks(clicks[10],...)
部分,因为那是它们的名字。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)