Last active
November 12, 2015 15:31
-
-
Save MattRix/a149ee6776801e613f5e to your computer and use it in GitHub Desktop.
Photobomb painting code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System; | |
public class Bench : MonoBehaviour | |
{ | |
static public bool SHOULD_DEBUG = true; | |
static public Color defaultColor = Color.white; | |
public Vector2 simPos; | |
public Obstacle obstacle; | |
public float radius = 1f; | |
public float angle = 0; | |
public Vector2 dropPos; | |
public float dropRadius = 0.2f; | |
public Backpack backpack; | |
public BenchColor benchColor; | |
static public Bench Create() | |
{ | |
var benchGO = new GameObject("Bench"); | |
var bench = benchGO.GetComponent<Bench>(); | |
if(bench == null) bench = benchGO.AddComponent<Bench>(); | |
bench.obstacle = Obstacle.Create(ObstacleType.Bench); | |
bench.gameObject.isStatic = true; | |
return bench; | |
} | |
public void Setup(BenchColor benchColor, Vector2 simPos, float angle) | |
{ | |
this.benchColor = benchColor; | |
this.simPos = simPos; | |
this.angle = angle; | |
obstacle.Setup(simPos,angle); | |
this.transform.position = new Vector3(simPos.x,0,simPos.y); | |
this.transform.rotation = Quaternion.AngleAxis(angle,Vector3.down); | |
obstacle.transform.parent = this.transform; | |
obstacle.renderer.material.color = benchColor.color; | |
dropPos = simPos + new Vector2(0.5f,0.0f).RotateDegrees(angle-90f); | |
} | |
public void EndSimulation() | |
{ | |
obstacle.renderer.material = benchColor.paintMaterial.material; | |
} | |
public void OnDrawGizmos() | |
{ | |
var pos3D = this.transform.position; | |
GizmoUtils.DrawWireDisc(pos3D,Vector3.up,radius); | |
Gizmos.color = Color.blue; | |
GizmoUtils.DrawWireDisc(new Vector3(dropPos.x,0,dropPos.y),Vector3.up,dropRadius); | |
} | |
} | |
public class BenchColor | |
{ | |
static public Material materialAsset; | |
static public List<BenchColor> allColors = new List<BenchColor>(); | |
static public BenchColor Red = new BenchColor("Red",0xFF0033); | |
static public BenchColor Orange = new BenchColor("Orange",0xFF9900); | |
static public BenchColor Yellow = new BenchColor("Yellow",0xFFFF00); | |
static public BenchColor Green = new BenchColor("Green",0x33FF00); | |
static public BenchColor Blue = new BenchColor("Blue",0x0066FF); | |
static public BenchColor Purple = new BenchColor("Purple",0x9900FF); | |
public string name; | |
public Color color; | |
public int index; | |
public PaintMaterial paintMaterial; | |
public BenchColor(string name, uint hexColor) | |
{ | |
this.name = name; | |
this.color = RXColor.GetColorFromHex(hexColor); | |
this.index = allColors.Count; | |
if(materialAsset == null) | |
{ | |
materialAsset = Resources.Load<Material>("Materials/PawnMat"); | |
} | |
paintMaterial = new PaintMaterial(materialAsset,this.color); | |
allColors.Add(this); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System; | |
public class Painter | |
{ | |
static Painter instance; | |
static public Painter GetInstance() | |
{ | |
if(instance == null) | |
{ | |
instance = new Painter(); | |
} | |
return instance; | |
} | |
public GameObject go; | |
public Camera camera; | |
public Shader shader; | |
public Painter() | |
{ | |
go = new GameObject("Painter"); | |
camera = go.AddComponent<Camera>(); | |
camera.enabled = false; //don't render normally | |
shader = Shader.Find("Photobomb/UVShader"); | |
} | |
public void Paint(Camera referenceCamera) | |
{ | |
camera.CopyFrom(referenceCamera); | |
camera.rect = new Rect(0,0,1.0f,1.0f); //full rect | |
if(GameConfig.SHOULD_PAINT_ONLY_IN_FRAME) | |
{ | |
camera.fieldOfView = GameConfig.PHOTO_FOV; | |
} | |
ActuallyPaint(); | |
// camera.transform.position = camera.transform.position + new Vector3(0.01f,0.01f,0.01f); //move it a bit and paint again | |
// camera.transform.Rotate(0.1f,0.1f,0.1f); | |
// ActuallyPaint(); | |
} | |
void ActuallyPaint() | |
{ | |
int width = Mathf.RoundToInt((float)GameConfig.PHOTO_WIDTH * GameConfig.PAINT_RENDERTEXTURE_RATIO); | |
int height = Mathf.RoundToInt((float)GameConfig.PHOTO_HEIGHT * GameConfig.PAINT_RENDERTEXTURE_RATIO); | |
camera.SetReplacementShader(shader,""); | |
camera.clearFlags = CameraClearFlags.Color; | |
camera.backgroundColor = Color.black; | |
var rt = RenderTexture.GetTemporary(width,height,16,RenderTextureFormat.ARGB32,RenderTextureReadWrite.Linear); | |
camera.targetTexture = rt; | |
camera.Render(); | |
camera.targetTexture = null; | |
var prevRT = RenderTexture.active; | |
RenderTexture.active = rt; | |
var tex = new Texture2D(width,height,TextureFormat.RGB24,false,true); | |
tex.ReadPixels(new Rect(0,0,width,height),0,0); | |
tex.Apply(); | |
ProcessPic(tex); | |
RenderTexture.active = prevRT; | |
RenderTexture.ReleaseTemporary(rt); | |
Texture2D.Destroy(tex); | |
} | |
void ProcessPic (Texture2D tex) | |
{ | |
var pixels = tex.GetPixels32(0); | |
int pixelCount = pixels.Length; | |
var paintMats = PaintMaterial.allPaintMaterials; | |
int matCount = paintMats.Count; | |
List<Vector2>[] paintUVs = new List<Vector2>[matCount]; | |
for(int m = 0; m<matCount; m++) | |
{ | |
paintUVs[m] = new List<Vector2>(100); | |
} | |
for(int p = 0; p<pixelCount; p++) | |
{ | |
var pixel = pixels[p]; | |
if(pixel.b != 0) | |
{ | |
if(pixel.b <= matCount) | |
{ | |
paintUVs[pixel.b-1].Add(new Vector2((float)pixel.r/255f,(float)pixel.g/255f)); | |
} | |
} | |
} | |
//go through all the materials and apply the painted UVs to them | |
for(int m = 0; m<matCount; m++) | |
{ | |
var uvs = paintUVs[m]; | |
int uvCount = uvs.Count; | |
if(uvCount > 0) //don't paint textures that we weren't in the picture | |
{ | |
var targetTex = paintMats[m].texture; | |
var paintColor = paintMats[m].paintColor; | |
float targetWidth = targetTex.width; | |
float targetHeight = targetTex.height; | |
for(int s = 0; s<uvCount; s++) | |
{ | |
int drawX = (int)(uvs[s].x*targetWidth); | |
int drawY = (int)(uvs[s].y*targetHeight); | |
//paint all 5 pixels around the target | |
targetTex.SetPixel(drawX,drawY,paintColor); | |
targetTex.SetPixel(drawX+1,drawY,paintColor); | |
targetTex.SetPixel(drawX,drawY+1,paintColor); | |
targetTex.SetPixel(drawX-1,drawY,paintColor); | |
targetTex.SetPixel(drawX,drawY-1,paintColor); | |
} | |
targetTex.Apply(); | |
} | |
} | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System; | |
public class PaintMaterial | |
{ | |
static public List<PaintMaterial> allPaintMaterials = new List<PaintMaterial>(); | |
public int index; | |
public float objectID; | |
public Material material; | |
public Texture2D texture; | |
public Color paintColor; | |
public PaintMaterial(Material referenceMaterial, Color paintColor) | |
{ | |
index = allPaintMaterials.Count; | |
allPaintMaterials.Add(this); | |
objectID = (float)(index+1); | |
this.paintColor = paintColor; | |
material = Material.Instantiate(referenceMaterial) as Material; | |
texture = new Texture2D(GameConfig.PAINT_TEXTURE_SIZE,GameConfig.PAINT_TEXTURE_SIZE,TextureFormat.RGB24,false); | |
material.mainTexture = texture; | |
material.SetFloat("_ObjectID",objectID); | |
ClearTexture(); | |
} | |
public void ClearTexture() | |
{ | |
int pixelCount = texture.width*texture.height; | |
Color32[] colors = new Color32[pixelCount]; | |
Color32 clearColor = (Color32)Color.white; | |
for(int c = 0; c<pixelCount; c++) | |
{ | |
colors[c] = clearColor; | |
} | |
texture.SetPixels32(colors); | |
texture.Apply(); | |
} | |
static public void ClearAll() | |
{ | |
foreach(var mat in allPaintMaterials) | |
{ | |
mat.ClearTexture(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Photobomb/UVShader" | |
{ | |
Properties | |
{ | |
_MainTex ("Base (RGB)", 2D) = "white" {} | |
_ObjectID ("Object ID", Float) = 0 | |
} | |
SubShader | |
{ | |
Pass | |
{ | |
Fog { Mode Off } | |
Tags { "LightMode" = "ForwardBase" } | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
uniform sampler2D _MainTex; | |
uniform float _ObjectID; | |
struct vertexInput | |
{ | |
float4 pos : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct vertexOutput | |
{ | |
float4 pos : SV_POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
vertexOutput vert (vertexInput i) | |
{ | |
vertexOutput o; | |
o.pos = mul(UNITY_MATRIX_MVP, i.pos); | |
o.uv = i.uv; | |
return o; | |
} | |
float4 frag (vertexOutput o) : COLOR | |
{ | |
if(_ObjectID <= 0.0) | |
{ | |
return float4(0.0,0.0,0.0,1.0); | |
} | |
else | |
{ | |
return float4(o.uv.x,o.uv.y,_ObjectID/255.0,1.0); | |
} | |
} | |
ENDCG | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment