Jason McKesson avatar Jason McKesson committed 6bd0e78

Most Tut10 images complete.

Comments (0)

Files changed (11)

Documents/Illumination/GenHalfangleVectorDiagram.lua

+require "SvgWriter"
+require "vmath"
+require "Viewport"
+require "SubImage"
+require "GridAxis"
+require "Colors"
+require "_utils"
+
+local imageSize = vmath.vec2(400, 150);
+
+local subImages = SubImage.SubImage(1, 1, imageSize.x, imageSize.y, 0, 0);
+
+local coordSize = 8;
+local coordWidth = coordSize * (imageSize.x / imageSize.y);
+
+local vp = Viewport.Viewport(imageSize, {0, 2}, {coordWidth, coordSize})
+local trans2 = Viewport.Transform2D()
+vp:SetTransform(trans2);
+
+local styleLib = SvgWriter.StyleLibrary();
+
+local lightSourceColor = Colors.clr("lightSource");
+local surfaceColor = Colors.clr("surface");
+local textSize = 14;
+
+styleLib:AddStyle(nil, "surface", SvgWriter.Style():stroke("none"):fill(surfaceColor));
+
+styleLib:AddStyle(nil, "label",
+	SvgWriter.Style():stroke("none"):fill("black"):font_size(textSize .. "pt")
+		:text_anchor("middle"));
+		
+styleLib:AddStyle(nil, "point", SvgWriter.Style():stroke("none"):fill("black"));
+
+styleLib:AddStyle(nil, "src_arrowhead",
+	SvgWriter.Style():stroke("black"):fill("black"));
+	
+styleLib:AddStyle(nil, "dir_arrowhead",
+	SvgWriter.Style():stroke("green"):fill("green"));
+	
+styleLib:AddStyle(nil, "src_direction",
+	SvgWriter.Style():stroke("black"):stroke_width("1px"):marker_end(SvgWriter.uriLocalElement("src_arrow")));
+	
+styleLib:AddStyle(nil, "normal_direction",
+	SvgWriter.Style():stroke("green"):stroke_width("1px"):marker_end(SvgWriter.uriLocalElement("dir_arrow")));
+
+local function WriteFile(filename, viewPos, labels)
+	--Surface and light.
+	local surfaceDim =
+	{
+		vmath.vec2(-coordWidth / 2, 0), vmath.vec2(coordWidth / 2, -2),
+	};
+
+	local lightPos = vmath.vec2(-7, 2);
+	local thePoint = vmath.vec2(0, 0);
+
+	--Compute reflection and half-angle vectors.
+	local reflectDir = nil;
+	local halfAngleDir = nil;
+
+	do
+		local finalPos = {}
+		local incident = vmath.norm(lightPos - thePoint);
+		local viewDir = vmath.norm(viewPos - thePoint);
+		
+		reflectDir = vmath.vec2(-incident.x, incident.y);
+		halfAngleDir = vmath.norm(viewDir + incident);
+	end
+
+	local vectorLengths = 4;
+
+	--Compute the normal vector.
+	local normalDir = vmath.vec2(0, 1);
+
+	--Compute all of the vectors we need to draw.
+	local vectors = 
+	{
+		(normalDir * vectorLengths) + thePoint,
+		lightPos,
+		viewPos,
+		(reflectDir * vectorLengths) + thePoint,
+		(halfAngleDir * vectorLengths) + thePoint,
+	}
+
+	vectors = vp:Transform(vectors);
+	thePoint = vp:Transform(thePoint);
+
+	surfaceDim = vp:Transform(surfaceDim);
+
+	--Vertices
+	local pointRadius = 4;
+	local radiusPt = vmath.vec2(pointRadius, pointRadius);
+
+	local writer = SvgWriter.SvgWriter(ConstructSVGName(filename), {subImages:Size().x .."px", subImages:Size().y .. "px"});
+		writer:StyleLibrary(styleLib);
+		writer:BeginDefinitions();
+			WriteStandardArrowhead(writer, "dir_arrow", {"dir_arrowhead"});
+			WriteStandardArrowhead(writer, "src_arrow", {"src_arrowhead"});
+		writer:EndDefinitions();
+
+		--Draw surface and light.
+		writer:Rect2Pt(surfaceDim[1], surfaceDim[2], nil, {"surface"});
+		
+		--Draw the lines
+		for i=1, #vectors do
+			writer:Line(thePoint, vectors[i], {labels[i][2]});
+		end
+		
+		--Draw the labels
+		for i=1, #labels do
+			writer:Text(labels[i][1], labels[i][3] + vectors[i], {"label"});
+		end
+
+	--	writer:Use("g_point", viewPoint, radiusPt * 2);
+	--	writer:Text("V", viewPoint + viewLabelOffset, {"label"});
+	writer:Close();
+end
+
+local mainLabels =
+{
+	{"N", "src_direction", vmath.vec2(10, 0)},
+	{"L", "src_direction", vmath.vec2(-10, 4)},
+	{"V", "src_direction", vmath.vec2(8, 0)},
+	{"R", "normal_direction", vmath.vec2(4, -8)},
+	{"H", "normal_direction", vmath.vec2(-4, -4)},
+}
+
+WriteFile(arg[0], vmath.vec2(2, 4), mainLabels);
+
+local perfectLabels =
+{
+	{"N", "src_direction", vmath.vec2(10, 0)},
+	{"L", "src_direction", vmath.vec2(-10, 4)},
+	{"V", "src_direction", vmath.vec2(8, 0)},
+	{"R", "normal_direction", vmath.vec2(4, -8)},
+	{"H", "normal_direction", vmath.vec2(-10, 0)},
+}
+
+WriteFile("GenHalfangleVectorPerfect.lua", vmath.vec2(7, 2), perfectLabels);
+

