- Home /
shader based on surface distance from center ?
hello everyone !
Before explaining my question, here's what i'm aiming to: a procedural generated planet starting from a sphere, where perlin noise determine random vertexes heigths.
and this part is working :)
now, i'd like to procedurally apply certain textures, and blending them depending on the surface distance from the center of sphere.
Since shader programming is still completely obscure to me, my main question is "does such a shader exist / where should i start trying to modify an existing one" Or a good hint on which nodes to riddle with in the wonderful Strumpy Shader Editor :)
I'll thank you in advance, but snippet of shaders code with "try to adapt from this" really won't help me at the moment, since i plan studying shaders a bit later on.
thank you for your time :)
Answer by syclamoth · Mar 20, 2012 at 09:44 PM
Completely possible, given that you have access to all the information needed! Here's the relevant pages, since you don't want me writing your shader for you (and I don't really have time right now anyway...)
Add 'worldPos' to your input structure (at the bottom)
Add a 'centrePos' vector4 to the properties (modify this in a script)
Then, in your shader you can use some variant of the line
output.albedo = lerp(sand.rgb, rock.rgb, distance(centrePos.xyz, worldPos.xyz));
Here, I've made up something to start you off. This only has two textures, but it should be possible to extend this to include more.
Shader "Custom/DistanceLerp" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_ChangePoint ("Change at this distance", Float) = 3
_OuterTex ("Base (RGB)", 2D) = "black" {}
_CentrePoint ("Centre", Vector) = (0, 0, 0, 0)
_BlendThreshold ("Blend Distance", Float) = 0.5
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
float _ChangePoint;
float4 _CentrePoint;
sampler2D _OuterTex;
float _BlendThreshold;
struct Input {
float2 uv_MainTex;
float3 worldPos;
};
void surf (Input IN, inout SurfaceOutput o) {
half4 main = tex2D (_MainTex, IN.uv_MainTex);
half4 outer = tex2D (_OuterTex, IN.uv_MainTex);
float startBlending = _ChangePoint - _BlendThreshold;
float endBlending = _ChangePoint + _BlendThreshold;
float curDistance = distance(_CentrePoint.xyz, IN.worldPos);
float changeFactor = saturate((curDistance - startBlending) / (_BlendThreshold * 2));
half4 c = lerp(main, outer, changeFactor);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
Also, if you want to work with shaders, have a read up of the CG standard library. There's absolutely no documentation for this in the Unity docs, only unity-specific stuff- so not many people actually know what the language even is!
thanks :)
i'm giving a read to these pages right now, hoping the shader snippet will look less obscure to me later.
(ok, it's pretty straightforward, reading it again... but sadly my best option would be to paste it with a wild guess in the first shader i see in my project :) btw, thank you again, and feel free to dump anything comes to your $$anonymous$$d, to help understand how to do it by myself.
So, do you or do you not want me to write this shader for you? When I have the time I can, but I though you wanted to do it yourself? You'll learn more if you try, at least.
actually, I don't $$anonymous$$d at all if you could drop a few comments in the shader code, just to speed up my understanding :) since even if i read some documentation, i still have no idea from where to start, so your kindness would be twice as appreciated :) of course take your time, and thank you again !
Ok! This sounds fun. I'll mix one up for you when I get home, give you something to start off with.
Answer by vikvega · Mar 21, 2012 at 05:49 AM
thank you so much :) at the moment, I' fiddling in Strumpy Shader Editor, since as I mentioned, I really can't find a way to start a shader from scratch, and tried lerping the distance between WorldPosition and an arbitrary float (which stores the same coordinates of the center of my object) since i can't see something closer to an "object center" node. but I can't really see why it doesn't work like should.
my aim, would be to have a slider, to control the distance threshold of each texture, so i probably need to do some more calculations, than just the difference of distances.
Updated with a new shader! Now I'm working on getting more than two textures in there.
I've played around with strumpy, but in the end it doesn't do anything you can't do yourself, and the generated shaders have a lot of junk in them. I find it useful to mix something up in it, and then have a look at the generated code to work out what it really does.
Hmm. I've been trying as hard as I can, but anything I do trying to get it working with more than 2 textures ends up overrunning the maximum number of registers! You'll have to make do with the 2-texture version, I'm afraid.
you sir, are awesome :) I just woke up, and i'm trying it right after my morning coffee :) you see, the shader editor may leave a lot of garbage in the shader, but still, the visual approach of connecting nodes, seams a lot easeier than writing. I'll start reading something about CG program$$anonymous$$g, thanks to you have a good day, and thank you again for your time, I'll see where I can get from there !
Your answer
Follow this Question
Related Questions
Help with triplanar atlas shader. 2 Answers
shader for 2D mesh with noise transparency at the edge 0 Answers
3D Perlin Noise mesh even in all axes 1 Answer
Material(string) is obsolete. How else can a shader be loaded at runtime? 2 Answers
Efficient code for shortest distance inside a fragment shader 1 Answer