Unity: Apply shader to object to curve its texture - unity3d

I'm making a endless runner game in Unity, and I want to add a curved shader to it like in this tutorial https://youtu.be/6_e_GoWlZOo
But when I add that material to a object it replaces the old one. And when I add it as second one in the Mesh Renderer it doesn't affect the first one.
https://drive.google.com/open?id=1-kP4A0Xh3P9xVjrwjTiTPlh_WcHnBA1d
This is the shader code:
Shader "PPP/BendWorld"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_Curvature("Curvature", Float) = 0.001
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert vertex:vert addshadow
uniform sampler2D _MainTex;
uniform float _Curvature;
struct Input
{
float uv_MainTex;
};
void vert(inout appdata_full v)
{
float4 worldSpace = mul(unity_ObjectToWorld, v.vertex);
worldSpace.xyz -= _WorldSpaceCameraPos.xyz;
worldSpace = float4(0.0f, (worldSpace.x * worldSpace.x) * -_Curvature, 0.0f, 0.0f);
v.vertex += mul(unity_WorldToObject, worldSpace);
}
void surf(Input IN, inout SurfaceOutput o)
{
half4 c = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
Fallback "Mobile/Diffuse"
}
I want to curve the object and have a texture on it, is there any way to do this?

Regarding the texture issue: The texture looks broken because you have defined your uv_MainTex as a float instead of a float2. UV coordinates are two-dimensional - if you define it as a scalar, it will only use the U axis of the UVs.

Related

How do I make the shader working for the standard pipeline work for the urp pipeline?

I have a shader that provides texture repeat. But it doesn't work in urp. How do I make it work for urp?
More precisely, the shader works, but the material turns pink. I made the option Rendering>Generate shader includes. I will be glad if you can help me how to do it.
My RepeatShader:
Shader "Custom/RepeatShader" {
Properties{
_Color("Main Color", Color) = (1,1,1,1)
_MainTex("Base (RGB)", 2D) = "white" {}
_Scale("Texture Scale", Float) = 1.0
}
SubShader{
Tags{ "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
fixed4 _Color;
float _Scale;
struct Input {
float3 worldNormal;
float3 worldPos;
};
void surf(Input IN, inout SurfaceOutput o) {
float2 UV;
fixed4 c;
if (abs(IN.worldNormal.x) > 0.5) {
UV = IN.worldPos.yz; // side
c = tex2D(_MainTex, UV* _Scale); // use WALLSIDE texture
}
else if (abs(IN.worldNormal.z) > 0.5) {
UV = IN.worldPos.xy; // front
c = tex2D(_MainTex, UV* _Scale); // use WALL texture
}
else {
UV = IN.worldPos.xz; // top
c = tex2D(_MainTex, UV* _Scale); // use FLR texture
}
o.Albedo = c.rgb * _Color;
}
ENDCG
}
Fallback "Legacy Shaders/VertexLit"
}
I don't know in which version of Unity and URP you are, but here's what I did:
First, right-click with your mouse and select Create > Shader Graph > URP > Lit Shader Graph (or Unlit if your shader should not react to light).
Inside your shader, create a Texture2D property called Main Tex, a float property called Scale and a color property called Color.
This is what your shader graph result should look like:
This should replicate exactly what you have in your shader. There are a few possible improvements, like using the Custom Function node to extract what you need without using all those nodes but this should help you start.

Clip the region in Ellipse shape using ShaderLab in Unity

I am trying to draw an Ellipsoid using shaders in Unity
Following the steps
1. I have written a custom shader with the help of some internet tutorial
2. Added the shader on the material
3. Applied that material on the object
Shader "Custom/HoleMaker" {
Properties{
_Position("Position", Vector) = (0,0,0,0)
_Radius("Radius", Range(0,1)) = 0.01
_Color("Color", Color) = (1,1,1,1)
_CutawayColor("Cutaway Color", Color) = (1,1,1,1)
}
SubShader{
Tags { "RenderType" = "Opaque"}
LOD 200
Cull Front
CGPROGRAMtypes
#pragma surface surf MonoColor fullforwardshadows vertex:vert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
fixed4 _CutawayColor;
float4 _Position;
float _Radius;
struct Input
{
float2 uv_MainTex;
float3 worldPos;
};
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
v.normal *= -1;
}
half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
return _CutawayColor;
}
void surf(Input IN, inout SurfaceOutput o)
{
//spherical clipping
float dist = distance(IN.worldPos.xyz, _Position.xyz);
if (dist < _Radius)
clip(-1);
o.Albedo = _CutawayColor.rgb;
}
ENDCG
}
FallBack "Diffuse"
}
This code is working for making a circle but when I try to use the function clip() to make an Ellipsoid, it is not working. According to the documentation, clip(float4 x) is also available to be used to clip the surface. The variable _Radius makes a perfect sphere in World Space but when I try to use _Radius.x and _Radius.y, the code does not work. Please refer to the image attached herewith.
_Radius.x and _Radius.y break the shader because _Radius is a float. It doesn't have x or y members. How could it possibly have a value for _Radius.y?
Instead, consider adding a Scale property, then scaling the difference between world position and _Position by that amount, before comparing the magnitude of the difference to _radius:
Shader "Custom/HoleMaker" {
Properties{
_Position("Position", Vector) = (0,0,0,0)
_Scale("Scale", Vector) = (1,1,1,0)
_Radius("Radius", Range(0,1)) = 0.01
_Color("Color", Color) = (1,1,1,1)
_CutawayColor("Cutaway Color", Color) = (1,1,1,1)
}
SubShader{
Tags { "RenderType" = "Opaque"}
LOD 200
Cull Front
CGPROGRAMtypes
#pragma surface surf MonoColor fullforwardshadows vertex:vert
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
fixed4 _CutawayColor;
float4 _Position;
float4 _Scale;
float _Radius;
struct Input
{
float2 uv_MainTex;
float3 worldPos;
};
void vert(inout appdata_full v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
v.normal *= -1;
}
half4 LightingMonoColor(SurfaceOutput s, half3 lightDir, half atten) {
return _CutawayColor;
}
void surf(Input IN, inout SurfaceOutput o)
{
//spherical clipping
float dist = length(_Scale.xyz * IN.worldPos.xyz - _Position.xyz);
if (dist < _Radius)
clip(-1);
o.Albedo = _CutawayColor.rgb;
}
ENDCG
}
FallBack "Diffuse"
}

Is there a way to repeat texture on Unity 3D object without specifying amount of tiles?

I am trying to make two different objects with the same size of texture / same material, which should be repeating; Without making new material for every new object I create. Below is an example of what I am trying to achieve.
Material A on both objects should look the same, the cube on the right represents how it should look.
This is fixed and working!
I had to make a Unity shader, which uses world space instead of local space (default). This is the code of a shader I used:
Shader "Legacy Shaders/Diffuse - Worldspace" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_Scale("Texture Scale", Float) = 1.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
fixed4 _Color;
float _Scale;
struct Input {
float3 worldNormal;
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutput o) {
float2 UV;
fixed4 c;
if (abs(IN.worldNormal.x) > 0.5) {
UV = IN.worldPos.yz; // side
c = tex2D(_MainTex, UV* _Scale); // use WALLSIDE texture
}
else if (abs(IN.worldNormal.z) > 0.5) {
UV = IN.worldPos.xy; // front
c = tex2D(_MainTex, UV* _Scale); // use WALL texture
}
else {
UV = IN.worldPos.xz; // top
c = tex2D(_MainTex, UV* _Scale); // use FLR texture
}
o.Albedo = c.rgb * _Color;
}
ENDCG
}
Fallback "Legacy Shaders/VertexLit"
}
Fixed version:
Fixed
Sources of Knowledge I used:
Video tutorial by PushyPixels
Blocks of code taken from this blog
#derHugo set me on the right track, thank you!!

How to reflect normals once they have been flipped in unity

I am trying to play a 360 video within a sphere. I am not an expert at unity or 3D modeling but I've managed to get the 360 video to invert its normals and play on the inside of the sphere.
The problem is the video has been flipped by the inversion (right is left and left is right). I need to correct this and despite the last three hours of searching I cannot find a solution that I understand. This is the code I've been using as a custom shader to achieve the inversion:
Shader "Custom/Flip Normals" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType" = "Opaque" }
Cull Off
CGPROGRAM
#pragma surface surf Lambert vertex:vert
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
float4 color : COLOR;
};
void vert(inout appdata_full v) {
v.normal.xyz = v.normal * -1;
}
void surf (Input IN, inout SurfaceOutput o) {
fixed3 result = tex2D(_MainTex, IN.uv_MainTex);
o.Albedo = result.rgb;
o.Alpha = 1;
}
ENDCG
}
Fallback "Diffuse"
}
Note: messing with the camera or the video file itself are not ideal options.

Unity3D: My shader doesn't work well in GameView

I wrote SurfaceShader with bumped texture.
I apply my material to a sphere. I can see the sphere in Scene View, but I can't see the sphere in Game View.
When I apply other shaders to the sphere, I can see the sphere in GameView.
I found the same question in Unity Community.
I understood I should use not Vertex Lighting but Pixel Lighting.
But I couldn't understand which settings should I change. Should I modify my shader or my settings?
My shader is the following.
Shader "Custom/MyShader2"{
Properties{
_Bump("Bump",2D) = "white"{}
_DiffuseColor("Diffuse Color", Color) = (1.0,1.0,1.0)
_Specular("Specular",Range(1.0,50.0)) = 15.0
_Alpha("Alpha",Range(0,1)) = 1
}
SubShader{
Tags{
"RenderType" = "Opaque"
}
CGPROGRAM
#pragma surface surf Original alpha
struct Input{
float4 color: COLOR;
float2 uv_Bump;
};
float3 _DiffuseColor;
float _Specular;
sampler2D _Bump;
float _Alpha;
half4 LightingOriginal( SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
half diff = max(0,dot(s.Normal,lightDir));
half spec = max(0,dot(s.Normal,normalize(lightDir + viewDir)));
spec = pow(spec, _Specular);
half trans = 1.0 - max(0,dot(s.Normal, viewDir)) + spec;
half4 c;
c. rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec / 2) * (atten * 2);
c.a = trans;
return c;
}
void surf( Input IN, inout SurfaceOutput o) {
o.Albedo = _DiffuseColor * _Alpha;;
o.Normal = UnpackNormal(tex2D(_Bump,IN.uv_Bump));
o.Alpha = _Alpha;
}
ENDCG
}
FallBack "Diffuse"
}
Thanks anyway.
Try to change
Tags { "RenderType" = "Opaque" }
with
Tags { "Queue"="Transparent" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
Cull Off ZWrite Off