Vertex gradient shader rotation?
I have a shader that allows me to create and rotate a 2 or 3 color gradient. My problem was that it was very heavy on the GPU, so I moved this part of the code from the fragment shader to the vertex shader:
fixed4 frag (v2f i) : SV_Target
{
//STARTS HERE
float2 uv = - (i.screenPos.xy / i.screenPos.w - 0.5)*2;
fixed3 c;
#if _BG_COLOR_GRADIENT2
c = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition));
#elif _BG_COLOR_GRADIENT3
c = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3);
#endif
//ENDS HERE
return fixed4(c, i.color.a);
}
Now my shader looks like this:
Shader "Custom/Gradient"
{
Properties
{
[KeywordEnum(Gradient2, Gradient3)] _BG_COLOR ("Color Type", Float) = 1
_Color("Color", Color) = (1, 1, 1, 1)
_BgColor1 ("Start Color",Color) = (0.667,0.851,0.937,1)
_BgColor2 ("Middle Color",Color) = (0.29, 0.8, 0.2,1)
_BgColor3 ("End Color",Color) = (0.29, 0.8, 0.2,1)
[GradientPositionSliderDrawer]
_BgColorPosition ("Gradient Position",Vector) = (0,1,0)
_BgColorRotation ("Gradient Rotation",Range(0,2)) = 0
_BgColorPosition3 ("Middle Size",Range(0,1)) = 0
}
SubShader
{
Tags{ "Queue" = "Background" "IgnoreProjectors"="True" }
Blend SrcAlpha OneMinusSrcAlpha
AlphaTest Greater .01
ColorMask RGB
Cull Off Lighting Off ZWrite Off
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _BG_COLOR_GRADIENT2 _BG_COLOR_GRADIENT3
#include "UnityCG.cginc"
#include "GradientHelper.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 screenPos : TEXCOORD4;
fixed4 color : COLOR;
};
fixed4 _BgColor1;
fixed4 _BgColor2;
fixed4 _BgColor3;
float _BgColorRotation;
float2 _BgColorPosition;
float _BgColorPosition3;
float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
float2 uv = - (o.screenPos.xy / o.screenPos.w - 0.5)*2;
#if _BG_COLOR_GRADIENT2
o.color = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition)) * v.color;
#elif _BG_COLOR_GRADIENT3
o.color = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3) * v.color;
#endif
return o;
}
fixed4 frag (v2f i) : COLOR {
return i.color;
}
ENDCG
}
}
CustomEditor "Background.Editor.BackgroundGradientEditor"
}
(Here is my shader helper):
#ifndef PI
#define PI 3.141592653589793
#endif
#ifndef HALF_PI
#define HALF_PI 1.5707963267948966
#endif
// Helper Funtions
inline float clampValue(float input, float2 limit)
{
float minValue = 1-limit.y;
float maxValue = 1-limit.x;
if(input<=minValue){
return 0;
} else if(input>=maxValue){
return 1;
} else {
return (input - minValue )/(maxValue-minValue);
}
}
inline float2 rotateUV(fixed2 uv, float rotation)
{
float sinX = sin (rotation);
float cosX = cos (rotation);
float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);
return mul ( uv, rotationMatrix )/2 + 0.5;
}
inline fixed4 lerp3(fixed4 a, fixed4 b, fixed4 c, float pos, float size){
float ratio2 = 0.5+size*0.5;
float ratio1 = 1-ratio2;
if(pos<ratio1)
return lerp(a,b,pos/ratio1);
else if(pos>ratio2)
return lerp(b,c,(pos-ratio2)/ratio1);
else
return b;
}
#endif
The performance is great now, but the rotation is totally messed up (most noticeable on the 3 color gradient) and I can't seem to figure it out why.
unity3d opengl shader fragment-shader vertex-shader
|
show 1 more comment
I have a shader that allows me to create and rotate a 2 or 3 color gradient. My problem was that it was very heavy on the GPU, so I moved this part of the code from the fragment shader to the vertex shader:
fixed4 frag (v2f i) : SV_Target
{
//STARTS HERE
float2 uv = - (i.screenPos.xy / i.screenPos.w - 0.5)*2;
fixed3 c;
#if _BG_COLOR_GRADIENT2
c = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition));
#elif _BG_COLOR_GRADIENT3
c = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3);
#endif
//ENDS HERE
return fixed4(c, i.color.a);
}
Now my shader looks like this:
Shader "Custom/Gradient"
{
Properties
{
[KeywordEnum(Gradient2, Gradient3)] _BG_COLOR ("Color Type", Float) = 1
_Color("Color", Color) = (1, 1, 1, 1)
_BgColor1 ("Start Color",Color) = (0.667,0.851,0.937,1)
_BgColor2 ("Middle Color",Color) = (0.29, 0.8, 0.2,1)
_BgColor3 ("End Color",Color) = (0.29, 0.8, 0.2,1)
[GradientPositionSliderDrawer]
_BgColorPosition ("Gradient Position",Vector) = (0,1,0)
_BgColorRotation ("Gradient Rotation",Range(0,2)) = 0
_BgColorPosition3 ("Middle Size",Range(0,1)) = 0
}
SubShader
{
Tags{ "Queue" = "Background" "IgnoreProjectors"="True" }
Blend SrcAlpha OneMinusSrcAlpha
AlphaTest Greater .01
ColorMask RGB
Cull Off Lighting Off ZWrite Off
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _BG_COLOR_GRADIENT2 _BG_COLOR_GRADIENT3
#include "UnityCG.cginc"
#include "GradientHelper.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 screenPos : TEXCOORD4;
fixed4 color : COLOR;
};
fixed4 _BgColor1;
fixed4 _BgColor2;
fixed4 _BgColor3;
float _BgColorRotation;
float2 _BgColorPosition;
float _BgColorPosition3;
float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
float2 uv = - (o.screenPos.xy / o.screenPos.w - 0.5)*2;
#if _BG_COLOR_GRADIENT2
o.color = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition)) * v.color;
#elif _BG_COLOR_GRADIENT3
o.color = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3) * v.color;
#endif
return o;
}
fixed4 frag (v2f i) : COLOR {
return i.color;
}
ENDCG
}
}
CustomEditor "Background.Editor.BackgroundGradientEditor"
}
(Here is my shader helper):
#ifndef PI
#define PI 3.141592653589793
#endif
#ifndef HALF_PI
#define HALF_PI 1.5707963267948966
#endif
// Helper Funtions
inline float clampValue(float input, float2 limit)
{
float minValue = 1-limit.y;
float maxValue = 1-limit.x;
if(input<=minValue){
return 0;
} else if(input>=maxValue){
return 1;
} else {
return (input - minValue )/(maxValue-minValue);
}
}
inline float2 rotateUV(fixed2 uv, float rotation)
{
float sinX = sin (rotation);
float cosX = cos (rotation);
float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);
return mul ( uv, rotationMatrix )/2 + 0.5;
}
inline fixed4 lerp3(fixed4 a, fixed4 b, fixed4 c, float pos, float size){
float ratio2 = 0.5+size*0.5;
float ratio1 = 1-ratio2;
if(pos<ratio1)
return lerp(a,b,pos/ratio1);
else if(pos>ratio2)
return lerp(b,c,(pos-ratio2)/ratio1);
else
return b;
}
#endif
The performance is great now, but the rotation is totally messed up (most noticeable on the 3 color gradient) and I can't seem to figure it out why.
unity3d opengl shader fragment-shader vertex-shader
1
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as yourlerped vars. You have an interpolation from rotated screen coordinates.
– Ripi2
Nov 13 '18 at 17:35
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
1
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33
|
show 1 more comment
I have a shader that allows me to create and rotate a 2 or 3 color gradient. My problem was that it was very heavy on the GPU, so I moved this part of the code from the fragment shader to the vertex shader:
fixed4 frag (v2f i) : SV_Target
{
//STARTS HERE
float2 uv = - (i.screenPos.xy / i.screenPos.w - 0.5)*2;
fixed3 c;
#if _BG_COLOR_GRADIENT2
c = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition));
#elif _BG_COLOR_GRADIENT3
c = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3);
#endif
//ENDS HERE
return fixed4(c, i.color.a);
}
Now my shader looks like this:
Shader "Custom/Gradient"
{
Properties
{
[KeywordEnum(Gradient2, Gradient3)] _BG_COLOR ("Color Type", Float) = 1
_Color("Color", Color) = (1, 1, 1, 1)
_BgColor1 ("Start Color",Color) = (0.667,0.851,0.937,1)
_BgColor2 ("Middle Color",Color) = (0.29, 0.8, 0.2,1)
_BgColor3 ("End Color",Color) = (0.29, 0.8, 0.2,1)
[GradientPositionSliderDrawer]
_BgColorPosition ("Gradient Position",Vector) = (0,1,0)
_BgColorRotation ("Gradient Rotation",Range(0,2)) = 0
_BgColorPosition3 ("Middle Size",Range(0,1)) = 0
}
SubShader
{
Tags{ "Queue" = "Background" "IgnoreProjectors"="True" }
Blend SrcAlpha OneMinusSrcAlpha
AlphaTest Greater .01
ColorMask RGB
Cull Off Lighting Off ZWrite Off
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _BG_COLOR_GRADIENT2 _BG_COLOR_GRADIENT3
#include "UnityCG.cginc"
#include "GradientHelper.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 screenPos : TEXCOORD4;
fixed4 color : COLOR;
};
fixed4 _BgColor1;
fixed4 _BgColor2;
fixed4 _BgColor3;
float _BgColorRotation;
float2 _BgColorPosition;
float _BgColorPosition3;
float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
float2 uv = - (o.screenPos.xy / o.screenPos.w - 0.5)*2;
#if _BG_COLOR_GRADIENT2
o.color = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition)) * v.color;
#elif _BG_COLOR_GRADIENT3
o.color = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3) * v.color;
#endif
return o;
}
fixed4 frag (v2f i) : COLOR {
return i.color;
}
ENDCG
}
}
CustomEditor "Background.Editor.BackgroundGradientEditor"
}
(Here is my shader helper):
#ifndef PI
#define PI 3.141592653589793
#endif
#ifndef HALF_PI
#define HALF_PI 1.5707963267948966
#endif
// Helper Funtions
inline float clampValue(float input, float2 limit)
{
float minValue = 1-limit.y;
float maxValue = 1-limit.x;
if(input<=minValue){
return 0;
} else if(input>=maxValue){
return 1;
} else {
return (input - minValue )/(maxValue-minValue);
}
}
inline float2 rotateUV(fixed2 uv, float rotation)
{
float sinX = sin (rotation);
float cosX = cos (rotation);
float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);
return mul ( uv, rotationMatrix )/2 + 0.5;
}
inline fixed4 lerp3(fixed4 a, fixed4 b, fixed4 c, float pos, float size){
float ratio2 = 0.5+size*0.5;
float ratio1 = 1-ratio2;
if(pos<ratio1)
return lerp(a,b,pos/ratio1);
else if(pos>ratio2)
return lerp(b,c,(pos-ratio2)/ratio1);
else
return b;
}
#endif
The performance is great now, but the rotation is totally messed up (most noticeable on the 3 color gradient) and I can't seem to figure it out why.
unity3d opengl shader fragment-shader vertex-shader
I have a shader that allows me to create and rotate a 2 or 3 color gradient. My problem was that it was very heavy on the GPU, so I moved this part of the code from the fragment shader to the vertex shader:
fixed4 frag (v2f i) : SV_Target
{
//STARTS HERE
float2 uv = - (i.screenPos.xy / i.screenPos.w - 0.5)*2;
fixed3 c;
#if _BG_COLOR_GRADIENT2
c = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition));
#elif _BG_COLOR_GRADIENT3
c = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3);
#endif
//ENDS HERE
return fixed4(c, i.color.a);
}
Now my shader looks like this:
Shader "Custom/Gradient"
{
Properties
{
[KeywordEnum(Gradient2, Gradient3)] _BG_COLOR ("Color Type", Float) = 1
_Color("Color", Color) = (1, 1, 1, 1)
_BgColor1 ("Start Color",Color) = (0.667,0.851,0.937,1)
_BgColor2 ("Middle Color",Color) = (0.29, 0.8, 0.2,1)
_BgColor3 ("End Color",Color) = (0.29, 0.8, 0.2,1)
[GradientPositionSliderDrawer]
_BgColorPosition ("Gradient Position",Vector) = (0,1,0)
_BgColorRotation ("Gradient Rotation",Range(0,2)) = 0
_BgColorPosition3 ("Middle Size",Range(0,1)) = 0
}
SubShader
{
Tags{ "Queue" = "Background" "IgnoreProjectors"="True" }
Blend SrcAlpha OneMinusSrcAlpha
AlphaTest Greater .01
ColorMask RGB
Cull Off Lighting Off ZWrite Off
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma shader_feature _BG_COLOR_GRADIENT2 _BG_COLOR_GRADIENT3
#include "UnityCG.cginc"
#include "GradientHelper.cginc"
struct appdata
{
float4 vertex : POSITION;
fixed4 color : COLOR;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 screenPos : TEXCOORD4;
fixed4 color : COLOR;
};
fixed4 _BgColor1;
fixed4 _BgColor2;
fixed4 _BgColor3;
float _BgColorRotation;
float2 _BgColorPosition;
float _BgColorPosition3;
float4 _Color;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.screenPos = ComputeScreenPos(o.pos);
float2 uv = - (o.screenPos.xy / o.screenPos.w - 0.5)*2;
#if _BG_COLOR_GRADIENT2
o.color = lerp(_BgColor1,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition)) * v.color;
#elif _BG_COLOR_GRADIENT3
o.color = lerp3(_BgColor1,_BgColor2,_BgColor3,clampValue(rotateUV(uv.xy,_BgColorRotation*PI).y,_BgColorPosition),_BgColorPosition3) * v.color;
#endif
return o;
}
fixed4 frag (v2f i) : COLOR {
return i.color;
}
ENDCG
}
}
CustomEditor "Background.Editor.BackgroundGradientEditor"
}
(Here is my shader helper):
#ifndef PI
#define PI 3.141592653589793
#endif
#ifndef HALF_PI
#define HALF_PI 1.5707963267948966
#endif
// Helper Funtions
inline float clampValue(float input, float2 limit)
{
float minValue = 1-limit.y;
float maxValue = 1-limit.x;
if(input<=minValue){
return 0;
} else if(input>=maxValue){
return 1;
} else {
return (input - minValue )/(maxValue-minValue);
}
}
inline float2 rotateUV(fixed2 uv, float rotation)
{
float sinX = sin (rotation);
float cosX = cos (rotation);
float2x2 rotationMatrix = float2x2(cosX, -sinX, sinX, cosX);
return mul ( uv, rotationMatrix )/2 + 0.5;
}
inline fixed4 lerp3(fixed4 a, fixed4 b, fixed4 c, float pos, float size){
float ratio2 = 0.5+size*0.5;
float ratio1 = 1-ratio2;
if(pos<ratio1)
return lerp(a,b,pos/ratio1);
else if(pos>ratio2)
return lerp(b,c,(pos-ratio2)/ratio1);
else
return b;
}
#endif
The performance is great now, but the rotation is totally messed up (most noticeable on the 3 color gradient) and I can't seem to figure it out why.
unity3d opengl shader fragment-shader vertex-shader
unity3d opengl shader fragment-shader vertex-shader
edited Nov 13 '18 at 16:40
genpfault
41.9k95298
41.9k95298
asked Nov 13 '18 at 16:37
Roland SzépRoland Szép
87112
87112
1
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as yourlerped vars. You have an interpolation from rotated screen coordinates.
– Ripi2
Nov 13 '18 at 17:35
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
1
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33
|
show 1 more comment
1
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as yourlerped vars. You have an interpolation from rotated screen coordinates.
– Ripi2
Nov 13 '18 at 17:35
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
1
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33
1
1
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as your
lerped vars. You have an interpolation from rotated screen coordinates.– Ripi2
Nov 13 '18 at 17:35
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as your
lerped vars. You have an interpolation from rotated screen coordinates.– Ripi2
Nov 13 '18 at 17:35
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
1
1
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33
|
show 1 more comment
1 Answer
1
active
oldest
votes
I never understand why people want to make their gradients inside the shader, it is quite limited and not necessarily more performant unless you are changing the values every frame. My best solution for this would be to generate the gradient as a texture on the CPU, with the size 1x128. Use the Gradient class which is provided by Unity, and loop:
Texture2D texture = new Texture2D(128, 1);
Color pixels = Color[128];
for (int i = 0; i < 128; i++) {
pixels[i] = gradient.Evaluate(1/127f);
}
texture.SetPixels(pixels);
texture.Apply();
Send it to the shader using:
material.SetTexture("_Gradient", texture)
Then, you can rotate and scroll along this texture all you want using a 2x2 matrix like you did. Just make sure to set texture overflow mode to clamp and not repeat. Remember that you can implement OnValidate() into your behavior to apply value updates in the editor, if you need to update it in build though, you will need to listen to changes some other way.
Using vertex colors would indeed be useful for gradients, since these are interpolated in the hardware... but from my understanding, this is a screen-space effect, and as such you would need the vertices to line up with the actual gradient bands.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285619%2fvertex-gradient-shader-rotation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I never understand why people want to make their gradients inside the shader, it is quite limited and not necessarily more performant unless you are changing the values every frame. My best solution for this would be to generate the gradient as a texture on the CPU, with the size 1x128. Use the Gradient class which is provided by Unity, and loop:
Texture2D texture = new Texture2D(128, 1);
Color pixels = Color[128];
for (int i = 0; i < 128; i++) {
pixels[i] = gradient.Evaluate(1/127f);
}
texture.SetPixels(pixels);
texture.Apply();
Send it to the shader using:
material.SetTexture("_Gradient", texture)
Then, you can rotate and scroll along this texture all you want using a 2x2 matrix like you did. Just make sure to set texture overflow mode to clamp and not repeat. Remember that you can implement OnValidate() into your behavior to apply value updates in the editor, if you need to update it in build though, you will need to listen to changes some other way.
Using vertex colors would indeed be useful for gradients, since these are interpolated in the hardware... but from my understanding, this is a screen-space effect, and as such you would need the vertices to line up with the actual gradient bands.
add a comment |
I never understand why people want to make their gradients inside the shader, it is quite limited and not necessarily more performant unless you are changing the values every frame. My best solution for this would be to generate the gradient as a texture on the CPU, with the size 1x128. Use the Gradient class which is provided by Unity, and loop:
Texture2D texture = new Texture2D(128, 1);
Color pixels = Color[128];
for (int i = 0; i < 128; i++) {
pixels[i] = gradient.Evaluate(1/127f);
}
texture.SetPixels(pixels);
texture.Apply();
Send it to the shader using:
material.SetTexture("_Gradient", texture)
Then, you can rotate and scroll along this texture all you want using a 2x2 matrix like you did. Just make sure to set texture overflow mode to clamp and not repeat. Remember that you can implement OnValidate() into your behavior to apply value updates in the editor, if you need to update it in build though, you will need to listen to changes some other way.
Using vertex colors would indeed be useful for gradients, since these are interpolated in the hardware... but from my understanding, this is a screen-space effect, and as such you would need the vertices to line up with the actual gradient bands.
add a comment |
I never understand why people want to make their gradients inside the shader, it is quite limited and not necessarily more performant unless you are changing the values every frame. My best solution for this would be to generate the gradient as a texture on the CPU, with the size 1x128. Use the Gradient class which is provided by Unity, and loop:
Texture2D texture = new Texture2D(128, 1);
Color pixels = Color[128];
for (int i = 0; i < 128; i++) {
pixels[i] = gradient.Evaluate(1/127f);
}
texture.SetPixels(pixels);
texture.Apply();
Send it to the shader using:
material.SetTexture("_Gradient", texture)
Then, you can rotate and scroll along this texture all you want using a 2x2 matrix like you did. Just make sure to set texture overflow mode to clamp and not repeat. Remember that you can implement OnValidate() into your behavior to apply value updates in the editor, if you need to update it in build though, you will need to listen to changes some other way.
Using vertex colors would indeed be useful for gradients, since these are interpolated in the hardware... but from my understanding, this is a screen-space effect, and as such you would need the vertices to line up with the actual gradient bands.
I never understand why people want to make their gradients inside the shader, it is quite limited and not necessarily more performant unless you are changing the values every frame. My best solution for this would be to generate the gradient as a texture on the CPU, with the size 1x128. Use the Gradient class which is provided by Unity, and loop:
Texture2D texture = new Texture2D(128, 1);
Color pixels = Color[128];
for (int i = 0; i < 128; i++) {
pixels[i] = gradient.Evaluate(1/127f);
}
texture.SetPixels(pixels);
texture.Apply();
Send it to the shader using:
material.SetTexture("_Gradient", texture)
Then, you can rotate and scroll along this texture all you want using a 2x2 matrix like you did. Just make sure to set texture overflow mode to clamp and not repeat. Remember that you can implement OnValidate() into your behavior to apply value updates in the editor, if you need to update it in build though, you will need to listen to changes some other way.
Using vertex colors would indeed be useful for gradients, since these are interpolated in the hardware... but from my understanding, this is a screen-space effect, and as such you would need the vertices to line up with the actual gradient bands.
answered yesterday
Kalle HalvarssonKalle Halvarsson
1486
1486
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53285619%2fvertex-gradient-shader-rotation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
A fragment shader (FS) outputs the color of a pixel. A vertex shader (VS) outputs values for vertices. The OpenGL engine interpolates values (for the FS) using the outputs of the VS, as your
lerped vars. You have an interpolation from rotated screen coordinates.– Ripi2
Nov 13 '18 at 17:35
Can you help me, what should I do then? Thank you in advance!
– Roland Szép
Nov 13 '18 at 18:07
1
Pass to the VS coordinates and colors of the vertices of the triangle of colors. The OGL will pass to the FS interpolated values (as by using 'lerp') for every point inside the triangle. No 'lerp' needed. No calcs needed in the FS. If you want a rotated triangle, just rotate the vertices in the VS, which needs you pass also, at least an angle. Don't confuse "triangle rotation" with "color rotation" (a gradient).
– Ripi2
Nov 13 '18 at 18:16
I am so sorry, I am really new to shaders and I am also not a native English speaker. If you could write down the code for me, I would gladly accept it as an answer.
– Roland Szép
Nov 13 '18 at 18:30
I can't write the code, I know nothing on unity3d. I recommend to study some OpenGL tutorial (for version >= 3.2) even it's written in C++. You'll learn how OpenGL works, specially about the automatic interpolation that is done between the VS and the FS.
– Ripi2
Nov 13 '18 at 18:33