Hey,
for a project we need interior mapping for some windows (so it doesn’t break the illusion).
We found a shader based on Unity 4 here (http://www.inear.se/2011/02/interior-mapping-in-unity3d/) and I did my best on getting it to work in Unity 5.
But as my shader (and math) knowledge is rather limited, it currently only works based on the World Position (so if you move the object, the walls stay where they were in the world and don’t move with the object)…
The problem is, that it’s not really nice to use that way. What would be ideal (and what it might have done in the first place) would be, if the position of walls, ceiling and floor depends on the object and not the world position (hope you understand what I mean).
If anyone could help us out here, it would be nice.
Shader
// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
Shader "buildingshader" {
Properties {
_wallFrequencies ("Wall freq", Vector) = (1,1,1)
_ceilingTexture ("Ceiling texture", 2D) = "white" { TexGen EyeLinear }
_floorTexture ("Floor texture", 2D) = "red" { TexGen EyeLinear }
_wallXYTexture ("wallXY texture", 2D) = "black" { TexGen EyeLinear }
_wallZYTexture ("wallZY texture", 2D) = "green" { TexGen EyeLinear }
_noiseTexture( "Noise texture", 2D) = "green" { TexGen EyeLinear }
}
SubShader {
Pass {
CGPROGRAM
#pragma target 3.0
#pragma exclude_renderers xbox360
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos: SV_POSITION;
float2 uv:TEXCOORD0;
float3 positionCopy:TEXCOORD1;
float4 lighting:TEXCOORD2;
};
float3 _wallFrequencies;
float _lightThreshold;
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex) ;
o.uv = v.texcoord /** float2(_uvMultiplier.xy)*/;
o.positionCopy = mul(unity_ObjectToWorld, v.vertex); //float3(v.vertex.xyz);
// Calculate lighting on the exterior of the building with a hard-coded directed light.
float lightStrength = dot(v.normal, float3(0.5, 0.33166, 0.8));
o.lighting = saturate(lightStrength) * float4(1, 1, 0.9, 1) * (1-_lightThreshold);
// Add some ambient lighting.
o.lighting += float4(0.3, 0.3, 0.4, 1);
return o;
}
sampler2D _ceilingTexture;
sampler2D _floorTexture;
sampler2D _wallXYTexture;
sampler2D _wallZYTexture;
sampler2D _noiseTexture;
half4 frag (v2f i) : COLOR
{
//position in object space
float4 objPos = mul(unity_ObjectToWorld, float4(0,0,0,1));
float3 mama = i.positionCopy - objPos.xyz;
float3 direction = i.positionCopy - _WorldSpaceCameraPos;
//multiply by 0.999 to prevent last wall from beeing displayed. Fix this?
float3 corner = floor(i.positionCopy *_wallFrequencies * 0.999);
float3 walls = corner + step(float3(0, 0, 0), direction);
walls /= _wallFrequencies;
corner /= _wallFrequencies;
float3 rayFractions = (float3(walls.x, walls.y,walls.z) - _WorldSpaceCameraPos) / direction;
float2 intersectionXY = (_WorldSpaceCameraPos + rayFractions.z * direction).xy;
float2 intersectionXZ = (_WorldSpaceCameraPos + rayFractions.y * direction).xz;
float2 intersectionZY = (_WorldSpaceCameraPos + rayFractions.x * direction).zy;
float4 ceilingColour = tex2D(_ceilingTexture, intersectionXZ);
float4 floorColour = tex2D(_floorTexture, intersectionXZ);
float4 verticalColour = lerp(floorColour, ceilingColour, step(0, direction.y));
//random texture on wall xy
float zNoise = tex2D(_noiseTexture, float2(corner.z/64,0)).r;
float yNoise = tex2D(_noiseTexture, float2(corner.y/64 + zNoise,0)).r;
float noiseXY = tex2D(_noiseTexture, float2(corner.x/64 + yNoise,0)).r;
noiseXY = floor(noiseXY * 4) / 4;
float2 atlasIndexXY;
atlasIndexXY[0] = floor(noiseXY * 2) / 2;
atlasIndexXY[1] = (noiseXY - atlasIndexXY[0]) * 2;
//put the intersection into room space, so that it comes within [0, 1]
intersectionXY = (intersectionXY - corner.xy) * _wallFrequencies.xy;
//use the texture coordinate to read from the correct texture in the atlas
float4 wallXYColour = 0.8 * tex2D(_wallXYTexture, intersectionXY);
//random texture on wall ZY
float zNoise2 = tex2D(_noiseTexture, float2(corner.z/64,0)).g;
float yNoise2 = tex2D(_noiseTexture, float2(corner.y/64 + zNoise2,0)).g;
float noiseZY = tex2D(_noiseTexture, float2(corner.x/64 + yNoise2,0)).g;
float2 atlasIndexZY;
atlasIndexZY[0] = floor(noiseZY * 2) / 2;
atlasIndexZY[1] = 0;//(noiseZY - atlasIndexZY[0]) * 2;
//put the intersection into room space, so that it comes within [0, 1]
intersectionZY = (intersectionZY - corner.zy) * _wallFrequencies.zy;
//use the texture coordinate to read from the correct texture in the atlas
float4 wallZYColour = 0.8 * tex2D(_wallZYTexture, intersectionZY);
//decide wich wall is closest to camera
float xVSz = step(rayFractions.x, rayFractions.z);
float4 interiorColour = lerp(wallXYColour, wallZYColour, xVSz);
float rayFraction_xVSz = lerp(rayFractions.z, rayFractions.x, xVSz);
//calculate variation in the lighting per room
float3 noises = float3(
tex2D(_noiseTexture, float2(corner.x, corner.y)/64).r,
tex2D(_noiseTexture, float2(corner.z, corner.x)/64).r,
tex2D(_noiseTexture, float2(corner.y, corner.z)/64).r
);
float lightVariation = step((noises.x + noises.y + noises.z)/3, _lightThreshold*0.6f)* 0.3 + noises.x;
float xzVSy = step(rayFraction_xVSz, rayFractions.y);
//floor/ceiling or walls
interiorColour = lerp(verticalColour, interiorColour, xzVSy)* lightVariation;
//blend colors
float4 wallColour = /*diffuseColour * */i.lighting;
float4 windowColour = /*cubeColour + */interiorColour;
//return half4(i.positionCopy.xyz, 1);
return interiorColour;
//return lerp(wallColour, windowColour, diffuseColour.a);
}
ENDCG
}
}
}