I have been trying out a grass compute shader by minionsart from patreon and it works awesome in pc but even though my mobile supports compute shaders, The grass appears pink on a sphere with no wind sway while it should have been all over a plane moving with the wind. if the shader code is important in analyzing this, please tell me.
Here are some images…
Did you try in windows standalone build?
If not there put the shader in always included shaders
Mobile often can’t handle as many thread groups etc as desktop. My guess is you exceeded a limit. SystenInfo has methods to check all the limits for the platform.
Yes but the shader works fine when put in unity remote in my mobile but when i build the games apk, this happens.
It works fine in the windows standalone build.
and by the way, I use URP (LWRP)
URP or LWRP?
And what unity version? Tried the latest lts already?
Oh wait, do you use vulkan? openGL doesn’t support compute shaders well
Just in case you’re not aware Unity Remote doesn’t actually run your application on your mobile device. Instead it’s running your application on your PC and simply passing the rendered output of the PC to the mobile device and the inputs of the mobile device back to the PC.
You could also check Shader.isSupported
You should check the device logs - there should be a message that details what didn’t work out.
I use URP unity 2021.3.4f1 and after you posted this, i found that vulcan wasn’t added to my graphics api list in project settings so when I tried to put it on, unity crashed.
Oh… I didn’t know that since i’m a beginner to developing to mobile.
I will try that.
Yes you are right… I found the device log via command prompt and this is the error GLSL link error: The number of vertex shader storage blocks (1) is greater than the maximum number allowed (0).
How do I fix this?
You can’t fix this using this shader. The message says “your GPU cannot read data from ComputeBuffers in Vertex Shaders”. You’ll need a different implementation of the effect.
You can check whether it’s supported on the given hardware by checking https://docs.unity3d.com/ScriptReference/SystemInfo-maxComputeBufferInputsVertex.html
The error above is from one of the grass shader files. Here is the code.
Shader "Custom/GrassComputeHLSL"
{
Properties
{
[Toggle(BLEND)] _BlendFloor("Blend with floor", Float) = 0
_Fade("Top Fade Offset", Range(-1,10)) = 0
_AmbientAdjustment("Ambient Adjustment", Range(-1,10)) = 0
}
HLSLINCLUDE
// Include some helper functions
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
// This describes a vertex on the generated mesh
struct DrawVertex
{
float3 positionWS; // The position in world space
float2 uv;
float3 diffuseColor;
};
// A triangle on the generated mesh
struct DrawTriangle
{
float3 normalOS;
DrawVertex vertices[3]; // The three points on the triangle
};
// A buffer containing the generated mesh
StructuredBuffer<DrawTriangle> _DrawTriangles;
struct v2f
{
float4 positionCS : SV_POSITION; // Position in clip space
float2 uv : TEXCOORD0; // The height of this vertex on the grass blade
float3 positionWS : TEXCOORD1; // Position in world space
float3 normalWS : TEXCOORD2; // Normal vector in world space
float3 diffuseColor : COLOR;
float fogFactor : TEXCOORD5;
};
float4 _TopTint;
float4 _BottomTint;
float _Fade;
float4 _PositionMoving;
float _OrthographicCamSize;
float3 _OrthographicCamPos;
uniform sampler2D _TerrainDiffuse;
float _AmbientAdjustment;
// ----------------------------------------
// Vertex function
// -- retrieve data generated from compute shader
v2f vert(uint vertexID : SV_VertexID)
{
// Initialize the output struct
v2f output = (v2f)0;
// Get the vertex from the buffer
// Since the buffer is structured in triangles, we need to divide the vertexID by three
// to get the triangle, and then modulo by 3 to get the vertex on the triangle
DrawTriangle tri = _DrawTriangles[vertexID / 3];
DrawVertex input = tri.vertices[vertexID % 3];
output.positionCS = TransformWorldToHClip(input.positionWS);
output.positionWS = input.positionWS;
float3 faceNormal = GetMainLight().direction * tri.normalOS;
output.normalWS = TransformObjectToWorldNormal(faceNormal, true);
float fogFactor = ComputeFogFactor(output.positionCS.z);
output.fogFactor = fogFactor;
output.uv = input.uv;
output.diffuseColor = input.diffuseColor;
return output;
}
// ----------------------------------------
// Fragment function
half4 frag(v2f i) : SV_Target
{
// For Shadow Caster Pass
#ifdef SHADERPASS_SHADOWCASTER
return 0;
#else
// For Color Pass
// rendertexture UV for terrain blending
float2 uv = i.positionWS.xz - _OrthographicCamPos.xz;
uv = uv / (_OrthographicCamSize * 2);
uv += 0.5;
// get ambient color from environment lighting
float4 ambient =float4(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w,1); //float4(ShadeSH9(float4(0,0,1,1)),0);
float shadow = 0;
#if BLEND
shadow = 1;
#endif
half4 shadowCoord = TransformWorldToShadowCoord(i.positionWS);
#if _MAIN_LIGHT_SHADOWS_CASCADE || _MAIN_LIGHT_SHADOWS
Light mainLight = GetMainLight(shadowCoord);
shadow = mainLight.shadowAttenuation;
#else
Light mainLight = GetMainLight();
#endif
// extra point lights support
float3 extraLights;
int pixelLightCount = GetAdditionalLightsCount();
for (int j = 0; j < pixelLightCount; ++j) {
Light light = GetAdditionalLight(j, i.positionWS, half4(1, 1, 1, 1));
float3 attenuatedLightColor = light.color * (light.distanceAttenuation * light.shadowAttenuation);
extraLights += attenuatedLightColor;
}
// fade over the length of the grass
float verticalFade = saturate(i.uv.y + _Fade);
extraLights *= verticalFade;
// colors from the tool with tinting from the grass script
float4 baseColor = lerp(_BottomTint , _TopTint,verticalFade) * float4(i.diffuseColor, 1);
// get the floor map
float4 terrainForBlending = tex2D(_TerrainDiffuse, uv);
float4 final = float4(0,0,0,0);
#if BLEND
_TopTint = _TopTint * ambient;
// tint the top blades and add in light color
terrainForBlending = lerp(terrainForBlending,terrainForBlending+ ( _TopTint* float4(i.diffuseColor, 1)) , verticalFade);
final = lerp((terrainForBlending) * shadow , terrainForBlending, shadow);
// add in ambient and attempt to blend in with the shadows
final += lerp((ambient * terrainForBlending) * _AmbientAdjustment, 0,shadow);
#else
final = baseColor;
// add in shadows
final *= shadow;
// if theres a main light, multiply with its color and intensity
final *= float4(mainLight.color,1);
// add in ambient
final += (ambient * baseColor) ;
#endif
final += float4(extraLights,1);
// fog
float fogFactor = i.fogFactor;
// Mix the pixel color with fogColor.
final.rgb = MixFog(final.rgb, fogFactor);
return final;
#endif // SHADERPASS_SHADOWCASTER
}
ENDHLSL
SubShader {
// UniversalPipeline needed to have this render in URP
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" "IgnoreProjector" = "True" }
// Forward Lit Pass
Pass
{
Name "ForwardLit"
Tags { "LightMode" = "UniversalForward" }
Cull Off // No culling since the grass must be double sided
HLSLPROGRAM
// Signal this shader requires a compute buffer
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 5.0
// Lighting and shadow keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _ADDITIONAL_LIGHTS
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
#pragma multi_compile_fog
#pragma shader_feature BLEND
// Register our functions
#pragma vertex vert
#pragma fragment frag
ENDHLSL
}
// Shadow Casting Pass
Pass
{
Name "ShadowCaster"
Tags { "LightMode" = "ShadowCaster" }
ZWrite On
ZTest LEqual
Cull Off
HLSLPROGRAM
// Signal this shader requires geometry function support
#pragma prefer_hlslcc gles
#pragma exclude_renderers d3d11_9x
#pragma target 5.0
// Support all the various light ypes and shadow paths
#pragma multi_compile_shadowcaster
// Register our functions
#pragma vertex vert
#pragma fragment frag
// A custom keyword to modify logic during the shadow caster pass
#define SHADERPASS_SHADOWCASTER
#pragma shader_feature_local _ DISTANCE_DETAIL
ENDHLSL
}
}
}
Oh ok then… I will try to change the implementation.
Using vulkan under android might fix this right?
@codevisionary005 did you add vulkan under android or desktop? You can use it for android and use automatic for desktop
@DevDunk Right, it should work on Vulkan if the ComputeBuffer is read-only.
One alternative is to use a RenderTexture instead of a ComputeBuffer. They are less flexible to work with, but reading from textures on vertex shaders should be supported on ES 3.0 and up.
I tried to, but wheneven I add vulcan, Unity crashes.
The ComputeBuffer is read-only but as I said earlier, I couldn’t add vulcan since unity crashes.
Do you have any resources for RenderTexture? Because i’m new to shader programming and i’m do not know if it could help me generate grass blades as the computebuffer does.
But unity shouldn’t crash if you change the android API. Unity itself should still run in dx11 in that case. Do make a bug report (after trying the latest LTS of your unity version) for it since it shouldn’t happen
Good news. After @DevDunk told me to try the latest LTS of my unity version, I tried it. It didn’t work, but then I tried 2021.3.0f1 which is a version older than what I currently use, The shader now works! Thank you for all your help, I will be changing the thread’s tag to resolved.