| View previous topic :: View next topic |
metervara

Joined: 15 Jun 2006 Posts: 201 Location: Copenhagen
|
Posted: Mon Jul 30, 2007 10:32 am Post subject: shader.SetGlobalVector ? |
|
|
|
Digging myself deeper and deeper into the ShaderLab hole...
I have a lot of objects with the same shader. The shader needs to know the position of another object.
First attempt has an exposed Vector property for the shader. This works, but with many objects it gets inconvenient:
| Code: |
//shader
Properties {
_Obstacle ("Obstacle", Vector) = (0,0,0,0)
}
//Object that affects shader
other.renderer.material.SetVector("_Obstacle", transform.position);
|
Then I remembered global shader properties, but it seems SetGlobalVector is missing . I can use SetGlobalFloat for x,y,z, that should work fine, I'm just wondering if there's a 'proper' way of getting a position like this into the shader?
/P
|
|
| Back to top |
|
|
Aras Unity Graphics Developer

Joined: 07 Nov 2005 Posts: 3316 Location: Unity Technologies, basement
|
Posted: Mon Jul 30, 2007 11:30 am Post subject: |
|
|
|
For now use SetGlobalColor, we'll add SetGlobalVector in the future release.
SetGlobalColor will just work; as vectors and colors internally are the same thing (four floating point numbers); and Colors can have components outside of the usual 0..1 range.
_________________ homepage | blog | twitter |
|
| Back to top |
|
|
metervara

Joined: 15 Jun 2006 Posts: 201 Location: Copenhagen
|
Posted: Mon Jul 30, 2007 12:09 pm Post subject: |
|
|
|
SetGlobalColor works great. Managed to hack the Windy Grass shader to make the grass bend to avoid an obstacle.
Still need to fix issues when the obstacle is inside the grass geometry as this will stretch the grass unnaturally. (Btw, I'm using geometry instead of billboards so I can have the camera close to the grass)
/P
|
|
| Back to top |
|
|
Aras Unity Graphics Developer

Joined: 07 Nov 2005 Posts: 3316 Location: Unity Technologies, basement
|
Posted: Mon Jul 30, 2007 1:45 pm Post subject: |
|
|
|
Gee, Patrik, you'll turn into a shader monster soon! Keep up the good work
_________________ homepage | blog | twitter |
|
| Back to top |
|
|
drJones
Joined: 19 Oct 2005 Posts: 1342 Location: New Hampshire
|
Posted: Mon Jul 30, 2007 2:13 pm Post subject: |
|
|
|
wow that's really cool - i'm wondering how is the performance using regular meshes instead of billboards?
_________________ -O |
|
| Back to top |
|
|
jeremyace
Joined: 12 Oct 2005 Posts: 1651 Location: Ontario, Canada
|
|
| Back to top |
|
|
metervara

Joined: 15 Jun 2006 Posts: 201 Location: Copenhagen
|
Posted: Tue Jul 31, 2007 8:19 am Post subject: |
|
|
|
Here is the most basic version. It has some problems when the obstacle is inside the geometry. One fix is to move the grass slightly away from the obstacle as it gets close, but it looks weird if the ground is visible. Works when you only see the top of the grass though.
It's a few additions to the standard Windy Grass shader from the Nature pack:
Firts off there's a global shader color: _Obstacle. Use Shader.SetGlobalColor to get the obstacle position to the shader.
Then the main block (/OBSTACLE AVOIDANCE CALC). The windy grass shader already calculates the world position for vertices so use that and compare with obstacle position to get bend direction vector. Also calculate distance falloff.
Finally we add the bend offset exponentially - v.vertex.xz += ...
We could also swap v.texcoord.y for let's say v.color.r and paint the 'bendyness' into the model using vertex colors to have some parts softer than others. Doesn't really make sense for a simple thing like a grass straw though, but could be cool for more complex models.
Note:
And all this is not really bending, but stretching or skewing so the geometry can look strange sometimes. Feel free to fix
| Code: |
Shader "Nature/Windy Grass" {
Properties {
_Color ("Main Color", Color) = (.5, .5, .5, 0)
_Color2 ("Fade Color", Color) = (1, .9, .8, 0)
_MainTex ("Base (RGB) Alpha (A)", 2D) = "white" {}
_Cutoff ("Base Alpha cutoff", Range (0,1)) = .5
}
SubShader {
Tags { "Queue" = "Transparent" }
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
Pass {
Lighting On
CGPROGRAM
// vertex Vertex
#include "waves.cginc" // Get in the helper wave functions
#include "UnityCG.cginc" // Get standard Unity constants
struct Appdata {
float4 vertex;
float3 normal;
float4 texcoord;
float4 color;
};
struct v2f {
float4 pos : POSITION;
float4 color : COLOR0;
float4 uv : TEXCOORD0;
float fog : FOGC;
};
uniform float4 _Color, _Color2, _SkyLight;
uniform float4 _Obstacle; // OBSTACLE AVOIDANCE
v2f Vertex(Appdata v) {
v2f o;
const float4 _waveXSize = float4(0.012, 0.02, -0.06, 0.048) * 2;
const float4 _waveZSize = float4 (0.006, .02, -0.02, 0.1) * 2;
const float4 waveSpeed = float4 (0.3, .3, .08, .07) * 4;
float4 _waveXmove = _waveXSize * waveSpeed * 25;
float4 _waveZmove = _waveZSize * waveSpeed * 25;
// We model the wind as basic waves...
// Calculate the wind input to leaves from their vertex positions....
// for now, we transform them into world-space x/z positions...
// Later on, we should actually be able to do the whole calc's in post-projective space
float3 worldPos = mul ((float3x4)_Object2World, v.vertex);
// OBSTACLE AVOIDANCE CALC
float3 bendDir = normalize (float3(worldPos.x,0,worldPos.z) - float3(_Obstacle.x,0,_Obstacle.z));//direction of obstacle bend
float distLimit = 3;// how far away does obstacle reach
float distMulti = (distLimit-min(distLimit,distance(float3(worldPos.x,0,worldPos.z),float3(_Obstacle.x,0,_Obstacle.z))))/distLimit; //distance falloff
//OBSTACLE AVOIDANCE END
// This is the input to the sinusiodal warp
float4 waves;
waves = worldPos.x * _waveXSize;
waves += worldPos.z * _waveZSize;
// Add in time to model them over time
waves += _Time.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.texcoord.y;
s *= waveAmount;
// Faste winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float fade = dot (s, 1.3);
s = s * s;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
v.vertex.xz += bendDir.xz*distMulti*v.texcoord.y*v.texcoord.y*1.5; //ADD OBSTACLE BENDING
o.pos = mul(glstate.matrix.mvp, v.vertex);
o.fog = o.pos.w;
o.uv = v.texcoord;
o.color = lerp (_Color, _Color2, fade.xxxx);
// o.color *= _SkyLight;
return o;
}
ENDCG
AlphaTest Greater [_Cutoff]
Cull Off
SetTexture [_MainTex] { combine texture * primary double, texture}
}
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Blend SrcAlpha oneMinusSrcAlpha
AlphaTest Greater [_Cutoff]
Cull Off
color [_Color]
ZTest Less
SetTexture [_MainTex] { combine texture * primary DOUBLE, texture}
}
}
}
|
/P
|
|
| Back to top |
|
|
jeremyace
Joined: 12 Oct 2005 Posts: 1651 Location: Ontario, Canada
|
|
| Back to top |
|
|
metervara

