Skip to content

Commit

Permalink
Implement shader-based text in usd (PixarAnimationStudios#84)
Browse files Browse the repository at this point in the history
(cherry picked from commit f615f096ddff9c275385af7a7e709f1c7302be0c)
  • Loading branch information
PierreWang committed Jan 17, 2023
1 parent 6cb31c2 commit f9d4bba
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 148 deletions.
4 changes: 2 additions & 2 deletions extras/usd/examples/usdGeomExamples/simpleText.usda
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ def Xform "Text1" {
def Scope "Text11"{
def SimpleText "TextA" (){
uniform token[] xformOpOrder = ["xformOp:translate"]
float3 xformOp:translate = (3, 0, 0)
float3 xformOp:translate = (0, 0, 0)

string typeface = "Arial"
int textHeight = 22
int textHeight = 12
string textData = "Fox"
}
}
Expand Down
3 changes: 2 additions & 1 deletion pxr/imaging/hd/simpleText.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ HdSimpleText::GetBuiltinPrimvarNames() const
{
static const TfTokenVector primvarNames = {
HdTokens->points,
HdTokens->textTextureUV
HdTokens->textUV,
HdTokens->triType
};
return primvarNames;
}
Expand Down
31 changes: 6 additions & 25 deletions pxr/imaging/hd/simpleTextTopology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,18 @@ PXR_NAMESPACE_OPEN_SCOPE

HdSimpleTextTopology::HdSimpleTextTopology()
: HdTopology()
, _textData("")
, _textEncoding(TfToken())
, _textHeight(22)
, _textWidthFactor(1.0f)
, _bold(false)
, _italic(false)
, _pointCount(0)
{
HD_PERF_COUNTER_INCR(HdPerfTokens->simpleTextTopology);
}
HdSimpleTextTopology::HdSimpleTextTopology(const std::string& textData,
const TfToken& textEncoding, int textHeight, float textWidthFactor,
bool bold, bool italic)
: HdTopology(), _textData(textData), _textEncoding(textEncoding),
_textHeight(textHeight), _textWidthFactor(textWidthFactor),
_bold(bold), _italic(italic)
HdSimpleTextTopology::HdSimpleTextTopology(int pointCount)
: HdTopology(), _pointCount(pointCount)
{
HD_PERF_COUNTER_INCR(HdPerfTokens->simpleTextTopology);
}

HdSimpleTextTopology::HdSimpleTextTopology(const HdSimpleTextTopology& src)
: HdTopology(src)
: HdTopology(src), _pointCount(src._pointCount)
{
HD_PERF_COUNTER_INCR(HdPerfTokens->simpleTextTopology);
}
Expand All @@ -68,12 +59,7 @@ HdSimpleTextTopology::operator==(HdSimpleTextTopology const &other) const
HD_TRACE_FUNCTION();

// no need to compare _adajency and _quadInfo
return (_textData == other._textData &&
_textEncoding == other._textEncoding &&
_textHeight == other._textHeight &&
_textWidthFactor == other._textWidthFactor &&
_bold == other._bold &&
_italic == other._italic);
return (_pointCount == other._pointCount);
}

bool
Expand All @@ -88,12 +74,7 @@ HdSimpleTextTopology::ComputeHash() const
HD_TRACE_FUNCTION();

HdTopology::ID hash = 0;
hash = ArchHash64((const char*)_textData.data(), _textData.length(), hash);
hash = ArchHash64((const char*)&_textEncoding, sizeof(TfToken), hash);
hash = ArchHash64((const char*)&_textHeight, sizeof(int), hash);
hash = ArchHash64((const char*)&_textWidthFactor, sizeof(float), hash);
hash = ArchHash64((const char*)&_bold, sizeof(bool), hash);
hash = ArchHash64((const char*)&_italic, sizeof(bool), hash);
hash = ArchHash64((const char*)&_pointCount, sizeof(int), hash);

// Note: We don't hash topological visibility, because it is treated as a
// per-prim opinion, and hence, shouldn't break topology sharing.
Expand Down
36 changes: 6 additions & 30 deletions pxr/imaging/hd/simpleTextTopology.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ class HdSimpleTextTopology : public HdTopology {
HD_API
HdSimpleTextTopology();
HD_API
HdSimpleTextTopology(const std::string& textData,
const TfToken& textEncoding, int textHeight, float textWidthFactor,
bool bold, bool italic);
HdSimpleTextTopology(int pointCount);
HD_API
HdSimpleTextTopology(const HdSimpleTextTopology& src);
HD_API
Expand All @@ -54,39 +52,17 @@ class HdSimpleTextTopology : public HdTopology {
HD_API
virtual ID ComputeHash() const;

/// Returns segment vertex counts.
std::string GetTextData() const {
return _textData;
int GetPointCount() const {
return _pointCount;
}

/// Returns indices.
TfToken GetTextEncoding() const {
return _textEncoding;
}

/// Returns the number of curves
int GetTextHeight() const {
return _textHeight;
}

/// See class documentation for valid combination of values
float GetTextWidthFactor() const { return _textWidthFactor; }
bool GetBold() const { return _bold; }
bool GetItalic() const { return _italic; }


/// Equality check between two basisCurves topologies.
HD_API
bool operator==(HdSimpleTextTopology const &other) const;
bool operator==(HdSimpleTextTopology const &other) const;
HD_API
bool operator!=(HdSimpleTextTopology const &other) const;
bool operator!=(HdSimpleTextTopology const &other) const;
private:
std::string _textData;
TfToken _textEncoding;
int _textHeight;
float _textWidthFactor;
bool _bold;
bool _italic;
int _pointCount;
};

HD_API
Expand Down
3 changes: 2 additions & 1 deletion pxr/imaging/hd/tokens.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ PXR_NAMESPACE_OPEN_SCOPE
(subdivTags) \
(taskState) \
(taskParams) \
(textTextureUV) \
(textUV) \
(topology) \
(topologyVisibility) \
(totalItemCount) \
(transform) \
(transformInverse) \
(triType) \
(velocities) \
(visibility) \
(widths) \
Expand Down
165 changes: 125 additions & 40 deletions pxr/imaging/hdSt/shaders/text.glslfx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--glslfx version 0.1
-- glslfx version 0.1

//
// Copyright 2018 Pixar
Expand Down Expand Up @@ -28,35 +28,13 @@
--- #import $TOOLS/hdSt/shaders/text.glslfx

#import $TOOLS/hdSt/shaders/renderPass.glslfx

-- configuration
{
"techniques": {
"default": {
"vertexShader" : {
"source": ["VSTextureText"]
},
"fragmentShader" : {
"source": ["PSTextureText"]
}
}
}
}
#import $TOOLS/hdSt/shaders/pointId.glslfx

--- --------------------------------------------------------------------------
-- glsl VSTextureText

// Vertex shader input structure.
in VSInputTextureShaderData
{
// The vertex position.
vec3 Peye;
// The interpolated texture coordinates.
vec2 UV;
}inData;

// Vertex shader output structure.
out VSOutputTextureShaderData
out TextureShaderData
{
// The vertex position.
vec4 Peye;
Expand All @@ -67,17 +45,15 @@ out VSOutputTextureShaderData
}outData;

// Vertex shader - for textured based text.
outData VSTextureText(inData In)
void main(void)
{
outData output;

vec4 position = vec4(In.Peye, 1.0);
vec4 position = vec4(HdGet_points(), 1.0);

// Transform the position from object space to clip space for output.
output.Peye = position * GetWorldToViewMatrix();
outData.Peye = position * GetWorldToViewMatrix();

// Pass the texture coordinates.
output.UV = In.UV;
outData.UV = HdGet_textTextureUV();

float alpha = 1.0;
vec3 displayColor = vec3(0.5, 0.5, 0.5);
Expand All @@ -89,10 +65,10 @@ outData VSTextureText(inData In)
alpha = HdGet_displayOpacity().r;
#endif
// Texture color.
output.TextColor = vec4(displayColor.rgb, alpha);
outData.TextColor = vec4(displayColor.rgb, alpha);

gl_Position = vec4(GetProjectionMatrix() * output.Peye);
ApplyClipPlanes(output.Peye);
gl_Position = vec4(GetProjectionMatrix() * outData.Peye);
ApplyClipPlanes(outData.Peye);

return output;
}
Expand All @@ -101,7 +77,7 @@ outData VSTextureText(inData In)
-- glsl PSTextureText

// Pixel shader input structure.
in VSInputTextureShaderData
in TextureShaderData
{
// The vertex position.
vec4 Peye;
Expand All @@ -114,20 +90,129 @@ in VSInputTextureShaderData
layout(binding = 0) uniform sampler2D inTexture;

// Pixel shader - for texture based text.
vec4 PSTextureText(inData In)
void main(void)
{
float alpha = In.TextColor.a;
float alpha = IninDataTextColor.a;

// The texture used for text is an alpha texture.
float textureAlpha = texture(inTexture, In.UV).a * alpha;
float textureAlpha = texture(inTexture, inData.UV).a * alpha;

// 0.001953125 == 1/512
// When the alpha value is less than 1/512, we can safely discard this fragment.
if (textureAlpha < 0.001953125) discard;

// The output color is the user supplied color, and the output alpha is the mudulated by
// the user supplied opacity.
vec4 finalColor = vec4(In.TextColor.rgb, textureAlpha);
vec4 finalColor = vec4(inData.TextColor.rgb, textureAlpha);

RenderOutput(vec4(Peye, 1), vec3(0, 0, 1), inData.TextColor, vec4(1));
}

--- --------------------------------------------------------------------------
-- glsl VSShaderText

// Vertex shader output structure.
out VSOutputShaderData
{
// The vertex position.
vec4 Peye;
// The interpolated texture coordinates.
vec2 UV;
vec2 TriType;
}outData;

// Vertex shader - for shader based text.
void main(void)
{
vec4 position = vec4(HdGet_points(), 1.0);

// Transform the position from object space to clip space for output.
outData.Peye = GetWorldToViewMatrix() * position;

// Pass the texture coordinates and TriType.
outData.UV = HdGet_textUV();
outData.TriType = HdGet_triType();

gl_Position = vec4(GetProjectionMatrix() * outData.Peye);
gl_Position.z -= gl_Position.w* 2.0 * GetDepthPriority();
ApplyClipPlanes(outData.Peye);
}

--- --------------------------------------------------------------------------
-- glsl PSShaderText

// Pixel shader input structure.
in VSOutputShaderData
{
// The vertex position.
vec4 Peye;
// The interpolated texture coordinates.
vec2 UV;
vec2 TriType;
}inData;

// Pixel shader - for shader based text.
void main(void)
{
float alpha = 1.0;
#ifdef HD_HAS_displayOpacity
alpha = HdGet_displayOpacity().r;
#endif
// vec2 uv = inData.UV;
// vec2 triType = inData.TriType;

// if (triType.x <= 0.5) {
//// The curve is u^2 - v, where (u, v) is the texture coordinate.
// //
// // As in the paper, the signed distance from the pixel to the curve g(x,y) is calculated as
// //
// // g(x, y)
// // d(x, y) = ---------------------------------
// // || (g'x(x,y), g'y(x,y))||
// //
// // Here, g(x, y) = g(u(x, y), v(x, y)) = u(x, y) ^ 2 - v(x, y)
// // So, we can calculate the partial derivative:
// //
// // g'x(x, y) = 2 * u(x, y) * u'x(x, y) - v'x(x, y)
// // g'y(x, y) = 2 * u(x, y) * u'y(x, y) - v'y(x, y)
// //
//
// // g(x, y)
// float g = uv.x * uv.x - uv.y;

// // g'x(x, y)
// float pgdx = 2.0 * uv.x * dFdx(uv.x) - dFdx(uv.y);

// // g'y(x, y)
// float pgdy = 2.0 * uv.x * dFdy(uv.x) - dFdy(uv.y);

// // g(x, y)
// // d(x, y) = ---------------------------------
// // || (g'x(x,y), g'y(x,y))||
// float dist = g / sqrt( pgdx * pgdx + pgdy * pgdy);
//
//// The anti-alias algorithm is simple.
// // If the distance from the pixel to the outline is larger than 0.5 and on the fill side,
// // we think the pixel should be fully filled, so alpha will be gOpacity.
// // If the distance from the pixel to the outline is larger than 0.5 and on the non-fill side,
// // we think the pixel should be empty, so alpha will be 0.0.
// // If the distance from the pixel to the outline is smaller than 0.5,
// // we think the coverage of the pixel is (0.5 - distance), so alpha will be gOpacity plus this minus.

// if (triType.y <= 0.5)
// alpha = dist > 0.5 ? 1.0 : ( dist > -0.5 ? (0.5 + dist) : 0.0);
// else
// alpha = dist < -0.5 ? 1.0 : ( dist < 0.5 ? (0.5 - dist) : 0.0);
// }

vec3 displayColor = vec3(0.5, 0.5, 0.5);
#ifdef HD_HAS_displayColor
displayColor = HdGet_displayColor().rgb;
#endif

vec4 finalColor = vec4(displayColor, alpha);
finalColor = ApplyColorOverrides(finalColor);

return finalColor;
vec3 Peye = inData.Peye.xyz / inData.Peye.w;
RenderOutput(vec4(Peye, 1), vec3(0, 0, 1), finalColor, vec4(1));
}
Loading

0 comments on commit f9d4bba

Please sign in to comment.