Documents/Illumination/GenMicrofacetRoughSmooth.lua

+require "SvgWriter"
+require "vmath"
+require "Viewport"
+require "SubImage"
+require "GridAxis"
+require "_utils"
+
+local imageSize = vmath.vec2(400, 100);
+
+local subImages = SubImage.SubImage(1, 2, imageSize.x, imageSize.y, 0, 25);
+
+local coordSize = 3;
+local coordWidth = coordSize * (imageSize.x / imageSize.y);
+
+local vp = Viewport.Viewport(imageSize, {0, 0}, {coordWidth, coordSize})
+local trans2 = Viewport.Transform2D()
+vp:SetTransform(trans2);
+
+local styleLib = SvgWriter.StyleLibrary();
+
+local lightSourceColor = "yellow";
+local surfaceColor = "lightblue";
+local rayColor = "darkblue";
+
+styleLib:AddStyle(nil, "surface", SvgWriter.Style():stroke("none"):fill(surfaceColor));
+
+--Surface and light.
+local surfaceDim =
+{
+	vmath.vec2(-coordWidth / 2, 0), vmath.vec2(coordWidth / 2, -coordSize / 2),
+};
+
+local function GenerateSurfacePath(heights)
+	local path = SvgWriter.Path();
+	
+	path:M(vp:Transform(surfaceDim[2]));
+	path:L(vp:Transform(vmath.vec2(surfaceDim[1][1], surfaceDim[2][2])));
+	path:L(vp:Transform(surfaceDim[1]));
+	
+	local baseHeight = 0;
+	local facetWidth = (coordWidth / #heights);
+	for i=1, #heights do
+		local xPos = surfaceDim[1][1] + (i * facetWidth);
+		path:L(vp:Transform(vmath.vec2(xPos, heights[i] + baseHeight)));
+	end
+	
+	path:Z();
+	return path;
+end
+
+local smoothHeights =
+{
+	0.2,
+	-0.15,
+	0.1,
+	0.2,
+	0.1,
+	-0.05,
+	0.03,
+	-0.13,
+	-0.18,
+	0.2,
+	-0.13,
+	-0.04,
+	0,
+}
+
+local roughHeights =
+{
+	0.8,
+	-0.2,
+	0.8,
+	0.4,
+	0.3,
+	-0.7,
+	0.4,
+	-0.2,
+	-0.1,
+	0.9,
+	-0.5,
+	-0.2,
+	0.4,
+}
+
+local smoothPath = GenerateSurfacePath(smoothHeights);
+local roughPath = GenerateSurfacePath(roughHeights);
+
+local lightSourceRadius = 10;
+
+local writer = SvgWriter.SvgWriter(ConstructSVGName(arg[0]), {subImages:Size().x .."px", subImages:Size().y .. "px"});
+	writer:StyleLibrary(styleLib);
+	writer:BeginDefinitions();
+		WriteStandardArrowhead(writer, "arrow", {"arrowhead"});
+		
+		writer:BeginGroup(nil, "g_smooth_surface");
+			writer:Path(smoothPath, {"surface"});
+		writer:EndGroup();
+		writer:BeginGroup(nil, "g_rough_surface");
+			writer:Path(roughPath, {"surface"});
+		writer:EndGroup();
+
+	writer:EndDefinitions();
+
+	writer:Use("g_smooth_surface", subImages:Offset(1, 1), subImages:SubSize());
+	writer:Use("g_rough_surface", subImages:Offset(1, 2), subImages:SubSize());
+
+writer:Close();

Documents/Illumination/GenPhongReflectDirTooGreat.lua

+require "SvgWriter"
+require "vmath"
+require "Viewport"
+require "SubImage"
+require "GridAxis"
+require "Colors"
+require "_utils"
+
+local imageSize = vmath.vec2(400, 150);
+
+local subImages = SubImage.SubImage(1, 1, imageSize.x, imageSize.y, 0, 0);
+
+local coordSize = 8;
+local coordWidth = coordSize * (imageSize.x / imageSize.y);
+
+local vp = Viewport.Viewport(imageSize, {0, 2}, {coordWidth, coordSize})
+local trans2 = Viewport.Transform2D()
+vp:SetTransform(trans2);
+
+local styleLib = SvgWriter.StyleLibrary();
+
+local lightSourceColor = Colors.clr("lightSource");
+local surfaceColor = Colors.clr("surface");
+local textSize = 14;
+
+styleLib:AddStyle(nil, "surface", SvgWriter.Style():stroke("none"):fill(surfaceColor));
+styleLib:AddStyle(nil, "light", SvgWriter.Style():stroke("none"):fill(lightSourceColor));
+
+styleLib:AddStyle(nil, "lightRay", SvgWriter.Style():stroke(surfaceColor));
+
+styleLib:AddStyle(nil, "label",
+	SvgWriter.Style():stroke("none"):fill("black"):font_size(textSize .. "pt")
+		:text_anchor("middle"));
+		
+styleLib:AddStyle(nil, "point", SvgWriter.Style():stroke("none"):fill("black"));
+
+local axisData = GridAxis.GridAxis2D(vp, nil, styleLib, true, nil);
+
+--Surface and light.
+local surfaceDim =
+{
+	vmath.vec2(-coordWidth / 2, 0), vmath.vec2(coordWidth / 2, -2),
+};
+
+local lightPos = vmath.vec2(-7, 2);
+local lightSourceRadius = 20;
+
+surfaceDim = vp:Transform(surfaceDim);
+lightPos = vp:Transform(lightPos);
+
+--Light rays
+local thePoint = vmath.vec2(0, 0);
+local viewPoint = vmath.vec2(-4, 4);
+
+thePoint = vp:Transform(thePoint);
+viewPoint = vp:Transform(viewPoint);
+
+--Labels
+local reflectLabelOffset = vmath.vec2(12, 5)
+local pointLabelOffset = vmath.vec2(0, 20)
+local viewLabelOffset = vmath.vec2(-12, 5);
+
+--Vertices
+local pointRadius = 4;
+local radiusPt = vmath.vec2(pointRadius, pointRadius);
+
+local writer = SvgWriter.SvgWriter(ConstructSVGName(arg[0]), {subImages:Size().x .."px", subImages:Size().y .. "px"});
+	writer:StyleLibrary(styleLib);
+	writer:BeginDefinitions();
+		writer:BeginGroup(nil, "g_point");
+			writer:Circle(vmath.vec2(0, 0), pointRadius, {"vertex"});
+		writer:EndGroup();
+	writer:EndDefinitions();
+
+	--Draw surface and light.
+	writer:Rect2Pt(surfaceDim[1], surfaceDim[2], nil, {"surface"});
+
+	--Draw the light ray.
+	writer:Line(lightPos, thePoint, {"lightRay"});
+
+	--Draw the view direction
+	writer:Line(viewPoint, thePoint, {"lightRay"});
+	
+	--Draw the reflection direction.
+	local finalPos = {}
+	local incident = vmath.norm(thePoint - lightPos);
+	local reflect = vmath.vec2(incident.x, -incident.y);
+	
+	local yLen = surfaceDim[1].y - lightPos.y;
+	local len = yLen / incident.y;
+	local finalPos = (len * reflect) + thePoint;
+	writer:Line(finalPos, thePoint, {"lightRay"});
+	
+	writer:Circle(lightPos, lightSourceRadius, {"light"});
+	
+	writer:Use("g_point", finalPos, radiusPt * 2);
+	writer:Text("R", reflectLabelOffset + finalPos, {"label"});
+	
+	writer:Use("g_point", thePoint, radiusPt * 2);
+	writer:Text("P", thePoint + pointLabelOffset, {"label"});
+
+	writer:Use("g_point", viewPoint, radiusPt * 2);
+	writer:Text("V", viewPoint + viewLabelOffset, {"label"});
+	
+writer:Close();

Documents/Illumination/GenSpecularReflection.lua

+require "SvgWriter"
+require "vmath"
+require "Viewport"
+require "SubImage"
+require "GridAxis"
+require "Colors"
+require "_utils"
+
+local imageSize = vmath.vec2(500, 300);
+
+local subImages = SubImage.SubImage(1, 1, imageSize.x, imageSize.y, 0, 0);
+
+local coordSize = 10;
+local coordWidth = coordSize * (imageSize.x / imageSize.y);
+
+local vp = Viewport.Viewport({500, 300}, {0, 3}, {coordWidth, coordSize})
+local trans2 = Viewport.Transform2D()
+vp:SetTransform(trans2);
+
+local styleLib = SvgWriter.StyleLibrary();
+
+local lightSourceColor = Colors.clr("lightSource");
+local surfaceColor = Colors.clr("surface");
+local textSize = 14;
+
+styleLib:AddStyle(nil, "surface", SvgWriter.Style():stroke("none"):fill(surfaceColor));
+styleLib:AddStyle(nil, "light", SvgWriter.Style():stroke("none"):fill(lightSourceColor));
+
+styleLib:AddStyle(nil, "lightRay", SvgWriter.Style():stroke(surfaceColor));
+
+styleLib:AddStyle(nil, "label",
+	SvgWriter.Style():stroke("none"):fill("black"):font_size(textSize .. "pt")
+		:text_anchor("middle"));
+		
+styleLib:AddStyle(nil, "point", SvgWriter.Style():stroke("none"):fill("black"));
+
+local axisData = GridAxis.GridAxis2D(vp, nil, styleLib, true, nil);
+
+--Surface and light.
+local surfaceDim =
+{
+	vmath.vec2(-coordWidth / 2, 0), vmath.vec2(coordWidth / 2, -3),
+};
+
+local lightSourcePos = vmath.vec2(-7, 6);
+local lightSourceRadius = 20;
+
+surfaceDim = vp:Transform(surfaceDim);
+lightSourcePos = vp:Transform(lightSourcePos);
+
+--Light rays
+local posRayStart = -4.0;
+
+local rayPoints =
+{
+	-3, 0,
+}
+
+local rayLines = {}
+
+for i,pos in ipairs(rayPoints) do
+	rayLines[#rayLines + 1] = vmath.vec2(pos, 0);
+end
+
+rayLines = vp:Transform(rayLines);
+
+
+--Labels
+local viewLabel =
+{
+	{"A", vmath.vec2(12, 5)},
+	{"B", vmath.vec2(12, 5)},
+}
+
+local reflectLabelOffset = vmath.vec2(0, 20)
+
+--Vertices
+local pointRadius = 4;
+local radiusPt = vmath.vec2(pointRadius, pointRadius);
+
+local writer = SvgWriter.SvgWriter(ConstructSVGName(arg[0]), {subImages:Size().x .."px", subImages:Size().y .. "px"});
+	writer:StyleLibrary(styleLib);
+	writer:BeginDefinitions();
+		writer:BeginGroup(nil, "g_point");
+			writer:Circle(vmath.vec2(0, 0), pointRadius, {"vertex"});
+		writer:EndGroup();
+	writer:EndDefinitions();
+
+	--Draw surface and light.
+	writer:Rect2Pt(surfaceDim[1], surfaceDim[2], nil, {"surface"});
+
+	--Draw lines.
+	for i=1, #rayLines do
+		writer:Line(lightSourcePos, rayLines[i], {"lightRay"});
+	end
+	
+	--Draw reflections.
+	local finalPos = {}
+	for i=1, #rayLines do
+		local incident = vmath.norm(rayLines[i] - lightSourcePos);
+		local reflect = vmath.vec2(incident.x, -incident.y);
+		
+		local yLen = surfaceDim[1].y - lightSourcePos.y;
+		local len = yLen / incident.y;
+		finalPos[i] = (len * reflect) + rayLines[i];
+		
+		writer:Line(finalPos[i], rayLines[i], {"lightRay"});
+	end
+
+	writer:Circle(lightSourcePos, lightSourceRadius, {"light"});
+	
+	for i=1, #viewLabel do
+		local label = viewLabel[i];
+		writer:Text(label[1], label[2] + finalPos[i], {"label"});
+		writer:Use("g_point", finalPos[i], radiusPt * 2);
+	end
+
+	writer:Use("g_point", rayLines[1], radiusPt * 2);
+	writer:Text("P", rayLines[1] + reflectLabelOffset, {"label"});
+	
+writer:Close();
Add a comment to this file

Documents/Illumination/HalfangleVectorDiagram.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" height="150px" width="400px" >
+	<style type="text/css" ><![CDATA[.point
+{
+	fill: black;
+	stroke: none;
+}
+
+.src_arrowhead
+{
+	fill: black;
+	stroke: black;
+}
+
+.dir_arrowhead
+{
+	fill: green;
+	stroke: green;
+}
+
+.normal_direction
+{
+	marker-end: url(#dir_arrow);
+	stroke: green;
+	stroke-width: 1px;
+}
+
+.label
+{
+	font-size: 14pt;
+	stroke: none;
+	text-anchor: middle;
+	fill: black;
+}
+
+.surface
+{
+	fill: lightblue;
+	stroke: none;
+}
+
+.src_direction
+{
+	marker-end: url(#src_arrow);
+	stroke: black;
+	stroke-width: 1px;
+}]]></style>
+	<defs >
+		<marker markerWidth="10" markerHeight="8" refX="10" refY="4" markerUnits="userSpaceOnUse" orient="auto" id="dir_arrow" >
+			<path d="M 10 4 L 0 0 L 0 8 Z" class="dir_arrowhead" />
+		</marker>
+		<marker markerWidth="10" markerHeight="8" refX="10" refY="4" markerUnits="userSpaceOnUse" orient="auto" id="src_arrow" >
+			<path d="M 10 4 L 0 0 L 0 8 Z" class="src_arrowhead" />
+		</marker>
+	</defs>
+	<rect y="112.5" x="0" height="37.5" width="400" class="surface" />
+	<line x2="200" y2="37.5" y1="112.5" x1="200" class="src_direction" />
+	<line x2="68.75" y2="75" y1="112.5" x1="200" class="src_direction" />
+	<line x2="237.5" y2="37.5" y1="112.5" x1="200" class="src_direction" />
+	<line x2="272.11429607306" y2="91.895915407697" y1="112.5" x1="200" class="normal_direction" />
+	<line x2="169.80025691674" y2="43.848885531952" y1="112.5" x1="200" class="normal_direction" />
+	<text y="37.5" x="210" class="label" >N</text>
+	<text y="79" x="58.75" class="label" >L</text>
+	<text y="37.5" x="245.5" class="label" >V</text>
+	<text y="83.895915407697" x="276.11429607306" class="label" >R</text>
+	<text y="39.848885531952" x="165.80025691674" class="label" >H</text>
+</svg>
Add a comment to this file

Documents/Illumination/HalfangleVectorPerfect.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" height="150px" width="400px" >
+	<style type="text/css" ><![CDATA[.point
+{
+	fill: black;
+	stroke: none;
+}
+
+.src_arrowhead
+{
+	fill: black;
+	stroke: black;
+}
+
+.dir_arrowhead
+{
+	fill: green;
+	stroke: green;
+}
+
+.normal_direction
+{
+	marker-end: url(#dir_arrow);
+	stroke: green;
+	stroke-width: 1px;
+}
+
+.label
+{
+	font-size: 14pt;
+	stroke: none;
+	text-anchor: middle;
+	fill: black;
+}
+
+.surface
+{
+	fill: lightblue;
+	stroke: none;
+}
+
+.src_direction
+{
+	marker-end: url(#src_arrow);
+	stroke: black;
+	stroke-width: 1px;
+}]]></style>
+	<defs >
+		<marker markerWidth="10" markerHeight="8" refX="10" refY="4" markerUnits="userSpaceOnUse" orient="auto" id="dir_arrow" >
+			<path d="M 10 4 L 0 0 L 0 8 Z" class="dir_arrowhead" />
+		</marker>
+		<marker markerWidth="10" markerHeight="8" refX="10" refY="4" markerUnits="userSpaceOnUse" orient="auto" id="src_arrow" >
+			<path d="M 10 4 L 0 0 L 0 8 Z" class="src_arrowhead" />
+		</marker>
+	</defs>
+	<rect y="112.5" x="0" height="37.5" width="400" class="surface" />
+	<line x2="200" y2="37.5" y1="112.5" x1="200" class="src_direction" />
+	<line x2="68.75" y2="75" y1="112.5" x1="200" class="src_direction" />
+	<line x2="331.25" y2="75" y1="112.5" x1="200" class="src_direction" />
+	<line x2="272.11429607306" y2="91.895915407697" y1="112.5" x1="200" class="normal_direction" />
+	<line x2="200" y2="37.5" y1="112.5" x1="200" class="normal_direction" />
+	<text y="37.5" x="210" class="label" >N</text>
+	<text y="79" x="58.75" class="label" >L</text>
+	<text y="75" x="339.25" class="label" >V</text>
+	<text y="83.895915407697" x="276.11429607306" class="label" >R</text>
+	<text y="37.5" x="190" class="label" >H</text>
+</svg>
Add a comment to this file

Documents/Illumination/MicrofacetRoughSmooth.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" height="225px" width="400px" >
+	<style type="text/css" ><![CDATA[.surface
+{
+	fill: lightblue;
+	stroke: none;
+}]]></style>
+	<defs >
+		<marker markerWidth="10" markerHeight="8" refX="10" refY="4" markerUnits="userSpaceOnUse" orient="auto" id="arrow" >
+			<path d="M 10 4 L 0 0 L 0 8 Z" class="arrowhead" />
+		</marker>
+		<g id="g_smooth_surface" >
+			<path d="M 400 100 L 2.8421709430404e-014 100 L 2.8421709430404e-014 50 L 30.769230769231 43.333333333333 L 61.538461538462 55 L 92.307692307692 46.666666666667 L 123.07692307692 43.333333333333 L 153.84615384615 46.666666666667 L 184.61538461538 51.666666666667 L 215.38461538462 49 L 246.15384615385 54.333333333333 L 276.92307692308 56 L 307.69230769231 43.333333333333 L 338.46153846154 54.333333333333 L 369.23076923077 51.333333333333 L 400 50 Z" class="surface" />
+		</g>
+		<g id="g_rough_surface" >
+			<path d="M 400 100 L 2.8421709430404e-014 100 L 2.8421709430404e-014 50 L 30.769230769231 23.333333333333 L 61.538461538462 56.666666666667 L 92.307692307692 23.333333333333 L 123.07692307692 36.666666666667 L 153.84615384615 40 L 184.61538461538 73.333333333333 L 215.38461538462 36.666666666667 L 246.15384615385 56.666666666667 L 276.92307692308 53.333333333333 L 307.69230769231 20 L 338.46153846154 66.666666666667 L 369.23076923077 56.666666666667 L 400 36.666666666667 Z" class="surface" />
+		</g>
+	</defs>
+	<use xlink:href="#g_smooth_surface" y="0" x="0" height="100" width="400" />
+	<use xlink:href="#g_rough_surface" y="125" x="0" height="100" width="400" />
+</svg>
Add a comment to this file

Documents/Illumination/PhongReflectDirTooGreat.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" height="150px" width="400px" >
+	<style type="text/css" ><![CDATA[.lightRay
+{
+	stroke: lightblue;
+}
+
+.__axis1
+{
+	stroke: black;
+	stroke-width: 2px;
+	fill: none;
+}
+
+.point
+{
+	fill: black;
+	stroke: none;
+}
+
+.label
+{
+	font-size: 14pt;
+	stroke: none;
+	text-anchor: middle;
+	fill: black;
+}
+
+.surface
+{
+	fill: lightblue;
+	stroke: none;
+}
+
+.__grid1
+{
+	stroke: #CCC;
+	stroke-width: 1px;
+	fill: none;
+}
+
+.__axis_arrow_end1
+{
+	marker-end: url(#__axis_arrow1);
+}
+
+.light
+{
+	fill: yellow;
+	stroke: none;
+}]]></style>
+	<defs >
+		<g id="g_point" >
+			<circle r="4" cy="0" cx="0" class="vertex" />
+		</g>
+	</defs>
+	<rect y="112.5" x="0" height="37.5" width="400" class="surface" />
+	<line x2="200" y2="112.5" y1="75" x1="68.75" class="lightRay" />
+	<line x2="200" y2="112.5" y1="37.5" x1="125" class="lightRay" />
+	<line x2="200" y2="112.5" y1="75" x1="331.25" class="lightRay" />
+	<circle r="20" cy="75" cx="68.75" class="light" />
+	<use xlink:href="#g_point" y="75" x="331.25" height="8" width="8" />
+	<text y="80" x="343.25" class="label" >R</text>
+	<use xlink:href="#g_point" y="112.5" x="200" height="8" width="8" />
+	<text y="132.5" x="200" class="label" >P</text>
+	<use xlink:href="#g_point" y="37.5" x="125" height="8" width="8" />
+	<text y="42.5" x="113" class="label" >V</text>
+</svg>
Add a comment to this file

Documents/Illumination/SpecularReflection.svg

Added
New image
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" height="300px" width="500px" >
+	<style type="text/css" ><![CDATA[.__axis1
+{
+	stroke: black;
+	stroke-width: 2px;
+	fill: none;
+}
+
+.point
+{
+	fill: black;
+	stroke: none;
+}
+
+.light
+{
+	fill: yellow;
+	stroke: none;
+}
+
+.surface
+{
+	fill: lightblue;
+	stroke: none;
+}
+
+.__grid1
+{
+	stroke: #CCC;
+	stroke-width: 1px;
+	fill: none;
+}
+
+.__axis_arrow_end1
+{
+	marker-end: url(#__axis_arrow1);
+}
+
+.lightRay
+{
+	stroke: lightblue;
+}
+
+.label
+{
+	font-size: 14pt;
+	stroke: none;
+	text-anchor: middle;
+	fill: black;
+}]]></style>
+	<defs >
+		<g id="g_point" >
+			<circle r="4" cy="0" cx="0" class="vertex" />
+		</g>
+	</defs>
+	<rect y="240" x="-2.8421709430404e-014" height="90" width="500" class="surface" />
+	<line x2="160" y2="240" y1="60" x1="40" class="lightRay" />
+	<line x2="250" y2="240" y1="60" x1="40" class="lightRay" />
+	<line x2="160" y2="240" y1="60" x1="280" class="lightRay" />
+	<line x2="250" y2="240" y1="60" x1="460" class="lightRay" />
+	<circle r="20" cy="60" cx="40" class="light" />
+	<text y="65" x="292" class="label" >A</text>
+	<use xlink:href="#g_point" y="60" x="280" height="8" width="8" />
+	<text y="65" x="472" class="label" >B</text>
+	<use xlink:href="#g_point" y="60" x="460" height="8" width="8" />
+	<use xlink:href="#g_point" y="240" x="160" height="8" width="8" />
+	<text y="260" x="160" class="label" >P</text>
+</svg>

Documents/Illumination/Tutorial 10.xml

             characteristics of the surface. If a surface was perfectly smooth, then the specular
             highlight from a point light would be infinitely small (since point lights themselves
             are infinitely small).</para>
-        <!--TODO: Show a perfectly smooth surface with reflection from a light source. Have several camera positions.
-Position A should be in view of the reflection at the point P, while position B should not.-->
+        <figure>
+            <title>Perfect Specular Reflection</title>
+            <mediaobject>
+                <imageobject>
+                    <imagedata fileref="SpecularReflection.svg" format="SVG"/>
+                </imageobject>
+            </mediaobject>
+        </figure>
         <para>Notice that the intensity of the reflected light depends not only on the angle of
             incidence, but only the direction to the viewer. This is called the <glossterm>angle of
                 view</glossterm> or <glossterm>viewing angle</glossterm>. Viewing position A detects
-            the light specularly reflected from the surface, but the viewing position B does
-            not.</para>
-        <para>Surfaces however are rarely perfectly smooth. Surfaces that seem smooth from far away
-            can be rough on closer examination. This is true at the microscopic level as well, even
-            for surfaces that look quite smooth. This roughness can be modelled by assuming that a
-            surface is composed of a number of <glossterm>microfacets.</glossterm></para>
+            the light specularly reflected from the surface at the point P, but the viewing position
+            B does not.</para>
+        <para>Surfaces however are rarely perfect specular reflectors (mirrors are the most common
+            perfect reflectors). Surfaces that seem smooth from far away can be rough on closer
+            examination. This is true at the microscopic level as well, even for surfaces that
+            appear quite smooth. This roughness can be modelled by assuming that a surface is
+            composed of a number of <glossterm>microfacets.</glossterm></para>
         <para>A microfacet is a flat plane that is oriented in a single direction. Each microfacet
-            reflects light perfectly in that direction. A surface with microfacets would look like
+            reflects light perfectly in that direction. Surfaces with microfacets would look like
             this:</para>
-        <!--TODO: show two 2D surface with microfacets, one relatively rough and one smooth.-->
+        <figure>
+            <title>Smooth and Rough Microfacets</title>
+            <mediaobject>
+                <imageobject>
+                    <imagedata fileref="MicrofacetRoughSmooth.svg" format="SVG"/>
+                </imageobject>
+            </mediaobject>
+        </figure>
         <para>It is part of the microfacet model's assumption that many microfacets on a surface
             will contribute to the light returned under a single pixel of the final image. So each
-            pixel in the rendered image is the result of an aggregate of the microfacets.</para>
+            pixel in the rendered image is the result of an aggregate of the microfacets that lie
+            under the area of that pixel on the surface.</para>
         <para>The average normal of the microfacets is the surface normal at that point. The
-            relative smoothness of a surface can be modeled as a statistical distribution of the
-            orientation of microfacets on the surface. A smooth surface has a distribution close to
-            the average, while a rough surface has a broader distribution.</para>
+            relative smoothness of a surface can therefore be modeled as a statistical distribution
+            of the orientation of microfacets on the surface. A smooth surface has a distribution
+            close to the average, while a rough surface has a broader distribution.</para>
         <para>Thus, a model of specular reflections includes a term that defines the overall
             smoothness of the source. This is a surface characteristic, representing the
             distribution of microfacets using whatever statistical distribution the particular
                 reasonable.</para>
             <para>In particular, it is interesting to note what happens when you use a very dark
                 diffuse color. You can activate this by pressing the <keycap>G</keycap> key.</para>
-            <!--TODO: Show dark diffuse color.-->
+            <!--TODO: Show dark diffuse color from the tutorial.-->
             <para>If there was no specular term at all, you would a virtually scene. The specular
                 highlight, even with the fairly weak specular reflection of 0.25, is strong enough
                 to give some definition to the object when seen from various angles. This more
                 accurately shows what a black plastic object might look like.</para>
             <para>One thing you may notice is that, if you bring the light close to the surface, the
                 specular area tends to have very sharp edges.</para>
-            <!--TODO: Show a picture of the clipping.-->
+            <!--TODO: Show a picture of the Phong clipping.-->
             <para>This is part of the nature of specular reflections. If the light is almost
                 perpendicular to the surface, the specular reflection will shine brightest when the
                 light is almost eclipsed by the surface. This creates a strong discontinuity at the
             more than Phong.</para>
         <para>The main problem with Phong is that the angle between the view direction and the
             reflection direction has to be less than 90 degrees in order for the specular term to be
-            non-zero. So cases like this:</para>
-        <!--TODO: Show the Phong problem in 2D-->
-        <para>These are not modeled correctly. These could have microfacets that are oriented
-            towards the camera, but Phong cannot properly render this. The problem is that the dot
-            product between the view direction and reflection direction can be negative, which does
-            not lead to a reasonable result when passed through the rest of the equation.</para>
+            non-zero.</para>
+        <figure>
+            <title>Large View and Reflect Angle</title>
+            <mediaobject>
+                <imageobject>
+                    <imagedata fileref="PhongReflectDirTooGreat.svg" format="SVG"/>
+                </imageobject>
+            </mediaobject>
+        </figure>
+        <para>The angle between V and R is greater than 90 degrees. Cases like this are not modeled
+            correctly by Phong. There could be microfacets at the point which are oriented towards
+            the camera, but Phong cannot properly model this. The problem is that the dot product
+            between the view direction and reflection direction can be negative, which does not lead
+            to a reasonable result when passed through the rest of the equation.</para>
         <para>The Blinn model uses a different set of vectors for its computations, one that are
             less than 90 degrees in all valid cases. The Blinn model requires computing the
                 <glossterm>half-angle vector</glossterm>. The half-angle vector is the direction
             halfway between the view direction and the light position.</para>
-        <!--TODO: Show a 2D representation of the half-angle vector.-->
+        <figure>
+            <title>Geometric Half-Angle Vector</title>
+            <mediaobject>
+                <imageobject>
+                    <imagedata fileref="HalfangleVectorDiagram.svg" format="SVG"/>
+                </imageobject>
+            </mediaobject>
+        </figure>
         <equation>
             <title>Half-Angle Vector</title>
             <mediaobject>
             </mediaobject>
         </equation>
         <para>When the view direction is perfectly aligned with the reflected direction, the
-            half-angle vector is perfectly aligned with the surface normal. To describe the
-            half-angle vector another way, it is the direction the surface normal would need to be
-            oriented in in order for the viewer to see a specular reflection from the light
-            source.</para>
-        <!--TODO: Show the halfangle vector for a view direction equal to the reflection direction.-->
+            half-angle vector is perfectly aligned with the surface normal. Or to put it another
+            way, the half-angle is the direction the surface normal would need to be facing in order
+            for the viewer to see a specular reflection from the light source.</para>
+        <figure>
+            <title>Perfect Reflection Half-Angle Vector</title>
+            <mediaobject>
+                <imageobject>
+                    <imagedata fileref="HalfangleVectorPerfect.svg" format="SVG"/>
+                </imageobject>
+            </mediaobject>
+        </figure>
         <para>So instead of comparing the reflection vector to the view direction, the Blinn model
             compares the half-angle vector to the surface normal. It then raises this value to a
             power representing the shininess of the surface.</para>
             hardware however, taking the reciprocal square-root (1 / √X) is generally about as fast
             as doing a vector multiply. This puts Blinn as approximately equal in performance to
             Phong; on some hardware, it may even be faster. In general, the performance difference
-            between the two will be negligable.</para>
+            between the two will be negligible.</para>
         <para>Gaussian is a different story. It would be reasonable to expect the
                 <function>pow</function> function, taking <inlineequation>
                 <mathphrase>x<superscript>y</superscript></mathphrase>
                 <mathphrase>e<superscript>x</superscript></mathphrase>
             </inlineequation>. They might have the same performance, but if one is going to be
             faster, it is more likely to be <function>exp</function> than <function>pow</function>.
-            However, Gaussian also uses the inverse cosine; that pretty much negates any possibility
-            of performance parity. The inverse cosine computation is certainly not built into the
-            hardware, and thus must be computed using the shader logic. And while this is likely
-            true of exponentiation and power functions, Gaussian has to do <emphasis>two</emphasis>
-            of these operations, compared to just one for Phong or Blinn.</para>
+            However, Gaussian also uses the inverse cosine to compute the angle between the normal
+            and half-angle vector; that pretty much negates any possibility of performance parity.
+            The inverse cosine computation is certainly not built into the hardware, and thus must
+            be computed using the shader logic. And while this is likely true of exponentiation and
+            power functions, Gaussian has to do <emphasis>two</emphasis> of these operations,
+            compared to just one for Phong or Blinn.</para>
         <para>One might consider using Gouraud shading with specular reflections as a method of
-            optimization. This is not for the best. Specular highlights do not interpolate linearly
-            at all, so unless the mesh is finely divided, it will generally look awful.</para>
+            optimization. That is, doing per-vertex specular reflections. Since there are fewer
+            vertices than fragments, this might sound like a good idea. However, this is not for the
+            best. Specular highlights do not interpolate linearly at all, so unless the mesh is
+            finely divided, it will generally look awful.</para>
     </section>
     <section>
         <?dbhtml filename="Tut10 In Review.html" ?>

Documents/Tools/Colors.lua

+
+module(..., package.seeall);
+
+
+local g_colorTable =
+{
+	lightSource = {"yellow"},
+	surface = {"lightblue"},
+}
+
+function clrDirect(colorName, bIsBW)
+	local clrValue = g_colorTable[colorName];
+	
+	if(clrValue) then
+		if(bIsBW and clrValue[2]) then
+			return clrValue[2];
+		else
+			return clrValue[1];
+		end
+	else
+		return nil, "No Color value named " .. colorName;
+	end
+end
+
+function clr(...)
+	return assert(clrDirect(...));
+end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.