I'm trying to create a custom shader in unity. Following is the code for my shader.
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
// Default Vertex Shader
v2f vert(appdata_img v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy);
return o;
}
// Parameters
sampler2D _MainTex;
float _FOV;
// Alpha is the ratio of pixel density: width to height
float _Alpha;
uniform float4x4 _UnityDisplayTransform;
// Fragment Shader: Remap the texture coordinates to combine
// barrel distortion and disparity video display
fixed4 frag(v2f i) : COLOR {
float2 uv1, uv2, uv3;
float t1, t2;
float offset;
// uv1 is the remap of left and right screen to a full screen
uv1 = i.uv - 0.5;
uv1.x = uv1.x * 2 - 0.5 + step(i.uv.x, 0.5);
t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y);
t2 = 1.0 / (t1 * tan(_FOV * 0.5));
// uv2 is the remap of side screen with barrel distortion
uv2 = uv1 * t2 + 0.5;
// black color for out-of-range pixels
if (uv2.x >= 1.5 || uv2.y >= 1.0 || uv2.x <= -0.5 || uv2.y <= 0.0) {
return fixed4(0, 0, 0, 1);
} else {
offset = 0.5 - _Alpha * 0.5;
// uv3 is the remap of image texture
uv3 = uv2;
uv3.x = uv2.x * _Alpha + offset;
return tex2D(_MainTex, uv3);
}
}
ENDCG
}
Im getting the following output with the same. This is the effect that I get when I apply the shader.
However Im desiring to get a two perfect squares instead of the curved edges. How can I be able to sort it out?
This should work:
Shader "Custom/FakeAR"
{
Properties{
_MainTex("", 2D) = "white" {}
_FOV("FOV", Range(1, 2)) = 1.6
_Disparity("Disparity", Range(0, 0.3)) = 0.1
_Alpha("Alpha", Range(0, 2.0)) = 1.0
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
// Default Vertex Shader
v2f vert(appdata_img v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy);
return o;
}
// Parameters
sampler2D _MainTex;
float _FOV;
// Alpha is the ratio of pixel density: width to height
float _Alpha;
// Disparity is the portion to separate
// larger disparity cause closer stereovision
float _Disparity;
// Fragment Shader: Remap the texture coordinates to combine
// barrel distortion and disparity video display
fixed4 frag(v2f i) : COLOR
{
float2 uv1, uv2, uv3;
float t1, t2;
float offset;
// uv1 is the remap of left and right screen to a full screen
uv1 = i.uv - 0.5;
uv1.x = uv1.x * 2 - 0.5 + sign(i.uv.x < 0.5);
//t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y);
t2 = _FOV;// 1.0 / (t1 * tan(_FOV * 0.5));
// uv2 is the remap of side screen with barrel distortion
uv2 = uv1 * t2 + 0.5;
// black color for out-of-range pixels
if (uv2.x >= 1 || uv2.y >= 1 || uv2.x <= 0 || uv2.y <= 0) {
return fixed4(0, 0, 0, 1);
}
else {
offset = 0.5 - _Alpha * 0.5 + _Disparity * 0.5 - _Disparity * sign(i.uv.x < 0.5);
// uv3 is the remap of image texture
uv3 = uv2;
uv3.x = uv2.x * _Alpha + offset;
return tex2D(_MainTex, uv3);
}
//float4 color = tex2D(_MainTex, i.uv);
//return 1 - color;
}
ENDCG
}
}
FallBack "Diffuse"
}
Related
Trying to change the colors of this shader from black and white to a multitude of colors, is there any way one would be able to do this? I'm pretty new to unity and trying my best with what I've got. If possible I'd like to be able to do at least 3 different colors, but I understand if that's not really feasible with what's made here. If so, could someone potentially point me towards something similar that I can try using instead?
http://www.shaderslab.com/demo-01---concentric-circles.html
Here's the code from the shader itself.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/ConcentricCircles" {
Properties {
_OrigineX ("PosX Origine", Range(0,1)) = 0.5
_OrigineY ("PosY Origine", Range(0,1)) = 0.5
_Speed ("Speed", Range(-100,100)) = 60.0
_CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
float _OrigineX;
float _OrigineY;
float _Speed;
float _CircleNbr;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord0 : TEXCOORD0;
};
struct fragmentInput{
float4 position : SV_POSITION;
float4 texcoord0 : TEXCOORD0;
};
fragmentInput vert(vertexInput i){
fragmentInput o;
o.position = UnityObjectToClipPos (i.vertex);
o.texcoord0 = i.texcoord0;
return o;
}
fixed4 frag(fragmentInput i) : SV_Target {
fixed4 color;
float distanceToCenter;
float time = _Time.x * _Speed;
float xdist = _OrigineX - i.texcoord0.x;
float ydist = _OrigineY - i.texcoord0.y;
distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;
color = sin(distanceToCenter + time);
return color;
}
ENDCG
}
}
}
I am not great at shaders, but I can help out a bit. You would want to add a _Color property. The value can be changed in code, or in the inspector. There are different ways to apply the color either by summation or multiplication. Both options produce different results. It will only replace the white portion, or add highlights around the white. The reason for the black portions is due to how the sin function works.
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/Test" {
Properties {
_OrigineX ("PosX Origine", Range(0,1)) = 0.5
_OrigineY ("PosY Origine", Range(0,1)) = 0.5
_Speed ("Speed", Range(-100,100)) = 60.0
_CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
_Color ("Main Color", Color) = (1,1,1,1)
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
float _OrigineX;
float _OrigineY;
float _Speed;
float _CircleNbr;
fixed4 _Color;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord0 : TEXCOORD0;
};
struct fragmentInput{
float4 position : SV_POSITION;
float4 texcoord0 : TEXCOORD0;
};
fragmentInput vert(vertexInput i){
fragmentInput o;
o.position = UnityObjectToClipPos (i.vertex);
o.texcoord0 = i.texcoord0;
return o;
}
fixed4 frag(fragmentInput i) : SV_Target {
fixed4 color;
float distanceToCenter;
float time = _Time.x * _Speed;
float xdist = _OrigineX - i.texcoord0.x;
float ydist = _OrigineY - i.texcoord0.y;
distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;
color = sin(distanceToCenter + time) + _Color;
return color;
}
ENDCG
}
}
}
Replace the line color = sin(distanceToCenter + time) + _Color; with color = sin(distanceToCenter + time) * _Color; to see the other option. The left image is with additive while the right is multiplicative. I set the color in the editor to green. You can also try changing the sin function to another trig function which produces different results as well.
Edit: This line is pretty cool color = sin(distanceToCenter + time) + cos(distanceToCenter + time) * _Color;
Edit 2: As per request, here is one way to get multiple different colors. As the sin function is being used, the values are between [-1, 1], so at times this would equal 0, or (0,0,0,1) which is black. You can make if conditionals to catch ranges of these values then directly set the color. Here is how I approach it.
Shader "Custom/Test" {
Properties {
_OrigineX ("PosX Origine", Range(0,1)) = 0.5
_OrigineY ("PosY Origine", Range(0,1)) = 0.5
_Speed ("Speed", Range(-100,100)) = 60.0
_CircleNbr ("Circle quantity", Range(10,1000)) = 60.0
_Color1 ("Color 1", Color) = (1,1,1,1)
_Color2 ("Color 2", Color) = (1,1,1,1)
_Color3 ("Color 3", Color) = (1,1,1,1)
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma target 3.0
float _OrigineX;
float _OrigineY;
float _Speed;
float _CircleNbr;
fixed4 _Color1;
fixed4 _Color2;
fixed4 _Color3;
struct vertexInput {
float4 vertex : POSITION;
float4 texcoord0 : TEXCOORD0;
};
struct fragmentInput{
float4 position : SV_POSITION;
float4 texcoord0 : TEXCOORD0;
};
fragmentInput vert(vertexInput i){
fragmentInput o;
o.position = UnityObjectToClipPos (i.vertex);
o.texcoord0 = i.texcoord0;
return o;
}
fixed4 frag(fragmentInput i) : SV_Target {
fixed4 color;
float distanceToCenter;
float time = _Time.x * _Speed;
float xdist = _OrigineX - i.texcoord0.x;
float ydist = _OrigineY - i.texcoord0.y;
distanceToCenter = (xdist * xdist + ydist * ydist) * _CircleNbr;
float preColor = sin(distanceToCenter + time);
if(preColor < -0.8)
{
color = _Color1;
}
else if(preColor < 0.2)
{
color = _Color2;
}
else
{
color = _Color3;
}
return color;
}
ENDCG
}
}
}
And my result
Just assign the three colors you would like in the inspector. You can edit the code to change how many thresholds there are, or what the thresholds are.
You can find the shader code below. I did this as an "image effect shader" in Unity. Then I apply it to my camera along with the C# script (below the shader). Looks great on desktop but on Android it just makes the screen black. I'm probably using something that doesn't work on Android, maybe someone could point me in the right direction for fixing it?
//#<!--
//# CRT-simple shader
//#
//# Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
//#
//# Modified by fontmas: 2015-03-06
//#
//# This program is free software; you can redistribute it and/or modify it
//# under the terms of the GNU General Public License as published by the Free
//# Software Foundation; either version 2 of the License, or (at your option)
//# any later version.
//# -->
Shader "Custom/CRT"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
#define CURVATURE
#pragma target 3.0
#define PI 3.141592653589
uniform sampler2D _MainTex;
uniform float2 _InputSize;
uniform float2 _OutputSize;
uniform float2 _TextureSize;
uniform float2 _One;
uniform float2 _Texcoord;
uniform float _Factor;
uniform float _Distortion = 0.1f; // 0.1f
uniform float _Gamma = 1.0f; // 1.0f
uniform float _curvatureSet1 = 0.5f; // 0.5f
uniform float _curvatureSet2 = 0.5f; // 0.5f
uniform float _YExtra = 0.5f; // 0.5f;
uniform float _rgb1R = 1.0f; // 1.0f
uniform float _rgb1G = 1.0f; // 1.0f
uniform float _rgb1B = 1.0f; // 1.0f
uniform float _rgb2R = 1.0f; // 1.0f
uniform float _rgb2G = 1.0f; // 1.0f
uniform float _rgb2B = 1.0f; // 1.0f
uniform float _dotWeight = 2.0f; // 2.0f
float2 RadialDistortion(float2 coord)
{
coord *= _TextureSize / _InputSize;
float2 cc = coord - _curvatureSet1;
float dist = dot(cc, cc) * _Distortion;
return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize;
}
float4 ScanlineWeights(float distance, float4 color)
{
float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
float4 weights = float4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f);
return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width);
}
float4 frag(v2f_img i) : COLOR
{
_Texcoord = i.uv;
_One = 1.0f / _TextureSize;
_OutputSize = _TextureSize;
_InputSize = _TextureSize;
_Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;
//float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _Gamma);
#ifdef CURVATURE
float2 xy = RadialDistortion(_Texcoord);
#else
float2 xy = _Texcoord;
#endif
float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f);
float2 uvratio = frac(ratio);
xy.y = (floor(ratio.y) + _YExtra) / _TextureSize;
float4 col = tex2D(_MainTex, xy);
float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y));
float4 weights = ScanlineWeights(uvratio.y, col);
float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
float3 res = (col * weights + col2 * weights2).rgb;
float3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B);
float3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B);
float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight)));
res *= dotMaskWeights;
return float4(pow(res, float3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), 1.0f);
//return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f);
}
ENDCG
}
}
}
using UnityEngine;
using System.Collections;
public enum CRTScanLinesSizes { S32 = 32, S64 = 64, S128 = 128, S256 = 256, S512 = 512, S1024 = 1024 };
[ExecuteInEditMode]
public class CRT : MonoBehaviour
{
#region Variables
public Shader curShader;
public float Distortion = 0.1f;
public float Gamma = 1.0f;
public float YExtra = 0.5f;
public float CurvatureSet1 = 0.5f;
public float CurvatureSet2 = 1.0f;
public float DotWeight = 1.0f;
public CRTScanLinesSizes scanSize = CRTScanLinesSizes.S512;
public Color rgb1 = Color.white;
public Color rgb2 = Color.white;
private Material curMaterial;
#endregion
#region Properties
Material material
{
get
{
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
// Use this for initialization
void Start()
{
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (curShader != null)
{
material.SetFloat("_Distortion", Distortion);
material.SetFloat("_Gamma", Gamma);
material.SetFloat("_curvatureSet1", CurvatureSet1);
material.SetFloat("_curvatureSet2", CurvatureSet2);
material.SetFloat("_YExtra", YExtra);
material.SetFloat("_rgb1R", rgb1.r);
material.SetFloat("_rgb1G", rgb1.g);
material.SetFloat("_rgb1B", rgb1.b);
material.SetFloat("_rgb2R", rgb2.r);
material.SetFloat("_rgb2G", rgb2.g);
material.SetFloat("_rgb2B", rgb2.b);
material.SetFloat("_dotWeight", DotWeight);
material.SetVector("_TextureSize", new Vector2((float)scanSize, (float)scanSize));
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
// Update is called once per frame
void Update()
{
}
void OnDisable()
{
if (curMaterial)
{
DestroyImmediate(curMaterial);
}
}
}
Might be the RenderTexture, change the depth buffer to 0, if you create the RenderTexture in Unity do it like this:
rt = new RenderTexture(*width*, *height*, 0, RenderTextureFormat.ARGB32);
if you create the RenderTexture in Unity set "Depth Buffer" to "No depth buffer",
if changing the depth doesn't have any impact it could also be Graphics.Blit().
Let me start off by saying I know very little about shader programming. A lot of what I have here is stitched together from online resources and existing assets. I just need to know how to correctly integrate a height map into a unity shader. It doesn't have to be more complex than the standard Unity shader's. I can't use the Standard shader because I need a shader that tiles together multiple textures, which is probably why I haven't found a solution to this problem yet.
I've mixed and moved around the code, deleted some variables, renamed some variables, and looked online for anyone who had a similar problem.
Shader "Unlit/TRUE_EARTH"
{
Properties
{
_TexA1 ("Tex A1", 2D) = "white" {}
_TexA2 ("Tex A2", 2D) = "white" {}
_TexB1 ("Tex B1", 2D) = "white" {}
_TexB2 ("Tex B2", 2D) = "white" {}
_TexC1 ("Tex C1", 2D) = "white" {}
_TexC2 ("Tex C2", 2D) = "white" {}
_TexD1 ("Tex D1", 2D) = "white" {}
_TexD2 ("Tex D2", 2D) = "white" {}
_BumpScale("Scale", Float) = 1.0
[Normal] _BumpMap("Normal Map", 2D) = "bump" {}
_Height("Height Scale", Range(0.005, 0.08)) = 0.02
_HeightMap("Height Map", 2D) = "black" {}
_OcclusionStrength("Strength", Range(0.0, 1.0)) = 1.0
_OcclusionMap("Occlusion", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Lighting Off
ZWrite Off
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _TexA1;
sampler2D _TexA2;
sampler2D _TexB1;
sampler2D _TexB2;
sampler2D _TexC1;
sampler2D _TexC2;
sampler2D _TexD1;
sampler2D _TexD2;
sampler2D _NormalMap;
sampler2D _HeightMap;
half _BumpAmount;
half _Height;
struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
half3 normal: TEXCOORD1;
#if WPM_BUMPMAP_ENABLED
half3 tspace0 : TEXCOORD2; // tangent.x, bitangent.x, normal.x
half3 tspace1 : TEXCOORD3; // tangent.y, bitangent.y, normal.y
half3 tspace2 : TEXCOORD4; // tangent.z, bitangent.z, normal.z
#endif
};
v2f vert (float4 vertex : POSITION, half3 normal : NORMAL, half4 tangent : TANGENT, float2 uv : TEXCOORD5, appdata_full v) {
v2f o;
float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
vertex.z += heightMap.b * _Height;
o.pos = UnityObjectToClipPos (vertex);
o.uv = uv;
half3 wNormal = UnityObjectToWorldNormal(normal);
o.normal = wNormal;
#if WPM_BUMPMAP_ENABLED
half3 wTangent = UnityObjectToWorldDir(tangent.xyz);
half tangentSign = tangent.w * unity_WorldTransformParams.w;
half3 wBitangent = cross(wNormal, wTangent) * tangentSign;
//output the tangent space matrix
o.tspace0 = half3(wTangent.x, wBitangent.x, wNormal.x);
o.tspace1 = half3(wTangent.y, wBitangent.y, wNormal.y);
o.tspace2 = half3(wTangent.z, wBitangent.z, wNormal.z);
#endif
return o;
}
half4 frag (v2f i) : SV_Target
{
// compute Earth pixel color
half4 color;
// compute Earth pixel color
if (i.uv.x<0.25)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexA1, float4(i.uv.x * 4.0, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexA2, float4(i.uv.x * 4.0, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 0.5)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexB1, float4((i.uv.x - 0.25) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexB2, float4((i.uv.x - 0.25) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 0.75)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexC1, float4((i.uv.x - 0.50) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexC2, float4((i.uv.x - 0.50) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
else if (i.uv.x < 1.01)
{
if (i.uv.y>0.4999)
{
color = tex2Dlod(_TexD1, float4((i.uv.x - 0.75) * 4.0f, (i.uv.y - 0.5) * 2.0, 0, 0));
}
else
{
color = tex2Dlod(_TexD2, float4((i.uv.x - 0.75) * 4.0f, i.uv.y * 2.0, 0, 0));
}
}
// sphere normal (without bump-map)
half3 snormal = normalize(i.normal);
// transform normal from tangent to world space
#if WPM_BUMPMAP_ENABLED
half3 tnormal = UnpackNormal(tex2D(_NormalMap, i.uv));
half3 worldNormal;
worldNormal.x = dot(i.tspace0, tnormal);
worldNormal.y = dot(i.tspace1, tnormal);
worldNormal.z = dot(i.tspace2, tnormal);
half3 normal = normalize(lerp(snormal, worldNormal, _BumpAmount));
#else
half3 normal = snormal;
#endif
return color;
}
ENDCG
}
}
}
The texture comes out fine, but there is no semblance of heightmapping. It's all flat.
There were 3 parts that needed to change.
Make sure your properties match up with your variables:
_Height("Height Scale", Range(0.005, 0.08)) = 0.02
_HeightMap("Height Map", 2D) = "black" {}
....
sampler2D _HeightMap;
half _Height;
Make modifications to the vertex before it gets stored in o
Modify the y component of the vertex instead of the z:
float4 heightMap = tex2Dlod(_HeightMap, float4(v.texcoord.xy, 0, 0));
vertex.y += heightMap.b * _Height;
o.pos = UnityObjectToClipPos (vertex);
I use unity 2018.3.5f1. I would like to overlay a custom shader while rendering an image. Following is my onRenderImage Function.
void OnRenderImage(RenderTexture src, RenderTexture dest) {
// shaderMaterial renders the image with Barrel distortion and disparity effect
Graphics.Blit(camTextureHolder.mainTexture, nullRenderTexture, shaderMaterial);
// measure average frames per second
m_FpsAccumulator++;
if (Time.realtimeSinceStartup > m_FpsNextPeriod) {
m_CurrentFps = (int)(m_FpsAccumulator / fpsMeasurePeriod);
m_FpsAccumulator = 0;
m_FpsNextPeriod += fpsMeasurePeriod;
}
}
The issue is that the entire screen appears to be black while I'm trying to do so. May I know how do I fix this issue?
Update:
This is the code for the shader that I'm using
Shader "Custom/FakeAR"
{
Properties{
_MainTex("", 2D) = "white" {}
[HideInInspector]_FOV("FOV", Range(1, 2)) = 1.6
[HideInInspector]_Disparity("Disparity", Range(0, 0.3)) = 0.1
[HideInInspector]_Alpha("Alpha", Range(0, 2.0)) = 1.0
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
// Default Vertex Shader
v2f vert(appdata_img v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord.xy);
return o;
}
// Parameters
sampler2D _MainTex;
float _FOV;
// Alpha is the ratio of pixel density: width to height
float _Alpha;
// Disparity is the portion to separate
// larger disparity cause closer stereovision
float _Disparity;
// Fragment Shader: Remap the texture coordinates to combine
// barrel distortion and disparity video display
fixed4 frag(v2f i) : COLOR {
float2 uv1, uv2, uv3;
float t1, t2;
float offset;
// uv1 is the remap of left and right screen to a full screen
uv1 = i.uv - 0.5;
uv1.x = uv1.x * 2 - 0.5 + sign(i.uv.x < 0.5);
t1 = sqrt(1.0 - uv1.x * uv1.x - uv1.y * uv1.y);
t2 = 1.0 / (t1 * tan(_FOV * 0.5));
// uv2 is the remap of side screen with barrel distortion
uv2 = uv1 * t2 + 0.5;
// black color for out-of-range pixels
if (uv2.x >= 1 || uv2.y >= 1 || uv2.x <= 0 || uv2.y <= 0) {
return fixed4(0, 0, 0, 1);
}
else {
offset = 0.5 - _Alpha * 0.5 + _Disparity * 0.5 - _Disparity * sign(i.uv.x < 0.5);
// uv3 is the remap of image texture
uv3 = uv2;
uv3.x = uv2.x * _Alpha + offset;
return tex2D(_MainTex, uv3);
}
}
ENDCG
}
}
FallBack "Diffuse"
}
Is it because of the shader?
Well I think it's working it's just that the shader has nothing to render meaning it goes for black. You might want the shader to use the excisting camera texture. So maybe this?
void OnRenderImage(RenderTexture src, RenderTexture dest) {
// shaderMaterial renders the image with Barrel distortion and disparity effect
Graphics.Blit(src, dst, shaderMaterial);
// measure average frames per second
m_FpsAccumulator++;
if (Time.realtimeSinceStartup > m_FpsNextPeriod) {
m_CurrentFps = (int)(m_FpsAccumulator / fpsMeasurePeriod);
m_FpsAccumulator = 0;
m_FpsNextPeriod += fpsMeasurePeriod;
}
}
Try making the shader really default and see if it renders something. So try a shader that looks like this:
Shader "Examples/ExampleDisplacement"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
float4 frag (v2f i) : SV_Target
{
float4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}
I have began to create some shaders for my university group project however I have ran into a bit of a snag with my water shader. I am trying to create one which utilises two overlapping normal maps.
Whilst everything looks okay in the editor, when I then publish to the webplayer, the scene looks like its unlit.
Heres my code for the shader:
//
// Filename : WaterShader.shader
// Version : 2.0
// Date : 1st March 2014
//
Shader "Flight/WaterShader/2.0"
{
// Set up variables so we can access them in inspector mode
Properties
{
// Variable to control the colour tint
_Color ("Base Color", Color) = (1, 1, 1, 1)
// Variables for specular
_SpecularColor ("Specular Color", Color) = (1, 1, 1, 1)
_SpecularAmount ("Shininess", Float) = 10
// Variable for setting the base texture
_MainTex ("Water Texture", 2D) = "white" { }
// Variables to set the normal map 1
_BumpMapA ("Normal Map", 2D) = "bump" { }
_BumpDepthA ("Depth", Range(0.25, 10.0)) = 1
// Variables to set the normal map 2
_BumpMapB ("Normal Map", 2D) = "bump" { }
_BumpDepthB ("Depth", Range(0.25, 10.0)) = 1
}
SubShader
{
pass
{
Tags { "RenderType" = "Opaque" }
Lighting On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma exclude_renderers flash
// Variables
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BumpMapA;
float4 _BumpMapA_ST;
float _BumpDepthA;
sampler2D _BumpMapB;
float4 _BumpMapB_ST;
float _BumpDepthB;
float4 _Color;
float4 _SpecularColor;
float _SpecularAmount;
float4 _LightColor0;
struct vertexInput
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
float4 tangent : TANGENT;
};
struct vertexOutput
{
float4 pos : SV_POSITION;
float4 tex : TEXCOORD0;
float4 posWorld : TEXCOORD1;
float3 normalWorld : TEXCOORD2;
float3 tangentWorld : TEXCOORD3;
float3 binormalWorld : TEXCOORD4;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.tex = input.texcoord;
output.posWorld = mul(_Object2World, input.vertex);
output.normalWorld = normalize( mul( float4( input.normal, 0.0f ), _World2Object ).xyz );
output.tangentWorld = normalize( mul( _Object2World, input.tangent ).xyz );
output.binormalWorld = normalize( cross( output.normalWorld, output.tangentWorld) * input.tangent.w );
return output;
}
float4 frag(vertexOutput input) : COLOR
{
// Set up variables
float3 viewDirection;
float3 lightDirection;
float3 normalDirection;
float lightIntensity;
float4 normalColorA;
float4 normalColorB;
float4 normalColor;
float3 normalLocalA;
float3 normalLocalB;
float3 normalLocal;
float3x3 normalWorld;
float4 textureColor;
float3 diffuseColor;
float3 specularColor;
float3 lightColor;
float4 finalColor;
// Begin calculations
// Calculate the angle we are looking at the pixel
viewDirection = normalize(_WorldSpaceCameraPos.xyz - input.posWorld.xyz );
if(_WorldSpaceLightPos0.w == 0.0)
{
lightIntensity = 1.0;
lightDirection = normalize(_WorldSpaceLightPos0.xyz);
}
else
{
float3 fragmentToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
float distance = length(fragmentToLightSource);
lightIntensity = 1.0 / distance;
lightDirection = normalize(fragmentToLightSource);
}
// Sample the textures
textureColor = tex2D(_MainTex, input.tex.xy * _MainTex_ST.xy + _MainTex_ST.zw);
normalColorA = tex2D(_BumpMapA, input.tex.xy * _BumpMapA_ST.xy + _BumpMapA_ST.zw);
normalColorB = tex2D(_BumpMapB, input.tex.xy * _BumpMapB_ST.xy + _BumpMapB_ST.zw);
// Expand the normals and set the intensity of the normal map
normalLocalA = float3(2.0 * normalColorA.ag - float2(1.0, 1.0), 0.0);
normalLocalA.z = _BumpDepthA;
normalLocalB = float3(2.0 * normalColorB.ag - float2(1.0, 1.0), 0.0);
normalLocalB.z = _BumpDepthB;
// Combine the two normals
normalLocal = normalize(normalLocalA + normalLocalB);
// Calculate the normal in the world
normalWorld = float3x3( input.tangentWorld, input.binormalWorld, input.normalWorld );
normalDirection = normalize( mul( normalLocal, normalWorld ) );
// Calculate lighting
diffuseColor = lightIntensity * _LightColor0.xyz * saturate( dot(normalDirection, lightDirection) );
specularColor = diffuseColor * _SpecularColor.xyz * pow( saturate( dot( reflect(-lightDirection, normalDirection), viewDirection) ), _SpecularAmount );
// Combine lighting
lightColor = UNITY_LIGHTMODEL_AMBIENT.xyz + diffuseColor + specularColor;
// Apply lighting to the texture color
textureColor = float4( textureColor.xyz * lightColor * _Color.xyz, 1.0);
return textureColor;
}
ENDCG
}
}
FallBack "Specular"
}
In the editor it looks like this:
Where as in the webplayer it looks like this:
Anyone able to help me see where I have gone wrong? :)
You need a separate pass of pixel light in the scene for the web player. Replace your current SubShader Parameters with
SubShader
{
Tags {"RenderType" = "Opaque"}
Pass
{
Tags {"LightMode" = "ForwardAdd"}
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma exclude_renderers flash