- Home /
'vert': output parameter 'o' not completely initialized
Please help with this error, I'm not sure what i'm doing wrong here?
This is the area of the shader that is causing the error, I dont have much experience at this level of shader code.
Error: 'vert': output parameter 'o' not completely initialized
Shader "Custom/Animated Refractive Water" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_ReflectColor ("Reflection Color", Color) = (0.5, 0.5, 0.5, 1)
_UVScroll ("UV Scroll Speed", float) = 0.5
_DistAmt ("Distortion", range (0,128)) = 10
_Lerp ("Reflection Blend (0 Cubemap, 1 Refraction)", Range (0,1)) = 0.5
_BriLvl ("Reflection Brightness Level", Range (0.5,3)) = 1.5
_BumpMap1 ("Normalmap 1", 2D) = "bump" {}
_BumpMap2 ("Normalmap 2", 2D) = "bump" {}
_Cube ("Reflection Cubemap", Cube) = "" { TexGen CubeReflect }
}
SubShader {
GrabPass { }
Tags { "Queue"="Background+11" "IgnoreProjector"="True" "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma exclude_renderers gles
#pragma vertex vert
#pragma surface surf HalfLambert noambient
#include "UnityCG.cginc"
#pragma target 3.0
float4 _Color, _ReflectColor, _GrabTexture_TexelSize;
sampler2D _BumpMap1, _BumpMap2, _GrabTexture;
samplerCUBE _Cube;
fixed _DistAmt, _UVScroll, _Lerp, _BriLvl;
struct Input {
float2 uv_BumpMap1;
float4 proj : TEXCOORD;
float3 worldRefl;
INTERNAL_DATA
};
//Vertex Vert
void vert (inout appdata_full v, out Input o) {
float4 oPos = mul(UNITY_MATRIX_MVP, v.vertex);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.proj.xy = (float2(oPos.x, oPos.y*scale) + oPos.w) * 0.5;
o.proj.zw = oPos.zw;
}
void surf (Input IN, inout SurfaceOutput o) {
//Animated Normals
fixed2 UVOffset1 = IN.uv_BumpMap1;
fixed2 UVOffset2 = IN.uv_BumpMap1;
fixed xValue = (_UVScroll/2) * _Time;
UVOffset1 += fixed (xValue);
UVOffset2 -= fixed (xValue);
half3 n1 = UnpackNormal(tex2D(_BumpMap1, UVOffset1));
half3 n2 = UnpackNormal(tex2D(_BumpMap2, UVOffset2));
//Normals
half3 NewNormals = (n1/1.5) + (n2/1.5);
o.Normal = NewNormals.rgb;
//Refraction Texture Grab
float2 offset = NewNormals * _DistAmt * _GrabTexture_TexelSize.xy;
IN.proj.xy = offset * IN.proj.z + IN.proj.xy;
half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(IN.proj));
//Cubemap Reflection
float3 worldRefl = WorldReflectionVector (IN, o.Normal);
fixed4 refltex = texCUBE (_Cube, worldRefl);
fixed4 Emiss = (refltex * _ReflectColor) * (col * _BriLvl);
half3 B = lerp(Emiss.rgb, col.rgb, _Lerp);
half3 Diff = B.rgb * _Color.rgb;
//Output
o.Albedo = Diff.rgb;
}
//Lighting Model
half4 LightingHalfLambert (SurfaceOutput s, half3 lightDir, half atten)
{
half NdotL = dot(s.Normal, lightDir);
half diff = NdotL * 0.5 + 0.5;
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * ( diff * atten * 2);
c.a = s.Alpha;
return c;
}
ENDCG
}
FallBack "Transparent/Diffuse"
}
Can you post the complete code if it is not to long, it's easier to debug.
I have added the full shader, I didn't write the vertex part of the shader which is why im not sure how to fix it.
I'm really grateful for any advise you can offer :)
All I really know is that by removing this element from the shader removes the bug..... it also breaks the refraction and therefore brakes the shader :)
Answer by MaT227 · Jul 22, 2014 at 02:24 PM
Try adding UNITY_INITIALIZE_OUTPUT(Input,o);
like this in your vert function.
void vert (inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input,o);
o.customColor = abs(v.normal);
}
Did you defined all the properties you are using ?
This worked! many thanks, only im not sure why or how :)
fixed code:
//Vertex Vert
void vert (inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input,o)
float4 oPos = mul(UNITY_$$anonymous$$ATRIX_$$anonymous$$VP, v.vertex);
#if UNITY_UV_STARTS_AT_TOP
float scale = -1.0;
#else
float scale = 1.0;
#endif
o.proj.xy = (float2(oPos.x, oPos.y*scale) +
oPos.w) * 0.5; o.proj.zw = oPos.zw; }
Here is the answer to what it does :) Predefined shader preprocessor macros
UNITY_INITIALIZE_OUTPUT(type,name)
- initialize variable name of given type to zero.
@$$anonymous$$aT227 I had this same issue - thank you for the excellent answer!
Awesome. That solved my problem and saved me a lot of time. Thanks a lot!
Very good, thanks. But why do some people have to include this while others don't?
I believe the reason this doesn't always show up is that in many cases all of shader output parameters DO get values assigned to them somewhere in the vert() function.
In other words, if your vert() function has v2f o with a vertex and a texcoord property, and your vert function looks like this:
void vert (inout appdata_full v, out Input o) { v2f o; o.vertex = v.vertex; }
...then o.texcoord never has a value assigned to it. I think it's possible to solve this either by adding
o.[variableName] = v.[variableName]
for every property in your v2f; OR you can just call
UNITY_INITIALIZE_OUTPUT(Input,o);
and then all properties will have initial values of 0 and you only need to explicitly assign the ones you want.
Answer by monotoan · Oct 11, 2017 at 07:17 PM
I assume there's a reason why the Unity initialization function is preferred... but as an alternative, here's another way to initialize your v2f output struct in your vert() function:
v2f vert (appdata v) {
//initialize 'o'...
v2f o = (v2f)0;
//rest of code...
}
I find that using either of these tends to resolve the 'not fully initialized' error. I see this option used more commonly in vertex/fragment shaders (instead of the specialized Unity surface shaders).