Hi all!
I’ve been developing an atmosphere system and so far have managed to create some decent looking clouds made entirely procedurally, I am using my own particle system.

:-o
Originally, the generated billboards (which all share the same material/shader procural texture (from a texture atlas) so they are batched) were oriented to face the camera CPU side via a script as well as setting vertex colours. I really wanted to have a screen space based orientation to solve the problems of axis flipping as you look down over the top of clouds while moving. Eventually, I made the decision to move these calculations to GPU, letting a shader take care of it.
I started by using the Unity ready made Particles/PreMultiply shader. Then, following this tutorial found here:
http://en.wikibooks.org/wiki/Cg_Programming/Unity/Billboards
I began to integrate this logic into the premultiply shader. But I seem to be having some issues with the MVP, although you can see where the particles are located, the actual imagery is drawn elsewhere.
Before I get to the actual code, I originally assumed this was a problem with scaling the particles before they are sent to the GPU, which was done after mesh creation upon turning each mesh into a prefab. I removed this code and have now realized that the scale must be set in the shader if I am not mistaken. However, this has not resolved this issue. ![]()
Another theory was that is was due to the fact that each particle was set to be a child object of a single game empty, and perhaps that was somehow causing confusion in the shader. So, I removed the code that does this and now each particle is simply its own object again, this however, has still not resolved this issue. ![]()
My last guess, which I can only assume to be the issue after much research is that dynamic batching has a part to play in this. It’s obviously vital that the particles need to remain batched or there really is no point to the whole thing.
Other than that, it must have something to do with “unity_Scale.w”…which I don’t entirely understand where that’s pulling values from. ![]()
I feel as though I am on the right track here but I need a helping hand. Does anybody have an (easy to understand) explanation as to why this is occurring? and how I might go about resolving this? Admittedly, I still have a ways to go in shader experience, but I understand a fair amount. ![]()
I’m not too worried about scaling entirely, I know that I can either keep the original mesh scale and change it dynamically in the shader by multiplying v.vertex.x or y by a _Scale amount. OR, I could just scale the original mesh during it’s creation. Though I think the first option is better if I’m honest, I’d rather not have to rebuild and array of meshes every time I want to change the scale.
Any help or guidance here would be greatly appreciated, I’ve been pulling my hair out for day’s battling with this. It seems crazy to me that I’m having such a big problem with such a small modification to such a simple shader! :lol:
==================================================================
Here is the shader code, with any irrelevant part’s //commented out. This all looks correct to me, so I’m a bit confused…
Shader "Particles/UA Cloud Shader" {
Properties {
_MainTex ("Particle Texture", 2D) = "white" {}
_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
}
Category {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend One OneMinusSrcAlpha
ColorMask RGB
Cull Off Lighting Off ZWrite Off Fog { Mode Off }
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_particles
#include "UnityCG.cginc"
sampler2D _MainTex;
//fixed4 _TintColor;
float _Scale;
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
//#ifdef SOFTPARTICLES_ON
//float4 projPos : TEXCOORD1;
//#endif
};
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_P,
mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0)) +
float4(v.vertex.x, v.vertex.y, 0.0, 0.0));
//#ifdef SOFTPARTICLES_ON
//o.projPos = ComputeScreenPos (o.vertex);
//COMPUTE_EYEDEPTH(o.projPos.z);
//#endif
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
//sampler2D _CameraDepthTexture;
//float _InvFade;
fixed4 frag (v2f i) : COLOR
{
//#ifdef SOFTPARTICLES_ON
//float sceneZ = LinearEyeDepth (UNITY_SAMPLE_DEPTH(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))));
//float partZ = i.projPos.z;
//float fade = saturate (_InvFade * (sceneZ-partZ));
//i.color.a *= fade;
//#endif
return i.color * tex2D(_MainTex, i.texcoord) * i.color.a;
}
ENDCG
}
}
}
}
