- Home /
Cubemap Diffuse / Heightmap Shader Issues.
I'm trying to code a shader that uses two cubemaps, one for diffuse and one for vertex deformation. There going to be used on a quad sphere.
My shader skills are yet to be...refined shall we say. I can grasp the basic logic but I still need to get my head around how these things work...
From what I understand about shaders, I managed to combine and modify what I could to get this result...
Shader "Custom/Test"
{
Properties
{
_CubeDiffuse ("Cubemap Diffuse Map", CUBE) = "" {}
_CubeHeight ("Cubemap Height Map", CUBE) = "" {}
_Amount ("Extrusion Amount", Range(-1,1)) = 0.5 //PROBLEM2 - This should act as a multiplier for _CubeHeight rather than a dedicated setting.
}
SubShader
{
Tags { "RenderType" = "Opaque" }
CGPROGRAM
#pragma surface surf Lambert vertex:vert
struct Input
{
float3 worldRefl; //PROBLEM 1 - I this this input is causing the diffuse to distort like a reflective cubemap would.
};
float _Amount; //PROBLEM2 - I need this 'Amount' to read the values from _CubeHeight not _Amount.
void vert (inout appdata_full v)
{
v.vertex.xyz += v.normal * _Amount;
}
samplerCUBE _CubeDiffuse;
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = texCUBE (_CubeDiffuse, IN.worldRefl).rgb; //PROBEM 1 - It's applied here.
}
ENDCG
}
Fallback "Diffuse"
}
The diffuse part works, but it acts like a reflection cube map and distorts as the object rotates. And adjusting the 'Amount' value leads to every vertex moving the exact same amount as expected.
Problem1 - I need to solve the distortion issue.
Problem2 - I need the amount value to read from the greyscale value of the _CubeHeight Texture.
I've searched everywhere on the net for something similar and found this one shader which takes care of the diffuse but not the vertex deformation. And it also does not respond to lighting...
Shader "Custom/PlanetShader"
{
Properties
{
_CubeTex("Cubemap", CUBE) = "" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
samplerCUBE _CubeTex;
struct appdata_t
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 vertex : POSITION;
float3 texcoord : TEXCOORD0;
};
v2f vert(appdata_t v)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
OUT.texcoord = v.normal;
return OUT;
}
half4 frag(v2f IN) : COLOR
{
return texCUBE(_CubeTex, IN.texcoord);
}
ENDCG
}
}
FallBack "Diffuse"
}
Any help or guidance would be greatly appreciated.
Ok - so you want to not use a reflection vector for the cubemap sample I guess, just the normal, (because that's what the second shader does).
The following is a total guess as I don't have a rig to test it:
Shader "Custom/Test"
{
Properties
{
_CubeDiffuse ("Cubemap Diffuse $$anonymous$$ap", CUBE) = "" {}
_CubeHeight ("Cubemap Height $$anonymous$$ap", CUBE) = "" {}
_Amount ("Extrusion Amount", Range(-1,1)) = 0.5 //PROBLE$$anonymous$$2 - This should act as a multiplier for _CubeHeight rather than a dedicated setting.
}
SubShader
{
Tags { "RenderType" = "Opaque" }
CGPROGRA$$anonymous$$
#pragma surface surf Lambert vertex:vert
samplerCUBE _CubeDiffuse;
samplerCUBE _CubeHeight;
float _Amount;
struct Input
{
float3 normal; //PROBLE$$anonymous$$ 1 - I this this input is causing the diffuse to distort like a reflective cubemap would.
};
void vert (inout appdata_full v)
{
v.vertex.xyz += v.normal * texCUBE(_CubeHeight, v.normal).r;
}
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = texCUBE (_CubeDiffuse, IN.normal).rgb;
}
ENDCG
}
Fallback "Diffuse"
}
Ok scratch that - spotted the definitions I was missing and have updated the comment.
Thanks, I'll try this out and let you know how it goes!
No such luck, I don't think it likes the 'normal' stuff, and it seems to throwing up at line 31. Hmm, it's for an FYP so, I guess I'll just have to work around it and write down other methods.
There's some platforms that don't support samplers in the vertex shader - that may go double for cube samplers...
Answer by Matthew Scott · Apr 29, 2013 at 10:19 PM
Well, this was the idea I had, but I'm running short on time, and I'm not entirely sure it would work.
For every vertice in the quad sphere mesh, I need to get the colour of the height map at that particular point and move it vector3.up a said amount depending on the greyscale value of the texture at that point. I can't use vertex colours, so my idea was this.
Each vertex position is in local space so theoretically it should work. At each vertex point, create another point further out in the same direction. From there, ray cast back towards the sphere and retrieve the uv co-oords of the texture at the hit point. From these uv co-oords I hope to retrieve the colour of the pixel in that texture uv location and then move the related vertex by that amount according to my own math...move Vector.up pixel.greyscale heightscale...for e.g.
Am I on the right track here? I've run out of options I can think off..
HAC$$anonymous$$Y! But it got the job done. (Old question but just wanted to clear that up...
Your answer
Follow this Question
Related Questions
How do I update the collider mesh based on the shader vertex deformed mesh? 0 Answers
How can I add the diffuse property to a vertex Shader? 1 Answer
Stitching planes 0 Answers
Simple mesh deformation : Mesh.vertices or vertex shader with displacement texture ? 1 Answer
Raycast on mesh deformed by shader 0 Answers