Joined: 15 Jun 2006 Posts: 201 Location: Copenhagen
|
Posted: Tue Jul 31, 2007 9:47 am Post subject: |
|
|
|
Would love to see implementations or variations of it
/P
|
|
| Back to top |
|
|
rawrman2381238
Joined: 28 Jan 2008 Posts: 122
|
Posted: Fri Mar 20, 2009 3:51 am Post subject: |
|
|
|
| Can someone make a unity package as I am unsure how to se this up... It looks awesome though!
|
|
| Back to top |
|
|
God at play

Joined: 03 Nov 2006 Posts: 105 Location: Des Moines, IA
|
Posted: Sat Jul 04, 2009 7:07 am Post subject: |
|
|
|
Here's a version that works in Unity 2.5. Please note, I customized it to my own situation, which means the texture has been removed.
| Code: | Shader "Dynamic Grass"
{
Properties
{
_Color ("Main Color", Color) = (.055, .094, .082, 1)
_Color2 ("Fade Color", Color) = (.09, .157, .137, 1)
_WaveX ("Wave X", Vector) = (.07, .01, .01, 0.01)
_WaveZ ("Wave Z", Vector) = (-.07, .01, .01, 0.01)
_WaveSpeed ("Wave Speed", Vector) = (1, 1.5, 1.1, .9)
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
Lighting On
CGPROGRAM
#pragma vertex Vertex
#include "waves.cginc" // Get in the helper wave functions
#include "UnityCG.cginc" // Get standard Unity constants
struct v2f
{
float4 pos : POSITION;
float4 color : COLOR0;
float4 uv : TEXCOORD0;
float fog : FOGC;
};
uniform float4 _Color, _Color2, _WaveX, _WaveZ, _WaveSpeed;
uniform float3 _obstacle;
uniform float _affectDist, _bendAmount;
v2f Vertex(appdata_base v)
{
v2f o;
const float4 _waveXSize = _WaveX * 2;
const float4 _waveZSize = _WaveZ * 2;
const float4 waveSpeed = _WaveSpeed * 4;
float4 _waveXmove = _waveXSize * waveSpeed * 25;
float4 _waveZmove = _waveZSize * waveSpeed * 25;
// Calculate the wind input to leaves from their vertex positions....
float3 worldPos = mul ((float3x4)_Object2World, v.vertex);
// OBSTACLE AVOIDANCE CALC
float3 bendDir = normalize (float3(worldPos.x,0,worldPos.z) - float3(_obstacle.x,0,_obstacle.z));//direction of obstacle bend
float distLimit = _affectDist;// how far away does obstacle reach
float distMulti = (distLimit-min(distLimit,distance(float3(worldPos.x,0,worldPos.z),float3(_obstacle.x,0,_obstacle.z))))/distLimit; //distance falloff
//OBSTACLE AVOIDANCE END
// This is the input to the sinusiodal warp
float4 waves;
waves = worldPos.x * _waveXSize;
waves += worldPos.z * _waveZSize;
// Add in time to model them over time
waves += _Time.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.texcoord.y;
s *= waveAmount;
// Faste winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float fade = dot (v.texcoord.y * v.texcoord.y, 2);
s = s * s;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
v.vertex.xz += bendDir.xz * distMulti * v.texcoord.y * v.texcoord.y * _bendAmount; //ADD OBSTACLE BENDING
o.pos = mul(glstate.matrix.mvp, v.vertex);
o.fog = o.pos.w;
o.uv = v.texcoord;
o.color = lerp (_Color, _Color2, fade.xxxx);
return o;
}
ENDCG
AlphaTest Greater [_Cutoff]
Cull Off
}
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
Blend SrcAlpha oneMinusSrcAlpha
AlphaTest Greater [_Cutoff]
Cull Off
color [_Color]
ZTest Less
}
}
} |
This script is attached to a cube that acts as my obstacle. I've rigged it up so that it increases how far it affects the grass and how much the grass bends when you're pressing the Jump button.
| Code: | #pragma strict
@script ExecuteInEditMode
var affectDist : float = 8;
var bendAmount : float = 5;
private var myTransform : Transform;
function Awake()
{
SetBend();
myTransform = transform;
}
function Update() : void
{
Shader.SetGlobalVector("_obstacle", myTransform.position);
if (Input.GetButton("Jump"))
{
if (affectDist < 22)
{
affectDist += 3;
bendAmount += 0.3;
SetBend(affectDist, bendAmount);
}
if (affectDist > 20)
{
affectDist = 20;
bendAmount = 6.2;
SetBend(affectDist, bendAmount);
}
}
else
{
if (affectDist > 8)
{
affectDist -= 4;
bendAmount -= 0.6;
SetBend(affectDist, bendAmount);
}
else
{
SetBend();
}
}
}
function SetBend(_affectDist : float, _bendAmount : float) : void
{
Shader.SetGlobalFloat("_affectDist", _affectDist);
Shader.SetGlobalFloat("_bendAmount", _bendAmount);
}
function SetBend() : void
{
SetBend(8, 5);
} |
IMPORTANT: The values here are set to blades of grass that are approximately 1 unit wide and 8 units tall or so. It's very important that the grass blade mesh has UV coordinates such that the grass blade looks "upright," which a planar projection along the Z would get you. A screenshot is attached. Note, that cube is a default cube created by Unity.
_________________ /////////////////////////
God at play - http://www.godatplay.com
Part of the Intuition collective
Portfolio
@godatplay
///////////////////////// |
|
| Back to top |
|
|
larzie
Joined: 18 Mar 2008 Posts: 34 Location: Copenhagen
|
Posted: Sat Jul 25, 2009 6:54 pm Post subject: |
|
|
|
I am having trouble getting the shader to work. When I use the shader on my planes no color is added and they remain invisible. Would it be possible by any chance for you to upload the Unity project?
many thanks,
Lars
|
|
| Back to top |
|
|
showoff

