I'm creating simple google cardboard game in unity and i want to add score count. I know how to do it normally, but in VR it doesn't work for me. I tried to just put Text and display score in it, and it looked good(not exactly because it was displayed only for one eye) but after I tested it on my phone text was in completely different place. Do you know what's the proper way to do it?
Create a World Space canvas and have that canvas attached to the camera. Thats how I get my UI in VR games.
You're going to need a custom shader for your World Space UI objects that has it's Render Order to Overlay and has ZTest turned off.
This is a copy of the Default UI shader with the necessary changes. Should do the trick. Just make a material with this shader, and apply it to everything you want drawn over the top of geometry in your WorldSpace UI.
Shader "UI/Default_OverlayNoZTest"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue"="Overlay"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
#ifdef UNITY_HALF_TEXEL_OFFSET
OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
#endif
OUT.color = IN.color * _Color;
return OUT;
}
sampler2D _MainTex;
fixed4 frag(v2f IN) : SV_Target
{
half4 color = tex2D(_MainTex, IN.texcoord) * IN.color;
clip (color.a - 0.01);
return color;
}
ENDCG
}
}
}
credit goes to http://answers.unity3d.com/questions/878667/world-space-canvas-on-top-of-everything.html
I'd say; setup a RenderTexture and make your/the UI the only thing drawn onto it, then stick the RenderTexture onto something else in your world
Related
I'm trying to get a value property from a shader attached in an object at runtime, but it's never changes in material editor. Maybe I misunderstood anything of how shaders works?
I read about the GetFloat, GetColor, etc but don't figure out yet how it properly works to get an information of a shader in Update(). The real objective here is catch a specific value from shader (in realtime) and do something in C# script, if it's possible.
C# example:
public Color colorInfo;
Awake()
{
rend = GetComponent<Renderer>();// Get renderer
rend.material.shader = Shader.Find("Unlit/shadowCreatures");//shader
}
Update()// I want the info in a realtime
{
//get current float state of the shader
colorInfo = rend.material.GetColor("_Color");
//If I setup a white color in shader properties, the color in material editor is always white
}
Shader:
Shader "Unlit/shadowCreatures"
{
Properties {
_Color ("Color", Color) = (1,1,1,1)
[PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}
_Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Tags
{
"Queue"="Geometry"
"RenderType"="TransparentCutout"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
LOD 200
Cull Off
CGPROGRAM
// Lambert lighting model, and enable shadows on all light types
#pragma surface surf Lambert addshadow fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
fixed _Cutoff;
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Alpha = c.a;
clip(o.Alpha - _Cutoff);
_Color = (0,0,0,0); //trying turn to black just for a test, and nothing happens
}
ENDCG
}
FallBack "Diffuse"
}
Thank you for your time
I think I figured out what you're trying to do and
That's not how things work, sorry
Piecing together your comments and question, this is what I think you're trying to fiddle with:
void surf (Input IN, inout SurfaceOutput o) {
_Color = (0,0,0,0); //trying turn to black just for a test, and nothing happens
}
That doesn't do what you think it does. That line sets this _Color:
#pragma target 3.0
sampler2D _MainTex;
fixed4 _Color;
fixed _Cutoff; //here
Not this one:
Properties {
_Color ("Color", Color) = (1,1,1,1) //here
[PerRendererData]_MainTex ("Sprite Texture", 2D) = "white" {}
_Cutoff("Shadow alpha cutoff", Range(0,1)) = 0.5
}
That second one is what is shown in the inspector panel, and its linkage with the CGPROGRAM block is effectively one-way because frag surf and geom are all called multiple times, in parallel, and rely on receiving the same data in, so the Properties value is read into the CGPROGRAM and the CGPROGRAM's values are discarded when it is done.
I don't think there's any way you can make the shader CGPROGRAM do anything that you can read from C# (because that code runs hundreds of times per frame, how would you know which one to read from?)
I know you can get at the properties (including changing a property for one instance or for all instances), but not the underlying CGPROGRAM data. The only way I can even think of getting around this would be to render to a texture and then read the texture data, and that would be slow (and again, you get into "which pixel has the value you want"?)
We are loading our assets from an asset bundle. everything is contained on the asset bundle.
We have a material with name of light_bulb_tex in our asset bundle. we have wrote a shader , here is the shader code , (this material uses this shader):
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Porject/FX/ColorDimmer" {
Properties {
_Color ("Color",Color)=(1.0, 1.0, 1.0, 1.0)
_OffColor ("OffColor",Color)=(0.772, 0.772, 0.772)
_Intensity("Intensity",Range (0, 1))=0
}
CGINCLUDE
#include "UnityCG.cginc"
sampler2D _MainTex;
uniform fixed4 _Color;
uniform fixed4 _OffColor;
uniform fixed _Intensity;
half4 _MainTex_ST;
struct v2f {
half4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
};
v2f vert(appdata_full v) {
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag( v2f i ) : COLOR {
fixed4 texColor= tex2D (_MainTex, i.uv.xy) ;
//fixed4 colorWithIntensity =
return lerp(_OffColor,_Color,_Intensity);
}
ENDCG
SubShader {
Tags{ "LightMode" = "ForwardBase" }
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
ENDCG
}
}
FallBack Off
}
shader is also included in the asset bundles, also it has been added to the list of "Always Included shaders" of the game. hence we have added the ColorDimmer shader to our project.
So when we have downloaded the asset bundles, by this piece of code , we are going to instantiate the game objects. the material are added to instantiated game objects by asset bundle automatically.
...
/* objectRenderer.material is added to the _instancedGameObject
from asset bundle. here we want to create
copy of this material. so newMaterial is
just copy of objectRenderer.material with
it's specific shader (loading from app), in this case ColorDimmer is the shader which will be added to the newMaterial. */
var objectRenderer = _instancedGameObject.GetComponent<Renderer>();
var objectInAssetBundleMaterial = objectRenderer.material;
if (shaderName == "Proejct/FX/ColorDimmer")
{
Material newMaterial = new Material(Shader.Find("Proejct/FX/ColorDimmer"));
newMaterial.SetColor("_Color", objectInAssetBundleMaterial.GetColor("_Color"));
newMaterial.name = System.Guid.NewGuid().ToString();
objectRenderer.material = newMaterial;
}
...
I don't know why objectInAssetBundleMaterial.GetColor(_Color) returns black. everything in inspector looks good, the material is loaded with the shader correctly. also the corresponding mat file in the asset bundle is defined in YAML like this:
....
m_Colors:
- _Color: {r: 0.8088235, g: 0.18436417, b: 0.18436417, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
- _OffColor: {r: 0.77205884, g: 0.77205884, b: 0.77205884, a: 1}
You can see that _Color is not black.
How can I call GetColor to get the value of _Color?
Yesterday I had implemented Fog of war for my RTS game. All was working fine last night before I went to bed, I checked it scene by scene and ran through loads of tests to make sure it was working and all was good.
But today, when I try and run the game, it loads the main menu, but when it tries to load the first level, unity crashes and doesn't give me a reason.
I tried going through code and game objects until I found that if I removed the custom shader attached to the terrain I was using to create fog over the map, it would stop crashing unity and continue running the game, however I reattached it and it ran fine again with the fog of war working again, but as soon as i closed unity and opened it again, the same problem occurred with crashing loading the first level.
I am unsure if it is the shader or the code for it thats causing the problem.
I have little experience with shaders but if anyone can have a look at the code for it and tell me if anything looks wrong with it I would be very greatful.
Shader "Fog Of War/Terrain" {
Properties {
_FOWTex ("Detail", 2D) = "gray" {}
// Splat Map Control Texture
[HideInInspector] _Control ("Control (RGBA)", 2D) = "red" {}
[HideInInspector] _Splat3 ("Layer 3 (A)", 2D) = "white" {}
[HideInInspector] _Splat2 ("Layer 2 (B)", 2D) = "white" {}
[HideInInspector] _Splat1 ("Layer 1 (G)", 2D) = "white" {}
[HideInInspector] _Splat0 ("Layer 0 (R)", 2D) = "white" {}
// used in fallback on old cards & base map
// [HideInInspector] _MainTex ("BaseMap (RGB)", 2D) = "white" {}
// [HideInInspector] _Color ("Main Color", Color) = (1,1,1,1)
}
SubShader {
Tags { "RenderType"="Opaque"
"SplatCount" = "4"
}
CGPROGRAM
#pragma surface surf Lambert nolightmap
struct Input {
float2 uv_FOWTex;
float2 uv_Control : TEXCOORD0;
float2 uv_Splat0 : TEXCOORD1;
float2 uv_Splat1 : TEXCOORD2;
float2 uv_Splat2 : TEXCOORD3;
float2 uv_Splat3 : TEXCOORD4;
};
sampler2D _Control, _FOWTex;
sampler2D _Splat0,_Splat1,_Splat2,_Splat3;
void surf (Input IN, inout SurfaceOutput o) {
fixed4 splat_control = tex2D (_Control, IN.uv_Control);
fixed3 col;
col = splat_control.r * tex2D (_Splat0, IN.uv_Splat0).rgb;
col += splat_control.g * tex2D (_Splat1, IN.uv_Splat1).rgb;
col += splat_control.b * tex2D (_Splat2, IN.uv_Splat2).rgb;
col += splat_control.a * tex2D (_Splat3, IN.uv_Splat3).rgb;
o.Albedo = col;
fixed3 c = tex2D (_FOWTex, IN.uv_FOWTex).aaa;
c = 1-c;
o.Albedo *= c;
}
ENDCG
}
FallBack off
}
It is very unlikely that a shader is causing the application to crash. If there is an issue with a shader, then Unity will fail to compile the shader and anything which used it will be rendered solid bright pink.
I don't see anything terribly wrong in the shader, however this line:
float2 uv_FOWTex;
in your input struct I think is probably unnecessary.
To debug it, you could strip down your Fog of War shader to as basic and simple as you can get it. Then see if it keeps crashing. It it doesn't, then gradually add back in pieces of the shader until it does.
But when it comes to crashes usually it's from you doing something bad with calls to unmanaged code.
I've been experimenting a fog of war. I have been following this tutorial apparently this is unity 4 and I'm using unity 5, I'm currently getting this error:
Surface shader vertex function 'vert' not found
I read on the comment section on this youtube video, I followed them, but it gives me the error. Tried the original version(The one in the video) but it makes my plane a always underneath even though it's y axis is zero, and the main map's y axis is -10.
btw here is my code for my shader:
Shader "Custom/FogOWarShader" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Transparent" "LightMode"="ForwardBase" }
Blend SrcAlpha OneMinusSrcAlpha
Lighting Off
LOD 200
CGPROGRAM
//#pragma surface surf NoLighting Lambert alpha:blend --the one that makes the map always on top
#pragma surface surf Lambert vertex:vert alpha:blend
fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, float aten){
fixed4 color;
color.rgb = s.Albedo;
color.a = s.Alpha;
return color;
}
fixed4 _Color;
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 baseColor = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = _Color.rgb * baseColor.b;
o.Alpha = _Color.a - baseColor.g;
}
ENDCG
}
FallBack "Diffuse"
}
You have a line in that shader which says:
#pragma surface surf Lambert vertex:vert alpha:blend
So you say you have a vertex shader called vert, but then there is no such function in the rest of your code. That is what it's complaining about.
Having taken a look at the actual shader, all you need to do it set up the blending. You can do that by modifying the pragma that is in the original shader to
#pragma surface surf NoLighting noambient alpha:blend
That should do the trick.
I am working on a game and this is what happens in the game scene.
I verified the shader on each piece dozens of times, but it is ok. In the picture you can see the debug messages with the color, emission and albedo on the materials, and they are ok.
Any ideas what the problem could be? Any suggestion is ok because the release day is coming.
EDIT:
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_Cube ("Cubemap", CUBE) = "" {}
_Emission ("Emission", Range (0.0, 1.0)) = 0.5
_Albedo("Albedo", Range (0.01, 1)) = 0.9
}
SubShader {
Tags {"RenderType" = "Opaque" }
//Blend Off
Cull Off
CGPROGRAM
#pragma surface surf Lambert approxview noforwardadd
fixed4 _Color;
struct Input
{
half3 worldRefl;
};
samplerCUBE _Cube;
float _Emission;
float _Albedo;
void surf (Input IN, inout SurfaceOutput o) {
o.Albedo = _Color.rgb * _Albedo;
o.Emission = texCUBE (_Cube, IN.worldRefl).rgb * _Emission;
}
ENDCG
}
Fallback "Diffuse"
}
Try making "main color" brighter. That could potentially solve it.