Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sagarpatel/376ed0b42211a65db0ebdb71b91b7617 to your computer and use it in GitHub Desktop.
Save sagarpatel/376ed0b42211a65db0ebdb71b91b7617 to your computer and use it in GitHub Desktop.
Using surface shader with compute buffers
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Custom/CS_GeneratedMesh_VertexID_Surf"
{
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
_SpawnColAudioColMix("Spawn Col vs Audio Col Mix", Range(0,1)) = 1.0
_TextureScaleX("TextureScale X", Range(0,1)) = 1.0
_TextureScaleY("TextureScale Y", Range(0,1)) = 1.0
_SimSpeed("Sim Speed", float) = 1
_GeneratedMesh_VertexCount("_Generated Mesh Vertex Count", int) = 24 // 24 for unity default cube
_GeneratedMesh_BaseScaler("Generated Mesh Base Scaler", Range(0,10)) = 1.0
_GeneratedMesh_YScaler("Generated Mesh Y Scaler", Range(0,1)) = 1.0
_SpawnColorScaler("Spawn Color Scaler", Range(0,4)) = 1.0
_LiveAudioColorScaler("Live Audio Scaler", Range(0,4)) = 1.0
_FinalColorScaler("Final Color Scaler", Range(0,4)) = 1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
//Cull Off
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
//#pragma surface surf Standard fullforwardshadows vertex:vert
#pragma surface surf Standard addshadow vertex:vert
//#pragma multi_compile_instancing
#pragma target 5.0
#include "UnityCG.cginc"
#ifdef SHADER_API_D3D11
StructuredBuffer<float4> _Positions;
StructuredBuffer<float4> _Colors;
StructuredBuffer<float4> _Velocities;
StructuredBuffer<float4> _ForwardVectors;
StructuredBuffer<float4> _UpVectors;
StructuredBuffer<uint> _ParticlesToSpawnIDs; // bad name, should be ToDraw
#endif
sampler2D _MainTex;
half _SpawnColAudioColMix;
half _TextureScaleX;
half _TextureScaleY;
half _SimSpeed;
int _GeneratedMesh_VertexCount;
half _GeneratedMesh_BaseScaler;
half _SpawnColorScaler;
half _LiveAudioColorScaler;
half _FinalColorScaler;
half _GeneratedMesh_YScaler;
// struct for vertex input data
struct appdata_id
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
uint id : SV_VertexID;
};
struct Input
{
float2 uv_MainTex;
float4 col;
};
void vert(inout appdata_id v, out Input o)
{
float3 vertexPos = v.vertex.xyz;
UNITY_INITIALIZE_OUTPUT(Input, o);
#ifdef SHADER_API_D3D11
// setup base data
int meshID = v.id / _GeneratedMesh_VertexCount;
uint particleID = _ParticlesToSpawnIDs[(uint)meshID];
float4 posData = _Positions[particleID];
float4 colData = _Colors[particleID];
float4 velData = _Velocities[particleID];
float4 upVecData = _UpVectors[particleID];
float3 particleWorldPos = posData.xyz;
float speed = length(velData.xyz);
// calcualte particle life and scale
float lifeRemaining = max(0, posData.w);
float maxLife = upVecData.w;
float lifeRatio = min((lifeRemaining / maxLife), 1);
float spriteScale = lifeRatio * velData.w;
// calculate particle color
float2 audioColUV = float2(_TextureScaleX, _TextureScaleY * (1.0 - lifeRatio)); //+ IN.idOffset));
float lifeColScaler = 1.0; //max((lifeRatio + 0.17), 0.5);
float4 audioCol = lifeColScaler * tex2Dlod(_MainTex, float4(audioColUV, 0, 0));
float4 spawnedCol = colData;
//float4 mixedCol = lerp(spawnedCol * _SpawnColorScaler, audioCol * _LiveAudioColorScaler, _SpawnColAudioColMix);
float4 mixedCol = spawnedCol * _SpawnColorScaler + pow((0.50 + audioCol * _LiveAudioColorScaler), 2) * _SpawnColAudioColMix;
o.col = mixedCol;
// calculate particle rotaiton
float3 normedVel = normalize(velData).xyz;
float3 pDir = normedVel;
//pDir = float3(0, 0, 1);
float3 upDir = upVecData.xyz; //float3(0, 1, 0);
//upDir = float3(0, 1, 0);
// tried, got this from http://stackoverflow.com/questions/18558910/direction-vector-to-rotation-matrix
float3 xAxis = normalize(cross(upDir, pDir));
float3 yAxis = normalize(cross(pDir, xAxis));
matrix forwardRotMat = matrix( xAxis.x, yAxis.x, pDir.x, 0,
xAxis.y, yAxis.y, pDir.y, 0,
xAxis.z, yAxis.z, pDir.z, 0,
0, 0, 0, 1);
// speed boost scale
vertexPos.y *= _GeneratedMesh_YScaler;
vertexPos.z *= pow(1.0 + abs(0.5*speed) * abs(0.5*_SimSpeed), 2);
// set particle scale
// apply base mesh scaling
vertexPos *= _GeneratedMesh_BaseScaler; // scale
vertexPos *= spriteScale;
// set particle world pos
//vertexPos = particleWorldPos + mul(UNITY_MATRIX_VP, mul(forwardRotMat, vertexPos)) ;
//vertexPos = particleWorldPos + vertexPos;
//vertexPos += particleWorldPos;
vertexPos = mul(forwardRotMat, vertexPos);
vertexPos += particleWorldPos ;
v.normal = mul(forwardRotMat, v.normal);
#endif
//v.vertex.xyz = mul( transpose(UNITY_MATRIX_VP), vertexPos);
v.vertex.xyz = vertexPos;
}
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = IN.col; //tex2D (_MainTex, IN.uv_MainTex) * _Color;
//c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb * _FinalColorScaler;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment