我们使用UE4.26 在opengles3_1下 想给材质蓝图里的某些运算提高精度,但是发现我们就算使用custom node 声明float变量,编译后的glsl代码也不会添加highp关键字。初步怀疑是因为custom node的返回值是MateriaFloat ,在android下会换成half,导致在词法分析阶段认为变量类型并不是GLSL_TYPE_FLOAT。请问有什么好的解决方案吗?
Hi,
custom node里的运算如果是申明float,应该是float,但是我怀疑是custom node的输入以及输出还是用Material Float,所以导致结果不符合你们的需求。
UE5的版本里支持只把Material Float都转成float的功能,不影响shader里half的写法,不知道这个功能是否能满足你们的需求?其他改法看起来目前没有特别好的办法。
您好,我改了源码 目前已经可以让custom返回值都是float了。例如生成的hlsl代码
// Uniform material expressions.
float3 CustomExpression0(FMaterialPixelParameters Parameters,float input)
{
float3 test = input * 0.354;
return test;
}
在CalcPixelMaterialInputs函数中的使用
// Now the rest of the inputs
float3 Local0 \= CustomExpression0(Parameters,Material.ScalarExpressions\[0].x);
float3 Local1 \= lerp(Local0,Material.VectorExpressions\[1].rgb,MaterialFloat(Material.ScalarExpressions\[0].y));
PixelMaterialInputs.EmissiveColor \= Local1;
但是对应生成glsl代码依然没有highp关键字
void main()
{
vec4 v0;
vec3 v1;
highp float f2;
f2 = pc1_m[0].x;
vec3 v3;
v3.xyz = vec3((f2*3.540000e-01));
v1.xyz = max(v3,vec3(0.000000e+00,0.000000e+00,0.000000e+00));
Custom Node返回的变量是 “vec3 v3”,但是前面没有 highp 关键字。
请问是词法分析出的问题吗?有什么地方能改吗?或者有办法能让我在custom节点里写glsl代码吗?
材质很简单,如下:
[Image Removed]对应的shader代码:
[HLSL]
...
// Now the rest of the inputs
float3 Local0 = CustomExpression0(Parameters,Material.ScalarExpressions[0].x);
float3 Local1 = lerp(Local0,Material.VectorExpressions[1].rgb,MaterialFloat(Material.ScalarExpressions[0].y));
PixelMaterialInputs.EmissiveColor = Local1;
PixelMaterialInputs.Opacity = 1.00000000;
PixelMaterialInputs.OpacityMask = 1.00000000;
PixelMaterialInputs.BaseColor = MaterialFloat3(0.00000000,0.00000000,0.00000000);
PixelMaterialInputs.Metallic = 0.00000000;
PixelMaterialInputs.Specular = 0.50000000;
PixelMaterialInputs.Roughness = 0.50000000;
PixelMaterialInputs.Anisotropy = 0.00000000;
PixelMaterialInputs.Tangent = MaterialFloat3(1.00000000,0.00000000,0.00000000);
PixelMaterialInputs.Subsurface = 0;
PixelMaterialInputs.AmbientOcclusion = 1.00000000;
PixelMaterialInputs.Refraction = 0;
PixelMaterialInputs.PixelDepthOffset = 0.00000000;
PixelMaterialInputs.ShadingModel = 0;
...
// Uniform material expressions.
float3 CustomExpression0(FMaterialPixelParameters Parameters,float TestInput)
{
float3 result = TestInput * 0.34;
return result;
}
...
[GLSL]
#version 310 es
// end extensions
precision mediump float;
precision highp int;
void compiler_internal_AdjustInputSemantic(inout vec4 TempVariable)
{
//#if HLSLCC_DX11ClipSpace
TempVariable.y = -TempVariable.y;
TempVariable.z = ( TempVariable.z + TempVariable.w ) / 2.0;
//#endif
}
void compiler_internal_AdjustOutputSemantic(inout vec4 Src)
{
//#if HLSLCC_DX11ClipSpace
Src.y = -Src.y;
Src.z = ( 2.0 * Src.z ) - Src.w;
//#endif
}
bool compiler_internal_AdjustIsFrontFacing(bool isFrontFacing)
{
//#if HLSLCC_DX11ClipSpace
return !isFrontFacing;
//#else
// return isFrontFacing;
//#endif
}
uniform highp vec4 pc0_h[4];
uniform vec4 pc1_m[1];
layout(location=3) in vec4 in_TEXCOORD7;
layout(location=0) out vec4 out_Target0;
void main()
{
vec4 v0;
vec3 v1;
highp float f2;
f2 = pc1_m[0].x;
vec3 v3;
v3.xyz = vec3((f2*3.400000e-01));
v1.xyz = max(v3,vec3(0.000000e+00,0.000000e+00,0.000000e+00));
highp float f4;
f4 = ((v1.x+v1.y)+v1.z);
highp vec3 v5;
v5.xyz = v1;
vec3 v6;
v6.xyz = mix(v5,vec3((f4*pc0_h[1].x)),pc0_h[2].xxx);
v0.xyz = ((v6*in_TEXCOORD7.www)+in_TEXCOORD7.xyz);
v0.w = 1.000000e+00;
float h7;
h7 = (gl_FragCoord.z*pc0_h[3].x);
v0.w = h7;
float h8;
h8 = pc0_h[0].x;
v0.xyz = (v0.xyz*vec3(h8));
vec3 v9;
v9.xyz = max(v0.xyz,vec3(1.000000e-05,1.000000e-05,1.000000e-05));
v0.xyz = v9;
v0.xyz = min(vec3(1.000000e+02,1.000000e+02,1.000000e+02),v9);
out_Target0.xyzw = v0;
}
/**
* Parameters calculated from the pixel material inputs.
*/
struct FPixelMaterialInputs
{
float3 EmissiveColor;
MaterialFloat Opacity;
MaterialFloat OpacityMask;
float3 BaseColor;
MaterialFloat Metallic;
MaterialFloat Specular;
MaterialFloat Roughness;
MaterialFloat Anisotropy;
float3 Normal;
float3 Tangent;
MaterialFloat4 Subsurface;
MaterialFloat AmbientOcclusion;
MaterialFloat2 Refraction;
MaterialFloat PixelDepthOffset;
uint ShadingModel;
};
是float 但是 GetMaterialEmissive函数的返回值是half3 。我可以试试看float用来当作uv采样 然后给emissive,是不是会是float。
原来是测试的shader太短,编译器直接转half3了,Custom Node里面代码多点就好了,![]()
[Image Removed]
Hi,
理论上GLSLbacked.cpp里ir_gen_glsl_visitor.GetPrecisionModifier函数根据类型是否是float来添加highp,你能看一下除了customnode,其余地方的写法是否正常吗?另外你方便把hlsl和glsl文件发上来我看一下吗?
你看一下HLSL里PixelMaterialInputs.EmissiveColor是half,还是float?
应该跟GetMaterialEmissive是half3也有关系,可以改成float3测试一下。
感谢反馈,问题解决就好。