从 DX9 到 DX11 的顶点着色器编译错误(Unity 5.6 到 2017.4)
Vertex shader compilation error from DX9 to DX11 (Unity 5.6 to 2017.4)
我有一个使用自定义着色器的 Unity 图像 post 效果,在从 Unity 5.6 迁移到 Unity 2017.4 时抛出错误
Assertion failed: Failed to create DX11 vertex declaration; something
wrong with vertex shader input data? (hr=80070057)
这似乎是这个脚本中的错误。
Shader "SG/Stretch Shadows" {
Properties {
_MainTex ("Light texture", 2D) = "white" {}
}
SubShader {
LOD 100
Blend One Zero
Cull Off
ZWrite Off
Lighting Off
Pass { // 0 Blacken source
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
fixed4 shadow = tex2D(_MainTex, i.uv);
half intensity = max(shadow.r, max(shadow.g, shadow.b));
intensity = step(intensity,0.1);
return 1-intensity;
}
ENDCG
}
Pass { // 1 Stretch
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half2 basePos = i.basePos;
half2 zoomPos = i.zoomPos;
half4 tex = tex2D(_MainTex, i.basePos);
half sub = 1.0/60;
half len = length((basePos - zoomPos));
half4 col = tex*tex.a;
col = half4(0,0,0,0);
half pos = 1;
half power = 0.5;
for(int i = 0; i < 60; i++){
pos -= sub;
half4 obstacle = tex2D(_MainTex, lerp(zoomPos, basePos, pos));
obstacle *= pow(pos, power);
col = max(col, obstacle);
}
return 1-col;//half4(half3((basePos - zoomPos).x*20), 1);//tex2D(_ObstacleTex, basePos);
}
ENDCG
}
Pass { // 2 Blacken alpha
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
fixed4 shadow = tex2D(_MainTex, i.uv);
half4 intensity = half4(0,0.2,0.2,shadow.a);
intensity = lerp(shadow, intensity, shadow.a);
return intensity;
}
ENDCG
}
Pass { // 3 Draw fully zoomed shadow and half zoomed shadow
// Each pass duplicates previous pass, doubling drawn shadows
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
half _Offset; // frational lerp value. Decrease by powers of two each pass
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half2 basePos = i.basePos;
half2 zoomPos = i.zoomPos;
half firstPass = tex2D(_MainTex, basePos).a;
half secondPass = tex2D(_MainTex, zoomPos).a-0.85;
half4 output = half4(0,0,0,max(firstPass, secondPass));
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.65)).a-0.3;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.4)).a-0.45;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.25)).a-0.6;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.1)).a-0.7;
output.a = max(output.a, secondPass);
return output;//half4(half3((basePos - zoomPos).x*20), 1);//tex2D(_ObstacleTex, basePos);
}
ENDCG
}
Pass { // 4 Single pass. Ping-pong
// Each pass duplicates previous pass, doubling drawn shadows
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
half _Offset; // frational lerp value. Decrease by powers of two each pass
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half firstPass = tex2D(_MainTex, i.basePos).a;
half secondPass = tex2D(_MainTex, lerp(i.zoomPos, i.basePos, _Offset)).a;
half4 output = half4(0,0,0,max(firstPass, secondPass));
return output;
}
ENDCG
}
}
构建工具不提供任何有关错误脚本或行号的详细信息。关于 Unity post 效果的文档没有涵盖任何细节。 Google 没有发现其他人遇到同样的问题。我发现的唯一一件事是有人建议 SV_POSITION 应该替换为 POSITION,我尝试了各种组合都没有成功。
我也在Unity中新建了一个image effect shader来对比,代码看起来是一样的。
为 post 效果创建合适的顶点着色器的正确形式是什么?或者这甚至是我的代码的问题?
你很接近! SV_POSITION
语义用于传递给片段着色器的顶点位置。
从 vertdata
结构中的 SV_POSITION
中删除所有 SV_
前缀。例如:
struct vertdata
{
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : POSITION; // <- Remove here
};
struct frag_v2f
{
float4 vertex : SV_POSITION; // <- Keep here
half2 uv : TEXCOORD0;
};
我有一个使用自定义着色器的 Unity 图像 post 效果,在从 Unity 5.6 迁移到 Unity 2017.4 时抛出错误
Assertion failed: Failed to create DX11 vertex declaration; something wrong with vertex shader input data? (hr=80070057)
这似乎是这个脚本中的错误。
Shader "SG/Stretch Shadows" {
Properties {
_MainTex ("Light texture", 2D) = "white" {}
}
SubShader {
LOD 100
Blend One Zero
Cull Off
ZWrite Off
Lighting Off
Pass { // 0 Blacken source
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
fixed4 shadow = tex2D(_MainTex, i.uv);
half intensity = max(shadow.r, max(shadow.g, shadow.b));
intensity = step(intensity,0.1);
return 1-intensity;
}
ENDCG
}
Pass { // 1 Stretch
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half2 basePos = i.basePos;
half2 zoomPos = i.zoomPos;
half4 tex = tex2D(_MainTex, i.basePos);
half sub = 1.0/60;
half len = length((basePos - zoomPos));
half4 col = tex*tex.a;
col = half4(0,0,0,0);
half pos = 1;
half power = 0.5;
for(int i = 0; i < 60; i++){
pos -= sub;
half4 obstacle = tex2D(_MainTex, lerp(zoomPos, basePos, pos));
obstacle *= pow(pos, power);
col = max(col, obstacle);
}
return 1-col;//half4(half3((basePos - zoomPos).x*20), 1);//tex2D(_ObstacleTex, basePos);
}
ENDCG
}
Pass { // 2 Blacken alpha
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
};
uniform sampler2D _MainTex;
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
fixed4 shadow = tex2D(_MainTex, i.uv);
half4 intensity = half4(0,0.2,0.2,shadow.a);
intensity = lerp(shadow, intensity, shadow.a);
return intensity;
}
ENDCG
}
Pass { // 3 Draw fully zoomed shadow and half zoomed shadow
// Each pass duplicates previous pass, doubling drawn shadows
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
half _Offset; // frational lerp value. Decrease by powers of two each pass
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half2 basePos = i.basePos;
half2 zoomPos = i.zoomPos;
half firstPass = tex2D(_MainTex, basePos).a;
half secondPass = tex2D(_MainTex, zoomPos).a-0.85;
half4 output = half4(0,0,0,max(firstPass, secondPass));
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.65)).a-0.3;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.4)).a-0.45;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.25)).a-0.6;
output.a = max(output.a, secondPass);
secondPass = tex2D(_MainTex, lerp(zoomPos, basePos, 0.1)).a-0.7;
output.a = max(output.a, secondPass);
return output;//half4(half3((basePos - zoomPos).x*20), 1);//tex2D(_ObstacleTex, basePos);
}
ENDCG
}
Pass { // 4 Single pass. Ping-pong
// Each pass duplicates previous pass, doubling drawn shadows
CGPROGRAM
#pragma target 3.0
#include "UnityCG.cginc"
#pragma vertex processVerts
#pragma fragment drawFrag
#pragma glsl_no_auto_normalization
struct vertdata {
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : SV_POSITION;
};
struct frag_v2f {
float4 vertex : SV_POSITION;
half2 basePos : TEXCOORD0;
half2 zoomPos : TEXCOORD1;
};
uniform sampler2D _ObstacleTex;
uniform sampler2D _MainTex;
half4 _SunPos;
half _Offset; // frational lerp value. Decrease by powers of two each pass
#ifdef UNITY_HALF_TEXEL_OFFSET
#endif
frag_v2f processVerts (vertdata v){
frag_v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.basePos = v.uv;
o.zoomPos = v.uv * _SunPos.zw + (_SunPos.xy -_SunPos.zw*0.5);
return o;
}
half4 drawFrag (frag_v2f i) : SV_Target {
half firstPass = tex2D(_MainTex, i.basePos).a;
half secondPass = tex2D(_MainTex, lerp(i.zoomPos, i.basePos, _Offset)).a;
half4 output = half4(0,0,0,max(firstPass, secondPass));
return output;
}
ENDCG
}
}
构建工具不提供任何有关错误脚本或行号的详细信息。关于 Unity post 效果的文档没有涵盖任何细节。 Google 没有发现其他人遇到同样的问题。我发现的唯一一件事是有人建议 SV_POSITION 应该替换为 POSITION,我尝试了各种组合都没有成功。
我也在Unity中新建了一个image effect shader来对比,代码看起来是一样的。
为 post 效果创建合适的顶点着色器的正确形式是什么?或者这甚至是我的代码的问题?
你很接近! SV_POSITION
语义用于传递给片段着色器的顶点位置。
从 vertdata
结构中的 SV_POSITION
中删除所有 SV_
前缀。例如:
struct vertdata
{
float2 uv : TEXCOORD0;
float2 uvScaled : TEXCOORD1;
float4 vertex : POSITION; // <- Remove here
};
struct frag_v2f
{
float4 vertex : SV_POSITION; // <- Keep here
half2 uv : TEXCOORD0;
};