Page 1 of 1

Add Pass to Standard Shader

PostPosted: Thu Mar 01, 2018 6:11 am
by Rob_Positomic
Hi all,

I have been able to combine the Curved World Asset with ASE and get it to work. However, I need the Curved World vertex offset to apply after the surface shading occurs.I believe I need to add a new Pass to the Shader for this; and to make sure that I can still edit in ASE; this should be done using a template.

I'm curious to confirm this is the right approach, and if anyone has done something similar - or can give me a rough guide as to what I need to do to pull this together.

Re: Add Pass to Standard Shader

PostPosted: Thu Mar 01, 2018 12:49 pm
by Ricardo Teixeira
Rob_Positomic wrote:Hi all,

I have been able to combine the Curved World Asset with ASE and get it to work. However, I need the Curved World vertex offset to apply after the surface shading occurs.I believe I need to add a new Pass to the Shader for this; and to make sure that I can still edit in ASE; this should be done using a template.
I'm curious to confirm this is the right approach, and if anyone has done something similar - or can give me a rough guide as to what I need to do to pull this together.


Hello Rob,

Thank you for getting in touch, we would be happy to help!

I must admit that I'm not entirely familiar with Curved World, or its specific requirements, but our users seem to be using it without a custom template. Are you looking to implement a specific feature or technique that we should be aware of?

If you are comfortable with shader programming, a template is the most flexible solution; in the end it really depends on your specific requirements.

You can use Curve World by adding its cginc and using a simple custom expression, check the link bellow for additional information.

Curve World Shaders with ASE

Multi-pass support, along with relevant template samples, will be available soon.

Looking forward to your reply!

Re: Add Pass to Standard Shader

PostPosted: Sun Mar 04, 2018 5:49 am
by Rob_Positomic
Thanks Ricardo,

I'm not very proficient with shaders; but from what I understand, Curved World is a vertex shader which manipulates the position of mesh vertices so that the meshes "curve over a horizon" the further they are from the viewer. I have already been able to implement using the instructions given. This results in the vertex being manipulated before the surface shading is applied - this is probably fine for 99% of use cases.

In my case, the problem is that I have built a terrain shader which looks at the height of a vertex to determine if it should apply a 'land' or 'water' texture. Because the vertex offset calculation is applied prior to the surface shader logic, this results in a bug where underwater textures are being applied and visible on the sides of mountains the distance.

I think that when multi-pass support is available, and the templates as examples are available, that should help me to fix my problem :) Looking forward to it.

Re: Add Pass to Standard Shader

PostPosted: Mon Mar 05, 2018 4:12 pm
by Ricardo Teixeira
Rob_Positomic wrote:Thanks Ricardo,

I'm not very proficient with shaders; but from what I understand, Curved World is a vertex shader which manipulates the position of mesh vertices so that the meshes "curve over a horizon" the further they are from the viewer. I have already been able to implement using the instructions given. This results in the vertex being manipulated before the surface shading is applied - this is probably fine for 99% of use cases.

In my case, the problem is that I have built a terrain shader which looks at the height of a vertex to determine if it should apply a 'land' or 'water' texture. Because the vertex offset calculation is applied prior to the surface shader logic, this results in a bug where underwater textures are being applied and visible on the sides of mountains the distance.

I think that when multi-pass support is available, and the templates as examples are available, that should help me to fix my problem :) Looking forward to it.


Hello,

I wish I had some additional information to add but, as I mentioned, I'm not too familiar with all the Curve World requirements.

Can you share your shader for further examination on our side?

I'll keep you posted on any multi-pass related developments.

Thanks!

Re: Add Pass to Standard Shader

PostPosted: Wed Mar 07, 2018 12:23 pm
by Rob_Positomic
A bit hard to post the entire shader, but this is the main part.

The bottom section "slope exposure" is at the end of the land based texture calculations. The top section "water level.." figures out what sort of texture to apply to a mesh when the height is roughly around or below 0. And will override anything come out of the land area in that case. As you can see I have configured the CurvedWorldShader as per the instructions on your site

TerrainShader.png
TerrainShader.png (238.64 KiB) Viewed 3650 times


Here is the outcome; when we're up close - without any curved world bending occurring; the beachline is at the appropriate height (note its position comparative to the trees)
Mountain-Close.png
Mountain-Close.png (223.61 KiB) Viewed 3650 times


However, as we draw backwards; the beachline "rises" up the mountain, as the Curved World Shader starts to manipulate the vertices:
Mountain-Distant.png
Mountain-Distant.png (167.98 KiB) Viewed 3650 times


The code generated by ASE applies the Curved World function ("vertexDataFunc") in the "v2f"; and then afterwards the surface shading ("surf") in the frag function. I understand that this is the appropriate order of operations for a shader, so not disputing that at all. I believe I need to take the "vertexDataFunc" and all its related code out of the first pass, and add it into a second pass to get the effect I'm after.

However if there's another way; Id be glad to hear it :)


Code: Select all
         v2f vert( appdata_full v )
         {
            v2f o;
            UNITY_SETUP_INSTANCE_ID( v );
            UNITY_INITIALIZE_OUTPUT( v2f, o );
            UNITY_TRANSFER_INSTANCE_ID( v, o );
            Input customInputData;
            vertexDataFunc( v, customInputData );
            float3 worldPos = mul( unity_ObjectToWorld, v.vertex ).xyz;
            fixed3 worldNormal = UnityObjectToWorldNormal( v.normal );
            o.worldNormal = worldNormal;
            o.customPack1.xy = customInputData.uv_texcoord;
            o.customPack1.xy = v.texcoord;
            o.worldPos = worldPos;
            TRANSFER_SHADOW_CASTER_NORMALOFFSET( o )
            return o;
         }
         fixed4 frag( v2f IN
         #if !defined( CAN_SKIP_VPOS )
         , UNITY_VPOS_TYPE vpos : VPOS
         #endif
         ) : SV_Target
         {
            UNITY_SETUP_INSTANCE_ID( IN );
            Input surfIN;
            UNITY_INITIALIZE_OUTPUT( Input, surfIN );
            surfIN.uv_texcoord = IN.customPack1.xy;
            float3 worldPos = IN.worldPos;
            fixed3 worldViewDir = normalize( UnityWorldSpaceViewDir( worldPos ) );
            surfIN.worldPos = worldPos;
            surfIN.worldNormal = IN.worldNormal;
            SurfaceOutputStandard o;
            UNITY_INITIALIZE_OUTPUT( SurfaceOutputStandard, o )
            surf( surfIN, o );
            #if defined( CAN_SKIP_VPOS )
            float2 vpos = IN.pos;
            #endif
            SHADOW_CASTER_FRAGMENT( IN )
         }

Re: Add Pass to Standard Shader

PostPosted: Wed Mar 07, 2018 1:09 pm
by Ricardo Teixeira
Greetings,

Thank you for the additional information, I really appreciate it.

Unfortunately, I'm a bit overloaded at the moment; I will have to examine the Curve world package in order to determine how they handle this type of situations. Is there any chance you can share your actual shader via PM?

Thanks!