Joined: 28 Apr 2009 Posts: 170 Location: Atlanta, Ga
|
Posted: Tue Aug 04, 2009 12:19 am Post subject: |
|
|
|
Im also having problems with the shader aswell. I cant seem to get either of the shaders working either.
_________________ ________________________________
3D Graphic Artist
http://www.andresmaximumcgi.com/
________________________________ |
|
| Back to top |
|
|
God at play

Joined: 03 Nov 2006 Posts: 105 Location: Des Moines, IA
|
Posted: Fri Aug 14, 2009 10:18 pm Post subject: |
|
|
|
I've attached the waves.cginc file, which I have in my Materials folder along with the shader.
Dynamic Grass shader applied as a material to grass blade meshes with UV coordinates with optional bending on the y:
| Code: | Shader "Dynamic Grass"
{
Properties
{
_Color ("Main Color", Color) = (.055, .094, .082, 1)
_Color2 ("Fade Color", Color) = (.09, .157, .137, 1)
_WaveX ("Wave X", Vector) = (.07, .01, .01, 0.01)
_WaveZ ("Wave Z", Vector) = (-.07, .01, .01, 0.01)
_WaveSpeed ("Wave Speed", Vector) = (1, 1.5, 1.1, .9)
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
Lighting On
CGPROGRAM
#pragma vertex Vertex
#include "waves.cginc" // Get in the helper wave functions
#include "UnityCG.cginc" // Get standard Unity constants
struct v2f
{
float4 pos : POSITION;
float4 color : COLOR0;
float4 uv : TEXCOORD0;
float fog : FOGC;
};
uniform float4 _Color, _Color2, _WaveX, _WaveZ, _WaveSpeed;
uniform float3 _obstacle;
uniform float _affectDist, _bendAmount;
v2f Vertex(appdata_base v)
{
v2f o;
const float4 _waveXSize = _WaveX * 2;
const float4 _waveZSize = _WaveZ * 2;
const float4 waveSpeed = _WaveSpeed * 4;
float4 _waveXmove = _waveXSize * waveSpeed * 25;
float4 _waveZmove = _waveZSize * waveSpeed * 25;
// Calculate the wind input to leaves from their vertex positions....
float3 worldPos = mul ((float3x4)_Object2World, v.vertex);
// OBSTACLE AVOIDANCE CALC
float3 bendDir = normalize (float3(worldPos.x,worldPos.y,worldPos.z) - float3(_obstacle.x,_obstacle.y,_obstacle.z));//direction of obstacle bend
float distLimit = _affectDist;// how far away does obstacle reach
float distMulti = (distLimit-min(distLimit,distance(float3(worldPos.x,worldPos.y,worldPos.z),float3(_obstacle.x,_obstacle.y,_obstacle.z))))/distLimit; //distance falloff
//OBSTACLE AVOIDANCE END
// This is the input to the sinusiodal warp
float4 waves;
waves = worldPos.x * _waveXSize;
waves += worldPos.z * _waveZSize;
// Add in time to model them over time
waves += _Time.x * waveSpeed;
float4 s, c;
waves = frac (waves);
FastSinCos (waves, s,c);
float waveAmount = v.texcoord.y;
s *= waveAmount;
// Faste winds move the grass more than slow winds
s *= normalize (waveSpeed);
s = s * s;
float fade = dot (v.texcoord.y * v.texcoord.y, 2);
s = s * s;
float3 waveMove = float3 (0,0,0);
waveMove.x = dot (s, _waveXmove);
waveMove.z = dot (s, _waveZmove);
v.vertex.xz -= mul ((float3x3)_World2Object, waveMove).xz;
v.vertex.xz += bendDir.xz * distMulti * v.texcoord.y * v.texcoord.y * _bendAmount; //ADD OBSTACLE BENDING
//optional y bending
//v.vertex.xyz += bendDir.xyz * distMulti * v.texcoord.y * v.texcoord.y * _bendAmount; //ADD OBSTACLE BENDING
o.pos = mul(glstate.matrix.mvp, v.vertex);
o.fog = o.pos.w;
o.uv = v.texcoord;
o.color = lerp (_Color, _Color2, fade.xxxx);
return o;
}
ENDCG
AlphaTest Greater [_Cutoff]
Cull Off
}
}
SubShader
{
Tags { "Queue" = "Transparent" }
Pass
{
Blend SrcAlpha oneMinusSrcAlpha
AlphaTest Greater [_Cutoff]
Cull Off
color [_Color]
ZTest Less
}
}
} |
Bend affect script attached to obstacle object:
| Code: | #pragma strict
@script ExecuteInEditMode
var affectDist : float = 20;
var bendAmount : float = 5;
private var myTransform : Transform;
function Awake()
{
myTransform = transform;
}
function Update()
{
Shader.SetGlobalVector("_obstacle", myTransform.position);
Shader.SetGlobalFloat("_affectDist", _affectDist);
Shader.SetGlobalFloat("_bendAmount", _bendAmount);
} |
| Description: |
|
 Download |
| Filename: |
waves.cginc.zip |
| Filesize: |
1.21 KB |
| Downloaded: |
228 Time(s) |
_________________ /////////////////////////
God at play - http://www.godatplay.com
Part of the Intuition collective
Portfolio
@godatplay
///////////////////////// |
|
| Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|